41 #include <QDomDocument>
42 #include <QDomElement>
44 #include <QImageReader>
46 #include <QSvgRenderer>
47 #include <QNetworkRequest>
48 #include <QNetworkReply>
50 #include <QCoreApplication>
98 double boundRectWidthMM;
99 double boundRectHeightMM;
103 boundRectWidthMM = mPictureWidth;
104 boundRectHeightMM = mPictureHeight;
105 imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
109 boundRectWidthMM = rect().width();
110 boundRectHeightMM = rect().height();
111 imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
115 boundRectWidthMM = rect().width();
116 boundRectHeightMM = rect().height();
117 int imageRectWidthPixels = mImage.width();
118 int imageRectHeightPixels = mImage.height();
119 imageRect = clippedImageRect( boundRectWidthMM, boundRectHeightMM,
120 QSize( imageRectWidthPixels, imageRectHeightPixels ) );
124 boundRectWidthMM = rect().width();
125 boundRectHeightMM = rect().height();
131 if ( mResizeMode ==
Zoom )
137 painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
138 painter->rotate( mPictureRotation );
139 painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
144 double diffX = rect().width() - boundRectWidthMM;
145 double diffY = rect().height() - boundRectHeightMM;
149 switch ( mPictureAnchor )
167 switch ( mPictureAnchor )
185 painter->translate( dX, dY );
192 painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
193 painter->rotate( mPictureRotation );
194 painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
200 mSVG.render( painter, QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ) );
204 painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, imageRect );
212 QSizeF currentPictureSize = pictureSize();
213 QSizeF newSize = targetSize;
216 mPictureWidth = targetSize.width();
217 mPictureHeight = targetSize.height();
221 if ( mResizeMode ==
ZoomResizeFrame && !rect().isEmpty() && !( currentPictureSize.isEmpty() ) )
223 QSizeF targetImageSize;
226 targetImageSize = currentPictureSize;
232 tr.rotate( mPictureRotation );
233 QRectF rotatedBounds = tr.mapRect( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ) );
234 targetImageSize = QSizeF( rotatedBounds.width(), rotatedBounds.height() );
239 if ( std::fabs( rect().width() - targetSize.width() ) <
240 std::fabs( rect().height() - targetSize.height() ) )
242 newSize.setHeight( targetImageSize.height() * newSize.width() / targetImageSize.width() );
246 newSize.setWidth( targetImageSize.width() * newSize.height() / targetImageSize.height() );
251 if ( !( currentPictureSize.isEmpty() ) )
254 newSize.setWidth( sizeMM.
width() * 25.4 /
mLayout->renderContext().dpi() );
255 newSize.setHeight( sizeMM.
height() * 25.4 /
mLayout->renderContext().dpi() );
263 QRectF( 0, 0, newSize.width(), newSize.height() ), mPictureRotation );
264 mPictureWidth = rotatedImageRect.width();
265 mPictureHeight = rotatedImageRect.height();
269 mPictureWidth = newSize.width();
270 mPictureHeight = newSize.height();
273 if ( newSize != targetSize )
282 QRect QgsLayoutItemPicture::clippedImageRect(
double &boundRectWidthMM,
double &boundRectHeightMM, QSize imageRectPixels )
284 int boundRectWidthPixels = boundRectWidthMM *
mLayout->renderContext().dpi() / 25.4;
285 int boundRectHeightPixels = boundRectHeightMM *
mLayout->renderContext().dpi() / 25.4;
288 boundRectWidthMM = boundRectWidthPixels * 25.4 /
mLayout->renderContext().dpi();
289 boundRectHeightMM = boundRectHeightPixels * 25.4 /
mLayout->renderContext().dpi();
296 switch ( mPictureAnchor )
306 leftClip = ( imageRectPixels.width() - boundRectWidthPixels ) / 2;
311 leftClip = imageRectPixels.width() - boundRectWidthPixels;
316 switch ( mPictureAnchor )
326 topClip = ( imageRectPixels.height() - boundRectHeightPixels ) / 2;
331 topClip = imageRectPixels.height() - boundRectHeightPixels;
335 return QRect( leftClip, topClip, boundRectWidthPixels, boundRectHeightPixels );
345 QVariant source( mSourcePath );
348 mHasExpressionError =
false;
354 source = sourceProperty.
value( *evalContext, source, &ok );
355 if ( !ok || !source.canConvert( QMetaType::QString ) )
357 mHasExpressionError =
true;
361 else if ( source.type() != QVariant::ByteArray )
363 source = source.toString().trimmed();
364 QgsDebugMsgLevel( QStringLiteral(
"exprVal PictureSource:%1" ).arg( source.toString() ), 2 );
368 loadPicture( source );
371 void QgsLayoutItemPicture::loadRemotePicture(
const QString &url )
381 loop.exec( QEventLoop::ExcludeUserInputEvents );
383 QNetworkReply *reply = fetcher.
reply();
386 QImageReader imageReader( reply );
387 mImage = imageReader.read();
396 void QgsLayoutItemPicture::loadLocalPicture(
const QString &path )
399 pic.setFileName( path );
407 QFileInfo sourceFileInfo( pic );
408 QString sourceFileSuffix = sourceFileInfo.suffix();
409 if ( sourceFileSuffix.compare( QLatin1String(
"svg" ), Qt::CaseInsensitive ) == 0 )
418 mSVG.load( svgContent );
419 if ( mSVG.isValid() )
422 QRect viewBox = mSVG.viewBox();
423 mDefaultSvgSize.setWidth( viewBox.width() );
424 mDefaultSvgSize.setHeight( viewBox.height() );
434 QImageReader imageReader( pic.fileName() );
435 if ( imageReader.read( &mImage ) )
447 void QgsLayoutItemPicture::loadPictureUsingCache(
const QString &path )
449 if ( path.isEmpty() )
462 bool fitsInCache =
false;
463 bool isMissing =
false;
465 if ( mImage.isNull() || isMissing )
477 QMap<QString, QString> parameters;
481 mSVG.load( svgContent );
485 QRect viewBox = mSVG.viewBox();
486 mDefaultSvgSize.setWidth( viewBox.width() );
487 mDefaultSvgSize.setHeight( viewBox.height() );
498 void QgsLayoutItemPicture::updateNorthArrowRotation(
double rotation )
504 void QgsLayoutItemPicture::loadPicture(
const QVariant &data )
506 mIsMissingImage =
false;
507 QVariant imageData( data );
508 mEvaluatedPath = data.toString();
510 if ( mEvaluatedPath.startsWith( QLatin1String(
"base64:" ), Qt::CaseInsensitive ) && mMode ==
FormatUnknown )
512 QByteArray base64 = mEvaluatedPath.mid( 7 ).toLocal8Bit();
513 imageData = QByteArray::fromBase64( base64, QByteArray::OmitTrailingEquals );
516 if ( imageData.type() == QVariant::ByteArray )
518 if ( mImage.loadFromData( imageData.toByteArray() ) )
523 else if ( mMode ==
FormatUnknown && mEvaluatedPath.startsWith( QLatin1String(
"http" ) ) )
526 loadRemotePicture( mEvaluatedPath );
531 loadLocalPicture( mEvaluatedPath );
535 loadPictureUsingCache( mEvaluatedPath );
542 else if ( mHasExpressionError || !mEvaluatedPath.isEmpty() )
546 mIsMissingImage =
true;
547 QString badFile( QStringLiteral(
":/images/composer/missing_image.svg" ) );
548 mSVG.load( badFile );
549 if ( mSVG.isValid() )
552 QRect viewBox = mSVG.viewBox();
553 mDefaultSvgSize.setWidth( viewBox.width() );
554 mDefaultSvgSize.setHeight( viewBox.height() );
563 QRectF QgsLayoutItemPicture::boundedImageRect(
double deviceWidth,
double deviceHeight )
565 double imageToDeviceRatio;
566 if ( mImage.width() / deviceWidth > mImage.height() / deviceHeight )
568 imageToDeviceRatio = deviceWidth / mImage.width();
569 double height = imageToDeviceRatio * mImage.height();
570 return QRectF( 0, 0, deviceWidth, height );
574 imageToDeviceRatio = deviceHeight / mImage.height();
575 double width = imageToDeviceRatio * mImage.width();
576 return QRectF( 0, 0, width, deviceHeight );
580 QRectF QgsLayoutItemPicture::boundedSVGRect(
double deviceWidth,
double deviceHeight )
582 double imageToSvgRatio;
583 if ( deviceWidth / mDefaultSvgSize.width() > deviceHeight / mDefaultSvgSize.height() )
585 imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
586 double width = mDefaultSvgSize.width() * imageToSvgRatio;
587 return QRectF( 0, 0, width, deviceHeight );
591 imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
592 double height = mDefaultSvgSize.height() * imageToSvgRatio;
593 return QRectF( 0, 0, deviceWidth, height );
597 QSizeF QgsLayoutItemPicture::pictureSize()
601 return mDefaultSvgSize;
605 return QSizeF( mImage.width(), mImage.height() );
609 return QSizeF( 0, 0 );
615 return mIsMissingImage;
620 return mEvaluatedPath;
623 void QgsLayoutItemPicture::shapeChanged()
625 if ( mMode ==
FormatSVG && !mLoadingSvg )
635 double oldRotation = mPictureRotation;
636 mPictureRotation = rotation;
638 if ( mResizeMode ==
Zoom )
641 QSizeF currentPictureSize = pictureSize();
643 mPictureWidth = rotatedImageRect.width();
644 mPictureHeight = rotatedImageRect.height();
649 QSizeF currentPictureSize = pictureSize();
650 QRectF oldRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
657 tr.rotate( mPictureRotation );
658 QRectF newRect = tr.mapRect( QRectF( 0, 0, rotatedImageRect.width(), rotatedImageRect.height() ) );
661 newRect.moveCenter( oldRect.center() );
720 QString imagePath = mSourcePath;
724 if ( imagePath.endsWith( QLatin1String(
".svg" ), Qt::CaseInsensitive ) )
727 imagePath = pathResolver.
writePath( imagePath );
729 elem.setAttribute( QStringLiteral(
"file" ), imagePath );
730 elem.setAttribute( QStringLiteral(
"pictureWidth" ), QString::number( mPictureWidth ) );
731 elem.setAttribute( QStringLiteral(
"pictureHeight" ), QString::number( mPictureHeight ) );
732 elem.setAttribute( QStringLiteral(
"resizeMode" ), QString::number(
static_cast< int >( mResizeMode ) ) );
733 elem.setAttribute( QStringLiteral(
"anchorPoint" ), QString::number(
static_cast< int >( mPictureAnchor ) ) );
736 elem.setAttribute( QStringLiteral(
"svgBorderWidth" ), QString::number( mSvgStrokeWidth ) );
737 elem.setAttribute( QStringLiteral(
"mode" ), mMode );
740 elem.setAttribute( QStringLiteral(
"pictureRotation" ), QString::number( mPictureRotation ) );
743 elem.setAttribute( QStringLiteral(
"mapUuid" ), QString() );
747 elem.setAttribute( QStringLiteral(
"mapUuid" ), mNorthArrowHandler->
linkedMap()->
uuid() );
749 elem.setAttribute( QStringLiteral(
"northMode" ), mNorthArrowHandler->
northMode() );
750 elem.setAttribute( QStringLiteral(
"northOffset" ), mNorthArrowHandler->
northOffset() );
756 mPictureWidth = itemElem.attribute( QStringLiteral(
"pictureWidth" ), QStringLiteral(
"10" ) ).toDouble();
757 mPictureHeight = itemElem.attribute( QStringLiteral(
"pictureHeight" ), QStringLiteral(
"10" ) ).toDouble();
764 mSvgStrokeWidth = itemElem.attribute( QStringLiteral(
"svgBorderWidth" ), QStringLiteral(
"0.2" ) ).toDouble();
765 mMode =
static_cast< Format >( itemElem.attribute( QStringLiteral(
"mode" ), QString::number(
FormatUnknown ) ).toInt() );
767 QDomNodeList composerItemList = itemElem.elementsByTagName( QStringLiteral(
"ComposerItem" ) );
768 if ( !composerItemList.isEmpty() )
770 QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
772 if ( !
qgsDoubleNear( composerItemElem.attribute( QStringLiteral(
"rotation" ), QStringLiteral(
"0" ) ).toDouble(), 0.0 ) )
775 mPictureRotation = composerItemElem.attribute( QStringLiteral(
"rotation" ), QStringLiteral(
"0" ) ).toDouble();
779 mDefaultSvgSize = QSize( 0, 0 );
781 if ( itemElem.hasAttribute( QStringLiteral(
"sourceExpression" ) ) )
784 QString sourceExpression = itemElem.attribute( QStringLiteral(
"sourceExpression" ), QString() );
785 QString useExpression = itemElem.attribute( QStringLiteral(
"useExpression" ) );
786 bool expressionActive;
787 expressionActive = ( useExpression.compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0 );
792 QString imagePath = itemElem.attribute( QStringLiteral(
"file" ) );
796 if ( imagePath.endsWith( QLatin1String(
".svg" ), Qt::CaseInsensitive ) )
799 imagePath = pathResolver.
readPath( imagePath );
801 mSourcePath = imagePath;
804 if ( !
qgsDoubleNear( itemElem.attribute( QStringLiteral(
"pictureRotation" ), QStringLiteral(
"0" ) ).toDouble(), 0.0 ) )
806 mPictureRotation = itemElem.attribute( QStringLiteral(
"pictureRotation" ), QStringLiteral(
"0" ) ).toDouble();
811 mNorthArrowHandler->
setNorthOffset( itemElem.attribute( QStringLiteral(
"northOffset" ), QStringLiteral(
"0" ) ).toDouble() );
814 mRotationMapUuid = itemElem.attribute( QStringLiteral(
"mapUuid" ) );
846 mPictureAnchor = anchor;
852 mSvgFillColor = color;
858 mSvgStrokeColor = color;
864 mSvgStrokeWidth = width;
879 if ( !
mLayout || mRotationMapUuid.isEmpty() )
885 mNorthArrowHandler->
setLinkedMap( qobject_cast< QgsLayoutItemMap * >(
mLayout->itemByUuid( mRotationMapUuid,
true ) ) );
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
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...
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
Layout graphical items for displaying a map.
A layout item subclass that displays SVG files or raster format images (jpg, png, ....
void setResizeMode(QgsLayoutItemPicture::ResizeMode mode)
Sets the resize mode used for drawing the picture within the item bounds.
QString picturePath() const
Returns the path of the source image.
void setPictureAnchor(QgsLayoutItem::ReferencePoint anchor)
Sets the picture's anchor point, which controls how it is placed within the picture item's frame.
void setNorthMode(NorthMode mode)
Sets the mode used to align the picture to a map's North.
double northOffset() const
Returns the offset added to the picture's rotation from a map's North.
QgsLayoutItemPicture(QgsLayout *layout)
Constructor for QgsLayoutItemPicture, with the specified parent layout.
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map object for rotation.
void setPictureRotation(double rotation)
Sets the picture rotation within the item bounds, in degrees clockwise.
bool isMissingImage() const
Returns true if the source image is missing and the picture cannot be rendered.
bool writePropertiesToElement(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const override
Stores item state within an XML DOM element.
bool readPropertiesFromElement(const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context) override
Sets item state from a DOM element.
void setPicturePath(const QString &path, Format format=FormatUnknown)
Sets the source path of the image (may be svg or a raster format).
void setSvgStrokeWidth(double width)
Sets the stroke width (in layout units) used for parametrized SVG files.
QgsLayoutItemMap * linkedMap() const
Returns the linked rotation map, if set.
void pictureRotationChanged(double newRotation)
Emitted on picture rotation change.
void draw(QgsLayoutItemRenderContext &context) override
Draws the item's contents using the specified item render context.
static QgsLayoutItemPicture * create(QgsLayout *layout)
Returns a new picture item for the specified layout.
NorthMode
Method for syncing rotation to a map's North direction.
void finalizeRestoreFromXml() override
Called after all pending items have been restored from XML.
Format mode() const
Returns the current picture mode (image format).
QString evaluatedPath() const
Returns the current evaluated picture path, which includes the result of data defined path overrides.
QSizeF applyItemSizeConstraint(QSizeF targetSize) override
Applies any item-specific size constraint handling to a given targetSize in layout units.
void setSvgStrokeColor(const QColor &color)
Sets the stroke color used for parametrized SVG files.
int type() const override
void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties) override
QIcon icon() const override
Returns the item's icon.
void refreshPicture(const QgsExpressionContext *context=nullptr)
Recalculates the source image (if using an expression for picture's source) and reloads and redraws t...
void setMode(Format mode)
Sets the current picture mode (image format).
NorthMode northMode() const
Returns the mode used to align the picture to a map's North.
void setSvgFillColor(const QColor &color)
Sets the fill color used for parametrized SVG files.
void recalculateSize()
Forces a recalculation of the picture's frame size.
ResizeMode
Controls how pictures are scaled within the item's frame.
@ FrameToImageSize
Sets size of frame to match original size of image without scaling.
@ ZoomResizeFrame
Enlarges image to fit frame, then resizes frame to fit resultant image.
@ Clip
Draws image at original size and clips any portion which falls outside frame.
@ Stretch
Stretches image to fit frame, ignores aspect ratio.
@ Zoom
Enlarges image to fit frame while maintaining aspect ratio of picture.
Format
Format of source image.
@ FormatRaster
Raster image.
@ FormatUnknown
Invalid or unknown image type.
void setNorthOffset(double offset)
Sets the offset added to the picture's rotation from a map's North.
@ LayoutPicture
Picture item.
Contains settings and helpers relating to a render of a QgsLayoutItem.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Base class for graphical items within a QgsLayout.
ReferencePoint
Fixed position reference point.
@ LowerMiddle
Lower center of item.
@ MiddleLeft
Middle left of item.
@ UpperRight
Upper right corner of item.
@ LowerLeft
Lower left corner of item.
@ UpperLeft
Upper left corner of item.
@ UpperMiddle
Upper center of item.
@ MiddleRight
Middle right of item.
@ LowerRight
Lower right corner of item.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
virtual void refreshDataDefinedProperty(QgsLayoutObject::DataDefinedProperty property=QgsLayoutObject::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
void sizePositionChanged()
Emitted when the item's size or position changes.
virtual QString uuid() const
Returns the item identification string.
void attemptSetSceneRect(const QRectF &rect, bool includesFrame=false)
Attempts to update the item's position and size to match the passed rect in layout coordinates.
void setBackgroundEnabled(bool drawBackground)
Sets whether this item has a background drawn under it or not.
An object which handles north-arrow type behavior for layout items.
void setNorthOffset(double offset)
Sets the offset added to the arrows's rotation from a map's North.
NorthMode northMode() const
Returns the mode used to calculate the arrow rotation.
QgsLayoutItemMap * linkedMap() const
Returns the linked rotation map, if set.
void arrowRotationChanged(double newRotation)
Emitted on arrow rotation change.
NorthMode
Method for syncing rotation to a map's North direction.
void setNorthMode(NorthMode mode)
Sets the mode used to calculate the arrow rotation.
void setLinkedMap(QgsLayoutItemMap *map)
Sets the linked map item.
double northOffset() const
Returns the offset added to the arrows's rotation from a map's North.
QgsPropertyCollection mDataDefinedProperties
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
QPointer< QgsLayout > mLayout
DataDefinedProperty
Data defined properties for different item types.
@ PictureSvgStrokeColor
SVG stroke color.
@ AllProperties
All properties for item.
@ PictureSvgStrokeWidth
SVG stroke width.
@ PictureSvgBackgroundColor
SVG background color.
@ PictureSource
Picture source url.
void dpiChanged()
Emitted when the context's DPI is changed.
void changed()
Emitted certain settings in the context is changed, e.g.
This class provides a method of storing sizes, consisting of a width and height, for use in QGIS layo...
double height() const
Returns the height of the size.
double width() const
Returns the width of the size.
static QRectF largestRotatedRectWithinBounds(const QRectF &originalRect, const QRectF &boundsRect, double rotation)
Calculates the largest scaled version of originalRect which fits within boundsRect,...
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
HTTP network content fetcher.
void finished()
Emitted when content has loaded.
QNetworkReply * reply()
Returns a reference to the network reply.
void fetchContent(const QUrl &url, const QString &authcfg=QString())
Fetches content from a remote URL and handles redirects.
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const override
Prepares the collection against a specified expression context.
A store for object properties.
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
The class is used as a container of context for various read/write operations on other objects.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
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.
Scoped object for saving and restoring a QPainter object's state.
QByteArray svgContent(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 > ¶meters=QMap< QString, QString >(), bool *isMissingImage=nullptr)
Gets the SVG content corresponding to the given path.
static QColor decodeColor(const QString &str)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
@ LayoutMillimeters
Millimeters.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define QgsDebugMsgLevel(str, level)