Skip to content

Commit

Permalink
Cleanup QgsSvgCache API
Browse files Browse the repository at this point in the history
- Remove QgsSvgCacheEntry from public API (is an internal detail only)
- Modernize code
- Make protected QgsSvgCache members private, since this class is not
designed to be subclassed
  • Loading branch information
nyalldawson committed Oct 31, 2017
1 parent a6eea72 commit b07f675
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 133 deletions.
3 changes: 3 additions & 0 deletions doc/api_break.dox
Expand Up @@ -319,6 +319,7 @@ should now call QgsCoordinateReferenceSystem::invalidateCache() and QgsCoordinat
- QgsEditorWidgetConfig was removed. Use QVariantMap instead.
- QgsScaleExpression. Use QgsProperty with a QgsSizeScalePropertyTransformer instead.
- QgsSvgAnnotationItem. Use QgsSvgAnnotation instead.
- QgsSvgCacheEntry. This is an internal class and is no longer exposed to public API.
- QgsSymbologyV2Conversion was removed. Reading of renderers from pre-1.0 versions is not supported anymore.
- QgsTextAnnotationItem. Use QgsTextAnnotation instead.
- QgsTransectSample. This class was unused and unmaintained.
Expand Down Expand Up @@ -2289,6 +2290,8 @@ QgsSvgCache {#qgis_api_break_3_0_QgsSvgCache}
- containsParamsV2() was removed. Use containsParamsV3() instead.
- The rasterScaleFactor parameter was removed from all methods
- svgAsImage(), svgAsPicture(), svgViewboxSize(), svgContent(), insertSvg(), cacheEntry() only accept absolute path to SVG file (relative paths will not be resolved).
- The protected member insertSvg() was made private. QgsSvgCache is not intended to be subclassed.


QgsSvgCacheEntry {#qgis_api_break_3_0_QgsSvgCacheEntry}
----------------
Expand Down
96 changes: 0 additions & 96 deletions python/core/symbology/qgssvgcache.sip
Expand Up @@ -11,69 +11,6 @@



class QgsSvgCacheEntry
{

%TypeHeaderCode
#include "qgssvgcache.h"
%End
public:

QgsSvgCacheEntry();

QgsSvgCacheEntry( const QString &path, double size, double strokeWidth, double widthScaleFactor, const QColor &fill, const QColor &stroke,
double fixedAspectRatio = 0 ) ;
%Docstring
Constructor.
\param path Absolute path to SVG file (relative paths are not resolved).
\param size
\param strokeWidth width of stroke
\param widthScaleFactor width scale factor
\param fill color of fill
\param stroke color of stroke
\param fixedAspectRatio fixed aspect ratio (optional)
%End
~QgsSvgCacheEntry();


QString path;
%Docstring
Absolute path to SVG file
%End
double size;
double strokeWidth;
double widthScaleFactor;

double fixedAspectRatio;
%Docstring
Fixed aspect ratio
%End

QSizeF viewboxSize;
%Docstring
SVG viewbox size.
.. versionadded:: 2.14
%End

QColor fill;
QColor stroke;
QImage *image;
QPicture *picture;
QByteArray svgContent;

QgsSvgCacheEntry *nextEntry;
QgsSvgCacheEntry *previousEntry;

bool operator==( const QgsSvgCacheEntry &other ) const;
int dataSize() const;
%Docstring
Return memory usage in bytes
:rtype: int
%End

private:
QgsSvgCacheEntry( const QgsSvgCacheEntry &rh );
};

class QgsSvgCache : QObject
{
Expand Down Expand Up @@ -200,39 +137,6 @@ Get SVG content
Emit a signal to be caught by qgisapp and display a msg on status bar
%End

protected:

QgsSvgCacheEntry *insertSvg( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, double fixedAspectRatio = 0 );
%Docstring
Creates new cache entry and returns pointer to it
\param path Absolute path to SVG file
\param size size of cached image
\param fill color of fill
\param stroke color of stroke
\param strokeWidth width of stroke
\param widthScaleFactor width scale factor
\param fixedAspectRatio fixed aspect ratio (optional)
:rtype: QgsSvgCacheEntry
%End

void replaceParamsAndCacheSvg( QgsSvgCacheEntry *entry );
void cacheImage( QgsSvgCacheEntry *entry );
void cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput = false );
QgsSvgCacheEntry *cacheEntry( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
double widthScaleFactor, double fixedAspectRatio = 0 );
%Docstring
Returns entry from cache or creates a new entry if it does not exist already
:rtype: QgsSvgCacheEntry
%End

void trimToMaximumSize();
%Docstring
Removes the least used items until the maximum size is under the limit
%End

void takeEntryFromList( QgsSvgCacheEntry *entry );

};

/************************************************************************
Expand Down
38 changes: 12 additions & 26 deletions src/core/symbology/qgssvgcache.cpp
Expand Up @@ -36,12 +36,7 @@
#include <QNetworkReply>
#include <QNetworkRequest>

QgsSvgCacheEntry::QgsSvgCacheEntry()
: path( QString() )
, fill( Qt::black )
, stroke( Qt::black )
{
}
///@cond PRIVATE

QgsSvgCacheEntry::QgsSvgCacheEntry( const QString &p, double s, double ow, double wsf, const QColor &fi, const QColor &ou, double far )
: path( p )
Expand All @@ -54,13 +49,6 @@ QgsSvgCacheEntry::QgsSvgCacheEntry( const QString &p, double s, double ow, doubl
{
}


QgsSvgCacheEntry::~QgsSvgCacheEntry()
{
delete image;
delete picture;
}

bool QgsSvgCacheEntry::operator==( const QgsSvgCacheEntry &other ) const
{
return other.path == path && qgsDoubleNear( other.size, size ) && qgsDoubleNear( other.strokeWidth, strokeWidth ) && qgsDoubleNear( other.widthScaleFactor, widthScaleFactor )
Expand All @@ -80,6 +68,8 @@ int QgsSvgCacheEntry::dataSize() const
}
return size;
}
///@endcond


QgsSvgCache::QgsSvgCache( QObject *parent )
: QObject( parent )
Expand Down Expand Up @@ -127,9 +117,7 @@ QImage QgsSvgCache::svgAsImage( const QString &file, double size, const QColor &
if ( cachedDataSize > MAXIMUM_SIZE / 2 )
{
fitsInCache = false;
delete currentEntry->image;
currentEntry->image = nullptr;
//currentEntry->image = new QImage( 0, 0 );
currentEntry->image.reset();

// instead cache picture
if ( !currentEntry->picture )
Expand Down Expand Up @@ -488,18 +476,17 @@ void QgsSvgCache::cacheImage( QgsSvgCacheEntry *entry )
return;
}

delete entry->image;
entry->image = nullptr;
entry->image.reset();

QSizeF viewBoxSize;
QSizeF scaledSize;
QSize imageSize = sizeForImage( *entry, viewBoxSize, scaledSize );

// cast double image sizes to int for QImage
QImage *image = new QImage( imageSize, QImage::Format_ARGB32_Premultiplied );
std::unique_ptr< QImage > image = qgis::make_unique< QImage >( imageSize, QImage::Format_ARGB32_Premultiplied );
image->fill( 0 ); // transparent background

QPainter p( image );
QPainter p( image.get() );
QSvgRenderer r( entry->svgContent );
if ( qgsDoubleNear( viewBoxSize.width(), viewBoxSize.height() ) )
{
Expand All @@ -513,8 +500,8 @@ void QgsSvgCache::cacheImage( QgsSvgCacheEntry *entry )
r.render( &p, rect );
}

entry->image = image;
mTotalSize += ( image->width() * image->height() * 32 );
entry->image = std::move( image );
}

void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput )
Expand All @@ -525,13 +512,12 @@ void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput
return;
}

delete entry->picture;
entry->picture = nullptr;
entry->picture.reset();

bool isFixedAR = entry->fixedAspectRatio > 0;

//correct QPictures dpi correction
QPicture *picture = new QPicture();
std::unique_ptr< QPicture > picture = qgis::make_unique< QPicture >();
QRectF rect;
QSvgRenderer r( entry->svgContent );
double hwRatio = 1.0;
Expand All @@ -554,9 +540,9 @@ void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput
s.scale( wSize, hSize, isFixedAR ? Qt::IgnoreAspectRatio : Qt::KeepAspectRatio );
rect = QRectF( -s.width() / 2.0, -s.height() / 2.0, s.width(), s.height() );

QPainter p( picture );
QPainter p( picture.get() );
r.render( &p, rect );
entry->picture = picture;
entry->picture = std::move( picture );
mTotalSize += entry->picture->size();
}

Expand Down
27 changes: 16 additions & 11 deletions src/core/symbology/qgssvgcache.h
Expand Up @@ -34,6 +34,10 @@ class QDomElement;
class QImage;
class QPicture;

#ifndef SIP_RUN

///@cond PRIVATE

/**
* \ingroup core
* \class QgsSvgCacheEntry
Expand All @@ -42,7 +46,7 @@ class CORE_EXPORT QgsSvgCacheEntry
{
public:

QgsSvgCacheEntry();
QgsSvgCacheEntry() = default;

/**
* Constructor.
Expand All @@ -56,7 +60,6 @@ class CORE_EXPORT QgsSvgCacheEntry
*/
QgsSvgCacheEntry( const QString &path, double size, double strokeWidth, double widthScaleFactor, const QColor &fill, const QColor &stroke,
double fixedAspectRatio = 0 ) ;
~QgsSvgCacheEntry();

//! QgsSvgCacheEntry cannot be copied.
QgsSvgCacheEntry( const QgsSvgCacheEntry &rh ) = delete;
Expand All @@ -78,10 +81,10 @@ class CORE_EXPORT QgsSvgCacheEntry
*/
QSizeF viewboxSize;

QColor fill;
QColor stroke;
QImage *image = nullptr;
QPicture *picture = nullptr;
QColor fill = Qt::black;
QColor stroke = Qt::black;
std::unique_ptr< QImage > image;
std::unique_ptr< QPicture > picture;
//content (with params replaced)
QByteArray svgContent;

Expand All @@ -101,6 +104,9 @@ class CORE_EXPORT QgsSvgCacheEntry

};

///@endcond
#endif

/**
* \ingroup core
* A cache for images / pictures derived from svg files. This class supports parameter replacement in svg files
Expand Down Expand Up @@ -211,7 +217,10 @@ class CORE_EXPORT QgsSvgCache : public QObject
//! Emit a signal to be caught by qgisapp and display a msg on status bar
void statusChanged( const QString &statusQString );

protected:
private slots:
void downloadProgress( qint64, qint64 );

private:

/**
* Creates new cache entry and returns pointer to it
Expand Down Expand Up @@ -239,10 +248,6 @@ class CORE_EXPORT QgsSvgCache : public QObject
//Removes entry from the ordered list (but does not delete the entry itself)
void takeEntryFromList( QgsSvgCacheEntry *entry );

private slots:
void downloadProgress( qint64, qint64 );

private:
//! Entry pointers accessible by file name
QMultiHash< QString, QgsSvgCacheEntry * > mEntryLookup;
//! Estimated total size of all images, pictures and svgContent
Expand Down

0 comments on commit b07f675

Please sign in to comment.