Skip to content
Permalink
Browse files

When an svg image has no viewbox tags, try to take the width/height

attribute as a fallback for these

Allows the aspect ratio of svgs without a viewbox to be determined,
resulting in correct rendering as svg markers

(cherry picked from commit 0864e0a)
  • Loading branch information
nyalldawson committed Sep 11, 2020
1 parent 5e6f5d9 commit ed47dd3f5dc768923ca00c7f904f5cbf4d6b1bf2
Showing with 90 additions and 0 deletions.
  1. +24 −0 src/core/symbology/qgssvgcache.cpp
  2. +17 −0 tests/src/core/testqgssvgcache.cpp
  3. +49 −0 tests/testdata/svg/no_viewbox.svg
@@ -345,7 +345,31 @@ double QgsSvgCache::calcSizeScaleFactor( QgsSvgCacheEntry *entry, const QDomElem

//could not find valid viewbox attribute
if ( viewBox.isEmpty() )
{
// trying looking for width/height and use them as a fallback
if ( docElem.tagName() == QLatin1String( "svg" ) && docElem.hasAttribute( QStringLiteral( "width" ) ) )
{
const QString widthString = docElem.attribute( QStringLiteral( "width" ) );
const QRegularExpression measureRegEx( QStringLiteral( "([\\d\\.]+).*?$" ) );
const QRegularExpressionMatch widthMatch = measureRegEx.match( widthString );
if ( widthMatch.hasMatch() )
{
double width = widthMatch.captured( 1 ).toDouble();
const QString heightString = docElem.attribute( QStringLiteral( "height" ) );

const QRegularExpressionMatch heightMatch = measureRegEx.match( heightString );
if ( heightMatch.hasMatch() )
{
double height = heightMatch.captured( 1 ).toDouble();
viewboxSize = QSizeF( width, height );
return width / entry->size;
}
}
}

return 1.0;
}


//width should be 3rd element in a 4 part space delimited string
QStringList parts = viewBox.split( ' ' );
@@ -54,6 +54,7 @@ class TestQgsSvgCache : public QObject
void base64();
void replaceParams();
void aspectRatio();
void noViewBox();

};

@@ -332,6 +333,22 @@ void TestQgsSvgCache::aspectRatio()
QVERIFY( imageCheck( QStringLiteral( "svgcache_aspect_ratio" ), img, 30 ) );
}

void TestQgsSvgCache::noViewBox()
{
// if a source SVG has no viewbox but it does have width/height, use that as a backup so that
// we can correctly determine the svg's aspect ratio
const QString originalImage = TEST_DATA_DIR + QStringLiteral( "/svg/no_viewbox.svg" );
QgsSvgCache cache;
double size = 12;
const QColor fill = QColor( 0, 0, 0 );
const QColor stroke = QColor( 0, 0, 0 );
double strokeWidth = 1;
double widthScaleFactor = 1;
QSizeF viewBoxSize = cache.svgViewboxSize( originalImage, size, fill, stroke, strokeWidth, widthScaleFactor );
QGSCOMPARENEAR( viewBoxSize.width(), 1.329267, 0.0001 );
QGSCOMPARENEAR( viewBoxSize.height(), 6.358467, 0.0001 );
}

bool TestQgsSvgCache::imageCheck( const QString &testName, QImage &image, int mismatchCount )
{
//draw background
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg13"
height="6.3584666mm"
width="1.3292667mm"
version="1.0">
<metadata
id="metadata17">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3">
<pattern
y="0"
x="0"
height="6"
width="6"
patternUnits="userSpaceOnUse"
id="EMFhbasepattern" />
</defs>
<path
id="path5"
d=" M 0.66666667,0 L 0.66666667,24 z "
style="fill:#ffffff;fill-rule:nonzero;fill-opacity:1;stroke:none;" />
<path
id="path7"
d=" M 0.66666667,0 L 0.66666667,24 "
style="fill:none;stroke:#000000;stroke-width:0.66666669px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;" />
<path
id="path9"
d=" M 0.66666667,8 C 3,8 5,9.6666667 5,12 C 5,14.333333 3,16 0.66666667,16 "
style="fill:none;stroke:#000000;stroke-width:0.66666669px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;" />
<path
id="path11"
d=" M 0.66666667,12 L 5,12 "
style="fill:none;stroke:#000000;stroke-width:0.66666669px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1;" />
</svg>

0 comments on commit ed47dd3

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