From 7ebd7ef9ac3e74ac147481c868912f0960b43451 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 17 Jan 2015 13:40:56 +0000 Subject: [PATCH] Added PushFont/PopFont API --- imgui.cpp | 58 +++++++++++++++++++++++++++++++++++++---------------- imgui.h | 60 ++++++++++++++++++++++++++++--------------------------- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6a569c7f9..3d18a0e4d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -323,6 +323,7 @@ static void RenderText(ImVec2 pos, const char* text, const char* text_en static void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); static void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); +static void SetFont(ImFont* font); static void ItemSize(ImVec2 size, ImVec2* adjust_start_offset = NULL); static void ItemSize(const ImGuiAabb& aabb, ImVec2* adjust_start_offset = NULL); static void PushColumnClipRect(int column_index = -1); @@ -345,9 +346,10 @@ static const char* ImStristr(const char* haystack, const char* needle, const ch static size_t ImFormatString(char* buf, size_t buf_size, const char* fmt, ...); static size_t ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args); -// Helpers: Data +// Helpers: Misc static ImU32 ImCrc32(const void* data, size_t data_size, ImU32 seed); static bool ImLoadFileToMemory(const char* filename, const char* file_open_mode, void** out_file_data, size_t* out_file_size, size_t padding_bytes = 0); +static int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } // Helpers: Color Conversion static ImU32 ImConvertColorFloat4ToU32(const ImVec4& in); @@ -873,8 +875,9 @@ struct ImGuiState bool Initialized; ImGuiIO IO; ImGuiStyle Style; - float FontSize; // == IO.FontGlobalScale * IO.Font->Scale * IO.Font->Info->FontSize. Vertical distance between two lines of text, aka == CalcTextSize(" ").y - ImVec2 FontTexUvWhitePixel; // == IO.Font->TexUvForWhite (cached copy) + ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() + float FontSize; // (Shortcut) == IO.FontGlobalScale * (Font->Scale * Font->FontSize). Vertical distance between two lines of text, aka == CalcTextSize(" ").y + ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvForWhite float Time; int FrameCount; @@ -893,6 +896,7 @@ struct ImGuiState ImVector Settings; ImVector ColorModifiers; ImVector StyleModifiers; + ImVector FontStack; ImVec2 SetNextWindowPosVal; ImGuiSetCondition SetNextWindowPosCond; ImVec2 SetNextWindowSizeVal; @@ -1003,7 +1007,7 @@ public: void FocusItemUnregister(); ImGuiAabb Aabb() const { return ImGuiAabb(Pos, Pos+Size); } - ImFont* Font() const { return GImGui.IO.Font; } + ImFont* Font() const { return GImGui.Font; } float FontSize() const { return GImGui.FontSize * FontWindowScale; } ImVec2 CursorPos() const { return DC.CursorPos; } float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0 : FontSize() + GImGui.Style.FramePadding.y * 2.0f; } @@ -1537,11 +1541,7 @@ void ImGui::NewFrame() g.Initialized = true; } - IM_ASSERT(g.IO.Font->Scale > 0.0f); - g.FontSize = g.IO.FontGlobalScale * g.IO.Font->FontSize * g.IO.Font->Scale; - g.FontTexUvWhitePixel = g.IO.Font->TexUvWhitePixel; - g.IO.Font->FallbackGlyph = NULL; - g.IO.Font->FallbackGlyph = g.IO.Font->FindGlyph(g.IO.Font->FallbackChar); + SetFont(g.IO.Font); g.Time += g.IO.DeltaTime; g.FrameCount += 1; @@ -2795,6 +2795,34 @@ float ImGui::GetItemWidth() return window->DC.ItemWidth.back(); } +static void SetFont(ImFont* font) +{ + ImGuiState& g = GImGui; + + IM_ASSERT(font->Scale > 0.0f); + g.Font = font; + g.FontSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; + g.FontTexUvWhitePixel = g.Font->TexUvWhitePixel; + g.Font->FallbackGlyph = NULL; + g.Font->FallbackGlyph = g.Font->FindGlyph(g.Font->FallbackChar); +} + +void ImGui::PushFont(ImFont* font) +{ + ImGuiState& g = GImGui; + + g.FontStack.push_back(font); + SetFont(font); +} + +void ImGui::PopFont() +{ + ImGuiState& g = GImGui; + + g.FontStack.pop_back(); + SetFont(g.FontStack.empty() ? g.IO.Font : g.FontStack.back()); +} + void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) { ImGuiWindow* window = GetCurrentWindow(); @@ -6432,8 +6460,6 @@ bool ImFont::LoadFromFileTTF(const char* filename, float size_pixels, const I return ret; } -static int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } - bool ImFont::LoadFromMemoryTTF(const void* data, size_t data_size, float size_pixels, const ImWchar* glyph_ranges, int font_no) { Clear(); @@ -6841,7 +6867,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const { if (!text_end) - text_end = text_begin + strlen(text_begin); // FIXME-OPT + text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. const float scale = size / FontSize; const float line_height = FontSize * scale; @@ -6890,8 +6916,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons if (c == '\n') { - if (text_size.x < line_width) - text_size.x = line_width; + text_size.x = ImMax(text_size.x, line_width); text_size.y += line_height; line_width = 0.0f; continue; @@ -6946,8 +6971,7 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be if (c == '\n') { - if (text_size.x < line_width) - text_size.x = line_width; + text_size.x = ImMax(text_size.x, line_width); text_size.y += line_height; line_width = 0.0f; continue; @@ -7435,7 +7459,7 @@ void ImGui::ShowTestWindow(bool* opened) if (ImGui::TreeNode("UTF-8 Text")) { // UTF-8 test with Japanese characters - // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) + // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) // Most compiler appears to support UTF-8 in source code (with Visual Studio you need to save your file as 'UTF-8 without signature') // However for the sake for maximum portability here we are *not* including raw UTF-8 character in this source file, instead we encode the string with hexadecimal constants. // In your own application be reasonable and use UTF-8 in source or retrieve the data from file system! diff --git a/imgui.h b/imgui.h index 368609b7d..3e1df04c7 100644 --- a/imgui.h +++ b/imgui.h @@ -178,6 +178,8 @@ namespace ImGui IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case. default to ~2/3 of windows width. IMGUI_API void PopItemWidth(); IMGUI_API float GetItemWidth(); + IMGUI_API void PushFont(ImFont* font); + IMGUI_API void PopFont(); IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets. IMGUI_API void PopAllowKeyboardFocus(); IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); @@ -753,16 +755,16 @@ struct ImFont float Scale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() ImVec2 DisplayOffset; // = (0.0f,0.0f) // Offset font rendering by xx pixels ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. - ImTextureID TexID; // = 0 // After loading texture, store your texture handle here (ignore if you aren't using multiple fonts/textures) + ImTextureID TexID; // = 0 // After loading texture, store your texture handle here (ignore if you aren't using multiple fonts/textures) - // Retrieve texture data + // Retrieve texture data // User is in charge of copying the pixels into graphics memory, then set 'TexID'. - // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white. - // If you intend to use large font it may be pref - // NB: the data is invalidated as soon as you call a Load* function. - IMGUI_API void GetTextureDataRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel - IMGUI_API void GetTextureDataAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel - IMGUI_API void ClearTextureData(); // Save RAM once the texture has been copied to graphics memory. + // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white. + // If you intend to use large font it may be pref + // NB: the data is invalidated as soon as you call a Load* function. + IMGUI_API void GetTextureDataRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel + IMGUI_API void GetTextureDataAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel + IMGUI_API void ClearTextureData(); // Save RAM once the texture has been copied to graphics memory. // Methods IMGUI_API ImFont(); @@ -772,7 +774,7 @@ struct ImFont IMGUI_API bool LoadFromMemoryTTF(const void* data, size_t data_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); IMGUI_API void Clear(); IMGUI_API void BuildLookupTable(); - struct Glyph; + struct Glyph; IMGUI_API const Glyph* FindGlyph(unsigned short c) const; IMGUI_API bool IsLoaded() const { return !Glyphs.empty(); } @@ -788,29 +790,29 @@ struct ImFont IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width = 0.0f) const; IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; - // Texture data - // Access via GetTextureData() which will load the font if not loaded - 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; - int TexHeight; - ImVec2 TexExtraDataPos; // Position of our rectangle where we draw non-font graphics - ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel (part of the TexExtraData block) + // Texture data + // Access via GetTextureData() which will load the font if not loaded + 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; + int TexHeight; + ImVec2 TexExtraDataPos; // Position of our rectangle where we draw non-font graphics + ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel (part of the TexExtraData block) - struct Glyph - { - ImWchar Codepoint; + struct Glyph + { + ImWchar Codepoint; signed short XAdvance; - signed short Width, Height; - signed short XOffset, YOffset; - float U0, V0, U1, V1; // Texture coordinates - }; + signed short Width, Height; + signed short XOffset, YOffset; + float U0, V0, U1, V1; // Texture coordinates + }; - // Runtime data - float FontSize; // Height of characters - ImVector Glyphs; - ImVector IndexLookup; - const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) + // Runtime data + float FontSize; // Height of characters + ImVector Glyphs; + ImVector IndexLookup; + const Glyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) }; //---- Include imgui_user.h at the end of imgui.h