mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 21:21:06 +01:00 
			
		
		
		
	Merge branch 'master' into navigation
This commit is contained in:
		| @@ -3751,7 +3751,7 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex | ||||
|         return ImVec2(0.0f, font_size); | ||||
|     ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); | ||||
|  | ||||
|     // Cancel out character spacing for the last character of a line (it is baked into glyph->XAdvance field) | ||||
|     // Cancel out character spacing for the last character of a line (it is baked into glyph->AdvanceX field) | ||||
|     const float font_scale = font_size / font->FontSize; | ||||
|     const float character_spacing_x = 1.0f * font_scale; | ||||
|     if (text_size.x > 0.0f) | ||||
| @@ -8750,7 +8750,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 | ||||
|     // Password pushes a temporary font with only a fallback glyph | ||||
|     if (is_password) | ||||
|     { | ||||
|         const ImFont::Glyph* glyph = g.Font->FindGlyph('*'); | ||||
|         const ImFontGlyph* glyph = g.Font->FindGlyph('*'); | ||||
|         ImFont* password_font = &g.InputTextPasswordFont; | ||||
|         password_font->FontSize = g.Font->FontSize; | ||||
|         password_font->Scale = g.Font->Scale; | ||||
| @@ -8759,8 +8759,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 | ||||
|         password_font->Descent = g.Font->Descent; | ||||
|         password_font->ContainerAtlas = g.Font->ContainerAtlas; | ||||
|         password_font->FallbackGlyph = glyph; | ||||
|         password_font->FallbackXAdvance = glyph->XAdvance; | ||||
|         IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexXAdvance.empty() && password_font->IndexLookup.empty()); | ||||
|         password_font->FallbackAdvanceX = glyph->AdvanceX; | ||||
|         IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty()); | ||||
|         PushFont(password_font); | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										108
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -905,7 +905,7 @@ struct ImGuiIO | ||||
|     ImVec2      MouseDelta;                 // Mouse delta. Note that this is zero if either current or previous position are negative, so a disappearing/reappearing mouse won't have a huge delta for one frame. | ||||
|  | ||||
|     //------------------------------------------------------------------ | ||||
|     // [Private] ImGui will maintain those fields. Forward compatibility not guaranteed! | ||||
|     // [Internal] ImGui will maintain those fields. Forward compatibility not guaranteed! | ||||
|     //------------------------------------------------------------------ | ||||
|  | ||||
|     ImVec2      MousePosPrev;               // Previous mouse position temporary storage (nb: not for public use, set to MousePos in NewFrame()) | ||||
| @@ -1375,7 +1375,7 @@ struct ImFontConfig | ||||
|     float           SizePixels;                 //          // Size in pixels for rasterizer. | ||||
|     int             OversampleH, OversampleV;   // 3, 1     // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. | ||||
|     bool            PixelSnapH;                 // false    // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. | ||||
|     ImVec2          GlyphExtraSpacing;          // 0, 0     // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. | ||||
|     ImVec2          GlyphExtraSpacing;          // 1, 0     // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. | ||||
|     ImVec2          GlyphOffset;                // 0, 0     // Offset all glyphs from this font input. | ||||
|     const ImWchar*  GlyphRanges;                // NULL     // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. | ||||
|     bool            MergeMode;                  // false    // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. | ||||
| @@ -1389,6 +1389,14 @@ struct ImFontConfig | ||||
|     IMGUI_API ImFontConfig(); | ||||
| }; | ||||
|  | ||||
| struct ImFontGlyph | ||||
| { | ||||
|     ImWchar         Codepoint;          // 0x0000..0xFFFF | ||||
|     float           AdvanceX;           // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) | ||||
|     float           X0, Y0, X1, Y1;     // Glyph corners | ||||
|     float           U0, V0, U1, V1;     // Texture coordinates | ||||
| }; | ||||
|  | ||||
| // 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. | ||||
| @@ -1412,25 +1420,29 @@ struct ImFontAtlas | ||||
|     IMGUI_API void              ClearFonts();               // Clear the ImGui-side font data (glyphs storage, UV coordinates) | ||||
|     IMGUI_API void              Clear();                    // Clear all | ||||
|  | ||||
|     // Retrieve texture data | ||||
|     // User is in charge of copying the pixels into graphics memory, then call SetTextureUserID() | ||||
|     // After loading the texture into your graphic system, store your texture handle in 'TexID' (ignore if you aren't using multiple fonts nor images) | ||||
|     // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white, so 75% of the memory is wasted. | ||||
|     // Build atlas, retrieve pixel data. | ||||
|     // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). | ||||
|     // RGBA32 format is provided for convenience and compatibility, but note that unless you use CustomRect to draw color data, the RGB pixels emitted from Fonts will all be white (~75% of waste).  | ||||
|     // Pitch = Width * BytesPerPixels | ||||
|     IMGUI_API bool              Build();                    // Build pixels data. This is called automatically for you by the GetTexData*** functions. | ||||
|     IMGUI_API void              GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL);  // 1 byte per-pixel | ||||
|     IMGUI_API void              GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL);  // 4 bytes-per-pixel | ||||
|     void                        SetTexID(ImTextureID id)  { TexID = id; } | ||||
|     void                        SetTexID(ImTextureID id)    { TexID = id; } | ||||
|  | ||||
|     //------------------------------------------- | ||||
|     // Glyph Ranges | ||||
|     //------------------------------------------- | ||||
|  | ||||
|     // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) | ||||
|     // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8"Hello world" syntax. See FAQ for details. | ||||
|     IMGUI_API const ImWchar*    GetGlyphRangesDefault();    // Basic Latin, Extended Latin | ||||
|     IMGUI_API const ImWchar*    GetGlyphRangesKorean();     // Default + Korean characters | ||||
|     IMGUI_API const ImWchar*    GetGlyphRangesJapanese();   // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs | ||||
|     IMGUI_API const ImWchar*    GetGlyphRangesChinese();    // Japanese + full set of about 21000 CJK Unified Ideographs | ||||
|     IMGUI_API const ImWchar*    GetGlyphRangesChinese();    // Default + Japanese + full set of about 21000 CJK Unified Ideographs | ||||
|     IMGUI_API const ImWchar*    GetGlyphRangesCyrillic();   // Default + about 400 Cyrillic characters | ||||
|     IMGUI_API const ImWchar*    GetGlyphRangesThai();       // Default + Thai characters | ||||
|  | ||||
|     // Helpers to build glyph ranges from text data. Feed all your application strings/characters to it then call BuildRanges(). | ||||
|     // Helpers to build glyph ranges from text data. Feed your application strings/characters to it then call BuildRanges(). | ||||
|     struct GlyphRangesBuilder | ||||
|     { | ||||
|         ImVector<unsigned char> UsedChars;  // Store 1-bit per Unicode code point (0=unused, 1=used) | ||||
| @@ -1443,57 +1455,64 @@ struct ImFontAtlas | ||||
|         IMGUI_API void BuildRanges(ImVector<ImWchar>* out_ranges);                  // Output new ranges | ||||
|     }; | ||||
|  | ||||
|     //------------------------------------------- | ||||
|     // Custom Rectangles/Glyphs API | ||||
|     //------------------------------------------- | ||||
|  | ||||
|     // You can request arbitrary rectangles to be packed into the atlas, for your own purposes. After calling Build(), you can query the rectangle position and render your pixels. | ||||
|     // You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), so you can render e.g. custom colorful icons and use them as regular glyphs. | ||||
|     struct CustomRect | ||||
|     { | ||||
|         unsigned int    ID;             // Input    // User ID. Use <0x10000 to map into a font glyph, >=0x10000 for other/internal/custom texture data. | ||||
|         unsigned short  Width, Height;  // Input    // Desired rectangle dimension | ||||
|         unsigned short  X, Y;           // Output   // Packed position in Atlas | ||||
|         float           GlyphAdvanceX;  // Input    // For custom font glyphs only (ID<0x10000): glyph xadvance | ||||
|         ImVec2          GlyphOffset;    // Input    // For custom font glyphs only (ID<0x10000): glyph display offset | ||||
|         ImFont*         Font;           // Input    // For custom font glyphs only (ID<0x10000): target font | ||||
|         CustomRect()            { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; } | ||||
|         bool IsPacked() const   { return X != 0xFFFF; } | ||||
|     }; | ||||
|  | ||||
|     IMGUI_API int       AddCustomRectRegular(unsigned int id, int width, int height);                                                                   // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList | ||||
|     IMGUI_API int       AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0));   // Id needs to be < 0x10000 to register a rectangle to map into a specific font. | ||||
|     IMGUI_API void      ClearCustomRects(); | ||||
|     IMGUI_API void      CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); | ||||
|     const CustomRect*   GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; } | ||||
|  | ||||
|     //------------------------------------------- | ||||
|     // Members | ||||
|     // (Access texture data via GetTexData*() calls which will setup a default font for you.) | ||||
|     //------------------------------------------- | ||||
|  | ||||
|     ImTextureID                 TexID;              // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. | ||||
|     int                         TexDesiredWidth;    // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. | ||||
|     int                         TexGlyphPadding;    // Padding between glyphs within texture in pixels. Defaults to 1. | ||||
|  | ||||
|     // [Internal] | ||||
|     // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. | ||||
|     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(). | ||||
|     int                         TexHeight;          // Texture height calculated during Build(). | ||||
|     int                         TexDesiredWidth;    // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. | ||||
|     int                         TexGlyphPadding;    // Padding between glyphs within texture in pixels. Defaults to 1. | ||||
|     ImVec2                      TexUvWhitePixel;    // Texture coordinates to a white pixel | ||||
|     ImVector<ImFont*>           Fonts;              // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. | ||||
|  | ||||
|     // [Private] User rectangle for packing custom texture data into the atlas. | ||||
|     struct CustomRect | ||||
|     { | ||||
|         unsigned int    ID;             // Input    // User ID. <0x10000 for font mapped data (WIP/UNSUPPORTED), >=0x10000 for other texture data | ||||
|         unsigned short  Width, Height;  // Input    // Desired rectangle dimension | ||||
|         unsigned short  X, Y;           // Output   // Packed position in Atlas | ||||
|         CustomRect()            { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; } | ||||
|         bool IsPacked() const   { return X != 0xFFFF; } | ||||
|     }; | ||||
|  | ||||
|     // [Private] Members | ||||
|     ImVector<CustomRect>        CustomRects;        // Rectangles for packing custom texture data into the atlas. | ||||
|     ImVector<ImFontConfig>      ConfigData;         // Internal data | ||||
|     IMGUI_API bool              Build();            // Build pixels data. This is automatically for you by the GetTexData*** functions. | ||||
|     IMGUI_API int               CustomRectRegister(unsigned int id, int width, int height); | ||||
|     IMGUI_API void              CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); | ||||
|     int                         CustomRectIds[1];   // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList | ||||
| }; | ||||
|  | ||||
| // Font runtime data and rendering | ||||
| // ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). | ||||
| struct ImFont | ||||
| { | ||||
|     struct Glyph | ||||
|     { | ||||
|         ImWchar                 Codepoint; | ||||
|         float                   XAdvance; | ||||
|         float                   X0, Y0, X1, Y1; | ||||
|         float                   U0, V0, U1, V1;     // Texture coordinates | ||||
|     }; | ||||
|  | ||||
|     // Members: Hot ~62/78 bytes | ||||
|     float                       FontSize;           // <user set>   // Height of characters, set during loading (don't change after loading) | ||||
|     float                       Scale;              // = 1.f        // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() | ||||
|     ImVec2                      DisplayOffset;      // = (0.f,1.f)  // Offset font rendering by xx pixels | ||||
|     ImVector<Glyph>             Glyphs;             //              // All glyphs. | ||||
|     ImVector<float>             IndexXAdvance;      //              // Sparse. Glyphs->XAdvance in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). | ||||
|     ImVector<ImFontGlyph>       Glyphs;             //              // All glyphs. | ||||
|     ImVector<float>             IndexAdvanceX;      //              // Sparse. Glyphs->AdvanceX in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). | ||||
|     ImVector<unsigned short>    IndexLookup;        //              // Sparse. Index glyphs by Unicode code-point. | ||||
|     const Glyph*                FallbackGlyph;      // == FindGlyph(FontFallbackChar) | ||||
|     float                       FallbackXAdvance;   // == FallbackGlyph->XAdvance | ||||
|     const ImFontGlyph*          FallbackGlyph;      // == FindGlyph(FontFallbackChar) | ||||
|     float                       FallbackAdvanceX;   // == FallbackGlyph->AdvanceX | ||||
|     ImWchar                     FallbackChar;       // = '?'        // Replacement glyph if one isn't found. Only set via SetFallbackChar() | ||||
|  | ||||
|     // Members: Cold ~18/26 bytes | ||||
| @@ -1508,9 +1527,9 @@ struct ImFont | ||||
|     IMGUI_API ~ImFont(); | ||||
|     IMGUI_API void              Clear(); | ||||
|     IMGUI_API void              BuildLookupTable(); | ||||
|     IMGUI_API const Glyph*      FindGlyph(ImWchar c) const; | ||||
|     IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; | ||||
|     IMGUI_API void              SetFallbackChar(ImWchar c); | ||||
|     float                       GetCharAdvance(ImWchar c) const     { return ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] : FallbackXAdvance; } | ||||
|     float                       GetCharAdvance(ImWchar c) const     { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } | ||||
|     bool                        IsLoaded() const                    { return ContainerAtlas != NULL; } | ||||
|  | ||||
|     // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. | ||||
| @@ -1520,9 +1539,14 @@ struct ImFont | ||||
|     IMGUI_API void              RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; | ||||
|     IMGUI_API void              RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; | ||||
|  | ||||
|     // Private | ||||
|     // [Internal] | ||||
|     IMGUI_API void              GrowIndex(int new_size); | ||||
|     IMGUI_API void              AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); | ||||
|     IMGUI_API void              AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. | ||||
|  | ||||
| #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS | ||||
|     typedef ImFontGlyph Glyph; // OBSOLETE 1.52+ | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| #if defined(__clang__) | ||||
|   | ||||
| @@ -1937,7 +1937,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) | ||||
|                 if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) | ||||
|                 { | ||||
|                     // Display all glyphs of the fonts in separate pages of 256 characters | ||||
|                     const ImFont::Glyph* glyph_fallback = font->FallbackGlyph; // Forcefully/dodgily make FindGlyph() return NULL on fallback, which isn't the default behavior. | ||||
|                     const ImFontGlyph* glyph_fallback = font->FallbackGlyph; // Forcefully/dodgily make FindGlyph() return NULL on fallback, which isn't the default behavior. | ||||
|                     font->FallbackGlyph = NULL; | ||||
|                     for (int base = 0; base < 0x10000; base += 256) | ||||
|                     { | ||||
| @@ -1954,7 +1954,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) | ||||
|                             { | ||||
|                                 ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size.x + cell_spacing), base_pos.y + (n / 16) * (cell_size.y + cell_spacing)); | ||||
|                                 ImVec2 cell_p2(cell_p1.x + cell_size.x, cell_p1.y + cell_size.y); | ||||
|                                 const ImFont::Glyph* glyph = font->FindGlyph((ImWchar)(base+n));; | ||||
|                                 const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base+n));; | ||||
|                                 draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50)); | ||||
|                                 font->RenderChar(draw_list, cell_size.x, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. | ||||
|                                 if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) | ||||
| @@ -1962,7 +1962,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) | ||||
|                                     ImGui::BeginTooltip(); | ||||
|                                     ImGui::Text("Codepoint: U+%04X", base+n); | ||||
|                                     ImGui::Separator(); | ||||
|                                     ImGui::Text("XAdvance+1: %.1f", glyph->XAdvance); | ||||
|                                     ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX); | ||||
|                                     ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); | ||||
|                                     ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); | ||||
|                                     ImGui::EndTooltip(); | ||||
|   | ||||
							
								
								
									
										147
									
								
								imgui_draw.cpp
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								imgui_draw.cpp
									
									
									
									
									
								
							| @@ -1066,7 +1066,7 @@ ImFontConfig::ImFontConfig() | ||||
| // The white texels on the top left are the ones we'll use everywhere in ImGui to render filled shapes. | ||||
| const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 90; | ||||
| const int FONT_ATLAS_DEFAULT_TEX_DATA_H      = 27; | ||||
| const int FONT_ATLAS_DEFAULT_TEX_DATA_ID     = 0xF0000; | ||||
| const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000; | ||||
| const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = | ||||
| { | ||||
|     "..-         -XXXXXXX-    X    -           X           -XXXXXXX          -          XXXXXXX" | ||||
| @@ -1101,11 +1101,14 @@ const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF | ||||
| ImFontAtlas::ImFontAtlas() | ||||
| { | ||||
|     TexID = NULL; | ||||
|     TexDesiredWidth = 0; | ||||
|     TexGlyphPadding = 1; | ||||
|     TexPixelsAlpha8 = NULL; | ||||
|     TexPixelsRGBA32 = NULL; | ||||
|     TexWidth = TexHeight = TexDesiredWidth = 0; | ||||
|     TexGlyphPadding = 1; | ||||
|     TexWidth = TexHeight = 0; | ||||
|     TexUvWhitePixel = ImVec2(0, 0); | ||||
|     for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) | ||||
|         CustomRectIds[n] = -1; | ||||
| } | ||||
|  | ||||
| ImFontAtlas::~ImFontAtlas() | ||||
| @@ -1122,7 +1125,7 @@ void    ImFontAtlas::ClearInputData() | ||||
|             ConfigData[i].FontData = NULL; | ||||
|         } | ||||
|  | ||||
|     // When clearing this we lose access to the font name and other information used to build the font. | ||||
|     // When clearing this we lose access to  the font name and other information used to build the font. | ||||
|     for (int i = 0; i < Fonts.Size; i++) | ||||
|         if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) | ||||
|         { | ||||
| @@ -1318,8 +1321,9 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed | ||||
|     return font; | ||||
| } | ||||
|  | ||||
| int ImFontAtlas::CustomRectRegister(unsigned int id, int width, int height) | ||||
| int ImFontAtlas::AddCustomRectRegular(unsigned int id, int width, int height) | ||||
| { | ||||
|     IM_ASSERT(id >= 0x10000); | ||||
|     IM_ASSERT(width > 0 && width <= 0xFFFF); | ||||
|     IM_ASSERT(height > 0 && height <= 0xFFFF); | ||||
|     CustomRect r; | ||||
| @@ -1330,7 +1334,23 @@ int ImFontAtlas::CustomRectRegister(unsigned int id, int width, int height) | ||||
|     return CustomRects.Size - 1; // Return index | ||||
| } | ||||
|  | ||||
| void ImFontAtlas::CustomRectCalcUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) | ||||
| int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset) | ||||
| { | ||||
|     IM_ASSERT(font != NULL); | ||||
|     IM_ASSERT(width > 0 && width <= 0xFFFF); | ||||
|     IM_ASSERT(height > 0 && height <= 0xFFFF); | ||||
|     CustomRect r; | ||||
|     r.ID = id; | ||||
|     r.Width = (unsigned short)width; | ||||
|     r.Height = (unsigned short)height; | ||||
|     r.GlyphAdvanceX = advance_x; | ||||
|     r.GlyphOffset = offset; | ||||
|     r.Font = font; | ||||
|     CustomRects.push_back(r); | ||||
|     return CustomRects.Size - 1; // Return index | ||||
| } | ||||
|  | ||||
| void ImFontAtlas::CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) | ||||
| { | ||||
|     IM_ASSERT(TexWidth > 0 && TexHeight > 0);   // Font atlas needs to be built before we can calculate UV coordinates | ||||
|     IM_ASSERT(rect->IsPacked());                // Make sure the rectangle has been packed | ||||
| @@ -1535,26 +1555,9 @@ bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) | ||||
|                 stbtt_aligned_quad q; | ||||
|                 float dummy_x = 0.0f, dummy_y = 0.0f; | ||||
|                 stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); | ||||
|  | ||||
|                 dst_font->Glyphs.resize(dst_font->Glyphs.Size + 1); | ||||
|                 ImFont::Glyph& glyph = dst_font->Glyphs.back(); | ||||
|                 glyph.Codepoint = (ImWchar)codepoint; | ||||
|                 glyph.X0 = q.x0 + off_x;  | ||||
|                 glyph.Y0 = q.y0 + off_y;  | ||||
|                 glyph.X1 = q.x1 + off_x;  | ||||
|                 glyph.Y1 = q.y1 + off_y; | ||||
|                 glyph.U0 = q.s0;  | ||||
|                 glyph.V0 = q.t0;  | ||||
|                 glyph.U1 = q.s1;  | ||||
|                 glyph.V1 = q.t1; | ||||
|                 glyph.XAdvance = (pc.xadvance + cfg.GlyphExtraSpacing.x);  // Bake spacing into XAdvance | ||||
|  | ||||
|                 if (cfg.PixelSnapH) | ||||
|                     glyph.XAdvance = (float)(int)(glyph.XAdvance + 0.5f); | ||||
|                 dst_font->MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * atlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * atlas->TexHeight + 1.99f); // +1 to account for average padding, +0.99 to round | ||||
|                 dst_font->AddGlyph((ImWchar)codepoint, q.x0 + off_x, q.y0 + off_y, q.x1 + off_x, q.y1 + off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance); | ||||
|             } | ||||
|         } | ||||
|         cfg.DstFont->BuildLookupTable(); | ||||
|     } | ||||
|  | ||||
|     // Cleanup temporaries | ||||
| @@ -1562,17 +1565,15 @@ bool    ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) | ||||
|     ImGui::MemFree(buf_ranges); | ||||
|     ImGui::MemFree(tmp_array); | ||||
|  | ||||
|     // Render into our custom data block | ||||
|     ImFontAtlasBuildRenderDefaultTexData(atlas); | ||||
|     ImFontAtlasBuildFinish(atlas); | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas) | ||||
| { | ||||
|     // FIXME-WIP: We should register in the constructor (but cannot because our static instances may not have allocator ready by the time they initialize). This needs to be fixed because we can expose CustomRects. | ||||
|     if (atlas->CustomRects.empty()) | ||||
|         atlas->CustomRectRegister(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); | ||||
|     if (atlas->CustomRectIds[0] < 0) | ||||
|         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); | ||||
| } | ||||
|  | ||||
| void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) | ||||
| @@ -1615,9 +1616,10 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaq | ||||
|         } | ||||
| } | ||||
|  | ||||
| void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) | ||||
| static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) | ||||
| { | ||||
|     ImFontAtlas::CustomRect& r = atlas->CustomRects[0]; | ||||
|     IM_ASSERT(atlas->CustomRectIds[0] >= 0); | ||||
|     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); | ||||
| @@ -1665,6 +1667,29 @@ void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImFontAtlasBuildFinish(ImFontAtlas* atlas) | ||||
| { | ||||
|     // Render into our custom data block | ||||
|     ImFontAtlasBuildRenderDefaultTexData(atlas); | ||||
|  | ||||
|     // Register custom rectangle glyphs | ||||
|     for (int i = 0; i < atlas->CustomRects.Size; i++) | ||||
|     { | ||||
|         const ImFontAtlas::CustomRect& r = atlas->CustomRects[i]; | ||||
|         if (r.Font == NULL || r.ID > 0x10000) | ||||
|             continue; | ||||
|  | ||||
|         IM_ASSERT(r.Font->ContainerAtlas == atlas); | ||||
|         ImVec2 uv0, uv1; | ||||
|         atlas->CalcCustomRectUV(&r, &uv0, &uv1); | ||||
|         r.Font->AddGlyph((ImWchar)r.ID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); | ||||
|     } | ||||
|  | ||||
|     // Build all fonts lookup tables | ||||
|     for (int i = 0; i < atlas->Fonts.Size; i++) | ||||
|         atlas->Fonts[i]->BuildLookupTable(); | ||||
| } | ||||
|  | ||||
| // Retrieve list of range (2 int per range, values are inclusive) | ||||
| const ImWchar*   ImFontAtlas::GetGlyphRangesDefault() | ||||
| { | ||||
| @@ -1858,10 +1883,10 @@ void    ImFont::Clear() | ||||
|     FontSize = 0.0f; | ||||
|     DisplayOffset = ImVec2(0.0f, 1.0f); | ||||
|     Glyphs.clear(); | ||||
|     IndexXAdvance.clear(); | ||||
|     IndexAdvanceX.clear(); | ||||
|     IndexLookup.clear(); | ||||
|     FallbackGlyph = NULL; | ||||
|     FallbackXAdvance = 0.0f; | ||||
|     FallbackAdvanceX = 0.0f; | ||||
|     ConfigDataCount = 0; | ||||
|     ConfigData = NULL; | ||||
|     ContainerAtlas = NULL; | ||||
| @@ -1876,13 +1901,13 @@ void ImFont::BuildLookupTable() | ||||
|         max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); | ||||
|  | ||||
|     IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved | ||||
|     IndexXAdvance.clear(); | ||||
|     IndexAdvanceX.clear(); | ||||
|     IndexLookup.clear(); | ||||
|     GrowIndex(max_codepoint + 1); | ||||
|     for (int i = 0; i < Glyphs.Size; i++) | ||||
|     { | ||||
|         int codepoint = (int)Glyphs[i].Codepoint; | ||||
|         IndexXAdvance[codepoint] = Glyphs[i].XAdvance; | ||||
|         IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX; | ||||
|         IndexLookup[codepoint] = (unsigned short)i; | ||||
|     } | ||||
|  | ||||
| @@ -1892,20 +1917,20 @@ void ImFont::BuildLookupTable() | ||||
|     { | ||||
|         if (Glyphs.back().Codepoint != '\t')   // So we can call this function multiple times | ||||
|             Glyphs.resize(Glyphs.Size + 1); | ||||
|         ImFont::Glyph& tab_glyph = Glyphs.back(); | ||||
|         ImFontGlyph& tab_glyph = Glyphs.back(); | ||||
|         tab_glyph = *FindGlyph((unsigned short)' '); | ||||
|         tab_glyph.Codepoint = '\t'; | ||||
|         tab_glyph.XAdvance *= 4; | ||||
|         IndexXAdvance[(int)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance; | ||||
|         tab_glyph.AdvanceX *= 4; | ||||
|         IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; | ||||
|         IndexLookup[(int)tab_glyph.Codepoint] = (unsigned short)(Glyphs.Size-1); | ||||
|     } | ||||
|  | ||||
|     FallbackGlyph = NULL; | ||||
|     FallbackGlyph = FindGlyph(FallbackChar); | ||||
|     FallbackXAdvance = FallbackGlyph ? FallbackGlyph->XAdvance : 0.0f; | ||||
|     FallbackAdvanceX = FallbackGlyph ? FallbackGlyph->AdvanceX : 0.0f; | ||||
|     for (int i = 0; i < max_codepoint + 1; i++) | ||||
|         if (IndexXAdvance[i] < 0.0f) | ||||
|             IndexXAdvance[i] = FallbackXAdvance; | ||||
|         if (IndexAdvanceX[i] < 0.0f) | ||||
|             IndexAdvanceX[i] = FallbackAdvanceX; | ||||
| } | ||||
|  | ||||
| void ImFont::SetFallbackChar(ImWchar c) | ||||
| @@ -1916,13 +1941,35 @@ void ImFont::SetFallbackChar(ImWchar c) | ||||
|  | ||||
| void ImFont::GrowIndex(int new_size) | ||||
| { | ||||
|     IM_ASSERT(IndexXAdvance.Size == IndexLookup.Size); | ||||
|     IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size); | ||||
|     if (new_size <= IndexLookup.Size) | ||||
|         return; | ||||
|     IndexXAdvance.resize(new_size, -1.0f); | ||||
|     IndexAdvanceX.resize(new_size, -1.0f); | ||||
|     IndexLookup.resize(new_size, (unsigned short)-1); | ||||
| } | ||||
|  | ||||
| void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x) | ||||
| { | ||||
|     Glyphs.resize(Glyphs.Size + 1); | ||||
|     ImFontGlyph& glyph = Glyphs.back(); | ||||
|     glyph.Codepoint = (ImWchar)codepoint; | ||||
|     glyph.X0 = x0;  | ||||
|     glyph.Y0 = y0;  | ||||
|     glyph.X1 = x1;  | ||||
|     glyph.Y1 = y1; | ||||
|     glyph.U0 = u0;  | ||||
|     glyph.V0 = v0;  | ||||
|     glyph.U1 = u1;  | ||||
|     glyph.V1 = v1; | ||||
|     glyph.AdvanceX = advance_x + ConfigData->GlyphExtraSpacing.x;  // Bake spacing into AdvanceX | ||||
|  | ||||
|     if (ConfigData->PixelSnapH) | ||||
|         glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f); | ||||
|      | ||||
|     // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round) | ||||
|     MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f); | ||||
| } | ||||
|  | ||||
| void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) | ||||
| { | ||||
|     IM_ASSERT(IndexLookup.Size > 0);    // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function. | ||||
| @@ -1935,10 +1982,10 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) | ||||
|  | ||||
|     GrowIndex(dst + 1); | ||||
|     IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (unsigned short)-1; | ||||
|     IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f; | ||||
|     IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f; | ||||
| } | ||||
|  | ||||
| const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const | ||||
| const ImFontGlyph* ImFont::FindGlyph(unsigned short c) const | ||||
| { | ||||
|     if (c < IndexLookup.Size) | ||||
|     { | ||||
| @@ -2003,7 +2050,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance); | ||||
|         const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX); | ||||
|         if (ImCharIsSpace(c)) | ||||
|         { | ||||
|             if (inside_word) | ||||
| @@ -2120,7 +2167,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons | ||||
|                 continue; | ||||
|         } | ||||
|  | ||||
|         const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance) * scale; | ||||
|         const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX) * scale; | ||||
|         if (line_width + char_width >= max_width) | ||||
|         { | ||||
|             s = prev_s; | ||||
| @@ -2146,7 +2193,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col | ||||
| { | ||||
|     if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. | ||||
|         return; | ||||
|     if (const Glyph* glyph = FindGlyph(c)) | ||||
|     if (const ImFontGlyph* glyph = FindGlyph(c)) | ||||
|     { | ||||
|         float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; | ||||
|         pos.x = (float)(int)pos.x + DisplayOffset.x; | ||||
| @@ -2250,9 +2297,9 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col | ||||
|         } | ||||
|  | ||||
|         float char_width = 0.0f; | ||||
|         if (const Glyph* glyph = FindGlyph((unsigned short)c)) | ||||
|         if (const ImFontGlyph* glyph = FindGlyph((unsigned short)c)) | ||||
|         { | ||||
|             char_width = glyph->XAdvance * scale; | ||||
|             char_width = glyph->AdvanceX * scale; | ||||
|  | ||||
|             // Arbitrarily assume that both space and tabs are empty glyphs as an optimization | ||||
|             if (c != ' ' && c != '\t') | ||||
|   | ||||
| @@ -921,7 +921,7 @@ IMGUI_API bool              ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas); | ||||
| IMGUI_API void              ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); | ||||
| IMGUI_API void              ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);  | ||||
| IMGUI_API void              ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); | ||||
| IMGUI_API void              ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas); | ||||
| IMGUI_API void              ImFontAtlasBuildFinish(ImFontAtlas* atlas); | ||||
| IMGUI_API void              ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); | ||||
| IMGUI_API void              ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user