Skip to content

Commit a427a2e

Browse files
committed
Update font baseline, make vertical mode applying with font baseline
1 parent 8dd9f26 commit a427a2e

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
@@ -139,7 +139,7 @@ export function getGlyphQuads(anchor: Anchor,
139139
const rect = glyph.rect;
140140
if (!rect) continue;
141141

142-
// The rects have an addditional buffer that is not included in their size.
142+
// The rects have an additional buffer that is not included in their size.
143143
const glyphPadding = 1.0;
144144
const rectBuffer = GLYPH_PBF_BORDER + glyphPadding;
145145

@@ -175,21 +175,23 @@ export function getGlyphQuads(anchor: Anchor,
175175

176176
if (rotateVerticalGlyph) {
177177
// Vertical-supporting glyphs are laid out in 24x24 point boxes (1 square em)
178-
// In horizontal orientation, the y values for glyphs are below the midline
179-
// and we use a "yOffset" of -17 to pull them up to the middle.
178+
// In horizontal orientation, the y values for glyphs are below the midline.
179+
// If the glyph's baseline is applicable, we take the value of the baseline offset.
180+
// Otherwise, we use a "yOffset" of -17 to pull them up to the middle.
180181
// By rotating counter-clockwise around the point at the center of the left
181182
// edge of a 24x24 layout box centered below the midline, we align the center
182183
// of the glyphs with the horizontal midline, so the yOffset is no longer
183184
// necessary, but we also pull the glyph to the left along the x axis.
184185
// The y coordinate includes baseline yOffset, thus needs to be accounted
185186
// for when glyph is rotated and translated.
186-
const center = new Point(-halfAdvance, halfAdvance - shaping.yOffset);
187+
const yShift = shaping.hasBaseline ? (-glyph.metrics.ascender + glyph.metrics.descender) / 2 : shaping.yOffset;
188+
const center = new Point(-halfAdvance, halfAdvance - yShift);
187189
const verticalRotation = -Math.PI / 2;
188190

189191
// xHalfWidhtOffsetcorrection is a difference between full-width and half-width
190192
// advance, should be 0 for full-width glyphs and will pull up half-width glyphs.
191193
const xHalfWidhtOffsetcorrection = ONE_EM / 2 - halfAdvance;
192-
const xOffsetCorrection = new Point(5 - shaping.yOffset - xHalfWidhtOffsetcorrection, 0);
194+
const xOffsetCorrection = new Point(5 - yShift - xHalfWidhtOffsetcorrection, 0);
193195
const verticalOffsetCorrection = new Point(...verticalizedLabelOffset);
194196
tl._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection);
195197
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
@@ -43,6 +43,7 @@ export type Shaping = {
4343
lineCount: number,
4444
text: string,
4545
yOffset: number,
46+
hasBaseline: Boolean,
4647
};
4748

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

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

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

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

550551
// 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)