From 9dd0474a52f6ec2dfd01468034ca2f00f10b8a7f Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Fri, 5 Nov 2021 14:17:56 +0000 Subject: [PATCH] DrawArt: Fix bounds check (#3395) The bounds checks were performed against the global screen dimensions instead of the output buffer dimensions. Also includes some minor cleanup of DrawArt. Fixes #3388 --- Source/DiabloUI/art_draw.cpp | 24 ++++++++---------------- Source/DiabloUI/art_draw.h | 2 +- Source/engine/render/text_render.cpp | 2 +- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Source/DiabloUI/art_draw.cpp b/Source/DiabloUI/art_draw.cpp index 06b74abc9..37c74a5d9 100644 --- a/Source/DiabloUI/art_draw.cpp +++ b/Source/DiabloUI/art_draw.cpp @@ -26,14 +26,10 @@ void UpdatePalette(Art *art, const SDL_Surface *output) void DrawArt(Point screenPosition, Art *art, int nFrame, Uint16 srcW, Uint16 srcH) { - if (screenPosition.y >= gnScreenHeight || screenPosition.x >= gnScreenWidth || art->surface == nullptr) + if (art->surface == nullptr || screenPosition.y >= gnScreenHeight || screenPosition.x >= gnScreenWidth) return; - SDL_Rect srcRect; - srcRect.x = 0; - srcRect.y = nFrame * art->h(); - srcRect.w = art->w(); - srcRect.h = art->h(); + SDL_Rect srcRect = MakeSdlRect(0, nFrame * art->h(), art->w(), art->h()); ScaleOutputRect(&srcRect); @@ -50,23 +46,19 @@ void DrawArt(Point screenPosition, Art *art, int nFrame, Uint16 srcW, Uint16 src ErrSdl(); } -void DrawArt(const Surface &out, Point screenPosition, Art *art, int nFrame, Uint16 srcW, Uint16 srcH) +void DrawArt(const Surface &out, Point position, Art *art, int nFrame, Uint16 srcW, Uint16 srcH) { - if (screenPosition.y >= gnScreenHeight || screenPosition.x >= gnScreenWidth || art->surface == nullptr) + if (art->surface == nullptr || position.y >= out.h() || position.x >= out.w()) return; - SDL_Rect srcRect; - srcRect.x = 0; - srcRect.y = nFrame * art->h(); - srcRect.w = art->w(); - srcRect.h = art->h(); - + SDL_Rect srcRect = MakeSdlRect(0, nFrame * art->h(), art->w(), art->h()); if (srcW != 0 && srcW < srcRect.w) srcRect.w = srcW; if (srcH != 0 && srcH < srcRect.h) srcRect.h = srcH; - out.Clip(&srcRect, &screenPosition); - SDL_Rect dstRect { screenPosition.x + out.region.x, screenPosition.y + out.region.y, 0, 0 }; + + out.Clip(&srcRect, &position); + SDL_Rect dstRect = MakeSdlRect(position.x + out.region.x, position.y + out.region.y, 0, 0); UpdatePalette(art, out.surface); diff --git a/Source/DiabloUI/art_draw.h b/Source/DiabloUI/art_draw.h index 54a9f7051..728052f3a 100644 --- a/Source/DiabloUI/art_draw.h +++ b/Source/DiabloUI/art_draw.h @@ -9,7 +9,7 @@ void UpdatePalette(Art *art, const SDL_Surface *output = nullptr); void DrawArt(Point screenPosition, Art *art, int nFrame = 0, Uint16 srcW = 0, Uint16 srcH = 0); -void DrawArt(const Surface &out, Point screenPosition, Art *art, int nFrame = 0, Uint16 srcW = 0, Uint16 srcH = 0); +void DrawArt(const Surface &out, Point position, Art *art, int nFrame = 0, Uint16 srcW = 0, Uint16 srcH = 0); void DrawAnimatedArt(Art *art, Point screenPosition); diff --git a/Source/engine/render/text_render.cpp b/Source/engine/render/text_render.cpp index 612551c0b..fac8e9172 100644 --- a/Source/engine/render/text_render.cpp +++ b/Source/engine/render/text_render.cpp @@ -346,7 +346,7 @@ uint32_t DrawString(const Surface &out, string_view text, const Rectangle &rect, characterPosition.x += rect.size.width - lineWidth; int rightMargin = rect.position.x + rect.size.width; - int bottomMargin = rect.size.height != 0 ? rect.position.y + rect.size.height : out.h(); + const int bottomMargin = rect.size.height != 0 ? std::min(rect.position.y + rect.size.height, out.h()) : out.h(); if (lineHeight == -1) lineHeight = LineHeights[size];