QgsSymbol estimateMaxBleed methods now use a QgsRenderContext

argument to correctly calculate bleed for mapunits/pixels/etc
This commit is contained in:
Nyall Dawson 2017-01-30 12:36:04 +10:00
parent fac7887a9c
commit dd51843e54
17 changed files with 63 additions and 65 deletions

View File

@ -102,7 +102,7 @@ class QgsSimpleFillSymbolLayer : QgsFillSymbolLayer
void setMapUnitScale( const QgsMapUnitScale &scale );
QgsMapUnitScale mapUnitScale() const;
double estimateMaxBleed() const;
double estimateMaxBleed( const QgsRenderContext& context ) const;
double dxfWidth( const QgsDxfExport& e, QgsSymbolRenderContext& context ) const;
QColor dxfColor( QgsSymbolRenderContext& context ) const;
@ -172,7 +172,7 @@ class QgsGradientFillSymbolLayer : QgsFillSymbolLayer
virtual QgsGradientFillSymbolLayer* clone() const /Factory/;
double estimateMaxBleed() const;
double estimateMaxBleed( const QgsRenderContext& context ) const;
/** Type of gradient, e.g., linear or radial*/
GradientType gradientType() const;
@ -270,7 +270,7 @@ class QgsShapeburstFillSymbolLayer : QgsFillSymbolLayer
virtual QgsShapeburstFillSymbolLayer* clone() const /Factory/;
double estimateMaxBleed() const;
double estimateMaxBleed( const QgsRenderContext& context ) const;
/** Sets the blur radius, which controls the amount of blurring applied to the fill.
* @param blurRadius Radius for fill blur. Values between 0 - 17 are valid, where higher values results in a stronger blur. Set to 0 to disable blur.
@ -476,7 +476,7 @@ class QgsImageFillSymbolLayer: QgsFillSymbolLayer
void setMapUnitScale( const QgsMapUnitScale& scale );
QgsMapUnitScale mapUnitScale() const;
virtual double estimateMaxBleed() const;
virtual double estimateMaxBleed( const QgsRenderContext& context ) const;
virtual double dxfWidth( const QgsDxfExport& e, QgsSymbolRenderContext& context ) const;
virtual QColor dxfColor( QgsSymbolRenderContext& context ) const;
@ -519,7 +519,7 @@ class QgsRasterFillSymbolLayer: QgsImageFillSymbolLayer
void stopRender( QgsSymbolRenderContext& context );
QgsStringMap properties() const;
virtual QgsRasterFillSymbolLayer* clone() const;
virtual double estimateMaxBleed() const;
virtual double estimateMaxBleed( const QgsRenderContext& context ) const;
//override QgsImageFillSymbolLayer's support for sub symbols
virtual QgsSymbol* subSymbol();
@ -762,7 +762,7 @@ class QgsLinePatternFillSymbolLayer: QgsImageFillSymbolLayer
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const;
double estimateMaxBleed() const;
double estimateMaxBleed( const QgsRenderContext& context ) const;
QString ogrFeatureStyleWidth( double widthScaleFactor ) const;
@ -870,7 +870,7 @@ class QgsPointPatternFillSymbolLayer : QgsImageFillSymbolLayer
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const;
double estimateMaxBleed() const;
double estimateMaxBleed( const QgsRenderContext& context ) const;
//getters and setters
double distanceX() const;

View File

@ -41,7 +41,7 @@ class QgsSimpleLineSymbolLayer : QgsLineSymbolLayer
void setMapUnitScale( const QgsMapUnitScale &scale );
QgsMapUnitScale mapUnitScale() const;
double estimateMaxBleed() const;
double estimateMaxBleed( const QgsRenderContext& context ) const;
// new stuff
@ -161,7 +161,7 @@ class QgsMarkerLineSymbolLayer : QgsLineSymbolLayer
virtual void setWidth( double width );
virtual double width() const;
double estimateMaxBleed() const;
double estimateMaxBleed( const QgsRenderContext& context ) const;
// new stuff

View File

@ -355,7 +355,7 @@ class QgsFilledMarkerSymbolLayer : QgsSimpleMarkerSymbolLayerBase
virtual QgsFilledMarkerSymbolLayer* clone() const /Factory/;
virtual QgsSymbol* subSymbol();
virtual bool setSubSymbol( QgsSymbol* symbol /Transfer/ );
virtual double estimateMaxBleed() const;
virtual double estimateMaxBleed( const QgsRenderContext& context ) const;
QSet<QString> usedAttributes( const QgsRenderContext& context ) const;
void setColor( const QColor& c );
virtual QColor color() const;

View File

@ -210,7 +210,7 @@ class QgsSymbolLayer
the drawn shape. For example, polygons drawn with an outline will draw half the width
of the outline outside of the polygon. This amount is estimated, since it may
be affected by data defined symbology rules.*/
virtual double estimateMaxBleed() const;
virtual double estimateMaxBleed( const QgsRenderContext& context ) const;
/** Sets the units to use for sizes and widths within the symbol layer. Individual
* symbol layer subclasses will interpret this in different ways, e.g., a marker symbol

View File

@ -152,7 +152,7 @@ class QgsSymbolLayerUtils
static void drawStippledBackground( QPainter* painter, QRect rect );
/** Returns the maximum estimated bleed for the symbol */
static double estimateMaxSymbolBleed( QgsSymbol* symbol );
static double estimateMaxSymbolBleed( QgsSymbol* symbol, const QgsRenderContext& context );
/** Attempts to load a symbol from a DOM element
* @param element DOM element representing symbol

View File

@ -83,7 +83,7 @@ void QgsComposerShape::setShapeStyleSymbol( QgsFillSymbol* symbol )
void QgsComposerShape::refreshSymbol()
{
mMaxSymbolBleed = QgsSymbolLayerUtils::estimateMaxSymbolBleed( mShapeStyleSymbol );
mMaxSymbolBleed = QgsSymbolLayerUtils::estimateMaxSymbolBleed( mShapeStyleSymbol, QgsComposerUtils::createRenderContextForComposition( mComposition, nullptr ) );
updateBoundingRect();
update();
@ -102,7 +102,7 @@ void QgsComposerShape::createDefaultShapeStyleSymbol()
properties.insert( QStringLiteral( "joinstyle" ), QStringLiteral( "miter" ) );
mShapeStyleSymbol = QgsFillSymbol::createSimple( properties );
mMaxSymbolBleed = QgsSymbolLayerUtils::estimateMaxSymbolBleed( mShapeStyleSymbol );
mMaxSymbolBleed = QgsSymbolLayerUtils::estimateMaxSymbolBleed( mShapeStyleSymbol, QgsComposerUtils::createRenderContextForComposition( mComposition, nullptr ) );
updateBoundingRect();
emit frameChanged();

View File

@ -201,7 +201,8 @@ void QgsPaperItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* ite
void QgsPaperItem::calculatePageMargin()
{
//get max bleed from symbol
double maxBleed = QgsSymbolLayerUtils::estimateMaxSymbolBleed( mComposition->pageStyleSymbol() );
double maxBleed = QgsSymbolLayerUtils::estimateMaxSymbolBleed( mComposition->pageStyleSymbol(),
QgsComposerUtils::createRenderContextForComposition( mComposition, nullptr ) );
//Now subtract 1 pixel to prevent semi-transparent borders at edge of solid page caused by
//anti-aliased painting. This may cause a pixel to be cropped from certain edge lines/symbols,

View File

@ -386,10 +386,10 @@ QgsSymbolLayer* QgsSimpleFillSymbolLayer::createFromSld( QDomElement &element )
return sl;
}
double QgsSimpleFillSymbolLayer::estimateMaxBleed() const
double QgsSimpleFillSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
double penBleed = mBorderStyle == Qt::NoPen ? 0 : ( mBorderWidth / 2.0 );
double offsetBleed = mOffset.x() > mOffset.y() ? mOffset.x() : mOffset.y();
double penBleed = context.convertToPainterUnits( mBorderStyle == Qt::NoPen ? 0 : ( mBorderWidth / 2.0 ), mBorderWidthUnit, mBorderWidthMapUnitScale );
double offsetBleed = context.convertToPainterUnits( mOffset.x() > mOffset.y() ? mOffset.x() : mOffset.y(), mOffsetUnit, mOffsetMapUnitScale );
return penBleed + offsetBleed;
}
@ -907,9 +907,9 @@ QgsGradientFillSymbolLayer* QgsGradientFillSymbolLayer::clone() const
return sl;
}
double QgsGradientFillSymbolLayer::estimateMaxBleed() const
double QgsGradientFillSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
double offsetBleed = mOffset.x() > mOffset.y() ? mOffset.x() : mOffset.y();
double offsetBleed = context.convertToPainterUnits( mOffset.x() > mOffset.y() ? mOffset.x() : mOffset.y(), mOffsetUnit, mOffsetMapUnitScale );
return offsetBleed;
}
@ -1502,9 +1502,9 @@ QgsShapeburstFillSymbolLayer* QgsShapeburstFillSymbolLayer::clone() const
return sl;
}
double QgsShapeburstFillSymbolLayer::estimateMaxBleed() const
double QgsShapeburstFillSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
double offsetBleed = qMax( mOffset.x(), mOffset.y() );
double offsetBleed = context.convertToPainterUnits( qMax( mOffset.x(), mOffset.y() ), mOffsetUnit, mOffsetMapUnitScale );
return offsetBleed;
}
@ -1654,11 +1654,11 @@ QgsMapUnitScale QgsImageFillSymbolLayer::mapUnitScale() const
return mOutlineWidthMapUnitScale;
}
double QgsImageFillSymbolLayer::estimateMaxBleed() const
double QgsImageFillSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
if ( mOutline && mOutline->symbolLayer( 0 ) )
{
double subLayerBleed = mOutline->symbolLayer( 0 )->estimateMaxBleed();
double subLayerBleed = mOutline->symbolLayer( 0 )->estimateMaxBleed( context );
return subLayerBleed;
}
return 0;
@ -2340,7 +2340,7 @@ QSet<QString> QgsLinePatternFillSymbolLayer::usedAttributes( const QgsRenderCont
return attr;
}
double QgsLinePatternFillSymbolLayer::estimateMaxBleed() const
double QgsLinePatternFillSymbolLayer::estimateMaxBleed( const QgsRenderContext& ) const
{
return 0;
}
@ -2520,14 +2520,7 @@ void QgsLinePatternFillSymbolLayer::applyPattern( const QgsSymbolRenderContext&
for ( int i = 0; i < fillLineSymbol->symbolLayerCount(); i++ )
{
QgsSymbolLayer *layer = fillLineSymbol->symbolLayer( i );
double layerBleed = layer->estimateMaxBleed();
// TODO: to get real bleed we have to scale it using context and units,
// unfortunately estimateMaxBleed() ignore units completely, e.g.
// QgsMarkerLineSymbolLayer::estimateMaxBleed() is mixing marker size and
// offset regardless units. This has to be fixed especially
// in estimateMaxBleed(), context probably has to be used.
// For now, we only support millimeters
double outputPixelLayerBleed = ctx.convertToPainterUnits( layerBleed, QgsUnitTypes::RenderMillimeters );
double outputPixelLayerBleed = layer->estimateMaxBleed( context.renderContext() );
outputPixelBleed = qMax( outputPixelBleed, outputPixelLayerBleed );
QgsMarkerLineSymbolLayer *markerLineLayer = dynamic_cast<QgsMarkerLineSymbolLayer *>( layer );
@ -3330,7 +3323,7 @@ void QgsPointPatternFillSymbolLayer::applyDataDefinedSettings( QgsSymbolRenderCo
applyPattern( context, mBrush, distanceX, distanceY, displacementX, displacementY );
}
double QgsPointPatternFillSymbolLayer::estimateMaxBleed() const
double QgsPointPatternFillSymbolLayer::estimateMaxBleed( const QgsRenderContext& ) const
{
return 0;
}
@ -3732,9 +3725,9 @@ QgsRasterFillSymbolLayer* QgsRasterFillSymbolLayer::clone() const
return sl;
}
double QgsRasterFillSymbolLayer::estimateMaxBleed() const
double QgsRasterFillSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
return mOffset.x() > mOffset.y() ? mOffset.x() : mOffset.y();
return context.convertToPainterUnits( mOffset.x() > mOffset.y() ? mOffset.x() : mOffset.y(), mOffsetUnit, mOffsetMapUnitScale );
}
void QgsRasterFillSymbolLayer::setImageFilePath( const QString &imagePath )

View File

@ -125,7 +125,7 @@ class CORE_EXPORT QgsSimpleFillSymbolLayer : public QgsFillSymbolLayer
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
QgsMapUnitScale mapUnitScale() const override;
double estimateMaxBleed() const override;
double estimateMaxBleed( const QgsRenderContext& context ) const override;
double dxfWidth( const QgsDxfExport& e, QgsSymbolRenderContext& context ) const override;
QColor dxfColor( QgsSymbolRenderContext& context ) const override;
@ -220,7 +220,7 @@ class CORE_EXPORT QgsGradientFillSymbolLayer : public QgsFillSymbolLayer
QgsGradientFillSymbolLayer* clone() const override;
double estimateMaxBleed() const override;
double estimateMaxBleed( const QgsRenderContext& context ) const override;
//! Type of gradient, e.g., linear or radial
GradientType gradientType() const { return mGradientType; }
@ -362,7 +362,7 @@ class CORE_EXPORT QgsShapeburstFillSymbolLayer : public QgsFillSymbolLayer
QgsShapeburstFillSymbolLayer* clone() const override;
double estimateMaxBleed() const override;
double estimateMaxBleed( const QgsRenderContext& context ) const override;
/** Sets the blur radius, which controls the amount of blurring applied to the fill.
* @param blurRadius Radius for fill blur. Values between 0 - 17 are valid, where higher values results in a stronger blur. Set to 0 to disable blur.
@ -613,7 +613,7 @@ class CORE_EXPORT QgsImageFillSymbolLayer: public QgsFillSymbolLayer
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
QgsMapUnitScale mapUnitScale() const override;
virtual double estimateMaxBleed() const override;
virtual double estimateMaxBleed( const QgsRenderContext& context ) const override;
double dxfWidth( const QgsDxfExport& e, QgsSymbolRenderContext& context ) const override;
QColor dxfColor( QgsSymbolRenderContext& context ) const override;
@ -663,7 +663,7 @@ class CORE_EXPORT QgsRasterFillSymbolLayer: public QgsImageFillSymbolLayer
void stopRender( QgsSymbolRenderContext& context ) override;
QgsStringMap properties() const override;
QgsRasterFillSymbolLayer* clone() const override;
virtual double estimateMaxBleed() const override;
virtual double estimateMaxBleed( const QgsRenderContext& context ) const override;
//override QgsImageFillSymbolLayer's support for sub symbols
virtual QgsSymbol* subSymbol() override { return nullptr; }
@ -961,7 +961,7 @@ class CORE_EXPORT QgsLinePatternFillSymbolLayer: public QgsImageFillSymbolLayer
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const override;
double estimateMaxBleed() const override;
double estimateMaxBleed( const QgsRenderContext& context ) const override;
QString ogrFeatureStyleWidth( double widthScaleFactor ) const;
@ -1095,7 +1095,7 @@ class CORE_EXPORT QgsPointPatternFillSymbolLayer: public QgsImageFillSymbolLayer
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const override;
double estimateMaxBleed() const override;
double estimateMaxBleed( const QgsRenderContext& context ) const override;
//getters and setters
double distanceX() const { return mDistanceX; }

View File

@ -566,7 +566,7 @@ void QgsSimpleLineSymbolLayer::applyDataDefinedSymbology( QgsSymbolRenderContext
}
}
double QgsSimpleLineSymbolLayer::estimateMaxBleed() const
double QgsSimpleLineSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
if ( mDrawInsidePolygon )
{
@ -575,7 +575,8 @@ double QgsSimpleLineSymbolLayer::estimateMaxBleed() const
}
else
{
return ( mWidth / 2.0 ) + mOffset;
return context.convertToPainterUnits(( mWidth / 2.0 ), mWidthUnit, mWidthMapUnitScale ) +
context.convertToPainterUnits( mOffset, mOffsetUnit, mOffsetMapUnitScale );
}
}
@ -1593,9 +1594,10 @@ QSet<QString> QgsMarkerLineSymbolLayer::usedAttributes( const QgsRenderContext&
return attr;
}
double QgsMarkerLineSymbolLayer::estimateMaxBleed() const
double QgsMarkerLineSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
return ( mMarker->size() / 2.0 ) + mOffset;
return context.convertToPainterUnits(( mMarker->size() / 2.0 ), mMarker->sizeUnit(), mMarker->sizeMapUnitScale() ) +
context.convertToPainterUnits( mOffset, mOffsetUnit, mOffsetMapUnitScale );
}

View File

@ -72,7 +72,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
QgsMapUnitScale mapUnitScale() const override;
double estimateMaxBleed() const override;
double estimateMaxBleed( const QgsRenderContext& context ) const override;
// new stuff
@ -215,7 +215,7 @@ class CORE_EXPORT QgsMarkerLineSymbolLayer : public QgsLineSymbolLayer
virtual void setWidth( double width ) override;
virtual double width() const override;
double estimateMaxBleed() const override;
double estimateMaxBleed( const QgsRenderContext& context ) const override;
// new stuff

View File

@ -1620,11 +1620,11 @@ bool QgsFilledMarkerSymbolLayer::setSubSymbol( QgsSymbol *symbol )
}
}
double QgsFilledMarkerSymbolLayer::estimateMaxBleed() const
double QgsFilledMarkerSymbolLayer::estimateMaxBleed( const QgsRenderContext& context ) const
{
if ( mFill.data() )
{
return QgsSymbolLayerUtils::estimateMaxSymbolBleed( mFill.data() );
return QgsSymbolLayerUtils::estimateMaxSymbolBleed( mFill.data(), context );
}
return 0;
}

View File

@ -420,7 +420,7 @@ class CORE_EXPORT QgsFilledMarkerSymbolLayer : public QgsSimpleMarkerSymbolLayer
QgsFilledMarkerSymbolLayer* clone() const override;
virtual QgsSymbol* subSymbol() override;
virtual bool setSubSymbol( QgsSymbol* symbol ) override;
virtual double estimateMaxBleed() const override;
virtual double estimateMaxBleed( const QgsRenderContext& context ) const override;
QSet<QString> usedAttributes( const QgsRenderContext& context ) const override;
void setColor( const QColor& c ) override;
virtual QColor color() const override;

View File

@ -197,10 +197,11 @@ class CORE_EXPORT QgsSymbolLayer
bool isLocked() const { return mLocked; }
/** Returns the estimated maximum distance which the layer style will bleed outside
the drawn shape. For example, polygons drawn with an outline will draw half the width
the drawn shape when drawn in the specified /a context. For example, polygons
drawn with an outline will draw half the width
of the outline outside of the polygon. This amount is estimated, since it may
be affected by data defined symbology rules.*/
virtual double estimateMaxBleed() const { return 0; }
virtual double estimateMaxBleed( const QgsRenderContext& context ) const { Q_UNUSED( context ); return 0; }
/** Sets the units to use for sizes and widths within the symbol layer. Individual
* symbol layer subclasses will interpret this in different ways, e.g., a marker symbol

View File

@ -607,13 +607,13 @@ QPixmap QgsSymbolLayerUtils::symbolPreviewPixmap( QgsSymbol* symbol, QSize size,
return pixmap;
}
double QgsSymbolLayerUtils::estimateMaxSymbolBleed( QgsSymbol* symbol )
double QgsSymbolLayerUtils::estimateMaxSymbolBleed( QgsSymbol* symbol, const QgsRenderContext& context )
{
double maxBleed = 0;
for ( int i = 0; i < symbol->symbolLayerCount(); i++ )
{
QgsSymbolLayer* layer = symbol->symbolLayer( i );
double layerMaxBleed = layer->estimateMaxBleed();
double layerMaxBleed = layer->estimateMaxBleed( context );
maxBleed = layerMaxBleed > maxBleed ? layerMaxBleed : maxBleed;
}

View File

@ -197,7 +197,7 @@ class CORE_EXPORT QgsSymbolLayerUtils
static void drawStippledBackground( QPainter* painter, QRect rect );
//! Returns the maximum estimated bleed for the symbol
static double estimateMaxSymbolBleed( QgsSymbol* symbol );
static double estimateMaxSymbolBleed( QgsSymbol* symbol, const QgsRenderContext& context );
/** Attempts to load a symbol from a DOM element
* @param element DOM element representing symbol

View File

@ -22,6 +22,7 @@
#include "qgsvectorlayer.h"
#include "qgsfeatureiterator.h"
#include "qgscsexception.h"
#include "qgssymbollayerutils.h"
#include <QPainter>
@ -76,14 +77,14 @@ QRectF QgsMapCanvasAnnotationItem::boundingRect() const
void QgsMapCanvasAnnotationItem::updateBoundingRect()
{
prepareGeometryChange();
double frameBorderWidth;
// TODO
QgsRenderContext rc = QgsRenderContext::fromQPainter( nullptr );
double fillSymbolBleed = mAnnotation && mAnnotation->fillSymbol() ?
QgsSymbolLayerUtils::estimateMaxSymbolBleed( mAnnotation->fillSymbol(), rc ) : 0;
if ( mAnnotation && !mAnnotation->hasFixedMapPosition() )
{
mBoundingRect = QRectF( - frameBorderWidth / 2.0, -frameBorderWidth / 2.0, mAnnotation->frameSize().width() + frameBorderWidth, mAnnotation->frameSize().height() + frameBorderWidth );
mBoundingRect = QRectF( - fillSymbolBleed, -fillSymbolBleed, mAnnotation->frameSize().width() + fillSymbolBleed * 2, mAnnotation->frameSize().height() + fillSymbolBleed * 2 );
}
else
{
@ -97,10 +98,10 @@ void QgsMapCanvasAnnotationItem::updateBoundingRect()
QSizeF frameSize = mAnnotation ? mAnnotation->frameSize() : QSizeF( 0.0, 0.0 );
double xMinPos = qMin( -halfSymbolSize, offset.x() - frameBorderWidth );
double xMaxPos = qMax( halfSymbolSize, offset.x() + frameSize.width() + frameBorderWidth );
double yMinPos = qMin( -halfSymbolSize, offset.y() - frameBorderWidth );
double yMaxPos = qMax( halfSymbolSize, offset.y() + frameSize.height() + frameBorderWidth );
double xMinPos = qMin( -halfSymbolSize, offset.x() - fillSymbolBleed );
double xMaxPos = qMax( halfSymbolSize, offset.x() + frameSize.width() + fillSymbolBleed );
double yMinPos = qMin( -halfSymbolSize, offset.y() - fillSymbolBleed );
double yMaxPos = qMax( halfSymbolSize, offset.y() + frameSize.height() + fillSymbolBleed );
mBoundingRect = QRectF( xMinPos, yMinPos, xMaxPos - xMinPos, yMaxPos - yMinPos );
}
}