Skip to content

Commit 740ccbe

Browse files
dmarteaurldhont
authored andcommitted
Add fixedAspectRatio in QgsSvgCacheEntry and compute image size accordingly
1 parent f9f5aaf commit 740ccbe

File tree

3 files changed

+74
-32
lines changed

3 files changed

+74
-32
lines changed

python/core/symbology/qgssvgcache.sip

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ class QgsSvgCacheEntry
1818
#include "qgssvgcache.h"
1919
%End
2020
public:
21+
2122
QgsSvgCacheEntry();
2223

23-
QgsSvgCacheEntry( const QString &path, double size, double strokeWidth, double widthScaleFactor, const QColor &fill, const QColor &stroke );
24+
QgsSvgCacheEntry( const QString &path, double size, double strokeWidth, double widthScaleFactor, const QColor &fill, const QColor &stroke,
25+
double fixedAspectRatio = 0 ) ;
2426
%Docstring
2527
Constructor.
2628
\param path Absolute path to SVG file (relative paths are not resolved).
@@ -29,6 +31,7 @@ class QgsSvgCacheEntry
2931
\param widthScaleFactor width scale factor
3032
\param fill color of fill
3133
\param stroke color of stroke
34+
\param fixedAspectRatio fixed aspect ratio (optional)
3235
%End
3336
~QgsSvgCacheEntry();
3437

@@ -41,6 +44,11 @@ Absolute path to SVG file
4144
double strokeWidth;
4245
double widthScaleFactor;
4346

47+
double fixedAspectRatio;
48+
%Docstring
49+
Fixed aspect ratio
50+
%End
51+
4452
QSizeF viewboxSize;
4553
%Docstring
4654
SVG viewbox size.
@@ -91,7 +99,7 @@ the parameters 'fill-color', 'pen-color', 'outline-width', 'stroke-width'. E.g.
9199
~QgsSvgCache();
92100

93101
QImage svgAsImage( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
94-
double widthScaleFactor, bool &fitsInCache );
102+
double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio = 0 );
95103
%Docstring
96104
Get SVG as QImage.
97105
\param path Absolute path to SVG file.
@@ -105,7 +113,7 @@ the parameters 'fill-color', 'pen-color', 'outline-width', 'stroke-width'. E.g.
105113
%End
106114

107115
QPicture svgAsPicture( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
108-
double widthScaleFactor, bool forceVectorOutput = false );
116+
double widthScaleFactor, bool forceVectorOutput = false, double fixedAspectRatio = 0 );
109117
%Docstring
110118
Get SVG as QPicture&.
111119
\param path Absolute path to SVG file.
@@ -119,7 +127,7 @@ the parameters 'fill-color', 'pen-color', 'outline-width', 'stroke-width'. E.g.
119127
%End
120128

121129
QSizeF svgViewboxSize( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
122-
double widthScaleFactor );
130+
double widthScaleFactor, double fixedAspectRatio = 0 );
123131
%Docstring
124132
Calculates the viewbox size of a (possibly cached) SVG file.
125133
\param path Absolute path to SVG file.
@@ -177,7 +185,7 @@ Get image data
177185
%End
178186

179187
QByteArray svgContent( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
180-
double widthScaleFactor );
188+
double widthScaleFactor, double fixedAspectRatio = 0);
181189
%Docstring
182190
Get SVG content
183191
:rtype: QByteArray
@@ -192,7 +200,7 @@ Emit a signal to be caught by qgisapp and display a msg on status bar
192200
protected:
193201

194202
QgsSvgCacheEntry *insertSvg( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
195-
double widthScaleFactor );
203+
double widthScaleFactor, double fixedAspectRatio = 0 );
196204
%Docstring
197205
Creates new cache entry and returns pointer to it
198206
\param path Absolute path to SVG file
@@ -208,7 +216,7 @@ Emit a signal to be caught by qgisapp and display a msg on status bar
208216
void cacheImage( QgsSvgCacheEntry *entry );
209217
void cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput = false );
210218
QgsSvgCacheEntry *cacheEntry( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
211-
double widthScaleFactor );
219+
double widthScaleFactor, double fixedAspectRatio = 0 );
212220
%Docstring
213221
Returns entry from cache or creates a new entry if it does not exist already
214222
:rtype: QgsSvgCacheEntry

src/core/symbology/qgssvgcache.cpp

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ QgsSvgCacheEntry::QgsSvgCacheEntry()
4343
{
4444
}
4545

46-
QgsSvgCacheEntry::QgsSvgCacheEntry( const QString &p, double s, double ow, double wsf, const QColor &fi, const QColor &ou )
46+
QgsSvgCacheEntry::QgsSvgCacheEntry( const QString &p, double s, double ow, double wsf, const QColor &fi, const QColor &ou, double far )
4747
: path( p )
4848
, size( s )
4949
, strokeWidth( ow )
5050
, widthScaleFactor( wsf )
51+
, fixedAspectRatio( far )
5152
, fill( fi )
5253
, stroke( ou )
5354
{
@@ -93,12 +94,12 @@ QgsSvgCache::~QgsSvgCache()
9394

9495

9596
QImage QgsSvgCache::svgAsImage( const QString &file, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
96-
double widthScaleFactor, bool &fitsInCache )
97+
double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio )
9798
{
9899
QMutexLocker locker( &mMutex );
99100

100101
fitsInCache = true;
101-
QgsSvgCacheEntry *currentEntry = cacheEntry( file, size, fill, stroke, strokeWidth, widthScaleFactor );
102+
QgsSvgCacheEntry *currentEntry = cacheEntry( file, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio );
102103

103104
//if current entry image is 0: cache image for entry
104105
// checks to see if image will fit into cache
@@ -109,7 +110,14 @@ QImage QgsSvgCache::svgAsImage( const QString &file, double size, const QColor &
109110
double hwRatio = 1.0;
110111
if ( r.viewBoxF().width() > 0 )
111112
{
112-
hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
113+
if( currentEntry->fixedAspectRatio > 0 )
114+
{
115+
hwRatio = currentEntry->fixedAspectRatio;
116+
}
117+
else
118+
{
119+
hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
120+
}
113121
}
114122
long cachedDataSize = 0;
115123
cachedDataSize += currentEntry->svgContent.size();
@@ -138,11 +146,11 @@ QImage QgsSvgCache::svgAsImage( const QString &file, double size, const QColor &
138146
}
139147

140148
QPicture QgsSvgCache::svgAsPicture( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
141-
double widthScaleFactor, bool forceVectorOutput )
149+
double widthScaleFactor, bool forceVectorOutput, double fixedAspectRatio )
142150
{
143151
QMutexLocker locker( &mMutex );
144152

145-
QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor );
153+
QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio );
146154

147155
//if current entry picture is 0: cache picture for entry
148156
//update stats for memory usage
@@ -156,28 +164,28 @@ QPicture QgsSvgCache::svgAsPicture( const QString &path, double size, const QCol
156164
}
157165

158166
QByteArray QgsSvgCache::svgContent( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
159-
double widthScaleFactor )
167+
double widthScaleFactor, double fixedAspectRatio )
160168
{
161169
QMutexLocker locker( &mMutex );
162170

163-
QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor );
171+
QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio );
164172

165173
return currentEntry->svgContent;
166174
}
167175

168-
QSizeF QgsSvgCache::svgViewboxSize( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor )
176+
QSizeF QgsSvgCache::svgViewboxSize( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio )
169177
{
170178
QMutexLocker locker( &mMutex );
171179

172-
QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor );
180+
QgsSvgCacheEntry *currentEntry = cacheEntry( path, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio );
173181

174182
return currentEntry->viewboxSize;
175183
}
176184

177185
QgsSvgCacheEntry *QgsSvgCache::insertSvg( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
178-
double widthScaleFactor )
186+
double widthScaleFactor, double fixedAspectRatio )
179187
{
180-
QgsSvgCacheEntry *entry = new QgsSvgCacheEntry( path, size, strokeWidth, widthScaleFactor, fill, stroke );
188+
QgsSvgCacheEntry *entry = new QgsSvgCacheEntry( path, size, strokeWidth, widthScaleFactor, fill, stroke, fixedAspectRatio );
181189

182190
replaceParamsAndCacheSvg( entry );
183191

@@ -471,11 +479,20 @@ void QgsSvgCache::cacheImage( QgsSvgCacheEntry *entry )
471479
delete entry->image;
472480
entry->image = nullptr;
473481

482+
bool isFixedAR = entry->fixedAspectRatio > 0;
483+
474484
QSvgRenderer r( entry->svgContent );
475485
double hwRatio = 1.0;
476486
if ( r.viewBoxF().width() > 0 )
477487
{
478-
hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
488+
if( isFixedAR )
489+
{
490+
hwRatio = entry->fixedAspectRatio;
491+
}
492+
else
493+
{
494+
hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
495+
}
479496
}
480497
double wSize = entry->size;
481498
int wImgSize = static_cast< int >( wSize );
@@ -521,20 +538,30 @@ void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput
521538
delete entry->picture;
522539
entry->picture = nullptr;
523540

541+
bool isFixedAR = entry->fixedAspectRatio > 0;
542+
524543
//correct QPictures dpi correction
525544
QPicture *picture = new QPicture();
526545
QRectF rect;
527546
QSvgRenderer r( entry->svgContent );
528547
double hwRatio = 1.0;
529548
if ( r.viewBoxF().width() > 0 )
530549
{
531-
hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
550+
if( isFixedAR )
551+
{
552+
hwRatio = entry->fixedAspectRatio;
553+
}
554+
else
555+
{
556+
hwRatio = r.viewBoxF().height() / r.viewBoxF().width();
557+
}
532558
}
533559

534560
double wSize = entry->size;
535561
double hSize = wSize * hwRatio;
562+
536563
QSizeF s( r.viewBoxF().size() );
537-
s.scale( wSize, hSize, Qt::KeepAspectRatio );
564+
s.scale( wSize, hSize, isFixedAR ? Qt::IgnoreAspectRatio : Qt::KeepAspectRatio );
538565
rect = QRectF( -s.width() / 2.0, -s.height() / 2.0, s.width(), s.height() );
539566

540567
QPainter p( picture );
@@ -544,7 +571,7 @@ void QgsSvgCache::cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput
544571
}
545572

546573
QgsSvgCacheEntry *QgsSvgCache::cacheEntry( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
547-
double widthScaleFactor )
574+
double widthScaleFactor, double fixedAspectRatio )
548575
{
549576
//search entries in mEntryLookup
550577
QgsSvgCacheEntry *currentEntry = nullptr;
@@ -555,7 +582,8 @@ QgsSvgCacheEntry *QgsSvgCache::cacheEntry( const QString &path, double size, con
555582
{
556583
QgsSvgCacheEntry *cacheEntry = *entryIt;
557584
if ( qgsDoubleNear( cacheEntry->size, size ) && cacheEntry->fill == fill && cacheEntry->stroke == stroke &&
558-
qgsDoubleNear( cacheEntry->strokeWidth, strokeWidth ) && qgsDoubleNear( cacheEntry->widthScaleFactor, widthScaleFactor ) )
585+
qgsDoubleNear( cacheEntry->strokeWidth, strokeWidth ) && qgsDoubleNear( cacheEntry->widthScaleFactor, widthScaleFactor ) &&
586+
qgsDoubleNear( cacheEntry->fixedAspectRatio, fixedAspectRatio ))
559587
{
560588
currentEntry = cacheEntry;
561589
break;
@@ -566,7 +594,7 @@ QgsSvgCacheEntry *QgsSvgCache::cacheEntry( const QString &path, double size, con
566594
//cache and replace params in svg content
567595
if ( !currentEntry )
568596
{
569-
currentEntry = insertSvg( path, size, fill, stroke, strokeWidth, widthScaleFactor );
597+
currentEntry = insertSvg( path, size, fill, stroke, strokeWidth, widthScaleFactor, fixedAspectRatio);
570598
}
571599
else
572600
{

src/core/symbology/qgssvgcache.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class QPicture;
4040
class CORE_EXPORT QgsSvgCacheEntry
4141
{
4242
public:
43+
4344
QgsSvgCacheEntry();
4445

4546
/** Constructor.
@@ -49,8 +50,10 @@ class CORE_EXPORT QgsSvgCacheEntry
4950
* \param widthScaleFactor width scale factor
5051
* \param fill color of fill
5152
* \param stroke color of stroke
53+
* \param fixedAspectRatio fixed aspect ratio (optional)
5254
*/
53-
QgsSvgCacheEntry( const QString &path, double size, double strokeWidth, double widthScaleFactor, const QColor &fill, const QColor &stroke );
55+
QgsSvgCacheEntry( const QString &path, double size, double strokeWidth, double widthScaleFactor, const QColor &fill, const QColor &stroke,
56+
double fixedAspectRatio = 0 ) ;
5457
~QgsSvgCacheEntry();
5558

5659
//! QgsSvgCacheEntry cannot be copied.
@@ -64,6 +67,9 @@ class CORE_EXPORT QgsSvgCacheEntry
6467
double strokeWidth = 0;
6568
double widthScaleFactor = 1.0;
6669

70+
//! Fixed aspect ratio
71+
double fixedAspectRatio = 0;
72+
6773
/** SVG viewbox size.
6874
* \since QGIS 2.14
6975
*/
@@ -123,7 +129,7 @@ class CORE_EXPORT QgsSvgCache : public QObject
123129
* \param fitsInCache
124130
*/
125131
QImage svgAsImage( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
126-
double widthScaleFactor, bool &fitsInCache );
132+
double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio = 0 );
127133

128134
/** Get SVG as QPicture&.
129135
* \param path Absolute path to SVG file.
@@ -135,7 +141,7 @@ class CORE_EXPORT QgsSvgCache : public QObject
135141
* \param forceVectorOutput
136142
*/
137143
QPicture svgAsPicture( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
138-
double widthScaleFactor, bool forceVectorOutput = false );
144+
double widthScaleFactor, bool forceVectorOutput = false, double fixedAspectRatio = 0 );
139145

140146
/** Calculates the viewbox size of a (possibly cached) SVG file.
141147
* \param path Absolute path to SVG file.
@@ -148,7 +154,7 @@ class CORE_EXPORT QgsSvgCache : public QObject
148154
* \since QGIS 2.14
149155
*/
150156
QSizeF svgViewboxSize( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
151-
double widthScaleFactor );
157+
double widthScaleFactor, double fixedAspectRatio = 0 );
152158

153159
/** Tests if an svg file contains parameters for fill, stroke color, stroke width. If yes, possible default values are returned. If there are several
154160
default values in the svg file, only the first one is considered*/
@@ -187,7 +193,7 @@ class CORE_EXPORT QgsSvgCache : public QObject
187193

188194
//! Get SVG content
189195
QByteArray svgContent( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
190-
double widthScaleFactor );
196+
double widthScaleFactor, double fixedAspectRatio = 0);
191197

192198
signals:
193199
//! Emit a signal to be caught by qgisapp and display a msg on status bar
@@ -204,14 +210,14 @@ class CORE_EXPORT QgsSvgCache : public QObject
204210
* \param widthScaleFactor width scale factor
205211
*/
206212
QgsSvgCacheEntry *insertSvg( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
207-
double widthScaleFactor );
213+
double widthScaleFactor, double fixedAspectRatio = 0 );
208214

209215
void replaceParamsAndCacheSvg( QgsSvgCacheEntry *entry );
210216
void cacheImage( QgsSvgCacheEntry *entry );
211217
void cachePicture( QgsSvgCacheEntry *entry, bool forceVectorOutput = false );
212218
//! Returns entry from cache or creates a new entry if it does not exist already
213219
QgsSvgCacheEntry *cacheEntry( const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth,
214-
double widthScaleFactor );
220+
double widthScaleFactor, double fixedAspectRatio = 0 );
215221

216222
//! Removes the least used items until the maximum size is under the limit
217223
void trimToMaximumSize();

0 commit comments

Comments
 (0)