[wxPython-users] LCD vs CRT Monitors Issues (!)

Nitro nitro at dr-code.org
Fri Nov 2 05:48:49 PDT 2007


Am 02.11.2007, 13:12 Uhr, schrieb Andrea Gavana <andrea.gavana at gmail.com>:

> Hi Robin and All,
>
> On 11/2/07, Robin Dunn wrote:
>> Andrea Gavana wrote:
>>
>> > Curiously, just replacing this line:
>> >
>> > fnt = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
>> >
>> > with this line:
>> >
>> > fnt = wx.SystemSettings_GetFont(wx.SYS_ANSI_VAR_FONT)
>> >
>> > Fixed the issue. I have no idea why, but it works.
>>
>> Probably because the font used in that case on your system is either a
>> bitmap font (instead of a vector format like TTF) or doesn't specify any
>> hinting that the system will use for anti-aliased drawing.
>>
>> I expect that the only way to truly solve this for any font is to make
>> sure that the text only gets drawn once.  If it needs to be drawn again
>> for some reason, such as it is part of the update region in a paint
>> event, then you either need to redraw everything 'behind' it too, or
>> don't use dc.SetBackgroundMode(wx.TRANSPARENT).  To better see what is
>> happening you should get a tool that lets you zoom in on the display and
>> see the individual pixels magnified.  If you look at some text then if
>> it's using anti-aliasing (or 'font smoothing' or 'ClearType') you'll see
>> some pixels along the curves and corners that are not fully black, or
>> that may even have some color.  If the same text gets redrawn at the
>> same place then those aliased pixels will be blended with the ones that
>> are already there and they will become a little bit darker, and a little
>> more dark the next time it is drawn.
>
> I found that the issue is *not* related to multiple drawing of the
> text, but actually on a strange behavior of wx.Mask/wx.MemoryDC. Let
> me explain.
>
> To speed up the drawing, the first time I paint the menubar (and after
> every resize event), I paint the menu label (with its accelerator) to
> a bitmap using a wx.MemoryDC() and I save a reference to this bitmap
> in the menu class. All the next paint event (generated by
> EVT_ENTER_WINDOW, EVT_LEAVE_WINDOW and others) use this bitmap instead
> of redrawing the text because it's much faster (redrawing the text
> requires more calculations, background drawing, line drawing etc...).
>
> Ok, the problem is, I paint the menu background using the following code:
>
> bmp = wx.EmptyBitmap(rect.width, rect.height)
> memDc = wx.MemoryDC()
> memDc.SelectObject(bmp)
>
> # Fill the bitmap with the maksing colour
> memDc.SetPen(wx.Pen(wx.Colour(0, 128, 128)))
> memDc.SetBrush(wx.Brush(wx.Colour(0, 128, 128)))
> memDc.DrawRectangle(0, 0, rect.width, rect.height)
>
> And then I do all the voodoo to correctly paint the menu label. In the
> end, what I do to store the bitmap is:
>
> bmp.SetMask(wx.Mask(bmp, wx.Colour(0, 128, 128)))
> item.SetTextBitmap(bmp)
>
> The problem is with wx.Mask: it doesn't mask correctly the
> wx.Colour(0, 128, 128), or whatever other colour you choose for the
> wx.Pen, wx.Brush and wx.Mask. I attach a simple example which
> demonstrates the problem: you will notice that the text saved to a
> bitmap (and then painted on the DC) is blurred. Obviously you will see
> this strange behavior on LCD screens or on CRT screens with ClearType
> on.
>
> Does anyone know what I can do to obtain the bitmap with the correct
> mask? Any other solution?

I guess what's happening is that the anti-aliased text is blended with  
your mask colour, thereby slightly altering it. Then the mask won't work  
anymore because it masks exactly one colour. You can think of masks as  
1-bit alpha channels. Anti-aliasing has varying levels of alpha and thus  
the 1-bit won't cut it anymore.
One way to solve this is to use some kind of 8-bit alpha channel. The  
background colour of the bitmap would be completely transparent. Then the  
text drawing would fill the bitmap in such a way that the alpha channel is  
taken account of. Meaning 50% anti-aliased pixels get an alpha value of  
128 while fullly drawn pixels use an alpha of 255.
Now I am not sure if wx can do all this kind of alpha handling. I guess  
especially the "draw font into bitmap preserving alpha information" part  
might be impossible. Then you could probably just fill the bitmap with the  
background colour initially instead.

-Matthias




More information about the wxpython-users mailing list