Hi,

drawtext currently cannot render color-bitmap emoji fonts such as Noto
Color Emoji: glyphs are loaded without FT_LOAD_COLOR, so CBDT/CBLC faces
present their glyphs as monochrome bitmaps and rendering fails with
"Monocromatic (1bpp) fonts are not supported".

The attached patch (git format-patch against master c231236) loads
glyphs with FT_LOAD_COLOR when the face has color (falling back to the
regular glyph when the color glyph cannot be rasterized, e.g. OT-SVG),
and blends the premultiplied-BGRA glyphs through a new drawutils
function, ff_blend_color_bitmap(): per destination sample - including
each chroma sample at its subsampled resolution - it accumulates
coverage-weighted contributions of all source pixels mapping to it and
composites in a single blend, so subsampled YUV output is exact and
order-independent; frame-edge truncated blocks are weighted by their
real pixel count. Straight-alpha targets get exact source-over with the
destination alpha accumulated per full-resolution position (correct even
when coverage and destination alpha vary together inside a chroma
block); premultiplied and alphaless targets blend directly. Shadows are
drawn from the glyph alpha channel, the stroker border pass skips color
glyphs, and bitmap-only faces select the fixed strike nearest the
requested fontsize.

Verification highlights (worst-case absolute differences, 8-bit code
values): yuv420p at an odd origin vs a reference from the rgba render
(BT.601 + 2x2 chroma box filter): Y max 1.04, U max 0.93, V max 0.93,
no sample off by more than 2; odd-sized (641x361) frame: Y max 0.78,
U max 0.88, V max 0.87. Straight-alpha rgba over transparent:
destination alpha exact, color max 1.00 above 0.45 coverage; over a
50%-alpha background: alpha max 0.36, color max 1.38. A yuva420p frame
whose alpha checkerboards inside every chroma block vs the per-pixel
source-over reference: Y max 0.86, A max 0.48, U/V max 3.2, with 1 of
4625 glyph-covered blocks above 3 per plane. A premultiplied-tagged
frame receives exactly the premultiplied composite over transparent
and is byte-identical to the straight-tagged render over opaque.
framemd5 of DejaVuSans (border+shadow) and of the COLR faces Nabla and
Noto-COLRv1 are bit-identical before/after; the full test set is clean
under an ASan+UBSan build. Requires FreeType >= 2.5.1; the color path
compiles out on older builds.

Prior art: Yogeshwar Velingker's March 2025 patch addressed monochrome
bitmaps but not color glyphs and was not merged; this patch is
self-contained.

Notes for review: bitmap strikes are not scaled (nearest strike +
warning); no stroker border on color glyphs; the new blend uses plain
rounding division for clarity and can be converted to the fixed-point
style of the neighbouring code if preferred. The patch is attached
rather than inlined; happy to resend inline via git send-email if that
is preferred.

Thanks,
George

Attachment: 0001-avfilter-vf_drawtext-support-color-bitmap-CBDT-emoji.patch
Description: Binary data

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to