diff --git a/imgui.h b/imgui.h index 0ddef9510..989ae5ebc 100644 --- a/imgui.h +++ b/imgui.h @@ -3532,7 +3532,7 @@ struct ImFont // '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 void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c); + 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); // [Internal] Don't use! diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 07145751a..13130a242 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -4113,7 +4113,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons } // Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. -void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) +void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip) { const ImFontGlyph* glyph = FindGlyph(c); if (!glyph || !glyph->Visible) @@ -4123,8 +4123,31 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; float x = IM_TRUNC(pos.x); float y = IM_TRUNC(pos.y); + + float x1 = x + glyph->X0 * scale; + float x2 = x + glyph->X1 * scale; + if (cpu_fine_clip && (x1 > cpu_fine_clip->z || x2 < cpu_fine_clip->x)) + return; + float y1 = y + glyph->Y0 * scale; + float y2 = y + glyph->Y1 * scale; + float u1 = glyph->U0; + float v1 = glyph->V0; + float u2 = glyph->U1; + float v2 = glyph->V1; + + // Always CPU fine clip. Code extracted from RenderText(). + // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads. + if (cpu_fine_clip != NULL) + { + if (x1 < cpu_fine_clip->x) { u1 = u1 + (1.0f - (x2 - cpu_fine_clip->x) / (x2 - x1)) * (u2 - u1); x1 = cpu_fine_clip->x; } + if (y1 < cpu_fine_clip->y) { v1 = v1 + (1.0f - (y2 - cpu_fine_clip->y) / (y2 - y1)) * (v2 - v1); y1 = cpu_fine_clip->y; } + if (x2 > cpu_fine_clip->z) { u2 = u1 + ((cpu_fine_clip->z - x1) / (x2 - x1)) * (u2 - u1); x2 = cpu_fine_clip->z; } + if (y2 > cpu_fine_clip->w) { v2 = v1 + ((cpu_fine_clip->w - y1) / (y2 - y1)) * (v2 - v1); y2 = cpu_fine_clip->w; } + if (y1 >= y2) + return; + } draw_list->PrimReserve(6, 4); - draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); + draw_list->PrimRectUV(ImVec2(x1, y1), ImVec2(x2, y2), ImVec2(u1, v1), ImVec2(u2, v2), col); } // Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.