Font: fix for fallback character width.

This commit is contained in:
ocornut 2015-03-06 19:17:20 +00:00
parent 386cfada83
commit 0ffd99d319
2 changed files with 25 additions and 10 deletions

View File

@ -3194,8 +3194,6 @@ static void SetFont(ImFont* font)
g.Font = font; g.Font = font;
g.FontSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; g.FontSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale;
g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel; g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel;
g.Font->FallbackGlyph = NULL;
g.Font->FallbackGlyph = g.Font->FindGlyph(g.Font->FallbackChar);
} }
void ImGui::PushFont(ImFont* font) void ImGui::PushFont(ImFont* font)
@ -7459,9 +7457,10 @@ void ImFont::Clear()
DisplayOffset = ImVec2(-0.5f, 0.5f); DisplayOffset = ImVec2(-0.5f, 0.5f);
ContainerAtlas = NULL; ContainerAtlas = NULL;
Glyphs.clear(); Glyphs.clear();
FallbackGlyph = NULL;
FallbackXAdvance = 0.0f;
IndexXAdvance.clear(); IndexXAdvance.clear();
IndexLookup.clear(); IndexLookup.clear();
FallbackGlyph = NULL;
} }
// Retrieve list of range (2 int per range, values are inclusive) // 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); IndexLookup.resize((size_t)max_codepoint + 1);
for (size_t i = 0; i < (size_t)max_codepoint + 1; i++) for (size_t i = 0; i < (size_t)max_codepoint + 1; i++)
{ {
IndexXAdvance[i] = 0.0f; IndexXAdvance[i] = -1.0f;
IndexLookup[i] = -1; IndexLookup[i] = -1;
} }
for (size_t i = 0; i < Glyphs.size(); i++) 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" // 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)' ')) 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(); ImFont::Glyph& tab_glyph = Glyphs.back();
tab_glyph = *FindGlyph((unsigned short)' '); tab_glyph = *FindGlyph((unsigned short)' ');
tab_glyph.Codepoint = '\t'; tab_glyph.Codepoint = '\t';
@ -7585,6 +7585,19 @@ void ImFont::BuildLookupTable()
IndexXAdvance[(size_t)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; IndexXAdvance[(size_t)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance;
IndexLookup[(size_t)tab_glyph.Codepoint] = (int)(Glyphs.size()-1); 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 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; 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 (ImCharIsSpace(c))
{ {
if (inside_word) if (inside_word)
@ -7900,7 +7913,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
continue; 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) if (line_width + char_width >= max_width)
break; break;
@ -7944,7 +7957,7 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be
continue; 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) if (line_width + char_width >= max_width)
break; break;

View File

@ -921,7 +921,7 @@ struct ImFont
float FontSize; // <user set> // Height of characters, set during loading (don't change after loading) float FontSize; // <user set> // 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() 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 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 // Members: Runtime data
struct Glyph struct Glyph
@ -934,9 +934,10 @@ struct ImFont
}; };
ImFontAtlas* ContainerAtlas; // What we has been loaded into ImFontAtlas* ContainerAtlas; // What we has been loaded into
ImVector<Glyph> Glyphs; ImVector<Glyph> Glyphs;
const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)
float FallbackXAdvance; //
ImVector<float> IndexXAdvance; // Glyphs->XAdvance directly indexable (for CalcTextSize functions which are often bottleneck in large UI) ImVector<float> IndexXAdvance; // Glyphs->XAdvance directly indexable (for CalcTextSize functions which are often bottleneck in large UI)
ImVector<int> IndexLookup; // Index glyphs by Unicode code-point ImVector<int> IndexLookup; // Index glyphs by Unicode code-point
const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)
// Methods // Methods
IMGUI_API ImFont(); IMGUI_API ImFont();
@ -944,6 +945,7 @@ struct ImFont
IMGUI_API void Clear(); IMGUI_API void Clear();
IMGUI_API void BuildLookupTable(); IMGUI_API void BuildLookupTable();
IMGUI_API const Glyph* FindGlyph(unsigned short c) const; IMGUI_API const Glyph* FindGlyph(unsigned short c) const;
IMGUI_API void SetFallbackChar(ImWchar c);
IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } 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. // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.