diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 526e594604..13aa430a1c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -33,6 +33,7 @@ - Fix: [#20628] Moving caret using Ctrl+left can move too far when using a multibyte grapheme. - Fix: [#20631] IME window not positioned correctly. - Fix: [#20845] Trying to save under a folder with no write permissions causes a crash. +- Fix: [#21039] Text rendering bleeds pixels through windows. - Fix: [#21054] “No entrance” style is selected by default in the track designer. - Fix: [#21145] [Plugin] setInterval/setTimeout handle conflict. - Fix: [#21157] [Plugin] Widgets do not redraw correctly when updating disabled or visibility state. diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index 3025fd54cc..f8e44f4503 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -572,16 +572,20 @@ static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextD auto src = static_cast(surface->pixels); uint8_t* dst = dpi.bits; + int32_t srcXStart = 0; + int32_t srcYStart = 0; if (skipX < 0) { width += skipX; src += -skipX; + srcXStart += -skipX; skipX = 0; } if (skipY < 0) { height += skipY; src += (-skipY * surface->pitch); + srcYStart += -skipY; skipY = 0; } @@ -591,60 +595,44 @@ static void TTFDrawStringRawTTF(DrawPixelInfo& dpi, std::string_view text, TextD int32_t srcScanSkip = surface->pitch - width; int32_t dstScanSkip = dpi.width + dpi.pitch - width; uint8_t* dst_orig = dst; - const uint8_t* src_orig = src; // Draw shadow/outline - if (info->flags & TEXT_DRAW_FLAG_OUTLINE) + if (info->flags & (TEXT_DRAW_FLAG_OUTLINE | TEXT_DRAW_FLAG_INSET)) { - for (int32_t yy = 0; yy < height - 0; yy++) + for (int32_t yy = 0; yy < height; yy++) { - for (int32_t xx = 0; xx < width - 0; xx++) + for (int32_t xx = 0; xx < width; xx++) { - if (*src != 0) + if (info->flags & TEXT_DRAW_FLAG_OUTLINE) { - // right - if (xx + skipX < dpi.width + dpi.pitch - 1) + if (GetPixel(*surface, xx + srcXStart + 1, yy + srcYStart) + || GetPixel(*surface, xx + srcXStart - 1, yy + srcYStart) + || GetPixel(*surface, xx + srcXStart, yy + srcYStart + 1) + || GetPixel(*surface, xx + srcXStart, yy + srcYStart - 1)) { - *(dst + 1) = info->palette[3]; - } - // left - if (xx + skipX > 1) - { - *(dst - 1) = info->palette[3]; - } - // top - if (yy + skipY > 1) - { - *(dst - width - dstScanSkip) = info->palette[3]; - } - // bottom - if (yy + skipY < dpi.height - 1) - { - *(dst + width + dstScanSkip) = info->palette[3]; + *dst = info->palette[3]; + } + } + if (info->flags & TEXT_DRAW_FLAG_INSET) + { + if (GetPixel(*surface, xx + srcXStart - 1, yy + srcYStart - 1)) + { + *dst = info->palette[3]; } } - src++; dst++; } // Skip any remaining bits - src += srcScanSkip; dst += dstScanSkip; } } - dst = dst_orig; - src = src_orig; for (int32_t yy = 0; yy < height; yy++) { for (int32_t xx = 0; xx < width; xx++) { if (*src != 0) { - if (info->flags & TEXT_DRAW_FLAG_INSET) - { - *(dst + width + dstScanSkip + 1) = info->palette[3]; - } - if (*src > 180 || !use_hinting) { // Centre of the glyph: use full colour. diff --git a/src/openrct2/drawing/TTF.cpp b/src/openrct2/drawing/TTF.cpp index 329ee34436..7c48db277a 100644 --- a/src/openrct2/drawing/TTF.cpp +++ b/src/openrct2/drawing/TTF.cpp @@ -374,6 +374,13 @@ void TTFFreeSurface(TTFSurface* surface) free(surface); } +uint8_t GetPixel(const TTFSurface& surface, int32_t x, int32_t y) +{ + if (x < 0 || y < 0 || x >= surface.w || y >= surface.h) + return 0; + return static_cast(surface.pixels)[y * surface.pitch + x]; +} + #else # include "TTF.h" diff --git a/src/openrct2/drawing/TTF.h b/src/openrct2/drawing/TTF.h index d3e497ff55..273fb48f90 100644 --- a/src/openrct2/drawing/TTF.h +++ b/src/openrct2/drawing/TTF.h @@ -43,5 +43,6 @@ void TTF_CloseFont(TTF_Font* font); void TTF_SetFontHinting(TTF_Font* font, int hinting); int TTF_GetFontHinting(const TTF_Font* font); void TTF_Quit(void); +uint8_t GetPixel(const TTFSurface& surface, int32_t x, int32_t y); #endif // NO_TTF