Hello, I have a problem with 2.9 (just began using it). When MapMode is wx.MM_TWIPS in a custom drawn window, SetPointSize for wx.Font doesn't work as expected. I want to get dc.SetMapMode(wx.MM_TWIPS) ... dc.SetUserScale(self.zoom, self.zoom) ... # Get the font font = dc.GetFont() font.SetPointSize(int(self.zoom*dc.DeviceToLogicalYRel(12))) # Works in 2.8
Scale method of wx.Font (only in 2.9.1+) does increase/decrease the size while zooming in/out, but I can't get the original size to what it would be if dc.SetMapMode(wx.MM_POINTS) was used, even by multiplying with a factor of TWIPS/POINTS = 20.
On Fri, 9 Nov 2012 00:04:36 -0800 (PST) Gregory Papadopoulos wrote:
GP> I have a problem with 2.9 (just began using it).
Under which platform did you test this?
GP> I want to get GP> dc.SetMapMode(wx.MM_TWIPS)
GP> ...
GP> dc.SetUserScale(self.zoom, self.zoom)
GP> ...
GP> # Get the font
GP> font = dc.GetFont()
GP> font.SetPointSize(int(self.zoom*dc.DeviceToLogicalYRel(12))) # Works in 2.8
I think it should be just
font.SetPointSize(12)
I didn't realize that this changed since 2.8 but the current behaviour
seems to be logical to me as the font size adjusts to the scaling/mapping
mode just as everything else does.
FWIW it could be argued that the size specified in points shouldn't depend
on scaling as a point is a physical unit, just as a centimeter, but I think
this would be quite surprising.
I've been testing this on Win XP and Win 7 64bit (python 2.7 32bit, wxPython 2.8 unicode )
VZ> I think it should be just VZ> font.SetPointSize(12)
Indeed it should be like that. Since I am working in wx.MM_TWIPS the actual font is about 182points big. The function above (self.zoom*dc.DeviceToLogicalYRel(12)) just sets the font to appear like it would if pointsize 12 was used in wx.MM_POINTS for the appropriate zoom.
But that is not the point. Even if i just set it to font.SetPointSize(12), when SetUserScale is called, the font doesn't "zoom" (only in wx 2.9), while everything else does. And this is my problem. It is opposite to what you are pointing out yourself.
On Fri, 9 Nov 2012 06:00:35 -0800 (PST) Gregory Papadopoulos wrote:
GP> I've been testing this on Win XP and Win 7 64bit (python 2.7 32bit, GP> wxPython 2.8 unicode )
And which version of 2.9? Please retest if it wasn't the latest one
because I don't see what you're seeing here.
GP> VZ> I think it should be just font.SetPointSize(12) GP>
GP> Indeed it should be like that. Since I am working in wx.MM_TWIPS the actual GP> font is about 182points big.
Err, its physical size should be much smaller than 12 points, not larger,
in TWIPS mapping mode.
GP> Even if i just set it to font.SetPointSize(12), when SetUserScale is GP> called, the font doesn't "zoom" (only in wx 2.9), while everything else GP> does.
It does for me in the drawing sample included with wxWidgets. Both
changing the mapping mode and the scale (see the appropriate menus in this
sample) change the font size.
I'm attaching screenshot of the result in both systems and a stripped down code that reproduces the problem. Its the same script. The left one is on WinXP, 64bit Python 2.7.3 32bit with wx.Python 2.8.12.1 32 bit unicode for Py2.7 The right one is on Win7 64bit Python 2.7.3 32bit with wx.Python 2.9.4.0 32bit for Py2.7
I did what you proposed and it works just fine. Really thanks for that. Just in case anybody is interested, I didn't leave it to that, and so tried to locate where the problem was in my code. What I was doing (and worked in wx 2.8) was getting the dc font and the manipulating its properties, changing the face all the while. Something like: font = dc.GetFont() font.SetFaceName(facename) font.SetPointSize(pointsize) font.SetStyle(wx.FONTSTYLE_NORMAL) font.SetWeight(wx.FONTWEIGHT_NORMAL) dc.SetFont(font) I know it not the most compact way of programming, instead I thought it'd be better not to create a new wx.Font object.
Now in wx 2.9 this code doesn't work properly unless you've already set a font, like: dc.SetFont(wx.Font(12, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) So adding this line before font = dc.GetFont() fixes my problem. Now I am asking myself if I should expect that.
On Sat, 10 Nov 2012 08:36:42 -0800 (PST) Gregory Papadopoulos wrote:
GP> What I was doing (and worked in wx 2.8) was getting the dc font and the GP> manipulating its properties, changing the face all the while. Something GP> like:
GP> font = dc.GetFont()
GP> font.SetFaceName(facename)
GP> font.SetPointSize(pointsize) GP> font.SetStyle(wx.FONTSTYLE_NORMAL)
GP> font.SetWeight(wx.FONTWEIGHT_NORMAL)
GP> dc.SetFont(font)
GP> I know it not the most compact way of programming, instead I thought it'd GP> be better not to create a new wx.Font object.
wxFont objects are pretty lightweight, it's the fonts themselves (i.e. the
graphical objects actually used for drawing) that are not. And a new such
underlying object is created whenever you call any wxFont::SetXXX(), so the
above doesn't really save you anything.
GP> Now in wx 2.9 this code doesn't work properly unless you've already set a GP> font, like:
GP> dc.SetFont(wx.Font(12, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, GP> wx.FONTWEIGHT_NORMAL))
GP> So adding this line before font = dc.GetFont() fixes my problem. GP> Now I am asking myself if I should expect that.
No, you shouldn't. And the trouble is that, just as before, I can't
reproduce the problem you have, e.g. this code:
This time I can verify that it doesn't work otherwise. This is the paint routine that doesn't work
def OnPaint(self, event): dc = wx.PaintDC(self) dc.SetMapMode(wx.MM_TWIPS) font = dc.GetFont() font.SetPointSize(182) dc.SetFont(font) dc.DrawText('How about now', 0, 0)
while this works:
def OnPaint(self, event): dc = wx.PaintDC(self) dc.SetMapMode(wx.MM_TWIPS) dc.SetFont(wx.Font(182, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) font = dc.GetFont() font.SetPointSize(182) dc.SetFont(font) dc.DrawText('How about now', 0, 0)
The first piece does exactly what you are proposing on your C++ code. Well, besides the text rendered and its position. The second just works, even on the original code by adding that line (or any equivalent I guess).
Would you like me to take a deeper look into it? Any thoughts/proposals on what we should do?
On Sunday, November 11, 2012 2:43:54 PM UTC+2, Vadim Zeitlin wrote:
> On Sat, 10 Nov 2012 08:36:42 -0800 (PST) Gregory Papadopoulos wrote:
> GP> What I was doing (and worked in wx 2.8) was getting the dc font and > the > GP> manipulating its properties, changing the face all the while. > Something > GP> like: > GP> font = dc.GetFont() > GP> font.SetFaceName(facename) > GP> font.SetPointSize(pointsize) > GP> font.SetStyle(wx.FONTSTYLE_NORMAL) > GP> font.SetWeight(wx.FONTWEIGHT_NORMAL) > GP> dc.SetFont(font) > GP> I know it not the most compact way of programming, instead I thought > it'd > GP> be better not to create a new wx.Font object.
> wxFont objects are pretty lightweight, it's the fonts themselves (i.e. > the > graphical objects actually used for drawing) that are not. And a new such > underlying object is created whenever you call any wxFont::SetXXX(), so > the > above doesn't really save you anything.
> GP> Now in wx 2.9 this code doesn't work properly unless you've already > set a > GP> font, like: > GP> dc.SetFont(wx.Font(12, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, > GP> wx.FONTWEIGHT_NORMAL)) > GP> So adding this line before font = dc.GetFont() fixes my problem. > GP> Now I am asking myself if I should expect that.
> No, you shouldn't. And the trouble is that, just as before, I can't > reproduce the problem you have, e.g. this code:
On Mon, 12 Nov 2012 02:03:13 -0800 (PST) Gregory Papadopoulos wrote:
GP> This time I can verify that it doesn't work otherwise. This is the paint GP> routine that doesn't work
GP> GP> def OnPaint(self, event):
GP> dc = wx.PaintDC(self)
GP> dc.SetMapMode(wx.MM_TWIPS)
GP> font = dc.GetFont()
GP> font.SetPointSize(182) GP> dc.SetFont(font)
GP> dc.DrawText('How about now', 0, 0)
GP> GP> while this works: GP> GP> def OnPaint(self, event):
GP> dc = wx.PaintDC(self)
GP> dc.SetMapMode(wx.MM_TWIPS)
GP> dc.SetFont(wx.Font(182, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, GP> wx.FONTWEIGHT_NORMAL))
GP> font = dc.GetFont()
GP> font.SetPointSize(182) GP> dc.SetFont(font)
GP> dc.DrawText('How about now', 0, 0)
GP> GP> The first piece does exactly what you are proposing on your C++ code. Well, GP> besides the text rendered and its position. GP> The second just works, even on the original code by adding that line (or GP> any equivalent I guess).
Strange, I don't see why would the behaviour be different in Python and
C++.
GP> Would you like me to take a deeper look into it? Any thoughts/proposals on GP> what we should do?
First, could you please check if the problem persists if you draw directly
on wxFrame, like my code did, or if it only happens when using
wxScrolledWindow?
Second, please try to test with the latest svn if possible or retest with
2.9.5 when it's out. While I don't remember any relevant changes in the
code, perhaps something did change recently.
> Strange, I don't see why would the behaviour be different in Python and > C++.
Same here. I don't get it. I was thinking of moving the code to C++, but for the time being I am forced to use Python. (+ it is faster to develop :)
First, could you please check if the problem persists if you draw directly
> on wxFrame, like my code did, or if it only happens when using > wxScrolledWindow?
Same result for wx.Panel. Leaning towards believing it's related to the font system
> Second, please try to test with the latest svn if possible or retest with > 2.9.5 when it's out. While I don't remember any relevant changes in the > code, perhaps something did change recently.
I'll get the svn if its not a big deal to setup in a system. Can't test it right away. I should be thanking you. Greg
> On Mon, 12 Nov 2012 02:03:13 -0800 (PST) Gregory Papadopoulos wrote:
> GP> This time I can verify that it doesn't work otherwise. This is the paint
> GP> routine that doesn't work
> GP>
> GP> def OnPaint(self, event):
> GP> dc = wx.PaintDC(self)
> GP> dc.SetMapMode(wx.MM_TWIPS)
> GP> font = dc.GetFont()
> GP> font.SetPointSize(182)
> GP> dc.SetFont(font)
> GP> dc.DrawText('How about now', 0, 0)
> GP>
> GP> while this works:
> GP>
> GP> def OnPaint(self, event):
> GP> dc = wx.PaintDC(self)
> GP> dc.SetMapMode(wx.MM_TWIPS)
> GP> dc.SetFont(wx.Font(182, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL,
> GP> wx.FONTWEIGHT_NORMAL))
> GP> font = dc.GetFont()
> GP> font.SetPointSize(182)
> GP> dc.SetFont(font)
> GP> dc.DrawText('How about now', 0, 0)
> GP>
> GP> The first piece does exactly what you are proposing on your C++ code. Well,
> GP> besides the text rendered and its position.
> GP> The second just works, even on the original code by adding that line (or
> GP> any equivalent I guess).
> Strange, I don't see why would the behaviour be different in Python and
> C++.
One difference is that the C++ code made a copy of the dc's font:
wxFont font(dc.GetFont());
but the Python code was using and modifying the same font already set in the DC, if any:
font = dc.GetFont()
Since GetFont is returning a reference then it will be the same font object that is already set in the DC. I seem to recall that there was some change in the last several months related to the default font in DCs, perhaps that is part of the cause of the different results?
Indeed that seems to be the main difference.
But dc.GetFont() returns a wx.Font object, which is a copy of the one
already set. After that if you make changes you have to set the font with
dc.SetFont( the_wx.FontObject )
I think it will be better to have a look into wx.Python code to see what is
done there
On Mon, Nov 12, 2012 at 8:06 PM, Robin Dunn <ro...@alldunn.com> wrote:
> On 11/12/12 3:26 AM, Vadim Zeitlin wrote:
>> On Mon, 12 Nov 2012 02:03:13 -0800 (PST) Gregory Papadopoulos wrote:
>> GP> This time I can verify that it doesn't work otherwise. This is the
>> paint
>> GP> routine that doesn't work
>> GP>
>> GP> def OnPaint(self, event):
>> GP> dc = wx.PaintDC(self)
>> GP> dc.SetMapMode(wx.MM_TWIPS)
>> GP> font = dc.GetFont()
>> GP> font.SetPointSize(182)
>> GP> dc.SetFont(font)
>> GP> dc.DrawText('How about now', 0, 0)
>> GP>
>> GP> while this works:
>> GP>
>> GP> def OnPaint(self, event):
>> GP> dc = wx.PaintDC(self)
>> GP> dc.SetMapMode(wx.MM_TWIPS)
>> GP> dc.SetFont(wx.Font(182, wx.FONTFAMILY_ROMAN,
>> wx.FONTSTYLE_NORMAL,
>> GP> wx.FONTWEIGHT_NORMAL))
>> GP> font = dc.GetFont()
>> GP> font.SetPointSize(182)
>> GP> dc.SetFont(font)
>> GP> dc.DrawText('How about now', 0, 0)
>> GP>
>> GP> The first piece does exactly what you are proposing on your C++ code.
>> Well,
>> GP> besides the text rendered and its position.
>> GP> The second just works, even on the original code by adding that line
>> (or
>> GP> any equivalent I guess).
>> Strange, I don't see why would the behaviour be different in Python and
>> C++.
> One difference is that the C++ code made a copy of the dc's font:
> wxFont font(dc.GetFont());
> but the Python code was using and modifying the same font already set in
> the DC, if any:
> font = dc.GetFont()
> Since GetFont is returning a reference then it will be the same font
> object that is already set in the DC. I seem to recall that there was some
> change in the last several months related to the default font in DCs,
> perhaps that is part of the cause of the different results?