Skip to content

wxMSW: A better (IMHO) RTL fixes for wx{Auto}BufferedDC#26398

Open
AliKet wants to merge 9 commits into
wxWidgets:masterfrom
AliKet:msw-rtl-fixes
Open

wxMSW: A better (IMHO) RTL fixes for wx{Auto}BufferedDC#26398
AliKet wants to merge 9 commits into
wxWidgets:masterfrom
AliKet:msw-rtl-fixes

Conversation

@AliKet
Copy link
Copy Markdown
Contributor

@AliKet AliKet commented Apr 20, 2026

Also fix custom drawing where wxDC::DeviceToLogical() and related functions need to be used.

@AliKet
Copy link
Copy Markdown
Contributor Author

AliKet commented Apr 20, 2026

I don't have a real explanation of why we need this commit da9c92e to fix tests failures in OneDevRegionRTL, Just some weired rounding errors? I'm guessing...

@AliKet

This comment was marked as low quality.

@AliKet
Copy link
Copy Markdown
Contributor Author

AliKet commented Apr 20, 2026

@vslavik I would be grateful if you could test this and see whether it breaks something I’m not aware of. Thanks in advance!

Copy link
Copy Markdown
Contributor

@vadz vadz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm still very confused by this stuff. It would be great to have an explanation in a comment somewhere about how RTL works in wxMSW, i.e. which coordinates take into account and which don't. Right now I don't understand why is is it correct to disable RTL when converting between device and logical, hopefully it would become clearer with a comment like this...

Comment thread src/msw/dc.cpp Outdated
Comment thread src/msw/dc.cpp Outdated
Comment thread src/msw/dc.cpp
// honor the LAYOUT_RTL flag set on the DC, so we have to apply
// mirroring ourselves (see SetLayout() documentation in MSDN).
const LONG wDIB = ds.dsBmih.biWidth;
if ( wDIB > 0 )
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it really be 0 here? It might be clearer/simpler to return early from this function if the width (or height) is 0.

Comment thread tests/graphics/clippingbox.cpp Outdated
@vslavik
Copy link
Copy Markdown
Member

vslavik commented May 1, 2026

@vslavik I would be grateful if you could test this and see whether it breaks something I’m not aware of. Thanks in advance!

Sorry, I wanted to, but ran out of time and won’t be able to until May 12-ish.

@vadz
Copy link
Copy Markdown
Contributor

vadz commented May 12, 2026

I'm still not sure if it this is correct, it seems wrong to disable RTL when doing device/logical conversions. But if this is how the other ports work and if there is no good way to fix this otherwise, we could still merge this...

@vslavik Please let me know what do you think when you get back.

@AliKet AliKet force-pushed the msw-rtl-fixes branch 3 times, most recently from e468462 to 526a148 Compare May 13, 2026 22:05
@vadz
Copy link
Copy Markdown
Contributor

vadz commented May 15, 2026

@AliKet What (if anything) has changed since the previous version after the last force push?

@AliKet
Copy link
Copy Markdown
Contributor Author

AliKet commented May 15, 2026

@AliKet What (if anything) has changed since the previous version after the last force push?

Nothing interesting, just rebased on master and updating the last commit:

> git diff HEAD~1 HEAD

diff --git a/tests/graphics/clippingbox.cpp b/tests/graphics/clippingbox.cpp
index 802f62d29c..bd11ab4871 100644
--- a/tests/graphics/clippingbox.cpp
+++ b/tests/graphics/clippingbox.cpp
@@ -1057,15 +1057,9 @@ static void OneDevRegionRTL(wxDC& dc, const wxBitmap& bmp, bool useTransformMatr
     dc.Clear();
     // right physical edge becomes left logical edge in a mirrored DC.
     const int x2 = s_dcSize.x - (x + w);
-    // In a mirrored DC, the device origin (0, 0) is always at the top left
-    // of the DC under wxMSW, but under wxGTK3 is at the top right.
-#if defined(__WXGTK3__) || defined(__WXQT__)
+
     wxPoint pos = dc.DeviceToLogical(x, y);
     wxSize dim = dc.DeviceToLogicalRel(w, h);
-#else
-    wxPoint pos = dc.DeviceToLogical(s_dcSize.x-x, y);
-    wxSize dim = dc.DeviceToLogicalRel(-w, h);
-#endif

     CheckClipBox(dc, bmp,
                  pos.x, pos.y, dim.x, dim.y,

@vadz
Copy link
Copy Markdown
Contributor

vadz commented May 15, 2026

Thanks!

I'd still like to have some explanation of how RTL works (i.e. what is mirrored and what is not) somewhere, but I'm ready to merge this anyhow.

Pinging @vslavik one last time just in case.

AliKet added 9 commits May 16, 2026 14:12
… under wxMSW

Ditto for wxDC::DeviceToLogical{Rel}() functions.

In RTL layout, these functions always return unmirrored coordinates under wxGTK3
and wxQt. This is now the case under wxMSW too for consistency and also to fix
double-mirroring problem when passing the transformed coordinates to GDI drawing
functions. See wxGrid::Render() for example.
Added in commit f5d326f (2025-10-19, wxMSW: Fix SetClippingRegion() after reverting commit 288b208)

wxDC::LogicalToDevice() now always returns unmirrored coordinates in RTL layout.
Also revert commit 3d40c2a (Fix wxDC::StretchBlit() for non-0
xsrc in RTL layout) which is no longer needed.
This constant is only used inside ApplyEffectiveScale()

No real changes.
Zooming and scaling the GDI device context in RTL layout was already broken
even before the latest changes.
- Try enabling (Zoom 125%) under (File > Render setup) before clicking on
  (Render) in the griddemo.
- Try Scale (Ctrl+H) in the drawing sample.

The implementation has been changed to use the GDI function ScaleWindowExtEx()
instead, which gives better results even in an LTR layout.
@AliKet
Copy link
Copy Markdown
Contributor Author

AliKet commented May 16, 2026

@vadz let me know if this commit 886240d should be extracted to its own PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants