From 5ac54027dcff9fb06f0d45788f92f7228d69a797 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 22 Nov 2022 02:58:29 +0000 Subject: [PATCH] Text rendering: Clip text to the given rect Previously, we only clipped to the given surface, without clipping to the given rect. --- Source/engine/render/text_render.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Source/engine/render/text_render.cpp b/Source/engine/render/text_render.cpp index 991d493c9..8f0844090 100644 --- a/Source/engine/render/text_render.cpp +++ b/Source/engine/render/text_render.cpp @@ -354,6 +354,16 @@ int GetLineHeight(string_view fmt, DrawStringFormatArg *args, std::size_t argsLe return LineHeights[fontIndex]; } +Surface ClipSurface(const Surface &out, Rectangle rect) +{ + if (rect.size.height == 0) { + return out.subregion(0, 0, std::min(rect.position.x + rect.size.width, out.w()), out.h()); + } + return out.subregion(0, 0, + std::min(rect.position.x + rect.size.width, out.w()), + std::min(rect.position.y + rect.size.height, out.h())); +} + int DoDrawString(const Surface &out, string_view text, Rectangle rect, Point &characterPosition, int spacing, int lineHeight, int lineWidth, int rightMargin, int bottomMargin, UiFlags flags, GameFontTables size, text_color color) @@ -642,12 +652,14 @@ uint32_t DrawString(const Surface &out, string_view text, const Rectangle &rect, characterPosition.y += BaseLineOffset[size]; - const int bytesDrawn = DoDrawString(out, text, rect, characterPosition, spacing, lineHeight, lineWidth, rightMargin, bottomMargin, flags, size, color); + const Surface clippedOut = ClipSurface(out, rect); + + const int bytesDrawn = DoDrawString(clippedOut, text, rect, characterPosition, spacing, lineHeight, lineWidth, rightMargin, bottomMargin, flags, size, color); if (HasAnyOf(flags, UiFlags::PentaCursor)) { - ClxDraw(out, characterPosition + Displacement { 0, lineHeight - BaseLineOffset[size] }, (*pSPentSpn2Cels)[PentSpn2Spin()]); + ClxDraw(clippedOut, characterPosition + Displacement { 0, lineHeight - BaseLineOffset[size] }, (*pSPentSpn2Cels)[PentSpn2Spin()]); } else if (HasAnyOf(flags, UiFlags::TextCursor) && GetAnimationFrame(2, 500) != 0) { - DrawFont(out, characterPosition, LoadFont(size, color, 0), color, '|'); + DrawFont(clippedOut, characterPosition, LoadFont(size, color, 0), color, '|'); } return bytesDrawn; @@ -686,6 +698,8 @@ void DrawStringWithColors(const Surface &out, string_view fmt, DrawStringFormatA characterPosition.y += BaseLineOffset[size]; + const Surface clippedOut = ClipSurface(out, rect); + Font *font = nullptr; std::array *kerning = nullptr; @@ -701,7 +715,7 @@ void DrawStringWithColors(const Surface &out, string_view fmt, DrawStringFormatA } const std::optional fmtArgPos = fmtArgParser(rest); if (fmtArgPos) { - DoDrawString(out, args[*fmtArgPos].GetFormatted(), rect, characterPosition, spacing, lineHeight, lineWidth, rightMargin, bottomMargin, flags, size, + DoDrawString(clippedOut, args[*fmtArgPos].GetFormatted(), rect, characterPosition, spacing, lineHeight, lineWidth, rightMargin, bottomMargin, flags, size, GetColorFromFlags(args[*fmtArgPos].GetFlags())); prev = U'\0'; font = nullptr; @@ -747,15 +761,15 @@ void DrawStringWithColors(const Surface &out, string_view fmt, DrawStringFormatA } } - DrawFont(out, characterPosition, font, color, frame); + DrawFont(clippedOut, characterPosition, font, color, frame); characterPosition.x += (*kerning)[frame] + spacing; prev = next; } if (HasAnyOf(flags, UiFlags::PentaCursor)) { - ClxDraw(out, characterPosition + Displacement { 0, lineHeight - BaseLineOffset[size] }, (*pSPentSpn2Cels)[PentSpn2Spin()]); + ClxDraw(clippedOut, characterPosition + Displacement { 0, lineHeight - BaseLineOffset[size] }, (*pSPentSpn2Cels)[PentSpn2Spin()]); } else if (HasAnyOf(flags, UiFlags::TextCursor) && GetAnimationFrame(2, 500) != 0) { - DrawFont(out, characterPosition, LoadFont(size, color, 0), color, '|'); + DrawFont(clippedOut, characterPosition, LoadFont(size, color, 0), color, '|'); } }