@@ -3,95 +3,32 @@ import Frozen from "./Frozen.js";
33import defined from "./defined.js" ;
44import DeveloperError from "./DeveloperError.js" ;
55
6- function measureText ( context2D , textString , font , stroke , fill ) {
6+ function measureText ( context2D , textString ) {
77 const metrics = context2D . measureText ( textString ) ;
88 const isSpace = ! / \S / . test ( textString ) ;
99
10- if ( ! isSpace ) {
11- const fontSize = document . defaultView
12- . getComputedStyle ( context2D . canvas )
13- . getPropertyValue ( "font-size" )
14- . replace ( "px" , "" ) ;
15- const canvas = document . createElement ( "canvas" ) ;
16- const padding = 100 ;
17- const width = ( metrics . width + padding ) | 0 ;
18- const height = 3 * fontSize ;
19- const baseline = height / 2 ;
20- canvas . width = width ;
21- canvas . height = height ;
22-
23- const ctx = canvas . getContext ( "2d" ) ;
24- ctx . font = font ;
25- ctx . fillStyle = "white" ;
26- ctx . fillRect ( 0 , 0 , canvas . width + 1 , canvas . height + 1 ) ;
27-
28- if ( stroke ) {
29- ctx . strokeStyle = "black" ;
30- ctx . lineWidth = context2D . lineWidth ;
31- ctx . strokeText ( textString , padding / 2 , baseline ) ;
32- }
33-
34- if ( fill ) {
35- ctx . fillStyle = "black" ;
36- ctx . fillText ( textString , padding / 2 , baseline ) ;
37- }
38-
39- // Context image data has width * height * 4 elements, because
40- // each pixel's R, G, B and A are consecutive values in the array.
41- const pixelData = ctx . getImageData ( 0 , 0 , width , height ) . data ;
42- const length = pixelData . length ;
43- const width4 = width * 4 ;
44- let i , j ;
45-
46- let ascent , descent ;
47- // Find the number of rows (from the top) until the first non-white pixel
48- for ( i = 0 ; i < length ; ++ i ) {
49- if ( pixelData [ i ] !== 255 ) {
50- ascent = ( i / width4 ) | 0 ;
51- break ;
52- }
53- }
54-
55- // Find the number of rows (from the bottom) until the first non-white pixel
56- for ( i = length - 1 ; i >= 0 ; -- i ) {
57- if ( pixelData [ i ] !== 255 ) {
58- descent = ( i / width4 ) | 0 ;
59- break ;
60- }
61- }
62-
63- let minx = - 1 ;
64- // For each column, for each row, check for first non-white pixel
65- for ( i = 0 ; i < width && minx === - 1 ; ++ i ) {
66- for ( j = 0 ; j < height ; ++ j ) {
67- const pixelIndex = i * 4 + j * width4 ;
68- if (
69- pixelData [ pixelIndex ] !== 255 ||
70- pixelData [ pixelIndex + 1 ] !== 255 ||
71- pixelData [ pixelIndex + 2 ] !== 255 ||
72- pixelData [ pixelIndex + 3 ] !== 255
73- ) {
74- minx = i ;
75- break ;
76- }
77- }
78- }
79-
10+ if ( isSpace ) {
8011 return {
8112 width : metrics . width ,
82- height : descent - ascent ,
83- ascent : baseline - ascent ,
84- descent : descent - baseline ,
85- minx : minx - padding / 2 ,
13+ height : 0 ,
14+ ascent : 0 ,
15+ descent : 0 ,
16+ minx : 0 ,
8617 } ;
8718 }
8819
20+ // For historical reasons, round all metrics except 'width' to the nearest
21+ // whole pixel. See: https://github.com/CesiumGS/cesium/pull/13081
22+ const height =
23+ metrics . actualBoundingBoxAscent + metrics . actualBoundingBoxDescent ;
8924 return {
9025 width : metrics . width ,
91- height : 0 ,
92- ascent : 0 ,
93- descent : 0 ,
94- minx : 0 ,
26+ // Don't round height to zero. Certain characters ("_") may have height less
27+ // than 0.5 at some font sizes.
28+ height : Math . max ( Math . round ( height ) , 1 ) ,
29+ ascent : Math . round ( metrics . actualBoundingBoxAscent ) ,
30+ descent : Math . round ( metrics . actualBoundingBoxDescent ) ,
31+ minx : Math . round ( Math . abs ( metrics . actualBoundingBoxLeft ) ) ,
9532 } ;
9633}
9734
@@ -164,7 +101,7 @@ function writeTextToCanvas(text, options) {
164101 canvas . style . visibility = "hidden" ;
165102 document . body . appendChild ( canvas ) ;
166103
167- const dimensions = measureText ( context2D , text , font , stroke , fill ) ;
104+ const dimensions = measureText ( context2D , text ) ;
168105 // Set canvas.dimensions to be accessed in LabelCollection
169106 canvas . dimensions = dimensions ;
170107
0 commit comments