diff --git a/examples/tests/text-vertical-align.ts b/examples/tests/text-vertical-align.ts index 9943232..9b75eb8 100644 --- a/examples/tests/text-vertical-align.ts +++ b/examples/tests/text-vertical-align.ts @@ -39,26 +39,40 @@ const NODE_PROPS = { } satisfies Partial; const CONTAINER_SIZE = 200; +const CONTAINER_SIZE_3L = 280; -function getSquare(renderer: RendererMain, node: ITextNode) { +function getSquare( + renderer: RendererMain, + node: ITextNode, + size = CONTAINER_SIZE, +) { const wrapper = renderer.createNode({ - w: CONTAINER_SIZE, - h: CONTAINER_SIZE, + w: size, + h: size, }); const line1 = renderer.createNode({ - w: CONTAINER_SIZE, + w: size, h: 1, color: 0x00ff00ff, y: NODE_PROPS.lineHeight, }); line1.parent = wrapper; const line2 = renderer.createNode({ - w: CONTAINER_SIZE, + w: size, h: 1, color: 0x00ff00ff, y: NODE_PROPS.lineHeight * 2, }); line2.parent = wrapper; + if (size >= NODE_PROPS.lineHeight * 3) { + const line3 = renderer.createNode({ + w: size, + h: 1, + color: 0x00ff00ff, + y: NODE_PROPS.lineHeight * 3, + }); + line3.parent = wrapper; + } node.parent = wrapper; return wrapper; } @@ -144,5 +158,48 @@ function generateVerticalAlignTest( ]); }, }, + { + title: `Three Lines ('verticalAlign', ${textRenderer}, fontSize = 50, lineHeight = 70)`, + content: async (rowNode) => { + const nodeProps = { + ...NODE_PROPS, + text: 'abcd\nefgh\ntxyz', + textRendererOverride: textRenderer, + contain: 'height', + maxHeight: CONTAINER_SIZE_3L, + } satisfies Partial; + + const baselineNode = renderer.createTextNode({ + ...nodeProps, + verticalAlign: 'middle', + }); + + return await constructTestRow( + { renderer, rowNode, containerSize: CONTAINER_SIZE_3L }, + [ + 'verticalAlign: middle\n(default)\n->', + getSquare(renderer, baselineNode, CONTAINER_SIZE_3L), + 'top ->', + getSquare( + renderer, + renderer.createTextNode({ + ...nodeProps, + verticalAlign: 'top', + }), + CONTAINER_SIZE_3L, + ), + 'bottom ->', + getSquare( + renderer, + renderer.createTextNode({ + ...nodeProps, + verticalAlign: 'bottom', + }), + CONTAINER_SIZE_3L, + ), + ], + ); + }, + }, ] satisfies TestRow[]; } diff --git a/src/core/CoreTextNode.ts b/src/core/CoreTextNode.ts index 15bc9da..ae36a6a 100644 --- a/src/core/CoreTextNode.ts +++ b/src/core/CoreTextNode.ts @@ -144,16 +144,19 @@ export class CoreTextNode extends CoreNode implements CoreTextNodeProps { } mountTranslateX = mountX * maxWidth; } - if (contain & TextConstraint.height && maxHeight > 0) { - if (verticalAlign === 'bottom') { - containY = maxHeight - h; - } else if (verticalAlign === 'middle') { - containY = (maxHeight - h) * 0.5; - } + if (contain & TextConstraint.height && hasMaxHeight === true) { mountTranslateY = mountY * maxHeight; } } + if (hasMaxHeight === true) { + if (verticalAlign === 'bottom') { + containY = maxHeight - h; + } else if (verticalAlign === 'middle') { + containY = (maxHeight - h) * 0.5; + } + } + if (p.rotation !== 0 || p.scaleX !== 1 || p.scaleY !== 1) { const scaleRotate = Matrix3d.rotate(p.rotation, Matrix3d.temp).scale( p.scaleX, diff --git a/src/core/text-rendering/TextRenderer.ts b/src/core/text-rendering/TextRenderer.ts index 5ba41e6..20a1432 100644 --- a/src/core/text-rendering/TextRenderer.ts +++ b/src/core/text-rendering/TextRenderer.ts @@ -231,13 +231,15 @@ export interface TrProps extends TrFontProps { */ maxLines: number; /** - * Vertical Align for text when lineHeight > fontSize + * Vertical alignment of the text block within `maxHeight`. * * @remarks - * This property sets the vertical align of the text. - * Not yet implemented in the SDF renderer. + * Activates when `maxHeight > 0`. Composes with `textBaselineMode` + * (per-line anchor). CSS line-box semantics — `'top'` leaves + * half-leading above the first line's cap-top; `'bottom'` leaves + * half-leading below the last line's descender. * - * @default middle + * @default top */ verticalAlign: TextVerticalAlign; /** diff --git a/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-1.png b/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-1.png index c3d4563..51d991a 100644 Binary files a/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-1.png and b/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-1.png differ diff --git a/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-2.png b/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-2.png index 353e19f..93c1064 100644 Binary files a/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-2.png and b/visual-regression/certified-snapshots/chromium-ci/text-vertical-align-2.png differ