1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-08 23:44:19 +00:00

Fonts: Baked system, v12: support GlyphOffset / GlyphMinAdvanceX / GlyphMaxAdvanceX by scaling from ref value.

Overwriting cfg->PixelSnapH = true; in imgui_freetype is weird.
This commit is contained in:
ocornut 2025-02-03 17:46:59 +01:00
parent df694c89b0
commit 99f6b305c1
4 changed files with 27 additions and 10 deletions

View file

@ -8602,7 +8602,7 @@ void ImGui::SetCurrentFont(ImFont* font, float font_size)
{
ImGuiContext& g = *GImGui;
g.Font = font;
//g.FontBaseSize = ImMax(1.0f, g.IO.FontGlobalScale * g.FontBaked->FontSize * g.Font->Scale);
//g.FontBaseSize = ImMax(1.0f, g.IO.FontGlobalScale * g.FontBaked->Size * g.Font->Scale);
g.FontSize = font_size;// g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f;
if (font != NULL)
{

View file

@ -3424,15 +3424,16 @@ struct ImFontConfig
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
bool PixelSnapV; // true // Align Scaled GlyphOffset.y to pixel boundaries.
int FontNo; // 0 // Index of font within TTF/OTF file
int OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED IN 1.91.9: use GlyphExtraAdvanceX)
ImVec2 GlyphOffset; // 0, 0 // [FIXME-BAKED] Offset all glyphs from this font input.
//ImVec2 GlyphExtraSpacing; // 0, 0 // (REMOVED AT IT SEEMS LARGELY OBSOLETE. PLEASE REPORT IF YOU WERE USING THIS). Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
ImVec2 GlyphOffset; // 0, 0 // Offset (in pixels) all glyphs from this font input. Absolute value for default size, other sizes will scale this value.
const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
float GlyphMinAdvanceX; // 0 // [FIXME-BAKED] Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
float GlyphMaxAdvanceX; // FLT_MAX // [FIXME-BAKED] Maximum AdvanceX for glyphs
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font. Absolute value for default size, other sizes will scale this value.
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
float GlyphExtraAdvanceX; // 0 // Extra spacing (in pixels) between glyphs. Please contact us if you are using this.
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.

View file

@ -4351,8 +4351,15 @@ static bool ImGui_ImplStbTrueType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontBa
if (oversample_v > 1)
stbtt__v_prefilter(bitmap_pixels, r->w, r->h, r->w, oversample_v);
float font_off_x = src->GlyphOffset.x + stbtt__oversample_shift(oversample_h);
float font_off_y = src->GlyphOffset.y + stbtt__oversample_shift(oversample_v) + IM_ROUND(baked->Ascent);
const float offsets_scale = baked->Size / baked->ContainerFont->Sources[0].SizePixels;
float font_off_x = (src->GlyphOffset.x * offsets_scale);
float font_off_y = (src->GlyphOffset.y * offsets_scale);
if (src->PixelSnapH) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome.
font_off_x = IM_ROUND(font_off_x);
if (src->PixelSnapV)
font_off_y = IM_ROUND(font_off_y);
font_off_x += stbtt__oversample_shift(oversample_h);
font_off_y += stbtt__oversample_shift(oversample_v) + IM_ROUND(baked->Ascent);
float recip_h = 1.0f / (oversample_h * src->RasterizerDensity);
float recip_v = 1.0f / (oversample_v * src->RasterizerDensity);
@ -4800,7 +4807,8 @@ ImFontGlyph* ImFontAtlasBakedAddFontGlyph(ImFontAtlas* atlas, ImFontBaked* baked
if (src != NULL)
{
// Clamp & recenter if needed
float advance_x = ImClamp(glyph.AdvanceX, src->GlyphMinAdvanceX, src->GlyphMaxAdvanceX);
const float offsets_scale = baked->Size / baked->ContainerFont->Sources[0].SizePixels;
float advance_x = ImClamp(glyph.AdvanceX, src->GlyphMinAdvanceX * offsets_scale, src->GlyphMaxAdvanceX * offsets_scale);
if (advance_x != glyph.AdvanceX)
{
float char_off_x = src->PixelSnapH ? ImTrunc((advance_x - glyph.AdvanceX) * 0.5f) : (advance_x - glyph.AdvanceX) * 0.5f;

View file

@ -204,6 +204,9 @@ namespace
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoHinting)
LoadFlags |= FT_LOAD_NO_HINTING;
else
src->PixelSnapH = true; // FIXME: A bit weird to do this this way.
if (UserFlags & ImGuiFreeTypeBuilderFlags_NoAutoHint)
LoadFlags |= FT_LOAD_NO_AUTOHINT;
if (UserFlags & ImGuiFreeTypeBuilderFlags_ForceAutoHint)
@ -559,8 +562,13 @@ bool ImGui_ImplFreeType_FontBakedAddGlyph(ImFontAtlas* atlas, ImFontBaked* baked
uint32_t* temp_buffer = (uint32_t*)atlas->Builder->TempBuffer.Data;
bd_font_data->BlitGlyph(ft_bitmap, temp_buffer, w);
float font_off_x = src->GlyphOffset.x;
float font_off_y = src->GlyphOffset.y + IM_ROUND(baked->Ascent);
const float offsets_scale = baked->Size / baked->ContainerFont->Sources[0].SizePixels;
float font_off_x = (src->GlyphOffset.x * offsets_scale);
float font_off_y = (src->GlyphOffset.y * offsets_scale) + baked->Ascent;
if (src->PixelSnapH) // Snap scaled offset. This is to mitigate backward compatibility issues for GlyphOffset, but a better design would be welcome.
font_off_x = IM_ROUND(font_off_x);
if (src->PixelSnapV)
font_off_y = IM_ROUND(font_off_y);
float recip_h = 1.0f / src->RasterizerDensity;
float recip_v = 1.0f / src->RasterizerDensity;