#9483

FreeType: Fix CBDT/COLR bitmap color emoji font loading (#6302)

OpenTurtle-PBwants to merge intofrom

Problem

Issue #6302: NotoColorEmoji and other CBDT/COLR bitmap color emoji fonts fail to load in ImGui's FreeType backend. Glyphs render as empty boxes because FT_Request_Size() returns 0x0 dimensions for non-scalable bitmap fonts.

Root cause: CBDT fonts (NotoColorEmoji, Twemoji COLR, etc.) are not scalable (FT_IS_SCALABLE(face) is false). They contain pre-rendered bitmap strikes at fixed sizes. FT_Request_Size() fails because it tries to scale an unscalable outline.

Fix

Detect CBDT table via FT_Load_Sfnt_Table(). When present:

  • Use FT_Select_Size() to pick the closest available bitmap strike size
  • Set FT_LOAD_COLOR flag for color glyph rendering

Falls back to standard FT_Request_Size() path for scalable fonts (no behavioral change).

Implementation

Based on solution proposed by @sakiodre in issue #6302:

// Detect CBDT/COLR bitmap fonts
FT_ULong cbdt_tag = FT_MAKE_TAG('C', 'B', 'D', 'T');
FT_ULong cbdt_length = 0;
FT_Error cbdt_err = FT_Load_Sfnt_Table(face, cbdt_tag, 0, nullptr, &cbdt_length);
bool is_cbdt_font = (cbdt_err == 0 && cbdt_length > 0);

if (is_cbdt_font && face->num_fixed_sizes > 0)
{
    // Select closest bitmap strike
    FT_Select_Size(face, best_match);
    LoadFlags |= FT_LOAD_COLOR;
}

Testing

  • NotoColorEmoji_WindowsCompatible.ttf now loads and renders correctly
  • Twemoji COLR v0.7.0 (Mozilla) also works
  • Scalable fonts (TTF/OTF) unaffected — same code path as before
  • No new dependencies

References