QGIS API Documentation 3.99.0-Master (d270888f95f)
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 <QString>
21#include <QTransform>
22
23using namespace Qt::StringLiterals;
24
25Q_GUI_EXPORT extern int qt_defaultDpiX();
26Q_GUI_EXPORT extern int qt_defaultDpiY();
27
28QPainter::CompositionMode QgsPainting::getCompositionMode( Qgis::BlendMode blendMode )
29{
30 // Map Qgis::BlendMode::Normal to QPainter::CompositionMode
31 switch ( blendMode )
32 {
34 return QPainter::CompositionMode_SourceOver;
36 return QPainter::CompositionMode_Lighten;
38 return QPainter::CompositionMode_Screen;
40 return QPainter::CompositionMode_ColorDodge;
42 return QPainter::CompositionMode_Plus;
44 return QPainter::CompositionMode_Darken;
46 return QPainter::CompositionMode_Multiply;
48 return QPainter::CompositionMode_ColorBurn;
50 return QPainter::CompositionMode_Overlay;
52 return QPainter::CompositionMode_SoftLight;
54 return QPainter::CompositionMode_HardLight;
56 return QPainter::CompositionMode_Difference;
58 return QPainter::CompositionMode_Exclusion;
60 return QPainter::CompositionMode_Source;
62 return QPainter::CompositionMode_DestinationOver;
64 return QPainter::CompositionMode_Clear;
66 return QPainter::CompositionMode_Destination;
68 return QPainter::CompositionMode_SourceIn;
70 return QPainter::CompositionMode_DestinationIn;
72 return QPainter::CompositionMode_SourceOut;
74 return QPainter::CompositionMode_DestinationOut;
76 return QPainter::CompositionMode_SourceAtop;
78 return QPainter::CompositionMode_DestinationAtop;
80 return QPainter::CompositionMode_Xor;
81 default:
82 QgsDebugError( u"Blend mode %1 mapped to SourceOver"_s.arg( qgsEnumValueToKey( blendMode ) ) );
83 return QPainter::CompositionMode_SourceOver;
84 }
85}
86
87
88Qgis::BlendMode QgsPainting::getBlendModeEnum( QPainter::CompositionMode blendMode )
89{
90 // Map QPainter::CompositionMode to Qgis::BlendMode::Normal
91 switch ( blendMode )
92 {
93 case QPainter::CompositionMode_SourceOver:
95 case QPainter::CompositionMode_Lighten:
97 case QPainter::CompositionMode_Screen:
99 case QPainter::CompositionMode_ColorDodge:
101 case QPainter::CompositionMode_Plus:
103 case QPainter::CompositionMode_Darken:
105 case QPainter::CompositionMode_Multiply:
107 case QPainter::CompositionMode_ColorBurn:
109 case QPainter::CompositionMode_Overlay:
111 case QPainter::CompositionMode_SoftLight:
113 case QPainter::CompositionMode_HardLight:
115 case QPainter::CompositionMode_Difference:
117 case QPainter::CompositionMode_Exclusion:
119 case QPainter::CompositionMode_Source:
121 case QPainter::CompositionMode_DestinationOver:
123 case QPainter::CompositionMode_Clear:
125 case QPainter::CompositionMode_Destination:
127 case QPainter::CompositionMode_SourceIn:
129 case QPainter::CompositionMode_DestinationIn:
131 case QPainter::CompositionMode_SourceOut:
133 case QPainter::CompositionMode_DestinationOut:
135 case QPainter::CompositionMode_SourceAtop:
137 case QPainter::CompositionMode_DestinationAtop:
139 case QPainter::CompositionMode_Xor:
141 default:
142 QgsDebugError( u"Composition mode %1 mapped to Normal"_s.arg( blendMode ) );
144 }
145}
146
181
182QTransform 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 )
183{
184 // QTransform maps points using X' = X * T (not X' = T * X !)
185 // So we are trying to solve the equation: U * T = V, where U = input triangle and V = output triangle
186 // Hence T = U^(-1) * V
187
188 const QTransform U(
189 inX1, inY1, 1,
190 inX2, inY2, 1,
191 inX3, inY3, 1 );
192
193 const QTransform V(
194 outX1, outY1, 1,
195 outX2, outY2, 1,
196 outX3, outY3, 1
197 );
198
199 return ( U.inverted( &ok ) ) * V;
200}
201
202bool QgsPainting::drawTriangleUsingTexture( QPainter *painter, const QPolygonF &triangle, const QImage &textureImage, float textureX1, float textureY1, float textureX2, float textureY2, float textureX3, float textureY3 )
203{
204 bool ok = false;
205 const QTransform brushTransform = triangleToTriangleTransform(
206 textureX1 * ( textureImage.width() - 1 ), textureY1 * ( textureImage.height() - 1 ),
207 textureX2 * ( textureImage.width() - 1 ), textureY2 * ( textureImage.height() - 1 ),
208 textureX3 * ( textureImage.width() - 1 ), textureY3 * ( textureImage.height() - 1 ),
209 triangle.at( 0 ).x(), triangle.at( 0 ).y(),
210 triangle.at( 1 ).x(), triangle.at( 1 ).y(),
211 triangle.at( 2 ).x(), triangle.at( 2 ).y(),
212 ok
213 );
214 if ( !ok )
215 return false;
216
217 // only store/restore the painter's current brush -- this is cheaper than saving/restoring the whole painter state
218 const QBrush previousBrush = painter->brush();
219
220 QBrush textureBrush( textureImage );
221 textureBrush.setTransform( brushTransform );
222
223 painter->setBrush( textureBrush );
224 painter->drawPolygon( triangle );
225 painter->setBrush( previousBrush );
226
227 return true;
228}
229
231{
232 return qt_defaultDpiX();
233}
234
236{
237 return qt_defaultDpiY();
238}
239
241{
242 // QPicture makes an assumption that we drawing to it with system DPI.
243 // Then when being drawn, it scales the painter. The following call
244 // negates the effect. There is no way of setting QPicture's DPI.
245 // See QTBUG-20361
246 painter->scale( static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX(),
247 static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY() );
248}
249
250void QgsPainting::drawPicture( QPainter *painter, const QPointF &point, const QPicture &picture )
251{
252 // QPicture makes an assumption that we drawing to it with system DPI.
253 // Then when being drawn, it scales the painter. The following call
254 // negates the effect. There is no way of setting QPicture's DPI.
255 // See QTBUG-20361
256 const double xScale = static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX();
257 const double yScale = static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY();
258 painter->scale( xScale, yScale );
259 painter->drawPicture( QPointF( point.x() / xScale, point.y() / yScale ), picture );
260 painter->scale( 1 / xScale, 1 / yScale );
261}
BlendMode
Blending modes defining the available composition modes that can be used when painting.
Definition qgis.h:5002
@ SoftLight
Soft light.
Definition qgis.h:5012
@ Burn
Burn.
Definition qgis.h:5010
@ Destination
Destination.
Definition qgis.h:5019
@ Lighten
Lighten.
Definition qgis.h:5004
@ Subtract
Subtract.
Definition qgis.h:5015
@ Difference
Difference.
Definition qgis.h:5014
@ Screen
Screen.
Definition qgis.h:5005
@ SourceOut
Source out.
Definition qgis.h:5022
@ DestinationOut
Destination out.
Definition qgis.h:5023
@ DestinationIn
Destination in.
Definition qgis.h:5021
@ Overlay
Overlay.
Definition qgis.h:5011
@ SourceIn
Source in.
Definition qgis.h:5020
@ Addition
Addition.
Definition qgis.h:5007
@ DestinationOver
Destination over.
Definition qgis.h:5017
@ SourceAtop
Source atop.
Definition qgis.h:5024
@ DestinationAtop
Destination atop.
Definition qgis.h:5025
@ Normal
Normal.
Definition qgis.h:5003
@ Dodge
Dodge.
Definition qgis.h:5006
@ HardLight
Hard light.
Definition qgis.h:5013
@ Clear
Clear.
Definition qgis.h:5018
@ Multiply
Multiple.
Definition qgis.h:5009
@ Source
Source.
Definition qgis.h:5016
@ Darken
Darken.
Definition qgis.h:5008
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:7091
#define QgsDebugError(str)
Definition qgslogger.h:59
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()