From 0be4f66d89a1130c04262844dcbef600e91dcb88 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 16 Aug 2017 18:56:26 +0800 Subject: [PATCH] ImFontAtlas: Shuffling some code inside Build() to make upcoming diffs less confusing (nb: we might break compat with forks of Build() like #618) --- TODO.txt | 1 + imgui_draw.cpp | 60 +++++++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/TODO.txt b/TODO.txt index 61d9e048..5f70cc96 100644 --- a/TODO.txt +++ b/TODO.txt @@ -24,6 +24,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd. - window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon? - window: expose contents size. (#1045) + - window: GetWindowSize() returns (0,0) when not calculated? (#1045) !- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet. - scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 6e94cfb6..2c6d88e5 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1034,7 +1034,7 @@ void ImDrawData::ScaleClipRects(const ImVec2& scale) } //----------------------------------------------------------------------------- -// ImFontAtlas +// ImFontConfig //----------------------------------------------------------------------------- ImFontConfig::ImFontConfig() @@ -1055,6 +1055,10 @@ ImFontConfig::ImFontConfig() memset(Name, 0, sizeof(Name)); } +//----------------------------------------------------------------------------- +// ImFontAtlas +//----------------------------------------------------------------------------- + ImFontAtlas::ImFontAtlas() { TexID = NULL; @@ -1282,40 +1286,19 @@ bool ImFontAtlas::Build() TexUvWhitePixel = ImVec2(0, 0); ClearTexData(); - struct ImFontTempBuildData - { - stbtt_fontinfo FontInfo; - stbrp_rect* Rects; - stbtt_pack_range* Ranges; - int RangesCount; - }; - ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)ConfigData.Size * sizeof(ImFontTempBuildData)); - - // Initialize font information early (so we can error without any cleanup) + count glyphs + // Count glyphs/ranges int total_glyph_count = 0; int total_glyph_range_count = 0; for (int input_i = 0; input_i < ConfigData.Size; input_i++) { ImFontConfig& cfg = ConfigData[input_i]; - ImFontTempBuildData& tmp = tmp_array[input_i]; - - IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == this)); - const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); - IM_ASSERT(font_offset >= 0); - if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) - return false; - - // Count glyphs if (!cfg.GlyphRanges) cfg.GlyphRanges = GetGlyphRangesDefault(); - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) - { + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_glyph_range_count++) total_glyph_count += (in_range[1] - in_range[0]) + 1; - total_glyph_range_count++; - } } - // Start packing. We need a known width for the skyline algorithm. Using a cheap heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. + // Start packing. We need a known width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. // After packing is done, width shouldn't matter much, but some API/GPU have texture size limitations and increasing width can decrease height. TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyph_count > 4000) ? 4096 : (total_glyph_count > 2000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; TexHeight = 0; @@ -1332,6 +1315,26 @@ bool ImFontAtlas::Build() if (extra_rects[i].was_packed) TexHeight = ImMax(TexHeight, extra_rects[i].y + extra_rects[i].h); + // Initialize font information (so we can error without any cleanup) + struct ImFontTempBuildData + { + stbtt_fontinfo FontInfo; + stbrp_rect* Rects; + stbtt_pack_range* Ranges; + int RangesCount; + }; + ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)ConfigData.Size * sizeof(ImFontTempBuildData)); + for (int input_i = 0; input_i < ConfigData.Size; input_i++) + { + ImFontConfig& cfg = ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == this)); + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); + IM_ASSERT(font_offset >= 0); + if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + return false; + } + // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); @@ -1350,11 +1353,8 @@ bool ImFontAtlas::Build() // Setup ranges int glyph_count = 0; int glyph_ranges_count = 0; - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2) - { + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, glyph_ranges_count++) glyph_count += (in_range[1] - in_range[0]) + 1; - glyph_ranges_count++; - } tmp.Ranges = buf_ranges + buf_ranges_n; tmp.RangesCount = glyph_ranges_count; buf_ranges_n += glyph_ranges_count; @@ -1392,7 +1392,7 @@ bool ImFontAtlas::Build() spc.pixels = TexPixelsAlpha8; spc.height = TexHeight; - // Second pass: render characters + // Second pass: render font characters for (int input_i = 0; input_i < ConfigData.Size; input_i++) { ImFontConfig& cfg = ConfigData[input_i];