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 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 QgsFontMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context ) { QPainter* p = context.renderContext().painter(); QColor penColor = context.selected() ? context.selectionColor() : mColor; penColor.setAlphaF( context.alpha() ); p->setPen( penColor ); p->setFont( mFont ); p->save(); QPointF outputOffset = QPointF( context.outputLineWidth( mOffset.x() ), context.outputLineWidth( mOffset.y() ) ); 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 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 QgsSimpleMarkerSymbolLayerV2::prepareCache( QgsSymbolV2RenderContext& context ) { double scaledSize = context.outputPixelSize( mSize ); // calculate necessary image size for the cache double pw = (( mPen.widthF() == 0 ? 1 : mPen.widthF() ) + 1 ) / 2 * 2; // make even (round up); handle cosmetic pen int imageSize = (( int ) scaledSize + pw ) / 2 * 2 + 1; // make image width, height odd; account for pen width double center = (( double ) imageSize / 2 ) + 0.5; // add 1/2 pixel for proper rounding when the figure's coordinates are added mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied ); mCache.fill( 0 ); QPainter p; p.begin( &mCache ); p.setRenderHint( QPainter::Antialiasing ); p.setBrush( mBrush ); p.setPen( mPen ); p.translate( QPointF( center, center ) ); drawMarker( &p, context ); p.end(); // Construct the selected version of the Cache QColor selColor = context.selectionColor(); mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied ); mSelCache.fill( 0 ); p.begin( &mSelCache ); p.setRenderHint( QPainter::Antialiasing ); p.setBrush( mSelBrush ); p.setPen( mSelPen ); p.translate( QPointF( center, center ) ); drawMarker( &p, context ); p.end(); // Check that the selected version is different. If not, then re-render, // filling the background with the selection color and using the normal // colors for the symbol .. could be ugly! if ( mSelCache == mCache ) { p.begin( &mSelCache ); p.setRenderHint( QPainter::Antialiasing ); p.fillRect( 0, 0, imageSize, imageSize, selColor ); p.setBrush( mBrush ); p.setPen( mPen ); p.translate( QPointF( center, center ) ); drawMarker( &p, context ); p.end(); } }
void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context ) { QPainter* p = context.renderContext().painter(); if ( !p ) { return; } p->setPen( QPen( Qt::NoPen ) ); if ( context.selected() ) { QColor selColor = context.selectionColor(); // Alister - this doesn't seem to work here //if ( ! selectionIsOpaque ) // selColor.setAlphaF( context.alpha() ); p->setBrush( QBrush( selColor ) ); _renderPolygon( p, points, rings ); } if ( doubleNear( mAngle, 0.0 ) ) { p->setBrush( mBrush ); } else { QTransform t = mBrush.transform(); t.rotate( mAngle ); QBrush rotatedBrush = mBrush; rotatedBrush.setTransform( t ); p->setBrush( rotatedBrush ); } _renderPolygon( p, points, rings ); if ( mOutline ) { mOutline->renderPolyline( points, context.feature(), context.renderContext(), -1, selectFillBorder && context.selected() ); if ( rings ) { QList<QPolygonF>::const_iterator ringIt = rings->constBegin(); for ( ; ringIt != rings->constEnd(); ++ringIt ) { mOutline->renderPolyline( *ringIt, context.feature(), context.renderContext(), -1, selectFillBorder && context.selected() ); } } } }
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( context.outputLineWidth( mPen.widthF() ) ); QColor selBrushColor = context.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( context.outputLineWidth( mPen.widthF() ) ); bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation; bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale; // use caching only when: // - the size and rotation is not data-defined // - drawing to screen (not printer) mUsingCache = !hasDataDefinedRotation && !hasDataDefinedSize && !context.renderContext().forceVectorOutput(); // 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 = context.outputLineWidth( mSize ); 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 ) { prepareCache( context ); } else { mCache = QImage(); mSelCache = QImage(); } }
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(); }