1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-01-09 23:54:20 +00:00

Fonts: make RasterizerDensity a dynamic field. (temporarily exposed as SetFontRasterizerDensity()).

# Conflicts:
#	imgui.cpp
#	imgui.h
This commit is contained in:
ocornut 2025-04-30 21:29:09 +02:00
parent 8140a9d8a6
commit b32ef3c05d
5 changed files with 60 additions and 35 deletions

View file

@ -3349,10 +3349,11 @@ void ImFontAtlasBuildMain(ImFontAtlas* atlas)
atlas->TexIsBuilt = true;
}
void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, float size, int* out_oversample_h, int* out_oversample_v)
void ImFontAtlasBuildGetOversampleFactors(ImFontConfig* src, ImFontBaked* baked, int* out_oversample_h, int* out_oversample_v)
{
// Automatically disable horizontal oversampling over size 36
*out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : ((size * src->RasterizerDensity > 36.0f) || src->PixelSnapH) ? 1 : 2;
const float raster_size = baked->Size * baked->RasterizerDensity * src->RasterizerDensity;
*out_oversample_h = (src->OversampleH != 0) ? src->OversampleH : (raster_size > 36.0f || src->PixelSnapH) ? 1 : 2;
*out_oversample_v = (src->OversampleV != 0) ? src->OversampleV : 1;
}
@ -3733,11 +3734,12 @@ void ImFontAtlasBakedDiscardFontGlyph(ImFontAtlas* atlas, ImFont* font, ImFontBa
baked->IndexAdvanceX[c] = baked->FallbackAdvanceX;
}
ImFontBaked* ImFontAtlasBakedAdd(ImFontAtlas* atlas, ImFont* font, float font_size, ImGuiID baked_id)
ImFontBaked* ImFontAtlasBakedAdd(ImFontAtlas* atlas, ImFont* font, float font_size, float font_rasterizer_density, ImGuiID baked_id)
{
IMGUI_DEBUG_LOG_FONT("[font] Created baked %.2fpx\n", font_size);
ImFontBaked* baked = atlas->Builder->BakedPool.push_back(ImFontBaked());
baked->Size = font_size;
baked->RasterizerDensity = font_rasterizer_density;
baked->BakedId = baked_id;
baked->ContainerFont = font;
baked->LastUsedFrame = atlas->Builder->FrameCount;
@ -3764,7 +3766,7 @@ ImFontBaked* ImFontAtlasBakedAdd(ImFontAtlas* atlas, ImFont* font, float font_si
}
// FIXME-OPT: This is not a fast query. Adding a BakedCount field in Font might allow to take a shortcut for the most common case.
ImFontBaked* ImFontAtlasBakedGetClosestMatch(ImFontAtlas* atlas, ImFont* font, float font_size)
ImFontBaked* ImFontAtlasBakedGetClosestMatch(ImFontAtlas* atlas, ImFont* font, float font_size, float font_rasterizer_density)
{
ImFontAtlasBuilder* builder = atlas->Builder;
ImFontBaked* closest_larger_match = NULL;
@ -3774,6 +3776,8 @@ ImFontBaked* ImFontAtlasBakedGetClosestMatch(ImFontAtlas* atlas, ImFont* font, f
ImFontBaked* baked = &builder->BakedPool[baked_n];
if (baked->ContainerFont != font || baked->WantDestroy)
continue;
if (baked->RasterizerDensity != font_rasterizer_density)
continue;
if (baked->Size > font_size && (closest_larger_match == NULL || baked->Size < closest_larger_match->Size))
closest_larger_match = baked;
if (baked->Size < font_size && (closest_smaller_match == NULL || baked->Size > closest_smaller_match->Size))
@ -4543,10 +4547,11 @@ static ImFontGlyph* ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas,
// Fonts unit to pixels
int oversample_h, oversample_v;
ImFontAtlasBuildGetOversampleFactors(src, baked->Size, &oversample_h, &oversample_v);
ImFontAtlasBuildGetOversampleFactors(src, baked, &oversample_h, &oversample_v);
const float scale_for_layout = bd_font_data->ScaleFactor * baked->Size;
const float scale_for_raster_x = bd_font_data->ScaleFactor * baked->Size * src->RasterizerDensity * oversample_h;
const float scale_for_raster_y = bd_font_data->ScaleFactor * baked->Size * src->RasterizerDensity * oversample_v;
const float rasterizer_density = src->RasterizerDensity * baked->RasterizerDensity;
const float scale_for_raster_x = bd_font_data->ScaleFactor * baked->Size * rasterizer_density * oversample_h;
const float scale_for_raster_y = bd_font_data->ScaleFactor * baked->Size * rasterizer_density * oversample_v;
// Obtain size and advance
int x0, y0, x1, y1;
@ -4601,8 +4606,8 @@ static ImFontGlyph* ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas,
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);
float recip_h = 1.0f / (oversample_h * rasterizer_density);
float recip_v = 1.0f / (oversample_v * rasterizer_density);
// Register glyph
// r->x r->y are coordinates inside texture (in pixels)
@ -5172,11 +5177,12 @@ float ImFontBaked::GetCharAdvance(ImWchar c)
}
IM_MSVC_RUNTIME_CHECKS_RESTORE
ImGuiID ImFontAtlasBakedGetId(ImGuiID font_id, float baked_size)
ImGuiID ImFontAtlasBakedGetId(ImGuiID font_id, float baked_size, float rasterizer_density)
{
struct { ImGuiID FontId; float BakedSize; } hashed_data;
struct { ImGuiID FontId; float BakedSize; float RasterizerDensity; } hashed_data;
hashed_data.FontId = font_id;
hashed_data.BakedSize = baked_size;
hashed_data.RasterizerDensity = rasterizer_density;
return ImHashData(&hashed_data, sizeof(hashed_data));
}
@ -5189,12 +5195,12 @@ ImFontBaked* ImFont::GetFontBaked(float size)
// - ImGui::PushFontSize() will already round, but other paths calling GetFontBaked() directly also needs it (e.g. ImFontAtlasBuildPreloadAllGlyphRanges)
size = ImGui::GetRoundedFontSize(size);
if (baked && baked->Size == size)
if (baked && baked->Size == size && baked->RasterizerDensity == CurrentRasterizerDensity)
return baked;
ImFontAtlas* atlas = ContainerAtlas;
ImFontAtlasBuilder* builder = atlas->Builder;
baked = ImFontAtlasBakedGetOrAdd(atlas, this, size);
baked = ImFontAtlasBakedGetOrAdd(atlas, this, size, CurrentRasterizerDensity);
if (baked == NULL)
return NULL;
baked->LastUsedFrame = builder->FrameCount;
@ -5202,11 +5208,11 @@ ImFontBaked* ImFont::GetFontBaked(float size)
return baked;
}
ImFontBaked* ImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas, ImFont* font, float font_size)
ImFontBaked* ImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas, ImFont* font, float font_size, float font_rasterizer_density)
{
// FIXME-NEWATLAS: Design for picking a nearest size based on some criteria?
// FIXME-NEWATLAS: Altering font density won't work right away.
ImGuiID baked_id = ImFontAtlasBakedGetId(font->FontId, font_size);
ImGuiID baked_id = ImFontAtlasBakedGetId(font->FontId, font_size, font_rasterizer_density);
ImFontAtlasBuilder* builder = atlas->Builder;
ImFontBaked** p_baked_in_map = (ImFontBaked**)builder->BakedMap.GetVoidPtrRef(baked_id);
ImFontBaked* baked = *p_baked_in_map;
@ -5220,7 +5226,7 @@ ImFontBaked* ImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas, ImFont* font, float fo
// FIXME-OPT: This is not an optimal query.
if ((font->Flags & ImFontFlags_LockBakedSizes) || atlas->Locked)
{
baked = ImFontAtlasBakedGetClosestMatch(atlas, font, font_size);
baked = ImFontAtlasBakedGetClosestMatch(atlas, font, font_size, font_rasterizer_density);
if (baked != NULL)
return baked;
if (atlas->Locked)
@ -5231,7 +5237,7 @@ ImFontBaked* ImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas, ImFont* font, float fo
}
// Create new
baked = ImFontAtlasBakedAdd(atlas, font, font_size, baked_id);
baked = ImFontAtlasBakedAdd(atlas, font, font_size, font_rasterizer_density, baked_id);
*p_baked_in_map = baked; // To avoid 'builder->BakedMap.SetVoidPtr(baked_id, baked);' while we can.
return baked;
}