Skip to content

Commit

Permalink
Don't scale images in labels with text size
Browse files Browse the repository at this point in the history
  • Loading branch information
alexshalamov committed Nov 15, 2019
1 parent a32c230 commit 17d6581
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
35 changes: 19 additions & 16 deletions src/symbol/shaping.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ const WritingMode = {
horizontalOnly: 3
};

// Ratio between default font size and EM unit
const BASE_FONT_RATIO = (1 / (16 / ONE_EM));
const SHAPING_DEFAULT_OFFSET = -17;
export {shapeText, shapeIcon, fitIconToText, getAnchorAlignment, WritingMode, SHAPING_DEFAULT_OFFSET};

Expand Down Expand Up @@ -249,7 +247,8 @@ function shapeText(text: Formatted,
translate: [number, number],
writingMode: 1 | 2,
allowVerticalPlacement: boolean,
symbolPlacement: string): Shaping | false {
symbolPlacement: string,
layoutTextSize: number): Shaping | false {
const logicalInput = TaggedString.fromFeature(text, defaultFontStack);

if (writingMode === WritingMode.vertical) {
Expand All @@ -264,7 +263,7 @@ function shapeText(text: Formatted,
lines = [];
const untaggedLines =
processBidirectionalText(logicalInput.toString(),
determineLineBreaks(logicalInput, spacing, maxWidth, glyphPositions, imagePositions, symbolPlacement));
determineLineBreaks(logicalInput, spacing, maxWidth, glyphPositions, imagePositions, symbolPlacement, layoutTextSize));
for (const line of untaggedLines) {
const taggedLine = new TaggedString();
taggedLine.text = line;
Expand All @@ -281,7 +280,7 @@ function shapeText(text: Formatted,
const processedLines =
processStyledBidirectionalText(logicalInput.text,
logicalInput.sectionIndex,
determineLineBreaks(logicalInput, spacing, maxWidth, glyphPositions, imagePositions, symbolPlacement));
determineLineBreaks(logicalInput, spacing, maxWidth, glyphPositions, imagePositions, symbolPlacement, layoutTextSize));
for (const line of processedLines) {
const taggedLine = new TaggedString();
taggedLine.text = line[0];
Expand All @@ -290,7 +289,7 @@ function shapeText(text: Formatted,
lines.push(taggedLine);
}
} else {
lines = breakLines(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, glyphPositions, imagePositions, symbolPlacement));
lines = breakLines(logicalInput, determineLineBreaks(logicalInput, spacing, maxWidth, glyphPositions, imagePositions, symbolPlacement, layoutTextSize));
}

const positionedLines = [];
Expand All @@ -306,7 +305,7 @@ function shapeText(text: Formatted,
verticalizable: false
};

shapeLines(shaping, glyphPositions, imagePositions, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement);
shapeLines(shaping, glyphPositions, imagePositions, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement, layoutTextSize);
if (isEmpty(positionedLines)) return false;

return shaping;
Expand Down Expand Up @@ -348,7 +347,8 @@ function getGlyphAdvance(codePoint: number,
section: SectionOptions,
glyphPositions: {[string]: {[number]: GlyphPosition}},
imagePositions: {[string]: ImagePosition},
spacing: number): number | null {
spacing: number,
layoutTextSize: number): number | null {
if (!section.imageName) {
const positions = glyphPositions[section.fontStack];
const glyph = positions && positions[codePoint];
Expand All @@ -357,20 +357,21 @@ function getGlyphAdvance(codePoint: number,
} else {
const imagePosition = imagePositions[section.imageName];
if (!imagePosition) return null;
return imagePosition.displaySize[0] * section.scale * BASE_FONT_RATIO + spacing;
return imagePosition.displaySize[0] * section.scale * ONE_EM / layoutTextSize + spacing;
}
}

function determineAverageLineWidth(logicalInput: TaggedString,
spacing: number,
maxWidth: number,
glyphPositions: {[string]: {[number]: GlyphPosition}},
imagePositions: {[string]: ImagePosition}) {
imagePositions: {[string]: ImagePosition},
layoutTextSize: number) {
let totalWidth = 0;

for (let index = 0; index < logicalInput.length(); index++) {
const section = logicalInput.getSection(index);
const advance = getGlyphAdvance(logicalInput.getCharCode(index), section, glyphPositions, imagePositions, spacing);
const advance = getGlyphAdvance(logicalInput.getCharCode(index), section, glyphPositions, imagePositions, spacing, layoutTextSize);
if (advance) totalWidth += advance;
}

Expand Down Expand Up @@ -470,15 +471,16 @@ function determineLineBreaks(logicalInput: TaggedString,
maxWidth: number,
glyphPositions: {[string]: {[number]: GlyphPosition}},
imagePositions: {[string]: ImagePosition},
symbolPlacement: string): Array<number> {
symbolPlacement: string,
layoutTextSize: number): Array<number> {
if (symbolPlacement !== 'point')
return [];

if (!logicalInput)
return [];

const potentialLineBreaks = [];
const targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphPositions, imagePositions);
const targetWidth = determineAverageLineWidth(logicalInput, spacing, maxWidth, glyphPositions, imagePositions, layoutTextSize);

const hasServerSuggestedBreakpoints = logicalInput.text.indexOf("\u200b") >= 0;

Expand All @@ -487,7 +489,7 @@ function determineLineBreaks(logicalInput: TaggedString,
for (let i = 0; i < logicalInput.length(); i++) {
const section = logicalInput.getSection(i);
const codePoint = logicalInput.getCharCode(i);
if (!whitespace[codePoint]) currentX += getGlyphAdvance(codePoint, section, glyphPositions, imagePositions, spacing);
if (!whitespace[codePoint]) currentX += getGlyphAdvance(codePoint, section, glyphPositions, imagePositions, spacing, layoutTextSize);

// Ideographic characters, spaces, and word-breaking punctuation that often appear without
// surrounding spaces.
Expand Down Expand Up @@ -558,7 +560,8 @@ function shapeLines(shaping: Shaping,
textJustify: TextJustify,
writingMode: 1 | 2,
spacing: number,
allowVerticalPlacement: boolean) {
allowVerticalPlacement: boolean,
layoutTextSize: number) {

let x = 0;
let y = SHAPING_DEFAULT_OFFSET;
Expand Down Expand Up @@ -623,7 +626,7 @@ function shapeLines(shaping: Shaping,
// If needed, allow to set scale factor for an image using
// alias "image-scale" that could be alias for "font-scale"
// when FormattedSection is an image section.
section.scale = section.scale * BASE_FONT_RATIO;
section.scale = section.scale * ONE_EM / layoutTextSize;

metrics = {width: size[0],
height: size[1],
Expand Down
17 changes: 9 additions & 8 deletions src/symbol/symbol_layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ export function performSymbolLayout(bucket: SymbolBucket,

for (const feature of bucket.features) {
const fontstack = layout.get('text-font').evaluate(feature, {}).join(',');
const layoutTextSize = sizes.layoutTextSize.evaluate(feature, {});
const layoutIconSize = sizes.layoutIconSize.evaluate(feature, {});

const shapedTextOrientations = {
horizontal: {},
Expand Down Expand Up @@ -232,7 +234,7 @@ export function performSymbolLayout(bucket: SymbolBucket,
// writing mode, thus, default left justification is used. If Latin
// scripts would need to be supported, this should take into account other justifications.
shapedTextOrientations.vertical = shapeText(text, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor,
'left', spacingIfAllowed, textOffset, WritingMode.vertical, true, symbolPlacement);
'left', spacingIfAllowed, textOffset, WritingMode.vertical, true, symbolPlacement, layoutTextSize);
}
};

Expand All @@ -254,7 +256,7 @@ export function performSymbolLayout(bucket: SymbolBucket,
// If using text-variable-anchor for the layer, we use a center anchor for all shapings and apply
// the offsets for the anchor in the placement step.
const shaping = shapeText(text, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, 'center',
justification, spacingIfAllowed, textOffset, WritingMode.horizontal, false, symbolPlacement);
justification, spacingIfAllowed, textOffset, WritingMode.horizontal, false, symbolPlacement, layoutTextSize);
if (shaping) {
shapedTextOrientations.horizontal[justification] = shaping;
singleLine = shaping.positionedLines.length === 1;
Expand All @@ -270,7 +272,7 @@ export function performSymbolLayout(bucket: SymbolBucket,

// Horizontal point or line label.
const shaping = shapeText(text, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify, spacingIfAllowed,
textOffset, WritingMode.horizontal, false, symbolPlacement);
textOffset, WritingMode.horizontal, false, symbolPlacement, layoutTextSize);
if (shaping) shapedTextOrientations.horizontal[textJustify] = shaping;

// Vertical point label (if allowVerticalPlacement is enabled).
Expand All @@ -279,7 +281,7 @@ export function performSymbolLayout(bucket: SymbolBucket,
// Verticalized line label.
if (allowsVerticalWritingMode(unformattedText) && textAlongLine && keepUpright) {
shapedTextOrientations.vertical = shapeText(text, glyphPositions, imagePositions, fontstack, maxWidth, lineHeight, textAnchor, textJustify,
spacingIfAllowed, textOffset, WritingMode.vertical, false, symbolPlacement);
spacingIfAllowed, textOffset, WritingMode.vertical, false, symbolPlacement, layoutTextSize);
}
}
}
Expand Down Expand Up @@ -310,7 +312,7 @@ export function performSymbolLayout(bucket: SymbolBucket,
const shapedText = getDefaultHorizontalShaping(shapedTextOrientations.horizontal) || shapedTextOrientations.vertical;
bucket.iconsInText = shapedText ? shapedText.iconsInText : false;
if (shapedText || shapedIcon) {
addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, textOffset, isSDFIcon);
addFeature(bucket, feature, shapedTextOrientations, shapedIcon, imageMap, sizes, layoutTextSize, layoutIconSize, textOffset, isSDFIcon);
}
}

Expand Down Expand Up @@ -347,11 +349,10 @@ function addFeature(bucket: SymbolBucket,
shapedIcon: PositionedIcon | void,
imageMap: {[string]: StyleImage},
sizes: Sizes,
layoutTextSize: number,
layoutIconSize: number,
textOffset: [number, number],
isSDFIcon: boolean) {
const layoutTextSize = sizes.layoutTextSize.evaluate(feature, {});
const layoutIconSize = sizes.layoutIconSize.evaluate(feature, {});

// To reduce the number of labels that jump around when zooming we need
// to use a text-size value that is the same for all zoom levels.
// bucket calculates text-size at a high zoom level so that all tiles can
Expand Down

0 comments on commit 17d6581

Please sign in to comment.