Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions packages/engine/Source/Scene/LabelCollection.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import BoundingRectangle from "../Core/BoundingRectangle.js";
import Cartesian2 from "../Core/Cartesian2.js";
import CesiumMath from "../Core/Math.js";
import Color from "../Core/Color.js";
import Frozen from "../Core/Frozen.js";
import defined from "../Core/defined.js";
Expand Down Expand Up @@ -132,22 +133,34 @@ const splitter = new GraphemeSplitter();
const whitespaceRegex = /\s/;

function rebindAllGlyphs(labelCollection, label) {
const labels = labelCollection._labels;
const text = label._renderedText;
const graphemes = splitter.splitGraphemes(text);
const textLength = graphemes.length;
const glyphs = label._glyphs;
const glyphsLength = glyphs.length;

// Compute SDF size based on largest label font size.
const sdfSize = CesiumMath.clamp(
labels.reduce((max, l) => Math.max(max, l._fontSize), 0),
SDFSettings.MIN_FONT_SIZE,
SDFSettings.MAX_FONT_SIZE,
);

// Compute a font size scale relative to the sdf font generated size.
label._relativeSize = label._fontSize / SDFSettings.FONT_SIZE;
label._relativeSize = label._fontSize / sdfSize;

// if we have more glyphs than needed, unbind the extras.
if (textLength < glyphsLength) {
for (let glyphIndex = textLength; glyphIndex < glyphsLength; ++glyphIndex) {
if (textLength < glyphsLength || labelCollection._sdfSize < sdfSize) {
let glyphIndex = labelCollection._sdfSize < sdfSize ? 0 : textLength;
while (glyphIndex < glyphsLength) {
unbindGlyphBillboard(labelCollection, glyphs[glyphIndex]);
glyphIndex++;
}
}

labelCollection._sdfSize = sdfSize;

// presize glyphs to match the new text length
glyphs.length = textLength;

Expand Down Expand Up @@ -188,13 +201,16 @@ function rebindAllGlyphs(labelCollection, label) {
+verticalOrigin,
]);

// TODO(donmccurdy): We're unbinding the glyph billboard above, but the glyph texture cache entry remains,
// so nothing is rebound. Worth checking whether this might represent a memory leak (black textures mobile)
// in `main`. But in any case, we need to replace the cached texture now.
let dimensions = textDimensionsCache[id];
let glyphBillboardTexture = glyphTextureCache.get(id);
if (!defined(glyphBillboardTexture) || !defined(dimensions)) {
glyphBillboardTexture = new BillboardTexture(glyphBillboardCollection);
glyphTextureCache.set(id, glyphBillboardTexture);

const glyphFont = `${label._fontStyle} ${label._fontWeight} ${SDFSettings.FONT_SIZE}px ${label._fontFamily}`;
const glyphFont = `${label._fontStyle} ${label._fontWeight} ${sdfSize}px ${label._fontFamily}`;

const canvas = createGlyphCanvas(
character,
Expand Down Expand Up @@ -646,6 +662,7 @@ function LabelCollection(options) {
this._labels = [];
this._labelsToUpdate = [];
this._totalGlyphCount = 0;
this._sdfSize = SDFSettings.MIN_FONT_SIZE;

this._highlightColor = Color.clone(Color.WHITE); // Only used by Vector3DTilePoints

Expand Down
12 changes: 10 additions & 2 deletions packages/engine/Source/Scene/SDFSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@
*/
const SDFSettings = {
/**
* The font size in pixels
* Minimum font size in pixels
*
* @type {number}
* @constant
*/
FONT_SIZE: 48.0,
MIN_FONT_SIZE: 48.0,

/**
* Maximum font size in pixels
*
* @type {number}
* @constant
*/
MAX_FONT_SIZE: 256.0,

/**
* Whitespace padding around glyphs.
Expand Down