[Qgis-developer] QgsRubberBand 1px shift

Martin Dobias wonder.sk at gmail.com
Mon May 2 10:31:53 EDT 2011


On Mon, May 2, 2011 at 3:36 PM, Radim Blazek <radim.blazek at gmail.com> wrote:
> On Mon, May 2, 2011 at 3:04 PM, Martin Dobias <wonder.sk at gmail.com> wrote:
>>> // use the same rounding as in qrasterizer.cpp (6 bit fixed point)
>>> static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
>>
>> As far as I understand this, Qt treats pixels to be squares (x,y) to
>> (x+1,y+1), where x and y are integers. Therefore a horizontal line
>> (0,1) - (10,1) is located exactly between the row 0 and row 1. Indeed
>> when rendering with antialiasing turned on, and 1pixel pen width the
>> line spans two rows, each with 50% opacity. When rendering without
>> antialiasing, Qt probably wants to avoid rounding errors and shifts
>> everything by 0.5px, therefore the same line (0,1) - (10,1) fits
>> exactly the pixels on row 1.
>
> What 'rounding errors'? The problem is, that using
>  p.drawLine(QPointF(0,0.2), QPointF(10,0.2))
> in your script without antialiasing will render the line on the second
> row! Which I believe, is far from any expected result.

Oh, I see! This really looks like a bug in x11 paint engine (running
Qt 4.6.2 here). If you use QImage (raster engine) instead of QPixmap
you get the expected result (line still on the first row). Also OpenGL
engine gives correct results.

You may try adding this before creation of QApplication instance:
QApplication::setGraphicsSystem("raster");

This will effectively use QImage raster engine also for QPixmap
operations. I think it is also believed to be more performant than
native x11 engine):
http://labs.qt.nokia.com/2008/10/22/so-long-and-thanks-for-the-blit/

>> Shouldn't we actually use the antialiasing flag from map canvas
>> instead of hardcoding antialiasing on? Like that the offset in
>> rendered map and canvas items should be equal.
>
> Better, but currently QgsMapCanvas sets antialiasing directly on
> QgsMapCanvasMap which has no QgsMapCanvasMap::antiAliasing() method so
> it has to be added somewhere.

Right, there's only QgsMapCanvas::enableAntiAliasing() which should
have also the getter like hasAntiAliasing()

Martin


More information about the Qgis-developer mailing list