Hi Radim
On Mon, May 2, 2011 at 1:13 PM, Radim Blazek <[email protected]> wrote:
> Hi,
> I am observing QgsRubberBand 1px shift with GRASS region. You can
> verify comparing a layer with full region extent (e.g. r.mapcalc
> test=1 or v.in.region output=test) with current region. After a long
> QGIS code inspection I have discovered quite strange piece of code in
> QT:
>
> qpaintengine_x11.cpp:
>
> // 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.
The magic constant 0.15625 is actually 1/64 and it is apparently there
to produce equivalent results to the native Qt rasterizer which works
in fixed precision of 1/64 px.
Btw. this simple script illustrates the behavior:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
a = QApplication(sys.argv)
pix = QPixmap(64, 64)
pix.fill()
p = QPainter(pix)
p.drawLine(QPointF(0,0), QPointF(10,0)) # no antialiasing
p.setRenderHint(QPainter.Antialiasing)
p.drawLine(QPointF(0,2), QPointF(10,2))
p.end()
pix.save("antitest.png")
> using QPainter::Antialiasing hint in fact solves the problem:
>
> --- src/gui/qgsmapcanvasitem.cpp (revision 15861)
> +++ src/gui/qgsmapcanvasitem.cpp (working copy)
> @@ -42,6 +42,7 @@
> const QStyleOptionGraphicsItem * option,
> QWidget * widget )
> {
> + painter->setRenderHint(QPainter::Antialiasing);
> paint( painter ); // call the derived item's drawing routines
> }
>
> May I apply the patch? I hope that just setting the hint should not
> harm but I don't want to break anything in QGIS core few days before
> release.
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.
Cau
Martin
_______________________________________________
Qgis-developer mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/qgis-developer