Skip to content

Commit

Permalink
enable dynamic SVGs for fill symbol (#40902)
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Jan 8, 2021
1 parent f002f96 commit 6061030
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 6 deletions.
14 changes: 14 additions & 0 deletions python/core/auto_generated/symbology/qgsfillsymbollayer.sip.in
Expand Up @@ -1414,6 +1414,20 @@ Returns the map unit scale for the pattern's stroke.
virtual QgsMapUnitScale mapUnitScale() const;


QMap<QString, QgsProperty> parameters() const;
%Docstring
Returns the dynamic SVG parameters

.. versionadded:: 3.18
%End

void setParameters( const QMap<QString, QgsProperty> &parameters );
%Docstring
Sets the dynamic SVG parameters

.. versionadded:: 3.18
%End

protected:

virtual void applyDataDefinedSettings( QgsSymbolRenderContext &context );
Expand Down
40 changes: 36 additions & 4 deletions src/core/symbology/qgsfillsymbollayer.cpp
Expand Up @@ -2005,6 +2005,21 @@ QgsSymbolLayer *QgsSVGFillSymbolLayer::create( const QVariantMap &properties )
symbolLayer->setStrokeWidthMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "outline_width_map_unit_scale" )].toString() ) );
}

if ( properties.contains( QStringLiteral( "parameters" ) ) )
{
const QVariantMap parameters = properties[QStringLiteral( "parameters" )].toMap();
QMap<QString, QgsProperty> parametersProperties;
QVariantMap::const_iterator it = parameters.constBegin();
for ( ; it != parameters.constEnd(); ++it )
{
QgsProperty property;
if ( property.loadVariant( it.value() ) )
parametersProperties.insert( it.key(), property );
}

symbolLayer->setParameters( parametersProperties );
}

symbolLayer->restoreOldDataDefinedProperties( properties );

return symbolLayer.release();
Expand All @@ -2030,7 +2045,7 @@ QString QgsSVGFillSymbolLayer::layerType() const
void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush, const QString &svgFilePath, double patternWidth, QgsUnitTypes::RenderUnit patternWidthUnit,
const QColor &svgFillColor, const QColor &svgStrokeColor, double svgStrokeWidth,
QgsUnitTypes::RenderUnit svgStrokeWidthUnit, const QgsSymbolRenderContext &context,
const QgsMapUnitScale &patternWidthMapUnitScale, const QgsMapUnitScale &svgStrokeWidthMapUnitScale )
const QgsMapUnitScale &patternWidthMapUnitScale, const QgsMapUnitScale &svgStrokeWidthMapUnitScale, const QgsStringMap svgParameters )
{
if ( mSvgViewBox.isNull() )
{
Expand All @@ -2048,7 +2063,7 @@ void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush, const QString &svgFileP
bool fitsInCache = true;
double strokeWidth = context.renderContext().convertToPainterUnits( svgStrokeWidth, svgStrokeWidthUnit, svgStrokeWidthMapUnitScale );
QImage patternImage = QgsApplication::svgCache()->svgAsImage( svgFilePath, size, svgFillColor, svgStrokeColor, strokeWidth,
context.renderContext().scaleFactor(), fitsInCache, 0, ( context.renderContext().flags() & QgsRenderContext::RenderBlocking ) );
context.renderContext().scaleFactor(), fitsInCache, 0, ( context.renderContext().flags() & QgsRenderContext::RenderBlocking ), svgParameters );
if ( !fitsInCache )
{
QPicture patternPict = QgsApplication::svgCache()->svgAsPicture( svgFilePath, size, svgFillColor, svgStrokeColor, strokeWidth,
Expand Down Expand Up @@ -2082,8 +2097,9 @@ void QgsSVGFillSymbolLayer::applyPattern( QBrush &brush, const QString &svgFileP

void QgsSVGFillSymbolLayer::startRender( QgsSymbolRenderContext &context )
{
QgsStringMap evaluatedParameters = QgsSymbolLayerUtils::evaluatePropertiesMap( mParameters, context.renderContext().expressionContext() );

applyPattern( mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit, mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale );
applyPattern( mBrush, mSvgFilePath, mPatternWidth, mPatternWidthUnit, mColor, mSvgStrokeColor, mSvgStrokeWidth, mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );

if ( mStroke )
{
Expand Down Expand Up @@ -2126,6 +2142,13 @@ QVariantMap QgsSVGFillSymbolLayer::properties() const
map.insert( QStringLiteral( "svg_outline_width_map_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSvgStrokeWidthMapUnitScale ) );
map.insert( QStringLiteral( "outline_width_unit" ), QgsUnitTypes::encodeUnit( mStrokeWidthUnit ) );
map.insert( QStringLiteral( "outline_width_map_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mStrokeWidthMapUnitScale ) );

QVariantMap parameters;
QMap<QString, QgsProperty>::const_iterator it = mParameters.constBegin();
for ( ; it != mParameters.constEnd(); ++it )
parameters.insert( it.key(), it.value().toVariant() );
map[QStringLiteral( "parameters" )] = parameters;

return map;
}

Expand All @@ -2151,6 +2174,8 @@ QgsSVGFillSymbolLayer *QgsSVGFillSymbolLayer::clone() const
clonedLayer->setStrokeWidthUnit( mStrokeWidthUnit );
clonedLayer->setStrokeWidthMapUnitScale( mStrokeWidthMapUnitScale );

clonedLayer->setParameters( mParameters );

if ( mStroke )
{
clonedLayer->setSubSymbol( mStroke->clone() );
Expand Down Expand Up @@ -2330,8 +2355,10 @@ void QgsSVGFillSymbolLayer::applyDataDefinedSettings( QgsSymbolRenderContext &co
context.setOriginalValueVariable( mSvgStrokeWidth );
strokeWidth = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyStrokeWidth, context.renderContext().expressionContext(), mSvgStrokeWidth );
}
QgsStringMap evaluatedParameters = QgsSymbolLayerUtils::evaluatePropertiesMap( mParameters, context.renderContext().expressionContext() );

applyPattern( mBrush, svgFile, width, mPatternWidthUnit, svgFillColor, svgStrokeColor, strokeWidth,
mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale );
mSvgStrokeWidthUnit, context, mPatternWidthMapUnitScale, mSvgStrokeWidthMapUnitScale, evaluatedParameters );

}

Expand Down Expand Up @@ -2394,6 +2421,11 @@ void QgsSVGFillSymbolLayer::setDefaultSvgParams()
}
}

void QgsSVGFillSymbolLayer::setParameters( const QMap<QString, QgsProperty> &parameters )
{
mParameters = parameters;
}


QgsLinePatternFillSymbolLayer::QgsLinePatternFillSymbolLayer()
: QgsImageFillSymbolLayer()
Expand Down
16 changes: 15 additions & 1 deletion src/core/symbology/qgsfillsymbollayer.h
Expand Up @@ -1254,6 +1254,18 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
QgsMapUnitScale mapUnitScale() const override;

/**
* Returns the dynamic SVG parameters
* \since QGIS 3.18
*/
QMap<QString, QgsProperty> parameters() const { return mParameters; }

/**
* Sets the dynamic SVG parameters
* \since QGIS 3.18
*/
void setParameters( const QMap<QString, QgsProperty> &parameters );

protected:

void applyDataDefinedSettings( QgsSymbolRenderContext &context ) override;
Expand All @@ -1264,6 +1276,7 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
double mPatternWidth = 20;
QgsUnitTypes::RenderUnit mPatternWidthUnit = QgsUnitTypes::RenderMillimeters;
QgsMapUnitScale mPatternWidthMapUnitScale;
QMap<QString, QgsProperty> mParameters;

//! SVG data
QByteArray mSvgData;
Expand All @@ -1285,7 +1298,8 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer

//! Applies the svg pattern to the brush
void applyPattern( QBrush &brush, const QString &svgFilePath, double patternWidth, QgsUnitTypes::RenderUnit patternWidthUnit, const QColor &svgFillColor, const QColor &svgStrokeColor,
double svgStrokeWidth, QgsUnitTypes::RenderUnit svgStrokeWidthUnit, const QgsSymbolRenderContext &context, const QgsMapUnitScale &patternWidthMapUnitScale, const QgsMapUnitScale &svgStrokeWidthMapUnitScale );
double svgStrokeWidth, QgsUnitTypes::RenderUnit svgStrokeWidthUnit, const QgsSymbolRenderContext &context, const QgsMapUnitScale &patternWidthMapUnitScale, const QgsMapUnitScale &svgStrokeWidthMapUnitScale,
const QgsStringMap svgParameters );
};

/**
Expand Down
3 changes: 2 additions & 1 deletion src/gui/symbology/qgssymbollayerwidget.cpp
Expand Up @@ -2729,6 +2729,7 @@ QgsSVGFillSymbolLayerWidget::QgsSVGFillSymbolLayerWidget( QgsVectorLayer *vl, QW
mLayer = nullptr;
setupUi( this );

mSvgSelectorWidget->setAllowParameters( true );
mSvgSelectorWidget->sourceLineEdit()->setPropertyOverrideToolButtonVisible( true );

connect( mTextureWidthSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSVGFillSymbolLayerWidget::mTextureWidthSpinBox_valueChanged );
Expand Down Expand Up @@ -2853,7 +2854,7 @@ void QgsSVGFillSymbolLayerWidget::setFile( const QString &name )

void QgsSVGFillSymbolLayerWidget::setSvgParameters( const QMap<QString, QgsProperty> &parameters )
{
// TODO mLayer->setParameters(parameters);
mLayer->setParameters( parameters );
whileBlocking( mSvgSelectorWidget )->setSvgParameters( parameters );

updateParamGui();
Expand Down

0 comments on commit 6061030

Please sign in to comment.