wxWidgets / Phoenix

wxPython's Project Phoenix. A new implementation of wxPython, better, stronger, faster than he was before.
http://wxpython.org/
2.29k stars 516 forks source link

GraphicsContext 0.5 Offset Helper not working in v4.2 #2449

Open TravStu22 opened 1 year ago

TravStu22 commented 1 year ago

Operating system: Microsoft Windows 10 Pro Version 10.0.19045 Build 19045 wxPython version & source: 4.2.1 msw (phoenix) wxWidgets 3.2.2.1 from pypi Python version & source: Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD64)] on win32 from stock

Description of the problem: I upgraded to v4.2 and noticed my line drawing is now blurry on a scaled display. While researching the problem, I saw that there is something important about 0.5 and how there is a helper function in the graphics context that is supposed to deal with that automatically?

It looks like the offset helper only does something at 100% scale in v4.2.

Here is v4.2 at 3 different display scales. Note how the top left and bottom left panel show the helper being on/off has an effect at 100% but not at the other scales. (in the right side panels, I’m manually offsetting x and y by 0.5) graphics context offset issue examples

Now going back to v4.1 we see that the helper does something at each scale. (shoe-horned into image above)

Here is some code to reproduce the samples: (click to expand) ```python import wx import ctypes ctypes.windll.shcore.SetProcessDpiAwareness(1) #1=PROCESS_SYSTEM_DPI_AWARE, 2=PROCESS_PER_MONITOR_DPI_AWARE class ExampleFrame(wx.Frame): def __init__(self, parent): super(ExampleFrame, self).__init__(parent) self.SetTitle('{} Display Scale: {}%'.format(wx.version(), self.scaled_dpi(100))) self.SetSize(650, 350) self.buffer = wx.Bitmap(600, 300, 32) dc = wx.MemoryDC(self.buffer) dc.SetBackground(wx.Brush(wx.Colour(255, 255, 255))) dc.Clear() gc = wx.GraphicsContext.Create(dc) self.draw(gc) self.Bind(wx.EVT_PAINT, self.on_paint) self.Show(True) def scaled_dpi(self, value): #round down the result scaled by DPI return int(value * (self.FromDIP(100)/100)) def draw(self, gc): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) if '4.1' in wx.version(): font.SetPointSize(12) else: font.SetPointSize(self.scaled_dpi(12)) gc.SetFont(font, wx.BLACK) gc.SetPen(wx.Pen(wx.Colour(0, 0, 0), 1)) #divider path = gc.CreatePath() path.MoveToPoint(300, 0) path.AddLineToPoint(300, 300) path.MoveToPoint(0, 150) path.AddLineToPoint(600, 150) gc.DrawPath(path) for i in range(4): gc.PushState() if i==0: gc.Translate(0, 0) gc.DrawText('( x, y )', 60, 5) gc.EnableOffset() gc.DrawText('GC Offset Enabled', 60, 110) if i==1: gc.Translate(300, 0) gc.Translate(0.5, 0.5) gc.DrawText('( x+0.5, y+0.5 )', 60, 5) gc.EnableOffset() gc.DrawText('GC Offset Enabled', 60, 110) if i==2: gc.Translate(0, 150) gc.DrawText('( x, y )', 60, 5) gc.DisableOffset() gc.DrawText('GC Offset Disabled', 60, 110) if i==3: gc.Translate(300, 150) gc.Translate(0.5, 0.5) gc.DrawText('( x+0.5, y+0.5 )', 60, 5) gc.DisableOffset() gc.DrawText('GC Offset Disabled', 60, 110) gc.SetBrush(wx.Brush(wx.Colour(245, 245, 245))) gc.DrawRectangle(100, 50, 50, 50) gc.SetBrush(wx.NullBrush) path = gc.CreatePath() path.MoveToPoint(20, 20) path.AddLineToPoint(100, 100) path.AddLineToPoint(200, 100) path.AddLineToPoint(220, 50) gc.DrawPath(path) gc.PopState() def on_paint(self, e): dc = wx.BufferedPaintDC(self, self.buffer) app = wx.App() ExampleFrame(None) app.MainLoop() ```
swt2c commented 1 year ago

Thanks for the detailed report. I don't think anything relevant changed in wxPython itself, so I think the difference in behavior is likely due to upstream wxWidgets changes. You may want to ask on one of the wxWidgets support forums (e.g., mailing lists: https://wxwidgets.org/support/mailing-lists/) as they are going to have more expertise in this area.