26 #include <QApplication> 27 #include <QCoreApplication> 29 #include <QDomDocument> 30 #include <QDomElement> 35 #include <QSvgRenderer> 37 #include <QNetworkReply> 38 #include <QNetworkRequest> 46 QgsSvgCacheEntry::QgsSvgCacheEntry(
const QString &path,
double size,
double strokeWidth,
double widthScaleFactor,
const QColor &fill,
const QColor &stroke,
double fixedAspectRatio )
49 , strokeWidth( strokeWidth )
50 , widthScaleFactor( widthScaleFactor )
51 , fixedAspectRatio( fixedAspectRatio )
59 const QgsSvgCacheEntry *otherSvg =
dynamic_cast< const QgsSvgCacheEntry *
>( other );
62 || !
qgsDoubleNear( otherSvg->fixedAspectRatio, fixedAspectRatio )
65 || !
qgsDoubleNear( otherSvg->widthScaleFactor, widthScaleFactor )
66 || otherSvg->fill != fill
67 || otherSvg->stroke != stroke
68 || otherSvg->path != path )
74 int QgsSvgCacheEntry::dataSize()
const 76 int size = svgContent.size();
79 size += picture->size();
83 size += ( image->width() * image->height() * 32 );
88 void QgsSvgCacheEntry::dump()
const 90 QgsDebugMsg( QStringLiteral(
"path: %1, size %2, width scale factor %3" ).arg( path ).arg( size ).arg( widthScaleFactor ) );
102 mMissingSvg = QStringLiteral(
"<svg width='10' height='10'><text x='5' y='10' font-size='10' text-anchor='middle'>?</text></svg>" ).toLatin1();
105 if ( QFile::exists( downloadingSvgPath ) )
107 QFile file( downloadingSvgPath );
108 if ( file.open( QIODevice::ReadOnly ) )
110 mFetchingSvg = file.readAll();
114 if ( mFetchingSvg.isEmpty() )
116 mFetchingSvg = QStringLiteral(
"<svg width='10' height='10'><text x='5' y='10' font-size='10' text-anchor='middle'>?</text></svg>" ).toLatin1();
122 QImage
QgsSvgCache::svgAsImage(
const QString &file,
double size,
const QColor &fill,
const QColor &stroke,
double strokeWidth,
123 double widthScaleFactor,
bool &fitsInCache,
double fixedAspectRatio,
bool blocking )
125 QMutexLocker locker( &
mMutex );
128 QgsSvgCacheEntry *currentEntry = cacheEntry( file, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio, blocking );
135 if ( !currentEntry->image )
137 QSvgRenderer r( currentEntry->svgContent );
138 double hwRatio = 1.0;
139 if ( r.viewBoxF().width() > 0 )
141 if ( currentEntry->fixedAspectRatio > 0 )
143 hwRatio = currentEntry->fixedAspectRatio;
147 hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
150 long cachedDataSize = 0;
151 cachedDataSize += currentEntry->svgContent.size();
152 cachedDataSize +=
static_cast< int >( currentEntry->size * currentEntry->size * hwRatio * 32 );
156 currentEntry->image.reset();
159 if ( !currentEntry->picture )
161 cachePicture( currentEntry,
false );
165 result = imageFromCachedPicture( *currentEntry );
169 cacheImage( currentEntry );
170 result = *( currentEntry->image );
176 result = *( currentEntry->image );
183 double widthScaleFactor,
bool forceVectorOutput,
double fixedAspectRatio,
bool blocking )
185 QMutexLocker locker( &
mMutex );
187 QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio, blocking );
191 if ( !currentEntry->picture )
193 cachePicture( currentEntry, forceVectorOutput );
202 p.setData( currentEntry->picture->data(), currentEntry->picture->size() );
206 QByteArray
QgsSvgCache::svgContent(
const QString &path,
double size,
const QColor &fill,
const QColor &stroke,
double strokeWidth,
207 double widthScaleFactor,
double fixedAspectRatio,
bool blocking )
209 QMutexLocker locker( &
mMutex );
211 QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio, blocking );
213 return currentEntry->svgContent;
217 double widthScaleFactor,
double fixedAspectRatio,
bool blocking )
219 QMutexLocker locker( &
mMutex );
221 QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio, blocking );
222 return currentEntry->viewboxSize;
225 void QgsSvgCache::containsParams(
const QString &path,
bool &hasFillParam, QColor &defaultFillColor,
bool &hasStrokeParam, QColor &defaultStrokeColor,
226 bool &hasStrokeWidthParam,
double &defaultStrokeWidth,
bool blocking )
const 228 bool hasDefaultFillColor =
false;
229 bool hasFillOpacityParam =
false;
230 bool hasDefaultFillOpacity =
false;
231 double defaultFillOpacity = 1.0;
232 bool hasDefaultStrokeColor =
false;
233 bool hasDefaultStrokeWidth =
false;
234 bool hasStrokeOpacityParam =
false;
235 bool hasDefaultStrokeOpacity =
false;
236 double defaultStrokeOpacity = 1.0;
238 containsParams( path, hasFillParam, hasDefaultFillColor, defaultFillColor,
239 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
240 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
241 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
242 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity,
247 bool &hasFillParam,
bool &hasDefaultFillParam, QColor &defaultFillColor,
248 bool &hasFillOpacityParam,
bool &hasDefaultFillOpacity,
double &defaultFillOpacity,
249 bool &hasStrokeParam,
bool &hasDefaultStrokeColor, QColor &defaultStrokeColor,
250 bool &hasStrokeWidthParam,
bool &hasDefaultStrokeWidth,
double &defaultStrokeWidth,
251 bool &hasStrokeOpacityParam,
bool &hasDefaultStrokeOpacity,
double &defaultStrokeOpacity,
252 bool blocking )
const 254 hasFillParam =
false;
255 hasFillOpacityParam =
false;
256 hasStrokeParam =
false;
257 hasStrokeWidthParam =
false;
258 hasStrokeOpacityParam =
false;
259 defaultFillColor = QColor( Qt::white );
260 defaultFillOpacity = 1.0;
261 defaultStrokeColor = QColor( Qt::black );
262 defaultStrokeWidth = 0.2;
263 defaultStrokeOpacity = 1.0;
265 hasDefaultFillParam =
false;
266 hasDefaultFillOpacity =
false;
267 hasDefaultStrokeColor =
false;
268 hasDefaultStrokeWidth =
false;
269 hasDefaultStrokeOpacity =
false;
272 if ( !svgDoc.setContent(
getContent( path, mMissingSvg, mFetchingSvg, blocking ) ) )
277 QDomElement docElem = svgDoc.documentElement();
278 containsElemParams( docElem, hasFillParam, hasDefaultFillParam, defaultFillColor,
279 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
280 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
281 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
282 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
285 void QgsSvgCache::replaceParamsAndCacheSvg( QgsSvgCacheEntry *entry,
bool blocking )
293 if ( !svgDoc.setContent(
getContent( entry->path, mMissingSvg, mFetchingSvg, blocking ) ) )
299 QDomElement docElem = svgDoc.documentElement();
302 double sizeScaleFactor = calcSizeScaleFactor( entry, docElem, viewboxSize );
303 entry->viewboxSize = viewboxSize;
304 replaceElemParams( docElem, entry->fill, entry->stroke, entry->strokeWidth * sizeScaleFactor );
306 entry->svgContent = svgDoc.toByteArray( 0 );
310 entry->svgContent.replace(
"\n<tspan",
"<tspan" );
311 entry->svgContent.replace(
"</tspan>\n",
"</tspan>" );
316 double QgsSvgCache::calcSizeScaleFactor( QgsSvgCacheEntry *entry,
const QDomElement &docElem, QSizeF &viewboxSize )
const 326 if ( docElem.tagName() == QLatin1String(
"svg" ) && docElem.hasAttribute( QStringLiteral(
"viewBox" ) ) )
328 viewBox = docElem.attribute( QStringLiteral(
"viewBox" ), QString() );
330 else if ( docElem.tagName() == QLatin1String(
"svg" ) && docElem.hasAttribute( QStringLiteral(
"viewbox" ) ) )
332 viewBox = docElem.attribute( QStringLiteral(
"viewbox" ), QString() );
336 QDomElement svgElem = docElem.firstChildElement( QStringLiteral(
"svg" ) );
337 if ( !svgElem.isNull() )
339 if ( svgElem.hasAttribute( QStringLiteral(
"viewBox" ) ) )
340 viewBox = svgElem.attribute( QStringLiteral(
"viewBox" ), QString() );
341 else if ( svgElem.hasAttribute( QStringLiteral(
"viewbox" ) ) )
342 viewBox = svgElem.attribute( QStringLiteral(
"viewbox" ), QString() );
347 if ( viewBox.isEmpty() )
351 QStringList parts = viewBox.split(
' ' );
352 if ( parts.count() != 4 )
355 bool heightOk =
false;
356 double height = parts.at( 3 ).toDouble( &heightOk );
358 bool widthOk =
false;
359 double width = parts.at( 2 ).toDouble( &widthOk );
363 viewboxSize = QSizeF( width, height );
364 return width / entry->size;
373 return getContent( path, mMissingSvg, mFetchingSvg, blocking );
380 QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString();
381 if ( !contentType.startsWith( QLatin1String(
"image/svg+xml" ), Qt::CaseInsensitive )
382 && !contentType.startsWith( QLatin1String(
"text/plain" ), Qt::CaseInsensitive ) )
390 void QgsSvgCache::cacheImage( QgsSvgCacheEntry *entry )
397 entry->image.reset();
401 QSize imageSize = sizeForImage( *entry, viewBoxSize, scaledSize );
404 std::unique_ptr< QImage > image = qgis::make_unique< QImage >( imageSize, QImage::Format_ARGB32_Premultiplied );
407 QPainter p( image.get() );
408 QSvgRenderer r( entry->svgContent );
409 if (
qgsDoubleNear( viewBoxSize.width(), viewBoxSize.height() ) )
415 QSizeF s( viewBoxSize );
416 s.scale( scaledSize.width(), scaledSize.height(), Qt::KeepAspectRatio );
417 QRectF rect( ( imageSize.width() - s.width() ) / 2, ( imageSize.height() - s.height() ) / 2, s.width(), s.height() );
418 r.render( &p, rect );
421 mTotalSize += ( image->width() * image->height() * 32 );
422 entry->image = std::move( image );
425 void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry,
bool forceVectorOutput )
427 Q_UNUSED( forceVectorOutput )
433 entry->picture.reset();
435 bool isFixedAR = entry->fixedAspectRatio > 0;
438 std::unique_ptr< QPicture > picture = qgis::make_unique< QPicture >();
440 QSvgRenderer r( entry->svgContent );
441 double hwRatio = 1.0;
442 if ( r.viewBoxF().width() > 0 )
446 hwRatio = entry->fixedAspectRatio;
450 hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
454 double wSize = entry->size;
455 double hSize = wSize * hwRatio;
457 QSizeF s( r.viewBoxF().size() );
458 s.scale( wSize, hSize, isFixedAR ? Qt::IgnoreAspectRatio : Qt::KeepAspectRatio );
459 rect = QRectF( -s.width() / 2.0, -s.height() / 2.0, s.width(), s.height() );
461 QPainter p( picture.get() );
462 r.render( &p, rect );
463 entry->picture = std::move( picture );
467 QgsSvgCacheEntry *QgsSvgCache::cacheEntry(
const QString &path,
double size,
const QColor &fill,
const QColor &stroke,
double strokeWidth,
468 double widthScaleFactor,
double fixedAspectRatio,
bool blocking )
470 QgsSvgCacheEntry *currentEntry =
findExistingEntry(
new QgsSvgCacheEntry( path, size, strokeWidth, widthScaleFactor, fill, stroke, fixedAspectRatio ) );
472 if ( currentEntry->svgContent.isEmpty() )
474 replaceParamsAndCacheSvg( currentEntry, blocking );
481 void QgsSvgCache::replaceElemParams( QDomElement &elem,
const QColor &fill,
const QColor &stroke,
double strokeWidth )
489 QDomNamedNodeMap attributes = elem.attributes();
490 int nAttributes = attributes.count();
491 for (
int i = 0; i < nAttributes; ++i )
493 QDomAttr attribute = attributes.item( i ).toAttr();
495 if ( attribute.name().compare( QLatin1String(
"style" ), Qt::CaseInsensitive ) == 0 )
498 QString newAttributeString;
500 QStringList entryList = attribute.value().split(
';' );
501 QStringList::const_iterator entryIt = entryList.constBegin();
502 for ( ; entryIt != entryList.constEnd(); ++entryIt )
504 QStringList keyValueSplit = entryIt->split(
':' );
505 if ( keyValueSplit.size() < 2 )
509 const QString key = keyValueSplit.at( 0 );
510 QString value = keyValueSplit.at( 1 );
511 QString newValue = value;
512 value = value.trimmed().toLower();
514 if ( value.startsWith( QLatin1String(
"param(fill)" ) ) )
516 newValue = fill.name();
518 else if ( value.startsWith( QLatin1String(
"param(fill-opacity)" ) ) )
520 newValue = QString::number( fill.alphaF() );
522 else if ( value.startsWith( QLatin1String(
"param(outline)" ) ) )
524 newValue = stroke.name();
526 else if ( value.startsWith( QLatin1String(
"param(outline-opacity)" ) ) )
528 newValue = QString::number( stroke.alphaF() );
530 else if ( value.startsWith( QLatin1String(
"param(outline-width)" ) ) )
532 newValue = QString::number( strokeWidth );
535 if ( entryIt != entryList.constBegin() )
537 newAttributeString.append(
';' );
539 newAttributeString.append( key +
':' + newValue );
541 elem.setAttribute( attribute.name(), newAttributeString );
545 const QString value = attribute.value().trimmed().toLower();
546 if ( value.startsWith( QLatin1String(
"param(fill)" ) ) )
548 elem.setAttribute( attribute.name(), fill.name() );
550 else if ( value.startsWith( QLatin1String(
"param(fill-opacity)" ) ) )
552 elem.setAttribute( attribute.name(), fill.alphaF() );
554 else if ( value.startsWith( QLatin1String(
"param(outline)" ) ) )
556 elem.setAttribute( attribute.name(), stroke.name() );
558 else if ( value.startsWith( QLatin1String(
"param(outline-opacity)" ) ) )
560 elem.setAttribute( attribute.name(), stroke.alphaF() );
562 else if ( value.startsWith( QLatin1String(
"param(outline-width)" ) ) )
564 elem.setAttribute( attribute.name(), QString::number( strokeWidth ) );
569 QDomNodeList childList = elem.childNodes();
570 int nChildren = childList.count();
571 for (
int i = 0; i < nChildren; ++i )
573 QDomElement childElem = childList.at( i ).toElement();
574 replaceElemParams( childElem, fill, stroke, strokeWidth );
578 void QgsSvgCache::containsElemParams(
const QDomElement &elem,
bool &hasFillParam,
bool &hasDefaultFill, QColor &defaultFill,
579 bool &hasFillOpacityParam,
bool &hasDefaultFillOpacity,
double &defaultFillOpacity,
580 bool &hasStrokeParam,
bool &hasDefaultStroke, QColor &defaultStroke,
581 bool &hasStrokeWidthParam,
bool &hasDefaultStrokeWidth,
double &defaultStrokeWidth,
582 bool &hasStrokeOpacityParam,
bool &hasDefaultStrokeOpacity,
double &defaultStrokeOpacity )
const 590 if ( hasFillParam && hasStrokeParam && hasStrokeWidthParam && hasFillOpacityParam && hasStrokeOpacityParam )
596 QDomNamedNodeMap attributes = elem.attributes();
597 int nAttributes = attributes.count();
599 QStringList valueSplit;
600 for (
int i = 0; i < nAttributes; ++i )
602 QDomAttr attribute = attributes.item( i ).toAttr();
603 if ( attribute.name().compare( QLatin1String(
"style" ), Qt::CaseInsensitive ) == 0 )
606 QStringList entryList = attribute.value().split(
';' );
607 QStringList::const_iterator entryIt = entryList.constBegin();
608 for ( ; entryIt != entryList.constEnd(); ++entryIt )
610 QStringList keyValueSplit = entryIt->split(
':' );
611 if ( keyValueSplit.size() < 2 )
615 QString value = keyValueSplit.at( 1 );
616 valueSplit = value.split(
' ' );
617 if ( !hasFillParam && value.startsWith( QLatin1String(
"param(fill)" ) ) )
620 if ( valueSplit.size() > 1 )
622 defaultFill = QColor( valueSplit.at( 1 ) );
623 hasDefaultFill =
true;
626 else if ( !hasFillOpacityParam && value.startsWith( QLatin1String(
"param(fill-opacity)" ) ) )
628 hasFillOpacityParam =
true;
629 if ( valueSplit.size() > 1 )
632 double opacity = valueSplit.at( 1 ).toDouble( &ok );
635 defaultFillOpacity = opacity;
636 hasDefaultFillOpacity =
true;
640 else if ( !hasStrokeParam && value.startsWith( QLatin1String(
"param(outline)" ) ) )
642 hasStrokeParam =
true;
643 if ( valueSplit.size() > 1 )
645 defaultStroke = QColor( valueSplit.at( 1 ) );
646 hasDefaultStroke =
true;
649 else if ( !hasStrokeWidthParam && value.startsWith( QLatin1String(
"param(outline-width)" ) ) )
651 hasStrokeWidthParam =
true;
652 if ( valueSplit.size() > 1 )
654 defaultStrokeWidth = valueSplit.at( 1 ).toDouble();
655 hasDefaultStrokeWidth =
true;
658 else if ( !hasStrokeOpacityParam && value.startsWith( QLatin1String(
"param(outline-opacity)" ) ) )
660 hasStrokeOpacityParam =
true;
661 if ( valueSplit.size() > 1 )
664 double opacity = valueSplit.at( 1 ).toDouble( &ok );
667 defaultStrokeOpacity = opacity;
668 hasDefaultStrokeOpacity =
true;
676 QString value = attribute.value();
677 valueSplit = value.split(
' ' );
678 if ( !hasFillParam && value.startsWith( QLatin1String(
"param(fill)" ) ) )
681 if ( valueSplit.size() > 1 )
683 defaultFill = QColor( valueSplit.at( 1 ) );
684 hasDefaultFill =
true;
687 else if ( !hasFillOpacityParam && value.startsWith( QLatin1String(
"param(fill-opacity)" ) ) )
689 hasFillOpacityParam =
true;
690 if ( valueSplit.size() > 1 )
693 double opacity = valueSplit.at( 1 ).toDouble( &ok );
696 defaultFillOpacity = opacity;
697 hasDefaultFillOpacity =
true;
701 else if ( !hasStrokeParam && value.startsWith( QLatin1String(
"param(outline)" ) ) )
703 hasStrokeParam =
true;
704 if ( valueSplit.size() > 1 )
706 defaultStroke = QColor( valueSplit.at( 1 ) );
707 hasDefaultStroke =
true;
710 else if ( !hasStrokeWidthParam && value.startsWith( QLatin1String(
"param(outline-width)" ) ) )
712 hasStrokeWidthParam =
true;
713 if ( valueSplit.size() > 1 )
715 defaultStrokeWidth = valueSplit.at( 1 ).toDouble();
716 hasDefaultStrokeWidth =
true;
719 else if ( !hasStrokeOpacityParam && value.startsWith( QLatin1String(
"param(outline-opacity)" ) ) )
721 hasStrokeOpacityParam =
true;
722 if ( valueSplit.size() > 1 )
725 double opacity = valueSplit.at( 1 ).toDouble( &ok );
728 defaultStrokeOpacity = opacity;
729 hasDefaultStrokeOpacity =
true;
737 QDomNodeList childList = elem.childNodes();
738 int nChildren = childList.count();
739 for (
int i = 0; i < nChildren; ++i )
741 QDomElement childElem = childList.at( i ).toElement();
742 containsElemParams( childElem, hasFillParam, hasDefaultFill, defaultFill,
743 hasFillOpacityParam, hasDefaultFillOpacity, defaultFillOpacity,
744 hasStrokeParam, hasDefaultStroke, defaultStroke,
745 hasStrokeWidthParam, hasDefaultStrokeWidth, defaultStrokeWidth,
746 hasStrokeOpacityParam, hasDefaultStrokeOpacity, defaultStrokeOpacity );
750 QSize QgsSvgCache::sizeForImage(
const QgsSvgCacheEntry &entry, QSizeF &viewBoxSize, QSizeF &scaledSize )
const 752 bool isFixedAR = entry.fixedAspectRatio > 0;
754 QSvgRenderer r( entry.svgContent );
755 double hwRatio = 1.0;
756 viewBoxSize = r.viewBoxF().size();
757 if ( viewBoxSize.width() > 0 )
761 hwRatio = entry.fixedAspectRatio;
765 hwRatio = viewBoxSize.height() / viewBoxSize.width();
770 scaledSize.setWidth( entry.size );
771 int wImgSize =
static_cast< int >( scaledSize.width() );
776 scaledSize.setHeight( scaledSize.width() * hwRatio );
777 int hImgSize =
static_cast< int >( scaledSize.height() );
782 return QSize( wImgSize, hImgSize );
785 QImage QgsSvgCache::imageFromCachedPicture(
const QgsSvgCacheEntry &entry )
const 789 QImage image( sizeForImage( entry, viewBoxSize, scaledSize ), QImage::Format_ARGB32_Premultiplied );
792 QPainter p( &image );
793 p.drawPicture( QPoint( 0, 0 ), *entry.picture );
QByteArray getContent(const QString &path, const QByteArray &missingContent, const QByteArray &fetchingContent, bool blocking=false) const
Gets the file content corresponding to the given path.
Abstract base class for file content caches, such as SVG or raster image caches.
static QString defaultThemePath()
Returns the path to the default theme directory.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false)
Gets SVG as QImage.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an svg file contains parameters for fill, stroke color, stroke width.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Base class for entries in a QgsAbstractContentCache.
void remoteContentFetched(const QString &url)
Emitted when the cache has finished retrieving content from a remote url.
QByteArray svgContent(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false)
Gets SVG content.
QSizeF svgViewboxSize(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false)
Calculates the viewbox size of a (possibly cached) SVG file.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QByteArray getImageData(const QString &path, bool blocking=false) const
Gets the SVG content corresponding to the given path.
QgsSvgCache(QObject *parent=nullptr)
Constructor for QgsSvgCache.
QgsSvgCacheEntry * findExistingEntry(QgsSvgCacheEntry *entryTemplate)
Returns the existing entry from the cache which matches entryTemplate (deleting entryTemplate when do...
void remoteSvgFetched(const QString &url)
Emitted when the cache has finished retrieving an SVG file from a remote url.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false)
Gets SVG as QPicture&.
long mMaxCacheSize
Maximum cache size.
long mTotalSize
Estimated total size of all cached content.
void trimToMaximumSize()
Removes the least used cache entries until the maximum cache size is under the predefined size limit...
bool checkReply(QNetworkReply *reply, const QString &path) const override
Runs additional checks on a network reply to ensure that the reply content is consistent with that re...