Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
This commit is contained in:
ocornut
2025-05-30 22:00:26 +02:00
7 changed files with 86 additions and 27 deletions

View File

@@ -43,6 +43,12 @@ Breaking changes:
- TreeNode: renamed ImGuiTreeNodeFlags_NavLeftJumpsBackHere to ImGuiTreeNodeFlags_NavLeftJumpsToParent
for clarity. Kept inline redirection enum (will obsolete). (#1079, #8639)
- Fonts: changed ImFont::CalcWordWrapPositionA() to ImFont::CalcWordWrapPosition():
- old: const char* CalcWordWrapPositionA(float scale, const char* text, ....);
- new: const char* CalcWordWrapPosition (float size, const char* text, ....);
The leading 'float scale' parameters was changed to 'float size'.
This was necessary as 'scale' is assuming standard font size which is a concept we aim to
eliminate in an upcoming update. Kept inline redirection function.
- Commented out PushAllowKeyboardFocus()/PopAllowKeyboardFocus() which was obsoleted
in 1.89.4 (March 2023). (#3092)
- PushAllowKeyboardFocus(bool tab_stop) --> PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop);
@@ -51,7 +57,9 @@ Breaking changes:
in 1.89.6 (June 2023).
- ForceDisplayRangeByIndices() --> IncludeItemsByIndex()
- Backends: SDL3: Fixed casing typo in function name: (#8509, #8163, #7998, #7988) [@puugz]
- Imgui_ImplSDLGPU3_PrepareDrawData() -> ImGui_ImplSDLGPU3_PrepareDrawData()
- Imgui_ImplSDLGPU3_PrepareDrawData() --> ImGui_ImplSDLGPU3_PrepareDrawData()
- Internals: RenderTextEllipsis() function removed the 'float clip_max_x' parameter directly
preceding 'float ellipsis_max_x'. Values were identical for a vast majority of users. (#8387)
Other changes:
@@ -97,8 +105,16 @@ Other changes:
which mitigates edge case issues in multi-viewport scenarios where abnormally large
windows (e.g. determined programmatically) can lead to renderer backend trying to
create abnormally large framebuffers.
- TextLinkOpenURL(): added bool return value on click. (#8645, #8451, #7660)
- Scroll: fixed contents size, scrollbar visibility and scrolling resetting issues
with abnormally large contents ranges. (#3609, #8215)
- Clipper: some mitigation/improvements for abnormally large contents ranges. (#3609, #8215)
- Nav: fixed assertion when holding gamepad FaceLeft/West button to open
CTRL+Tab windowing + pressing a keyboard key. (#8525)
- Nav: fixed scroll fallback (when there are no interactive widgets to jump to) not
being enabled on windows with menu or title bar.
- Nav: fixed an issue handling PageUp/PageDown on windows with abnormally large contents
range which could lead to clipper requesting very large ranges.
- Error Handling: added better error report and recovery for extraneous
EndPopup() call. (#1651, #8499)
- Error Handling: added better error report and recovery when calling EndFrame()
@@ -106,7 +122,7 @@ Other changes:
- Fonts: reworked text ellipsis logic to ensure a "..." is always displayed instead
of a single character. (#7024)
- Fonts: word-wrapping code handle ideographic comma & full stop (U+3001, U+3002). (#8540)
- Fonts: fixed CalcWordWrapPositionA() fallback when width is too small to wrap:
- Fonts: fixed CalcWordWrapPosition() fallback when width is too small to wrap:
would use a +1 offset instead of advancing to the next UTF-8 codepoint. (#8540)
- Style, InputText: added ImGuiCol_InputTextCursor to configure color of
the InputText cursor/caret. (#7031)
@@ -276,6 +292,7 @@ Other changes:
- Debug Tools: Added io.ConfigDebugHighlightIdConflictsShowItemPicker (defaults to true)
to allow disabled Item Picker suggestion in user facing builds. (#7961, #7669)
- Debug Tools: Tweaked layout of ID Stack Tool and always display full path. (#4631)
- imgui_freetype: update lunasvg API to support v3.0+. (#8656, #6842, #6591) [@moretromain]
- Misc: Various zealous warning fixes for newer version of Clang.
- Misc: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursors
(busy/wait/hourglass shape, with or without an arrow cursor).

View File

@@ -440,10 +440,15 @@ CODE
- likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2025/05/23 (1.92.0) - Fonts: changed ImFont::CalcWordWrapPositionA() to ImFont::CalcWordWrapPosition()
- old: const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, ....);
- new: const char* ImFont::CalcWordWrapPosition (float size, const char* text, ....);
The leading 'float scale' parameters was changed to 'float size'. This was necessary as 'scale' is assuming standard font size which is a concept we aim to eliminate in an upcoming update. Kept inline redirection function.
- 2025/05/15 (1.92.0) - TreeNode: renamed ImGuiTreeNodeFlags_NavLeftJumpsBackHere to ImGuiTreeNodeFlags_NavLeftJumpsToParent for clarity. Kept inline redirection enum (will obsolete).
- 2025/05/15 (1.92.0) - Commented out PushAllowKeyboardFocus()/PopAllowKeyboardFocus() which was obsoleted in 1.89.4. Use PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop)/PopItemFlag() instead. (#3092)
- 2025/05/15 (1.92.0) - Commented out ImGuiListClipper::ForceDisplayRangeByIndices() which was obsoleted in 1.89.6. Use ImGuiListClipper::IncludeItemsByIndex() instead.
- 2025/03/05 (1.91.9) - BeginMenu(): Internals: reworked mangling of menu windows to use "###Menu_00" etc. instead of "##Menu_00", allowing them to also store the menu name before it. This shouldn't affect code unless directly accessing menu window from their mangled name.
- 2025/04/16 (1.91.9) - Internals: RenderTextEllipsis() function removed the 'float clip_max_x' parameter directly preceding 'float ellipsis_max_x'. Values were identical for a vast majority of users. (#8387)
- 2025/02/27 (1.91.9) - Image(): removed 'tint_col' and 'border_col' parameter from Image() function. Added ImageWithBg() replacement. (#8131, #8238)
- old: void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1), ImVec4 tint_col = (1,1,1,1), ImVec4 border_col = (0,0,0,0));
- new: void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1));
@@ -3250,10 +3255,17 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
if (table)
IM_ASSERT(table->RowPosY1 == clipper->StartPosY && table->RowPosY2 == window->DC.CursorPos.y);
clipper->ItemsHeight = (window->DC.CursorPos.y - clipper->StartPosY) / (float)(clipper->DisplayEnd - clipper->DisplayStart);
bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision((float)clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
if (affected_by_floating_point_precision)
{
// Mitigation/hack for very large range: assume last time height constitute line height.
clipper->ItemsHeight = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y; // FIXME: Technically wouldn't allow multi-line entries.
window->DC.CursorPos.y = (float)(clipper->StartPosY + clipper->ItemsHeight);
}
else
{
clipper->ItemsHeight = (float)(window->DC.CursorPos.y - clipper->StartPosY) / (float)(clipper->DisplayEnd - clipper->DisplayStart);
}
if (clipper->ItemsHeight == 0.0f && clipper->ItemsCount == INT_MAX) // Accept that no item have been submitted if in indeterminate mode.
return false;
IM_ASSERT(clipper->ItemsHeight > 0.0f && "Unable to calculate item height! First item hasn't moved the cursor vertically!");
@@ -3277,7 +3289,10 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
// Add range selected to be included for navigation
const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav);
if (is_nav_request)
{
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringRect.Min.y, g.NavScoringRect.Max.y, 0, 0));
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0));
}
if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && g.NavTabbingDir == -1)
data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount));
@@ -3766,6 +3781,7 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons
// Another overly complex function until we reorganize everything into a nice all-in-one helper.
// This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) from 'ellipsis_max_x' which may be beyond it.
// This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move.
// (BREAKING) On 2025/04/16 we removed the 'float clip_max_x' parameters which was preceeding 'float ellipsis_max' and was the same value for 99% of users.
void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known)
{
ImGuiContext& g = *GImGui;
@@ -5394,7 +5410,6 @@ void ImGui::NewFrame()
UpdateViewportsNewFrame();
// Setup current font and draw list shared data
// FIXME-VIEWPORT: the concept of a single ClipRectFullscreen is not ideal!
SetupDrawListSharedData();
UpdateFontsNewFrame();
@@ -6676,10 +6691,10 @@ static void CalcWindowContentSizes(ImGuiWindow* window, ImVec2* content_size_cur
return;
}
content_size_current->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_TRUNC(window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
content_size_current->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_TRUNC(window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
content_size_ideal->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : IM_TRUNC(ImMax(window->DC.CursorMaxPos.x, window->DC.IdealMaxPos.x) - window->DC.CursorStartPos.x);
content_size_ideal->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : IM_TRUNC(ImMax(window->DC.CursorMaxPos.y, window->DC.IdealMaxPos.y) - window->DC.CursorStartPos.y);
content_size_current->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : ImTrunc64(window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
content_size_current->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : ImTrunc64(window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
content_size_ideal->x = (window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : ImTrunc64(ImMax(window->DC.CursorMaxPos.x, window->DC.IdealMaxPos.x) - window->DC.CursorStartPos.x);
content_size_ideal->y = (window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : ImTrunc64(ImMax(window->DC.CursorMaxPos.y, window->DC.IdealMaxPos.y) - window->DC.CursorStartPos.y);
}
static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_contents)
@@ -11820,7 +11835,7 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
}
scroll[axis] = scroll_target - center_ratio * (window->SizeFull[axis] - decoration_size[axis]);
}
scroll[axis] = IM_ROUND(ImMax(scroll[axis], 0.0f));
scroll[axis] = ImRound64(ImMax(scroll[axis], 0.0f));
if (!window->Collapsed && !window->SkipItems)
scroll[axis] = ImMin(scroll[axis], window->ScrollMax[axis]);
}
@@ -14058,7 +14073,7 @@ void ImGui::NavUpdateCreateMoveRequest()
//if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG]
}
g.NavScoringRect = scoring_rect;
g.NavScoringNoClipRect.Add(scoring_rect);
//g.NavScoringNoClipRect.Add(scoring_rect);
}
void ImGui::NavUpdateCreateTabbingRequest()
@@ -14277,7 +14292,7 @@ static float ImGui::NavUpdatePageUpPageDown()
if (g.NavLayer != ImGuiNavLayer_Main)
NavRestoreLayer(ImGuiNavLayer_Main);
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY)
if ((window->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Main)) == 0 && window->DC.NavWindowHasScrollY)
{
// Fallback manual-scroll when window has no navigable item
if (IsKeyPressed(ImGuiKey_PageUp, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner))

15
imgui.h
View File

@@ -29,7 +29,7 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.0 WIP"
#define IMGUI_VERSION_NUM 19196
#define IMGUI_VERSION_NUM 19197
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch
@@ -567,13 +567,14 @@ namespace ImGui
IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-FLT_MIN, 0), const char* overlay = NULL);
IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses
IMGUI_API bool TextLink(const char* label); // hyperlink text button, return true when clicked
IMGUI_API void TextLinkOpenURL(const char* label, const char* url = NULL); // hyperlink text button, automatically open file/url when clicked
IMGUI_API bool TextLinkOpenURL(const char* label, const char* url = NULL); // hyperlink text button, automatically open file/url when clicked
// Widgets: Images
// - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
// - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above.
// - Image() pads adds style.ImageBorderSize on each side, ImageButton() adds style.FramePadding on each side.
// - ImageButton() draws a background based on regular Button() color + optionally an inner background if specified.
// - An obsolete version of Image(), before 1.91.9 (March 2025), had a 'tint_col' parameter which is now supported by the ImageWithBg() function.
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1));
IMGUI_API void ImageWithBg(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
IMGUI_API bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1));
@@ -2822,7 +2823,7 @@ struct ImGuiListClipper
int DisplayEnd; // End of items to display (exclusive)
int ItemsCount; // [Internal] Number of items
float ItemsHeight; // [Internal] Height of item after a first step and item submission can calculate it
float StartPosY; // [Internal] Cursor position at the time of Begin() or after table frozen rows are all processed
double StartPosY; // [Internal] Cursor position at the time of Begin() or after table frozen rows are all processed
double StartSeekOffsetY; // [Internal] Account for frozen rows in a table and initial loss of precision in very large windows.
void* TempData; // [Internal] Internal data
@@ -3647,10 +3648,14 @@ struct ImFont
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL); // utf8
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width);
IMGUI_API const char* CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width);
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip = NULL);
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const 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);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(FontSize * scale, text, text_end, wrap_width); }
#endif
// [Internal] Don't use!
IMGUI_API void BuildLookupTable();
IMGUI_API void ClearOutputData();
@@ -3907,7 +3912,7 @@ struct ImGuiPlatformImeData
namespace ImGui
{
// OBSOLETED in 1.91.9 (from February 2025)
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- border_col was removed in favor of ImGuiCol_ImageBorder.
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- 'border_col' was removed in favor of ImGuiCol_ImageBorder. If you use 'tint_col', use ImageWithBg() instead.
// OBSOLETED in 1.91.0 (from July 2024)
static inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
static inline void PopButtonRepeat() { PopItemFlag(); }

View File

@@ -3942,7 +3942,7 @@ static inline const char* CalcWordWrapNextLineStartA(const char* text, const cha
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width)
const char* ImFont::CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width)
{
// For references, possible wrap point marked with ^
// "aaa bbb, ccc,ddd. eee fff. ggg!"
@@ -3958,6 +3958,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
float line_width = 0.0f;
float word_width = 0.0f;
float blank_width = 0.0f;
const float scale = size / FontSize;
wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters
const char* word_end = text;
@@ -4061,7 +4062,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
{
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
if (!word_wrap_eol)
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width);
word_wrap_eol = CalcWordWrapPosition(size, s, text_end, wrap_width - line_width);
if (s >= word_wrap_eol)
{
@@ -4181,10 +4182,10 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
const char* line_end = (const char*)ImMemchr(s, '\n', text_end - s);
if (word_wrap_enabled)
{
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA().
// If the specs for CalcWordWrapPositionA() were reworked to optionally return on \n we could combine both.
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPosition().
// If the specs for CalcWordWrapPosition() were reworked to optionally return on \n we could combine both.
// However it is still better than nothing performing the fast-forward!
s = CalcWordWrapPositionA(scale, s, line_end ? line_end : text_end, wrap_width);
s = CalcWordWrapPosition(size, s, line_end ? line_end : text_end, wrap_width);
s = CalcWordWrapNextLineStartA(s, text_end);
}
else
@@ -4229,7 +4230,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
if (!word_wrap_eol)
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - origin_x));
word_wrap_eol = CalcWordWrapPosition(size, s, text_end, wrap_width - (x - origin_x));
if (s >= word_wrap_eol)
{

View File

@@ -507,6 +507,8 @@ static inline float ImTrunc(float f)
static inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
static inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
static inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
static inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }

View File

@@ -1535,13 +1535,13 @@ bool ImGui::TextLink(const char* label)
return pressed;
}
void ImGui::TextLinkOpenURL(const char* label, const char* url)
bool ImGui::TextLinkOpenURL(const char* label, const char* url)
{
ImGuiContext& g = *GImGui;
if (url == NULL)
url = label;
if (TextLink(label))
if (g.PlatformIO.Platform_OpenInShellFn != NULL)
bool pressed = TextLink(label);
if (pressed && g.PlatformIO.Platform_OpenInShellFn != NULL)
g.PlatformIO.Platform_OpenInShellFn(&g, url);
SetItemTooltip(LocalizeGetMsg(ImGuiLocKey_OpenLink_s), url); // It is more reassuring for user to _always_ display URL when we same as label
if (BeginPopupContextItem())
@@ -1550,6 +1550,7 @@ void ImGui::TextLinkOpenURL(const char* label, const char* url)
SetClipboardText(url);
EndPopup();
}
return pressed;
}
//-------------------------------------------------------------------------

View File

@@ -880,8 +880,12 @@ static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state)
// rows is height, pitch (or stride) equals to width * sizeof(int32)
lunasvg::Bitmap bitmap((uint8_t*)slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.pitch);
#if LUNASVG_VERSION_MAJOR >= 3
state->svg->render(bitmap, state->matrix); // state->matrix is already scaled and translated
#else
state->svg->setMatrix(state->svg->matrix().identity()); // Reset the svg matrix to the default value
state->svg->render(bitmap, state->matrix); // state->matrix is already scaled and translated
#endif
state->err = FT_Err_Ok;
return state->err;
}
@@ -904,7 +908,11 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
return state->err;
}
#if LUNASVG_VERSION_MAJOR >= 3
lunasvg::Box box = state->svg->boundingBox();
#else
lunasvg::Box box = state->svg->box();
#endif
double scale = std::min(metrics.x_ppem / box.w, metrics.y_ppem / box.h);
double xx = (double)document->transform.xx / (1 << 16);
double xy = -(double)document->transform.xy / (1 << 16);
@@ -913,6 +921,15 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
double x0 = (double)document->delta.x / 64 * box.w / metrics.x_ppem;
double y0 = -(double)document->delta.y / 64 * box.h / metrics.y_ppem;
#if LUNASVG_VERSION_MAJOR >= 3
// Scale, transform and pre-translate the matrix for the rendering step
state->matrix = lunasvg::Matrix::translated(-box.x, -box.y);
state->matrix.multiply(lunasvg::Matrix(xx, xy, yx, yy, x0, y0));
state->matrix.scale(scale, scale);
// Apply updated transformation to the bounding box
box.transform(state->matrix);
#else
// Scale and transform, we don't translate the svg yet
state->matrix.identity();
state->matrix.scale(scale, scale);
@@ -924,6 +941,7 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
// Get the box again after the transformation
box = state->svg->box();
#endif
// Calculate the bitmap size
slot->bitmap_left = FT_Int(box.x);