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
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
329void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
330 const QPalette &pal, bool sunken,
331 int lineWidth, const QBrush *fill)
332{
333 if (w == 0 || h == 0)
334 return;
335 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
336 qWarning("qDrawShadePanel: Invalid parameters");
337 }
338
339 PainterStateGuard painterGuard(p);
340 const qreal devicePixelRatio = p->device()->devicePixelRatio();
341 bool isTranslated = false;
342 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
343 painterGuard.save();
344 const qreal inverseScale = qreal(1) / devicePixelRatio;
345 p->scale(inverseScale, inverseScale);
346 x = qRound(devicePixelRatio * x);
347 y = qRound(devicePixelRatio * y);
348 w = devicePixelRatio * w;
349 h = devicePixelRatio * h;
350 lineWidth = qRound(devicePixelRatio * lineWidth);
351 p->translate(0.5, 0.5);
352 isTranslated = true;
353 }
354
355 QColor shade = pal.dark().color();
356 QColor light = pal.light().color();
357 if (fill) {
358 if (fill->color() == shade)
359 shade = pal.shadow().color();
360 if (fill->color() == light)
361 light = pal.midlight().color();
362 }
363 QPen oldPen = p->pen(); // save pen
364 QList<QLineF> lines;
365 lines.reserve(2*lineWidth);
366
367 if (sunken)
368 p->setPen(shade);
369 else
370 p->setPen(light);
371 int x1, y1, x2, y2;
372 int i;
373 x1 = x;
374 y1 = y2 = y;
375 x2 = x+w-2;
376 for (i=0; i<lineWidth; i++) { // top shadow
377 lines << QLineF(x1, y1++, x2--, y2++);
378 }
379 x2 = x1;
380 y1 = y+h-2;
381 for (i=0; i<lineWidth; i++) { // left shado
382 lines << QLineF(x1++, y1, x2++, y2--);
383 }
384 p->drawLines(lines);
385 lines.clear();
386 if (sunken)
387 p->setPen(light);
388 else
389 p->setPen(shade);
390 x1 = x;
391 y1 = y2 = y+h-1;
392 x2 = x+w-1;
393 for (i=0; i<lineWidth; i++) { // bottom shadow
394 lines << QLineF(x1++, y1--, x2, y2--);
395 }
396 x1 = x2;
397 y1 = y;
398 y2 = y+h-lineWidth-1;
399 for (i=0; i<lineWidth; i++) { // right shadow
400 lines << QLineF(x1--, y1++, x2--, y2);
401 }
402 p->drawLines(lines);
403 if (fill) { // fill with fill color
404 if (isTranslated)
405 p->translate(-0.5, -0.5);
406 p->fillRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, *fill);
407 }
408 p->setPen(oldPen); // restore pen
409}
410
427 int x, int y, int w, int h,
428 const QColor &c1, const QColor &c2,
429 const QColor &c3, const QColor &c4,
430 const QBrush *fill)
431{
432 if (w < 2 || h < 2) // can't do anything with that
433 return;
434
435 PainterStateGuard painterGuard(p);
436 const qreal devicePixelRatio = p->device()->devicePixelRatio();
437 bool isTranslated = false;
438 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
439 painterGuard.save();
440 const qreal inverseScale = qreal(1) / devicePixelRatio;
441 p->scale(inverseScale, inverseScale);
442 x = qRound(devicePixelRatio * x);
443 y = qRound(devicePixelRatio * y);
444 w = devicePixelRatio * w;
445 h = devicePixelRatio * h;
446 p->translate(0.5, 0.5);
447 isTranslated = true;
448 }
449
450 QPen oldPen = p->pen();
451 QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
452 p->setPen(c1);
453 p->drawPolyline(a, 3);
454 QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
455 p->setPen(c2);
456 p->drawPolyline(b, 3);
457 if (w > 4 && h > 4) {
458 QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
459 p->setPen(c3);
460 p->drawPolyline(c, 3);
461 QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
462 p->setPen(c4);
463 p->drawPolyline(d, 3);
464 if (fill) {
465 if (isTranslated)
466 p->translate(-0.5, -0.5);
467 p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
468 }
469 }
470 p->setPen(oldPen);
471}
472
473
498void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
499 const QPalette &pal, bool sunken,
500 const QBrush *fill)
501{
502 if (sunken)
503 qDrawWinShades(p, x, y, w, h,
504 pal.shadow().color(), pal.light().color(), pal.dark().color(),
505 pal.button().color(), fill);
506 else
507 qDrawWinShades(p, x, y, w, h,
508 pal.light().color(), pal.shadow().color(), pal.button().color(),
509 pal.dark().color(), fill);
510}
511
538void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
539 const QPalette &pal, bool sunken,
540 const QBrush *fill)
541{
542 if (sunken)
543 qDrawWinShades(p, x, y, w, h,
544 pal.dark().color(), pal.light().color(), pal.shadow().color(),
545 pal.midlight().color(), fill);
546 else
547 qDrawWinShades(p, x, y, w, h,
548 pal.light().color(), pal.shadow().color(), pal.midlight().color(),
549 pal.dark().color(), fill);
550}
551
574void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
575 int lineWidth, const QBrush *fill)
576{
577 if (w == 0 || h == 0)
578 return;
579 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
580 qWarning("qDrawPlainRect: Invalid parameters");
581 }
582
583 PainterStateGuard painterGuard(p);
584 const qreal devicePixelRatio = p->device()->devicePixelRatio();
585 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
586 painterGuard.save();
587 const qreal inverseScale = qreal(1) / devicePixelRatio;
588 p->scale(inverseScale, inverseScale);
589 x = qRound(devicePixelRatio * x);
590 y = qRound(devicePixelRatio * y);
591 w = devicePixelRatio * w;
592 h = devicePixelRatio * h;
593 lineWidth = qRound(devicePixelRatio * lineWidth);
594 p->translate(0.5, 0.5);
595 }
596
597 QPen oldPen = p->pen();
598 QBrush oldBrush = p->brush();
599 p->setPen(c);
600 p->setBrush(Qt::NoBrush);
601 for (int i=0; i<lineWidth; i++)
602 p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
603 if (fill) { // fill with fill color
604 p->setPen(Qt::NoPen);
605 p->setBrush(*fill);
606 p->drawRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2);
607 }
608 p->setPen(oldPen);
609 p->setBrush(oldBrush);
610}
611
639// ### Qt7: Pass QPen instead of QColor for frame drawing
640void qDrawPlainRoundedRect(QPainter *p, int x, int y, int w, int h,
641 qreal rx, qreal ry, const QColor &c,
642 int lineWidth, const QBrush *fill)
643{
644 if (w == 0 || h == 0)
645 return;
646 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
647 qWarning("qDrawPlainRect: Invalid parameters");
648 }
649
650 PainterStateGuard painterGuard(p);
651 const qreal devicePixelRatio = p->device()->devicePixelRatio();
652 if (!qFuzzyCompare(devicePixelRatio, qreal(1))) {
653 painterGuard.save();
654 const qreal inverseScale = qreal(1) / devicePixelRatio;
655 p->scale(inverseScale, inverseScale);
656 x = qRound(devicePixelRatio * x);
657 y = qRound(devicePixelRatio * y);
658 w = devicePixelRatio * w;
659 h = devicePixelRatio * h;
660 lineWidth = qRound(devicePixelRatio * lineWidth);
661 p->translate(0.5, 0.5);
662 }
663
664 p->save();
665 p->setPen(c);
666 p->setBrush(Qt::NoBrush);
667 for (int i=0; i<lineWidth; i++) {
668 QRectF rect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
669 rect.marginsRemoved(QMarginsF(0.5,0.5,0.5,0.5));
670 p->drawRoundedRect(rect, rx, ry);
671 }
672 if (fill) { // fill with fill color
673 p->setPen(Qt::NoPen);
674 p->setBrush(*fill);
675 p->drawRoundedRect(x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2, rx, ry);
676 }
677 p->restore();
678}
679
680/*****************************************************************************
681 Overloaded functions.
682 *****************************************************************************/
683
716void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
717 const QPalette &pal, bool sunken,
718 int lineWidth, int midLineWidth)
719{
720 qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken,
721 lineWidth, midLineWidth);
722}
723
756 const QPalette &pal, bool sunken,
757 int lineWidth, int midLineWidth,
758 const QBrush *fill)
759{
760 qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
761 lineWidth, midLineWidth, fill);
762}
763
793 const QPalette &pal, bool sunken,
794 int lineWidth, const QBrush *fill)
795{
796 qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
797 lineWidth, fill);
798}
799
824 const QPalette &pal, bool sunken, const QBrush *fill)
825{
826 qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
827}
828
855 const QPalette &pal, bool sunken, const QBrush *fill)
856{
857 qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
858}
859
881void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c,
882 int lineWidth, const QBrush *fill)
883{
884 qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c,
885 lineWidth, fill);
886}
887
952typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray;
953
970void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins,
971 const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
972 const QTileRules &rules
973#ifndef Q_QDOC
974 , QDrawBorderPixmap::DrawingHints hints
975#endif
976 )
977{
979 d.opacity = 1.0;
980 d.rotation = 0.0;
981
982 QPixmapFragmentsArray opaqueData;
983 QPixmapFragmentsArray translucentData;
984
985 // source center
986 const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
987 const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
988 const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
989 const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
990 const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
991 const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
992 // target center
993 const int targetCenterTop = targetRect.top() + targetMargins.top();
994 const int targetCenterLeft = targetRect.left() + targetMargins.left();
995 const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
996 const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
997 const int targetCenterWidth = targetCenterRight - targetCenterLeft;
998 const int targetCenterHeight = targetCenterBottom - targetCenterTop;
999
1000 QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles
1001 QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles
1002
1003 int columns = 3;
1004 int rows = 3;
1005 if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
1006 columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
1007 if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
1008 rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
1009
1010 xTarget.resize(columns + 1);
1011 yTarget.resize(rows + 1);
1012
1016 && oldAA && painter->combinedTransform().type() != QTransform::TxNone) {
1018 }
1019
1020 xTarget[0] = targetRect.left();
1021 xTarget[1] = targetCenterLeft;
1022 xTarget[columns - 1] = targetCenterRight;
1023 xTarget[columns] = targetRect.left() + targetRect.width();
1024
1025 yTarget[0] = targetRect.top();
1026 yTarget[1] = targetCenterTop;
1027 yTarget[rows - 1] = targetCenterBottom;
1028 yTarget[rows] = targetRect.top() + targetRect.height();
1029
1030 qreal dx = targetCenterWidth;
1031 qreal dy = targetCenterHeight;
1032
1033 switch (rules.horizontal) {
1034 case Qt::StretchTile:
1035 dx = targetCenterWidth;
1036 break;
1037 case Qt::RepeatTile:
1038 dx = sourceCenterWidth;
1039 break;
1040 case Qt::RoundTile:
1041 dx = targetCenterWidth / qreal(columns - 2);
1042 break;
1043 }
1044
1045 for (int i = 2; i < columns - 1; ++i)
1046 xTarget[i] = xTarget[i - 1] + dx;
1047
1048 switch (rules.vertical) {
1049 case Qt::StretchTile:
1050 dy = targetCenterHeight;
1051 break;
1052 case Qt::RepeatTile:
1053 dy = sourceCenterHeight;
1054 break;
1055 case Qt::RoundTile:
1056 dy = targetCenterHeight / qreal(rows - 2);
1057 break;
1058 }
1059
1060 for (int i = 2; i < rows - 1; ++i)
1061 yTarget[i] = yTarget[i - 1] + dy;
1062
1063 // corners
1064 if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
1065 d.x = (0.5 * (xTarget[1] + xTarget[0]));
1066 d.y = (0.5 * (yTarget[1] + yTarget[0]));
1067 d.sourceLeft = sourceRect.left();
1068 d.sourceTop = sourceRect.top();
1069 d.width = sourceMargins.left();
1070 d.height = sourceMargins.top();
1071 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
1072 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
1074 opaqueData.append(d);
1075 else
1076 translucentData.append(d);
1077 }
1078 if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
1079 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
1080 d.y = (0.5 * (yTarget[1] + yTarget[0]));
1081 d.sourceLeft = sourceCenterRight;
1082 d.sourceTop = sourceRect.top();
1083 d.width = sourceMargins.right();
1084 d.height = sourceMargins.top();
1085 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
1086 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
1088 opaqueData.append(d);
1089 else
1090 translucentData.append(d);
1091 }
1092 if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
1093 d.x = (0.5 * (xTarget[1] + xTarget[0]));
1094 d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
1095 d.sourceLeft = sourceRect.left();
1096 d.sourceTop = sourceCenterBottom;
1097 d.width = sourceMargins.left();
1098 d.height = sourceMargins.bottom();
1099 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
1100 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1102 opaqueData.append(d);
1103 else
1104 translucentData.append(d);
1105 }
1106 if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
1107 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
1108 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
1109 d.sourceLeft = sourceCenterRight;
1110 d.sourceTop = sourceCenterBottom;
1111 d.width = sourceMargins.right();
1112 d.height = sourceMargins.bottom();
1113 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
1114 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1116 opaqueData.append(d);
1117 else
1118 translucentData.append(d);
1119 }
1120
1121 // horizontal edges
1122 if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
1123 if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
1124 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
1125 d.sourceLeft = sourceCenterLeft;
1126 d.sourceTop = sourceRect.top();
1127 d.width = sourceCenterWidth;
1128 d.height = sourceMargins.top();
1129 d.y = (0.5 * (yTarget[1] + yTarget[0]));
1130 d.scaleX = dx / d.width;
1131 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
1132 for (int i = 1; i < columns - 1; ++i) {
1133 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1134 data.append(d);
1135 }
1136 if (rules.horizontal == Qt::RepeatTile)
1137 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
1138 }
1139 if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
1140 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
1141 d.sourceLeft = sourceCenterLeft;
1142 d.sourceTop = sourceCenterBottom;
1143 d.width = sourceCenterWidth;
1144 d.height = sourceMargins.bottom();
1145 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
1146 d.scaleX = dx / d.width;
1147 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1148 for (int i = 1; i < columns - 1; ++i) {
1149 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1150 data.append(d);
1151 }
1152 if (rules.horizontal == Qt::RepeatTile)
1153 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
1154 }
1155 }
1156
1157 // vertical edges
1158 if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
1159 if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
1160 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
1161 d.sourceLeft = sourceRect.left();
1162 d.sourceTop = sourceCenterTop;
1163 d.width = sourceMargins.left();
1164 d.height = sourceCenterHeight;
1165 d.x = (0.5 * (xTarget[1] + xTarget[0]));
1166 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
1167 d.scaleY = dy / d.height;
1168 for (int i = 1; i < rows - 1; ++i) {
1169 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
1170 data.append(d);
1171 }
1172 if (rules.vertical == Qt::RepeatTile)
1173 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
1174 }
1175 if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
1176 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
1177 d.sourceLeft = sourceCenterRight;
1178 d.sourceTop = sourceCenterTop;
1179 d.width = sourceMargins.right();
1180 d.height = sourceCenterHeight;
1181 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
1182 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
1183 d.scaleY = dy / d.height;
1184 for (int i = 1; i < rows - 1; ++i) {
1185 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
1186 data.append(d);
1187 }
1188 if (rules.vertical == Qt::RepeatTile)
1189 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
1190 }
1191 }
1192
1193 // center
1194 if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
1195 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
1196 d.sourceLeft = sourceCenterLeft;
1197 d.sourceTop = sourceCenterTop;
1198 d.width = sourceCenterWidth;
1199 d.height = sourceCenterHeight;
1200 d.scaleX = dx / d.width;
1201 d.scaleY = dy / d.height;
1202
1203 qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
1204 qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
1205
1206 for (int j = 1; j < rows - 1; ++j) {
1207 d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
1208 for (int i = 1; i < columns - 1; ++i) {
1209 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1210 data.append(d);
1211 }
1212 if (rules.horizontal == Qt::RepeatTile)
1213 data[data.size() - 1].width = repeatWidth;
1214 }
1215 if (rules.vertical == Qt::RepeatTile) {
1216 for (int i = 1; i < columns - 1; ++i)
1217 data[data.size() - i].height = repeatHeight;
1218 }
1219 }
1220
1221 if (opaqueData.size())
1222 painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
1223 if (translucentData.size())
1224 painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
1225
1226 if (oldAA)
1228}
1229
\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:270
\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:484
\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]
rect
[4]
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)
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 qDrawPlainRoundedRect(QPainter *p, int x, int y, int w, int h, qreal rx, qreal ry, const QColor &c, int lineWidth, const QBrush *fill)
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: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)
p ry()++
p rx()++
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:88