void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor penColor = mColor; penColor.setAlphaF( context.alpha() ); mPen.setColor( penColor ); double scaledWidth = context.outputLineWidth( mWidth ); mPen.setWidthF( scaledWidth ); if ( mUseCustomDashPattern && scaledWidth != 0 ) { mPen.setStyle( Qt::CustomDashLine ); //scale pattern vector QVector<qreal> scaledVector; QVector<qreal>::const_iterator it = mCustomDashVector.constBegin(); for ( ; it != mCustomDashVector.constEnd(); ++it ) { //the dash is specified in terms of pen widths, therefore the division scaledVector << context.outputLineWidth(( *it ) / scaledWidth ); } mPen.setDashPattern( scaledVector ); } else { mPen.setStyle( mPenStyle ); } mPen.setJoinStyle( mPenJoinStyle ); mPen.setCapStyle( mPenCapStyle ); mSelPen = mPen; QColor selColor = context.selectionColor(); if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelPen.setColor( selColor ); }
void QgsSimpleFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor fillColor = mColor; fillColor.setAlphaF( context.alpha() * mColor.alphaF() ); mBrush = QBrush( fillColor, mBrushStyle ); // scale brush content for printout double rasterScaleFactor = context.renderContext().rasterScaleFactor(); if ( rasterScaleFactor != 1.0 ) { mBrush.setMatrix( QMatrix().scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ) ); } QColor selColor = context.selectionColor(); QColor selPenColor = selColor == mColor ? selColor : mBorderColor; if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelBrush = QBrush( selColor ); // N.B. unless a "selection line color" is implemented in addition to the "selection color" option // this would mean symbols with "no fill" look the same whether or not they are selected if ( selectFillStyle ) mSelBrush.setStyle( mBrushStyle ); QColor borderColor = mBorderColor; borderColor.setAlphaF( context.alpha() * mBorderColor.alphaF() ); mPen = QPen( borderColor ); mSelPen = QPen( selPenColor ); mPen.setStyle( mBorderStyle ); mPen.setWidthF( context.outputLineWidth( mBorderWidth ) ); }
void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context ) { if ( mSvgViewBox.isNull() ) { return; } delete mSvgPattern; mSvgPattern = 0; double size = context.outputPixelSize( mPatternWidth ); //don't render pattern if symbol size is below one or above 10,000 pixels if (( int )size < 1.0 || 10000.0 < size ) { mSvgPattern = new QImage(); mBrush.setTextureImage( *mSvgPattern ); } else { bool fitsInCache = true; const QImage& patternImage = QgsSvgCache::instance()->svgAsImage( mSvgFilePath, size, mSvgFillColor, mSvgOutlineColor, mSvgOutlineWidth, context.renderContext().scaleFactor(), context.renderContext().rasterScaleFactor(), fitsInCache ); if ( !fitsInCache ) { const QPicture& patternPict = QgsSvgCache::instance()->svgAsPicture( mSvgFilePath, size, mSvgFillColor, mSvgOutlineColor, mSvgOutlineWidth, context.renderContext().scaleFactor(), 1.0 ); double hwRatio = 1.0; if ( patternPict.width() > 0 ) { hwRatio = ( double )patternPict.height() / ( double )patternPict.width(); } mSvgPattern = new QImage(( int )size, ( int )( size * hwRatio ), QImage::Format_ARGB32_Premultiplied ); mSvgPattern->fill( 0 ); // transparent background QPainter p( mSvgPattern ); p.drawPicture( QPointF( size / 2, size * hwRatio / 2 ), patternPict ); } QTransform brushTransform; brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() ); if ( !doubleNear( context.alpha(), 1.0 ) ) { QImage transparentImage = fitsInCache ? patternImage.copy() : mSvgPattern->copy(); QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() ); mBrush.setTextureImage( transparentImage ); } else { mBrush.setTextureImage( fitsInCache ? patternImage : *mSvgPattern ); } mBrush.setTransform( brushTransform ); } if ( mOutline ) { mOutline->startRender( context.renderContext() ); } }
void QgsLineDecorationSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor penColor = mColor; penColor.setAlphaF( context.alpha() ); mPen.setWidth( context.outputLineWidth( mWidth ) ); mPen.setColor( penColor ); QColor selColor = context.selectionColor(); if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelPen.setWidth( context.outputLineWidth( mWidth ) ); mSelPen.setColor( selColor ); }
void QgsLineDecorationSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor penColor = mColor; penColor.setAlphaF( mColor.alphaF() * context.alpha() ); double width = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit ); mPen.setWidth( context.outputLineWidth( width ) ); mPen.setColor( penColor ); QColor selColor = context.renderContext().selectionColor(); if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelPen.setWidth( context.outputLineWidth( width ) ); mSelPen.setColor( selColor ); }
void QgsCentroidFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { mMarker->setAlpha( context.alpha() ); mMarker->setOutputUnit( context.outputUnit() ); mMarker->startRender( context.renderContext() ); }
void QgsFontMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) { QPainter *p = context.renderContext().painter(); if ( !p ) return; QColor penColor = context.selected() ? context.renderContext().selectionColor() : mColor; penColor.setAlphaF( mColor.alphaF() * context.alpha() ); p->setPen( penColor ); p->setFont( mFont ); p->save(); //offset double offsetX = 0; double offsetY = 0; markerOffset( context, offsetX, offsetY ); QPointF outputOffset( offsetX, offsetY ); if ( mAngle ) outputOffset = _rotatedOffset( outputOffset, mAngle ); p->translate( point + outputOffset ); if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) { double s = mSize / mOrigSize; p->scale( s, s ); } if ( mAngle != 0 ) p->rotate( mAngle ); p->drawText( -mChrOffset, mChr ); p->restore(); }
void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor penColor = mColor; penColor.setAlphaF( mColor.alphaF() * context.alpha() ); mPen.setColor( penColor ); double scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale ); mPen.setWidthF( scaledWidth ); if ( mUseCustomDashPattern && scaledWidth != 0 ) { mPen.setStyle( Qt::CustomDashLine ); //scale pattern vector double dashWidthDiv = scaledWidth; //fix dash pattern width in Qt 4.8 QStringList versionSplit = QString( qVersion() ).split( "." ); if ( versionSplit.size() > 1 && versionSplit.at( 1 ).toInt() >= 8 && ( scaledWidth * context.renderContext().rasterScaleFactor() ) < 1.0 ) { dashWidthDiv = 1.0; } QVector<qreal> scaledVector; QVector<qreal>::const_iterator it = mCustomDashVector.constBegin(); for ( ; it != mCustomDashVector.constEnd(); ++it ) { //the dash is specified in terms of pen widths, therefore the division scaledVector << ( *it ) * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv; } mPen.setDashPattern( scaledVector ); } else { mPen.setStyle( mPenStyle ); } mPen.setJoinStyle( mPenJoinStyle ); mPen.setCapStyle( mPenCapStyle ); mSelPen = mPen; QColor selColor = context.renderContext().selectionColor(); if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelPen.setColor( selColor ); //prepare expressions for data defined properties prepareExpressions( context.fields(), context.renderContext().rendererScale() ); }
void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor penColor = mColor; penColor.setAlphaF( mColor.alphaF() * context.alpha() ); mPen.setColor( penColor ); double scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit ); mPen.setWidthF( scaledWidth ); if ( mUseCustomDashPattern && scaledWidth != 0 ) { mPen.setStyle( Qt::CustomDashLine ); //scale pattern vector QVector<qreal> scaledVector; QVector<qreal>::const_iterator it = mCustomDashVector.constBegin(); for ( ; it != mCustomDashVector.constEnd(); ++it ) { //the dash is specified in terms of pen widths, therefore the division scaledVector << ( *it ) * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit ) / scaledWidth; } mPen.setDashPattern( scaledVector ); } else { mPen.setStyle( mPenStyle ); } mPen.setJoinStyle( mPenJoinStyle ); mPen.setCapStyle( mPenCapStyle ); mSelPen = mPen; QColor selColor = context.renderContext().selectionColor(); if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() ); mSelPen.setColor( selColor ); //prepare expressions for data defined properties prepareExpressions( context.layer() ); }
void QgsMarkerLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { mMarker->setAlpha( context.alpha() ); mMarker->setOutputUnit( context.outputUnit() ); // if being rotated, it gets initialized with every line segment int hints = 0; if ( mRotateMarker ) hints |= QgsSymbolV2::DataDefinedRotation; if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) hints |= QgsSymbolV2::DataDefinedSizeScale; mMarker->setRenderHints( hints ); mMarker->startRender( context.renderContext() ); }
void QgsMarkerLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { mMarker->setAlpha( context.alpha() ); // if being rotated, it gets initialized with every line segment int hints = 0; if ( mRotateMarker ) hints |= QgsSymbolV2::DataDefinedRotation; if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) hints |= QgsSymbolV2::DataDefinedSizeScale; mMarker->setRenderHints( hints ); mMarker->startRender( context.renderContext(), context.fields() ); //prepare expressions for data defined properties prepareExpressions( context.fields(), context.renderContext().rendererScale() ); }
void QgsLinePatternFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context ) { double outlinePixelWidth = context.outputPixelSize( mLineWidth ); double outputPixelDist = context.outputPixelSize( mDistance ); double outputPixelOffset = context.outputPixelSize( mOffset ); //create image int height, width; if ( doubleNear( mLineAngle, 0 ) || doubleNear( mLineAngle, 360 ) || doubleNear( mLineAngle, 90 ) || doubleNear( mLineAngle, 180 ) || doubleNear( mLineAngle, 270 ) ) { height = outputPixelDist; width = height; //width can be set to arbitrary value } else { height = qAbs( outputPixelDist / cos( mLineAngle * M_PI / 180 ) ); //keep perpendicular distance between lines constant width = qAbs( height / tan( mLineAngle * M_PI / 180 ) ); } //depending on the angle, we might need to render into a larger image and use a subset of it int dx = 0; int dy = 0; QImage patternImage( width, height, QImage::Format_ARGB32 ); patternImage.fill( 0 ); QPainter p( &patternImage ); p.setRenderHint( QPainter::Antialiasing, true ); QPen pen( mColor ); pen.setWidthF( outlinePixelWidth ); pen.setCapStyle( Qt::FlatCap ); p.setPen( pen ); QPoint p1, p2, p3, p4, p5, p6; if ( doubleNear( mLineAngle, 0.0 ) || doubleNear( mLineAngle, 360.0 ) || doubleNear( mLineAngle, 180.0 ) ) { p1 = QPoint( 0, height ); p2 = QPoint( width, height ); p3 = QPoint( 0, 0 ); p4 = QPoint( width, 0 ); p5 = QPoint( 0, 2 * height ); p6 = QPoint( width, 2 * height ); } else if ( doubleNear( mLineAngle, 90.0 ) || doubleNear( mLineAngle, 270.0 ) ) { p1 = QPoint( 0, height ); p2 = QPoint( 0, 0 ); p3 = QPoint( width, height ); p4 = QPoint( width, 0 ); p5 = QPoint( -width, height ); p6 = QPoint( -width, 0 ); } else if (( mLineAngle > 0 && mLineAngle < 90 ) || ( mLineAngle > 180 && mLineAngle < 270 ) ) { dx = outputPixelDist * cos(( 90 - mLineAngle ) * M_PI / 180.0 ); dy = outputPixelDist * sin(( 90 - mLineAngle ) * M_PI / 180.0 ); p1 = QPoint( 0, height ); p2 = QPoint( width, 0 ); p3 = QPoint( -dx, height - dy ); p4 = QPoint( width - dx, -dy ); //p4 = QPoint( p3.x() + width, p3.y() - height ); p5 = QPoint( dx, height + dy ); p6 = QPoint( width + dx, dy ); //p6 = QPoint( p5.x() + width, p5.y() - height ); } else if (( mLineAngle < 180 ) || ( mLineAngle > 270 && mLineAngle < 360 ) ) { dy = outputPixelDist * cos(( 180 - mLineAngle ) * M_PI / 180 ); dx = outputPixelDist * sin(( 180 - mLineAngle ) * M_PI / 180 ); p1 = QPoint( width, height ); p2 = QPoint( 0, 0 ); p5 = QPoint( width + dx, height - dy ); p6 = QPoint( p5.x() - width, p5.y() - height ); //p6 = QPoint( dx, -dy ); p3 = QPoint( width - dx, height + dy ); p4 = QPoint( p3.x() - width, p3.y() - height ); //p4 = QPoint( -dx, dy ); } if ( !doubleNear( mOffset, 0.0 ) ) //shift everything { QPointF tempPt; tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p1, p3, outputPixelDist + outputPixelOffset ); p3 = QPoint( tempPt.x(), tempPt.y() ); tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p2, p4, outputPixelDist + outputPixelOffset ); p4 = QPoint( tempPt.x(), tempPt.y() ); tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p1, p5, outputPixelDist - outputPixelOffset ); p5 = QPoint( tempPt.x(), tempPt.y() ); tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p2, p6, outputPixelDist - outputPixelOffset ); p6 = QPoint( tempPt.x(), tempPt.y() ); //update p1, p2 last tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p1, p3, outputPixelOffset ).toPoint(); p1 = QPoint( tempPt.x(), tempPt.y() ); tempPt = QgsSymbolLayerV2Utils::pointOnLineWithDistance( p2, p4, outputPixelOffset ).toPoint(); p2 = QPoint( tempPt.x(), tempPt.y() );; } p.drawLine( p1, p2 ); p.drawLine( p3, p4 ); p.drawLine( p5, p6 ); p.end(); //set image to mBrush if ( !doubleNear( context.alpha(), 1.0 ) ) { QImage transparentImage = patternImage.copy(); QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() ); mBrush.setTextureImage( transparentImage ); } else { mBrush.setTextureImage( patternImage ); } QTransform brushTransform; brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() ); mBrush.setTransform( brushTransform ); if ( mOutline ) { mOutline->startRender( context.renderContext() ); } }
void QgsPointPatternFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context ) { //render 3 rows and columns in one go to easily incorporate displacement double width = context.outputPixelSize( mDistanceX ) * 2.0; double height = context.outputPixelSize( mDistanceY ) * 2.0; QImage patternImage( width, height, QImage::Format_ARGB32 ); patternImage.fill( 0 ); if ( mMarkerSymbol ) { QPainter p( &patternImage ); //marker rendering needs context for drawing on patternImage QgsRenderContext pointRenderContext; pointRenderContext.setPainter( &p ); pointRenderContext.setRasterScaleFactor( 1.0 ); pointRenderContext.setScaleFactor( context.renderContext().scaleFactor() * context.renderContext().rasterScaleFactor() ); QgsMapToPixel mtp( context.renderContext().mapToPixel().mapUnitsPerPixel() / context.renderContext().rasterScaleFactor() ); pointRenderContext.setMapToPixel( mtp ); pointRenderContext.setForceVectorOutput( false ); mMarkerSymbol->setOutputUnit( context.outputUnit() ); mMarkerSymbol->startRender( pointRenderContext ); //render corner points mMarkerSymbol->renderPoint( QPointF( 0, 0 ), context.feature(), pointRenderContext ); mMarkerSymbol->renderPoint( QPointF( width, 0 ), context.feature(), pointRenderContext ); mMarkerSymbol->renderPoint( QPointF( 0, height ), context.feature(), pointRenderContext ); mMarkerSymbol->renderPoint( QPointF( width, height ), context.feature(), pointRenderContext ); //render displaced points double displacementPixelX = context.outputPixelSize( mDisplacementX ); double displacementPixelY = context.outputPixelSize( mDisplacementY ); mMarkerSymbol->renderPoint( QPointF( width / 2.0, -displacementPixelY ), context.feature(), pointRenderContext ); mMarkerSymbol->renderPoint( QPointF( displacementPixelX, height / 2.0 ), context.feature(), pointRenderContext ); mMarkerSymbol->renderPoint( QPointF( width / 2.0 + displacementPixelX, height / 2.0 - displacementPixelY ), context.feature(), pointRenderContext ); mMarkerSymbol->renderPoint( QPointF( width + displacementPixelX, height / 2.0 ), context.feature(), pointRenderContext ); mMarkerSymbol->renderPoint( QPointF( width / 2.0, height - displacementPixelY ), context.feature(), pointRenderContext ); mMarkerSymbol->stopRender( pointRenderContext ); } if ( !doubleNear( context.alpha(), 1.0 ) ) { QImage transparentImage = patternImage.copy(); QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() ); mBrush.setTextureImage( transparentImage ); } else { mBrush.setTextureImage( patternImage ); } QTransform brushTransform; brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() ); mBrush.setTransform( brushTransform ); if ( mOutline ) { mOutline->startRender( context.renderContext() ); } }
void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) { QPainter *p = context.renderContext().painter(); if ( !p ) return; double size = mSize; QgsExpression* sizeExpression = expression( "size" ); bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || sizeExpression; if ( sizeExpression ) { size = sizeExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble(); } size *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSizeUnit ); if ( hasDataDefinedSize ) { switch ( mScaleMethod ) { case QgsSymbolV2::ScaleArea: size = sqrt( size ); break; case QgsSymbolV2::ScaleDiameter: break; } } //don't render symbols with size below one or above 10,000 pixels if (( int )size < 1 || 10000.0 < size ) { return; } p->save(); //offset double offsetX = 0; double offsetY = 0; markerOffset( context, offsetX, offsetY ); QPointF outputOffset( offsetX, offsetY ); double angle = mAngle; QgsExpression* angleExpression = expression( "angle" ); if ( angleExpression ) { angle = angleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble(); } if ( angle ) outputOffset = _rotatedOffset( outputOffset, angle ); p->translate( point + outputOffset ); bool rotated = !qgsDoubleNear( angle, 0 ); bool drawOnScreen = qgsDoubleNear( context.renderContext().rasterScaleFactor(), 1.0, 0.1 ); if ( rotated ) p->rotate( angle ); QString path = mPath; QgsExpression* nameExpression = expression( "name" ); if ( nameExpression ) { path = nameExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); } double outlineWidth = mOutlineWidth; QgsExpression* outlineWidthExpression = expression( "outline_width" ); if ( outlineWidthExpression ) { outlineWidth = outlineWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble(); } QColor fillColor = mFillColor; QgsExpression* fillExpression = expression( "fill" ); if ( fillExpression ) { fillColor = QgsSymbolLayerV2Utils::decodeColor( fillExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ); } QColor outlineColor = mOutlineColor; QgsExpression* outlineExpression = expression( "outline" ); if ( outlineExpression ) { outlineColor = QgsSymbolLayerV2Utils::decodeColor( outlineExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ); } bool fitsInCache = true; bool usePict = true; double hwRatio = 1.0; if ( drawOnScreen && !rotated ) { usePict = false; const QImage& img = QgsSvgCache::instance()->svgAsImage( path, size, fillColor, outlineColor, outlineWidth, context.renderContext().scaleFactor(), context.renderContext().rasterScaleFactor(), fitsInCache ); if ( fitsInCache && img.width() > 1 ) { //consider transparency if ( !qgsDoubleNear( context.alpha(), 1.0 ) ) { QImage transparentImage = img.copy(); QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() ); p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage ); hwRatio = ( double )transparentImage.height() / ( double )transparentImage.width(); } else { p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img ); hwRatio = ( double )img.height() / ( double )img.width(); } } } if ( usePict || !fitsInCache ) { p->setOpacity( context.alpha() ); const QPicture& pct = QgsSvgCache::instance()->svgAsPicture( path, size, fillColor, outlineColor, outlineWidth, context.renderContext().scaleFactor(), context.renderContext().rasterScaleFactor(), context.renderContext().forceVectorOutput() ); if ( pct.width() > 1 ) { p->drawPicture( 0, 0, pct ); hwRatio = ( double )pct.height() / ( double )pct.width(); } } if ( context.selected() ) { QPen pen( context.renderContext().selectionColor() ); double penWidth = QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), QgsSymbolV2::MM ); if ( penWidth > size / 20 ) { // keep the pen width from covering symbol penWidth = size / 20; } double penOffset = penWidth / 2; pen.setWidth( penWidth ); p->setPen( pen ); p->setBrush( Qt::NoBrush ); double wSize = size + penOffset; double hSize = size * hwRatio + penOffset; p->drawRect( QRectF( -wSize / 2.0, -hSize / 2.0, wSize, hSize ) ); } p->restore(); }
void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context ) { QColor brushColor = mColor; QColor penColor = mBorderColor; brushColor.setAlphaF( mColor.alphaF() * context.alpha() ); penColor.setAlphaF( mBorderColor.alphaF() * context.alpha() ); mBrush = QBrush( brushColor ); mPen = QPen( penColor ); mPen.setWidthF( mOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit ) ); QColor selBrushColor = context.renderContext().selectionColor(); QColor selPenColor = selBrushColor == mColor ? selBrushColor : mBorderColor; if ( context.alpha() < 1 ) { selBrushColor.setAlphaF( context.alpha() ); selPenColor.setAlphaF( context.alpha() ); } mSelBrush = QBrush( selBrushColor ); mSelPen = QPen( selPenColor ); mSelPen.setWidthF( mOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit ) ); bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || dataDefinedProperty( "angle" ); bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || dataDefinedProperty( "size" ); // use caching only when: // - size, rotation, shape, color, border color is not data-defined // - drawing to screen (not printer) mUsingCache = !hasDataDefinedRotation && !hasDataDefinedSize && !context.renderContext().forceVectorOutput() && !dataDefinedProperty( "name" ) && !dataDefinedProperty( "color" ) && !dataDefinedProperty( "color_border" ) && !dataDefinedProperty( "outline_width" ) && !dataDefinedProperty( "size" ); // use either QPolygonF or QPainterPath for drawing // TODO: find out whether drawing directly doesn't bring overhead - if not, use it for all shapes if ( !prepareShape() ) // drawing as a polygon { if ( preparePath() ) // drawing as a painter path { // some markers can't be drawn as a polygon (circle, cross) // For these set the selected border color to the selected color if ( mName != "circle" ) mSelPen.setColor( selBrushColor ); } else { QgsDebugMsg( "unknown symbol" ); return; } } QMatrix transform; // scale the shape (if the size is not going to be modified) if ( !hasDataDefinedSize ) { double scaledSize = mSize * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSizeUnit ); if ( mUsingCache ) scaledSize *= context.renderContext().rasterScaleFactor(); double half = scaledSize / 2.0; transform.scale( half, half ); } // rotate if the rotation is not going to be changed during the rendering if ( !hasDataDefinedRotation && mAngle != 0 ) { transform.rotate( mAngle ); } if ( !mPolygon.isEmpty() ) mPolygon = transform.map( mPolygon ); else mPath = transform.map( mPath ); if ( mUsingCache ) { if ( !prepareCache( context ) ) { mUsingCache = false; } } else { mCache = QImage(); mSelCache = QImage(); } prepareExpressions( context.layer(), context.renderContext().rendererScale() ); mAngleExpression = expression( "angle" ); mNameExpression = expression( "name" ); QgsMarkerSymbolLayerV2::startRender( context ); }
void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) { QPainter* p = context.renderContext().painter(); if ( !p ) { return; } double size = context.outputLineWidth( mSize ); //don't render symbols with size below one or above 10,000 pixels if (( int )size < 1 || 10000.0 < size ) { return; } p->save(); QPointF outputOffset = QPointF( context.outputLineWidth( mOffset.x() ), context.outputLineWidth( mOffset.y() ) ); if ( mAngle ) outputOffset = _rotatedOffset( outputOffset, mAngle ); p->translate( point + outputOffset ); bool rotated = !doubleNear( mAngle, 0 ); bool drawOnScreen = doubleNear( context.renderContext().rasterScaleFactor(), 1.0, 0.1 ); if ( rotated ) p->rotate( mAngle ); bool fitsInCache = true; bool usePict = true; double hwRatio = 1.0; if ( drawOnScreen && !rotated ) { usePict = false; const QImage& img = QgsSvgCache::instance()->svgAsImage( mPath, size, mFillColor, mOutlineColor, mOutlineWidth, context.renderContext().scaleFactor(), context.renderContext().rasterScaleFactor(), fitsInCache ); if ( fitsInCache && img.width() > 1 ) { //consider transparency if ( !doubleNear( context.alpha(), 1.0 ) ) { QImage transparentImage = img.copy(); QgsSymbolLayerV2Utils::multiplyImageOpacity( &transparentImage, context.alpha() ); p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage ); hwRatio = ( double )transparentImage.height() / ( double )transparentImage.width(); } else { p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img ); hwRatio = ( double )img.height() / ( double )img.width(); } } } if ( usePict || !fitsInCache ) { p->setOpacity( context.alpha() ); const QPicture& pct = QgsSvgCache::instance()->svgAsPicture( mPath, size, mFillColor, mOutlineColor, mOutlineWidth, context.renderContext().scaleFactor(), context.renderContext().rasterScaleFactor() ); if ( pct.width() > 1 ) { p->drawPicture( 0, 0, pct ); hwRatio = ( double )pct.height() / ( double )pct.width(); } } if ( context.selected() ) { QPen pen( context.selectionColor() ); double penWidth = context.outputLineWidth( 1.0 ); if ( penWidth > size / 20 ) { // keep the pen width from covering symbol penWidth = size / 20; } double penOffset = penWidth / 2; pen.setWidth( penWidth ); p->setPen( pen ); p->setBrush( Qt::NoBrush ); double wSize = size + penOffset; double hSize = size * hwRatio + penOffset; p->drawRect( QRectF( -wSize / 2.0, -hSize / 2.0, wSize, hSize ) ); } p->restore(); }