From a51a26e2aa9717cc77d8a91416e31f611d4b72db Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 11 Dec 2024 19:21:10 +0100 Subject: [PATCH] Fonts: use a structure for post-processing - easier to pass things around and iterate on. --- imgui_draw.cpp | 45 +++++++++++++------------------- imgui_internal.h | 21 +++++++++++++-- misc/freetype/imgui_freetype.cpp | 5 ++-- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 48f99cdf1..10e69644f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2460,8 +2460,8 @@ void ImTextureData::DestroyPixels() // - ImFontAtlas::BuildCompactTexture() // - ImFontAtlasUpdateTextures() //----------------------------------------------------------------------------- -// - ImFontAtlasTextureBlockConvertAndPostProcess() // - ImFontAtlasTextureBlockConvert() +// - ImFontAtlasTextureBlockPostProcess() // - ImFontAtlasTextureBlockPostProcessMultiply() // - ImFontAtlasTextureBlockCopy() // - ImFontAtlasTextureBlockQueueUpload() @@ -2734,17 +2734,11 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas) // Source buffer may be written to (used for in-place mods). // Post-process hooks may eventually be added here. -void ImFontAtlasTextureBlockConvertAndPostProcess(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, ImFontGlyph* glyph, unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst, ImTextureFormat dst_fmt, int dst_pitch, int w, int h) +void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data) { - IM_UNUSED(atlas); - IM_UNUSED(font); - IM_UNUSED(glyph); - // Multiply operator (legacy) - if (src->RasterizerMultiply != 1.0f) - ImFontAtlasTextureBlockPostProcessMultiply(atlas, font, src, glyph, src_pixels, src_fmt, w, h, src_pitch, src->RasterizerMultiply); - - ImFontAtlasTextureBlockConvert(src_pixels, src_fmt, src_pitch, dst, dst_fmt, dst_pitch, w, h); + if (data->FontSrc->RasterizerMultiply != 1.0f) + ImFontAtlasTextureBlockPostProcessMultiply(data, data->FontSrc->RasterizerMultiply); } void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h) @@ -2782,34 +2776,30 @@ void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFo } } -void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, ImFontGlyph* glyph, unsigned char* pixels, ImTextureFormat format, int w, int h, int pitch, float in_multiply_factor) +void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data, float multiply_factor) { - IM_UNUSED(atlas); - IM_UNUSED(font); - IM_UNUSED(src); - IM_UNUSED(glyph); - IM_ASSERT(in_multiply_factor >= 0.0f); - IM_ASSERT_PARANOID(w <= pitch); - if (format == ImTextureFormat_Alpha8) + unsigned char* pixels = data->Pixels; + int pitch = data->Pitch; + if (data->Format == ImTextureFormat_Alpha8) { - for (int ny = h; ny > 0; ny--, pixels += pitch) + for (int ny = data->Height; ny > 0; ny--, pixels += pitch) { ImU8* p = (ImU8*)pixels; - for (int nx = w; nx > 0; nx--, p++) + for (int nx = data->Width; nx > 0; nx--, p++) { - unsigned int v = ImMin((unsigned int)(*p * in_multiply_factor), (unsigned int)255); + unsigned int v = ImMin((unsigned int)(*p * multiply_factor), (unsigned int)255); *p = (unsigned char)v; } } } - else if (format == ImTextureFormat_RGBA32) + else if (data->Format == ImTextureFormat_RGBA32) { - for (int ny = h; ny > 0; ny--, pixels += pitch) + for (int ny = data->Height; ny > 0; ny--, pixels += pitch) { ImU32* p = (ImU32*)(void*)pixels; - for (int nx = w; nx > 0; nx--, p++) + for (int nx = data->Width; nx > 0; nx--, p++) { - unsigned int a = ImMin((unsigned int)(((*p >> IM_COL32_A_SHIFT) & 0xFF) * in_multiply_factor), (unsigned int)255); + unsigned int a = ImMin((unsigned int)(((*p >> IM_COL32_A_SHIFT) & 0xFF) * multiply_factor), (unsigned int)255); *p = IM_COL32((*p >> IM_COL32_R_SHIFT) & 0xFF, (*p >> IM_COL32_G_SHIFT) & 0xFF, (*p >> IM_COL32_B_SHIFT) & 0xFF, a); } } @@ -4156,8 +4146,9 @@ static bool ImGui_ImplStbTrueType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, // Copy to texture, post-process and queue update for backend ImTextureData* tex = atlas->TexData; IM_ASSERT(r->x + r->w <= tex->Width && r->y + r->h <= tex->Height); - ImFontAtlasTextureBlockConvertAndPostProcess(atlas, font, src, &font->Glyphs.back(), - bitmap_pixels, ImTextureFormat_Alpha8, w, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h); + ImFontAtlasTextureBlockConvert(bitmap_pixels, ImTextureFormat_Alpha8, w, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h); + ImFontAtlasPostProcessData pp_data = { atlas, font, src, &font->Glyphs.back(), tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h }; + ImFontAtlasTextureBlockPostProcess(&pp_data); ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h); } else diff --git a/imgui_internal.h b/imgui_internal.h index 67a4b50cb..2c97cae01 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -144,6 +144,7 @@ struct ImDrawListSharedData; // Data shared between all ImDrawList instan struct ImFontAtlasRect; // Packed rectangle (same as ImTextureRect) struct ImFontAtlasRectEntry; // Packed rectangle lookup entry struct ImFontAtlasBuilder; // Internal storage for incrementally packing and building a ImFontAtlas +struct ImFontAtlasPostProcessData; // Data available to potential post-process functions // ImGui struct ImGuiBoxSelectState; // Box-selection state (currently used by multi-selection, could potentially be used by others) @@ -3658,6 +3659,22 @@ struct ImFontAtlasRectEntry unsigned int Used : 1; }; +// Data available to potential post-process functions +struct ImFontAtlasPostProcessData +{ + ImFontAtlas* FontAtlas; + ImFont* Font; + ImFontConfig* FontSrc; + ImFontGlyph* Glyph; + + // Pixel data + unsigned char* Pixels; + ImTextureFormat Format; + int Pitch; + int Width; + int Height; +}; + // Internal storage for incrementally packing and building a ImFontAtlas struct stbrp_context_opaque { char data[80]; }; struct stbrp_node; @@ -3714,9 +3731,9 @@ IMGUI_API void ImFontAtlasUpdateDrawListsSharedData(ImFontAtlas* at IMGUI_API void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas); -IMGUI_API void ImFontAtlasTextureBlockConvertAndPostProcess(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, ImFontGlyph* glyph, unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst, ImTextureFormat dst_fmt, int dst_pitch, int w, int h); IMGUI_API void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFormat src_fmt, int src_pitch, unsigned char* dst_pixels, ImTextureFormat dst_fmt, int dst_pitch, int w, int h); -IMGUI_API void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlas* atlas, ImFont* font, ImFontConfig* src, ImFontGlyph* glyph, unsigned char* pixels, ImTextureFormat format, int w, int h, int pitch, float in_multiply_factor); +IMGUI_API void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data); +IMGUI_API void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data, float multiply_factor); IMGUI_API void ImFontAtlasTextureBlockCopy(ImTextureData* src_tex, int src_x, int src_y, ImTextureData* dst_tex, int dst_x, int dst_y, int w, int h); IMGUI_API void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex, int x, int y, int w, int h); diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index a8dfa950e..efe8612ba 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -541,8 +541,9 @@ bool ImGui_ImplFreeType_FontAddGlyph(ImFontAtlas* atlas, ImFont* font, ImFontCon // Copy to texture, post-process and queue update for backend ImTextureData* tex = atlas->TexData; IM_ASSERT(r->x + r->w <= tex->Width && r->y + r->h <= tex->Height); - ImFontAtlasTextureBlockConvertAndPostProcess(atlas, font, src, &font->Glyphs.back(), - temp_buffer, ImTextureFormat_RGBA32, w * 4, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h); + ImFontAtlasTextureBlockConvert(temp_buffer, ImTextureFormat_RGBA32, w * 4, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h); + ImFontAtlasPostProcessData pp_data = { atlas, font, src, &font->Glyphs.back(), tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), w, h }; + ImFontAtlasTextureBlockPostProcess(&pp_data); ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h); } else