Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgssingleboxscalebarrenderer.cpp 3 : : -------------------------------- 4 : : begin : June 2008 5 : : copyright : (C) 2008 by Marco Hugentobler 6 : : email : marco.hugentobler@karto.baug.ethz.ch 7 : : ***************************************************************************/ 8 : : /*************************************************************************** 9 : : * * 10 : : * This program is free software; you can redistribute it and/or modify * 11 : : * it under the terms of the GNU General Public License as published by * 12 : : * the Free Software Foundation; either version 2 of the License, or * 13 : : * (at your option) any later version. * 14 : : * * 15 : : ***************************************************************************/ 16 : : 17 : : #include "qgssingleboxscalebarrenderer.h" 18 : : #include "qgsscalebarsettings.h" 19 : : #include "qgslayoututils.h" 20 : : #include "qgssymbol.h" 21 : : #include "qgstextrenderer.h" 22 : : #include <QList> 23 : : #include <QPainter> 24 : : 25 : 5 : QString QgsSingleBoxScaleBarRenderer::id() const 26 : : { 27 : 10 : return QStringLiteral( "Single Box" ); 28 : : } 29 : : 30 : 0 : QString QgsSingleBoxScaleBarRenderer::visibleName() const 31 : : { 32 : 0 : return QObject::tr( "Single Box" ); 33 : : } 34 : : 35 : 0 : int QgsSingleBoxScaleBarRenderer::sortKey() const 36 : : { 37 : 0 : return 1; 38 : : } 39 : : 40 : 0 : QgsScaleBarRenderer::Flags QgsSingleBoxScaleBarRenderer::flags() const 41 : : { 42 : 0 : return Flag::FlagUsesLineSymbol | 43 : 0 : Flag::FlagUsesFillSymbol | 44 : 0 : Flag::FlagUsesAlternateFillSymbol | 45 : 0 : Flag::FlagRespectsUnits | 46 : 0 : Flag::FlagRespectsMapUnitsPerScaleBarUnit | 47 : 0 : Flag::FlagUsesUnitLabel | 48 : 0 : Flag::FlagUsesSegments | 49 : 0 : Flag::FlagUsesLabelBarSpace | 50 : 0 : Flag::FlagUsesLabelVerticalPlacement | 51 : : Flag::FlagUsesLabelHorizontalPlacement; 52 : : } 53 : : 54 : 0 : QgsSingleBoxScaleBarRenderer *QgsSingleBoxScaleBarRenderer::clone() const 55 : : { 56 : 0 : return new QgsSingleBoxScaleBarRenderer( *this ); 57 : : } 58 : : 59 : 0 : void QgsSingleBoxScaleBarRenderer::draw( QgsRenderContext &context, const QgsScaleBarSettings &settings, const ScaleBarContext &scaleContext ) const 60 : : { 61 : 0 : if ( !context.painter() ) 62 : : { 63 : 0 : return; 64 : : } 65 : 0 : QPainter *painter = context.painter(); 66 : : 67 : 0 : const double scaledLabelBarSpace = context.convertToPainterUnits( settings.labelBarSpace(), QgsUnitTypes::RenderMillimeters ); 68 : 0 : const double scaledBoxContentSpace = context.convertToPainterUnits( settings.boxContentSpace(), QgsUnitTypes::RenderMillimeters ); 69 : 0 : const QFontMetricsF fontMetrics = QgsTextRenderer::fontMetrics( context, settings.textFormat() ); 70 : 0 : const double barTopPosition = scaledBoxContentSpace + ( settings.labelVerticalPlacement() == QgsScaleBarSettings::LabelAboveSegment ? fontMetrics.ascent() + scaledLabelBarSpace : 0 ); 71 : 0 : const double barHeight = context.convertToPainterUnits( settings.height(), QgsUnitTypes::RenderMillimeters ); 72 : : 73 : 0 : painter->save(); 74 : 0 : context.setPainterFlagsUsingContext( painter ); 75 : : 76 : 0 : std::unique_ptr< QgsLineSymbol > lineSymbol( settings.lineSymbol()->clone() ); 77 : 0 : lineSymbol->startRender( context ); 78 : : 79 : 0 : std::unique_ptr< QgsFillSymbol > fillSymbol1( settings.fillSymbol()->clone() ); 80 : 0 : fillSymbol1->startRender( context ); 81 : : 82 : 0 : std::unique_ptr< QgsFillSymbol > fillSymbol2( settings.alternateFillSymbol()->clone() ); 83 : 0 : fillSymbol2->startRender( context ); 84 : : 85 : 0 : painter->setPen( Qt::NoPen ); 86 : 0 : painter->setBrush( Qt::NoBrush ); 87 : : 88 : 0 : bool useColor = true; //alternate brush color/white 89 : 0 : const double xOffset = firstLabelXOffset( settings, context, scaleContext ); 90 : : 91 : 0 : const QList<double> positions = segmentPositions( context, scaleContext, settings ); 92 : 0 : const QList<double> widths = segmentWidths( scaleContext, settings ); 93 : : 94 : : // draw the fill 95 : 0 : double minX = 0; 96 : 0 : double maxX = 0; 97 : 0 : QgsFillSymbol *currentSymbol = nullptr; 98 : 0 : for ( int i = 0; i < positions.size(); ++i ) 99 : : { 100 : 0 : if ( useColor ) //alternating colors 101 : : { 102 : 0 : currentSymbol = fillSymbol1.get(); 103 : 0 : } 104 : : else //secondary fill 105 : : { 106 : 0 : currentSymbol = fillSymbol2.get(); 107 : : } 108 : : 109 : 0 : const double thisX = context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset; 110 : 0 : const double thisWidth = context.convertToPainterUnits( widths.at( i ), QgsUnitTypes::RenderMillimeters ); 111 : : 112 : 0 : if ( i == 0 ) 113 : 0 : minX = thisX; 114 : 0 : if ( i == positions.size() - 1 ) 115 : 0 : maxX = thisX + thisWidth; 116 : : 117 : 0 : QRectF segmentRect( thisX, barTopPosition, thisWidth, barHeight ); 118 : 0 : currentSymbol->renderPolygon( QPolygonF() 119 : 0 : << segmentRect.topLeft() 120 : 0 : << segmentRect.topRight() 121 : 0 : << segmentRect.bottomRight() 122 : 0 : << segmentRect.bottomLeft() 123 : 0 : << segmentRect.topLeft(), nullptr, nullptr, context ); 124 : 0 : useColor = !useColor; 125 : 0 : } 126 : : 127 : : // and then the lines 128 : : // note that we do this layer-by-layer, to avoid ugliness where the lines touch the outer rect 129 : 0 : for ( int layer = 0; layer < lineSymbol->symbolLayerCount(); ++layer ) 130 : : { 131 : 0 : for ( int i = 1; i < positions.size(); ++i ) 132 : : { 133 : 0 : const double lineX = context.convertToPainterUnits( positions.at( i ), QgsUnitTypes::RenderMillimeters ) + xOffset; 134 : 0 : lineSymbol->renderPolyline( QPolygonF() 135 : 0 : << QPointF( lineX, barTopPosition ) 136 : 0 : << QPointF( lineX, barTopPosition + barHeight ), 137 : 0 : nullptr, context, layer ); 138 : 0 : } 139 : : 140 : : // outside line 141 : 0 : lineSymbol->renderPolyline( QPolygonF() 142 : 0 : << QPointF( minX, barTopPosition ) 143 : 0 : << QPointF( maxX, barTopPosition ) 144 : 0 : << QPointF( maxX, barTopPosition + barHeight ) 145 : 0 : << QPointF( minX, barTopPosition + barHeight ) 146 : 0 : << QPointF( minX, barTopPosition ), 147 : 0 : nullptr, context, layer ); 148 : 0 : } 149 : : 150 : 0 : lineSymbol->stopRender( context ); 151 : 0 : fillSymbol1->stopRender( context ); 152 : 0 : fillSymbol2->stopRender( context ); 153 : 0 : painter->restore(); 154 : : 155 : : //draw labels using the default method 156 : 0 : drawDefaultLabels( context, settings, scaleContext ); 157 : 0 : } 158 : : 159 : : 160 : :