QGIS API Documentation 4.1.0-Master (60fea48833c)
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
183 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
184)
185{
186 // QTransform maps points using X' = X * T (not X' = T * X !)
187 // So we are trying to solve the equation: U * T = V, where U = input triangle and V = output triangle
188 // Hence T = U^(-1) * V
189
190 const QTransform U( inX1, inY1, 1, inX2, inY2, 1, inX3, inY3, 1 );
191
192 const QTransform V( outX1, outY1, 1, outX2, outY2, 1, outX3, outY3, 1 );
193
194 return ( U.inverted( &ok ) ) * V;
195}
196
198 QPainter *painter, const QPolygonF &triangle, const QImage &textureImage, float textureX1, float textureY1, float textureX2, float textureY2, float textureX3, float textureY3
199)
200{
201 bool ok = false;
202 const QTransform brushTransform = triangleToTriangleTransform(
203 textureX1 * ( textureImage.width() - 1 ),
204 textureY1 * ( textureImage.height() - 1 ),
205 textureX2 * ( textureImage.width() - 1 ),
206 textureY2 * ( textureImage.height() - 1 ),
207 textureX3 * ( textureImage.width() - 1 ),
208 textureY3 * ( textureImage.height() - 1 ),
209 triangle.at( 0 ).x(),
210 triangle.at( 0 ).y(),
211 triangle.at( 1 ).x(),
212 triangle.at( 1 ).y(),
213 triangle.at( 2 ).x(),
214 triangle.at( 2 ).y(),
215 ok
216 );
217 if ( !ok )
218 return false;
219
220 // only store/restore the painter's current brush -- this is cheaper than saving/restoring the whole painter state
221 const QBrush previousBrush = painter->brush();
222
223 QBrush textureBrush( textureImage );
224 textureBrush.setTransform( brushTransform );
225
226 painter->setBrush( textureBrush );
227 painter->drawPolygon( triangle );
228 painter->setBrush( previousBrush );
229
230 return true;
231}
232
234{
235 return qt_defaultDpiX();
236}
237
239{
240 return qt_defaultDpiY();
241}
242
244{
245 // QPicture makes an assumption that we drawing to it with system DPI.
246 // Then when being drawn, it scales the painter. The following call
247 // negates the effect. There is no way of setting QPicture's DPI.
248 // See QTBUG-20361
249 painter->scale( static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX(), static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY() );
250}
251
252void QgsPainting::drawPicture( QPainter *painter, const QPointF &point, const QPicture &picture )
253{
254 // QPicture makes an assumption that we drawing to it with system DPI.
255 // Then when being drawn, it scales the painter. The following call
256 // negates the effect. There is no way of setting QPicture's DPI.
257 // See QTBUG-20361
258 const double xScale = static_cast< double >( QgsPainting::qtDefaultDpiX() ) / painter->device()->logicalDpiX();
259 const double yScale = static_cast< double >( QgsPainting::qtDefaultDpiY() ) / painter->device()->logicalDpiY();
260 painter->scale( xScale, yScale );
261 painter->drawPicture( QPointF( point.x() / xScale, point.y() / yScale ), picture );
262 painter->scale( 1 / xScale, 1 / yScale );
263}
BlendMode
Blending modes defining the available composition modes that can be used when painting.
Definition qgis.h:5087
@ SoftLight
Soft light.
Definition qgis.h:5097
@ Burn
Burn.
Definition qgis.h:5095
@ Destination
Destination.
Definition qgis.h:5104
@ Lighten
Lighten.
Definition qgis.h:5089
@ Subtract
Subtract.
Definition qgis.h:5100
@ Difference
Difference.
Definition qgis.h:5099
@ Screen
Screen.
Definition qgis.h:5090
@ SourceOut
Source out.
Definition qgis.h:5107
@ DestinationOut
Destination out.
Definition qgis.h:5108
@ DestinationIn
Destination in.
Definition qgis.h:5106
@ Overlay
Overlay.
Definition qgis.h:5096
@ SourceIn
Source in.
Definition qgis.h:5105
@ Addition
Addition.
Definition qgis.h:5092
@ DestinationOver
Destination over.
Definition qgis.h:5102
@ SourceAtop
Source atop.
Definition qgis.h:5109
@ DestinationAtop
Destination atop.
Definition qgis.h:5110
@ Normal
Normal.
Definition qgis.h:5088
@ Dodge
Dodge.
Definition qgis.h:5091
@ HardLight
Hard light.
Definition qgis.h:5098
@ Clear
Clear.
Definition qgis.h:5103
@ Multiply
Multiple.
Definition qgis.h:5094
@ Source
Source.
Definition qgis.h:5101
@ Darken
Darken.
Definition qgis.h:5093
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:7157
#define QgsDebugError(str)
Definition qgslogger.h:59
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()