SubtitleRasterizer
Turns active text cues into the positioned images a renderer composites.
This is a platform seam for one reason: text needs a font engine, and the engine has none. Each platform's output backend supplies its own (StaticLayout on Android, CoreText on Apple) behind this one interface, and the ENGINE decides when to call it: on cue-set changes and viewport changes, never per frame, because cues change about once a second and frames sixty times a second.
The viewportWidth and viewportHeight of rasterize are the size of the area the engine lays text out in: the renderer's output, less the safe area the application set. The engine moves the images into output pixels afterwards, and a renderer composites them over its whole output, never over the picture alone. docs/subtitle-placement.md has the whole rule.
Bitmap cues arrive pre-rendered and are POSITIONED, not scaled: an overlay image carries an origin and its pixels, and no implementation resizes them. Giving a bitmap cue a target rectangle would be a public model change, so it is a decision to take deliberately rather than a promise this interface can quietly make.
Every implementation keeps to the limits in the companion object. The built-in ones draw nothing for a viewport larger than MAX_VIEWPORT_SIZE on a side, lay out only what limitCues keeps, and throw SubtitleOverlayLimitException rather than let their images pass overlayPixelBudget. The engine applies the same limits to any implementation, so a custom one gets only what limitCues keeps.
Types
The limits of one overlay. Cues past them are not drawn, and the engine warns once with io.github.yuroyami.kiteplayer.PlaybackWarning.SubtitlesNotDrawn. Ordinary subtitles stay far below every limit.