Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qpolygonclipper_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#pragma once
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of other Qt classes. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qrect.h>
19#include <QtGui/private/qdatabuffer_p.h>
20
22
23/* based on sutherland-hodgman line-by-line clipping, as described in
24 Computer Graphics and Principles */
25template <typename InType, typename OutType, typename CastType> class QPolygonClipper
26{
27public:
28 QPolygonClipper() :
29 buffer1(0), buffer2(0)
30 {
31 x1 = y1 = x2 = y2 = 0;
32 }
33
34 ~QPolygonClipper()
35 {
36 }
37
38 void setBoundingRect(const QRect bounds)
39 {
40 x1 = bounds.x();
41 x2 = bounds.x() + bounds.width();
42 y1 = bounds.y();
43 y2 = bounds.y() + bounds.height();
44 }
45
46 QRect boundingRect()
47 {
48 return QRect(QPoint(x1, y1), QPoint(x2, y2));
49 }
50
51 inline OutType intersectLeft(const OutType &p1, const OutType &p2)
52 {
53 OutType t;
54 qreal dy = (p1.y - p2.y) / qreal(p1.x - p2.x);
55 t.x = x1;
56 t.y = static_cast<CastType>(p2.y + (x1 - p2.x) * dy);
57 return t;
58 }
59
60
61 inline OutType intersectRight(const OutType &p1, const OutType &p2)
62 {
63 OutType t;
64 qreal dy = (p1.y - p2.y) / qreal(p1.x - p2.x);
65 t.x = x2;
66 t.y = static_cast<CastType>(p2.y + (x2 - p2.x) * dy);
67 return t;
68 }
69
70
71 inline OutType intersectTop(const OutType &p1, const OutType &p2)
72 {
73 OutType t;
74 qreal dx = (p1.x - p2.x) / qreal(p1.y - p2.y);
75 t.x = static_cast<CastType>(p2.x + (y1 - p2.y) * dx);
76 t.y = y1;
77 return t;
78 }
79
80
81 inline OutType intersectBottom(const OutType &p1, const OutType &p2)
82 {
83 OutType t;
84 qreal dx = (p1.x - p2.x) / qreal(p1.y - p2.y);
85 t.x = static_cast<CastType>(p2.x + (y2 - p2.y) * dx);
86 t.y = y2;
87 return t;
88 }
89
90
91 void clipPolygon(const InType *inPoints, int inCount, OutType **outPoints, int *outCount,
92 bool closePolygon = true)
93 {
94 Q_ASSERT(outPoints);
95 Q_ASSERT(outCount);
96
97 if (inCount < 2) {
98 *outCount = 0;
99 return;
100 }
101
102 buffer1.reset();
103 buffer2.reset();
104
105 QDataBuffer<OutType> *source = &buffer1;
106 QDataBuffer<OutType> *clipped = &buffer2;
107
108 // Gather some info since we are iterating through the points anyway..
109 bool doLeft = false, doRight = false, doTop = false, doBottom = false;
110 OutType ot;
111 for (int i=0; i<inCount; ++i) {
112 ot = inPoints[i];
113 clipped->add(ot);
114
115 if (ot.x < x1)
116 doLeft = true;
117 else if (ot.x > x2)
118 doRight = true;
119 if (ot.y < y1)
120 doTop = true;
121 else if (ot.y > y2)
122 doBottom = true;
123 }
124
125 if (doLeft && clipped->size() > 1) {
126 QDataBuffer<OutType> *tmp = source;
127 source = clipped;
128 clipped = tmp;
129 clipped->reset();
130 int lastPos, start;
131 if (closePolygon) {
132 lastPos = source->size() - 1;
133 start = 0;
134 } else {
135 lastPos = 0;
136 start = 1;
137 if (source->at(0).x >= x1)
138 clipped->add(source->at(0));
139 }
140 for (int i=start; i<inCount; ++i) {
141 const OutType &cpt = source->at(i);
142 const OutType &ppt = source->at(lastPos);
143
144 if (cpt.x >= x1) {
145 if (ppt.x >= x1) {
146 clipped->add(cpt);
147 } else {
148 clipped->add(intersectLeft(cpt, ppt));
149 clipped->add(cpt);
150 }
151 } else if (ppt.x >= x1) {
152 clipped->add(intersectLeft(cpt, ppt));
153 }
154 lastPos = i;
155 }
156 }
157
158 if (doRight && clipped->size() > 1) {
159 QDataBuffer<OutType> *tmp = source;
160 source = clipped;
161 clipped = tmp;
162 clipped->reset();
163 int lastPos, start;
164 if (closePolygon) {
165 lastPos = source->size() - 1;
166 start = 0;
167 } else {
168 lastPos = 0;
169 start = 1;
170 if (source->at(0).x <= x2)
171 clipped->add(source->at(0));
172 }
173 for (int i=start; i<source->size(); ++i) {
174 const OutType &cpt = source->at(i);
175 const OutType &ppt = source->at(lastPos);
176
177 if (cpt.x <= x2) {
178 if (ppt.x <= x2) {
179 clipped->add(cpt);
180 } else {
181 clipped->add(intersectRight(cpt, ppt));
182 clipped->add(cpt);
183 }
184 } else if (ppt.x <= x2) {
185 clipped->add(intersectRight(cpt, ppt));
186 }
187
188 lastPos = i;
189 }
190
191 }
192
193 if (doTop && clipped->size() > 1) {
194 QDataBuffer<OutType> *tmp = source;
195 source = clipped;
196 clipped = tmp;
197 clipped->reset();
198 int lastPos, start;
199 if (closePolygon) {
200 lastPos = source->size() - 1;
201 start = 0;
202 } else {
203 lastPos = 0;
204 start = 1;
205 if (source->at(0).y >= y1)
206 clipped->add(source->at(0));
207 }
208 for (int i=start; i<source->size(); ++i) {
209 const OutType &cpt = source->at(i);
210 const OutType &ppt = source->at(lastPos);
211
212 if (cpt.y >= y1) {
213 if (ppt.y >= y1) {
214 clipped->add(cpt);
215 } else {
216 clipped->add(intersectTop(cpt, ppt));
217 clipped->add(cpt);
218 }
219 } else if (ppt.y >= y1) {
220 clipped->add(intersectTop(cpt, ppt));
221 }
222
223 lastPos = i;
224 }
225 }
226
227 if (doBottom && clipped->size() > 1) {
228 QDataBuffer<OutType> *tmp = source;
229 source = clipped;
230 clipped = tmp;
231 clipped->reset();
232 int lastPos, start;
233 if (closePolygon) {
234 lastPos = source->size() - 1;
235 start = 0;
236 } else {
237 lastPos = 0;
238 start = 1;
239 if (source->at(0).y <= y2)
240 clipped->add(source->at(0));
241 }
242 for (int i=start; i<source->size(); ++i) {
243 const OutType &cpt = source->at(i);
244 const OutType &ppt = source->at(lastPos);
245
246 if (cpt.y <= y2) {
247 if (ppt.y <= y2) {
248 clipped->add(cpt);
249 } else {
250 clipped->add(intersectBottom(cpt, ppt));
251 clipped->add(cpt);
252 }
253 } else if (ppt.y <= y2) {
254 clipped->add(intersectBottom(cpt, ppt));
255 }
256 lastPos = i;
257 }
258 }
259
260 if (closePolygon && clipped->size() > 0) {
261 // close clipped polygon
262 if (clipped->at(0).x != clipped->at(clipped->size()-1).x ||
263 clipped->at(0).y != clipped->at(clipped->size()-1).y) {
264 OutType ot = clipped->at(0);
265 clipped->add(ot);
266 }
267 }
268 *outCount = clipped->size();
269 *outPoints = clipped->data();
270 }
271
272private:
273 int x1, x2, y1, y2;
274 QDataBuffer<OutType> buffer1;
275 QDataBuffer<OutType> buffer2;
276};
277
278QT_END_NAMESPACE
void systemStateChanged() override
QPolygonClipper< qt_float_point, qt_float_point, float > polygonClipper
void setupAdaptedOrigin(const QPoint &p)
void fillPolygon_translated(const QPointF *points, int pointCount, GCMode gcMode, QPaintEngine::PolygonDrawMode mode)
void clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly)
QTransform::TransformationType txop
void strokePolygon_dev(const QPointF *points, int pointCount, bool close)
const QXcbX11Info * xinfo
void fillPath(const QPainterPath &path, GCMode gcmode, bool transform)
void strokePolygon_translated(const QPointF *points, int pointCount, bool close)
void fillPolygon_dev(const QPointF *points, int pointCount, GCMode gcMode, QPaintEngine::PolygonDrawMode mode)
friend GC qt_x11_get_pen_gc(QPainter *)
Returns the X11 specific pen GC for the painter p.
void updateState(const QPaintEngineState &state) override
Reimplement this function to update the state of a paint engine.
void drawTextItem(const QPointF &p, const QTextItem &textItem) override
This function draws the text item textItem at position p.
void drawLines(const QLine *lines, int lineCount) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool begin(QPaintDevice *pdev) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
void updateBrush(const QBrush &brush, const QPointF &pt)
void updateClipRegion_dev(const QRegion &region, Qt::ClipOperation op)
void updateFont(const QFont &font)
virtual Drawable handle() const
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
QX11PaintEngine(QX11PaintEnginePrivate &dptr)
void drawRects(const QRect *rects, int rectCount) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
void updateMatrix(const QTransform &matrix)
Type type() const override
Reimplement this function to return the paint engine \l{Type}.
QPainter::RenderHints supportedRenderHints() const
void updateRenderHints(QPainter::RenderHints hints)
void drawPath(const QPainterPath &path) override
The default implementation ignores the path and does nothing.
void drawPoints(const QPoint *points, int pointCount) override
Draws the first pointCount points in the buffer points.
friend GC qt_x11_get_brush_gc(QPainter *)
Returns the X11 specific brush GC for the painter p.
virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override
Reimplement this function to draw the pixmap in the given rect, starting at the given p.
void updatePen(const QPen &pen)
void drawImage(const QRectF &r, const QImage &img, const QRectF &sr, Qt::ImageConversionFlags flags=Qt::AutoColor) override
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
bool end() override
Reimplement this function to finish painting on the current paint device.
void drawEllipse(const QRect &r) override
This is an overloaded member function, provided for convenience. It differs from the above function o...
friend const QXcbX11Info & qt_x11Info(const QPixmap &pixmap)
static Display * display()
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
static void setCapStyle(int cap_style, GC gc)
static void x11SetClipRegion(Display *dpy, GC gc, GC gc2, Qt::HANDLE picture, const QRegion &r)
static const qreal aliasedCoordinateDelta
#define X11
static QPaintEngine::PaintEngineFeatures qt_decide_features()
Q_GUI_EXPORT void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, Drawable hd, GC gc, Display *dpy, Visual *visual, int depth)
static QLine clipStraightLine(const QRect &clip, const QLine &l)
#define DITHER_SIZE
QPixmap qt_toX11Pixmap(const QPixmap &pixmap)
static void x11ClearClipRegion(Display *dpy, GC gc, GC gc2, Qt::HANDLE picture)
static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE]
static const QXcbX11Info * qt_x11Info(const QPaintDevice *pd)
void qt_draw_tile(QPaintEngine *, qreal, qreal, qreal, qreal, const QPixmap &, qreal, qreal)
static QPixmap qt_patternForAlpha(uchar alpha, int screen)
static bool clipLine(QLineF *line, const QRect &rect)
struct _XGC * GC
XID Drawable
QPixmap qt_pixmapForBrush(int style, bool invert)
Definition qbrush.cpp:80
XID Pixmap
int qt_x11SetDefaultScreen(int screen)
QT_BEGIN_NAMESPACE QPainterPath qt_regionToPath(const QRegion &region)
Definition qregion.cpp:1010
#define EvenOddRule
Definition qregion.cpp:1604
#define WindingRule
Definition qregion.cpp:1605
#define Q_XCB_EXPORT
Definition qxcbexport.h:14
void write(QChar *&dest) const
HexString(const T t)
static int size(const HexString< T > &)
static void appendTo(const HexString< T > &str, QChar *&out)
bool use_xrender
Definition qt_x11_p.h:94