Fonts: added support for RasterizerDensity to FreeType based atlas generator. (#6925)

This commit is contained in:
thedmd 2023-10-14 18:04:50 +02:00 committed by ocornut
parent ed29ff08ba
commit ade4d0e08a

View File

@ -166,6 +166,8 @@ namespace
unsigned int UserFlags; // = ImFontConfig::RasterizerFlags unsigned int UserFlags; // = ImFontConfig::RasterizerFlags
FT_Int32 LoadFlags; FT_Int32 LoadFlags;
FT_Render_Mode RenderMode; FT_Render_Mode RenderMode;
float RasterizationDensity;
float InvRasterizationDensity;
}; };
// From SDL_ttf: Handy routines for converting from fixed point // From SDL_ttf: Handy routines for converting from fixed point
@ -208,6 +210,9 @@ namespace
if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor) if (UserFlags & ImGuiFreeTypeBuilderFlags_LoadColor)
LoadFlags |= FT_LOAD_COLOR; LoadFlags |= FT_LOAD_COLOR;
RasterizationDensity = cfg.RasterizerDensity;
InvRasterizationDensity = 1.0f / RasterizationDensity;
memset(&Info, 0, sizeof(Info)); memset(&Info, 0, sizeof(Info));
SetPixelHeight((uint32_t)cfg.SizePixels); SetPixelHeight((uint32_t)cfg.SizePixels);
@ -231,19 +236,19 @@ namespace
FT_Size_RequestRec req; FT_Size_RequestRec req;
req.type = (UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM; req.type = (UserFlags & ImGuiFreeTypeBuilderFlags_Bitmap) ? FT_SIZE_REQUEST_TYPE_NOMINAL : FT_SIZE_REQUEST_TYPE_REAL_DIM;
req.width = 0; req.width = 0;
req.height = (uint32_t)pixel_height * 64; req.height = (uint32_t)(pixel_height * 64 * RasterizationDensity);
req.horiResolution = 0; req.horiResolution = 0;
req.vertResolution = 0; req.vertResolution = 0;
FT_Request_Size(Face, &req); FT_Request_Size(Face, &req);
// Update font info // Update font info
FT_Size_Metrics metrics = Face->size->metrics; FT_Size_Metrics metrics = Face->size->metrics;
Info.PixelHeight = (uint32_t)pixel_height; Info.PixelHeight = (uint32_t)(pixel_height * InvRasterizationDensity);
Info.Ascender = (float)FT_CEIL(metrics.ascender); Info.Ascender = (float)FT_CEIL(metrics.ascender) * InvRasterizationDensity;
Info.Descender = (float)FT_CEIL(metrics.descender); Info.Descender = (float)FT_CEIL(metrics.descender) * InvRasterizationDensity;
Info.LineSpacing = (float)FT_CEIL(metrics.height); Info.LineSpacing = (float)FT_CEIL(metrics.height) * InvRasterizationDensity;
Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender); Info.LineGap = (float)FT_CEIL(metrics.height - metrics.ascender + metrics.descender) * InvRasterizationDensity;
Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance); Info.MaxAdvanceWidth = (float)FT_CEIL(metrics.max_advance) * InvRasterizationDensity;
} }
const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint) const FT_Glyph_Metrics* FreeTypeFont::LoadGlyph(uint32_t codepoint)
@ -695,15 +700,15 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
const int ty = pack_rect.y + padding; const int ty = pack_rect.y + padding;
// Register glyph // Register glyph
float x0 = info.OffsetX + font_off_x; float x0 = info.OffsetX * src_tmp.Font.InvRasterizationDensity + font_off_x;
float y0 = info.OffsetY + font_off_y; float y0 = info.OffsetY * src_tmp.Font.InvRasterizationDensity + font_off_y;
float x1 = x0 + info.Width; float x1 = x0 + info.Width * src_tmp.Font.InvRasterizationDensity;
float y1 = y0 + info.Height; float y1 = y0 + info.Height * src_tmp.Font.InvRasterizationDensity;
float u0 = (tx) / (float)atlas->TexWidth; float u0 = (tx) / (float)atlas->TexWidth;
float v0 = (ty) / (float)atlas->TexHeight; float v0 = (ty) / (float)atlas->TexHeight;
float u1 = (tx + info.Width) / (float)atlas->TexWidth; float u1 = (tx + info.Width) / (float)atlas->TexWidth;
float v1 = (ty + info.Height) / (float)atlas->TexHeight; float v1 = (ty + info.Height) / (float)atlas->TexHeight;
dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX); dst_font->AddGlyph(&cfg, (ImWchar)src_glyph.Codepoint, x0, y0, x1, y1, u0, v0, u1, v1, info.AdvanceX * src_tmp.Font.InvRasterizationDensity);
ImFontGlyph* dst_glyph = &dst_font->Glyphs.back(); ImFontGlyph* dst_glyph = &dst_font->Glyphs.back();
IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint); IM_ASSERT(dst_glyph->Codepoint == src_glyph.Codepoint);