|
@ -6484,7 +6484,7 @@ bool ImFontAtlas::Build() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Start packing
|
|
|
// Start packing
|
|
|
TexWidth = (total_glyph_count > 3000) ? 2048 : (total_glyph_count > 1000) ? 1024 : 512; // Width doesn't actually matters.
|
|
|
TexWidth = (total_glyph_count > 1000) ? 1024 : 512; // Width doesn't actually matters.
|
|
|
TexHeight = 0; |
|
|
TexHeight = 0; |
|
|
const int max_tex_height = 1024*32; |
|
|
const int max_tex_height = 1024*32; |
|
|
stbtt_pack_context spc; |
|
|
stbtt_pack_context spc; |
|
@ -6499,6 +6499,14 @@ 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)
|
|
|
|
|
|
stbtt_packedchar* packed_chardata = (stbtt_packedchar*)ImGui::MemAlloc(total_glyph_count * sizeof(stbtt_packedchar)); |
|
|
|
|
|
int packed_chardata_n = 0; |
|
|
|
|
|
memset(packed_chardata, 0, total_glyph_count * sizeof(stbtt_packedchar)); |
|
|
|
|
|
|
|
|
|
|
|
stbrp_rect* rectdata = (stbrp_rect*)ImGui::MemAlloc(total_glyph_count * sizeof(stbrp_rect)); |
|
|
|
|
|
int rectdata_n = 0; |
|
|
|
|
|
|
|
|
// 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; |
|
|
for (size_t input_i = 0; input_i < InputData.size(); input_i++) |
|
|
for (size_t input_i = 0; input_i < InputData.size(); input_i++) |
|
@ -6521,17 +6529,13 @@ bool ImFontAtlas::Build() |
|
|
const ImWchar* in_range = &data.GlyphRanges[i * 2]; |
|
|
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; |
|
|
// Allocate characters and flag as not packed
|
|
|
packed_chardata_n += range.num_chars_in_range; |
|
|
// FIXME-OPT: Loose ranges will incur lots of allocations. Allocate all contiguous in loop above.
|
|
|
|
|
|
range.chardata_for_range = (stbtt_packedchar*)ImGui::MemAlloc(range.num_chars_in_range * sizeof(stbtt_packedchar)); |
|
|
|
|
|
for (int j = 0; j < range.num_chars_in_range; ++j) |
|
|
|
|
|
range.chardata_for_range[j].x0 = range.chardata_for_range[j].y0 = range.chardata_for_range[j].x1 = range.chardata_for_range[j].y1 = 0; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Pack
|
|
|
// Pack
|
|
|
data.Rects = (stbrp_rect*)ImGui::MemAlloc(sizeof(stbrp_rect) * glyph_count); |
|
|
data.Rects = rectdata + rectdata_n; |
|
|
IM_ASSERT(data.Rects); |
|
|
rectdata_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.begin(), data.Ranges.size(), data.Rects); |
|
|
stbrp_pack_rects((stbrp_context*)spc.pack_info, data.Rects, n); |
|
|
stbrp_pack_rects((stbrp_context*)spc.pack_info, data.Rects, n); |
|
|
|
|
|
|
|
@ -6540,6 +6544,7 @@ 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); |
|
|
|
|
|
|
|
|
// Create texture
|
|
|
// Create texture
|
|
|
TexHeight = ImUpperPowerOfTwo(tex_height); |
|
|
TexHeight = ImUpperPowerOfTwo(tex_height); |
|
@ -6553,12 +6558,13 @@ bool ImFontAtlas::Build() |
|
|
{ |
|
|
{ |
|
|
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.begin(), data.Ranges.size(), data.Rects); |
|
|
ImGui::MemFree(data.Rects); |
|
|
|
|
|
data.Rects = NULL; |
|
|
data.Rects = NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// End packing
|
|
|
// End packing
|
|
|
stbtt_PackEnd(&spc); |
|
|
stbtt_PackEnd(&spc); |
|
|
|
|
|
ImGui::MemFree(rectdata); |
|
|
|
|
|
rectdata = 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++) |
|
@ -6601,18 +6607,19 @@ bool ImFontAtlas::Build() |
|
|
|
|
|
|
|
|
data.OutFont->BuildLookupTable(); |
|
|
data.OutFont->BuildLookupTable(); |
|
|
|
|
|
|
|
|
// Cleanup temporary
|
|
|
// Cleanup temporaries
|
|
|
for (size_t i = 0; i < data.Ranges.size(); i++) |
|
|
|
|
|
ImGui::MemFree(data.Ranges[i].chardata_for_range); |
|
|
|
|
|
data.Ranges.clear(); |
|
|
data.Ranges.clear(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Cleanup temporaries
|
|
|
|
|
|
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; |
|
|
TexUvWhitePixel = ImVec2((TexExtraDataPos.x + 0.5f) / TexWidth, (TexExtraDataPos.y + 0.5f) / TexHeight); |
|
|
TexUvWhitePixel = ImVec2((TexExtraDataPos.x + 0.5f) / TexWidth, (TexExtraDataPos.y + 0.5f) / TexHeight); |
|
|
|
|
|
|
|
|
ClearInputData(); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|