|
@@ -2941,6 +2941,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
|
int total_surface = 0;
|
|
int total_surface = 0;
|
|
int buf_rects_out_n = 0;
|
|
int buf_rects_out_n = 0;
|
|
int buf_packedchars_out_n = 0;
|
|
int buf_packedchars_out_n = 0;
|
|
|
|
+ const int pack_padding = atlas->TexGlyphPadding;
|
|
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
|
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
|
{
|
|
{
|
|
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
|
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
|
@@ -2964,18 +2965,19 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
|
|
|
|
|
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
|
|
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
|
|
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
|
|
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
|
|
- const int padding = atlas->TexGlyphPadding;
|
|
|
|
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
|
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
|
{
|
|
{
|
|
int x0, y0, x1, y1;
|
|
int x0, y0, x1, y1;
|
|
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
|
|
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
|
|
IM_ASSERT(glyph_index_in_font != 0);
|
|
IM_ASSERT(glyph_index_in_font != 0);
|
|
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1);
|
|
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1);
|
|
- src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + padding + cfg.OversampleH - 1);
|
|
|
|
- src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + padding + cfg.OversampleV - 1);
|
|
|
|
|
|
+ src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + cfg.OversampleH - 1);
|
|
|
|
+ src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + cfg.OversampleV - 1);
|
|
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
|
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ for (int i = 0; i < atlas->CustomRects.Size; i++)
|
|
|
|
+ total_surface += (atlas->CustomRects[i].Width + pack_padding) * (atlas->CustomRects[i].Height + pack_padding);
|
|
|
|
|
|
// We need a width for the skyline algorithm, any width!
|
|
// We need a width for the skyline algorithm, any width!
|
|
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
|
|
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
|
|
@@ -2991,7 +2993,8 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
|
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
|
|
// Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values).
|
|
const int TEX_HEIGHT_MAX = 1024 * 32;
|
|
const int TEX_HEIGHT_MAX = 1024 * 32;
|
|
stbtt_pack_context spc = {};
|
|
stbtt_pack_context spc = {};
|
|
- stbtt_PackBegin(&spc, NULL, atlas->TexWidth, TEX_HEIGHT_MAX, 0, atlas->TexGlyphPadding, NULL);
|
|
|
|
|
|
+ stbtt_PackBegin(&spc, NULL, atlas->TexWidth, TEX_HEIGHT_MAX, 0, 0, NULL);
|
|
|
|
+ spc.padding = atlas->TexGlyphPadding; // Because we mixup stbtt_PackXXX and stbrp_PackXXX there's a bit of a hack here, not passing the value to stbtt_PackBegin() allows us to still pack a TexWidth-1 wide item. (#8107)
|
|
ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info);
|
|
ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info);
|
|
|
|
|
|
// 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.
|
|
// 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.
|
|
@@ -3137,13 +3140,14 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
|
|
if (user_rects.Size < 1) { __builtin_unreachable(); } // Workaround for GCC bug if IM_ASSERT() is defined to conditionally throw (see #5343)
|
|
if (user_rects.Size < 1) { __builtin_unreachable(); } // Workaround for GCC bug if IM_ASSERT() is defined to conditionally throw (see #5343)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+ const int pack_padding = atlas->TexGlyphPadding;
|
|
ImVector<stbrp_rect> pack_rects;
|
|
ImVector<stbrp_rect> pack_rects;
|
|
pack_rects.resize(user_rects.Size);
|
|
pack_rects.resize(user_rects.Size);
|
|
memset(pack_rects.Data, 0, (size_t)pack_rects.size_in_bytes());
|
|
memset(pack_rects.Data, 0, (size_t)pack_rects.size_in_bytes());
|
|
for (int i = 0; i < user_rects.Size; i++)
|
|
for (int i = 0; i < user_rects.Size; i++)
|
|
{
|
|
{
|
|
- pack_rects[i].w = user_rects[i].Width;
|
|
|
|
- pack_rects[i].h = user_rects[i].Height;
|
|
|
|
|
|
+ pack_rects[i].w = user_rects[i].Width + pack_padding;
|
|
|
|
+ pack_rects[i].h = user_rects[i].Height + pack_padding;
|
|
}
|
|
}
|
|
stbrp_pack_rects(pack_context, &pack_rects[0], pack_rects.Size);
|
|
stbrp_pack_rects(pack_context, &pack_rects[0], pack_rects.Size);
|
|
for (int i = 0; i < pack_rects.Size; i++)
|
|
for (int i = 0; i < pack_rects.Size; i++)
|
|
@@ -3151,7 +3155,7 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
|
|
{
|
|
{
|
|
user_rects[i].X = (unsigned short)pack_rects[i].x;
|
|
user_rects[i].X = (unsigned short)pack_rects[i].x;
|
|
user_rects[i].Y = (unsigned short)pack_rects[i].y;
|
|
user_rects[i].Y = (unsigned short)pack_rects[i].y;
|
|
- IM_ASSERT(pack_rects[i].w == user_rects[i].Width && pack_rects[i].h == user_rects[i].Height);
|
|
|
|
|
|
+ IM_ASSERT(pack_rects[i].w == user_rects[i].Width + pack_padding && pack_rects[i].h == user_rects[i].Height + pack_padding);
|
|
atlas->TexHeight = ImMax(atlas->TexHeight, pack_rects[i].y + pack_rects[i].h);
|
|
atlas->TexHeight = ImMax(atlas->TexHeight, pack_rects[i].y + pack_rects[i].h);
|
|
}
|
|
}
|
|
}
|
|
}
|