- New L1 crate filmcraft-text: fonts (bundled Inter Regular/Medium/SemiBold/Bold/Italic, JetBrains Mono, Noto Serif; DirectorySource scans system font folders reading only name/OS2 tables; family/style resolution with synthetic bold/italic; per-char fallback), layout (harfrust kerning/ligatures, unicode-bidi, unicode-linebreak, alignment incl. justify, leading, tracking, baseline shift, all/small caps, underline, carets/hit-test/selection, cached), raster (moved from captions; active-edge list, shapes, emboldening), render (outline + sub-pixel glyph-mask caches; transformed-outline path for rotation/skew), mask (distance-transform strokes, blur). - Captions burn-in now shapes and kerns via the engine (font.rs/raster.rs removed). - Timecode / Clip Name effects draw real text (full clip names, not seven-segment digits); text_burnin golden re-blessed. - UI takes its font bytes from the text crate (no duplicate copies in the binary). - New fonts: Inter Bold, Inter Italic (OFL-1.1, rsms/inter v4.1), Noto Serif Regular (OFL-1.1, notofonts) with sidecars, ATTRIBUTION.md rows and licence text. - Perf: 3-line 96 px title at 1080p ~1.6 ms cold / 0.15 ms warm (release). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
filmcraft-captions
Caption files and caption burn-in for FilmCraft (layer L2: depends on filmcraft-time,
filmcraft-color, filmcraft-project and filmcraft-text).
The caption model (caption tracks in a sequence, captions, track style) lives in
filmcraft-project (caption.rs) because it is part of the .fcproj document. This crate reads
and writes caption files, converts them to and from caption tracks, and draws captions.
Formats
| Format | Read | Write | Notes |
|---|---|---|---|
SubRip .srt |
yes | yes | BOM, UTF-16, Windows-1252 fallback, CRLF/CR, missing or wrong indexes, , or . milliseconds, 1–9 fraction digits, missing hours, SSA coordinates, cues not separated by blank lines. Inline tags are kept as text. |
WebVTT .vtt |
yes | yes | Cue identifiers, cue settings (verbatim), a leading <v Speaker> voice span (as the caption's speaker) and STYLE / REGION / NOTE blocks are kept. A missing WEBVTT signature is tolerated. |
Scenarist SCC .scc |
yes | yes | CEA-608 at 29.97 fps, drop-frame or not. Reads pop-on, roll-up and paint-on (channel 1); writes pop-on. |
All cue times are exact Ticks. Milliseconds convert exactly (1 ms = 254 016 000 ticks); SCC
frames map through FrameRate::FPS_29_97. Document::snap_to_frames snaps cues to a sequence's
frame grid (the engine does this on import) and removes overlaps.
SCC writer
Each caption is sent as a pop-on load (RCL, ENM, then per row a preamble address code and tab offset for centring, then text; control codes doubled) into non-displayed memory, followed by End Of Caption exactly on the caption's first frame. The load is placed in the latest run of free frames before the caption, so back-to-back captions load while the previous one is on screen. An Erase Displayed Memory clears the caption at its out point unless the next caption replaces it. Text is wrapped at 32 columns, bottom-aligned (last row 15) and centred. Characters come from the 608 basic, special and extended sets (extended characters are preceded by a basic fallback character, as the standard requires); others are dropped. If there is no room to load a caption before its in point (for example a caption at 00:00:00:00), it appears as soon as it is loaded.
Burn-in
burn::render_caption lays out a caption with the track style (font size relative to a 1080-line
frame, colour, background box, outline, alignment, top/middle/bottom anchor and margin; WebVTT
line:N% and align: settings override them), wraps lines to 90% of the frame width and
rasterises it to a small premultiplied linear-light RGBA overlay. filmcraft-render composites the
overlays of visible caption tracks over the finished frame (Program monitor and export burn-in).
Text is set in Inter SemiBold (assets/fonts/Inter-SemiBold.ttf, SIL OFL 1.1, attributed in
ATTRIBUTION.md) by the filmcraft-text engine: shaped with kerning and ligatures, bidi-ordered,
and drawn from its sub-pixel positioned glyph cache.
Tests
- Unit tests per module (timestamps, decoding, sloppy SRT, WebVTT blocks and voices, CEA-608 tables, PAC round trips, known SCC pop-on and roll-up streams, layout).
tests/roundtrip.rs: property tests — SRT (also with BOM + CRLF), WebVTT (ids, speakers, settings, STYLE blocks) and SCC (drop-frame and non-drop, gaps and back-to-back captions) round-trip exactly; readers never panic on random bytes; SRT → VTT → SCC keeps text and frames.