Consider map rotation in rendering of horizontal and parallel labels

See http://hub.qgis.org/issues/11814

NOTE: the map rotation should likely be considered at LabelPlacement
      configuration rather than at rendering time

Raises pixel mismatch tolerance for background labels tests
This commit is contained in:
Sandro Santilli 2014-12-10 10:57:29 +01:00
parent bd4087b4d3
commit 917cee0510
2 changed files with 61 additions and 4 deletions

View File

@ -1415,10 +1415,16 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF* fm, QString t
}
}
w /= rasterCompressFactor;
QgsPoint ptSize = xform->toMapCoordinatesF( w, h );
#if 0 // XXX strk
QgsPoint ptSize = xform->toMapCoordinatesF( w, h );
labelX = qAbs( ptSize.x() - ptZero.x() );
labelY = qAbs( ptSize.y() - ptZero.y() );
#else
double uPP = xform->mapUnitsPerPixel();
labelX = w * uPP;
labelY = h * uPP;
#endif
}
void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext& context, QString dxfLayer )
@ -4115,12 +4121,37 @@ QgsPalLabeling::Search QgsPalLabeling::searchMethod() const
void QgsPalLabeling::drawLabelCandidateRect( pal::LabelPosition* lp, QPainter* painter, const QgsMapToPixel* xform )
{
QgsPoint outPt = xform->transform( lp->getX(), lp->getY() );
QgsPoint outPt2 = xform->transform( lp->getX() + lp->getWidth(), lp->getY() + lp->getHeight() );
painter->save();
#if 1 // TODO: generalize some of this
double w = lp->getWidth();
double h = lp->getHeight();
double cx = lp->getX() + w/2.0;
double cy = lp->getY() + h/2.0;
double scale = 1.0/xform->mapUnitsPerPixel();
double rotation = xform->mapRotation();
double sw = w * scale;
double sh = h * scale;
QRectF rect( -sw/2, -sh/2, sw, sh );
painter->translate( xform->transform( QPointF(cx, cy) ).toQPointF() );
if ( rotation ) {
// Only if not horizontal
if ( lp->getFeaturePart()->getLayer()->getArrangement() != P_HORIZ ) {
painter->rotate( rotation );
}
}
painter->translate( rect.bottomLeft() );
painter->rotate( -lp->getAlpha() * 180 / M_PI );
painter->translate( -rect.bottomLeft() );
#else
QgsPoint outPt2 = xform->transform( lp->getX() + lp->getWidth(), lp->getY() + lp->getHeight() );
QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
painter->translate( QPointF( outPt.x(), outPt.y() ) );
painter->rotate( -lp->getAlpha() * 180 / M_PI );
QRectF rect( 0, 0, outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
#endif
painter->drawRect( rect );
painter->restore();
@ -4172,7 +4203,7 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
drawLabelBackground( context, component, tmpLyr );
}
if ( drawType == QgsPalLabeling::LabelBuffer
else if ( drawType == QgsPalLabeling::LabelBuffer
|| drawType == QgsPalLabeling::LabelText )
{
@ -4255,8 +4286,30 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
for ( int i = 0; i < lines; ++i )
{
painter->save();
#if 1 // TODO: generalize some of this
LabelPosition* lp = label;
double w = lp->getWidth();
double h = lp->getHeight();
double cx = lp->getX() + w/2.0;
double cy = lp->getY() + h/2.0;
double scale = 1.0/xform->mapUnitsPerPixel();
double rotation = xform->mapRotation();
double sw = w * scale;
double sh = h * scale;
QRectF rect( -sw/2, -sh/2, sw, sh );
painter->translate( xform->transform( QPointF(cx, cy) ).toQPointF() );
if ( rotation ) {
// Only if not horizontal
if ( lp->getFeaturePart()->getLayer()->getArrangement() != P_HORIZ ) {
painter->rotate( rotation );
}
}
painter->translate( rect.bottomLeft() );
painter->rotate( -lp->getAlpha() * 180 / M_PI );
#else
painter->translate( QPointF( outPt.x(), outPt.y() ) );
painter->rotate( -label->getAlpha() * 180 / M_PI );
#endif
// scale down painter: the font size has been multiplied by raster scale factor
// to workaround a Qt font scaling bug with small font sizes

View File

@ -79,6 +79,8 @@ class TestPointBase(object):
self.checkTest()
def test_background_rect(self):
self._Mismatches['TestComposerImageVsCanvasPoint'] = 800
self._Mismatches['TestComposerImagePoint'] = 800
self.lyr.shapeDraw = True
self._Mismatches['TestCanvasPoint'] = 776;
self._ColorTols['TestComposerPdfPoint'] = 1;
@ -86,6 +88,8 @@ class TestPointBase(object):
def test_background_rect_w_offset(self):
# Label rectangular background
self._Mismatches['TestComposerImageVsCanvasPoint'] = 800
self._Mismatches['TestComposerImagePoint'] = 800
# verify fix for issues
# http://hub.qgis.org/issues/9057
# http://gis.stackexchange.com/questions/86900