Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickdrawutil.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 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
4#include "qquickdrawutil.h"
5
6#include "qbitmap.h"
7#include "qpixmapcache.h"
8#include "qpainter.h"
9#include "qpalette.h"
10#include <private/qpaintengineex_p.h>
11#include <qvarlengtharray.h>
12#include <qmath.h>
13#include <private/qhexstring_p.h>
14
16
17namespace QQC2 {
18
19namespace {
20class PainterStateGuard {
21 Q_DISABLE_COPY_MOVE(PainterStateGuard)
22public:
23 explicit PainterStateGuard(QPainter *p) : m_painter(p) {}
24 ~PainterStateGuard()
25 {
26 for ( ; m_level > 0; --m_level)
27 m_painter->restore();
28 }
29
30 void save()
31 {
32 m_painter->save();
33 ++m_level;
34 }
35
36 void restore()
37 {
38 m_painter->restore();
39 --m_level;
40 }
41
42private:
43 QPainter *m_painter;
44 int m_level= 0;
45};
46} // namespace
47
88void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
89 const QPalette &pal, bool sunken,
90 int lineWidth, int midLineWidth)
91{
92 if (Q_UNLIKELY(!p || lineWidth < 0 || midLineWidth < 0)) {
93 qWarning("qDrawShadeLine: Invalid parameters");
94 return;
95 }
96 PainterStateGuard painterGuard(p);
97 const qreal devicePixelRatio = p->device()->devicePixelRatio();
98 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
99 painterGuard.save();
100 const qreal inverseScale = qreal(1) / devicePixelRatio;
101 p->scale(inverseScale, inverseScale);
102 x1 = qRound(devicePixelRatio * x1);
103 y1 = qRound(devicePixelRatio * y1);
104 x2 = qRound(devicePixelRatio * x2);
105 y2 = qRound(devicePixelRatio * y2);
106 lineWidth = qRound(devicePixelRatio * lineWidth);
107 midLineWidth = qRound(devicePixelRatio * midLineWidth);
108 p->translate(0.5, 0.5);
109 }
110 int tlw = lineWidth*2 + midLineWidth; // total line width
111 QPen oldPen = p->pen(); // save pen
112 if (sunken)
113 p->setPen(pal.color(QPalette::Dark));
114 else
115 p->setPen(pal.light().color());
116 QPolygon a;
117 int i;
118 if (y1 == y2) { // horizontal line
119 int y = y1 - tlw/2;
120 if (x1 > x2) { // swap x1 and x2
121 int t = x1;
122 x1 = x2;
123 x2 = t;
124 }
125 x2--;
126 for (i=0; i<lineWidth; i++) { // draw top shadow
127 a.setPoints(3, x1+i, y+tlw-1-i,
128 x1+i, y+i,
129 x2-i, y+i);
130 p->drawPolyline(a);
131 }
132 if (midLineWidth > 0) {
133 p->setPen(pal.mid().color());
134 for (i=0; i<midLineWidth; i++) // draw lines in the middle
135 p->drawLine(x1+lineWidth, y+lineWidth+i,
136 x2-lineWidth, y+lineWidth+i);
137 }
138 if (sunken)
139 p->setPen(pal.light().color());
140 else
141 p->setPen(pal.dark().color());
142 for (i=0; i<lineWidth; i++) { // draw bottom shadow
143 a.setPoints(3, x1+i, y+tlw-i-1,
144 x2-i, y+tlw-i-1,
145 x2-i, y+i+1);
146 p->drawPolyline(a);
147 }
148 }
149 else if (x1 == x2) { // vertical line
150 int x = x1 - tlw/2;
151 if (y1 > y2) { // swap y1 and y2
152 int t = y1;
153 y1 = y2;
154 y2 = t;
155 }
156 y2--;
157 for (i=0; i<lineWidth; i++) { // draw left shadow
158 a.setPoints(3, x+i, y2,
159 x+i, y1+i,
160 x+tlw-1, y1+i);
161 p->drawPolyline(a);
162 }
163 if (midLineWidth > 0) {
164 p->setPen(pal.mid().color());
165 for (i=0; i<midLineWidth; i++) // draw lines in the middle
166 p->drawLine(x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2);
167 }
168 if (sunken)
169 p->setPen(pal.light().color());
170 else
171 p->setPen(pal.dark().color());
172 for (i=0; i<lineWidth; i++) { // draw right shadow
173 a.setPoints(3, x+lineWidth, y2-i,
174 x+tlw-i-1, y2-i,
175 x+tlw-i-1, y1+lineWidth);
176 p->drawPolyline(a);
177 }
178 }
179 p->setPen(oldPen);
180}
181
215void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
216 const QPalette &pal, bool sunken,
217 int lineWidth, int midLineWidth,
218 const QBrush *fill)
219{
220 if (w == 0 || h == 0)
221 return;
222 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0 || midLineWidth < 0)) {
223 qWarning("qDrawShadeRect: Invalid parameters");
224 return;
225 }
226
227 PainterStateGuard painterGuard(p);
228 const qreal devicePixelRatio = p->device()->devicePixelRatioF();
229 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
230 painterGuard.save();
231 const qreal inverseScale = qreal(1) / devicePixelRatio;
232 p->scale(inverseScale, inverseScale);
233 x = qRound(devicePixelRatio * x);
234 y = qRound(devicePixelRatio * y);
235 w = qRound(devicePixelRatio * w);
236 h = qRound(devicePixelRatio * h);
237 lineWidth = qRound(devicePixelRatio * lineWidth);
238 midLineWidth = qRound(devicePixelRatio * midLineWidth);
239 p->translate(0.5, 0.5);
240 }
241
242 QPen oldPen = p->pen();
243 if (sunken)
244 p->setPen(pal.dark().color());
245 else
246 p->setPen(pal.light().color());
247 int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
248
249 if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle
250 p->drawRect(x1, y1, w-2, h-2);
251 if (sunken)
252 p->setPen(pal.light().color());
253 else
254 p->setPen(pal.dark().color());
255 QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1),
256 QLineF(x1+1, y1+2, x1+1, y2-2),
257 QLineF(x1, y2, x2, y2),
258 QLineF(x2,y1, x2,y2-1) };
259 p->drawLines(lines, 4); // draw bottom/right lines
260 } else { // more complicated
261 int m = lineWidth+midLineWidth;
262 int i, j=0, k=m;
263 for (i=0; i<lineWidth; i++) { // draw top shadow
264 QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i),
265 QLineF(x1+i, y1+i, x2-i, y1+i),
266 QLineF(x1+k, y2-k, x2-k, y2-k),
267 QLineF(x2-k, y2-k, x2-k, y1+k) };
268 p->drawLines(lines, 4);
269 k++;
270 }
271 p->setPen(pal.mid().color());
272 j = lineWidth*2;
273 for (i=0; i<midLineWidth; i++) { // draw lines in the middle
274 p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1);
275 j += 2;
276 }
277 if (sunken)
278 p->setPen(pal.light().color());
279 else
280 p->setPen(pal.dark().color());
281 k = m;
282 for (i=0; i<lineWidth; i++) { // draw bottom shadow
283 QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i),
284 QLineF(x2-i, y2-i, x2-i, y1+i+1),
285 QLineF(x1+k, y2-k, x1+k, y1+k),
286 QLineF(x1+k, y1+k, x2-k, y1+k) };
287 p->drawLines(lines, 4);
288 k++;
289 }
290 }
291 if (fill) {
292 QBrush oldBrush = p->brush();
293 int tlw = lineWidth + midLineWidth;
294 p->setPen(Qt::NoPen);
295 p->setBrush(*fill);
296 p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw);
297 p->setBrush(oldBrush);
298 }
299 p->setPen(oldPen); // restore pen
300}
301
302
332void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
333 const QPalette &pal, bool sunken,
334 int lineWidth, const QBrush *fill)
335{
336 if (w == 0 || h == 0)
337 return;
338 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
339 qWarning("qDrawShadePanel: Invalid parameters");
340 }
341
342 PainterStateGuard painterGuard(p);
343 const qreal devicePixelRatio = p->device()->devicePixelRatioF();
344 bool isTranslated = false;
345 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
346 painterGuard.save();
347 const qreal inverseScale = qreal(1) / devicePixelRatio;
348 p->scale(inverseScale, inverseScale);
349 x = qRound(devicePixelRatio * x);
350 y = qRound(devicePixelRatio * y);
351 w = qRound(devicePixelRatio * w);
352 h = qRound(devicePixelRatio * h);
353 lineWidth = qRound(devicePixelRatio * lineWidth);
354 p->translate(0.5, 0.5);
355 isTranslated = true;
356 }
357
358 QColor shade = pal.dark().color();
359 QColor light = pal.light().color();
360 if (fill) {
361 if (fill->color() == shade)
362 shade = pal.shadow().color();
363 if (fill->color() == light)
364 light = pal.midlight().color();
365 }
366 QPen oldPen = p->pen(); // save pen
367 QVector<QLineF> lines;
368 lines.reserve(2*lineWidth);
369
370 if (sunken)
371 p->setPen(shade);
372 else
373 p->setPen(light);
374 int x1, y1, x2, y2;
375 int i;
376 x1 = x;
377 y1 = y2 = y;
378 x2 = x+w-2;
379 for (i=0; i<lineWidth; i++) { // top shadow
380 lines << QLineF(x1, y1++, x2--, y2++);
381 }
382 x2 = x1;
383 y1 = y+h-2;
384 for (i=0; i<lineWidth; i++) { // left shado
385 lines << QLineF(x1++, y1, x2++, y2--);
386 }
387 p->drawLines(lines);
388 lines.clear();
389 if (sunken)
390 p->setPen(light);
391 else
392 p->setPen(shade);
393 x1 = x;
394 y1 = y2 = y+h-1;
395 x2 = x+w-1;
396 for (i=0; i<lineWidth; i++) { // bottom shadow
397 lines << QLineF(x1++, y1--, x2, y2--);
398 }
399 x1 = x2;
400 y1 = y;
401 y2 = y+h-lineWidth-1;
402 for (i=0; i<lineWidth; i++) { // right shadow
403 lines << QLineF(x1--, y1++, x2--, y2);
404 }
405 p->drawLines(lines);
406 if (fill) { // fill with fill color
407 if (isTranslated)
408 p->translate(-0.5, -0.5);
409 p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
410 }
411 p->setPen(oldPen); // restore pen
412}
413
414
431 int x, int y, int w, int h,
432 const QColor &c1, const QColor &c2,
433 const QColor &c3, const QColor &c4,
434 const QBrush *fill)
435{
436 if (w < 2 || h < 2) // can't do anything with that
437 return;
438
439 PainterStateGuard painterGuard(p);
440 const qreal devicePixelRatio = p->device()->devicePixelRatioF();
441 bool isTranslated = false;
442 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
443 painterGuard.save();
444 const qreal inverseScale = qreal(1) / devicePixelRatio;
445 p->scale(inverseScale, inverseScale);
446 x = qRound(devicePixelRatio * x);
447 y = qRound(devicePixelRatio * y);
448 w = qRound(devicePixelRatio * w);
449 h = qRound(devicePixelRatio * h);
450 p->translate(0.5, 0.5);
451 isTranslated = true;
452 }
453
454 QPen oldPen = p->pen();
455 QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
456 p->setPen(c1);
457 p->drawPolyline(a, 3);
458 QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
459 p->setPen(c2);
460 p->drawPolyline(b, 3);
461 if (w > 4 && h > 4) {
462 QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
463 p->setPen(c3);
464 p->drawPolyline(c, 3);
465 QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
466 p->setPen(c4);
467 p->drawPolyline(d, 3);
468 if (fill) {
469 if (isTranslated)
470 p->translate(-0.5, -0.5);
471 p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
472 }
473 }
474 p->setPen(oldPen);
475}
476
477
502void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
503 const QPalette &pal, bool sunken,
504 const QBrush *fill)
505{
506 if (sunken)
507 qDrawWinShades(p, x, y, w, h,
508 pal.shadow().color(), pal.light().color(), pal.dark().color(),
509 pal.button().color(), fill);
510 else
511 qDrawWinShades(p, x, y, w, h,
512 pal.light().color(), pal.shadow().color(), pal.button().color(),
513 pal.dark().color(), fill);
514}
515
542void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
543 const QPalette &pal, bool sunken,
544 const QBrush *fill)
545{
546 if (sunken)
547 qDrawWinShades(p, x, y, w, h,
548 pal.dark().color(), pal.light().color(), pal.shadow().color(),
549 pal.midlight().color(), fill);
550 else
551 qDrawWinShades(p, x, y, w, h,
552 pal.light().color(), pal.shadow().color(), pal.midlight().color(),
553 pal.dark().color(), fill);
554}
555
578void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
579 int lineWidth, const QBrush *fill)
580{
581 if (w == 0 || h == 0)
582 return;
583 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
584 qWarning("qDrawPlainRect: Invalid parameters");
585 }
586
587 PainterStateGuard painterGuard(p);
588 const qreal devicePixelRatio = p->device()->devicePixelRatioF();
589 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
590 painterGuard.save();
591 const qreal inverseScale = qreal(1) / devicePixelRatio;
592 p->scale(inverseScale, inverseScale);
593 x = qRound(devicePixelRatio * x);
594 y = qRound(devicePixelRatio * y);
595 w = qRound(devicePixelRatio * w);
596 h = qRound(devicePixelRatio * h);
597 lineWidth = qRound(devicePixelRatio * lineWidth);
598 p->translate(0.5, 0.5);
599 }
600
601 QPen oldPen = p->pen();
602 QBrush oldBrush = p->brush();
603 p->setPen(c);
604 p->setBrush(Qt::NoBrush);
605 for (int i=0; i<lineWidth; i++)
606 p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
607 if (fill) { // fill with fill color
608 p->setPen(Qt::NoPen);
609 p->setBrush(*fill);
610 p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2);
611 }
612 p->setPen(oldPen);
613 p->setBrush(oldBrush);
614}
615
616/*****************************************************************************
617 Overloaded functions.
618 *****************************************************************************/
619
652void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
653 const QPalette &pal, bool sunken,
654 int lineWidth, int midLineWidth)
655{
656 qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken,
657 lineWidth, midLineWidth);
658}
659
692 const QPalette &pal, bool sunken,
693 int lineWidth, int midLineWidth,
694 const QBrush *fill)
695{
696 qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
697 lineWidth, midLineWidth, fill);
698}
699
729 const QPalette &pal, bool sunken,
730 int lineWidth, const QBrush *fill)
731{
732 qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
733 lineWidth, fill);
734}
735
760 const QPalette &pal, bool sunken, const QBrush *fill)
761{
762 qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
763}
764
790 const QPalette &pal, bool sunken, const QBrush *fill)
791{
792 qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
793}
794
816void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c,
817 int lineWidth, const QBrush *fill)
818{
819 qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c,
820 lineWidth, fill);
821}
822
823
861typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray;
862
878void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins,
879 const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
880 const QTileRules &rules
881#ifndef Q_QDOC
882 , QDrawBorderPixmap::DrawingHints hints
883#endif
884 )
885{
887 d.opacity = 1.0;
888 d.rotation = 0.0;
889
890 QPixmapFragmentsArray opaqueData;
891 QPixmapFragmentsArray translucentData;
892
893 // source center
894 const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
895 const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
896 const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
897 const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
898 const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
899 const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
900 // target center
901 const int targetCenterTop = targetRect.top() + targetMargins.top();
902 const int targetCenterLeft = targetRect.left() + targetMargins.left();
903 const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
904 const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
905 const int targetCenterWidth = targetCenterRight - targetCenterLeft;
906 const int targetCenterHeight = targetCenterBottom - targetCenterTop;
907
908 QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles
909 QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles
910
911 int columns = 3;
912 int rows = 3;
913 if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
914 columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
915 if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
916 rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
917
918 xTarget.resize(columns + 1);
919 yTarget.resize(rows + 1);
920
924 && oldAA && painter->combinedTransform().type() != QTransform::TxNone) {
926 }
927
928 xTarget[0] = targetRect.left();
929 xTarget[1] = targetCenterLeft;
930 xTarget[columns - 1] = targetCenterRight;
931 xTarget[columns] = targetRect.left() + targetRect.width();
932
933 yTarget[0] = targetRect.top();
934 yTarget[1] = targetCenterTop;
935 yTarget[rows - 1] = targetCenterBottom;
936 yTarget[rows] = targetRect.top() + targetRect.height();
937
938 qreal dx = targetCenterWidth;
939 qreal dy = targetCenterHeight;
940
941 switch (rules.horizontal) {
942 case Qt::StretchTile:
943 dx = targetCenterWidth;
944 break;
945 case Qt::RepeatTile:
946 dx = sourceCenterWidth;
947 break;
948 case Qt::RoundTile:
949 dx = targetCenterWidth / qreal(columns - 2);
950 break;
951 }
952
953 for (int i = 2; i < columns - 1; ++i)
954 xTarget[i] = xTarget[i - 1] + dx;
955
956 switch (rules.vertical) {
957 case Qt::StretchTile:
958 dy = targetCenterHeight;
959 break;
960 case Qt::RepeatTile:
961 dy = sourceCenterHeight;
962 break;
963 case Qt::RoundTile:
964 dy = targetCenterHeight / qreal(rows - 2);
965 break;
966 }
967
968 for (int i = 2; i < rows - 1; ++i)
969 yTarget[i] = yTarget[i - 1] + dy;
970
971 // corners
972 if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
973 d.x = (0.5 * (xTarget[1] + xTarget[0]));
974 d.y = (0.5 * (yTarget[1] + yTarget[0]));
975 d.sourceLeft = sourceRect.left();
976 d.sourceTop = sourceRect.top();
977 d.width = sourceMargins.left();
978 d.height = sourceMargins.top();
979 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
980 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
982 opaqueData.append(d);
983 else
984 translucentData.append(d);
985 }
986 if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
987 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
988 d.y = (0.5 * (yTarget[1] + yTarget[0]));
989 d.sourceLeft = sourceCenterRight;
990 d.sourceTop = sourceRect.top();
991 d.width = sourceMargins.right();
992 d.height = sourceMargins.top();
993 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
994 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
996 opaqueData.append(d);
997 else
998 translucentData.append(d);
999 }
1000 if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
1001 d.x = (0.5 * (xTarget[1] + xTarget[0]));
1002 d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
1003 d.sourceLeft = sourceRect.left();
1004 d.sourceTop = sourceCenterBottom;
1005 d.width = sourceMargins.left();
1006 d.height = sourceMargins.bottom();
1007 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
1008 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1010 opaqueData.append(d);
1011 else
1012 translucentData.append(d);
1013 }
1014 if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
1015 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
1016 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
1017 d.sourceLeft = sourceCenterRight;
1018 d.sourceTop = sourceCenterBottom;
1019 d.width = sourceMargins.right();
1020 d.height = sourceMargins.bottom();
1021 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
1022 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1024 opaqueData.append(d);
1025 else
1026 translucentData.append(d);
1027 }
1028
1029 // horizontal edges
1030 if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
1031 if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
1032 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
1033 d.sourceLeft = sourceCenterLeft;
1034 d.sourceTop = sourceRect.top();
1035 d.width = sourceCenterWidth;
1036 d.height = sourceMargins.top();
1037 d.y = (0.5 * (yTarget[1] + yTarget[0]));
1038 d.scaleX = dx / d.width;
1039 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
1040 for (int i = 1; i < columns - 1; ++i) {
1041 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1042 data.append(d);
1043 }
1044 if (rules.horizontal == Qt::RepeatTile)
1045 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
1046 }
1047 if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
1048 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
1049 d.sourceLeft = sourceCenterLeft;
1050 d.sourceTop = sourceCenterBottom;
1051 d.width = sourceCenterWidth;
1052 d.height = sourceMargins.bottom();
1053 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
1054 d.scaleX = dx / d.width;
1055 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1056 for (int i = 1; i < columns - 1; ++i) {
1057 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1058 data.append(d);
1059 }
1060 if (rules.horizontal == Qt::RepeatTile)
1061 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
1062 }
1063 }
1064
1065 // vertical edges
1066 if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
1067 if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
1068 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
1069 d.sourceLeft = sourceRect.left();
1070 d.sourceTop = sourceCenterTop;
1071 d.width = sourceMargins.left();
1072 d.height = sourceCenterHeight;
1073 d.x = (0.5 * (xTarget[1] + xTarget[0]));
1074 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
1075 d.scaleY = dy / d.height;
1076 for (int i = 1; i < rows - 1; ++i) {
1077 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
1078 data.append(d);
1079 }
1080 if (rules.vertical == Qt::RepeatTile)
1081 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
1082 }
1083 if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
1084 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
1085 d.sourceLeft = sourceCenterRight;
1086 d.sourceTop = sourceCenterTop;
1087 d.width = sourceMargins.right();
1088 d.height = sourceCenterHeight;
1089 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
1090 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
1091 d.scaleY = dy / d.height;
1092 for (int i = 1; i < rows - 1; ++i) {
1093 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
1094 data.append(d);
1095 }
1096 if (rules.vertical == Qt::RepeatTile)
1097 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
1098 }
1099 }
1100
1101 // center
1102 if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
1103 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
1104 d.sourceLeft = sourceCenterLeft;
1105 d.sourceTop = sourceCenterTop;
1106 d.width = sourceCenterWidth;
1107 d.height = sourceCenterHeight;
1108 d.scaleX = dx / d.width;
1109 d.scaleY = dy / d.height;
1110
1111 qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
1112 qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
1113
1114 for (int j = 1; j < rows - 1; ++j) {
1115 d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
1116 for (int i = 1; i < columns - 1; ++i) {
1117 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1118 data.append(d);
1119 }
1120 if (rules.horizontal == Qt::RepeatTile)
1121 data[data.size() - 1].width = repeatWidth;
1122 }
1123 if (rules.vertical == Qt::RepeatTile) {
1124 for (int i = 1; i < columns - 1; ++i)
1125 data[data.size() - i].height = repeatHeight;
1126 }
1127 }
1128
1129 if (opaqueData.size())
1130 painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
1131 if (translucentData.size())
1132 painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
1133
1134 if (oldAA)
1136}
1137
1138} // namespace QQC2
1139
\inmodule QtGui
Definition qbrush.h:30
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore\compares equality \compareswith equality QLine \endcompareswith
Definition qline.h:192
\inmodule QtCore
Definition qmargins.h:24
virtual Type type() const =0
Reimplement this function to return the paint engine \l{Type}.
This class is used in conjunction with the QPainter::drawPixmapFragments() function to specify how a ...
Definition qpainter.h:64
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
@ OpaqueHint
Definition qpainter.h:82
void drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, PixmapFragmentHints hints=PixmapFragmentHints())
QPaintEngine * paintEngine() const
Returns the paint engine that the painter is currently operating on if the painter is active; otherwi...
QTransform combinedTransform() const
Returns the transformation matrix combining the current window/viewport and world transformation.
@ Antialiasing
Definition qpainter.h:52
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint.
bool testRenderHint(RenderHint hint) const
Definition qpainter.h:407
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
const QBrush & button() const
Returns the button brush of the current color group.
Definition qpalette.h:84
const QBrush & dark() const
Returns the dark brush of the current color group.
Definition qpalette.h:86
const QBrush & shadow() const
Returns the shadow brush of the current color group.
Definition qpalette.h:97
const QBrush & light() const
Returns the light brush of the current color group.
Definition qpalette.h:85
const QColor & color(ColorGroup cg, ColorRole cr) const
Returns the color in the specified color group, used for the given color role.
Definition qpalette.h:67
const QBrush & mid() const
Returns the mid brush of the current color group.
Definition qpalette.h:87
const QBrush & midlight() const
Returns the midlight brush of the current color group.
Definition qpalette.h:94
\inmodule QtGui
Definition qpen.h:28
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qpoint.h:25
The QPolygon class provides a list of points using integer precision.
Definition qpolygon.h:23
Q_GUI_EXPORT void setPoints(int nPoints, const int *points)
Resizes the polygon to nPoints and populates it with the given points.
Definition qpolygon.cpp:253
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:176
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:173
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:179
TransformationType type() const
Returns the transformation type of this matrix.
QPixmap p2
QPixmap p1
[0]
void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
QVarLengthArray< QPainter::PixmapFragment, 16 > QPixmapFragmentsArray
void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth)
void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, int lineWidth, const QBrush *fill)
static void qDrawWinShades(QPainter *p, int x, int y, int w, int h, const QColor &c1, const QColor &c2, const QColor &c3, const QColor &c4, const QBrush *fill)
void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, const QPixmap &pixmap, const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
void qDrawWinPanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, const QBrush *fill)
void qDrawWinButton(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, const QBrush *fill)
void qDrawShadePanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, const QBrush *fill)
Combined button and popup list for selecting options.
@ RepeatTile
Definition qnamespace.h:135
@ RoundTile
Definition qnamespace.h:136
@ StretchTile
Definition qnamespace.h:134
@ NoPen
@ NoBrush
#define Q_UNLIKELY(x)
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
#define qWarning
Definition qlogging.h:166
int qCeil(T v)
Definition qmath.h:36
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLboolean r
[2]
GLuint GLfloat GLfloat GLfloat x1
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint y
GLfloat GLfloat GLfloat GLfloat h
const GLubyte * c
GLfixed GLfixed GLfixed y2
GLfixed GLfixed x2
GLdouble GLdouble t
Definition qopenglext.h:243
GLfloat GLfloat p
[1]
double qreal
Definition qtypes.h:187
MyCustomStruct c2
ba fill(true)
widget render & pixmap
QPainter painter(this)
[7]
The QTileRules class provides the rules used to draw a pixmap or image split into nine segments.