Extract Lottie text layout module and align rendering with Lottie spec#18333
Extract Lottie text layout module and align rendering with Lottie spec#18333VicenteCartas merged 3 commits intoBabylonJS:masterfrom
Conversation
…Lottie spec
Extracts text measurement and drawing from boundingBox.ts and spritePacker.ts into a new textLayout.ts module, and fixes spec-correctness issues in the process. This is a behavior change (bug fix), not a pure refactor — existing Lottie files containing text will render slightly differently, matching the reference renderer.
Spec-correctness fixes:
- Baseline offset now derived from font ascent (fontSize * rawFont.ascent / 100) instead of per-glyph metrics.actualBoundingBoxAscent. Per the Lottie spec, ascent is a font-level property ("text will be moved down based on this value"); using per-glyph metrics caused text to jitter vertically as content changed.
- Point-text anchor restored to the baseline origin. The old code forced offsetX/Y to 0 and returned width = ceil(metrics.width), which silently shifted glyphs whose side bearings were asymmetric (e.g. italic T). offsetX/Y now reflect actualBoundingBoxLeft/Right so the sprite center matches the authored layer origin.
- fontKerning = "none" on the measurement/draw context. Lottie applies tracking (tr) as a per-character advance and the reference renderer does not kern; leaving browser kerning on double-applied spacing adjustments.
New capability:
- Paragraph-box text (sz / ps fields on RawTextDocument) with word wrap, long-word breaking, and box-relative justification.
Mechanical changes:
- New helpers: ResolveLottieText, MeasureLottieText, ApplyLottieTextContext, DrawLottieText, BuildCanvasFont.
- GetTextBoundingBox and SpritePacker._drawText delegate to the new helpers. _drawText drops its unused boundingBox parameter.
- lottieTextLayout.test.ts: 7 new unit tests covering font resolution, paragraph-box layout, justification, tracking, line-break handling, and variable substitution.
Visual regression coverage is tracked as an Untriaged item on the lottie-fixes task board.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
There was a problem hiding this comment.
Pull request overview
Extracts Lottie text resolution/measurement/drawing into a dedicated textLayout.ts module and updates text atlas packing + bounding-box measurement to be more spec-aligned (baseline handling, point-text anchoring, tracking/kerning behavior, and paragraph-box wrapping).
Changes:
- Introduces
textLayout.tshelpers (ResolveLottieText,MeasureLottieText,ApplyLottieTextContext,DrawLottieText, etc.) and updates text measurement/layout behavior. - Refactors
GetTextBoundingBoxandSpritePacker._drawTextto delegate to the new layout module (and adds paragraph-box support). - Adds unit tests covering the new layout/draw behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/dev/lottiePlayer/src/parsing/textLayout.ts | New shared module for resolving, measuring, and drawing Lottie text (including paragraph box wrapping and tracking). |
| packages/dev/lottiePlayer/src/maths/boundingBox.ts | Routes text bounding-box computation through the new text layout/measurement helpers. |
| packages/dev/lottiePlayer/src/parsing/spritePacker.ts | Updates sprite atlas text drawing to use the new text layout module; removes the unused boundingBox parameter. |
| packages/dev/lottiePlayer/src/parsing/rawTypes.ts | Extends RawTextDocument with sz/ps (paragraph box) fields. |
| packages/dev/lottiePlayer/test/unit/lottieTextLayout.test.ts | Adds focused unit coverage for resolution, layout, wrapping, justification, tracking, and draw ordering. |
|
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
|
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/18333/merge/index.html#WGZLGJ#4600 Links to test your changes to core in the published versions of the Babylon tools (does not contain changes you made to the tools themselves): https://playground.babylonjs.com/?snapshot=refs/pull/18333/merge To test the snapshot in the playground with a playground ID add it after the snapshot query string: https://playground.babylonjs.com/?snapshot=refs/pull/18333/merge#BCU1XR#0 If you made changes to the sandbox or playground in this PR, additional comments will be generated soon containing links to the dev versions of those tools. |
|
WebGL2 visualization test reporter: |
|
Visualization tests for WebGPU |
|
Visualization tests for WebGPU |
|
WebGL2 visualization test reporter: |
Summary
Extracts Lottie text measurement and drawing out of
boundingBox.tsandspritePacker.tsinto a newtextLayout.tsmodule, and fixes spec-correctness issues in the process. This is a behavior change (bug fix), not a pure refactor, existing Lottie files containing text will render slightly differently, matching the reference renderer.Spec-correctness fixes
metrics.actualBoundingBoxAscent, which caused text to jitter vertically as content changed. NowfontSize × rawFont.ascent / 100, matching the Lottie spec's definition ofascentas a font-level property ("text will be moved down based on this value").offsetX/Yto0and returnedwidth = ceil(metrics.width), which silently shifted glyphs whose side bearings were asymmetric (e.g. italicT).offsetX/Ynow reflectactualBoundingBoxLeft/Rightso the sprite center matches the authored layer origin.fontKerning = "none"on the measurement/draw context. Lottie applies tracking (tr) as a per-character advance and the reference renderer does not kern; leaving browser kerning on double-applied spacing adjustments.New capability
sz/psfields onRawTextDocument) with word wrap, long-word breaking, and box-relative justification.Mechanical changes
ResolveLottieText,MeasureLottieText,ApplyLottieTextContext,DrawLottieText,BuildCanvasFont.GetTextBoundingBoxandSpritePacker._drawTextdelegate to the new helpers._drawTextdrops its unusedboundingBoxparameter.DrawTrackedTextlays glyphs out in a single pass (wasO(n²)inmeasureTextcalls when tracking was non-zero).Tests
lottieTextLayout.test.ts(12 tests) covering font resolution, paragraph-box layout, justification, tracking, line-break handling, variable substitution, long-word break, stroke-under / stroke-over-fill ordering, and per-glyph tracked-draw X positions.lottiePlayerunit tests pass.format:checkand eslint pass on changed files.