浏览代码

Font: Fixed MergeMode adding duplicate glyphs data instead of reusing existing (broken by 072d6d8cb5a8bb66318ae5db7d23b3be74bf5ffe)

omar 7 年之前
父节点
当前提交
1ef1acbd8d
共有 5 个文件被更改,包括 16 次插入3 次删除
  1. 2 1
      CHANGELOG.txt
  2. 4 1
      TODO.txt
  3. 1 0
      imgui.h
  4. 7 1
      imgui_draw.cpp
  5. 2 0
      misc/freetype/imgui_freetype.cpp

+ 2 - 1
CHANGELOG.txt

@@ -268,8 +268,9 @@ Other Changes:
 - NewFrame(): using literal strings in the most-frequently firing IM_ASSERT expressions to increase the odd of programmers seeing them (especially those who don't use a debugger).
 - NewFrame(): using literal strings in the most-frequently firing IM_ASSERT expressions to increase the odd of programmers seeing them (especially those who don't use a debugger).
 - NewFrame() now asserts if neither Render or EndFrame have been called. Exposed EndFrame(). Made it legal to call EndFrame() more than one. (#1423)
 - NewFrame() now asserts if neither Render or EndFrame have been called. Exposed EndFrame(). Made it legal to call EndFrame() more than one. (#1423)
 - ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from stratch.
 - ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from stratch.
-- ImFont: Added GetDebugName() helper. 
+- ImFont: Added GetDebugName() helper.
 - ImFontAtlas: Added missing Thai punctuation in the GetGlyphRangesThai() ranges. (#1396) [@nProtect]
 - ImFontAtlas: Added missing Thai punctuation in the GetGlyphRangesThai() ranges. (#1396) [@nProtect]
+- ImFontAtlas: Fixed cfg.MergeMode not reusing existing glyphs if available (always overwrote).
 - ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags.
 - ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags.
 - ImDrawList: Added ImDrawList::AddImageRounded() helper. (#845) [@thedmd] 
 - ImDrawList: Added ImDrawList::AddImageRounded() helper. (#845) [@thedmd] 
 - ImDrawList: Refactored to make ImDrawList independant of ImGui. Removed static variable in PathArcToFast() which caused linking issues to some.
 - ImDrawList: Refactored to make ImDrawList independant of ImGui. Removed static variable in PathArcToFast() which caused linking issues to some.

+ 4 - 1
TODO.txt

@@ -212,7 +212,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
  - pie menus patterns (#434)
  - pie menus patterns (#434)
  - markup: simple markup language for color change? (#902)
  - markup: simple markup language for color change? (#902)
 
 
- - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered.
+!- font: need handling of missing glyphs by not packing/rasterizing glyph 0 of a given font.
+ - font: MergeMode: flags to select overwriting or not.
+ - font: MergeMode: duplicate glyphs are stored in the atlas texture which is suboptimal.
+ - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered. (#1619)
  - font: free the Alpha buffer if user only requested RGBA.
  - font: free the Alpha buffer if user only requested RGBA.
 !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
 !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
  - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX
  - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX

+ 1 - 0
imgui.h

@@ -1775,6 +1775,7 @@ struct ImFont
     ImFontConfig*               ConfigData;         //              // Pointer within ContainerAtlas->ConfigData
     ImFontConfig*               ConfigData;         //              // Pointer within ContainerAtlas->ConfigData
     ImFontAtlas*                ContainerAtlas;     //              // What we has been loaded into
     ImFontAtlas*                ContainerAtlas;     //              // What we has been loaded into
     float                       Ascent, Descent;    //              // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
     float                       Ascent, Descent;    //              // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
+    bool                        DirtyLookupTables;
     int                         MetricsTotalSurface;//              // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
     int                         MetricsTotalSurface;//              // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
 
 
     // Methods
     // Methods

+ 7 - 1
imgui_draw.cpp

@@ -1817,6 +1817,8 @@ bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
         ImFontConfig& cfg = atlas->ConfigData[input_i];
         ImFontConfig& cfg = atlas->ConfigData[input_i];
         ImFontTempBuildData& tmp = tmp_array[input_i];
         ImFontTempBuildData& tmp = tmp_array[input_i];
         ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
         ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
+        if (cfg.MergeMode)
+            dst_font->BuildLookupTable();
 
 
         const float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels);
         const float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels);
         int unscaled_ascent, unscaled_descent, unscaled_line_gap;
         int unscaled_ascent, unscaled_descent, unscaled_line_gap;
@@ -1960,7 +1962,8 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
 
 
     // Build all fonts lookup tables
     // Build all fonts lookup tables
     for (int i = 0; i < atlas->Fonts.Size; i++)
     for (int i = 0; i < atlas->Fonts.Size; i++)
-        atlas->Fonts[i]->BuildLookupTable();
+        if (atlas->Fonts[i]->DirtyLookupTables)
+            atlas->Fonts[i]->BuildLookupTable();
 }
 }
 
 
 // Retrieve list of range (2 int per range, values are inclusive)
 // Retrieve list of range (2 int per range, values are inclusive)
@@ -2165,6 +2168,7 @@ void    ImFont::ClearOutputData()
     ConfigData = NULL;
     ConfigData = NULL;
     ContainerAtlas = NULL;
     ContainerAtlas = NULL;
     Ascent = Descent = 0.0f;
     Ascent = Descent = 0.0f;
+    DirtyLookupTables = true;
     MetricsTotalSurface = 0;
     MetricsTotalSurface = 0;
 }
 }
 
 
@@ -2177,6 +2181,7 @@ void ImFont::BuildLookupTable()
     IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved
     IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved
     IndexAdvanceX.clear();
     IndexAdvanceX.clear();
     IndexLookup.clear();
     IndexLookup.clear();
+    DirtyLookupTables = false;
     GrowIndex(max_codepoint + 1);
     GrowIndex(max_codepoint + 1);
     for (int i = 0; i < Glyphs.Size; i++)
     for (int i = 0; i < Glyphs.Size; i++)
     {
     {
@@ -2241,6 +2246,7 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1,
         glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f);
         glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f);
     
     
     // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
     // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
+    DirtyLookupTables = true;
     MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f);
     MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f);
 }
 }
 
 

+ 2 - 0
misc/freetype/imgui_freetype.cpp

@@ -315,6 +315,8 @@ bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
         ImFontConfig& cfg = atlas->ConfigData[input_i];
         ImFontConfig& cfg = atlas->ConfigData[input_i];
         FreeTypeFont& font_face = fonts[input_i];
         FreeTypeFont& font_face = fonts[input_i];
         ImFont* dst_font = cfg.DstFont;
         ImFont* dst_font = cfg.DstFont;
+        if (cfg.MergeMode)
+            dst_font->BuildLookupTable();
 
 
         const float ascent = font_face.Info.Ascender;
         const float ascent = font_face.Info.Ascender;
         const float descent = font_face.Info.Descender;
         const float descent = font_face.Info.Descender;