From 0ffd99d3193854547e24c68b1b1fe18c09949d2a Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 6 Mar 2015 19:17:20 +0000 Subject: [PATCH] Font: fix for fallback character width. --- imgui.cpp | 29 +++++++++++++++++++++-------- imgui.h | 6 ++++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a75e0035c..9397e7940 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3194,8 +3194,6 @@ static void SetFont(ImFont* font) g.Font = font; g.FontSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel; - g.Font->FallbackGlyph = NULL; - g.Font->FallbackGlyph = g.Font->FindGlyph(g.Font->FallbackChar); } void ImGui::PushFont(ImFont* font) @@ -7459,9 +7457,10 @@ void ImFont::Clear() DisplayOffset = ImVec2(-0.5f, 0.5f); ContainerAtlas = NULL; Glyphs.clear(); + FallbackGlyph = NULL; + FallbackXAdvance = 0.0f; IndexXAdvance.clear(); IndexLookup.clear(); - FallbackGlyph = NULL; } // Retrieve list of range (2 int per range, values are inclusive) @@ -7563,7 +7562,7 @@ void ImFont::BuildLookupTable() IndexLookup.resize((size_t)max_codepoint + 1); for (size_t i = 0; i < (size_t)max_codepoint + 1; i++) { - IndexXAdvance[i] = 0.0f; + IndexXAdvance[i] = -1.0f; IndexLookup[i] = -1; } for (size_t i = 0; i < Glyphs.size(); i++) @@ -7577,7 +7576,8 @@ void ImFont::BuildLookupTable() // FIXME: Needs proper TAB handling but it needs to be contextualized (can arbitrary say that each string starts at "column 0" if (FindGlyph((unsigned short)' ')) { - Glyphs.resize(Glyphs.size() + 1); + if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times + Glyphs.resize(Glyphs.size() + 1); ImFont::Glyph& tab_glyph = Glyphs.back(); tab_glyph = *FindGlyph((unsigned short)' '); tab_glyph.Codepoint = '\t'; @@ -7585,6 +7585,19 @@ void ImFont::BuildLookupTable() IndexXAdvance[(size_t)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; IndexLookup[(size_t)tab_glyph.Codepoint] = (int)(Glyphs.size()-1); } + + FallbackGlyph = NULL; + FallbackGlyph = FindGlyph(FallbackChar); + FallbackXAdvance = FallbackGlyph ? FallbackGlyph->XAdvance : 0.0f; + for (size_t i = 0; i < (size_t)max_codepoint + 1; i++) + if (IndexXAdvance[i] < 0.0f) + IndexXAdvance[i] = FallbackXAdvance; +} + +void ImFont::SetFallbackChar(ImWchar c) +{ + FallbackChar = c; + BuildLookupTable(); } const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const @@ -7796,7 +7809,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c continue; } - const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : 0.0f; + const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; if (ImCharIsSpace(c)) { if (inside_word) @@ -7900,7 +7913,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons continue; } - const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : 0.0f; + const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; if (line_width + char_width >= max_width) break; @@ -7944,7 +7957,7 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be continue; } - const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : 0.0f; + const float char_width = ((size_t)c < IndexXAdvance.size()) ? IndexXAdvance[(size_t)c] * scale : FallbackXAdvance; if (line_width + char_width >= max_width) break; diff --git a/imgui.h b/imgui.h index edf800330..2041a4836 100644 --- a/imgui.h +++ b/imgui.h @@ -921,7 +921,7 @@ struct ImFont float FontSize; // // Height of characters, set during loading (don't change after loading) float Scale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() ImVec2 DisplayOffset; // = (0.0f,0.0f) // Offset font rendering by xx pixels - ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. + ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() // Members: Runtime data struct Glyph @@ -934,9 +934,10 @@ struct ImFont }; ImFontAtlas* ContainerAtlas; // What we has been loaded into ImVector Glyphs; + const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) + float FallbackXAdvance; // ImVector IndexXAdvance; // Glyphs->XAdvance directly indexable (for CalcTextSize functions which are often bottleneck in large UI) ImVector IndexLookup; // Index glyphs by Unicode code-point - const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) // Methods IMGUI_API ImFont(); @@ -944,6 +945,7 @@ struct ImFont IMGUI_API void Clear(); IMGUI_API void BuildLookupTable(); IMGUI_API const Glyph* FindGlyph(unsigned short c) const; + IMGUI_API void SetFallbackChar(ImWchar c); IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.