16
16
***************************************************************************/
17
17
18
18
#include " qgssvgcache.h"
19
+ #include " qgis.h"
19
20
#include " qgslogger.h"
20
21
#include " qgsnetworkaccessmanager.h"
21
22
#include " qgsmessagelog.h"
33
34
#include < QNetworkReply>
34
35
#include < QNetworkRequest>
35
36
36
- QgsSvgCacheEntry::QgsSvgCacheEntry (): file( QString() ), size( 0 ), outlineWidth( 0 ), widthScaleFactor( 1.0 ), rasterScaleFactor( 1.0 ), fill( Qt::black ),
37
+ QgsSvgCacheEntry::QgsSvgCacheEntry (): file( QString() ), size( 0.0 ), outlineWidth( 0 ), widthScaleFactor( 1.0 ), rasterScaleFactor( 1.0 ), fill( Qt::black ),
37
38
outline( Qt::black ), image( 0 ), picture( 0 )
38
39
{
39
40
}
@@ -107,28 +108,52 @@ QgsSvgCache::~QgsSvgCache()
107
108
}
108
109
109
110
110
- const QImage& QgsSvgCache::svgAsImage ( const QString& file, int size, const QColor& fill, const QColor& outline , double outlineWidth,
111
- double widthScaleFactor, double rasterScaleFactor )
111
+ const QImage& QgsSvgCache::svgAsImage ( const QString& file, double size, const QColor& fill, const QColor& outline , double outlineWidth,
112
+ double widthScaleFactor, double rasterScaleFactor, bool & fitsInCache )
112
113
{
114
+ fitsInCache = true ;
113
115
QgsSvgCacheEntry* currentEntry = cacheEntry ( file, size, fill, outline , outlineWidth, widthScaleFactor, rasterScaleFactor );
114
116
115
117
// if current entry image is 0: cache image for entry
118
+ // checks to see if image will fit into cache
116
119
// update stats for memory usage
117
120
if ( !currentEntry->image )
118
121
{
119
- cacheImage ( currentEntry );
122
+ QSvgRenderer r ( currentEntry->svgContent );
123
+ double hwRatio = 1.0 ;
124
+ if ( r.viewBoxF ().width () > 0 )
125
+ {
126
+ hwRatio = r.viewBoxF ().height () / r.viewBoxF ().width ();
127
+ }
128
+ long cachedDataSize = 0 ;
129
+ cachedDataSize += currentEntry->svgContent .size ();
130
+ cachedDataSize += ( int )( currentEntry->size * currentEntry->size * hwRatio * 32 );
131
+ if ( cachedDataSize > mMaximumSize / 2 )
132
+ {
133
+ fitsInCache = false ;
134
+ delete currentEntry->image ;
135
+ currentEntry->image = 0 ;
136
+ // currentEntry->image = new QImage( 0, 0 );
137
+
138
+ // instead cache picture
139
+ cachePicture ( currentEntry );
140
+ }
141
+ else
142
+ {
143
+ cacheImage ( currentEntry );
144
+ }
120
145
trimToMaximumSize ();
121
146
}
122
147
123
148
return *( currentEntry->image );
124
149
}
125
150
126
- const QPicture& QgsSvgCache::svgAsPicture ( const QString& file, int size, const QColor& fill, const QColor& outline , double outlineWidth,
151
+ const QPicture& QgsSvgCache::svgAsPicture ( const QString& file, double size, const QColor& fill, const QColor& outline , double outlineWidth,
127
152
double widthScaleFactor, double rasterScaleFactor )
128
153
{
129
154
QgsSvgCacheEntry* currentEntry = cacheEntry ( file, size, fill, outline , outlineWidth, widthScaleFactor, rasterScaleFactor );
130
155
131
- // if current entry image is 0: cache image for entry
156
+ // if current entry picture is 0: cache picture for entry
132
157
// update stats for memory usage
133
158
if ( !currentEntry->picture )
134
159
{
@@ -139,7 +164,7 @@ const QPicture& QgsSvgCache::svgAsPicture( const QString& file, int size, const
139
164
return *( currentEntry->picture );
140
165
}
141
166
142
- QgsSvgCacheEntry* QgsSvgCache::insertSVG ( const QString& file, int size, const QColor& fill, const QColor& outline , double outlineWidth,
167
+ QgsSvgCacheEntry* QgsSvgCache::insertSVG ( const QString& file, double size, const QColor& fill, const QColor& outline , double outlineWidth,
143
168
double widthScaleFactor, double rasterScaleFactor )
144
169
{
145
170
QgsSvgCacheEntry* entry = new QgsSvgCacheEntry ( file, size, outlineWidth, widthScaleFactor, rasterScaleFactor, fill, outline );
@@ -326,21 +351,38 @@ void QgsSvgCache::cacheImage( QgsSvgCacheEntry* entry )
326
351
delete entry->image ;
327
352
entry->image = 0 ;
328
353
329
- int imageSize = entry->size ;
330
- QImage* image = new QImage ( imageSize, imageSize, QImage::Format_ARGB32_Premultiplied );
354
+ QSvgRenderer r ( entry->svgContent );
355
+ double hwRatio = 1.0 ;
356
+ if ( r.viewBoxF ().width () > 0 )
357
+ {
358
+ hwRatio = r.viewBoxF ().height () / r.viewBoxF ().width ();
359
+ }
360
+ double wSize = entry->size ;
361
+ int wImgSize = ( int )wSize;
362
+ if ( wImgSize < 1 )
363
+ {
364
+ wImgSize = 1 ;
365
+ }
366
+ double hSize = wSize * hwRatio;
367
+ int hImgSize = ( int )hSize;
368
+ if ( hImgSize < 1 )
369
+ {
370
+ hImgSize = 1 ;
371
+ }
372
+ // cast double image sizes to int for QImage
373
+ QImage* image = new QImage ( wImgSize, hImgSize, QImage::Format_ARGB32_Premultiplied );
331
374
image->fill ( 0 ); // transparent background
332
375
333
376
QPainter p ( image );
334
- QSvgRenderer r ( entry->svgContent );
335
- if ( r.viewBox ().width () == r.viewBox ().height () )
377
+ if ( r.viewBoxF ().width () == r.viewBoxF ().height () )
336
378
{
337
379
r.render ( &p );
338
380
}
339
381
else
340
382
{
341
- QSize s ( r.viewBox ().size () );
342
- s.scale ( imageSize, imageSize , Qt::KeepAspectRatio );
343
- QRect rect (( imageSize - s.width () ) / 2 , ( imageSize - s.height () ) / 2 , s.width (), s.height () );
383
+ QSizeF s ( r.viewBoxF ().size () );
384
+ s.scale ( wSize, hSize , Qt::KeepAspectRatio );
385
+ QRectF rect (( wImgSize - s.width () ) / 2 , ( hImgSize - s.height () ) / 2 , s.width (), s.height () );
344
386
r.render ( &p, rect );
345
387
}
346
388
@@ -360,18 +402,39 @@ void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry )
360
402
361
403
// correct QPictures dpi correction
362
404
QPicture* picture = new QPicture ();
363
- double pictureSize = entry->size / 25.4 / ( entry->rasterScaleFactor * entry->widthScaleFactor ) * picture->logicalDpiX ();
364
- QRectF rect ( QPointF ( -pictureSize / 2.0 , -pictureSize / 2.0 ), QSizeF ( pictureSize, pictureSize ) );
365
-
405
+ QRectF rect;
406
+ QSvgRenderer r ( entry->svgContent );
407
+ double hwRatio = 1.0 ;
408
+ if ( r.viewBoxF ().width () > 0 )
409
+ {
410
+ hwRatio = r.viewBoxF ().height () / r.viewBoxF ().width ();
411
+ }
412
+ bool drawOnScreen = doubleNear ( entry->rasterScaleFactor , 1.0 , 0.1 );
413
+ if ( drawOnScreen )
414
+ {
415
+ // fix to ensure rotated symbols scale with composer page (i.e. not map item) zoom
416
+ double wSize = entry->size ;
417
+ double hSize = wSize * hwRatio;
418
+ QSizeF s ( r.viewBoxF ().size () );
419
+ s.scale ( wSize, hSize, Qt::KeepAspectRatio );
420
+ rect = QRectF ( -s.width () / 2.0 , -s.height () / 2.0 , s.width (), s.height () );
421
+ }
422
+ else
423
+ {
424
+ // output for print or image saving @ specific dpi
425
+ double scaledSize = entry->size / 25.4 / ( entry->rasterScaleFactor * entry->widthScaleFactor );
426
+ double wSize = scaledSize * picture->logicalDpiX ();
427
+ double hSize = scaledSize * picture->logicalDpiY () * r.viewBoxF ().height () / r.viewBoxF ().width ();
428
+ rect = QRectF ( QPointF ( -wSize / 2.0 , -hSize / 2.0 ), QSizeF ( wSize, hSize ) );
429
+ }
366
430
367
- QSvgRenderer renderer ( entry->svgContent );
368
- QPainter painter ( picture );
369
- renderer.render ( &painter, rect );
431
+ QPainter p ( picture );
432
+ r.render ( &p, rect );
370
433
entry->picture = picture;
371
434
mTotalSize += entry->picture ->size ();
372
435
}
373
436
374
- QgsSvgCacheEntry* QgsSvgCache::cacheEntry ( const QString& file, int size, const QColor& fill, const QColor& outline , double outlineWidth,
437
+ QgsSvgCacheEntry* QgsSvgCache::cacheEntry ( const QString& file, double size, const QColor& fill, const QColor& outline , double outlineWidth,
375
438
double widthScaleFactor, double rasterScaleFactor )
376
439
{
377
440
// search entries in mEntryLookup
0 commit comments