Phoenix
Phoenix copied to clipboard
GraphicsContext 0.5 Offset Helper not working in v4.2
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)
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)
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()
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.