|
19 | 19 | #include <QDomDocument>
|
20 | 20 | #include <QFile>
|
21 | 21 | #include <QImage>
|
| 22 | +#include <QPainter> |
22 | 23 | #include <QPicture>
|
| 24 | +#include <QSvgRenderer> |
23 | 25 |
|
24 | 26 | QgsSvgCacheEntry::QgsSvgCacheEntry(): file( QString() ), size( 0 ), outlineWidth( 0 ), widthScaleFactor( 1.0 ), rasterScaleFactor( 1.0 ), fill( Qt::black ),
|
25 | 27 | outline( Qt::black ), image( 0 ), picture( 0 )
|
@@ -69,41 +71,35 @@ QgsSvgCache::QgsSvgCache()
|
69 | 71 |
|
70 | 72 | QgsSvgCache::~QgsSvgCache()
|
71 | 73 | {
|
| 74 | + QMap< QDateTime, QgsSvgCacheEntry* >::iterator it = mEntries.begin(); |
| 75 | + for(; it != mEntries.end(); ++it ) |
| 76 | + { |
| 77 | + delete it.value(); |
| 78 | + } |
72 | 79 | }
|
73 | 80 |
|
74 | 81 |
|
75 | 82 | const QImage& QgsSvgCache::svgAsImage( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
|
76 | 83 | double widthScaleFactor, double rasterScaleFactor )
|
77 | 84 | {
|
| 85 | + QgsSvgCacheEntry* currentEntry = this->cacheEntry( file, size, fill, outline, outlineWidth, widthScaleFactor, rasterScaleFactor ); |
| 86 | + |
| 87 | + //if current entry image is 0: cache image for entry |
| 88 | + //update stats for memory usage |
| 89 | + if( !currentEntry->image ) |
| 90 | + { |
| 91 | + cacheImage( currentEntry ); |
| 92 | + } |
78 | 93 |
|
| 94 | + //update lastUsed with current date time |
| 95 | + |
| 96 | + return *( currentEntry->image ); |
79 | 97 | }
|
80 | 98 |
|
81 | 99 | const QPicture& QgsSvgCache::svgAsPicture( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth,
|
82 | 100 | double widthScaleFactor, double rasterScaleFactor )
|
83 | 101 | {
|
84 |
| - //search entries in mEntryLookup |
85 |
| - QgsSvgCacheEntry* currentEntry = 0; |
86 |
| - QList<QgsSvgCacheEntry*> entries = mEntryLookup.values( file ); |
87 |
| - |
88 |
| - QList<QgsSvgCacheEntry*>::iterator entryIt = entries.begin(); |
89 |
| - for(; entryIt != entries.end(); ++entryIt ) |
90 |
| - { |
91 |
| - QgsSvgCacheEntry* cacheEntry = *entryIt; |
92 |
| - if( cacheEntry->file == file && cacheEntry->size == size && cacheEntry->fill == fill && cacheEntry->outline == outline && |
93 |
| - cacheEntry->outlineWidth == outlineWidth && cacheEntry->widthScaleFactor == widthScaleFactor && cacheEntry->rasterScaleFactor == rasterScaleFactor) |
94 |
| - { |
95 |
| - currentEntry = cacheEntry; |
96 |
| - break; |
97 |
| - } |
98 |
| - } |
99 |
| - |
100 |
| - |
101 |
| - //if not found: create new entry |
102 |
| - //cache and replace params in svg content |
103 |
| - if( !currentEntry ) |
104 |
| - { |
105 |
| - currentEntry = insertSVG( file, size, fill, outline, outlineWidth, widthScaleFactor, rasterScaleFactor ); |
106 |
| - } |
| 102 | + QgsSvgCacheEntry* currentEntry = this->cacheEntry( file, size, fill, outline, outlineWidth, widthScaleFactor, rasterScaleFactor ); |
107 | 103 |
|
108 | 104 | //if current entry image is 0: cache image for entry
|
109 | 105 | //update stats for memory usage
|
@@ -156,9 +152,75 @@ void QgsSvgCache::replaceParamsAndCacheSvg( QgsSvgCacheEntry* entry )
|
156 | 152 |
|
157 | 153 | void QgsSvgCache::cacheImage( QgsSvgCacheEntry* entry )
|
158 | 154 | {
|
| 155 | + if( !entry ) |
| 156 | + { |
| 157 | + return; |
| 158 | + } |
| 159 | + |
| 160 | + delete entry->image; |
| 161 | + entry->image = 0; |
| 162 | + |
| 163 | + double imageSize = entry->size * entry->widthScaleFactor * entry->rasterScaleFactor; |
| 164 | + QImage* image = new QImage( imageSize, imageSize, QImage::Format_ARGB32_Premultiplied ); |
| 165 | + image->fill( 0 ); // transparent background |
| 166 | + |
| 167 | + //rasterise byte array to image |
| 168 | + QPainter p( image ); |
| 169 | + QSvgRenderer r( entry->svgContent ); |
| 170 | + r.render( &p ); |
| 171 | + |
| 172 | + entry->image = image; |
159 | 173 | }
|
160 | 174 |
|
161 | 175 | void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry )
|
162 | 176 | {
|
| 177 | + if( !entry ) |
| 178 | + { |
| 179 | + return; |
| 180 | + } |
| 181 | + |
| 182 | + delete entry->picture; |
| 183 | + entry->picture = 0; |
| 184 | + |
| 185 | + //correct QPictures dpi correction |
| 186 | + QPicture* picture = new QPicture(); |
| 187 | + double dpi = entry->widthScaleFactor * 25.4 * entry->rasterScaleFactor; |
| 188 | + double pictureSize = entry->size * entry->widthScaleFactor / dpi * picture->logicalDpiX(); |
| 189 | + QRectF rect( QPointF( -pictureSize / 2.0, -pictureSize / 2.0 ), QSizeF( pictureSize, pictureSize ) ); |
| 190 | + |
| 191 | + |
| 192 | + QSvgRenderer renderer( entry->svgContent ); |
| 193 | + QPainter painter( picture ); |
| 194 | + renderer.render( &painter, rect ); |
| 195 | + entry->picture = picture; |
| 196 | +} |
| 197 | + |
| 198 | +QgsSvgCacheEntry* QgsSvgCache::cacheEntry( const QString& file, double size, const QColor& fill, const QColor& outline, double outlineWidth, |
| 199 | + double widthScaleFactor, double rasterScaleFactor ) |
| 200 | +{ |
| 201 | + //search entries in mEntryLookup |
| 202 | + QgsSvgCacheEntry* currentEntry = 0; |
| 203 | + QList<QgsSvgCacheEntry*> entries = mEntryLookup.values( file ); |
| 204 | + |
| 205 | + QList<QgsSvgCacheEntry*>::iterator entryIt = entries.begin(); |
| 206 | + for(; entryIt != entries.end(); ++entryIt ) |
| 207 | + { |
| 208 | + QgsSvgCacheEntry* cacheEntry = *entryIt; |
| 209 | + if( cacheEntry->file == file && cacheEntry->size == size && cacheEntry->fill == fill && cacheEntry->outline == outline && |
| 210 | + cacheEntry->outlineWidth == outlineWidth && cacheEntry->widthScaleFactor == widthScaleFactor && cacheEntry->rasterScaleFactor == rasterScaleFactor) |
| 211 | + { |
| 212 | + currentEntry = cacheEntry; |
| 213 | + break; |
| 214 | + } |
| 215 | + } |
| 216 | + |
| 217 | + |
| 218 | + //if not found: create new entry |
| 219 | + //cache and replace params in svg content |
| 220 | + if( !currentEntry ) |
| 221 | + { |
| 222 | + currentEntry = insertSVG( file, size, fill, outline, outlineWidth, widthScaleFactor, rasterScaleFactor ); |
| 223 | + } |
| 224 | + return currentEntry; |
163 | 225 | }
|
164 | 226 |
|
0 commit comments