Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdrawutil.cpp
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
4#include "qdrawutil.h"
5#include "qbitmap.h"
6#include "qpixmapcache.h"
7#include "qpainter.h"
8#include "qpalette.h"
9#include <private/qpaintengineex_p.h>
10#include <qvarlengtharray.h>
11#include <qmath.h>
12#include <private/qhexstring_p.h>
13
15
16namespace {
18 Q_DISABLE_COPY_MOVE(PainterStateGuard)
19public:
20 explicit PainterStateGuard(QPainter *p) : m_painter(p) {}
22 {
23 for ( ; m_level > 0; --m_level)
24 m_painter->restore();
25 }
26
27 void save()
28 {
29 m_painter->save();
30 ++m_level;
31 }
32
33 void restore()
34 {
35 m_painter->restore();
36 --m_level;
37 }
38
39private:
40 QPainter *m_painter;
41 int m_level= 0;
42};
43} // namespace
44
86void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
87 const QPalette &pal, bool sunken,
88 int lineWidth, int midLineWidth)
89{
90 if (Q_UNLIKELY(!p || lineWidth < 0 || midLineWidth < 0)) {
91 qWarning("qDrawShadeLine: Invalid parameters");
92 return;
93 }
94 PainterStateGuard painterGuard(p);
95 const qreal devicePixelRatio = p->device()->devicePixelRatio();
96 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
97 painterGuard.save();
98 const qreal inverseScale = qreal(1) / devicePixelRatio;
99 p->scale(inverseScale, inverseScale);
100 x1 = qRound(devicePixelRatio * x1);
101 y1 = qRound(devicePixelRatio * y1);
102 x2 = qRound(devicePixelRatio * x2);
103 y2 = qRound(devicePixelRatio * y2);
104 lineWidth = qRound(devicePixelRatio * lineWidth);
105 midLineWidth = qRound(devicePixelRatio * midLineWidth);
106 p->translate(0.5, 0.5);
107 }
108 int tlw = lineWidth*2 + midLineWidth; // total line width
109 QPen oldPen = p->pen(); // save pen
110 if (sunken)
111 p->setPen(pal.color(QPalette::Dark));
112 else
113 p->setPen(pal.light().color());
114 QPolygon a;
115 int i;
116 if (y1 == y2) { // horizontal line
117 int y = y1 - tlw/2;
118 if (x1 > x2) { // swap x1 and x2
119 int t = x1;
120 x1 = x2;
121 x2 = t;
122 }
123 x2--;
124 for (i=0; i<lineWidth; i++) { // draw top shadow
125 a.setPoints(3, x1+i, y+tlw-1-i,
126 x1+i, y+i,
127 x2-i, y+i);
128 p->drawPolyline(a);
129 }
130 if (midLineWidth > 0) {
131 p->setPen(pal.mid().color());
132 for (i=0; i<midLineWidth; i++) // draw lines in the middle
133 p->drawLine(x1+lineWidth, y+lineWidth+i,
134 x2-lineWidth, y+lineWidth+i);
135 }
136 if (sunken)
137 p->setPen(pal.light().color());
138 else
139 p->setPen(pal.dark().color());
140 for (i=0; i<lineWidth; i++) { // draw bottom shadow
141 a.setPoints(3, x1+i, y+tlw-i-1,
142 x2-i, y+tlw-i-1,
143 x2-i, y+i+1);
144 p->drawPolyline(a);
145 }
146 }
147 else if (x1 == x2) { // vertical line
148 int x = x1 - tlw/2;
149 if (y1 > y2) { // swap y1 and y2
150 int t = y1;
151 y1 = y2;
152 y2 = t;
153 }
154 y2--;
155 for (i=0; i<lineWidth; i++) { // draw left shadow
156 a.setPoints(3, x+i, y2,
157 x+i, y1+i,
158 x+tlw-1, y1+i);
159 p->drawPolyline(a);
160 }
161 if (midLineWidth > 0) {
162 p->setPen(pal.mid().color());
163 for (i=0; i<midLineWidth; i++) // draw lines in the middle
164 p->drawLine(x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2);
165 }
166 if (sunken)
167 p->setPen(pal.light().color());
168 else
169 p->setPen(pal.dark().color());
170 for (i=0; i<lineWidth; i++) { // draw right shadow
171 a.setPoints(3, x+lineWidth, y2-i,
172 x+tlw-i-1, y2-i,
173 x+tlw-i-1, y1+lineWidth);
174 p->drawPolyline(a);
175 }
176 }
177 p->setPen(oldPen);
178}
179
213void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
214 const QPalette &pal, bool sunken,
215 int lineWidth, int midLineWidth,
216 const QBrush *fill)
217{
218 if (w == 0 || h == 0)
219 return;
220 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0 || midLineWidth < 0)) {
221 qWarning("qDrawShadeRect: Invalid parameters");
222 return;
223 }
224
225 PainterStateGuard painterGuard(p);
226 const qreal devicePixelRatio = p->device()->devicePixelRatio();
227 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
228 painterGuard.save();
229 const qreal inverseScale = qreal(1) / devicePixelRatio;
230 p->scale(inverseScale, inverseScale);
231 x = qRound(devicePixelRatio * x);
232 y = qRound(devicePixelRatio * y);
233 w = devicePixelRatio * w;
234 h = devicePixelRatio * h;
235 lineWidth = qRound(devicePixelRatio * lineWidth);
236 midLineWidth = qRound(devicePixelRatio * midLineWidth);
237 p->translate(0.5, 0.5);
238 }
239
240 QPen oldPen = p->pen();
241 if (sunken)
242 p->setPen(pal.dark().color());
243 else
244 p->setPen(pal.light().color());
245 int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
246
247 if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle
248 p->drawRect(x1, y1, w-2, h-2);
249 if (sunken)
250 p->setPen(pal.light().color());
251 else
252 p->setPen(pal.dark().color());
253 QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1),
254 QLineF(x1+1, y1+2, x1+1, y2-2),
255 QLineF(x1, y2, x2, y2),
256 QLineF(x2,y1, x2,y2-1) };
257 p->drawLines(lines, 4); // draw bottom/right lines
258 } else { // more complicated
259 int m = lineWidth+midLineWidth;
260 int i, j=0, k=m;
261 for (i=0; i<lineWidth; i++) { // draw top shadow
262 QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i),
263 QLineF(x1+i, y1+i, x2-i, y1+i),
264 QLineF(x1+k, y2-k, x2-k, y2-k),
265 QLineF(x2-k, y2-k, x2-k, y1+k) };
266 p->drawLines(lines, 4);
267 k++;
268 }
269 p->setPen(pal.mid().color());
270 j = lineWidth*2;
271 for (i=0; i<midLineWidth; i++) { // draw lines in the middle
272 p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1);
273 j += 2;
274 }
275 if (sunken)
276 p->setPen(pal.light().color());
277 else
278 p->setPen(pal.dark().color());
279 k = m;
280 for (i=0; i<lineWidth; i++) { // draw bottom shadow
281 QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i),
282 QLineF(x2-i, y2-i, x2-i, y1+i+1),
283 QLineF(x1+k, y2-k, x1+k, y1+k),
284 QLineF(x1+k, y1+k, x2-k, y1+k) };
285 p->drawLines(lines, 4);
286 k++;
287 }
288 }
289 if (fill) {
290 QBrush oldBrush = p->brush();
291 int tlw = lineWidth + midLineWidth;
292 p->setPen(Qt::NoPen);
293 p->setBrush(*fill);
294 p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw);
295 p->setBrush(oldBrush);
296 }
297 p->setPen(oldPen); // restore pen
298}
299
300
330void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
331 const QPalette &pal, bool sunken,
332 int lineWidth, const QBrush *fill)
333{
334 if (w == 0 || h == 0)
335 return;
336 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
337 qWarning("qDrawShadePanel: Invalid parameters");
338 }
339
340 PainterStateGuard painterGuard(p);
341 const qreal devicePixelRatio = p->device()->devicePixelRatio();
342 bool isTranslated = false;
343 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
344 painterGuard.save();
345 const qreal inverseScale = qreal(1) / devicePixelRatio;
346 p->scale(inverseScale, inverseScale);
347 x = qRound(devicePixelRatio * x);
348 y = qRound(devicePixelRatio * y);
349 w = devicePixelRatio * w;
350 h = devicePixelRatio * h;
351 lineWidth = qRound(devicePixelRatio * lineWidth);
352 p->translate(0.5, 0.5);
353 isTranslated = true;
354 }
355
356 QColor shade = pal.dark().color();
357 QColor light = pal.light().color();
358 if (fill) {
359 if (fill->color() == shade)
360 shade = pal.shadow().color();
361 if (fill->color() == light)
362 light = pal.midlight().color();
363 }
364 QPen oldPen = p->pen(); // save pen
365 QList<QLineF> lines;
366 lines.reserve(2*lineWidth);
367
368 if (sunken)
369 p->setPen(shade);
370 else
371 p->setPen(light);
372 int x1, y1, x2, y2;
373 int i;
374 x1 = x;
375 y1 = y2 = y;
376 x2 = x+w-2;
377 for (i=0; i<lineWidth; i++) { // top shadow
378 lines << QLineF(x1, y1++, x2--, y2++);
379 }
380 x2 = x1;
381 y1 = y+h-2;
382 for (i=0; i<lineWidth; i++) { // left shado
383 lines << QLineF(x1++, y1, x2++, y2--);
384 }
385 p->drawLines(lines);
386 lines.clear();
387 if (sunken)
388 p->setPen(light);
389 else
390 p->setPen(shade);
391 x1 = x;
392 y1 = y2 = y+h-1;
393 x2 = x+w-1;
394 for (i=0; i<lineWidth; i++) { // bottom shadow
395 lines << QLineF(x1++, y1--, x2, y2--);
396 }
397 x1 = x2;
398 y1 = y;
399 y2 = y+h-lineWidth-1;
400 for (i=0; i<lineWidth; i++) { // right shadow
401 lines << QLineF(x1--, y1++, x2--, y2);
402 }
403 p->drawLines(lines);
404 if (fill) { // fill with fill color
405 if (isTranslated)
406 p->translate(-0.5, -0.5);
407 p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
408 }
409 p->setPen(oldPen); // restore pen
410}
411
412
429 int x, int y, int w, int h,
430 const QColor &c1, const QColor &c2,
431 const QColor &c3, const QColor &c4,
432 const QBrush *fill)
433{
434 if (w < 2 || h < 2) // can't do anything with that
435 return;
436
437 PainterStateGuard painterGuard(p);
438 const qreal devicePixelRatio = p->device()->devicePixelRatio();
439 bool isTranslated = false;
440 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
441 painterGuard.save();
442 const qreal inverseScale = qreal(1) / devicePixelRatio;
443 p->scale(inverseScale, inverseScale);
444 x = qRound(devicePixelRatio * x);
445 y = qRound(devicePixelRatio * y);
446 w = devicePixelRatio * w;
447 h = devicePixelRatio * h;
448 p->translate(0.5, 0.5);
449 isTranslated = true;
450 }
451
452 QPen oldPen = p->pen();
453 QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
454 p->setPen(c1);
455 p->drawPolyline(a, 3);
456 QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
457 p->setPen(c2);
458 p->drawPolyline(b, 3);
459 if (w > 4 && h > 4) {
460 QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
461 p->setPen(c3);
462 p->drawPolyline(c, 3);
463 QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
464 p->setPen(c4);
465 p->drawPolyline(d, 3);
466 if (fill) {
467 if (isTranslated)
468 p->translate(-0.5, -0.5);
469 p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
470 }
471 }
472 p->setPen(oldPen);
473}
474
475
500void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
501 const QPalette &pal, bool sunken,
502 const QBrush *fill)
503{
504 if (sunken)
505 qDrawWinShades(p, x, y, w, h,
506 pal.shadow().color(), pal.light().color(), pal.dark().color(),
507 pal.button().color(), fill);
508 else
509 qDrawWinShades(p, x, y, w, h,
510 pal.light().color(), pal.shadow().color(), pal.button().color(),
511 pal.dark().color(), fill);
512}
513
540void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
541 const QPalette &pal, bool sunken,
542 const QBrush *fill)
543{
544 if (sunken)
545 qDrawWinShades(p, x, y, w, h,
546 pal.dark().color(), pal.light().color(), pal.shadow().color(),
547 pal.midlight().color(), fill);
548 else
549 qDrawWinShades(p, x, y, w, h,
550 pal.light().color(), pal.shadow().color(), pal.midlight().color(),
551 pal.dark().color(), fill);
552}
553
576void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
577 int lineWidth, const QBrush *fill)
578{
579 if (w == 0 || h == 0)
580 return;
581 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
582 qWarning("qDrawPlainRect: Invalid parameters");
583 }
584
585 PainterStateGuard painterGuard(p);
586 const qreal devicePixelRatio = p->device()->devicePixelRatio();
587 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
588 painterGuard.save();
589 const qreal inverseScale = qreal(1) / devicePixelRatio;
590 p->scale(inverseScale, inverseScale);
591 x = qRound(devicePixelRatio * x);
592 y = qRound(devicePixelRatio * y);
593 w = devicePixelRatio * w;
594 h = devicePixelRatio * h;
595 lineWidth = qRound(devicePixelRatio * lineWidth);
596 p->translate(0.5, 0.5);
597 }
598
599 QPen oldPen = p->pen();
600 QBrush oldBrush = p->brush();
601 p->setPen(c);
602 p->setBrush(Qt::NoBrush);
603 for (int i=0; i<lineWidth; i++)
604 p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
605 if (fill) { // fill with fill color
606 p->setPen(Qt::NoPen);
607 p->setBrush(*fill);
608 p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2);
609 }
610 p->setPen(oldPen);
611 p->setBrush(oldBrush);
612}
613
614/*****************************************************************************
615 Overloaded functions.
616 *****************************************************************************/
617
650void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
651 const QPalette &pal, bool sunken,
652 int lineWidth, int midLineWidth)
653{
654 qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken,
655 lineWidth, midLineWidth);
656}
657
690 const QPalette &pal, bool sunken,
691 int lineWidth, int midLineWidth,
692 const QBrush *fill)
693{
694 qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
695 lineWidth, midLineWidth, fill);
696}
697
727 const QPalette &pal, bool sunken,
728 int lineWidth, const QBrush *fill)
729{
730 qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
731 lineWidth, fill);
732}
733
758 const QPalette &pal, bool sunken, const QBrush *fill)
759{
760 qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
761}
762
789 const QPalette &pal, bool sunken, const QBrush *fill)
790{
791 qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
792}
793
815void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c,
816 int lineWidth, const QBrush *fill)
817{
818 qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c,
819 lineWidth, fill);
820}
821
822
861
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
\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
Definition qline.h:182
Definition qlist.h:74
void reserve(qsizetype size)
Definition qlist.h:746
void clear()
Definition qlist.h:417
\inmodule QtCore
Definition qmargins.h:23
constexpr int bottom() const noexcept
Returns the bottom margin.
Definition qmargins.h:119
constexpr int left() const noexcept
Returns the left margin.
Definition qmargins.h:110
constexpr int right() const noexcept
Returns the right margin.
Definition qmargins.h:116
constexpr int top() const noexcept
Returns the top margin.
Definition qmargins.h:113
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:83
const QBrush & dark() const
Returns the dark brush of the current color group.
Definition qpalette.h:85
const QBrush & shadow() const
Returns the shadow brush of the current color group.
Definition qpalette.h:96
const QBrush & light() const
Returns the light brush of the current color group.
Definition qpalette.h:84
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:66
const QBrush & mid() const
Returns the mid brush of the current color group.
Definition qpalette.h:86
const QBrush & midlight() const
Returns the midlight brush of the current color group.
Definition qpalette.h:93
\inmodule QtGui
Definition qpen.h:25
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:23
The QPolygon class provides a list of points using integer precision.
Definition qpolygon.h:23
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:181
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:175
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:172
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:235
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:178
TransformationType type() const
Returns the transformation type of this matrix.
constexpr size_type size() const noexcept
void resize(qsizetype sz)
void append(const T &t)
T * data() noexcept
QPixmap p2
QPixmap p1
[0]
Combined button and popup list for selecting options.
@ RepeatTile
Definition qnamespace.h:134
@ RoundTile
Definition qnamespace.h:135
@ StretchTile
Definition qnamespace.h:133
@ NoPen
@ NoBrush
#define Q_UNLIKELY(x)
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 qDrawShadePanel(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, const QBrush *fill)
void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth)
Definition qdrawutil.cpp:86
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)
QVarLengthArray< QPainter::PixmapFragment, 16 > QPixmapFragmentsArray
void qDrawShadeRect(QPainter *p, int x, int y, int w, int h, const QPalette &pal, bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c, int lineWidth, const QBrush *fill)
Q_WIDGETS_EXPORT void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, const QPixmap &pixmap, const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules=QTileRules(), QDrawBorderPixmap::DrawingHints hints=QDrawBorderPixmap::DrawingHints())
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
#define qWarning
Definition qlogging.h:162
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:92
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.
Definition qdrawutil.h:77