Browse Source

Added PushFont/PopFont API

ocornut 10 years ago
parent
commit
7ebd7ef9ac
2 changed files with 74 additions and 48 deletions
  1. 41 17
      imgui.cpp
  2. 33 31
      imgui.h

+ 41 - 17
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<ImGuiIniData*> Settings;
     ImVector<ImGuiColMod>   ColorModifiers;
     ImVector<ImGuiStyleMod> StyleModifiers;
+    ImVector<ImFont*>       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!

+ 33 - 31
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)
-
-	struct Glyph
-	{
-		ImWchar         Codepoint;
+    // 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;
 		signed short    XAdvance;
-		signed short    Width, Height;
-		signed short    XOffset, YOffset;
-		float           U0, V0, U1, V1;     // Texture coordinates
-	};
-
-	// Runtime data
-	float               FontSize;           // Height of characters
-	ImVector<Glyph>     Glyphs;
-	ImVector<int>       IndexLookup;
-	const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
+        signed short    Width, Height;
+        signed short    XOffset, YOffset;
+        float           U0, V0, U1, V1;     // Texture coordinates
+    };
+
+    // Runtime data
+    float               FontSize;           // Height of characters
+    ImVector<Glyph>     Glyphs;
+    ImVector<int>       IndexLookup;
+    const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
 };
 
 //---- Include imgui_user.h at the end of imgui.h