My Caption Width Guard Passed Every Test. It Was Measuring Text the Renderer Never Drew.

2026年8月24日2 次浏览来源:Dev.to阅读原文

Originally published on hexisteme notes.

A user complaint sent me into a caption pipeline: "the subtitles cut to two words in places where the sentence doesn't make sense." The fix I shipped for that complaint introduced a second bug, one word narrower and easy to miss, because the code that measured whether a line of text would fit reproduced an assumption about the text that the code drawing the line didn't share.

Every test passed the whole time.

I only found it by watching the rendered video.

The bug the complaint pointed at The captioning system splits a transcript into short chunks that pop onto screen a few words at a time.

The chunking function was doing fixed-size slicing — take the next N words, regardless of what came before or after.

That's blind to sentence boundaries, so two unrelated sentences could land in the same chunk: reads as one visual unit even though it's the tail of one sentence and the head of the next.

The fix was a rule set, not a single tweak: hard break after terminal punctuation () soft break at commas, semicolons, and em-dashes extend or push a chunk rather than let it end on a function word (, , , , and about thirty others) target three words per chunk, four as a ceiling a pixel-width cap on the rendered chunk, measured against the actual caption font (Montserrat ExtraBold), with a budget of 1080 × 0.92 = 993.6px The first four rules are about where a line is allowed to break.

The fifth is a physical constraint: however good the break points are, a chunk still has to fit on screen at the font size actually in use.

That's the one that went wrong.

What the width guard actually measured To get the pixel width of a candidate chunk, the guard rendered the chunk's text through the font and measured the result — which is the correct approach in principle, not a shortcut.

Text width isn't a fixed number of pixels per character; it depends on the specific glyphs, so measuring the real string through the real font is the only way to get an honest number.

The chunk text going into that measurement, though, was uppercased first.

Elsewhere in the same video pipeline, an unrelated overlay — hook text shown at the very start of a clip — is deliberately rendered in all caps for a different visual style, and the width-measurement code for the caption line borrowed that same uppercasing step.

It reads like a defensible move if you don't check it against what's actually drawn: uppercase glyphs in this font run wider than mixed case, so measuring in uppercase gives you a safety margin — worst case, real width can only come in narrower than what you measured, never wider.

Except the caption itself is never rendered in uppercase.

The word-pop captions on screen keep the original sentence casing.

The margin wasn't a safety margin against a real risk; it was padding for a risk that doesn't exist in this code path, and the padding was large enough to distort the outcome.

The measurement was accurate.

The input was wrong.

Take a concrete chunk: "rich with nitrates." Rendered as written, mixed case, it measures 842px.

Rendered uppercase — the string the guard actually checked — it measures 1042px, about 20% wider.

The budget is 993.6px.

The real string clears the budget with room to spare.

The string the guard tested against does not.

So the guard did its job on the input it was given, and the input was wrong.

Chunks like "rich" and "with nitrates." got forced apart into one-word fragments to satisfy a width limit that the actual on-screen text was never close to violating.

That's a regression relative to the bug this whole rule set was supposed to fix — a one-word chunk is a more broken reading experience than the original two-sentences-in-one-chunk problem, just distributed differently across the caption track.

It's worth being precise about what was and wasn't broken here, because it would be easy to walk away distrusting the measurement machinery itself.

I checked that separately: the library's text-path measurement

分享
Baike.dev

baike.dev helps you discover great languages, frameworks, databases, DevOps and cloud-native tools.

Quick links

About

Contribute

Found a great developer tool? Share it with the community.

Submit a tool
© 2026 baike.dev Developer EncyclopediaUpdated daily · Discover great developer tools