mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-26 21:47:00 +00:00
ImFontAtlas: some more optimisations / cleanup.
This commit is contained in:
parent
e685e49781
commit
bfe894406d
78
imgui.cpp
78
imgui.cpp
@ -6297,17 +6297,18 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const Im
|
|||||||
struct ImFontAtlas::ImFontAtlasData
|
struct ImFontAtlas::ImFontAtlasData
|
||||||
{
|
{
|
||||||
// Input
|
// Input
|
||||||
ImFont* OutFont; // Load into this font
|
ImFont* OutFont; // Load into this font
|
||||||
void* TTFData; // TTF data, we own the memory
|
void* TTFData; // TTF data, we own the memory
|
||||||
size_t TTFDataSize; // TTF data size, in bytes
|
size_t TTFDataSize; // TTF data size, in bytes
|
||||||
float SizePixels; // Desired output size, in pixels
|
float SizePixels; // Desired output size, in pixels
|
||||||
const ImWchar* GlyphRanges; // List of Unicode range (2 value per range, values are inclusive, zero-terminated list)
|
const ImWchar* GlyphRanges; // List of Unicode range (2 value per range, values are inclusive, zero-terminated list)
|
||||||
int FontNo; // Index of font within .TTF file (0)
|
int FontNo; // Index of font within .TTF file (0)
|
||||||
|
|
||||||
// Temporary Build Data
|
// Temporary Build Data
|
||||||
stbtt_fontinfo FontInfo;
|
stbtt_fontinfo FontInfo;
|
||||||
stbrp_rect* Rects;
|
stbrp_rect* Rects;
|
||||||
ImVector<stbtt_pack_range> Ranges;
|
stbtt_pack_range* Ranges;
|
||||||
|
int RangesCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
ImFontAtlas::ImFontAtlas()
|
ImFontAtlas::ImFontAtlas()
|
||||||
@ -6468,6 +6469,7 @@ bool ImFontAtlas::Build()
|
|||||||
|
|
||||||
// Initialize font information early (so we can error without any cleanup) + count glyphs
|
// Initialize font information early (so we can error without any cleanup) + count glyphs
|
||||||
int total_glyph_count = 0;
|
int total_glyph_count = 0;
|
||||||
|
int total_glyph_range_count = 0;
|
||||||
for (size_t input_i = 0; input_i < InputData.size(); input_i++)
|
for (size_t input_i = 0; input_i < InputData.size(); input_i++)
|
||||||
{
|
{
|
||||||
ImFontAtlasData& data = *InputData[input_i];
|
ImFontAtlasData& data = *InputData[input_i];
|
||||||
@ -6480,7 +6482,10 @@ bool ImFontAtlas::Build()
|
|||||||
if (!data.GlyphRanges)
|
if (!data.GlyphRanges)
|
||||||
data.GlyphRanges = GetGlyphRangesDefault();
|
data.GlyphRanges = GetGlyphRangesDefault();
|
||||||
for (const ImWchar* in_range = data.GlyphRanges; in_range[0] && in_range[1]; in_range += 2)
|
for (const ImWchar* in_range = data.GlyphRanges; in_range[0] && in_range[1]; in_range += 2)
|
||||||
|
{
|
||||||
total_glyph_count += (in_range[1] - in_range[0]) + 1;
|
total_glyph_count += (in_range[1] - in_range[0]) + 1;
|
||||||
|
total_glyph_range_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start packing
|
// Start packing
|
||||||
@ -6499,13 +6504,13 @@ bool ImFontAtlas::Build()
|
|||||||
stbrp_pack_rects((stbrp_context*)spc.pack_info, &extra_rect, 1);
|
stbrp_pack_rects((stbrp_context*)spc.pack_info, &extra_rect, 1);
|
||||||
TexExtraDataPos = ImVec2(extra_rect.x, extra_rect.y);
|
TexExtraDataPos = ImVec2(extra_rect.x, extra_rect.y);
|
||||||
|
|
||||||
// Allocate packing character data and flag as non-packed (x0=y0=x1=y1=0)
|
// Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0)
|
||||||
stbtt_packedchar* packed_chardata = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar));
|
int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0;
|
||||||
int packed_chardata_n = 0;
|
stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar));
|
||||||
memset(packed_chardata, 0, total_glyph_count * sizeof(stbtt_packedchar));
|
stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect));
|
||||||
|
stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_glyph_range_count * sizeof(stbtt_pack_range));
|
||||||
stbrp_rect* rectdata = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect));
|
memset(buf_packedchars, 0, total_glyph_count * sizeof(stbtt_packedchar));
|
||||||
int rectdata_n = 0;
|
memset(buf_ranges, 0, total_glyph_range_count * sizeof(stbtt_pack_range));
|
||||||
|
|
||||||
// First pass: pack all glyphs (no rendering at this point, we are working with glyph sizes only)
|
// First pass: pack all glyphs (no rendering at this point, we are working with glyph sizes only)
|
||||||
int tex_height = extra_rect.y + extra_rect.h;
|
int tex_height = extra_rect.y + extra_rect.h;
|
||||||
@ -6521,22 +6526,24 @@ bool ImFontAtlas::Build()
|
|||||||
glyph_count += (in_range[1] - in_range[0]) + 1;
|
glyph_count += (in_range[1] - in_range[0]) + 1;
|
||||||
glyph_ranges_count++;
|
glyph_ranges_count++;
|
||||||
}
|
}
|
||||||
data.Ranges.resize(glyph_ranges_count);
|
data.Ranges = buf_ranges + buf_ranges_n;
|
||||||
for (size_t i = 0; i < data.Ranges.size(); i++)
|
data.RangesCount = glyph_ranges_count;
|
||||||
|
buf_ranges_n += glyph_ranges_count;
|
||||||
|
for (size_t i = 0; i < glyph_ranges_count; i++)
|
||||||
{
|
{
|
||||||
|
const ImWchar* in_range = &data.GlyphRanges[i * 2];
|
||||||
stbtt_pack_range& range = data.Ranges[i];
|
stbtt_pack_range& range = data.Ranges[i];
|
||||||
range.font_size = data.SizePixels;
|
range.font_size = data.SizePixels;
|
||||||
const ImWchar* in_range = &data.GlyphRanges[i * 2];
|
|
||||||
range.first_unicode_char_in_range = in_range[0];
|
range.first_unicode_char_in_range = in_range[0];
|
||||||
range.num_chars_in_range = (in_range[1] - in_range[0]) + 1;
|
range.num_chars_in_range = (in_range[1] - in_range[0]) + 1;
|
||||||
range.chardata_for_range = packed_chardata + packed_chardata_n;
|
range.chardata_for_range = buf_packedchars + buf_packedchars_n;
|
||||||
packed_chardata_n += range.num_chars_in_range;
|
buf_packedchars_n += range.num_chars_in_range;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack
|
// Pack
|
||||||
data.Rects = rectdata + rectdata_n;
|
data.Rects = buf_rects + buf_rects_n;
|
||||||
rectdata_n += glyph_count;
|
buf_rects_n += glyph_count;
|
||||||
const int n = stbtt_PackFontRangesGatherRects(&spc, &data.FontInfo, data.Ranges.begin(), data.Ranges.size(), data.Rects);
|
const int n = stbtt_PackFontRangesGatherRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects);
|
||||||
stbrp_pack_rects((stbrp_context*)spc.pack_info, data.Rects, n);
|
stbrp_pack_rects((stbrp_context*)spc.pack_info, data.Rects, n);
|
||||||
|
|
||||||
// Extend texture height
|
// Extend texture height
|
||||||
@ -6544,11 +6551,13 @@ bool ImFontAtlas::Build()
|
|||||||
if (data.Rects[i].was_packed)
|
if (data.Rects[i].was_packed)
|
||||||
tex_height = ImMax(tex_height, data.Rects[i].y + data.Rects[i].h);
|
tex_height = ImMax(tex_height, data.Rects[i].y + data.Rects[i].h);
|
||||||
}
|
}
|
||||||
IM_ASSERT(packed_chardata_n == total_glyph_count);
|
IM_ASSERT(buf_rects_n == total_glyph_count);
|
||||||
|
IM_ASSERT(buf_packedchars_n == total_glyph_count);
|
||||||
|
IM_ASSERT(buf_ranges_n == total_glyph_range_count);
|
||||||
|
|
||||||
// Create texture
|
// Create texture
|
||||||
TexHeight = ImUpperPowerOfTwo(tex_height);
|
TexHeight = ImUpperPowerOfTwo(tex_height);
|
||||||
TexPixelsAlpha8 = (unsigned char*)ImGui::MemRealloc(TexPixelsAlpha8, TexWidth * TexHeight);
|
TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(TexWidth * TexHeight);
|
||||||
memset(TexPixelsAlpha8, 0, TexWidth * TexHeight);
|
memset(TexPixelsAlpha8, 0, TexWidth * TexHeight);
|
||||||
spc.pixels = TexPixelsAlpha8;
|
spc.pixels = TexPixelsAlpha8;
|
||||||
spc.height = TexHeight;
|
spc.height = TexHeight;
|
||||||
@ -6557,14 +6566,14 @@ bool ImFontAtlas::Build()
|
|||||||
for (size_t input_i = 0; input_i < InputData.size(); input_i++)
|
for (size_t input_i = 0; input_i < InputData.size(); input_i++)
|
||||||
{
|
{
|
||||||
ImFontAtlasData& data = *InputData[input_i];
|
ImFontAtlasData& data = *InputData[input_i];
|
||||||
ret = stbtt_PackFontRangesRenderIntoRects(&spc, &data.FontInfo, data.Ranges.begin(), data.Ranges.size(), data.Rects);
|
ret = stbtt_PackFontRangesRenderIntoRects(&spc, &data.FontInfo, data.Ranges, data.RangesCount, data.Rects);
|
||||||
data.Rects = NULL;
|
data.Rects = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// End packing
|
// End packing
|
||||||
stbtt_PackEnd(&spc);
|
stbtt_PackEnd(&spc);
|
||||||
ImGui::MemFree(rectdata);
|
ImGui::MemFree(buf_rects);
|
||||||
rectdata = NULL;
|
buf_rects = NULL;
|
||||||
|
|
||||||
// Third pass: setup ImFont and glyphs for runtime
|
// Third pass: setup ImFont and glyphs for runtime
|
||||||
for (size_t input_i = 0; input_i < InputData.size(); input_i++)
|
for (size_t input_i = 0; input_i < InputData.size(); input_i++)
|
||||||
@ -6580,7 +6589,7 @@ bool ImFontAtlas::Build()
|
|||||||
const float uv_scale_x = 1.0f / TexWidth;
|
const float uv_scale_x = 1.0f / TexWidth;
|
||||||
const float uv_scale_y = 1.0f / TexHeight;
|
const float uv_scale_y = 1.0f / TexHeight;
|
||||||
const int character_spacing_x = 1;
|
const int character_spacing_x = 1;
|
||||||
for (size_t i = 0; i < data.Ranges.size(); i++)
|
for (int i = 0; i < data.RangesCount; i++)
|
||||||
{
|
{
|
||||||
stbtt_pack_range& range = data.Ranges[i];
|
stbtt_pack_range& range = data.Ranges[i];
|
||||||
for (int char_idx = 0; char_idx < range.num_chars_in_range; char_idx += 1)
|
for (int char_idx = 0; char_idx < range.num_chars_in_range; char_idx += 1)
|
||||||
@ -6606,15 +6615,14 @@ bool ImFontAtlas::Build()
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.OutFont->BuildLookupTable();
|
data.OutFont->BuildLookupTable();
|
||||||
|
|
||||||
// Cleanup temporaries
|
|
||||||
data.Ranges.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup temporaries
|
// Cleanup temporaries
|
||||||
|
ImGui::MemFree(buf_packedchars);
|
||||||
|
ImGui::MemFree(buf_ranges);
|
||||||
|
buf_packedchars = NULL;
|
||||||
|
buf_ranges = NULL;
|
||||||
ClearInputData();
|
ClearInputData();
|
||||||
ImGui::MemFree(packed_chardata);
|
|
||||||
packed_chardata = NULL;
|
|
||||||
|
|
||||||
// Draw white pixel into texture and make UV points to it
|
// Draw white pixel into texture and make UV points to it
|
||||||
TexPixelsAlpha8[0] = TexPixelsAlpha8[1] = TexPixelsAlpha8[TexWidth+0] = TexPixelsAlpha8[TexWidth+1] = 0xFF;
|
TexPixelsAlpha8[0] = TexPixelsAlpha8[1] = TexPixelsAlpha8[TexWidth+0] = TexPixelsAlpha8[TexWidth+1] = 0xFF;
|
||||||
|
Loading…
Reference in New Issue
Block a user