fix(geometry): resolve transform lengths per axis and per font-size - #228
Closed
LeadcodeDev wants to merge 1 commit into
Closed
LeadcodeDev wants to merge 1 commit into
LeadcodeDev wants to merge 1 commit into
Conversation
LeadcodeDev
force-pushed
the
fix/geometry-viewport-units
branch
from
September 21, 2026 23:39
b59cf4f to
f94bcad
Compare
LeadcodeDev
force-pushed
the
fix/geometry-transform-lengths
branch
from
September 21, 2026 23:39
e52dc82 to
f478e84
Compare
53 tasks
LeadcodeDev
force-pushed
the
fix/geometry-viewport-units
branch
from
September 22, 2026 06:09
5d0dc87 to
99491fd
Compare
LeadcodeDev
force-pushed
the
fix/geometry-transform-lengths
branch
from
September 22, 2026 06:09
9f00928 to
6753586
Compare
LeadcodeDev
force-pushed
the
fix/geometry-viewport-units
branch
from
September 22, 2026 08:33
99491fd to
c1f4b85
Compare
LeadcodeDev
force-pushed
the
fix/geometry-transform-lengths
branch
from
September 22, 2026 08:33
6753586 to
de249ff
Compare
LeadcodeDev
force-pushed
the
fix/geometry-viewport-units
branch
from
September 22, 2026 08:43
c1f4b85 to
fc20b4c
Compare
apply_transform_chain resolves translate/translateX/translateY lengths
through this context. The paint pass resolves the very same functions
through LengthContext { ..., parent_size: box_layout.width.max(height),
font_size: node.css.font_size_px_or(16.0), ... } and then splits it into
per-axis length_ctx_x/length_ctx_y (crates/rustmotion-
core/src/engine/paint_pass.rs:229-250, used at :953-962). Two divergences:
(a) em — a font-size: 96px text with transform: "translateX(-10em)" is moved
-960px by the renderer but only -160px by the validator, so a component at
x=200 that renders at x=-760 (fully off-frame) validates clean; (b)
percentage translate — the validator uses max(w, h) on both axes, the exact
mistake paint_pass.rs:236-242 calls out in a comment ("never max(width,
height) on both axes"), which over-estimates on the short axis and produces
false positives. Note the --strict-anim path funnels animated transforms
through this same function (geometry.rs:1482), so it inherits both errors.
Fix: Build the context from the node's resolved font-size
(css.font_size_px_or(16.0)) and resolve the x-component against bbox.w and
the y-component against bbox.h, mirroring length_ctx_x/length_ctx_y in
paint_pass.rs:243-250.
Refs #220
LeadcodeDev
force-pushed
the
fix/geometry-transform-lengths
branch
from
September 22, 2026 08:43
de249ff to
59ba406
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Severity Medium, category correctness. Location:
crates/rustmotion/src/cli/commands/geometry.rs:477Impact
apply_transform_chainresolvestranslate/translateX/translateYlengths through this context. The paint pass resolves the very same functions throughLengthContext { ..., parent_size: box_layout.width.max(height), font_size: node.css.font_size_px_or(16.0), ... }and then splits it into per-axislength_ctx_x/length_ctx_y(crates/rustmotion-core/src/engine/paint_pass.rs:229-250, used at :953-962). Two divergences: (a)em— afont-size: 96pxtext withtransform: "translateX(-10em)"is moved -960px by the renderer but only -160px by the validator, so a component at x=200 that renders at x=-760 (fully off-frame) validates clean; (b) percentage translate — the validator usesmax(w, h)on both axes, the exact mistake paint_pass.rs:236-242 calls out in a comment ("never max(width, height) on both axes"), which over-estimates on the short axis and produces false positives. Note the--strict-animpath funnels animated transforms through this same function (geometry.rs:1482), so it inherits both errors.Fix
Build the context from the node's resolved font-size (
css.font_size_px_or(16.0)) and resolve the x-component againstbbox.wand the y-component againstbbox.h, mirroringlength_ctx_x/length_ctx_yin paint_pass.rs:243-250.Evidence the audit read
Part of the September 2026 audit remediation chantier. Refs #220 (RM-15).