|
@@ -1,4 +1,4 @@
|
|
-// dear imgui, v1.83
|
|
|
|
|
|
+// dear imgui, v1.84 WIP
|
|
// (main code and documentation)
|
|
// (main code and documentation)
|
|
|
|
|
|
// Help:
|
|
// Help:
|
|
@@ -1734,7 +1734,7 @@ int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end)
|
|
}
|
|
}
|
|
|
|
|
|
// Based on stb_to_utf8() from github.com/nothings/stb/
|
|
// Based on stb_to_utf8() from github.com/nothings/stb/
|
|
-static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
|
|
|
|
|
|
+static inline int ImTextCharToUtf8_inline(char* buf, int buf_size, unsigned int c)
|
|
{
|
|
{
|
|
if (c < 0x80)
|
|
if (c < 0x80)
|
|
{
|
|
{
|
|
@@ -1769,6 +1769,13 @@ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const char* ImTextCharToUtf8(char out_buf[5], unsigned int c)
|
|
|
|
+{
|
|
|
|
+ int count = ImTextCharToUtf8_inline(out_buf, 5, c);
|
|
|
|
+ out_buf[count] = 0;
|
|
|
|
+ return out_buf;
|
|
|
|
+}
|
|
|
|
+
|
|
// Not optimal but we very rarely use this function.
|
|
// Not optimal but we very rarely use this function.
|
|
int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end)
|
|
int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end)
|
|
{
|
|
{
|
|
@@ -1785,20 +1792,20 @@ static inline int ImTextCountUtf8BytesFromChar(unsigned int c)
|
|
return 3;
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
|
|
-int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end)
|
|
|
|
|
|
+int ImTextStrToUtf8(char* out_buf, int out_buf_size, const ImWchar* in_text, const ImWchar* in_text_end)
|
|
{
|
|
{
|
|
- char* buf_out = buf;
|
|
|
|
- const char* buf_end = buf + buf_size;
|
|
|
|
- while (buf_out < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text)
|
|
|
|
|
|
+ char* buf_p = out_buf;
|
|
|
|
+ const char* buf_end = out_buf + out_buf_size;
|
|
|
|
+ while (buf_p < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text)
|
|
{
|
|
{
|
|
unsigned int c = (unsigned int)(*in_text++);
|
|
unsigned int c = (unsigned int)(*in_text++);
|
|
if (c < 0x80)
|
|
if (c < 0x80)
|
|
- *buf_out++ = (char)c;
|
|
|
|
|
|
+ *buf_p++ = (char)c;
|
|
else
|
|
else
|
|
- buf_out += ImTextCharToUtf8(buf_out, (int)(buf_end - buf_out - 1), c);
|
|
|
|
|
|
+ buf_p += ImTextCharToUtf8_inline(buf_p, (int)(buf_end - buf_p - 1), c);
|
|
}
|
|
}
|
|
- *buf_out = 0;
|
|
|
|
- return (int)(buf_out - buf);
|
|
|
|
|
|
+ *buf_p = 0;
|
|
|
|
+ return (int)(buf_p - out_buf);
|
|
}
|
|
}
|
|
|
|
|
|
int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end)
|
|
int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end)
|
|
@@ -16575,6 +16582,25 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
End();
|
|
End();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// [DEBUG] List fonts in a font atlas and display its texture
|
|
|
|
+void ImGui::ShowFontAtlas(ImFontAtlas* atlas)
|
|
|
|
+{
|
|
|
|
+ for (int i = 0; i < atlas->Fonts.Size; i++)
|
|
|
|
+ {
|
|
|
|
+ ImFont* font = atlas->Fonts[i];
|
|
|
|
+ PushID(font);
|
|
|
|
+ DebugNodeFont(font);
|
|
|
|
+ PopID();
|
|
|
|
+ }
|
|
|
|
+ if (TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight))
|
|
|
|
+ {
|
|
|
|
+ ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
+ ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
|
|
|
|
+ Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), tint_col, border_col);
|
|
|
|
+ TreePop();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// [DEBUG] Display contents of Columns
|
|
// [DEBUG] Display contents of Columns
|
|
void ImGui::DebugNodeColumns(ImGuiOldColumns* columns)
|
|
void ImGui::DebugNodeColumns(ImGuiOldColumns* columns)
|
|
{
|
|
{
|
|
@@ -16765,6 +16791,102 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
|
|
out_draw_list->Flags = backup_flags;
|
|
out_draw_list->Flags = backup_flags;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// [DEBUG] Display details for a single font, called by ShowStyleEditor().
|
|
|
|
+void ImGui::DebugNodeFont(ImFont* font)
|
|
|
|
+{
|
|
|
|
+ bool opened = TreeNode(font, "Font: \"%s\"\n%.2f px, %d glyphs, %d file(s)",
|
|
|
|
+ font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount);
|
|
|
|
+ SameLine();
|
|
|
|
+ if (SmallButton("Set as default"))
|
|
|
|
+ GetIO().FontDefault = font;
|
|
|
|
+ if (!opened)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ // Display preview text
|
|
|
|
+ PushFont(font);
|
|
|
|
+ Text("The quick brown fox jumps over the lazy dog");
|
|
|
|
+ PopFont();
|
|
|
|
+
|
|
|
|
+ // Display details
|
|
|
|
+ SetNextItemWidth(GetFontSize() * 8);
|
|
|
|
+ DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f");
|
|
|
|
+ SameLine(); MetricsHelpMarker(
|
|
|
|
+ "Note than the default embedded font is NOT meant to be scaled.\n\n"
|
|
|
|
+ "Font are currently rendered into bitmaps at a given size at the time of building the atlas. "
|
|
|
|
+ "You may oversample them to get some flexibility with scaling. "
|
|
|
|
+ "You can also render at multiple sizes and select which one to use at runtime.\n\n"
|
|
|
|
+ "(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)");
|
|
|
|
+ Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
|
|
|
|
+ char c_str[5];
|
|
|
|
+ Text("Fallback character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->FallbackChar), font->FallbackChar);
|
|
|
|
+ Text("Ellipsis character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->EllipsisChar), font->EllipsisChar);
|
|
|
|
+ const int surface_sqrt = (int)ImSqrt((float)font->MetricsTotalSurface);
|
|
|
|
+ Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt);
|
|
|
|
+ for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
|
|
|
|
+ if (font->ConfigData)
|
|
|
|
+ if (const ImFontConfig* cfg = &font->ConfigData[config_i])
|
|
|
|
+ BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
|
|
|
|
+ config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
|
|
|
|
+
|
|
|
|
+ // Display all glyphs of the fonts in separate pages of 256 characters
|
|
|
|
+ if (TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
|
|
|
|
+ {
|
|
|
|
+ ImDrawList* draw_list = GetWindowDrawList();
|
|
|
|
+ const ImU32 glyph_col = GetColorU32(ImGuiCol_Text);
|
|
|
|
+ const float cell_size = font->FontSize * 1;
|
|
|
|
+ const float cell_spacing = GetStyle().ItemSpacing.y;
|
|
|
|
+ for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
|
|
|
|
+ {
|
|
|
|
+ // Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k)
|
|
|
|
+ // This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT
|
|
|
|
+ // is large // (if ImWchar==ImWchar32 we will do at least about 272 queries here)
|
|
|
|
+ if (!(base & 4095) && font->IsGlyphRangeUnused(base, base + 4095))
|
|
|
|
+ {
|
|
|
|
+ base += 4096 - 256;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int count = 0;
|
|
|
|
+ for (unsigned int n = 0; n < 256; n++)
|
|
|
|
+ if (font->FindGlyphNoFallback((ImWchar)(base + n)))
|
|
|
|
+ count++;
|
|
|
|
+ if (count <= 0)
|
|
|
|
+ continue;
|
|
|
|
+ if (!TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph"))
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ // Draw a 16x16 grid of glyphs
|
|
|
|
+ ImVec2 base_pos = GetCursorScreenPos();
|
|
|
|
+ for (unsigned int n = 0; n < 256; n++)
|
|
|
|
+ {
|
|
|
|
+ // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions
|
|
|
|
+ // available here and thus cannot easily generate a zero-terminated UTF-8 encoded string.
|
|
|
|
+ ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
|
|
|
|
+ ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
|
|
|
|
+ const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
|
|
|
|
+ draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
|
|
|
|
+ if (glyph)
|
|
|
|
+ font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
|
|
|
|
+ if (glyph && IsMouseHoveringRect(cell_p1, cell_p2))
|
|
|
|
+ {
|
|
|
|
+ BeginTooltip();
|
|
|
|
+ Text("Codepoint: U+%04X", base + n);
|
|
|
|
+ Separator();
|
|
|
|
+ Text("Visible: %d", glyph->Visible);
|
|
|
|
+ Text("AdvanceX: %.1f", glyph->AdvanceX);
|
|
|
|
+ Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1);
|
|
|
|
+ Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1);
|
|
|
|
+ EndTooltip();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16));
|
|
|
|
+ TreePop();
|
|
|
|
+ }
|
|
|
|
+ TreePop();
|
|
|
|
+ }
|
|
|
|
+ TreePop();
|
|
|
|
+}
|
|
|
|
+
|
|
// [DEBUG] Display contents of ImGuiStorage
|
|
// [DEBUG] Display contents of ImGuiStorage
|
|
void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label)
|
|
void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label)
|
|
{
|
|
{
|
|
@@ -16943,9 +17065,11 @@ void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* la
|
|
#else
|
|
#else
|
|
|
|
|
|
void ImGui::ShowMetricsWindow(bool*) {}
|
|
void ImGui::ShowMetricsWindow(bool*) {}
|
|
|
|
+void ImGui::ShowFontAtlas(ImFontAtlas*) {}
|
|
void ImGui::DebugNodeColumns(ImGuiOldColumns*) {}
|
|
void ImGui::DebugNodeColumns(ImGuiOldColumns*) {}
|
|
void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP*, const ImDrawList*, const char*) {}
|
|
void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP*, const ImDrawList*, const char*) {}
|
|
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList*, const ImDrawList*, const ImDrawCmd*, bool, bool) {}
|
|
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList*, const ImDrawList*, const ImDrawCmd*, bool, bool) {}
|
|
|
|
+void ImGui::DebugNodeFont(ImFont*) {}
|
|
void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {}
|
|
void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {}
|
|
void ImGui::DebugNodeTabBar(ImGuiTabBar*, const char*) {}
|
|
void ImGui::DebugNodeTabBar(ImGuiTabBar*, const char*) {}
|
|
void ImGui::DebugNodeWindow(ImGuiWindow*, const char*) {}
|
|
void ImGui::DebugNodeWindow(ImGuiWindow*, const char*) {}
|