Skip to content

Commit 558a4e3

Browse files
committed
refactor(labels): Remove custom measureText implementation
1 parent 3d78834 commit 558a4e3

File tree

2 files changed

+18
-80
lines changed

2 files changed

+18
-80
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Billboards using `imageSubRegion` now render as expected. [#12585](https://github.com/CesiumGS/cesium/issues/12585)
1111
- Fixed depth testing bug with billboards and labels clipping through models [#13012](https://github.com/CesiumGS/cesium/issues/13012)
1212
- Fixed unexpected outline artifacts around billboards [#13038](https://github.com/CesiumGS/cesium/issues/13038)
13+
- Fixed label sizing for certain fonts and characters [#9767](https://github.com/CesiumGS/cesium/issues/9767)
1314

1415
#### Additions :tada:
1516

packages/engine/Source/Core/writeTextToCanvas.js

Lines changed: 17 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,95 +3,32 @@ import Frozen from "./Frozen.js";
33
import defined from "./defined.js";
44
import 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

Comments
 (0)