Face::has_char counted any non-zero cmap entry as coverage. Some fonts map
whole scripts to empty glyphs (a decorative Latin font installed on a Linux
machine maps あ, 水, ア and 。 to glyphs with no contours), so once such a
face was loaded, fallback_for could pick it and Japanese text rendered as
nothing; cjk_falls_back_to_a_system_family failed whenever another test had
loaded that face first.
has_char (and file_covers, used for faces not yet loaded) now also require
the glyph to draw something: an outline with at least one segment, a colour
glyph, or a bitmap in any strike. Characters that are blank by nature
(whitespace, and the default-ignorable code points such as soft hyphen,
joiners and variation selectors) still count as covered by any mapping.
Face::glyph is unchanged, so shaping with the chosen face is as before.
Test: an_empty_glyph_does_not_cover_its_character builds a minimal TrueType
font in code (no font file added to the repo) mapping U+E000 to an empty
glyph and U+E001 to a triangle, and checks has_char and fallback_for.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3vVft4VXvvy8SpbbUceTW