Skip to content

Commit

Permalink
Update font baseline, make vertical mode applying with font baseline
Browse files Browse the repository at this point in the history
  • Loading branch information
zmiao committed Sep 24, 2019
1 parent b9926f4 commit e242e8f
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 16 deletions.
12 changes: 7 additions & 5 deletions src/symbol/quads.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function getGlyphQuads(anchor: Anchor,
const rect = glyph.rect;
if (!rect) continue;

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

Expand Down Expand Up @@ -152,21 +152,23 @@ export function getGlyphQuads(anchor: Anchor,

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

// xHalfWidhtOffsetcorrection is a difference between full-width and half-width
// advance, should be 0 for full-width glyphs and will pull up half-width glyphs.
const xHalfWidhtOffsetcorrection = ONE_EM / 2 - halfAdvance;
const xOffsetCorrection = new Point(5 - shaping.yOffset - xHalfWidhtOffsetcorrection, 0);
const xOffsetCorrection = new Point(5 - yShift - xHalfWidhtOffsetcorrection, 0);
const verticalOffsetCorrection = new Point(...verticalizedLabelOffset);
tl._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection);
tr._rotateAround(verticalRotation, center)._add(xOffsetCorrection)._add(verticalOffsetCorrection);
Expand Down
23 changes: 12 additions & 11 deletions src/symbol/shaping.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type Shaping = {
lineCount: number,
text: string,
yOffset: number,
hasBaseline: Boolean,
};

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

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

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

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

// justify right = 1, left = 0, center = 0.5
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"version": 8,
"metadata": {
"test": {
"collisionDebug": true,
"height": 300,
"width": 300
}
Expand Down
Binary file not shown.

0 comments on commit e242e8f

Please sign in to comment.