QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsannotationpictureitem.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsannotationpictureitem.cpp
3 ----------------
4 begin : July 2024
5 copyright : (C) 2024 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19
20#include "qgsapplication.h"
21#include "qgscalloutsregistry.h"
22#include "qgsgeometry.h"
23#include "qgsimagecache.h"
24#include "qgspainting.h"
25#include "qgsrendercontext.h"
26#include "qgssvgcache.h"
27#include "qgssymbollayerutils.h"
28
29#include <QFileInfo>
30
36
38
40{
41 return QStringLiteral( "picture" );
42}
43
44void QgsAnnotationPictureItem::renderInBounds( QgsRenderContext &context, const QRectF &painterBounds, QgsFeedback * )
45{
46 bool lockAspectRatio = mLockAspectRatio;
47 bool fitsInCache = false;
48 switch ( mFormat )
49 {
51 {
52 const QSizeF svgViewbox = QgsApplication::svgCache()->svgViewboxSize( mPath, painterBounds.width(), QColor(), QColor(), 1, context.scaleFactor() );
53 double aspectRatio = painterBounds.height() / painterBounds.width();
54 double svgWidth = painterBounds.width();
55 if ( lockAspectRatio )
56 {
57 aspectRatio = svgViewbox.height() / svgViewbox.width();
58 if ( ( painterBounds.height() / painterBounds.width() ) < aspectRatio )
59 {
60 svgWidth = painterBounds.height() / aspectRatio;
61 }
62 }
63
64 const QPicture picture = QgsApplication::svgCache()->svgAsPicture( mPath, svgWidth, QColor(), QColor(), 1, context.scaleFactor(),
66 aspectRatio );
67 const double pictureWidth = picture.boundingRect().width();
68 const double pictureHeight = picture.boundingRect().height();
69
70 double xOffset = 0;
71 if ( lockAspectRatio && static_cast< int >( painterBounds.width() ) > pictureWidth )
72 {
73 xOffset = ( painterBounds.width() - pictureWidth ) * 0.5;
74 }
75 double yOffset = 0;
76 if ( lockAspectRatio && static_cast< int >( painterBounds.height() ) > pictureHeight )
77 {
78 yOffset = ( painterBounds.height() - pictureHeight ) * 0.5;
79 }
80
81 QgsPainting::drawPicture( context.painter(), QPointF( painterBounds.left() + pictureWidth / 2 + xOffset,
82 painterBounds.top() + pictureHeight / 2 + yOffset ), picture );
83
84 break;
85 }
86
88 {
89 const QImage im = QgsApplication::imageCache()->pathAsImage( mPath,
90 QSize( static_cast< int >( std::round( painterBounds.width() ) ), static_cast< int >( std::round( painterBounds.height() ) ) ),
91 lockAspectRatio, 1, fitsInCache );
92 double xOffset = 0;
93 if ( lockAspectRatio && static_cast< int >( painterBounds.width() ) > im.width() )
94 {
95 xOffset = ( painterBounds.width() - im.width() ) * 0.5;
96 }
97 double yOffset = 0;
98 if ( lockAspectRatio && static_cast< int >( painterBounds.height() ) > im.height() )
99 {
100 yOffset = ( painterBounds.height() - im.height() ) * 0.5;
101 }
102 context.painter()->drawImage( QPointF( painterBounds.left() + xOffset, painterBounds.top() + yOffset ), im );
103 break;
104 }
105
107 break;
108 }
109}
110
111bool QgsAnnotationPictureItem::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
112{
113 element.setAttribute( QStringLiteral( "lockAspect" ), mLockAspectRatio ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
114 element.setAttribute( QStringLiteral( "path" ), mPath );
115 element.setAttribute( QStringLiteral( "format" ), qgsEnumValueToKey( mFormat ) );
116 writeCommonProperties( element, document, context );
117 return true;
118}
119
124
125bool QgsAnnotationPictureItem::readXml( const QDomElement &element, const QgsReadWriteContext &context )
126{
127 mLockAspectRatio = element.attribute( QStringLiteral( "lockAspect" ), QStringLiteral( "1" ) ).toInt();
128
129 const Qgis::PictureFormat format = qgsEnumKeyToValue( element.attribute( QStringLiteral( "format" ) ), Qgis::PictureFormat::Unknown );
130 setPath( format, element.attribute( QStringLiteral( "path" ) ) );
131
132 readCommonProperties( element, context );
133 return true;
134}
135
137{
138 auto item = std::make_unique< QgsAnnotationPictureItem >( mFormat, mPath, bounds() );
139 item->setLockAspectRatio( mLockAspectRatio );
140
141 item->copyCommonProperties( this );
142 return item.release();
143}
144
146{
147 mPath = path;
148 mFormat = format;
149
150 if ( path.isEmpty() )
151 {
153 return;
154 }
155}
156
158{
159 return mLockAspectRatio;
160}
161
163{
164 mLockAspectRatio = locked;
165}
@ Default
Allow raster-based rendering in situations where it is required for correct rendering or where it wil...
Definition qgis.h:2704
PictureFormat
Picture formats.
Definition qgis.h:5272
@ Raster
Raster image.
Definition qgis.h:5274
@ Unknown
Invalid or unknown image type.
Definition qgis.h:5275
@ SVG
SVG image.
Definition qgis.h:5273
Qgis::PictureFormat format() const
Returns the picture format.
QString path() const
Returns the path of the image used to render the item.
void renderInBounds(QgsRenderContext &context, const QRectF &painterBounds, QgsFeedback *feedback) override
Renders the item to the specified render context.
bool lockAspectRatio() const
Returns true if the aspect ratio of the picture will be retained.
~QgsAnnotationPictureItem() override
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Writes the item's state into an XML element.
QgsAnnotationPictureItem(Qgis::PictureFormat format, const QString &path, const QgsRectangle &bounds)
Constructor for QgsAnnotationPictureItem, rendering the specified image path within the specified bou...
QgsAnnotationPictureItem * clone() const override
Returns a clone of the item.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads the item's state from the given DOM element.
void setLockAspectRatio(bool locked)
Sets whether the aspect ratio of the picture will be retained.
void setPath(Qgis::PictureFormat format, const QString &path)
Sets the format and path of the image used to render the item.
static QgsAnnotationPictureItem * create()
Creates a new polygon annotation item.
QString type() const override
Returns a unique (untranslated) string identifying the type of item.
QgsRectangle bounds() const
Returns the bounds of the item.
bool readCommonProperties(const QDomElement &element, const QgsReadWriteContext &context) override
Reads common properties from the base class from the given DOM element.
QgsAnnotationRectItem(const QgsRectangle &bounds)
Constructor for QgsAnnotationRectItem, rendering the annotation within the specified bounds geometry.
bool writeCommonProperties(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Writes common properties from the base class into an XML element.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
static void drawPicture(QPainter *painter, const QPointF &point, const QPicture &picture)
Draws a picture onto a painter, correctly applying workarounds to avoid issues with incorrect scaling...
A container for the context for various read/write operations on objects.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
Qgis::RasterizedRenderingPolicy rasterizedRenderingPolicy() const
Returns the policy controlling when rasterisation of content during renders is permitted.
QSizeF svgViewboxSize(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > &parameters=QMap< QString, QString >())
Calculates the viewbox size of a (possibly cached) SVG file.
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, const QMap< QString, QString > &parameters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
Definition qgis.h:6817
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6798