Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Format expression vertical alignment #4832

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
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
45 changes: 36 additions & 9 deletions src/symbol/shaping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,28 @@
fontStack: string;
// Image options
imageName: string | null;
// Common options
verticalAlign: 'baseline' | 'top' | 'center';

constructor() {
this.scale = 1.0;
this.fontStack = '';
this.imageName = null;
this.verticalAlign = 'baseline';
}

static forText(scale: number | null, fontStack: string) {
static forText(scale: number | null, fontStack: string, verticalAlign: 'baseline' | 'top' | 'center' | null) {
const textOptions = new SectionOptions();
textOptions.scale = scale || 1;
textOptions.fontStack = fontStack;
textOptions.verticalAlign = verticalAlign || 'baseline';
return textOptions;
}

static forImage(imageName: string) {
static forImage(imageName: string, verticalAlign: 'baseline' | 'top' | 'center' | null) {
const imageOptions = new SectionOptions();
imageOptions.imageName = imageName;
imageOptions.verticalAlign = verticalAlign || 'baseline';
return imageOptions;
}

Expand Down Expand Up @@ -184,7 +189,7 @@

addTextSection(section: FormattedSection, defaultFontStack: string) {
this.text += section.text;
this.sections.push(SectionOptions.forText(section.scale, section.fontStack || defaultFontStack));
this.sections.push(SectionOptions.forText(section.scale, section.fontStack || defaultFontStack, section.verticalAlign));

Check failure on line 192 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Code Hygiene

Property 'verticalAlign' does not exist on type 'FormattedSection'.
const index = this.sections.length - 1;
for (let i = 0; i < section.text.length; ++i) {
this.sectionIndex.push(index);
Expand All @@ -205,7 +210,7 @@
}

this.text += String.fromCharCode(nextImageSectionCharCode);
this.sections.push(SectionOptions.forImage(imageName));
this.sections.push(SectionOptions.forImage(imageName, section.verticalAlign));

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Build tests (ubuntu-latest)

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Unit tests and Coverage

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Integration tests (ubuntu-latest)

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Render tests (ubuntu-latest, 0)

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Render tests (ubuntu-latest, 2)

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Render tests (ubuntu-latest, 1)

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Code Hygiene

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Code Hygiene

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Code Hygiene

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Render tests (windows-latest, 0)

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Render tests (windows-latest, 2)

Property 'verticalAlign' does not exist on type 'FormattedSection'.

Check failure on line 213 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Render tests (windows-latest, 1)

Property 'verticalAlign' does not exist on type 'FormattedSection'.
this.sectionIndex.push(this.sections.length - 1);
}

Expand Down Expand Up @@ -637,7 +642,7 @@
const section = line.getSection(i);
const sectionIndex = line.getSectionIndex(i);
const codePoint = line.getCharCode(i);
let baselineOffset = 0.0;
let verticalAlignOffset = 0.0;
let metrics = null;
let rect = null;
let imageName = null;
Expand Down Expand Up @@ -665,7 +670,17 @@
// We don't know the baseline, but since we're laying out
// at 24 points, we can calculate how much it will move when
// we scale up or down.
baselineOffset = (lineMaxScale - section.scale) * ONE_EM;
verticalAlignOffset = (lineMaxScale - section.scale) * ONE_EM;

// Do not offset vertical alignment for vertical text.
if (writingMode !== WritingMode.vertical) {
if (section.verticalAlign === 'top') {
verticalAlignOffset = 0;
} else if (section.verticalAlign === 'center') {
// Calculate center as the middle between top and baseline alignment.
verticalAlignOffset = (lineMaxScale - section.scale) * (ONE_EM * 2 / 3) - (ONE_EM / 6);
}
}
} else {
const imagePosition = imagePositions[section.imageName];
if (!imagePosition) continue;
Expand All @@ -687,7 +702,19 @@
// Difference between one EM and an image size.
// Aligns bottom of an image to a baseline level.
const imageOffset = ONE_EM - size[1] * section.scale;
baselineOffset = maxLineOffset + imageOffset;
verticalAlignOffset = maxLineOffset + imageOffset;

// Do not offset vertical alignment for vertical text.
if (writingMode !== WritingMode.vertical) {
if (section.verticalAlign === 'top') {
// Aligns top of an image to top of a line.
verticalAlignOffset = 0;
} else if (section.verticalAlign === 'center') {
// We calculate center as the middle between top and baseline alignment.
verticalAlignOffset = (maxLineOffset + imageOffset) / 2;
}
}

Check failure on line 717 in src/symbol/shaping.ts

View workflow job for this annotation

GitHub Actions / Code Hygiene

Trailing spaces not allowed
verticalAdvance = metrics.advance;

// Difference between height of an image and one EM at max line scale.
Expand All @@ -700,11 +727,11 @@
}

if (!vertical) {
positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + baselineOffset, vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex, metrics, rect});
positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + verticalAlignOffset, vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex, metrics, rect});
x += metrics.advance * section.scale + spacing;
} else {
shaping.verticalizable = true;
positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + baselineOffset, vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex, metrics, rect});
positionedGlyphs.push({glyph: codePoint, imageName, x, y: y + verticalAlignOffset, vertical, scale: section.scale, fontStack: section.fontStack, sectionIndex, metrics, rect});
x += verticalAdvance * section.scale + spacing;
}
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading