Skip to content

Commit

Permalink
When an svg image has no viewbox tags, try to take the width/height
Browse files Browse the repository at this point in the history
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 ed47dd3
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/core/symbology/qgssvgcache.cpp
Expand Up @@ -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( ' ' );
Expand Down
17 changes: 17 additions & 0 deletions tests/src/core/testqgssvgcache.cpp
Expand Up @@ -54,6 +54,7 @@ class TestQgsSvgCache : public QObject
void base64();
void replaceParams();
void aspectRatio();
void noViewBox();

};

Expand Down Expand Up @@ -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
Expand Down
49 changes: 49 additions & 0 deletions tests/testdata/svg/no_viewbox.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ed47dd3

Please sign in to comment.