Skip to content

Commit 8be7a60

Browse files
committed
ImFontAtlas: Re-arranging code to simplify implementation of imgui_freetype. (#618)
1 parent 1086c87 commit 8be7a60

File tree

2 files changed

+40
-33
lines changed

2 files changed

+40
-33
lines changed

imgui_draw.cpp

+39-33
Original file line numberDiff line numberDiff line change
@@ -1336,40 +1336,45 @@ void ImFontAtlas::CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, I
13361336

13371337
bool ImFontAtlas::Build()
13381338
{
1339-
IM_ASSERT(ConfigData.Size > 0);
1339+
return ImFontAtlasBuildWithStbTruetype(this);
1340+
}
13401341

1341-
ImFontAtlasBuildRegisterDefaultCustomRects(this);
1342+
bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
1343+
{
1344+
IM_ASSERT(atlas->ConfigData.Size > 0);
13421345

1343-
TexID = NULL;
1344-
TexWidth = TexHeight = 0;
1345-
TexUvWhitePixel = ImVec2(0, 0);
1346-
ClearTexData();
1346+
ImFontAtlasBuildRegisterDefaultCustomRects(atlas);
1347+
1348+
atlas->TexID = NULL;
1349+
atlas->TexWidth = atlas->TexHeight = 0;
1350+
atlas->TexUvWhitePixel = ImVec2(0, 0);
1351+
atlas->ClearTexData();
13471352

13481353
// Count glyphs/ranges
13491354
int total_glyphs_count = 0;
13501355
int total_ranges_count = 0;
1351-
for (int input_i = 0; input_i < ConfigData.Size; input_i++)
1356+
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
13521357
{
1353-
ImFontConfig& cfg = ConfigData[input_i];
1358+
ImFontConfig& cfg = atlas->ConfigData[input_i];
13541359
if (!cfg.GlyphRanges)
1355-
cfg.GlyphRanges = GetGlyphRangesDefault();
1360+
cfg.GlyphRanges = atlas->GetGlyphRangesDefault();
13561361
for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_ranges_count++)
13571362
total_glyphs_count += (in_range[1] - in_range[0]) + 1;
13581363
}
13591364

13601365
// We need a width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish.
13611366
// Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
1362-
TexWidth = (TexDesiredWidth > 0) ? TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512;
1363-
TexHeight = 0;
1367+
atlas->TexWidth = (atlas->TexDesiredWidth > 0) ? atlas->TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512;
1368+
atlas->TexHeight = 0;
13641369

13651370
// Start packing
13661371
const int max_tex_height = 1024*32;
13671372
stbtt_pack_context spc;
1368-
stbtt_PackBegin(&spc, NULL, TexWidth, max_tex_height, 0, TexGlyphPadding, NULL);
1373+
stbtt_PackBegin(&spc, NULL, atlas->TexWidth, max_tex_height, 0, atlas->TexGlyphPadding, NULL);
13691374
stbtt_PackSetOversampling(&spc, 1, 1);
13701375

13711376
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
1372-
ImFontAtlasBuildPackCustomRects(this, spc.pack_info);
1377+
ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info);
13731378

13741379
// Initialize font information (so we can error without any cleanup)
13751380
struct ImFontTempBuildData
@@ -1379,12 +1384,13 @@ bool ImFontAtlas::Build()
13791384
stbtt_pack_range* Ranges;
13801385
int RangesCount;
13811386
};
1382-
ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)ConfigData.Size * sizeof(ImFontTempBuildData));
1383-
for (int input_i = 0; input_i < ConfigData.Size; input_i++)
1387+
ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)atlas->ConfigData.Size * sizeof(ImFontTempBuildData));
1388+
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
13841389
{
1385-
ImFontConfig& cfg = ConfigData[input_i];
1390+
ImFontConfig& cfg = atlas->ConfigData[input_i];
13861391
ImFontTempBuildData& tmp = tmp_array[input_i];
1387-
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == this));
1392+
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
1393+
13881394
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
13891395
IM_ASSERT(font_offset >= 0);
13901396
if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
@@ -1401,9 +1407,9 @@ bool ImFontAtlas::Build()
14011407
memset(buf_ranges, 0, total_ranges_count * sizeof(stbtt_pack_range));
14021408

14031409
// First font pass: pack all glyphs (no rendering at this point, we are working with rectangles in an infinitely tall texture at this point)
1404-
for (int input_i = 0; input_i < ConfigData.Size; input_i++)
1410+
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
14051411
{
1406-
ImFontConfig& cfg = ConfigData[input_i];
1412+
ImFontConfig& cfg = atlas->ConfigData[input_i];
14071413
ImFontTempBuildData& tmp = tmp_array[input_i];
14081414

14091415
// Setup ranges
@@ -1436,23 +1442,23 @@ bool ImFontAtlas::Build()
14361442
// Extend texture height
14371443
for (int i = 0; i < n; i++)
14381444
if (tmp.Rects[i].was_packed)
1439-
TexHeight = ImMax(TexHeight, tmp.Rects[i].y + tmp.Rects[i].h);
1445+
atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h);
14401446
}
14411447
IM_ASSERT(buf_rects_n == total_glyphs_count);
14421448
IM_ASSERT(buf_packedchars_n == total_glyphs_count);
14431449
IM_ASSERT(buf_ranges_n == total_ranges_count);
14441450

14451451
// Create texture
1446-
TexHeight = ImUpperPowerOfTwo(TexHeight);
1447-
TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(TexWidth * TexHeight);
1448-
memset(TexPixelsAlpha8, 0, TexWidth * TexHeight);
1449-
spc.pixels = TexPixelsAlpha8;
1450-
spc.height = TexHeight;
1452+
atlas->TexHeight = ImUpperPowerOfTwo(atlas->TexHeight);
1453+
atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight);
1454+
memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);
1455+
spc.pixels = atlas->TexPixelsAlpha8;
1456+
spc.height = atlas->TexHeight;
14511457

14521458
// Second pass: render font characters
1453-
for (int input_i = 0; input_i < ConfigData.Size; input_i++)
1459+
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
14541460
{
1455-
ImFontConfig& cfg = ConfigData[input_i];
1461+
ImFontConfig& cfg = atlas->ConfigData[input_i];
14561462
ImFontTempBuildData& tmp = tmp_array[input_i];
14571463
stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV);
14581464
stbtt_PackFontRangesRenderIntoRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects);
@@ -1465,9 +1471,9 @@ bool ImFontAtlas::Build()
14651471
buf_rects = NULL;
14661472

14671473
// Third pass: setup ImFont and glyphs for runtime
1468-
for (int input_i = 0; input_i < ConfigData.Size; input_i++)
1474+
for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++)
14691475
{
1470-
ImFontConfig& cfg = ConfigData[input_i];
1476+
ImFontConfig& cfg = atlas->ConfigData[input_i];
14711477
ImFontTempBuildData& tmp = tmp_array[input_i];
14721478
ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true)
14731479

@@ -1477,7 +1483,7 @@ bool ImFontAtlas::Build()
14771483

14781484
float ascent = unscaled_ascent * font_scale;
14791485
float descent = unscaled_descent * font_scale;
1480-
ImFontAtlasBuildSetupFont(this, dst_font, &cfg, ascent, descent);
1486+
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
14811487
float off_x = cfg.GlyphOffset.x;
14821488
float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f);
14831489

@@ -1497,7 +1503,7 @@ bool ImFontAtlas::Build()
14971503

14981504
stbtt_aligned_quad q;
14991505
float dummy_x = 0.0f, dummy_y = 0.0f;
1500-
stbtt_GetPackedQuad(range.chardata_for_range, TexWidth, TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0);
1506+
stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0);
15011507

15021508
dst_font->Glyphs.resize(dst_font->Glyphs.Size + 1);
15031509
ImFont::Glyph& glyph = dst_font->Glyphs.back();
@@ -1514,7 +1520,7 @@ bool ImFontAtlas::Build()
15141520

15151521
if (cfg.PixelSnapH)
15161522
glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f);
1517-
dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round
1523+
dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * atlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * atlas->TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round
15181524
}
15191525
}
15201526
cfg.DstFont->BuildLookupTable();
@@ -1526,7 +1532,7 @@ bool ImFontAtlas::Build()
15261532
ImGui::MemFree(tmp_array);
15271533

15281534
// Render into our custom data block
1529-
ImFontAtlasBuildRenderDefaultTexData(this);
1535+
ImFontAtlasBuildRenderDefaultTexData(atlas);
15301536

15311537
return true;
15321538
}

imgui_internal.h

+1
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ namespace ImGui
793793
} // namespace ImGui
794794

795795
// ImFontAtlas internals
796+
IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas);
796797
IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas);
797798
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
798799
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc);

0 commit comments

Comments
 (0)