-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Export parametric SVG, will fallback symbols for the systems that cannot understand them #3703
Conversation
@@ -2093,12 +2095,6 @@ void QgsSVGFillSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, cons | |||
symbolizerElem.appendChild( doc.createComment( QStringLiteral( "SVG from data not implemented yet" ) ) ); | |||
} | |||
|
|||
if ( mSvgOutlineColor.isValid() || mSvgOutlineWidth >= 0 ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was removed as the svg outline is not the same thing as the polygon fill outline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor suggestions, but this looks good in general to me! Will be very nice to have!
* that cannot do SVG at all | ||
* @note added in 3.0 | ||
*/ | ||
static void parametricSvgToSld( QDomDocument &doc, QDomElement &graphicElem, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest:
- Rename color to fillColor
- Make this return the QDomElement instead of passing it as an argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming to fill color, not a problem.
The second I'm not 100% syre, as I (thought I) was just following an established pattern, e.g.:
https://github.com/qgis/QGIS/blob/master/src/core/symbology-ng/qgssymbollayerutils.h#L242
https://github.com/qgis/QGIS/blob/master/src/core/symbology-ng/qgssymbollayerutils.h#L248
https://github.com/qgis/QGIS/blob/master/src/core/symbology-ng/qgssymbollayerutils.h#L257
However I also see smaller helper methods returning the element indeed:
https://github.com/qgis/QGIS/blob/master/src/core/symbology-ng/qgssymbollayerutils.h#L320
https://github.com/qgis/QGIS/blob/master/src/core/symbology-ng/qgssymbollayerutils.h#L323
So I'll follow your advice for this one too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally don't have a strong preference for either, but the vast majority of the xml writing methods in QGIS return the element. So my vote goes to consistency :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had another look and believe it should be kept as is. Here is an example of calling code:
void QgsSvgMarkerSymbolLayer::writeSldMarker( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const
{
// <Graphic>
QDomElement graphicElem = doc.createElement( QStringLiteral( "se:Graphic" ) );
element.appendChild( graphicElem );
// encode a parametric SVG reference
double size = QgsSymbolLayerUtils::rescaleUom( mSize, mSizeUnit, props );
double outlineWidth = QgsSymbolLayerUtils::rescaleUom( mOutlineWidth, mOutlineWidthUnit, props );
QgsSymbolLayerUtils::parametricSvgToSld( doc, graphicElem, mPath, mColor, size, mOutlineColor, outlineWidth );
// <Rotation>
QString angleFunc;
bool ok;
double angle = props.value( QStringLiteral( "angle" ), QStringLiteral( "0" ) ).toDouble( &ok );
if ( !ok )
{
angleFunc = QStringLiteral( "%1 + %2" ).arg( props.value( QStringLiteral( "angle" ), QStringLiteral( "0" ) ) ).arg( mAngle );
}
else if ( !qgsDoubleNear( angle + mAngle, 0.0 ) )
{
angleFunc = QString::number( angle + mAngle );
}
QgsSymbolLayerUtils::createRotationElement( doc, graphicElem, angleFunc );
// <Displacement>
QPointF offset = QgsSymbolLayerUtils::rescaleUom( mOffset, mOffsetUnit, props );
QgsSymbolLayerUtils::createDisplacementElement( doc, graphicElem, offset );
}
As you can see the pattern of passing "doc and element" is spread across the whole method, and parametricSvgToSld is not the only contributor to the creation of graphic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nyalldawson what do you think? I can still change that to break the existing pattern and build the element instead of accepting it... it would just look odd in the context where it's used, not the end of the world I presume ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaime - no, it's all good. your reasoning is sound!
{ | ||
url.addQueryItem( "outline", borderColor.name() ); | ||
url.addQueryItem( "outline-opacity", encodeSldAlpha( borderColor.alpha() ) ); | ||
url.addQueryItem( "outline-width", QString::number( borderWidth ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible that an svg could use the outline-width parameter without having an outline-color. Actually that applies to all parameters, eg fill opacity without paramaterised fill colors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix that
…m that cannot understand them
Pushed some fixes:
By the way, I noticed that the SVG param expansion code seems to assume colors are never invalid, I don't see checks. |
QString QgsSymbolLayerUtils::getSvgParametricPath( const QString& basePath, const QColor& fillColor, const QColor& borderColor, double borderWidth ) | ||
{ | ||
QUrl url = QUrl(); | ||
if ( fillColor.isValid() ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These also should be split up - eg you could potentially use 'fill-opacity' without any 'fill' parameter for a multi-colored fill svg. (same with outline opacity).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum hum... how is that done though? The existing callers only have a QColor, which embodies both color and opacity. You mean it would be better to have a string (encoded color) and a opacity (number) for each color, so that the caller can decide which parameters are going to be replaced?
As noted before, the actual rendering code seems to just assume colors are always present and valid, which is a bit strange, but I did not yet play with the UI and see if the fill can be excluded, and how.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah... ignore me.... i was confused.
Thank you @nyalldawson ! |
This pull request makes the SVG parameters explicit, but at the same time leverages SLD fallback symbol support to add a non parametric SVG fallback, as well as a simple mark with the right color and outline for systems that cannot deal with SVG, or lack the symbol on their file system.