QGIS API Documentation 3.41.0-Master (3440c17df1d)
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#include "qgsapplication.h"
20#include "qgsimagecache.h"
21#include "qgssvgcache.h"
22#include "qgsgeometry.h"
23#include "qgsrendercontext.h"
24#include "qgspainting.h"
25#include "qgssymbollayerutils.h"
26#include "qgscalloutsregistry.h"
27
28#include <QFileInfo>
29
31 : QgsAnnotationRectItem( bounds )
32{
34}
35
37
39{
40 return QStringLiteral( "picture" );
41}
42
43void QgsAnnotationPictureItem::renderInBounds( QgsRenderContext &context, const QRectF &painterBounds, QgsFeedback * )
44{
45 bool lockAspectRatio = mLockAspectRatio;
46 bool fitsInCache = false;
47 switch ( mFormat )
48 {
50 {
51 const QSizeF svgViewbox = QgsApplication::svgCache()->svgViewboxSize( mPath, painterBounds.width(), QColor(), QColor(), 1, context.scaleFactor() );
52 double aspectRatio = painterBounds.height() / painterBounds.width();
53 double svgWidth = painterBounds.width();
54 if ( lockAspectRatio )
55 {
56 aspectRatio = svgViewbox.height() / svgViewbox.width();
57 if ( ( painterBounds.height() / painterBounds.width() ) < aspectRatio )
58 {
59 svgWidth = painterBounds.height() / aspectRatio;
60 }
61 }
62
63 const QPicture picture = QgsApplication::svgCache()->svgAsPicture( mPath, svgWidth, QColor(), QColor(), 1, context.scaleFactor(), context.forceVectorOutput(), aspectRatio );
64 const double pictureWidth = picture.boundingRect().width();
65 const double pictureHeight = picture.boundingRect().height();
66
67 double xOffset = 0;
68 if ( lockAspectRatio && static_cast< int >( painterBounds.width() ) > pictureWidth )
69 {
70 xOffset = ( painterBounds.width() - pictureWidth ) * 0.5;
71 }
72 double yOffset = 0;
73 if ( lockAspectRatio && static_cast< int >( painterBounds.height() ) > pictureHeight )
74 {
75 yOffset = ( painterBounds.height() - pictureHeight ) * 0.5;
76 }
77
78 QgsPainting::drawPicture( context.painter(), QPointF( painterBounds.left() + pictureWidth / 2 + xOffset,
79 painterBounds.top() + pictureHeight / 2 + yOffset ), picture );
80
81 break;
82 }
83
85 {
86 const QImage im = QgsApplication::imageCache()->pathAsImage( mPath,
87 QSize( static_cast< int >( std::round( painterBounds.width() ) ), static_cast< int >( std::round( painterBounds.height() ) ) ),
88 lockAspectRatio, 1, fitsInCache );
89 double xOffset = 0;
90 if ( lockAspectRatio && static_cast< int >( painterBounds.width() ) > im.width() )
91 {
92 xOffset = ( painterBounds.width() - im.width() ) * 0.5;
93 }
94 double yOffset = 0;
95 if ( lockAspectRatio && static_cast< int >( painterBounds.height() ) > im.height() )
96 {
97 yOffset = ( painterBounds.height() - im.height() ) * 0.5;
98 }
99 context.painter()->drawImage( QPointF( painterBounds.left() + xOffset, painterBounds.top() + yOffset ), im );
100 break;
101 }
102
104 break;
105 }
106}
107
108bool QgsAnnotationPictureItem::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const
109{
110 element.setAttribute( QStringLiteral( "lockAspect" ), mLockAspectRatio ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
111 element.setAttribute( QStringLiteral( "path" ), mPath );
112 element.setAttribute( QStringLiteral( "format" ), qgsEnumValueToKey( mFormat ) );
113 writeCommonProperties( element, document, context );
114 return true;
115}
116
121
122bool QgsAnnotationPictureItem::readXml( const QDomElement &element, const QgsReadWriteContext &context )
123{
124 mLockAspectRatio = element.attribute( QStringLiteral( "lockAspect" ), QStringLiteral( "1" ) ).toInt();
125
126 const Qgis::PictureFormat format = qgsEnumKeyToValue( element.attribute( QStringLiteral( "format" ) ), Qgis::PictureFormat::Unknown );
127 setPath( format, element.attribute( QStringLiteral( "path" ) ) );
128
129 readCommonProperties( element, context );
130 return true;
131}
132
134{
135 std::unique_ptr< QgsAnnotationPictureItem > item = std::make_unique< QgsAnnotationPictureItem >( mFormat, mPath, bounds() );
136 item->setLockAspectRatio( mLockAspectRatio );
137
138 item->copyCommonProperties( this );
139 return item.release();
140}
141
143{
144 mPath = path;
145 mFormat = format;
146
147 if ( path.isEmpty() )
148 {
150 return;
151 }
152}
153
155{
156 return mLockAspectRatio;
157}
158
160{
161 mLockAspectRatio = locked;
162}
PictureFormat
Picture formats.
Definition qgis.h:4901
@ Raster
Raster image.
@ Unknown
Invalid or unknown image type.
An annotation item which renders a picture.
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.
Abstract base class for annotation items which render annotations in a rectangular shape.
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.
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...
The class is used as a container of context for various read/write operations on other 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.
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
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:6168
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:6149