Add fill symbol for symbol buffers

This commit is contained in:
Nyall Dawson 2024-07-24 12:27:26 +10:00
parent 13c1a1b997
commit b5437eef50
4 changed files with 145 additions and 3 deletions

View File

@ -78,6 +78,11 @@ Contains settings relating to symbol buffers, which draw a "halo" effect around
%End
public:
QgsSymbolBufferSettings();
~QgsSymbolBufferSettings();
QgsSymbolBufferSettings( const QgsSymbolBufferSettings &other );
bool enabled() const;
%Docstring
Returns whether the buffer is enabled.
@ -165,6 +170,24 @@ Sets the join ``style`` used for drawing the buffer.
.. seealso:: :py:func:`joinStyle`
%End
QgsFillSymbol *fillSymbol();
%Docstring
Returns the fill symbol used to render the buffer.
Ownership is not transferred.
.. seealso:: :py:func:`setFillSymbol`
%End
void setFillSymbol( QgsFillSymbol *symbol /Transfer/ );
%Docstring
Sets the fill ``symbol`` used to render the buffer. Ownership of ``symbol`` is
transferred to the buffer.
.. seealso:: :py:func:`fillSymbol`
%End
void writeXml( QDomElement &element, const QgsReadWriteContext &context ) const;
%Docstring
Writes the buffer settings to an XML ``element``.

View File

@ -78,6 +78,11 @@ Contains settings relating to symbol buffers, which draw a "halo" effect around
%End
public:
QgsSymbolBufferSettings();
~QgsSymbolBufferSettings();
QgsSymbolBufferSettings( const QgsSymbolBufferSettings &other );
bool enabled() const;
%Docstring
Returns whether the buffer is enabled.
@ -165,6 +170,24 @@ Sets the join ``style`` used for drawing the buffer.
.. seealso:: :py:func:`joinStyle`
%End
QgsFillSymbol *fillSymbol();
%Docstring
Returns the fill symbol used to render the buffer.
Ownership is not transferred.
.. seealso:: :py:func:`setFillSymbol`
%End
void setFillSymbol( QgsFillSymbol *symbol /Transfer/ );
%Docstring
Sets the fill ``symbol`` used to render the buffer. Ownership of ``symbol`` is
transferred to the buffer.
.. seealso:: :py:func:`fillSymbol`
%End
void writeXml( QDomElement &element, const QgsReadWriteContext &context ) const;
%Docstring
Writes the buffer settings to an XML ``element``.

View File

@ -53,6 +53,7 @@
#include "qgsmarkersymbol.h"
#include "qgslinesymbol.h"
#include "qgsfillsymbol.h"
#include "qgsfillsymbollayer.h"
#include "qgscolorutils.h"
#include "qgsunittypes.h"
@ -63,7 +64,46 @@ QgsPropertiesDefinition QgsSymbol::sPropertyDefinitions;
// QgsSymbolBufferSettings
//
void QgsSymbolBufferSettings::writeXml( QDomElement &element, const QgsReadWriteContext & ) const
QgsSymbolBufferSettings::QgsSymbolBufferSettings()
{
mFillSymbol = std::make_unique< QgsFillSymbol >( QgsSymbolLayerList() << new QgsSimpleFillSymbolLayer( QColor( 255, 255, 255 ), Qt::SolidPattern, QColor( 200, 200, 200 ), Qt::NoPen ) );
}
QgsSymbolBufferSettings::QgsSymbolBufferSettings( const QgsSymbolBufferSettings &other )
: mEnabled( other.mEnabled )
, mSize( other.mSize )
, mSizeUnit( other.mSizeUnit )
, mSizeMapUnitScale( other.mSizeMapUnitScale )
, mJoinStyle( other.mJoinStyle )
, mFillSymbol( other.mFillSymbol ? other.mFillSymbol->clone() : nullptr )
{
}
QgsSymbolBufferSettings &QgsSymbolBufferSettings::operator=( const QgsSymbolBufferSettings &other )
{
mEnabled = other.mEnabled;
mSize = other.mSize;
mSizeUnit = other.mSizeUnit;
mSizeMapUnitScale = other.mSizeMapUnitScale;
mJoinStyle = other.mJoinStyle;
mFillSymbol.reset( other.mFillSymbol ? other.mFillSymbol->clone() : nullptr );
return *this;
}
QgsFillSymbol *QgsSymbolBufferSettings::fillSymbol()
{
return mFillSymbol.get();
}
void QgsSymbolBufferSettings::setFillSymbol( QgsFillSymbol *symbol )
{
mFillSymbol.reset( symbol );
}
QgsSymbolBufferSettings::~QgsSymbolBufferSettings() = default;
void QgsSymbolBufferSettings::writeXml( QDomElement &element, const QgsReadWriteContext &context ) const
{
QDomElement symbolBufferElem = element.ownerDocument().createElement( QStringLiteral( "buffer" ) );
symbolBufferElem.setAttribute( QStringLiteral( "enabled" ), mEnabled );
@ -71,10 +111,18 @@ void QgsSymbolBufferSettings::writeXml( QDomElement &element, const QgsReadWrite
symbolBufferElem.setAttribute( QStringLiteral( "sizeUnits" ), QgsUnitTypes::encodeUnit( mSizeUnit ) );
symbolBufferElem.setAttribute( QStringLiteral( "sizeMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSizeMapUnitScale ) );
symbolBufferElem.setAttribute( QStringLiteral( "joinStyle" ), static_cast< unsigned int >( mJoinStyle ) );
if ( mFillSymbol )
{
QDomDocument document = element.ownerDocument();
const QDomElement fillElem = QgsSymbolLayerUtils::saveSymbol( QString(), mFillSymbol.get(), document, context );
symbolBufferElem.appendChild( fillElem );
}
element.appendChild( symbolBufferElem );
}
void QgsSymbolBufferSettings::readXml( const QDomElement &element, const QgsReadWriteContext & )
void QgsSymbolBufferSettings::readXml( const QDomElement &element, const QgsReadWriteContext &context )
{
const QDomElement symbolBufferElem = element.firstChildElement( QStringLiteral( "buffer" ) );
mEnabled = symbolBufferElem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
@ -82,6 +130,16 @@ void QgsSymbolBufferSettings::readXml( const QDomElement &element, const QgsRead
mSizeUnit = QgsUnitTypes::decodeRenderUnit( symbolBufferElem.attribute( QStringLiteral( "sizeUnits" ) ) );
mSizeMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( symbolBufferElem.attribute( QStringLiteral( "sizeMapUnitScale" ) ) );
mJoinStyle = static_cast< Qt::PenJoinStyle >( symbolBufferElem.attribute( QStringLiteral( "joinStyle" ), QString::number( Qt::RoundJoin ) ).toUInt() );
const QDomElement fillSymbolElem = element.firstChildElement( QStringLiteral( "symbol" ) );
if ( !fillSymbolElem.isNull() )
{
mFillSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( fillSymbolElem, context ) );
}
else
{
mFillSymbol = std::make_unique< QgsFillSymbol >( QgsSymbolLayerList() << new QgsSimpleFillSymbolLayer( QColor( 255, 255, 255 ), Qt::SolidPattern, QColor( 200, 200, 200 ), Qt::NoPen ) );
}
}
@ -914,6 +972,11 @@ void QgsSymbol::startRender( QgsRenderContext &context, const QgsFields &fields
mDataDefinedProperties.prepare( context.expressionContext() );
if ( mBufferSettings && mBufferSettings->enabled() && mBufferSettings->fillSymbol() )
{
mBufferSettings->fillSymbol()->startRender( context, fields );
}
for ( QgsSymbolLayer *layer : std::as_const( mLayers ) )
{
if ( !layer->enabled() || !context.isSymbolLayerEnabled( layer ) )
@ -960,6 +1023,11 @@ void QgsSymbol::stopRender( QgsRenderContext &context )
}
}
if ( mBufferSettings && mBufferSettings->enabled() && mBufferSettings->fillSymbol() )
{
mBufferSettings->fillSymbol()->stopRender( context );
}
mSymbolRenderContext.reset( nullptr );
Q_NOWARN_DEPRECATED_PUSH
@ -1280,6 +1348,10 @@ QSet<QString> QgsSymbol::usedAttributes( const QgsRenderContext &context ) const
attributes.unite( ( *sIt )->usedAttributes( context ) );
}
}
if ( mBufferSettings && mBufferSettings->enabled() && mBufferSettings->fillSymbol() )
{
attributes.unite( mBufferSettings->fillSymbol()->usedAttributes( context ) );
}
return attributes;
}

View File

@ -97,6 +97,12 @@ class CORE_EXPORT QgsSymbolBufferSettings
{
public:
QgsSymbolBufferSettings();
~QgsSymbolBufferSettings();
QgsSymbolBufferSettings( const QgsSymbolBufferSettings &other );
QgsSymbolBufferSettings &operator=( const QgsSymbolBufferSettings & );
/**
* Returns whether the buffer is enabled.
* \see setEnabled()
@ -173,6 +179,24 @@ class CORE_EXPORT QgsSymbolBufferSettings
*/
void setJoinStyle( Qt::PenJoinStyle style ) { mJoinStyle = style; }
/**
* Returns the fill symbol used to render the buffer.
*
* Ownership is not transferred.
*
* \see setFillSymbol()
*/
QgsFillSymbol *fillSymbol();
/**
* Sets the fill \a symbol used to render the buffer. Ownership of \a symbol is
* transferred to the buffer.
*
* \see fillSymbol()
*/
void setFillSymbol( QgsFillSymbol *symbol SIP_TRANSFER );
/**
* Writes the buffer settings to an XML \a element.
*
@ -193,7 +217,7 @@ class CORE_EXPORT QgsSymbolBufferSettings
Qgis::RenderUnit mSizeUnit = Qgis::RenderUnit::Millimeters;
QgsMapUnitScale mSizeMapUnitScale;
Qt::PenJoinStyle mJoinStyle = Qt::RoundJoin;
std::unique_ptr< QgsFillSymbol > mFillSymbol;
};