Skip to content
Permalink
Browse files

Fix svg outline widths are incorrectly scaled (fix #11522)

SVG outline width sizes were not correctly calculated, and were
set to a constant value regardless of the rendered size of the svg
image. This meant that:
1. the rendered outline width was effectively randomly scaled
2. the width would change as the symbol size was modified

This change has some large flow on effects, eg:

- the large outline widths required to render an outline in <2.12
will now be drawn in their correct sizes, eg massive outlines. Projects
will need to be updated to reflect this.
- the default outline width set for the provided svg symbols (1 mm)
is much too large, so the symbols look bad with the default width.
This size needs to be modified in all the (~300 svg marker images)
- On the plus side, the long standing issue where most of the svg
symbols were rendered with white fill on white background and an
almost invisible black border is now fixed (refs #10908, #8538)
  • Loading branch information
nyalldawson committed Oct 10, 2015
1 parent a721752 commit 16f700a56c7670076d6983193ba4df0ee4f90624
@@ -1039,7 +1039,7 @@ QgsSvgMarkerSymbolLayerV2::QgsSvgMarkerSymbolLayerV2( const QString& name, doubl
mAngle = angle;
mOffset = QPointF( 0, 0 );
mScaleMethod = scaleMethod;
mOutlineWidth = 1.0;
mOutlineWidth = 0.2;
mOutlineWidthUnit = QgsSymbolV2::MM;
mColor = QColor( Qt::black );
mOutlineColor = QColor( Qt::black );
@@ -229,7 +229,7 @@ void QgsSvgCache::containsParams( const QString& path, bool& hasFillParam, QColo
{
defaultFillColor = QColor( Qt::black );
defaultOutlineColor = QColor( Qt::black );
defaultOutlineWidth = 1.0;
defaultOutlineWidth = 0.2;

QDomDocument svgDoc;
if ( !svgDoc.setContent( getImageData( path ) ) )
@@ -256,12 +256,56 @@ void QgsSvgCache::replaceParamsAndCacheSvg( QgsSvgCacheEntry* entry )

//replace fill color, outline color, outline with in all nodes
QDomElement docElem = svgDoc.documentElement();
replaceElemParams( docElem, entry->fill, entry->outline, entry->outlineWidth );

double sizeScaleFactor = calcSizeScaleFactor( entry, docElem );
replaceElemParams( docElem, entry->fill, entry->outline, entry->outlineWidth * sizeScaleFactor );

entry->svgContent = svgDoc.toByteArray();
mTotalSize += entry->svgContent.size();
}

double QgsSvgCache::calcSizeScaleFactor( QgsSvgCacheEntry* entry, const QDomElement& docElem ) const
{
QString viewBox;

//bad size
if ( !entry || entry->size == 0 )
return 1.0;

//find svg viewbox attribute
//first check if docElem is svg element
if ( docElem.tagName() == "svg" )
{
viewBox = docElem.attribute( "viewBox", QString() );
}
else
{
QDomElement svgElem = docElem.firstChildElement( "svg" ) ;
if ( !svgElem.isNull() )
{
viewBox = svgElem.attribute( "viewBox", QString() );
}
}

//could not find valid viewbox attribute
if ( viewBox.isEmpty() )
return 1.0;

//width should be 3rd element in a 4 part space delimited string
QStringList parts = viewBox.split( " " );
if ( parts.count() != 4 )
return 1.0;

bool widthOk = false;
double width = parts.at( 2 ).toDouble( &widthOk );
if ( widthOk )
{
return width / entry->size ;
}

return 1.0;
}

QByteArray QgsSvgCache::getImageData( const QString &path ) const
{
// is it a path to local file?
@@ -178,6 +178,9 @@ class CORE_EXPORT QgsSvgCache : public QObject
void containsElemParams( const QDomElement& elem, bool& hasFillParam, QColor& defaultFill, bool& hasOutlineParam, QColor& defaultOutline,
bool& hasOutlineWidthParam, double& defaultOutlineWidth ) const;

/** Calculates scaling for rendered image sizes to SVG logical sizes*/
double calcSizeScaleFactor( QgsSvgCacheEntry* entry, const QDomElement& docElem ) const;

/** Release memory and remove cache entry from mEntryLookup*/
void removeCacheEntry( const QString& s, QgsSvgCacheEntry* entry );

@@ -189,6 +192,7 @@ class CORE_EXPORT QgsSvgCache : public QObject

//! Mutex to prevent concurrent access to the class from multiple threads at once (may corrupt the entries otherwise).
QMutex mMutex;

};

#endif // QGSSVGCACHE_H
@@ -35,6 +35,9 @@
<property name="singleStep">
<double>0.200000000000000</double>
</property>
<property name="value">
<double>0.200000000000000</double>
</property>
<property name="showClearButton" stdset="0">
<bool>false</bool>
</property>

0 comments on commit 16f700a

Please sign in to comment.
You can’t perform that action at this time.