QGIS API Documentation 4.3.0-Master (35968c35f7e)
Loading...
Searching...
No Matches
qgstransformeffect.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstransformeffect.cpp
3 ----------------------
4 begin : March 2015
5 copyright : (C) 2015 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
18#include "qgstransformeffect.h"
19
20#include "qgspainting.h"
21#include "qgssymbollayerutils.h"
22#include "qgsunittypes.h"
23
24#include <QPicture>
25#include <QString>
26#include <QTransform>
27
28using namespace Qt::StringLiterals;
29
30std::unique_ptr<QgsPaintEffect> QgsTransformEffect::create( const QVariantMap &map )
31{
32 auto newEffect = std::make_unique<QgsTransformEffect>();
33 newEffect->readProperties( map );
34 return newEffect;
35}
36
38{
39 if ( !enabled() || !context.painter() || source().isNull() )
40 return;
41
42 QPainter *painter = context.painter();
43
44 //apply transformations
45 const QgsScopedQPainterState painterState( painter );
46
47 const QTransform t = createTransform( context );
48 painter->setTransform( t, true );
49 drawSource( *painter );
50}
51
53{
54 QVariantMap props;
55 props.insert( u"reflect_x"_s, mReflectX ? "1" : "0" );
56 props.insert( u"reflect_y"_s, mReflectY ? "1" : "0" );
57 props.insert( u"scale_x"_s, QString::number( mScaleX ) );
58 props.insert( u"scale_y"_s, QString::number( mScaleY ) );
59 props.insert( u"rotation"_s, QString::number( mRotation ) );
60 props.insert( u"shear_x"_s, QString::number( mShearX ) );
61 props.insert( u"shear_y"_s, QString::number( mShearY ) );
62 props.insert( u"translate_x"_s, QString::number( mTranslateX ) );
63 props.insert( u"translate_y"_s, QString::number( mTranslateY ) );
64 props.insert( u"translate_unit"_s, QgsUnitTypes::encodeUnit( mTranslateUnit ) );
65 props.insert( u"translate_unit_scale"_s, QgsSymbolLayerUtils::encodeMapUnitScale( mTranslateMapUnitScale ) );
66 props.insert( u"enabled"_s, mEnabled ? "1" : "0" );
67 props.insert( u"draw_mode"_s, QString::number( int( mDrawMode ) ) );
68 return props;
69}
70
71void QgsTransformEffect::readProperties( const QVariantMap &props )
72{
73 mEnabled = props.value( u"enabled"_s, u"1"_s ).toInt();
74 mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( u"draw_mode"_s, u"2"_s ).toInt() );
75 mReflectX = props.value( u"reflect_x"_s, u"0"_s ).toInt();
76 mReflectY = props.value( u"reflect_y"_s, u"0"_s ).toInt();
77 mScaleX = props.value( u"scale_x"_s, u"1.0"_s ).toDouble();
78 mScaleY = props.value( u"scale_y"_s, u"1.0"_s ).toDouble();
79 mRotation = props.value( u"rotation"_s, u"0.0"_s ).toDouble();
80 mShearX = props.value( u"shear_x"_s, u"0.0"_s ).toDouble();
81 mShearY = props.value( u"shear_y"_s, u"0.0"_s ).toDouble();
82 mTranslateX = props.value( u"translate_x"_s, u"0.0"_s ).toDouble();
83 mTranslateY = props.value( u"translate_y"_s, u"0.0"_s ).toDouble();
84 mTranslateUnit = QgsUnitTypes::decodeRenderUnit( props.value( u"translate_unit"_s ).toString() );
85 mTranslateMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( u"translate_unit_scale"_s ).toString() );
86}
87
89{
90 QgsTransformEffect *newEffect = new QgsTransformEffect( *this );
91 return newEffect;
92}
93
94QRectF QgsTransformEffect::boundingRect( const QRectF &rect, const QgsRenderContext &context ) const
95{
96 const QTransform t = createTransform( context );
97 return t.mapRect( rect );
98}
99
100QTransform QgsTransformEffect::createTransform( const QgsRenderContext &context ) const
101{
102 QTransform t;
103
104 const QPicture &pic = source();
105 if ( pic.isNull() )
106 return t;
107
108 const int width = pic.boundingRect().width();
109 const int height = pic.boundingRect().height();
110 const int top = pic.boundingRect().top();
111 const int left = pic.boundingRect().left();
112
113 //remember that the below operations are effectively performed in the opposite order
114 //so, first the reflection applies, then scale, shear, rotate and lastly translation
115
116 const double translateX = context.convertToPainterUnits( mTranslateX, mTranslateUnit, mTranslateMapUnitScale );
117 const double translateY = context.convertToPainterUnits( mTranslateY, mTranslateUnit, mTranslateMapUnitScale );
118
119 t.translate( translateX + left + width / 2.0, translateY + top + height / 2.0 );
120
121 t.rotate( mRotation );
122 t.shear( mShearX, mShearY );
123 t.scale( mScaleX, mScaleY );
124
125 if ( mReflectX || mReflectY )
126 {
127 t.scale( mReflectX ? -1 : 1, mReflectY ? -1 : 1 );
128 }
129
130 t.translate( -left - width / 2.0, -top - height / 2.0 );
131
132 return t;
133}
void drawSource(QPainter &painter)
Draws the source QPicture onto the specified painter.
const QPicture & source() const
Returns the source QPicture.
bool enabled() const
Returns whether the effect is enabled.
DrawMode
Drawing modes for effects.
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
Scoped object for saving and restoring a QPainter object's state.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static std::unique_ptr< QgsPaintEffect > create(const QVariantMap &map)
Creates a new QgsTransformEffect effect from a properties string map.
double translateX() const
Returns the transform x translation.
QgsTransformEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
QgsTransformEffect()=default
double translateY() const
Returns the transform y translation.
void draw(QgsRenderContext &context) override
Handles drawing of the effect's result on to the specified render context.
QRectF boundingRect(const QRectF &rect, const QgsRenderContext &context) const override
Returns the bounding rect required for drawing the effect.
void readProperties(const QVariantMap &props) override
Reads a string map of an effect's properties and restores the effect to the state described by the pr...
QVariantMap properties() const override
Returns the properties describing the paint effect encoded in a string format.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.