Skip to content

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

Open
Turtle-PB wants to merge 1 commit into
ocornut:masterfrom
Turtle-PB:fix/freetype-cbdt-color-emoji
Open

FreeType: Fix CBDT/COLR bitmap color emoji font loading (#6302)#9483
Turtle-PB wants to merge 1 commit into
ocornut:masterfrom
Turtle-PB:fix/freetype-cbdt-color-emoji

Conversation

@Turtle-PB

Copy link
Copy Markdown
Contributor

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

CBDT fonts (NotoColorEmoji, Twemoji COLR) are not scalable — FT_Request_Size()
returns 0x0 glyphs because the font has no scalable outline.

Fix: Detect CBDT table via FT_Load_Sfnt_Table(). When present:
- Use FT_Select_Size() to pick the closest bitmap strike size
- Set FT_LOAD_COLOR flag for color glyph rendering

Based on solution by @sakiodre in issue ocornut#6302.
Tested with NotoColorEmoji_WindowsCompatible.ttf and Twemoji COLR v0.7.0.
Turtle-PB added a commit to Turtle-PB/imgui_xl that referenced this pull request Jul 20, 2026
Turtle-PB added a commit to Turtle-PB/imgui_xl that referenced this pull request Jul 20, 2026
- Hero badges: '3 PRs merged' + '3 PRs open' + 'Audio + MIDI + GUI Builder'
- Stats: 6 upstream PRs, 3 merged, 12 widget types, 2 royalty-free tracks
- PR list: All 6 PRs with correct status dots (merged=purple, open=green)
  - ocornut#9467 Android CI (merged)
  - ocornut#9473 OpenGL GL_UNPACK (merged)
  - ocornut#9474 Android touch + SDL2 (merged)
  - ocornut#9481 Texture destroy deferral (open)
  - ocornut#9483 CBDT/COLR emoji fonts (open)
  - ocornut#9469 Android backend + pressure (open)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants