QGIS API Documentation 3.99.0-Master (21b3aa880ba)
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
18#include "qgslogger.h"
19
20#include <QTransform>
21
22Q_GUI_EXPORT extern int qt_defaultDpiX();
23Q_GUI_EXPORT extern int qt_defaultDpiY();
24
25QPainter::CompositionMode QgsPainting::getCompositionMode( Qgis::BlendMode blendMode )
26{
27 // Map Qgis::BlendMode::Normal to QPainter::CompositionMode
28 switch ( blendMode )
29 {
31 return QPainter::CompositionMode_SourceOver;
33 return QPainter::CompositionMode_Lighten;
35 return QPainter::CompositionMode_Screen;
37 return QPainter::CompositionMode_ColorDodge;
39 return QPainter::CompositionMode_Plus;
41 return QPainter::CompositionMode_Darken;
43 return QPainter::CompositionMode_Multiply;
45 return QPainter::CompositionMode_ColorBurn;
47 return QPainter::CompositionMode_Overlay;
49 return QPainter::CompositionMode_SoftLight;
51 return QPainter::CompositionMode_HardLight;
53 return QPainter::CompositionMode_Difference;
55 return QPainter::CompositionMode_Exclusion;
57 return QPainter::CompositionMode_Source;
59 return QPainter::CompositionMode_DestinationOver;
61 return QPainter::CompositionMode_Clear;
63 return QPainter::CompositionMode_Destination;
65 return QPainter::CompositionMode_SourceIn;
67 return QPainter::CompositionMode_DestinationIn;
69 return QPainter::CompositionMode_SourceOut;
71 return QPainter::CompositionMode_DestinationOut;
73 return QPainter::CompositionMode_SourceAtop;
75 return QPainter::CompositionMode_DestinationAtop;
77 return QPainter::CompositionMode_Xor;
78 default:
79 QgsDebugError( QStringLiteral( "Blend mode %1 mapped to SourceOver" ).arg( qgsEnumValueToKey( blendMode ) ) );
80 return QPainter::CompositionMode_SourceOver;
81 }
82}
83
84
85Qgis::BlendMode QgsPainting::getBlendModeEnum( QPainter::CompositionMode blendMode )
86{
87 // Map QPainter::CompositionMode to Qgis::BlendMode::Normal
88 switch ( blendMode )
89 {
90 case QPainter::CompositionMode_SourceOver:
92 case QPainter::CompositionMode_Lighten:
94 case QPainter::CompositionMode_Screen:
96 case QPainter::CompositionMode_ColorDodge:
98 case QPainter::CompositionMode_Plus:
100 case QPainter::CompositionMode_Darken:
102 case QPainter::CompositionMode_Multiply:
104 case QPainter::CompositionMode_ColorBurn:
106 case QPainter::CompositionMode_Overlay:
108 case QPainter::CompositionMode_SoftLight:
110 case QPainter::CompositionMode_HardLight:
112 case QPainter::CompositionMode_Difference:
114 case QPainter::CompositionMode_Exclusion:
116 case QPainter::CompositionMode_Source:
118 case QPainter::CompositionMode_DestinationOver:
120 case QPainter::CompositionMode_Clear:
122 case QPainter::CompositionMode_Destination:
124 case QPainter::CompositionMode_SourceIn:
126 case QPainter::CompositionMode_DestinationIn:
128 case QPainter::CompositionMode_SourceOut:
130 case QPainter::CompositionMode_DestinationOut:
132 case QPainter::CompositionMode_SourceAtop:
134 case QPainter::CompositionMode_DestinationAtop:
136 case QPainter::CompositionMode_Xor:
138 default:
139 QgsDebugError( QStringLiteral( "Composition mode %1 mapped to Normal" ).arg( blendMode ) );
141 }
142}
143
178
179QTransform 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 )
180{
181 // QTransform maps points using X' = X * T (not X' = T * X !)
182 // So we are trying to solve the equation: U * T = V, where U = input triangle and V = output triangle
183 // Hence T = U^(-1) * V
184
185 const QTransform U(
186 inX1, inY1, 1,
187 inX2, inY2, 1,
188 inX3, inY3, 1 );
189
190 const QTransform V(
191 outX1, outY1, 1,
192 outX2, outY2, 1,
193 outX3, outY3, 1
194 );
195
196 return ( U.inverted( &ok ) ) * V;
197}
198
199bool QgsPainting::drawTriangleUsingTexture( QPainter *painter, const QPolygonF &triangle, const QImage &textureImage, float textureX1, float textureY1, float textureX2, float textureY2, float textureX3, float textureY3 )
200{
201 bool ok = false;
202 const QTransform brushTransform = triangleToTriangleTransform(
203 textureX1 * ( textureImage.width() - 1 ), textureY1 * ( textureImage.height() - 1 ),
204 textureX2 * ( textureImage.width() - 1 ), textureY2 * ( textureImage.height() - 1 ),
205 textureX3 * ( textureImage.width() - 1 ), textureY3 * ( textureImage.height() - 1 ),
206 triangle.at( 0 ).x(), triangle.at( 0 ).y(),
207 triangle.at( 1 ).x(), triangle.at( 1 ).y(),
208 triangle.at( 2 ).x(), triangle.at( 2 ).y(),
209 ok
210 );
211 if ( !ok )
212 return false;
213
214 // only store/restore the painter's current brush -- this is cheaper than saving/restoring the whole painter state
215 const QBrush previousBrush = painter->brush();
216
217 QBrush textureBrush( textureImage );
218 textureBrush.setTransform( brushTransform );
219
220 painter->setBrush( textureBrush );
221 painter->drawPolygon( triangle );
222 painter->setBrush( previousBrush );
223
224 return true;
225}
226
228{
229 return qt_defaultDpiX();
230}
231
233{
234 return qt_defaultDpiY();
235}
236
238{
239 // QPicture makes an assumption that we drawing to it with system DPI.
240 // Then when being drawn, it scales the painter. The following call
241 // negates the effect. There is no way of setting QPicture's DPI.
242 // See QTBUG-20361
243 painter->scale( static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX(),
244 static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY() );
245}
246
247void QgsPainting::drawPicture( QPainter *painter, const QPointF &point, const QPicture &picture )
248{
249 // QPicture makes an assumption that we drawing to it with system DPI.
250 // Then when being drawn, it scales the painter. The following call
251 // negates the effect. There is no way of setting QPicture's DPI.
252 // See QTBUG-20361
253 const double xScale = static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX();
254 const double yScale = static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY();
255 painter->scale( xScale, yScale );
256 painter->drawPicture( QPointF( point.x() / xScale, point.y() / yScale ), picture );
257 painter->scale( 1 / xScale, 1 / yScale );
258}
BlendMode
Blending modes defining the available composition modes that can be used when painting.
Definition qgis.h:4930
@ SoftLight
Soft light.
Definition qgis.h:4940
@ Burn
Burn.
Definition qgis.h:4938
@ Destination
Destination.
Definition qgis.h:4947
@ Lighten
Lighten.
Definition qgis.h:4932
@ Subtract
Subtract.
Definition qgis.h:4943
@ Difference
Difference.
Definition qgis.h:4942
@ Screen
Screen.
Definition qgis.h:4933
@ SourceOut
Source out.
Definition qgis.h:4950
@ DestinationOut
Destination out.
Definition qgis.h:4951
@ DestinationIn
Destination in.
Definition qgis.h:4949
@ Overlay
Overlay.
Definition qgis.h:4939
@ SourceIn
Source in.
Definition qgis.h:4948
@ Addition
Addition.
Definition qgis.h:4935
@ DestinationOver
Destination over.
Definition qgis.h:4945
@ SourceAtop
Source atop.
Definition qgis.h:4952
@ DestinationAtop
Destination atop.
Definition qgis.h:4953
@ Normal
Normal.
Definition qgis.h:4931
@ Dodge
Dodge.
Definition qgis.h:4934
@ HardLight
Hard light.
Definition qgis.h:4941
@ Clear
Clear.
Definition qgis.h:4946
@ Multiply
Multiple.
Definition qgis.h:4937
@ Source
Source.
Definition qgis.h:4944
@ Darken
Darken.
Definition qgis.h:4936
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:6798
#define QgsDebugError(str)
Definition qgslogger.h:57
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()