|
@@ -14,7 +14,7 @@ Index of this file:
|
|
|
// [SECTION] Helpers ShadeVertsXXX functions
|
|
|
// [SECTION] ImFontConfig
|
|
|
// [SECTION] ImFontAtlas
|
|
|
-// [SECTION] ImFontAtlas glyph ranges helpers
|
|
|
+// [SECTION] ImFontAtlas: glyph ranges helpers
|
|
|
// [SECTION] ImFontGlyphRangesBuilder
|
|
|
// [SECTION] ImFont
|
|
|
// [SECTION] ImGui Internal Render Helpers
|
|
@@ -394,6 +394,17 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
|
|
|
ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError);
|
|
|
}
|
|
|
|
|
|
+ImDrawList::ImDrawList(ImDrawListSharedData* shared_data)
|
|
|
+{
|
|
|
+ memset(this, 0, sizeof(*this));
|
|
|
+ _Data = shared_data;
|
|
|
+}
|
|
|
+
|
|
|
+ImDrawList::~ImDrawList()
|
|
|
+{
|
|
|
+ _ClearFreeMemory();
|
|
|
+}
|
|
|
+
|
|
|
// Initialize before use in a new frame. We always have a command ready in the buffer.
|
|
|
// In the majority of cases, you would want to call PushClipRect() and PushTextureID() after this.
|
|
|
void ImDrawList::_ResetForNewFrame()
|
|
@@ -2528,6 +2539,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
|
|
IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0);
|
|
|
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
|
|
IM_ASSERT(font_cfg->OversampleH > 0 && font_cfg->OversampleV > 0 && "Is ImFontConfig struct correctly initialized?");
|
|
|
+ IM_ASSERT(font_cfg->RasterizerDensity > 0.0f);
|
|
|
|
|
|
// Create new font
|
|
|
if (!font_cfg->MergeMode)
|
|
@@ -2546,9 +2558,16 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
|
|
memcpy(new_font_cfg.FontData, font_cfg->FontData, (size_t)new_font_cfg.FontDataSize);
|
|
|
}
|
|
|
|
|
|
+ // Round font size
|
|
|
+ // - We started rounding in 1.90 WIP (18991) as our layout system currently doesn't support non-rounded font size well yet.
|
|
|
+ // - Note that using io.FontGlobalScale or SetWindowFontScale(), with are legacy-ish, partially supported features, can still lead to unrounded sizes.
|
|
|
+ // - We may support it better later and remove this rounding.
|
|
|
+ new_font_cfg.SizePixels = ImTrunc(new_font_cfg.SizePixels);
|
|
|
+
|
|
|
if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1)
|
|
|
new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar;
|
|
|
|
|
|
+ // Pointers to ConfigData and BuilderData are otherwise dangling
|
|
|
ImFontAtlasUpdateConfigDataPointers(this);
|
|
|
|
|
|
// Invalidate texture
|
|
@@ -3163,35 +3182,35 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
|
|
|
IM_ASSERT(r->IsPacked());
|
|
|
|
|
|
const int w = atlas->TexWidth;
|
|
|
- if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
|
|
|
+ if (atlas->Flags & ImFontAtlasFlags_NoMouseCursors)
|
|
|
{
|
|
|
- // Render/copy pixels
|
|
|
- IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
|
|
|
- const int x_for_white = r->X;
|
|
|
- const int x_for_black = r->X + FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
|
|
|
+ // White pixels only
|
|
|
+ IM_ASSERT(r->Width == 2 && r->Height == 2);
|
|
|
+ const int offset = (int)r->X + (int)r->Y * w;
|
|
|
if (atlas->TexPixelsAlpha8 != NULL)
|
|
|
{
|
|
|
- ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
|
|
|
- ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
|
|
|
+ atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', IM_COL32_WHITE);
|
|
|
- ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', IM_COL32_WHITE);
|
|
|
+ atlas->TexPixelsRGBA32[offset] = atlas->TexPixelsRGBA32[offset + 1] = atlas->TexPixelsRGBA32[offset + w] = atlas->TexPixelsRGBA32[offset + w + 1] = IM_COL32_WHITE;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // Render 4 white pixels
|
|
|
- IM_ASSERT(r->Width == 2 && r->Height == 2);
|
|
|
- const int offset = (int)r->X + (int)r->Y * w;
|
|
|
+ // White pixels and mouse cursor
|
|
|
+ IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
|
|
|
+ const int x_for_white = r->X;
|
|
|
+ const int x_for_black = r->X + FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
|
|
|
if (atlas->TexPixelsAlpha8 != NULL)
|
|
|
{
|
|
|
- atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF;
|
|
|
+ ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
|
|
|
+ ImFontAtlasBuildRender8bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- atlas->TexPixelsRGBA32[offset] = atlas->TexPixelsRGBA32[offset + 1] = atlas->TexPixelsRGBA32[offset + w] = atlas->TexPixelsRGBA32[offset + w + 1] = IM_COL32_WHITE;
|
|
|
+ ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', IM_COL32_WHITE);
|
|
|
+ ImFontAtlasBuildRender32bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', IM_COL32_WHITE);
|
|
|
}
|
|
|
}
|
|
|
atlas->TexUvWhitePixel = ImVec2((r->X + 0.5f) * atlas->TexUvScale.x, (r->Y + 0.5f) * atlas->TexUvScale.y);
|
|
@@ -3205,38 +3224,38 @@ static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
|
|
|
// This generates a triangular shape in the texture, with the various line widths stacked on top of each other to allow interpolation between them
|
|
|
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdLines);
|
|
|
IM_ASSERT(r->IsPacked());
|
|
|
- for (unsigned int n = 0; n < IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1; n++) // +1 because of the zero-width row
|
|
|
+ for (int n = 0; n < IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1; n++) // +1 because of the zero-width row
|
|
|
{
|
|
|
// Each line consists of at least two empty pixels at the ends, with a line of solid pixels in the middle
|
|
|
- unsigned int y = n;
|
|
|
- unsigned int line_width = n;
|
|
|
- unsigned int pad_left = (r->Width - line_width) / 2;
|
|
|
- unsigned int pad_right = r->Width - (pad_left + line_width);
|
|
|
+ int y = n;
|
|
|
+ int line_width = n;
|
|
|
+ int pad_left = (r->Width - line_width) / 2;
|
|
|
+ int pad_right = r->Width - (pad_left + line_width);
|
|
|
|
|
|
// Write each slice
|
|
|
IM_ASSERT(pad_left + line_width + pad_right == r->Width && y < r->Height); // Make sure we're inside the texture bounds before we start writing pixels
|
|
|
if (atlas->TexPixelsAlpha8 != NULL)
|
|
|
{
|
|
|
unsigned char* write_ptr = &atlas->TexPixelsAlpha8[r->X + ((r->Y + y) * atlas->TexWidth)];
|
|
|
- for (unsigned int i = 0; i < pad_left; i++)
|
|
|
+ for (int i = 0; i < pad_left; i++)
|
|
|
*(write_ptr + i) = 0x00;
|
|
|
|
|
|
- for (unsigned int i = 0; i < line_width; i++)
|
|
|
+ for (int i = 0; i < line_width; i++)
|
|
|
*(write_ptr + pad_left + i) = 0xFF;
|
|
|
|
|
|
- for (unsigned int i = 0; i < pad_right; i++)
|
|
|
+ for (int i = 0; i < pad_right; i++)
|
|
|
*(write_ptr + pad_left + line_width + i) = 0x00;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
unsigned int* write_ptr = &atlas->TexPixelsRGBA32[r->X + ((r->Y + y) * atlas->TexWidth)];
|
|
|
- for (unsigned int i = 0; i < pad_left; i++)
|
|
|
+ for (int i = 0; i < pad_left; i++)
|
|
|
*(write_ptr + i) = IM_COL32(255, 255, 255, 0);
|
|
|
|
|
|
- for (unsigned int i = 0; i < line_width; i++)
|
|
|
+ for (int i = 0; i < line_width; i++)
|
|
|
*(write_ptr + pad_left + i) = IM_COL32_WHITE;
|
|
|
|
|
|
- for (unsigned int i = 0; i < pad_right; i++)
|
|
|
+ for (int i = 0; i < pad_right; i++)
|
|
|
*(write_ptr + pad_left + line_width + i) = IM_COL32(255, 255, 255, 0);
|
|
|
}
|
|
|
|
|
@@ -3251,13 +3270,6 @@ static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
|
|
|
// Note: this is called / shared by both the stb_truetype and the FreeType builder
|
|
|
void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
|
|
{
|
|
|
- // Round font size
|
|
|
- // - We started rounding in 1.90 WIP (18991) as our layout system currently doesn't support non-rounded font size well yet.
|
|
|
- // - Note that using io.FontGlobalScale or SetWindowFontScale(), with are legacy-ish, partially supported features, can still lead to unrounded sizes.
|
|
|
- // - We may support it better later and remove this rounding.
|
|
|
- for (ImFontConfig& cfg : atlas->ConfigData)
|
|
|
- cfg.SizePixels = ImTrunc(cfg.SizePixels);
|
|
|
-
|
|
|
// Register texture region for mouse cursors or standard white pixels
|
|
|
if (atlas->PackIdMouseCursors < 0)
|
|
|
{
|
|
@@ -3308,6 +3320,10 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
|
|
|
atlas->TexReady = true;
|
|
|
}
|
|
|
|
|
|
+//-------------------------------------------------------------------------
|
|
|
+// [SECTION] ImFontAtlas: glyph ranges helpers
|
|
|
+//-------------------------------------------------------------------------
|
|
|
+
|
|
|
// Retrieve list of range (2 int per range, values are inclusive)
|
|
|
const ImWchar* ImFontAtlas::GetGlyphRangesDefault()
|
|
|
{
|
|
@@ -3369,10 +3385,6 @@ static void UnpackAccumulativeOffsetsIntoRanges(int base_codepoint, const short*
|
|
|
out_ranges[0] = 0;
|
|
|
}
|
|
|
|
|
|
-//-------------------------------------------------------------------------
|
|
|
-// [SECTION] ImFontAtlas glyph ranges helpers
|
|
|
-//-------------------------------------------------------------------------
|
|
|
-
|
|
|
const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
|
|
|
{
|
|
|
// Store 2500 regularly used characters for Simplified Chinese.
|
|
@@ -3799,8 +3811,9 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
|
|
|
advance_x += cfg->GlyphExtraSpacing.x;
|
|
|
}
|
|
|
|
|
|
+ int glyph_idx = Glyphs.Size;
|
|
|
Glyphs.resize(Glyphs.Size + 1);
|
|
|
- ImFontGlyph& glyph = Glyphs.back();
|
|
|
+ ImFontGlyph& glyph = Glyphs[glyph_idx];
|
|
|
glyph.Codepoint = (unsigned int)codepoint;
|
|
|
glyph.Visible = (x0 != x1) && (y0 != y1);
|
|
|
glyph.Colored = false;
|
|
@@ -3836,6 +3849,7 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
|
|
|
IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f;
|
|
|
}
|
|
|
|
|
|
+// Find glyph, return fallback if missing
|
|
|
const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
|
|
|
{
|
|
|
if (c >= (size_t)IndexLookup.Size)
|