[patch] cosmetic fix for KPlotWidget

Zack Rusin zack at kde.org
Tue Jan 1 15:34:06 GMT 2008

On Monday 24 December 2007 08:49:56 am David Faure wrote:
> On Tuesday 04 December 2007, Zack Rusin wrote:
> > so lets try this again, but this time with the attached
> > example. the example illustrates:
> > a) how to properly snap primitives (within the DRAW_GOOD_SNAPPING) - of
> > course as i repeated a few times - this is vector graphics no amount of
> > snapping will solve all the cases but this one is the closest,
> > b) how not to snap, which is what was committed (within the
> > c) why "b" is wrong and how it breaks (within the MESS_UP_SNAPPING)
> > d) that the coordinate systems do match, it's just that the the aliased
> > one rounds up towards ceil (with SHOW_WHERE_ALIASED_COORDINATES_START)
> >
> > i think this should answer almost all the questions posed in this thread.
> > what it doesn't answer is why it was done this way but life has its
> > mysteries and the sooner we learn to deal with them the better.
> Hi Zack,
> Thanks for this example.
> To understand it better I made it interactive, so that one can now toggle
> checkboxes and see the effect immediately, rather than modify
> code+compile+run+open png file :) New example attached, I hope this helps
> others understanding it as well.

Hey, very nice :)

Looking back I'm not sure if we actually point out in the documentation what's 
up with the stroking voodoo.

So in a list:

- stroke is the outline of a shape. As an outline the definition is that the 
center of the stroke is the very edge of the shape. That means that stroke of 
width of 2 units is 1 unit outside the shape and 1 unit inside the shape. 

By default on QPainter we have a comestic pen of width 0 equaling 1px, which 
means it's going to be 0.5 outside the shape and 0.5 inside the shape.

- By definition *fill* of the figure is aligned. So a rectangle of width 1 and 
height 10 at (0,0) has:
   o) fill that goes from horizontally from 0-1 and 0-10 vertically which 
means it's perfectly aligned
   o) stroke that goes from horizontally -0.5-0.5 and 9.5-10.5 and
vertically from -0.5-0.5 and 0.5-1.5

- So one could ask "why are lines stroked instead of filled? If they would be 
a filled primitive they would be aligned". The reason for that is that lines 
by definition don't have an inside, so it's impossible to figure out what's 
the filled width - the width of the line is defined as the stroke width. 
Lines which have both inside and outside (fill and stroke respectively) are 
simply quads (polygons in Qt's terminology)

With the following three in mind one has to remember that my example shows 
only a portion of cases where the snapping breaks down. The cases not covered 
by my example include such problems as:

- translating the whole painter by 0.5 will make *fill* unaligned. So if any 
of the draw shapes has setPen(Qt::NoPen) and setBrush(anything) then they 
will look blurry.

- pen of width different than 0 (or 1 with setCosmetic set to true on QPen) 
will cause problems. For example translate(0.5, 0.5) will have opposite 
effect on QPen(Qt::black, 2). It will actually unalign it on an untransformed 
qpainter making it blurry. That's because by definition stroke of width 2 on 
an untransformed painter will fall 1px inside and 1px outside the shape. And 
since the fill is aligned fill 1px outside and 1px inside will be aligned as 
well :)

I think that if I were to ever write a gui app whose requirement would be 
pixel alignment with vector graphics I'd use setPen(Qt::NoPen) and make sure 
that everything I draw is simply filled not stroked. E.g. use rectangles 
instead of horizontal/vertical lines and *filled* paths instead of everything 
else. It would then just work and I wouldn't have to worry about any of the 
above mentioned problems and transformation voodoo :)
Hope that helps.


More information about the kde-core-devel mailing list