QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 #include "qgssymbollayerutils.h"
20 #include "qgsunittypes.h"
21 #include <QPicture>
22 #include <QTransform>
23 
25 {
26  QgsTransformEffect *newEffect = new QgsTransformEffect();
27  newEffect->readProperties( map );
28  return newEffect;
29 }
30 
32 {
33  if ( !source() || !enabled() || !context.painter() )
34  return;
35 
36  QPainter *painter = context.painter();
37 
38  //apply transformations
39  QgsScopedQPainterState painterState( painter );
40 
41  QTransform t = createTransform( context );
42  painter->setTransform( t, true );
43  drawSource( *painter );
44 }
45 
47 {
48  QgsStringMap props;
49  props.insert( QStringLiteral( "reflect_x" ), mReflectX ? "1" : "0" );
50  props.insert( QStringLiteral( "reflect_y" ), mReflectY ? "1" : "0" );
51  props.insert( QStringLiteral( "scale_x" ), QString::number( mScaleX ) );
52  props.insert( QStringLiteral( "scale_y" ), QString::number( mScaleY ) );
53  props.insert( QStringLiteral( "rotation" ), QString::number( mRotation ) );
54  props.insert( QStringLiteral( "shear_x" ), QString::number( mShearX ) );
55  props.insert( QStringLiteral( "shear_y" ), QString::number( mShearY ) );
56  props.insert( QStringLiteral( "translate_x" ), QString::number( mTranslateX ) );
57  props.insert( QStringLiteral( "translate_y" ), QString::number( mTranslateY ) );
58  props.insert( QStringLiteral( "translate_unit" ), QgsUnitTypes::encodeUnit( mTranslateUnit ) );
59  props.insert( QStringLiteral( "translate_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mTranslateMapUnitScale ) );
60  props.insert( QStringLiteral( "enabled" ), mEnabled ? "1" : "0" );
61  props.insert( QStringLiteral( "draw_mode" ), QString::number( int( mDrawMode ) ) );
62  return props;
63 }
64 
66 {
67  mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ).toInt();
68  mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( QStringLiteral( "draw_mode" ), QStringLiteral( "2" ) ).toInt() );
69  mReflectX = props.value( QStringLiteral( "reflect_x" ), QStringLiteral( "0" ) ).toInt();
70  mReflectY = props.value( QStringLiteral( "reflect_y" ), QStringLiteral( "0" ) ).toInt();
71  mScaleX = props.value( QStringLiteral( "scale_x" ), QStringLiteral( "1.0" ) ).toDouble();
72  mScaleY = props.value( QStringLiteral( "scale_y" ), QStringLiteral( "1.0" ) ).toDouble();
73  mRotation = props.value( QStringLiteral( "rotation" ), QStringLiteral( "0.0" ) ).toDouble();
74  mShearX = props.value( QStringLiteral( "shear_x" ), QStringLiteral( "0.0" ) ).toDouble();
75  mShearY = props.value( QStringLiteral( "shear_y" ), QStringLiteral( "0.0" ) ).toDouble();
76  mTranslateX = props.value( QStringLiteral( "translate_x" ), QStringLiteral( "0.0" ) ).toDouble();
77  mTranslateY = props.value( QStringLiteral( "translate_y" ), QStringLiteral( "0.0" ) ).toDouble();
78  mTranslateUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "translate_unit" ) ) );
79  mTranslateMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "translate_unit_scale" ) ) );
80 }
81 
83 {
84  QgsTransformEffect *newEffect = new QgsTransformEffect( *this );
85  return newEffect;
86 }
87 
88 QRectF QgsTransformEffect::boundingRect( const QRectF &rect, const QgsRenderContext &context ) const
89 {
90  QTransform t = createTransform( context );
91  return t.mapRect( rect );
92 }
93 
94 QTransform QgsTransformEffect::createTransform( const QgsRenderContext &context ) const
95 {
96  QTransform t;
97 
98  if ( !source() )
99  return t;
100 
101  int width = source()->boundingRect().width();
102  int height = source()->boundingRect().height();
103  int top = source()->boundingRect().top();
104  int left = source()->boundingRect().left();
105 
106  //remember that the below operations are effectively performed in the opposite order
107  //so, first the reflection applies, then scale, shear, rotate and lastly translation
108 
109  double translateX = context.convertToPainterUnits( mTranslateX, mTranslateUnit, mTranslateMapUnitScale );
110  double translateY = context.convertToPainterUnits( mTranslateY, mTranslateUnit, mTranslateMapUnitScale );
111 
112  t.translate( translateX + left + width / 2.0,
113  translateY + top + height / 2.0 );
114 
115  t.rotate( mRotation );
116  t.shear( mShearX, mShearY );
117  t.scale( mScaleX, mScaleY );
118 
119  if ( mReflectX || mReflectY )
120  {
121  t.scale( mReflectX ? -1 : 1, mReflectY ? -1 : 1 );
122  }
123 
124  t.translate( -left - width / 2.0,
125  -top - height / 2.0 );
126 
127  return t;
128 }
QgsPaintEffect::drawSource
void drawSource(QPainter &painter)
Draws the source QPicture onto the specified painter.
Definition: qgspainteffect.cpp:158
QgsPaintEffect::DrawMode
DrawMode
Drawing modes for effects.
Definition: qgspainteffect.h:105
QgsRenderContext::convertToPainterUnits
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
Definition: qgsrendercontext.cpp:318
QgsSymbolLayerUtils::encodeMapUnitScale
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
Definition: qgssymbollayerutils.cpp:558
qgssymbollayerutils.h
QgsTransformEffect::translateX
double translateX() const
Returns the transform x translation.
Definition: qgstransformeffect.h:76
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
qgsunittypes.h
QgsTransformEffect::properties
QgsStringMap properties() const override
Returns the properties describing the paint effect encoded in a string format.
Definition: qgstransformeffect.cpp:46
qgstransformeffect.h
QgsPaintEffect::mEnabled
bool mEnabled
Definition: qgspainteffect.h:225
QgsUnitTypes::decodeRenderUnit
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
Definition: qgsunittypes.cpp:2900
QgsTransformEffect::QgsTransformEffect
QgsTransformEffect()=default
Constructor for QgsTransformEffect.
QgsUnitTypes::encodeUnit
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
Definition: qgsunittypes.cpp:122
QgsTransformEffect::draw
void draw(QgsRenderContext &context) override
Handles drawing of the effect's result on to the specified render context.
Definition: qgstransformeffect.cpp:31
QgsTransformEffect::readProperties
void readProperties(const QgsStringMap &props) override
Reads a string map of an effect's properties and restores the effect to the state described by the pr...
Definition: qgstransformeffect.cpp:65
QgsScopedQPainterState
Scoped object for saving and restoring a QPainter object's state.
Definition: qgsrendercontext.h:1120
QgsTransformEffect::boundingRect
QRectF boundingRect(const QRectF &rect, const QgsRenderContext &context) const override
Returns the bounding rect required for drawing the effect.
Definition: qgstransformeffect.cpp:88
QgsPaintEffect::mDrawMode
DrawMode mDrawMode
Definition: qgspainteffect.h:226
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:758
QgsTransformEffect::translateY
double translateY() const
Returns the transform y translation.
Definition: qgstransformeffect.h:96
QgsPaintEffect::source
const QPicture * source() const
Returns the source QPicture.
Definition: qgspainteffect.h:254
QgsTransformEffect
A paint effect which applies transformations (such as move, scale and rotate) to a picture.
Definition: qgstransformeffect.h:37
QgsPaintEffect
Base class for visual effects which can be applied to QPicture drawings.
Definition: qgspainteffect.h:54
QgsTransformEffect::clone
QgsTransformEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
Definition: qgstransformeffect.cpp:82
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:179
QgsPaintEffect::enabled
bool enabled() const
Returns whether the effect is enabled.
Definition: qgspainteffect.h:198
QgsSymbolLayerUtils::decodeMapUnitScale
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
Definition: qgssymbollayerutils.cpp:568
QgsTransformEffect::create
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsTransformEffect effect from a properties string map.
Definition: qgstransformeffect.cpp:24