Commit 14b7766
authored
feat(text): let text declare that it must fit its box (#170)
Closes the second Critical gap from the re-scored Remotion differential, and
the one the original audit called the most profitable reliability lever here.
Until now, a text that overflowed its box was reported and nothing more.
`apply_fixes` deliberately refuses `ContentOverflowsBox`, and its comment says
why: growing the box, shrinking the font and shortening the copy are all
legitimate, and picking one is not the validator's call. That reasoning holds
only while the engine has no way to shrink text at all. Given one, the
arbitration disappears — the author declares the intent, and a whole class of
generation failure stops existing.
`style.text-autofit` makes `text` and `gradient_text` reduce their font size
until they fit the resolved width and, where taffy defines one, the content
box height. `white-space: nowrap` still decides *whether* the text wraps;
autofit decides *at what size* — they compose rather than compete.
`auto_scroll` never interacts: codeblock and terminal do not read the field,
by construction rather than by convention.
Three hazards drove the design:
- **Measure and paint must agree.** This repository spent a whole chantier
repairing divergences where `TextIntrinsic` measured one thing and the
painter drew another, blinding the geometry pass to real overflow. One pure
`resolve_text_autofit` is called with identical arguments from both sides,
so the agreement is structural rather than coincidental — and the tests
assert it rather than merely checking the render looks right.
- **The size must not drift.** Paint runs per frame. The resolution is fed
the complete content, never the typewriter-truncated view, so a reveal
cannot make the size oscillate mid-read. Asserted by rendering the same
content at two instants and comparing pixels byte for byte.
- **Shrinking needs a floor**, or a visible defect is traded for a discreet
one. The floor reuses `MIN_LEGIBLE_FONT_RATIO`, already calibrated by
visual inspection, relocated into `rustmotion-core` so both sides share the
one constant instead of inventing a second.
`rustmotion info` now reports each text's natural size, through the same
measurer the engine and the validator use.
The floor is pinned to a 1080-tall reference, because `IntrinsicMeasure`
cannot see the frame height and using the real one on the paint side alone
would reintroduce exactly the divergence above. On a taller canvas that floor
therefore sits below the legibility threshold, and a declared 120px shrinking
to ~13px on a 2160-tall frame would have passed the legibility check in
silence — the failure mode this feature exists to remove, not relocate.
`check_legibility` now warns in precisely that case, naming both numbers, and
stays quiet at 1080 where the two agree. The precise fix is a canvas-relative
floor on both sides; that needs the frame height plumbed into `TextIntrinsic`
and is tracked separately.1 parent a0fd570 commit 14b7766
7 files changed
Lines changed: 1737 additions & 109 deletions
File tree
- crates
- rustmotion-cli/src/commands
- rustmotion-components
- src
- tests
- rustmotion-core/src/css
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
1 | 2 | | |
| 3 | + | |
2 | 4 | | |
3 | 5 | | |
4 | 6 | | |
| |||
66 | 68 | | |
67 | 69 | | |
68 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
69 | 79 | | |
70 | 80 | | |
71 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
72 | 197 | | |
73 | 198 | | |
74 | 199 | | |
| |||
0 commit comments