move rescale into internal

This commit is contained in:
Green Sky 2026-02-19 19:10:23 +01:00
parent 2bc8becab2
commit 0271607fb3
No known key found for this signature in database
GPG Key ID: DBE05085D874AB4A
3 changed files with 67 additions and 66 deletions

View File

@ -2885,6 +2885,71 @@ void ImFontAtlasTextureBlockConvert(const unsigned char* src_pixels, ImTextureFo
}
}
void ImFontAtlasTextureBlockResize(const ImU32* src_pixels, const int src_w, const int src_h, ImU32* dst_pixels, const int dst_w, const int dst_h)
{
#if 0
// Point Sampling / Nearest Neighbor
for (int y = 0; y < dst_h; y++)
{
const int src_y = ImFloor(((y + 0.5f) * src_h) / dst_h);
for (int x = 0; x < dst_w; x++)
{
const int src_x = ImFloor(((x + 0.5f) * src_w) / dst_w);
dst_pixels[y * dst_w + x] = src_pixels[src_y * src_w + src_x];
}
}
#else
// Box sampling - Imagine projecting the new, smaller pixels onto the larger source, covering multiple pixel.
for (int y = 0; y < dst_h; y++)
{
for (int x = 0; x < dst_w; x++)
{
// We perform a weighted mean.
ImVec4 color;
float weight_sum = 0.0f;
// Walk from upper edge to bottom edge (vertical)
const float edge_up = ((float)y * src_h) / dst_h;
const float edge_down = ((y + 1.0f) * src_h) / dst_h;
for (float frac_pos_y = edge_up; frac_pos_y < edge_down;)
{
const int src_y = (int)ImFloor(frac_pos_y); IM_ASSERT(src_y < src_h);
const float frac_y = 1.0f - (frac_pos_y - src_y);
// Walk from left edge to right edge (horizontal)
const float edge_left = ((float)x * src_w) / dst_w;
const float edge_right = ((x + 1.0f) * src_w) / dst_w;
for (float frac_pos_x = edge_left; frac_pos_x < edge_right;)
{
const int src_x = (int)ImFloor(frac_pos_x); IM_ASSERT(src_x < src_w);
const float frac_x = 1.0f - (frac_pos_x - src_x);
const float src_pixel_weight = frac_x * frac_y;
const ImVec4 pixel_color = ImGui::ColorConvertU32ToFloat4(src_pixels[src_y * src_w + src_x]);
color.x += pixel_color.x * src_pixel_weight;
color.y += pixel_color.y * src_pixel_weight;
color.z += pixel_color.z * src_pixel_weight;
color.w += pixel_color.w * src_pixel_weight;
weight_sum += src_pixel_weight;
frac_pos_x += frac_x;
}
frac_pos_y += frac_y;
}
color.x /= weight_sum;
color.y /= weight_sum;
color.z /= weight_sum;
color.w /= weight_sum;
dst_pixels[y * dst_w + x] = ImGui::ColorConvertFloat4ToU32(color);
}
}
#endif
}
// Source buffer may be written to (used for in-place mods).
// Post-process hooks may eventually be added here.
void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data)

View File

@ -3958,6 +3958,7 @@ IMGUI_API void ImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atla
IMGUI_API void ImFontAtlasUpdateDrawListsSharedData(ImFontAtlas* atlas);
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 ImFontAtlasTextureBlockResize(const ImU32* src_pixels, const int src_w, const int src_h, ImU32* dst_pixels, const int dst_w, const int dst_h);
IMGUI_API void ImFontAtlasTextureBlockPostProcess(ImFontAtlasPostProcessData* data);
IMGUI_API void ImFontAtlasTextureBlockPostProcessMultiply(ImFontAtlasPostProcessData* data, float multiply_factor);
IMGUI_API void ImFontAtlasTextureBlockFill(ImTextureData* dst_tex, int dst_x, int dst_y, int w, int h, ImU32 col);

View File

@ -512,71 +512,6 @@ static void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig
bd_baked_data->~ImGui_ImplFreeType_FontSrcBakedData(); // ~IM_PLACEMENT_DELETE()
}
static void RescaleBitmap(uint32_t* dst, const int dst_w, const int dst_h, uint32_t* src, const int src_w, const int src_h)
{
#if 0
// Point Sampling / Nearest Neighbor
for (int y = 0; y < dst_h; y++)
{
const int src_y = ImFloor(((y + 0.5f) * src_h) / dst_h);
for (int x = 0; x < dst_w; x++)
{
const int src_x = ImFloor(((x + 0.5f) * src_w) / dst_w);
dst[y * dst_w + x] = src[src_y * src_w + src_x];
}
}
#else
// Box sampling - Imagine projecting the new, smaller pixels onto the larger source, covering multiple pixel.
for (int y = 0; y < dst_h; y++)
{
for (int x = 0; x < dst_w; x++)
{
// We perform a weighted mean.
ImVec4 color;
float weight_sum = 0.0f;
// Walk from upper edge to bottom edge (vertical)
const float edge_up = ((float)y * src_h) / dst_h;
const float edge_down = ((y + 1.0f) * src_h) / dst_h;
for (float frac_pos_y = edge_up; frac_pos_y < edge_down;)
{
const int src_y = (int)ImFloor(frac_pos_y); IM_ASSERT(src_y < src_h);
const float frac_y = 1.0f - (frac_pos_y - src_y);
// Walk from left edge to right edge (horizontal)
const float edge_left = ((float)x * src_w) / dst_w;
const float edge_right = ((x + 1.0f) * src_w) / dst_w;
for (float frac_pos_x = edge_left; frac_pos_x < edge_right;)
{
const int src_x = (int)ImFloor(frac_pos_x); IM_ASSERT(src_x < src_w);
const float frac_x = 1.0f - (frac_pos_x - src_x);
const float src_pixel_weight = frac_x * frac_y;
const ImVec4 pixel_color = ImGui::ColorConvertU32ToFloat4(src[src_y * src_w + src_x]);
color.x += pixel_color.x * src_pixel_weight;
color.y += pixel_color.y * src_pixel_weight;
color.z += pixel_color.z * src_pixel_weight;
color.w += pixel_color.w * src_pixel_weight;
weight_sum += src_pixel_weight;
frac_pos_x += frac_x;
}
frac_pos_y += frac_y;
}
color.x /= weight_sum;
color.y /= weight_sum;
color.z /= weight_sum;
color.w /= weight_sum;
dst[y * dst_w + x] = ImGui::ColorConvertFloat4ToU32(color);
}
}
#endif
}
static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint, ImFontGlyph* out_glyph, float* out_advance_x)
{
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
@ -663,7 +598,7 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf
uint32_t* dst_buffer = temp_buffer + bitmap_w * bitmap_h;
// Perform rescale, from temp_buffer (bitmap_w * bitmap_h) to dst_buffer (w * h)
RescaleBitmap(dst_buffer, w, h, temp_buffer, bitmap_w, bitmap_h);
ImFontAtlasTextureBlockResize(temp_buffer, bitmap_w, bitmap_h, dst_buffer, w, h);
// Redirect to rescaled part of the buffer
temp_buffer = dst_buffer;