Skip to content
Permalink
Browse files

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
  • Loading branch information
Sandro Santilli
Sandro Santilli committed Dec 12, 2014
1 parent bd4087b commit 917cee0510cdba4a52cae4a785a974808ecb7a56
Showing with 61 additions and 4 deletions.
  1. +57 −4 src/core/qgspallabeling.cpp
  2. +4 −0 tests/src/python/test_qgspallabeling_tests.py
@@ -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();
painter->translate( QPointF( outPt.x(), outPt.y() ) );

#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 );
#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
@@ -79,13 +79,17 @@ def test_text_color(self):
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;
self.checkTest()

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

0 comments on commit 917cee0

Please sign in to comment.
You can’t perform that action at this time.