From 8ccfd32d04086eb5ea618aa5f7f0ca9a99d1ff1d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 20 Aug 2021 22:06:41 +0100 Subject: [PATCH] Fix using wxDC::Blit() when using RTL layout under MSW Work around what seems like a bug in StretchBlt() implementation by applying an extra offset to it when using RTL layout and revert an earlier attempt to fix this problem for wxMemoryDC used in wxNotebook code from 6614aa496d (fix for tabs drawing in RTL (patch 1552881), 2006-10-21). Closes #19190. --- src/msw/dc.cpp | 19 +++++++++++++++++-- src/msw/notebook.cpp | 8 +------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index f4d2a25c51..7f566f34a6 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -2503,12 +2503,27 @@ bool wxMSWDCImpl::DoStretchBlit(wxCoord xdest, wxCoord ydest, { StretchBltModeChanger stretchModeChanger(GetHdc()); + /* + Workaround for #19190. See (reverted) 6614aa496d: "For some reason + in RTL mode, source offset has to be -1, otherwise the right + border (physical) remains unpainted." [note that the offset + actually is applied not only to the source but also dest] + + Be conservative about using the offset and only do it for + currently currently known failing cases: when xdest and xsrc are + equal and only when not actually stretching. + */ + const wxCoord ofs = (GetLayoutDirection() == wxLayout_RightToLeft + && xdest == xsrc + && srcWidth == dstWidth + && srcHeight == dstHeight) ? -1 : 0; + if ( !::StretchBlt ( GetHdc(), - xdest, ydest, dstWidth, dstHeight, + xdest + ofs, ydest, dstWidth, dstHeight, hdcSrc, - xsrc, ysrc, srcWidth, srcHeight, + xsrc + ofs, ysrc, srcWidth, srcHeight, dwRop ) ) { diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 0c53a7dbe7..5f281aaaae 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -795,9 +795,6 @@ void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event)) wxBitmap bmp(rc.right, rc.bottom); wxMemoryDC memdc(bmp); - const wxLayoutDirection dir = dc.GetLayoutDirection(); - memdc.SetLayoutDirection(dir); - const HDC hdc = GetHdcOf(memdc); // The drawing logic of the native tab control is absolutely impenetrable @@ -866,10 +863,7 @@ void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event)) ::ExtFloodFill(hdc, x, y, ::GetSysColor(COLOR_BTNFACE), FLOODFILLSURFACE); } - // For some reason in RTL mode, source offset has to be -1, otherwise the - // right border (physical) remains unpainted. - const wxCoord ofs = dir == wxLayout_RightToLeft ? -1 : 0; - dc.Blit(ofs, 0, rc.right, rc.bottom, &memdc, ofs, 0); + dc.Blit(0, 0, rc.right, rc.bottom, &memdc, 0, 0); } #endif // USE_NOTEBOOK_ANTIFLICKER