QGIS API Documentation 3.39.0-Master (3aed037ce22)
Loading...
Searching...
No Matches
qgspainting.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspainting.cpp
3 ---------------------
4 begin : July 2016
5 copyright : (C) 2016 by Martin Dobias
6 email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgspainting.h"
17#include "qgslogger.h"
18
19#include <QTransform>
20
21Q_GUI_EXPORT extern int qt_defaultDpiX();
22Q_GUI_EXPORT extern int qt_defaultDpiY();
23
24QPainter::CompositionMode QgsPainting::getCompositionMode( Qgis::BlendMode blendMode )
25{
26 // Map Qgis::BlendMode::Normal to QPainter::CompositionMode
27 switch ( blendMode )
28 {
30 return QPainter::CompositionMode_SourceOver;
32 return QPainter::CompositionMode_Lighten;
34 return QPainter::CompositionMode_Screen;
36 return QPainter::CompositionMode_ColorDodge;
38 return QPainter::CompositionMode_Plus;
40 return QPainter::CompositionMode_Darken;
42 return QPainter::CompositionMode_Multiply;
44 return QPainter::CompositionMode_ColorBurn;
46 return QPainter::CompositionMode_Overlay;
48 return QPainter::CompositionMode_SoftLight;
50 return QPainter::CompositionMode_HardLight;
52 return QPainter::CompositionMode_Difference;
54 return QPainter::CompositionMode_Exclusion;
56 return QPainter::CompositionMode_Source;
58 return QPainter::CompositionMode_DestinationOver;
60 return QPainter::CompositionMode_Clear;
62 return QPainter::CompositionMode_Destination;
64 return QPainter::CompositionMode_SourceIn;
66 return QPainter::CompositionMode_DestinationIn;
68 return QPainter::CompositionMode_SourceOut;
70 return QPainter::CompositionMode_DestinationOut;
72 return QPainter::CompositionMode_SourceAtop;
74 return QPainter::CompositionMode_DestinationAtop;
76 return QPainter::CompositionMode_Xor;
77 default:
78 QgsDebugError( QStringLiteral( "Blend mode %1 mapped to SourceOver" ).arg( qgsEnumValueToKey( blendMode ) ) );
79 return QPainter::CompositionMode_SourceOver;
80 }
81}
82
83
84Qgis::BlendMode QgsPainting::getBlendModeEnum( QPainter::CompositionMode blendMode )
85{
86 // Map QPainter::CompositionMode to Qgis::BlendMode::Normal
87 switch ( blendMode )
88 {
89 case QPainter::CompositionMode_SourceOver:
91 case QPainter::CompositionMode_Lighten:
93 case QPainter::CompositionMode_Screen:
95 case QPainter::CompositionMode_ColorDodge:
97 case QPainter::CompositionMode_Plus:
99 case QPainter::CompositionMode_Darken:
101 case QPainter::CompositionMode_Multiply:
103 case QPainter::CompositionMode_ColorBurn:
105 case QPainter::CompositionMode_Overlay:
107 case QPainter::CompositionMode_SoftLight:
109 case QPainter::CompositionMode_HardLight:
111 case QPainter::CompositionMode_Difference:
113 case QPainter::CompositionMode_Exclusion:
115 case QPainter::CompositionMode_Source:
117 case QPainter::CompositionMode_DestinationOver:
119 case QPainter::CompositionMode_Clear:
121 case QPainter::CompositionMode_Destination:
123 case QPainter::CompositionMode_SourceIn:
125 case QPainter::CompositionMode_DestinationIn:
127 case QPainter::CompositionMode_SourceOut:
129 case QPainter::CompositionMode_DestinationOut:
131 case QPainter::CompositionMode_SourceAtop:
133 case QPainter::CompositionMode_DestinationAtop:
135 case QPainter::CompositionMode_Xor:
137 default:
138 QgsDebugError( QStringLiteral( "Composition mode %1 mapped to Normal" ).arg( blendMode ) );
140 }
141}
142
177
178QTransform QgsPainting::triangleToTriangleTransform( double inX1, double inY1, double inX2, double inY2, double inX3, double inY3, double outX1, double outY1, double outX2, double outY2, double outX3, double outY3, bool &ok )
179{
180 // QTransform maps points using X' = X * T (not X' = T * X !)
181 // So we are trying to solve the equation: U * T = V, where U = input triangle and V = output triangle
182 // Hence T = U^(-1) * V
183
184 const QTransform U(
185 inX1, inY1, 1,
186 inX2, inY2, 1,
187 inX3, inY3, 1 );
188
189 const QTransform V(
190 outX1, outY1, 1,
191 outX2, outY2, 1,
192 outX3, outY3, 1
193 );
194
195 return ( U.inverted( &ok ) ) * V;
196}
197
198bool QgsPainting::drawTriangleUsingTexture( QPainter *painter, const QPolygonF &triangle, const QImage &textureImage, float textureX1, float textureY1, float textureX2, float textureY2, float textureX3, float textureY3 )
199{
200 bool ok = false;
201 const QTransform brushTransform = triangleToTriangleTransform(
202 textureX1 * ( textureImage.width() - 1 ), textureY1 * ( textureImage.height() - 1 ),
203 textureX2 * ( textureImage.width() - 1 ), textureY2 * ( textureImage.height() - 1 ),
204 textureX3 * ( textureImage.width() - 1 ), textureY3 * ( textureImage.height() - 1 ),
205 triangle.at( 0 ).x(), triangle.at( 0 ).y(),
206 triangle.at( 1 ).x(), triangle.at( 1 ).y(),
207 triangle.at( 2 ).x(), triangle.at( 2 ).y(),
208 ok
209 );
210 if ( !ok )
211 return false;
212
213 // only store/restore the painter's current brush -- this is cheaper than saving/restoring the whole painter state
214 const QBrush previousBrush = painter->brush();
215
216 QBrush textureBrush( textureImage );
217 textureBrush.setTransform( brushTransform );
218
219 painter->setBrush( textureBrush );
220 painter->drawPolygon( triangle );
221 painter->setBrush( previousBrush );
222
223 return true;
224}
225
227{
228 return qt_defaultDpiX();
229}
230
232{
233 return qt_defaultDpiY();
234}
235
237{
238 // QPicture makes an assumption that we drawing to it with system DPI.
239 // Then when being drawn, it scales the painter. The following call
240 // negates the effect. There is no way of setting QPicture's DPI.
241 // See QTBUG-20361
242 painter->scale( static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX(),
243 static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY() );
244}
245
246void QgsPainting::drawPicture( QPainter *painter, const QPointF &point, const QPicture &picture )
247{
248 // QPicture makes an assumption that we drawing to it with system DPI.
249 // Then when being drawn, it scales the painter. The following call
250 // negates the effect. There is no way of setting QPicture's DPI.
251 // See QTBUG-20361
252 const double xScale = static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX();
253 const double yScale = static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY();
254 painter->scale( xScale, yScale );
255 painter->drawPicture( QPointF( point.x() / xScale, point.y() / yScale ), picture );
256 painter->scale( 1 / xScale, 1 / yScale );
257}
BlendMode
Blending modes defining the available composition modes that can be used when painting.
Definition qgis.h:4380
@ SoftLight
Soft light.
@ Destination
Destination.
@ Lighten
Lighten.
@ Subtract
Subtract.
@ Difference
Difference.
@ SourceOut
Source out.
@ DestinationOut
Destination out.
@ DestinationIn
Destination in.
@ Overlay
Overlay.
@ SourceIn
Source in.
@ Addition
Addition.
@ DestinationOver
Destination over.
@ SourceAtop
Source atop.
@ DestinationAtop
Destination atop.
@ HardLight
Hard light.
@ Multiply
Multiple.
static bool drawTriangleUsingTexture(QPainter *painter, const QPolygonF &triangle, const QImage &textureImage, float textureX1, float textureY1, float textureX2, float textureY2, float textureX3, float textureY3)
Draws a triangle onto a painter using a mapped texture image.
static int qtDefaultDpiY()
Returns the default Qt vertical DPI.
static Qgis::BlendMode getBlendModeEnum(QPainter::CompositionMode blendMode)
Returns a Qgis::BlendMode corresponding to a QPainter::CompositionMode.
static bool isClippingMode(Qgis::BlendMode mode)
Returns true if mode is a clipping blend mode.
static int qtDefaultDpiX()
Returns the default Qt horizontal DPI.
static QTransform triangleToTriangleTransform(double inX1, double inY1, double inX2, double inY2, double inX3, double inY3, double outX1, double outY1, double outX2, double outY2, double outX3, double outY3, bool &ok)
Calculates the QTransform which maps the triangle defined by the points (inX1, inY1),...
static QPainter::CompositionMode getCompositionMode(Qgis::BlendMode blendMode)
Returns a QPainter::CompositionMode corresponding to a Qgis::BlendMode.
static void applyScaleFixForQPictureDpi(QPainter *painter)
Applies a workaround to a painter to avoid an issue with incorrect scaling when drawing QPictures.
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...
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
Definition qgis.h:5843
#define QgsDebugError(str)
Definition qgslogger.h:38
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()