Skip to content

Commit e242e8f

Browse files
committed
Update font baseline, make vertical mode applying with font baseline
1 parent b9926f4 commit e242e8f

5 files changed

Lines changed: 20 additions & 16 deletions

File tree

src/symbol/quads.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export function getGlyphQuads(anchor: Anchor,
116116
const rect = glyph.rect;
117117
if (!rect) continue;
118118

119-
// The rects have an addditional buffer that is not included in their size.
119+
// The rects have an additional buffer that is not included in their size.
120120
const glyphPadding = 1.0;
121121
const rectBuffer = GLYPH_PBF_BORDER + glyphPadding;
122122

@@ -152,21 +152,23 @@ export function getGlyphQuads(anchor: Anchor,
152152

153153
if (rotateVerticalGlyph) {
154154
// Vertical-supporting glyphs are laid out in 24x24 point boxes (1 square em)
155-
// In horizontal orientation, the y values for glyphs are below the midline
156-
// and we use a "yOffset" of -17 to pull them up to the middle.
155+
// In horizontal orientation, the y values for glyphs are below the midline.
156+
// If the glyph's baseline is applicable, we take the value of the baseline offset.
157+
// Otherwise, we use a "yOffset" of -17 to pull them up to the middle.
157158
// By rotating counter-clockwise around the point at the center of the left
158159
// edge of a 24x24 layout box centered below the midline, we align the center
159160
// of the glyphs with the horizontal midline, so the yOffset is no longer
160161
// necessary, but we also pull the glyph to the left along the x axis.
161162
// The y coordinate includes baseline yOffset, thus needs to be accounted
162163
// for when glyph is rotated and translated.
163-
const center = new Point(-halfAdvance, halfAdvance - shaping.yOffset);
164+
const yShift = shaping.hasBaseline ? (-glyph.metrics.ascender + glyph.metrics.descender) / 2 : shaping.yOffset;
165+
const center = new Point(-halfAdvance, halfAdvance - yShift);
164166
const verticalRotation = -Math.PI / 2;
165167

166168
// xHalfWidhtOffsetcorrection is a difference between full-width and half-width
167169
// advance, should be 0 for full-width glyphs and will pull up half-width glyphs.
168170
const xHalfWidhtOffsetcorrection = ONE_EM / 2 - halfAdvance;
169-
const xOffsetCorrection = new Point(5 - shaping.yOffset - xHalfWidhtOffsetcorrection, 0);
171+
const xOffsetCorrection = new Point(5 - yShift - xHalfWidhtOffsetcorrection, 0);
170172
const verticalOffsetCorrection = new Point(...verticalizedLabelOffset);
171173
tl._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection);
172174
tr._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection);

src/symbol/shaping.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export type Shaping = {
4444
lineCount: number,
4545
text: string,
4646
yOffset: number,
47+
hasBaseline: Boolean,
4748
};
4849

4950
export type SymbolAnchor = 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
@@ -210,7 +211,8 @@ function shapeText(text: Formatted,
210211
right: translate[0],
211212
writingMode,
212213
lineCount: lines.length,
213-
yOffset: -17 // the y offset *should* be part of the font metadata
214+
yOffset: -17, // the y offset *should* be part of the font metadata
215+
hasBaseline: false
214216
};
215217

216218
shapeLines(shaping, glyphs, lines, lineHeight, textAnchor, textJustify, writingMode, spacing, allowVerticalPlacement);
@@ -499,16 +501,14 @@ function shapeLines(shaping: Shaping,
499501
const glyph = positions && positions[codePoint];
500502
if (!glyph) continue;
501503

502-
// The rects have an addditional buffer that is not included in their size.
503-
const glyphPadding = 1.0;
504-
const rectBuffer = 3 + glyphPadding;
505-
// Each glyph's baseline is starting from its acsender, which is the vertical distance
506-
// from the horizontal baseline to the highest ‘character’ coordinate in a font face.
507-
// If ascender is applied, the shaping rect buffer needs to be counted.
508-
// If ascender is not applicable, fall back to use a default baseline yOffset.
509-
// Since we're laying out at 24 points, we need also calculate how much it will move
510-
// when we scale up or down.
511-
const baselineOffset = (hasBaseline ? ((-glyph.metrics.ascender + rectBuffer * 2) * section.scale) : shaping.yOffset) + (lineMaxScale - section.scale) * 24;
504+
// In order to make different fonts aligned, they must share a general baseline that starts from the midline
505+
// of each font face. Baseline offset is the vertical distance from font face's baseline to its top most
506+
// position, which is the half size of the sum (ascender + descender). Since glyph's position is counted
507+
// from the top left corner, the negative shift is needed. So different fonts shares the same baseline but
508+
// with different offset shift. If font's baseline is not applicable, fall back to use a default baseline
509+
// offset, see shaping.yOffset. Since we're laying out at 24 points, we need also calculate how much it will
510+
// move when we scale up or down.
511+
const baselineOffset = (hasBaseline ? ((-glyph.metrics.ascender + glyph.metrics.descender) / 2 * section.scale) : shaping.yOffset) + (lineMaxScale - section.scale) * 24;
512512

513513
if (writingMode === WritingMode.horizontal ||
514514
// Don't verticalize glyphs that have no upright orientation if vertical placement is disabled.
@@ -546,6 +546,7 @@ function shapeLines(shaping: Shaping,
546546
shaping.bottom = shaping.top + height;
547547
shaping.left += -horizontalAlign * maxLineLength;
548548
shaping.right = shaping.left + maxLineLength;
549+
shaping.hasBaseline = hasBaseline;
549550
}
550551

551552
// justify right = 1, left = 0, center = 0.5
8.9 KB
Loading

test/integration/render-tests/text-font/mixed-fonts/style.json renamed to test/integration/render-tests/text-font/mixed-fonts-both-with-baseline/style.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"version": 8,
33
"metadata": {
44
"test": {
5+
"collisionDebug": true,
56
"height": 300,
67
"width": 300
78
}
-8.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)