Dummy glyphs in font atlas #1703

Closed
opened 2018-03-27 09:12:21 +00:00 by r-lyeh · 7 comments
r-lyeh commented 2018-03-27 09:12:21 +00:00 (Migrated from github.com)

Hello omar,

image

I've found about a few thousand dummy glyphs in my font atlas when loading a CJK font.
See attached pic.

Is there a quick way to detect them and prevent them included in the final font atlas?
I would rather like a '?'/unused glyph in those dummy boxes instead :)

Ty!

PS: ImGui 1.60 beta

Hello omar, ![image](https://user-images.githubusercontent.com/35402248/37957909-5fee5370-31af-11e8-941d-5b524576ef54.png) I've found about a few thousand dummy glyphs in my font atlas when loading a CJK font. See attached pic. Is there a quick way to detect them and prevent them included in the final font atlas? I would rather like a '?'/unused glyph in those dummy boxes instead :) Ty! PS: ImGui 1.60 beta
ocornut commented 2018-03-27 09:56:02 +00:00 (Migrated from github.com)

Hello,
Yes this indeed an issue with the current code. Will tackle it shortly. This is essentially waiting for the same solution as #1671.
The stbtt_PackFontRangesGatherRects() call in stb_truetype don't check for missing glyph which ends up rendering the first glyph of the font, we need to refactor a bit of the font building function.

Hello, Yes this indeed an issue with the current code. Will tackle it shortly. This is essentially waiting for the same solution as #1671. The `stbtt_PackFontRangesGatherRects()` call in stb_truetype don't check for missing glyph which ends up rendering the first glyph of the font, we need to refactor a bit of the font building function.
r-lyeh commented 2018-03-27 10:46:10 +00:00 (Migrated from github.com)

Aha great! Ty for pointing that out.
I'll leave the issue open for you as a reminder.
For now, and as a workaround, I've just discarded glyph as well, only if both dummy_x and dummy_y are 0.

Aha great! Ty for pointing that out. I'll leave the issue open for you as a reminder. For now, and as a workaround, I've just discarded glyph as well, only if both dummy_x and dummy_y are 0.
r-lyeh commented 2018-03-27 10:57:23 +00:00 (Migrated from github.com)

2nd try: I've just tweaked stb_truetype to forbid baking of missing glyphs. Feels hacky but texture atlas fits nicely!

image

2nd try: I've just tweaked stb_truetype to forbid baking of missing glyphs. Feels hacky but texture atlas fits nicely! ![image](https://user-images.githubusercontent.com/35402248/37963563-f359f6a0-31be-11e8-8ddd-c3f6f2c0bdcb.png)
r-lyeh commented 2018-03-27 10:58:30 +00:00 (Migrated from github.com)
diff --git a/source/editor/3rd/@ocornut/imgui_draw.cpp b/source/editor/3rd/@ocornut/imgui_draw.cpp
index a2d0215..090fd24 100644
--- a/source/editor/3rd/@ocornut/imgui_draw.cpp
+++ b/source/editor/3rd/@ocornut/imgui_draw.cpp
@@ -1780,7 +1780,7 @@ bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
         buf_rects_n += font_glyphs_count;
         stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV);
         int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects);
-        IM_ASSERT(n == font_glyphs_count);
+        font_glyphs_count = n; // IM_ASSERT(n == font_glyphs_count);
         stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n);

         // Extend texture height
@@ -1858,6 +1858,7 @@ bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
                 stbtt_aligned_quad q;
                 float dummy_x = 0.0f, dummy_y = 0.0f;
                 stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0);
+                //if( dummy_x != 0 ) // @r-lyeh: see https://github.com/ocornut/imgui/issues/1671
                 dst_font->AddGlyph((ImWchar)codepoint, q.x0 + off_x, q.y0 + off_y, q.x1 + off_x, q.y1 + off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance);
             }
         }
diff --git a/source/editor/3rd/@ocornut/stb_truetype.h b/source/editor/3rd/@ocornut/stb_truetype.h
index f65deb5..7ab78ff 100644
--- a/source/editor/3rd/@ocornut/stb_truetype.h
+++ b/source/editor/3rd/@ocornut/stb_truetype.h
@@ -3645,6 +3645,7 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset,  // fo
    for (i=0; i < num_chars; ++i) {
       int advance, lsb, x0,y0,x1,y1,gw,gh;
       int g = stbtt_FindGlyphIndex(&f, first_char + i);
+      if(!g) continue; //@r-lyeh
       stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
       stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
       gw = x1-x0;
@@ -3968,6 +3969,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
          int x0,y0,x1,y1;
          int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
          int glyph = stbtt_FindGlyphIndex(info, codepoint);
+         if(!glyph) continue; //@r-lyeh
          stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
                                          scale * spc->h_oversample,
                                          scale * spc->v_oversample,
@@ -4032,6 +4034,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
             int advance, lsb, x0,y0,x1,y1;
             int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
             int glyph = stbtt_FindGlyphIndex(info, codepoint);
+            if(!glyph) continue; //@r-lyeh
             stbrp_coord pad = (stbrp_coord) spc->padding;
``` diff --git a/source/editor/3rd/@ocornut/imgui_draw.cpp b/source/editor/3rd/@ocornut/imgui_draw.cpp index a2d0215..090fd24 100644 --- a/source/editor/3rd/@ocornut/imgui_draw.cpp +++ b/source/editor/3rd/@ocornut/imgui_draw.cpp @@ -1780,7 +1780,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) buf_rects_n += font_glyphs_count; stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); - IM_ASSERT(n == font_glyphs_count); + font_glyphs_count = n; // IM_ASSERT(n == font_glyphs_count); stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n); // Extend texture height @@ -1858,6 +1858,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) stbtt_aligned_quad q; float dummy_x = 0.0f, dummy_y = 0.0f; stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); + //if( dummy_x != 0 ) // @r-lyeh: see https://github.com/ocornut/imgui/issues/1671 dst_font->AddGlyph((ImWchar)codepoint, q.x0 + off_x, q.y0 + off_y, q.x1 + off_x, q.y1 + off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance); } } diff --git a/source/editor/3rd/@ocornut/stb_truetype.h b/source/editor/3rd/@ocornut/stb_truetype.h index f65deb5..7ab78ff 100644 --- a/source/editor/3rd/@ocornut/stb_truetype.h +++ b/source/editor/3rd/@ocornut/stb_truetype.h @@ -3645,6 +3645,7 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // fo for (i=0; i < num_chars; ++i) { int advance, lsb, x0,y0,x1,y1,gw,gh; int g = stbtt_FindGlyphIndex(&f, first_char + i); + if(!g) continue; //@r-lyeh stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); gw = x1-x0; @@ -3968,6 +3969,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb int x0,y0,x1,y1; int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; int glyph = stbtt_FindGlyphIndex(info, codepoint); + if(!glyph) continue; //@r-lyeh stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, scale * spc->h_oversample, scale * spc->v_oversample, @@ -4032,6 +4034,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const int advance, lsb, x0,y0,x1,y1; int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; int glyph = stbtt_FindGlyphIndex(info, codepoint); + if(!glyph) continue; //@r-lyeh stbrp_coord pad = (stbrp_coord) spc->padding; ```
ocornut commented 2018-05-07 16:08:50 +00:00 (Migrated from github.com)

@r-lyeh This should be fixed in master now, could you confirm it does what you want with your font?

(Note that it was a minor bug that the Demo displayed ? at all here, the greyed out rectangles were meant to be left empty)

I submitted my modification to nothings/stb, I'm not sure it'll be merged as is (perhaps as an option to the packer) but either way I'll follow on that and hopefully the next version of stb_truetype will match our mod.

@r-lyeh This should be fixed in master now, could you confirm it does what you want with your font? (Note that it was a minor bug that the Demo displayed ? at all here, the greyed out rectangles were meant to be left empty) I submitted my modification to nothings/stb, I'm not sure it'll be merged as is (perhaps as an option to the packer) but either way I'll follow on that and hopefully the next version of stb_truetype will match our mod.
r-lyeh commented 2018-05-08 11:05:24 +00:00 (Migrated from github.com)

Cool. I'll let you know!

Cool. I'll let you know!
r-lyeh commented 2018-05-08 12:00:57 +00:00 (Migrated from github.com)

No problems found :)

No problems found :)
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ocornut/imgui#1703
No description provided.