Skip to content

Commit

Permalink
Fix incorrect render context scaling for scale bar rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 24, 2017
1 parent 8f5e0cb commit 7e7770b
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 30 deletions.
3 changes: 3 additions & 0 deletions src/core/composer/qgscomposerscalebar.cpp
Expand Up @@ -69,7 +69,10 @@ void QgsComposerScaleBar::paint( QPainter *painter, const QStyleOptionGraphicsIt

QgsRenderContext c = QgsComposerUtils::createRenderContextForMap( mComposerMap, painter );

// scale painter from mm to dots
painter->scale( 1.0 / c.scaleFactor(), 1.0 / c.scaleFactor() );
mStyle->draw( c, mSettings, createScaleContext() );
painter->scale( c.scaleFactor(), c.scaleFactor() );

//draw frame and selection boxes if necessary
drawFrame( painter );
Expand Down
19 changes: 13 additions & 6 deletions src/core/scalebar/qgsdoubleboxscalebarrenderer.cpp
Expand Up @@ -28,17 +28,20 @@ void QgsDoubleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsSca
}
QPainter *painter = context.painter();

double barTopPosition = QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace();
double segmentHeight = settings.height() / 2;
double barTopPosition = context.convertToPainterUnits( QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters );
double segmentHeight = context.convertToPainterUnits( settings.height() / 2, QgsUnitTypes::RenderMillimeters );

painter->save();
if ( context.flags() & QgsRenderContext::Antialiasing )
painter->setRenderHint( QPainter::Antialiasing, true );
painter->setPen( settings.pen() );

QPen pen = settings.pen();
pen.setWidthF( context.convertToPainterUnits( pen.widthF(), QgsUnitTypes::RenderMillimeters ) );
painter->setPen( pen );

bool useColor = true; //alternate brush color/white

double xOffset = firstLabelXOffset( settings );
double xOffset = context.convertToPainterUnits( firstLabelXOffset( settings ), QgsUnitTypes::RenderMillimeters );

QList<double> positions = segmentPositions( scaleContext, settings );
QList<double> widths = segmentWidths( scaleContext, settings );
Expand All @@ -55,7 +58,9 @@ void QgsDoubleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsSca
painter->setBrush( settings.brush2() );
}

QRectF segmentRectTop( positions.at( i ) + xOffset, barTopPosition, widths.at( i ), segmentHeight );
QRectF segmentRectTop( context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset,
barTopPosition,
context.convertToPainterUnits( widths.at( i ), QgsUnitTypes::RenderMillimeters ), segmentHeight );
painter->drawRect( segmentRectTop );

//draw bottom half
Expand All @@ -69,7 +74,9 @@ void QgsDoubleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsSca
painter->setBrush( settings.brush() );
}

QRectF segmentRectBottom( positions.at( i ) + xOffset, barTopPosition + segmentHeight, widths.at( i ), segmentHeight );
QRectF segmentRectBottom( context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset,
barTopPosition + segmentHeight,
context.convertToPainterUnits( widths.at( i ), QgsUnitTypes::RenderMillimeters ), segmentHeight );
painter->drawRect( segmentRectBottom );
useColor = !useColor;
}
Expand Down
11 changes: 7 additions & 4 deletions src/core/scalebar/qgsnumericscalebarrenderer.cpp
Expand Up @@ -32,9 +32,11 @@ void QgsNumericScaleBarRenderer::draw( QgsRenderContext &context, const QgsScale
painter->save();
if ( context.flags() & QgsRenderContext::Antialiasing )
painter->setRenderHint( QPainter::Antialiasing, true );
painter->setFont( settings.font() );

double margin = settings.boxContentSpace();
QFont scaledFont = settings.font();
scaledFont.setPointSizeF( scaledFont.pointSizeF() * context.scaleFactor() );

double margin = context.convertToPainterUnits( settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters );
//map scalebar alignment to Qt::AlignmentFlag type
Qt::AlignmentFlag hAlign = Qt::AlignLeft;
switch ( settings.alignment() )
Expand All @@ -51,8 +53,9 @@ void QgsNumericScaleBarRenderer::draw( QgsRenderContext &context, const QgsScale
}

//text destination is item's rect, excluding the margin
QRectF painterRect( margin, margin, scaleContext.size.width() - 2 * margin, scaleContext.size.height() - 2 * margin );
QgsComposerUtils::drawText( painter, painterRect, scaleText( scaleContext.scale ), settings.font(), settings.fontColor(), hAlign, Qt::AlignTop );
QRectF painterRect( margin, margin, context.convertToPainterUnits( scaleContext.size.width(), QgsUnitTypes::RenderMillimeters ) - 2 * margin,
context.convertToPainterUnits( scaleContext.size.height(), QgsUnitTypes::RenderMillimeters ) - 2 * margin );
QgsComposerUtils::drawText( painter, painterRect, scaleText( scaleContext.scale ), scaledFont, settings.fontColor(), hAlign, Qt::AlignTop );

painter->restore();
}
Expand Down
15 changes: 9 additions & 6 deletions src/core/scalebar/qgsscalebarrenderer.cpp
Expand Up @@ -31,11 +31,12 @@ void QgsScaleBarRenderer::drawDefaultLabels( QgsRenderContext &context, const Qg

painter->save();

painter->setFont( settings.font() );
QFont scaledFont = settings.font();
scaledFont.setPointSizeF( scaledFont.pointSizeF() * context.scaleFactor() );
painter->setPen( QPen( settings.fontColor() ) );

QString firstLabel = firstLabelString( settings );
double xOffset = QgsComposerUtils::textWidthMM( settings.font(), firstLabel ) / 2;
double xOffset = context.convertToPainterUnits( QgsComposerUtils::textWidthMM( settings.font(), firstLabel ) / 2, QgsUnitTypes::RenderMillimeters );

double currentLabelNumber = 0.0;

Expand Down Expand Up @@ -64,8 +65,9 @@ void QgsScaleBarRenderer::drawDefaultLabels( QgsRenderContext &context, const Qg

if ( segmentCounter == 0 || segmentCounter >= nSegmentsLeft ) //don't draw label for intermediate left segments
{
QgsComposerUtils::drawText( painter, QPointF( positions.at( i ) - QgsComposerUtils::textWidthMM( settings.font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( settings.font() ) + settings.boxContentSpace() ),
currentNumericLabel, settings.font(), settings.fontColor() );
QgsComposerUtils::drawText( painter, QPointF( context.convertToPainterUnits( positions.at( i ) - QgsComposerUtils::textWidthMM( settings.font(), currentNumericLabel ) / 2, QgsUnitTypes::RenderMillimeters ) + xOffset,
context.convertToPainterUnits( QgsComposerUtils::fontAscentMM( settings.font() ) + settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters ) ),
currentNumericLabel, scaledFont, settings.fontColor() );
}

if ( segmentCounter >= nSegmentsLeft )
Expand All @@ -79,8 +81,9 @@ void QgsScaleBarRenderer::drawDefaultLabels( QgsRenderContext &context, const Qg
if ( !positions.isEmpty() )
{
currentNumericLabel = QString::number( currentLabelNumber / settings.mapUnitsPerScaleBarUnit() );
QgsComposerUtils::drawText( painter, QPointF( positions.at( positions.size() - 1 ) + scaleContext.segmentWidth - QgsComposerUtils::textWidthMM( settings.font(), currentNumericLabel ) / 2 + xOffset, QgsComposerUtils::fontAscentMM( settings.font() ) + settings.boxContentSpace() ),
currentNumericLabel + ' ' + settings.unitLabel(), settings.font(), settings.fontColor() );
QgsComposerUtils::drawText( painter, QPointF( context.convertToPainterUnits( positions.at( positions.size() - 1 ) + scaleContext.segmentWidth - QgsComposerUtils::textWidthMM( settings.font(), currentNumericLabel ) / 2, QgsUnitTypes::RenderMillimeters ) + xOffset,
context.convertToPainterUnits( QgsComposerUtils::fontAscentMM( settings.font() ) + settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters ) ),
currentNumericLabel + ' ' + settings.unitLabel(), scaledFont, settings.fontColor() );
}

painter->restore();
Expand Down
13 changes: 9 additions & 4 deletions src/core/scalebar/qgssingleboxscalebarrenderer.cpp
Expand Up @@ -28,15 +28,18 @@ void QgsSingleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsSca
}
QPainter *painter = context.painter();

double barTopPosition = QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace();
double barTopPosition = context.convertToPainterUnits( QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters );

painter->save();
if ( context.flags() & QgsRenderContext::Antialiasing )
painter->setRenderHint( QPainter::Antialiasing, true );
painter->setPen( settings.pen() );

QPen pen = settings.pen();
pen.setWidthF( context.convertToPainterUnits( pen.widthF(), QgsUnitTypes::RenderMillimeters ) );
painter->setPen( pen );

bool useColor = true; //alternate brush color/white
double xOffset = firstLabelXOffset( settings );
double xOffset = context.convertToPainterUnits( firstLabelXOffset( settings ), QgsUnitTypes::RenderMillimeters );

QList<double> positions = segmentPositions( scaleContext, settings );
QList<double> widths = segmentWidths( scaleContext, settings );
Expand All @@ -52,7 +55,9 @@ void QgsSingleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsSca
painter->setBrush( settings.brush2() );
}

QRectF segmentRect( positions.at( i ) + xOffset, barTopPosition, widths.at( i ), settings.height() );
QRectF segmentRect( context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset,
barTopPosition, context.convertToPainterUnits( widths.at( i ), QgsUnitTypes::RenderMillimeters ),
context.convertToPainterUnits( settings.height(), QgsUnitTypes::RenderMillimeters ) );
painter->drawRect( segmentRect );
useColor = !useColor;
}
Expand Down
24 changes: 14 additions & 10 deletions src/core/scalebar/qgsticksscalebarrenderer.cpp
Expand Up @@ -40,30 +40,33 @@ void QgsTicksScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBa

QPainter *painter = context.painter();

double barTopPosition = QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace();
double middlePosition = barTopPosition + settings.height() / 2.0;
double bottomPosition = barTopPosition + settings.height();
double barTopPosition = context.convertToPainterUnits( QgsComposerUtils::fontAscentMM( settings.font() ) + settings.labelBarSpace() + settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters );
double middlePosition = barTopPosition + context.convertToPainterUnits( settings.height() / 2.0, QgsUnitTypes::RenderMillimeters );
double bottomPosition = barTopPosition + context.convertToPainterUnits( settings.height(), QgsUnitTypes::RenderMillimeters );

double xOffset = firstLabelXOffset( settings );
double xOffset = context.convertToPainterUnits( firstLabelXOffset( settings ), QgsUnitTypes::RenderMillimeters );

painter->save();
if ( context.flags() & QgsRenderContext::Antialiasing )
painter->setRenderHint( QPainter::Antialiasing, true );

painter->setPen( settings.pen() );
QPen pen = settings.pen();
pen.setWidthF( context.convertToPainterUnits( pen.widthF(), QgsUnitTypes::RenderMillimeters ) );
painter->setPen( pen );

QList<double> positions = segmentPositions( scaleContext, settings );

for ( int i = 0; i < positions.size(); ++i )
{
painter->drawLine( QLineF( positions.at( i ) + xOffset, barTopPosition,
positions.at( i ) + xOffset, barTopPosition + settings.height() ) );
painter->drawLine( QLineF( context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset, barTopPosition,
context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset,
barTopPosition + context.convertToPainterUnits( settings.height(), QgsUnitTypes::RenderMillimeters ) ) );
}

//draw last tick and horizontal line
if ( !positions.isEmpty() )
{
double lastTickPositionX = positions.at( positions.size() - 1 ) + scaleContext.segmentWidth + xOffset;
double lastTickPositionX = context.convertToPainterUnits( positions.at( positions.size() - 1 ) + scaleContext.segmentWidth, QgsUnitTypes::RenderMillimeters ) + xOffset;
double verticalPos = 0.0;
switch ( mTickPosition )
{
Expand All @@ -78,9 +81,10 @@ void QgsTicksScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBa
break;
}
//horizontal line
painter->drawLine( QLineF( xOffset + positions.at( 0 ), verticalPos, lastTickPositionX, verticalPos ) );
painter->drawLine( QLineF( xOffset + context.convertToPainterUnits( positions.at( 0 ), QgsUnitTypes::RenderMillimeters ),
verticalPos, lastTickPositionX, verticalPos ) );
//last vertical line
painter->drawLine( QLineF( lastTickPositionX, barTopPosition, lastTickPositionX, barTopPosition + settings.height() ) );
painter->drawLine( QLineF( lastTickPositionX, barTopPosition, lastTickPositionX, barTopPosition + context.convertToPainterUnits( settings.height(), QgsUnitTypes::RenderMillimeters ) ) );
}

painter->restore();
Expand Down

0 comments on commit 7e7770b

Please sign in to comment.