Fix off-by-one/one positioning by GeoPainter::drawEllipse/Rectangle

Summary:
GeoPainter::drawEllipse() & GeoPainter::drawRect() both take the
parameters width & height as qreal type, but if !isGeoProjected they do the
actual rendering calls using int based coordinates & sizes.

The old calculation would not compensate qreal->int rounding changes and often result
in a wrong 1 pixel offset in direction of topleft corner.

The respective GeoPainter::regionFromEllipse() and GeoPainter::regionFromRect()
also are adapted, with the first also being fixed to take also strokeWidth
into account for the topleft corner calculation, like done with the rect.

Test Plan: Extended geopainter example app renders rectangles and ellipses as expected.

Reviewers: nienhueser, rahn, #marble

Reviewed By: rahn, #marble

Differential Revision: https://phabricator.kde.org/D2141
parent 8b37d1ea
......@@ -333,8 +333,16 @@ void GeoPainter::drawEllipse ( const GeoDataCoordinates & centerPosition,
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
for( int it = 0; it < pointRepeatNum; ++it ) {
QPainter::drawEllipse( d->m_x[it] - width / 2.0,
y - height / 2.0, width, height );
// Have to compensate truncate rounding of conversion from real to int
// for all of rx, ry, rw, rh (given int-based method called).
// (and the 0.5 base-offset for the middle of center pixel). E.g. should
// x=5, w=3 -> rx = 4, rw = 3
// x=5, w=3.5 -> rx = 4, rw = 3
// x=5, w=4 -> rx = 3, rw = 4
// x=5, w=5 -> rx = 3, rw = 5
QPainter::drawEllipse(d->m_x[it] - static_cast<int>(width / 2.0),
y - static_cast<int>(height / 2.0),
width, height);
}
}
}
......@@ -403,11 +411,11 @@ QRegion GeoPainter::regionFromEllipse ( const GeoDataCoordinates & centerPositio
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
for( int it = 0; it < pointRepeatNum; ++it ) {
regions += QRegion( d->m_x[it] - width / 2.0,
y - height / 2.0,
width + strokeWidth,
height + strokeWidth,
QRegion::Ellipse );
regions += QRegion(d->m_x[it] - static_cast<int>((width + strokeWidth) / 2.0),
y - static_cast<int>((height + strokeWidth) / 2.0),
width + strokeWidth,
height + strokeWidth,
QRegion::Ellipse );
}
}
return regions;
......@@ -845,7 +853,9 @@ void GeoPainter::drawRect ( const GeoDataCoordinates & centerCoordinates,
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
for( int it = 0; it < pointRepeatNum; ++it ) {
QPainter::drawRect( d->m_x[it] - ( width / 2.0 ), y - ( height / 2.0 ), width, height );
QPainter::drawRect(d->m_x[it] - static_cast<int>(width / 2.0),
y - static_cast<int>(height / 2.0),
width, height );
}
}
}
......@@ -874,8 +884,8 @@ QRegion GeoPainter::regionFromRect ( const GeoDataCoordinates & centerCoordinate
if ( visible ) {
// Draw all the x-repeat-instances of the point on the screen
for( int it = 0; it < pointRepeatNum; ++it ) {
regions += QRegion( d->m_x[it] - ( ( width + strokeWidth ) / 2.0 ),
y - ( ( height + strokeWidth ) / 2.0 ),
regions += QRegion( d->m_x[it] - static_cast<int>((width + strokeWidth) / 2.0),
y - static_cast<int>((height + strokeWidth) / 2.0),
width + strokeWidth,
height + strokeWidth );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment