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) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display. This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but
| 3500 | // This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display. |
| 3501 | // 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. |
| 3502 | void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known) |
| 3503 | { |
| 3504 | ImGuiContext& g = *GImGui; |
| 3505 | if (text_end_full == NULL) |
| 3506 | text_end_full = FindRenderedTextEnd(text); |
| 3507 | const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f); |
| 3508 | |
| 3509 | //draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 4), IM_COL32(0, 0, 255, 255)); |
| 3510 | //draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y-2), ImVec2(ellipsis_max_x, pos_max.y+2), IM_COL32(0, 255, 0, 255)); |
| 3511 | //draw_list->AddLine(ImVec2(clip_max_x, pos_min.y), ImVec2(clip_max_x, pos_max.y), IM_COL32(255, 0, 0, 255)); |
| 3512 | // FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels. |
| 3513 | if (text_size.x > pos_max.x - pos_min.x) |
| 3514 | { |
| 3515 | // Hello wo... |
| 3516 | // | | | |
| 3517 | // min max ellipsis_max |
| 3518 | // <-> this is generally some padding value |
| 3519 | |
| 3520 | const ImFont* font = draw_list->_Data->Font; |
| 3521 | const float font_size = draw_list->_Data->FontSize; |
| 3522 | const float font_scale = draw_list->_Data->FontScale; |
| 3523 | const char* text_end_ellipsis = NULL; |
| 3524 | const float ellipsis_width = font->EllipsisWidth * font_scale; |
| 3525 | |
| 3526 | // We can now claim the space between pos_max.x and ellipsis_max.x |
| 3527 | const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_width) - pos_min.x, 1.0f); |
| 3528 | float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x; |
| 3529 | if (text == text_end_ellipsis && text_end_ellipsis < text_end_full) |
| 3530 | { |
| 3531 | // Always display at least 1 character if there's no room for character + ellipsis |
| 3532 | text_end_ellipsis = text + ImTextCountUtf8BytesFromChar(text, text_end_full); |
| 3533 | text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x; |
| 3534 | } |
| 3535 | while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1])) |
| 3536 | { |
| 3537 | // Trim trailing space before ellipsis (FIXME: Supporting non-ascii blanks would be nice, for this we need a function to backtrack in UTF-8 text) |
| 3538 | text_end_ellipsis--; |
| 3539 | text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x; // Ascii blanks are always 1 byte |
| 3540 | } |
| 3541 | |
| 3542 | // Render text, render ellipsis |
| 3543 | RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f)); |
| 3544 | ImVec2 ellipsis_pos = ImTrunc(ImVec2(pos_min.x + text_size_clipped_x, pos_min.y)); |
| 3545 | if (ellipsis_pos.x + ellipsis_width <= ellipsis_max_x) |
| 3546 | for (int i = 0; i < font->EllipsisCharCount; i++, ellipsis_pos.x += font->EllipsisCharStep * font_scale) |
| 3547 | font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar); |
| 3548 | } |
| 3549 | else |
| 3550 | { |
| 3551 | RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_full, &text_size, ImVec2(0.0f, 0.0f)); |
| 3552 | } |
| 3553 | |
| 3554 | if (g.LogEnabled) |
| 3555 | LogRenderedText(&pos_min, text, text_end_full); |
| 3556 | } |
| 3557 | |
| 3558 | // Render a rectangle shaped with optional rounding and borders |
| 3559 | void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) |
nothing calls this directly
no test coverage detected