6.1.3 - Teletext row padding
A rendering fix on the DVB teletext path, plus a build-level pin change that affects how released tags resolve. Anyone showing live teletext captions wants this one.
Fixed
-
Teletext rows no longer arrive with their column padding still on them. A two-row caption reached the host as
row one<pad>/<pad>row two, so a renderer that centres each line put the second row visibly off centre and drew the cue's background box wider than its text. Reported by tresby, who had solved it row-wise in a proxy implementation and supplied the failing sequence (#233).The padding is the grid. On a page libzvbi does not classify as a subtitle page,
gen_sub_asswrites every row at full column width (decode_string(page, row, &buf, 0, page->columns, ...), one\hper grid cell) and appends" \N"after it. Two whitespace passes existed and neither reached the inside of a line break:edgeTrimmedtrims the leading and trailing edge of the whole run sequence, so the first row's leading pad and the last row's trailing pad only, andcollapseInteriorBlankLinesfolds what sits between two newlines, dropping nothing against a single retained one and never looking at the characters before one at all.trimGridRowsnow takes the padding off both ends of every row. Like the fold it works on the flattened character sequence and re-splits along the original run boundaries, because a row's pad carries the spacing attribute that changes colour and therefore lands in a whitespace-only run of its own, which a per-run walk steps right over.The pass is gated, and the blank-line fold moved behind the same gate. Both only correct a raw grid dump, which is exactly the page that arrives without an
\an:gen_sub_assemits{\anN}on the first row of a flagged page that holds any character, and a flagged page holding none produces no cue at all, so an arriving alignment and a curated body are equivalent. On a curated page both of the things these passes remove are decisions rather than noise. Theempty_lines / 2fillers are its vertical fine-positioning inside the block, and the residual padding is the relative indentation that carries the horizontal alignment it picked (leading = min_leadingfor left,trailing = min_trailingfor right, both for its non-centrable centre case). A curated body is now passed through whole, including through that fold, which had been discarding those fillers since #107.Not taken, though the trim does make it measurable: deriving the horizontal anchor the way
can_align_left/_right/_centerdo. Where that analysis leaves more than one of the three viable it resolves the tie fromlast_ass_alignment, the answer given to the previous cue. A stateless parser has to fall back to centre there, so an unambiguous left-aligned cue followed by an ambiguous one would jump, which is the same blink the vertical derivation already refuses.
Changed
- FFmpegBuild and LibDovi are pinned to the minor rather than floating from a lower bound, so a released tag's dependency set is a property of the tag instead of the registry at resolve time. Both classes of drift were live this week: LibDovi 1.1.0 raised its declared tvOS floor in a minor, which SwiftPM floats onto and then fails on instead of backing off to a version that fits, so every 5.x tag stopped resolving; and FFmpegBuild 2.4.0 replaced 2.3.0 under a fixed 5.28.0 checkout, harmless in that instance but not by design. Forward-looking only, already published tags keep whatever they declared.
Upgrading
.package(url: "https://github.com/superuser404notfound/AetherEngine", from: "6.1.3")No API change and no source change for consumers. Resolution is unchanged too: the pin change lands on FFmpegBuild 2.4.0 and LibDovi 2.0.0, the same versions a from: bound resolved to.