summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFriedrich W. H. Kossebau <[email protected]>2016-07-12 05:17:10 +0200
committerFriedrich W. H. Kossebau <[email protected]>2016-07-12 13:49:53 +0200
commitad355e2fddffd8717555995b7880154c146a2bdd (patch)
treec1f32c8bad47125b72d7f46f01c8af6791c33411
parent8b37d1eae4d7bce9ca0d6b8c15aaf7477da754eb (diff)
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
-rw-r--r--src/lib/marble/GeoPainter.cpp30
1 files changed, 20 insertions, 10 deletions
diff --git a/src/lib/marble/GeoPainter.cpp b/src/lib/marble/GeoPainter.cpp
index 81f6674..019bc46 100644
--- a/src/lib/marble/GeoPainter.cpp
+++ b/src/lib/marble/GeoPainter.cpp
@@ -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 );
}