QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 "qgssymbollayerv2utils.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  : QgsPaintEffect()
33  , mTranslateX( 0.0 )
34  , mTranslateY( 0.0 )
35  , mTranslateUnit( QgsSymbolV2::MM )
36  , mScaleX( 1.0 )
37  , mScaleY( 1.0 )
38  , mRotation( 0.0 )
39  , mShearX( 0.0 )
40  , mShearY( 0.0 )
41  , mReflectX( false )
42  , mReflectY( false )
43 {
44 
45 }
46 
48 {
49 
50 }
51 
53 {
54  if ( !source() || !enabled() || !context.painter() )
55  return;
56 
57  QPainter* painter = context.painter();
58 
59  //apply transformations
60  painter->save();
61 
62  QTransform t = createTransform( context );
63  painter->setTransform( t, true );
64  drawSource( *painter );
65 
66  painter->restore();
67 }
68 
70 {
71  QgsStringMap props;
72  props.insert( "reflect_x", mReflectX ? "1" : "0" );
73  props.insert( "reflect_y", mReflectY ? "1" : "0" );
74  props.insert( "scale_x", QString::number( mScaleX ) );
75  props.insert( "scale_y", QString::number( mScaleY ) );
76  props.insert( "rotation", QString::number( mRotation ) );
77  props.insert( "shear_x", QString::number( mShearX ) );
78  props.insert( "shear_y", QString::number( mShearY ) );
79  props.insert( "translate_x", QString::number( mTranslateX ) );
80  props.insert( "translate_y", QString::number( mTranslateY ) );
81  props.insert( "translate_unit", QgsSymbolLayerV2Utils::encodeOutputUnit( mTranslateUnit ) );
82  props.insert( "translate_unit_scale", QgsSymbolLayerV2Utils::encodeMapUnitScale( mTranslateMapUnitScale ) );
83  props.insert( "enabled", mEnabled ? "1" : "0" );
84  props.insert( "draw_mode", QString::number( int( mDrawMode ) ) );
85  return props;
86 }
87 
89 {
90  mEnabled = props.value( "enabled", "1" ).toInt();
91  mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( "draw_mode", "2" ).toInt() );
92  mReflectX = props.value( "reflect_x", "0" ).toInt();
93  mReflectY = props.value( "reflect_y", "0" ).toInt();
94  mScaleX = props.value( "scale_x", "1.0" ).toDouble();
95  mScaleY = props.value( "scale_y", "1.0" ).toDouble();
96  mRotation = props.value( "rotation", "0.0" ).toDouble();
97  mShearX = props.value( "shear_x", "0.0" ).toDouble();
98  mShearY = props.value( "shear_y", "0.0" ).toDouble();
99  mTranslateX = props.value( "translate_x", "0.0" ).toDouble();
100  mTranslateY = props.value( "translate_y", "0.0" ).toDouble();
101  mTranslateUnit = QgsSymbolLayerV2Utils::decodeOutputUnit( props.value( "translate_unit" ) );
102  mTranslateMapUnitScale = QgsSymbolLayerV2Utils::decodeMapUnitScale( props.value( "translate_unit_scale" ) );
103 }
104 
106 {
107  QgsTransformEffect* newEffect = new QgsTransformEffect( *this );
108  return newEffect;
109 }
110 
112 {
113  QTransform t = createTransform( context );
114  return t.mapRect( rect );
115 }
116 
117 QTransform QgsTransformEffect::createTransform( const QgsRenderContext& context ) const
118 {
119  QTransform t;
120 
121  if ( !source() )
122  return t;
123 
124  int width = source()->boundingRect().width();
125  int height = source()->boundingRect().height();
126  int top = source()->boundingRect().top();
127  int left = source()->boundingRect().left();
128 
129  //remember that the below operations are effectively performed in the opposite order
130  //so, first the reflection applies, then scale, shear, rotate and lastly translation
131 
132  double translateX = mTranslateX *
133  QgsSymbolLayerV2Utils::pixelSizeScaleFactor( context, mTranslateUnit, mTranslateMapUnitScale );
134  double translateY = mTranslateY *
135  QgsSymbolLayerV2Utils::pixelSizeScaleFactor( context, mTranslateUnit, mTranslateMapUnitScale );
136 
137  t.translate( translateX + left + width / 2.0,
138  translateY + top + height / 2.0 );
139 
140  t.rotate( mRotation );
141  t.shear( mShearX, mShearY );
142  t.scale( mScaleX, mScaleY );
143 
144  if ( mReflectX || mReflectY )
145  {
146  t.scale( mReflectX ? -1 : 1, mReflectY ? -1 : 1 );
147  }
148 
149  t.translate( -left - width / 2.0,
150  -top - height / 2.0 );
151 
152  return t;
153 }
static QString encodeOutputUnit(QgsSymbolV2::OutputUnit unit)
void setTransform(const QTransform &transform, bool combine)
QRect boundingRect() const
DrawMode mDrawMode
virtual void readProperties(const QgsStringMap &props) override
Reads a string map of an effect&#39;s properties and restores the effect to the state described by the pr...
virtual void draw(QgsRenderContext &context) override
Handles drawing of the effect&#39;s result on to the specified render context.
Base class for visual effects which can be applied to QPicture drawings.
void save()
int height() const
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static double pixelSizeScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u, const QgsMapUnitScale &scale=QgsMapUnitScale())
Returns scale factor painter units -> pixel dimensions.
static QgsSymbolV2::OutputUnit decodeOutputUnit(const QString &str)
QTransform & translate(qreal dx, qreal dy)
QString number(int n, int base)
QTransform & scale(qreal sx, qreal sy)
int top() const
int left() const
double translateX() const
Returns the transform x translation.
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsTransformEffect effect from a properties string map.
bool enabled() const
Returns whether the effect is enabled.
DrawMode
Drawing modes for effects.
A paint effect which applies transformations (such as move, scale and rotate) to a picture...
void restore()
QTransform & rotate(qreal angle, Qt::Axis axis)
Contains information about the context of a rendering operation.
int width() const
QPainter * painter()
virtual QgsStringMap properties() const override
Returns the properties describing the paint effect encoded in a string format.
void drawSource(QPainter &painter)
Draws the source QPicture onto the specified painter.
iterator insert(const Key &key, const T &value)
const QPicture * source() const
Returns the source QPicture.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
virtual QRectF boundingRect(const QRectF &rect, const QgsRenderContext &context) const override
Returns the bounding rect required for drawing the effect.
QTransform & shear(qreal sh, qreal sv)
virtual QgsTransformEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
QRect mapRect(const QRect &rectangle) const
double translateY() const
Returns the transform y translation.
const T value(const Key &key) const