From fed0a884f721dcdd200a42631b2487dd1d56e113 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 14 Feb 2018 11:57:51 +0100 Subject: [PATCH] ImFontAtlas: Added ImFontAtlasFlags_NoPowerOfTwoHeight, ImFontAtlasFlags_NoMouseCursors flags. (#1613) --- imgui.h | 8 ++++++ imgui_draw.cpp | 44 ++++++++++++++++++++++---------- misc/freetype/imgui_freetype.cpp | 2 +- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/imgui.h b/imgui.h index 03f593e09b2f..61f6033a83d3 100644 --- a/imgui.h +++ b/imgui.h @@ -87,6 +87,7 @@ typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ typedef int ImDrawListFlags; // flags: for ImDrawList // enum ImDrawListFlags_ +typedef int ImFontAtlasFlags; // flags: for ImFontAtlas // enum ImFontAtlasFlags_ typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ @@ -1612,6 +1613,12 @@ struct ImFontGlyph float U0, V0, U1, V1; // Texture coordinates }; +enum ImFontAtlasFlags_ +{ + ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two + ImFontAtlasFlags_NoMouseCursors = 1 << 1 // Don't build software mouse cursors into the atlas +}; + // Load and rasterize multiple TTF/OTF fonts into a same texture. // Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering. // We also add custom graphic data into the texture that serves for ImGui. @@ -1706,6 +1713,7 @@ struct ImFontAtlas // [Internal] // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. + ImFontAtlasFlags Flags; // Build flags unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 int TexWidth; // Texture width calculated during Build(). diff --git a/imgui_draw.cpp b/imgui_draw.cpp index e7abffb5ff18..037e5263aa62 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1368,6 +1368,7 @@ ImFontAtlas::ImFontAtlas() TexWidth = TexHeight = 0; TexUvScale = ImVec2(0.0f, 0.0f); TexUvWhitePixel = ImVec2(0.0f, 0.0f); + Flags = 0x00; for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) CustomRectIds[n] = -1; } @@ -1619,6 +1620,8 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou { if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_Count_) return false; + if (Flags & ImFontAtlasFlags_NoMouseCursors) + return false; ImFontAtlas::CustomRect& r = CustomRects[CustomRectIds[0]]; IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); @@ -1774,7 +1777,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) IM_ASSERT(buf_ranges_n == total_ranges_count); // Create texture - atlas->TexHeight = ImUpperPowerOfTwo(atlas->TexHeight); + atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); @@ -1854,8 +1857,12 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas) { - if (atlas->CustomRectIds[0] < 0) + if (atlas->CustomRectIds[0] >= 0) + return; + if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); + else + atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, 2, 2); } void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) @@ -1901,22 +1908,31 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaq static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) { IM_ASSERT(atlas->CustomRectIds[0] >= 0); + IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); ImFontAtlas::CustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]]; IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); - IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1); - IM_ASSERT(r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); IM_ASSERT(r.IsPacked()); - IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); - // Render/copy pixels - for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) - for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) - { - const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * atlas->TexWidth; - const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; - atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; - atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; - } + const int w = atlas->TexWidth; + if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) + { + // Render/copy pixels + IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); + for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) + for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) + { + const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * w; + const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; + atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; + atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; + } + } + else + { + IM_ASSERT(r.Width == 2 && r.Height == 2); + const int offset = (int)(r.X) + (int)(r.Y) * w; + atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF; + } atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * atlas->TexUvScale.x, (r.Y + 0.5f) * atlas->TexUvScale.y); } diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 9e373c7dd8c0..0a80bbdfb7d7 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -295,7 +295,7 @@ bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags) atlas->TexHeight = (int)(min_rects_per_column * (max_glyph_size.y + 1.0f)); // Create texture - atlas->TexHeight = ImUpperPowerOfTwo(atlas->TexHeight); + atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight);