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
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// Qt-Security score:significant reason:default
4
6
7#include "qbitmap.h"
8#include "qpixmapcache.h"
9#include "qpainter.h"
10#include "qpalette.h"
11#include <private/qpaintengineex_p.h>
12#include <qvarlengtharray.h>
13#include <qmath.h>
14#include <private/qhexstring_p.h>
15
17
18namespace QQC2 {
19
20namespace {
21class PainterStateGuard {
22 Q_DISABLE_COPY_MOVE(PainterStateGuard)
23public:
24 explicit PainterStateGuard(QPainter *p) : m_painter(p) {}
25 ~PainterStateGuard()
26 {
27 for ( ; m_level > 0; --m_level)
28 m_painter->restore();
29 }
30
31 void save()
32 {
33 m_painter->save();
34 ++m_level;
35 }
36
37 void restore()
38 {
39 m_painter->restore();
40 --m_level;
41 }
42
43private:
44 QPainter *m_painter;
45 int m_level= 0;
46};
47} // namespace
48
49/*!
50 \headerfile <qdrawutil.h>
51 \title Drawing Utility Functions
52
53 \sa QPainter
54*/
55
56/*!
57 \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2,
58 const QPalette &palette, bool sunken,
59 int lineWidth, int midLineWidth)
60 \relates <qdrawutil.h>
61
62 Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
63 shaded line using the given \a painter. Note that nothing is
64 drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the line is
65 neither horizontal nor vertical).
66
67 The provided \a palette specifies the shading colors (\l
68 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
69 {QPalette::mid()}{middle} colors). The given \a lineWidth
70 specifies the line width for each of the lines; it is not the
71 total line width. The given \a midLineWidth specifies the width of
72 a middle line drawn in the QPalette::mid() color.
73
74 The line appears sunken if \a sunken is true, otherwise raised.
75
76 \warning This function does not look at QWidget::style() or
77 QApplication::style(). Use the drawing functions in QStyle to
78 make widgets that follow the current GUI style.
79
80
81 Alternatively you can use a QFrame widget and apply the
82 QFrame::setFrameStyle() function to display a shaded line:
83
84 \snippet code/src_gui_painting_qdrawutil.cpp 0
85
86 \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
87*/
88
89void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
90 const QPalette &pal, bool sunken,
91 int lineWidth, int midLineWidth)
92{
93 if (Q_UNLIKELY(!p || lineWidth < 0 || midLineWidth < 0)) {
94 qWarning("qDrawShadeLine: Invalid parameters");
95 return;
96 }
109 p->translate(0.5, 0.5);
110 }
111 int tlw = lineWidth*2 + midLineWidth; // total line width
112 QPen oldPen = p->pen(); // save pen
113 if (sunken)
115 else
116 p->setPen(pal.light().color());
117 QPolygon a;
118 int i;
119 if (y1 == y2) { // horizontal line
120 int y = y1 - tlw/2;
121 if (x1 > x2) { // swap x1 and x2
122 int t = x1;
123 x1 = x2;
124 x2 = t;
125 }
126 x2--;
127 for (i=0; i<lineWidth; i++) { // draw top shadow
128 a.setPoints(3, x1+i, y+tlw-1-i,
129 x1+i, y+i,
130 x2-i, y+i);
131 p->drawPolyline(a);
132 }
133 if (midLineWidth > 0) {
134 p->setPen(pal.mid().color());
135 for (i=0; i<midLineWidth; i++) // draw lines in the middle
138 }
139 if (sunken)
140 p->setPen(pal.light().color());
141 else
142 p->setPen(pal.dark().color());
143 for (i=0; i<lineWidth; i++) { // draw bottom shadow
144 a.setPoints(3, x1+i, y+tlw-i-1,
145 x2-i, y+tlw-i-1,
146 x2-i, y+i+1);
147 p->drawPolyline(a);
148 }
149 }
150 else if (x1 == x2) { // vertical line
151 int x = x1 - tlw/2;
152 if (y1 > y2) { // swap y1 and y2
153 int t = y1;
154 y1 = y2;
155 y2 = t;
156 }
157 y2--;
158 for (i=0; i<lineWidth; i++) { // draw left shadow
159 a.setPoints(3, x+i, y2,
160 x+i, y1+i,
161 x+tlw-1, y1+i);
162 p->drawPolyline(a);
163 }
164 if (midLineWidth > 0) {
165 p->setPen(pal.mid().color());
166 for (i=0; i<midLineWidth; i++) // draw lines in the middle
168 }
169 if (sunken)
170 p->setPen(pal.light().color());
171 else
172 p->setPen(pal.dark().color());
173 for (i=0; i<lineWidth; i++) { // draw right shadow
175 x+tlw-i-1, y2-i,
176 x+tlw-i-1, y1+lineWidth);
177 p->drawPolyline(a);
178 }
179 }
180 p->setPen(oldPen);
181}
182
183/*!
184 \fn void qDrawShadeRect(QPainter *painter, int x, int y, int width, int height,
185 const QPalette &palette, bool sunken,
186 int lineWidth, int midLineWidth,
187 const QBrush *fill)
188 \relates <qdrawutil.h>
189
190 Draws the shaded rectangle beginning at (\a x, \a y) with the
191 given \a width and \a height using the provided \a painter.
192
193 The provide \a palette specifies the shading colors (\l
194 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
195 {QPalette::mid()}{middle} colors. The given \a lineWidth
196 specifies the line width for each of the lines; it is not the
197 total line width. The \a midLineWidth specifies the width of a
198 middle line drawn in the QPalette::mid() color. The rectangle's
199 interior is filled with the \a fill brush unless \a fill is 0.
200
201 The rectangle appears sunken if \a sunken is true, otherwise
202 raised.
203
204 \warning This function does not look at QWidget::style() or
205 QApplication::style(). Use the drawing functions in QStyle to make
206 widgets that follow the current GUI style.
207
208 Alternatively you can use a QFrame widget and apply the
209 QFrame::setFrameStyle() function to display a shaded rectangle:
210
211 \snippet code/src_gui_painting_qdrawutil.cpp 1
212
213 \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
214*/
215
216void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
217 const QPalette &pal, bool sunken,
218 int lineWidth, int midLineWidth,
219 const QBrush *fill)
220{
221 if (w == 0 || h == 0)
222 return;
223 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0 || midLineWidth < 0)) {
224 qWarning("qDrawShadeRect: Invalid parameters");
225 return;
226 }
227
240 p->translate(0.5, 0.5);
241 }
242
243 QPen oldPen = p->pen();
244 if (sunken)
245 p->setPen(pal.dark().color());
246 else
247 p->setPen(pal.light().color());
248 int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
249
250 if (lineWidth == 1 && midLineWidth == 0) {// standard shade rectangle
251 p->drawRect(x1, y1, w-2, h-2);
252 if (sunken)
253 p->setPen(pal.light().color());
254 else
255 p->setPen(pal.dark().color());
256 QLineF lines[4] = { QLineF(x1+1, y1+1, x2-2, y1+1),
257 QLineF(x1+1, y1+2, x1+1, y2-2),
258 QLineF(x1, y2, x2, y2),
259 QLineF(x2,y1, x2,y2-1) };
260 p->drawLines(lines, 4); // draw bottom/right lines
261 } else { // more complicated
263 int i, j=0, k=m;
264 for (i=0; i<lineWidth; i++) { // draw top shadow
265 QLineF lines[4] = { QLineF(x1+i, y2-i, x1+i, y1+i),
266 QLineF(x1+i, y1+i, x2-i, y1+i),
267 QLineF(x1+k, y2-k, x2-k, y2-k),
268 QLineF(x2-k, y2-k, x2-k, y1+k) };
269 p->drawLines(lines, 4);
270 k++;
271 }
272 p->setPen(pal.mid().color());
273 j = lineWidth*2;
274 for (i=0; i<midLineWidth; i++) { // draw lines in the middle
275 p->drawRect(x1+lineWidth+i, y1+lineWidth+i, w-j-1, h-j-1);
276 j += 2;
277 }
278 if (sunken)
279 p->setPen(pal.light().color());
280 else
281 p->setPen(pal.dark().color());
282 k = m;
283 for (i=0; i<lineWidth; i++) { // draw bottom shadow
284 QLineF lines[4] = { QLineF(x1+1+i, y2-i, x2-i, y2-i),
285 QLineF(x2-i, y2-i, x2-i, y1+i+1),
286 QLineF(x1+k, y2-k, x1+k, y1+k),
287 QLineF(x1+k, y1+k, x2-k, y1+k) };
288 p->drawLines(lines, 4);
289 k++;
290 }
291 }
292 if (fill) {
293 QBrush oldBrush = p->brush();
294 int tlw = lineWidth + midLineWidth;
295 p->setPen(Qt::NoPen);
296 p->setBrush(*fill);
297 p->drawRect(x+tlw, y+tlw, w-2*tlw, h-2*tlw);
299 }
300 p->setPen(oldPen); // restore pen
301}
302
303
304/*!
305 \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height,
306 const QPalette &palette, bool sunken,
307 int lineWidth, const QBrush *fill)
308 \relates <qdrawutil.h>
309
310 Draws the shaded panel beginning at (\a x, \a y) with the given \a
311 width and \a height using the provided \a painter and the given \a
312 lineWidth.
313
314 The given \a palette specifies the shading colors (\l
315 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
316 {QPalette::mid()}{middle} colors). The panel's interior is filled
317 with the \a fill brush unless \a fill is 0.
318
319 The panel appears sunken if \a sunken is true, otherwise raised.
320
321 \warning This function does not look at QWidget::style() or
322 QApplication::style(). Use the drawing functions in QStyle to make
323 widgets that follow the current GUI style.
324
325 Alternatively you can use a QFrame widget and apply the
326 QFrame::setFrameStyle() function to display a shaded panel:
327
328 \snippet code/src_gui_painting_qdrawutil.cpp 2
329
330 \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
331*/
332
333void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
334 const QPalette &pal, bool sunken,
335 int lineWidth, const QBrush *fill)
336{
337 if (w == 0 || h == 0)
338 return;
339 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
340 qWarning("qDrawShadePanel: Invalid parameters");
341 }
342
345 bool isTranslated = false;
355 p->translate(0.5, 0.5);
356 isTranslated = true;
357 }
358
359 QColor shade = pal.dark().color();
360 QColor light = pal.light().color();
361 if (fill) {
362 if (fill->color() == shade)
363 shade = pal.shadow().color();
364 if (fill->color() == light)
365 light = pal.midlight().color();
366 }
367 QPen oldPen = p->pen(); // save pen
370
371 if (sunken)
372 p->setPen(shade);
373 else
374 p->setPen(light);
375 int x1, y1, x2, y2;
376 int i;
377 x1 = x;
378 y1 = y2 = y;
379 x2 = x+w-2;
380 for (i=0; i<lineWidth; i++) { // top shadow
381 lines << QLineF(x1, y1++, x2--, y2++);
382 }
383 x2 = x1;
384 y1 = y+h-2;
385 for (i=0; i<lineWidth; i++) { // left shado
386 lines << QLineF(x1++, y1, x2++, y2--);
387 }
388 p->drawLines(lines);
389 lines.clear();
390 if (sunken)
391 p->setPen(light);
392 else
393 p->setPen(shade);
394 x1 = x;
395 y1 = y2 = y+h-1;
396 x2 = x+w-1;
397 for (i=0; i<lineWidth; i++) { // bottom shadow
398 lines << QLineF(x1++, y1--, x2, y2--);
399 }
400 x1 = x2;
401 y1 = y;
402 y2 = y+h-lineWidth-1;
403 for (i=0; i<lineWidth; i++) { // right shadow
404 lines << QLineF(x1--, y1++, x2--, y2);
405 }
406 p->drawLines(lines);
407 if (fill) { // fill with fill color
408 if (isTranslated)
409 p->translate(-0.5, -0.5);
411 }
412 p->setPen(oldPen); // restore pen
413}
414
415
416/*!
417 \internal
418 This function draws a rectangle with two pixel line width.
419 It is called from qDrawWinButton() and qDrawWinPanel().
420
421 c1..c4 and fill are used:
422
423 1 1 1 1 1 2
424 1 3 3 3 4 2
425 1 3 F F 4 2
426 1 3 F F 4 2
427 1 4 4 4 4 2
428 2 2 2 2 2 2
429*/
430
432 int x, int y, int w, int h,
433 const QColor &c1, const QColor &c2,
434 const QColor &c3, const QColor &c4,
435 const QBrush *fill)
436{
437 if (w < 2 || h < 2) // can't do anything with that
438 return;
439
442 bool isTranslated = false;
451 p->translate(0.5, 0.5);
452 isTranslated = true;
453 }
454
455 QPen oldPen = p->pen();
456 QPoint a[3] = { QPoint(x, y+h-2), QPoint(x, y), QPoint(x+w-2, y) };
457 p->setPen(c1);
458 p->drawPolyline(a, 3);
459 QPoint b[3] = { QPoint(x, y+h-1), QPoint(x+w-1, y+h-1), QPoint(x+w-1, y) };
460 p->setPen(c2);
461 p->drawPolyline(b, 3);
462 if (w > 4 && h > 4) {
463 QPoint c[3] = { QPoint(x+1, y+h-3), QPoint(x+1, y+1), QPoint(x+w-3, y+1) };
464 p->setPen(c3);
465 p->drawPolyline(c, 3);
466 QPoint d[3] = { QPoint(x+1, y+h-2), QPoint(x+w-2, y+h-2), QPoint(x+w-2, y+1) };
467 p->setPen(c4);
468 p->drawPolyline(d, 3);
469 if (fill) {
470 if (isTranslated)
471 p->translate(-0.5, -0.5);
472 p->fillRect(QRect(x+2, y+2, w-4, h-4), *fill);
473 }
474 }
475 p->setPen(oldPen);
476}
477
478
479/*!
480 \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height,
481 const QPalette &palette, bool sunken,
482 const QBrush *fill)
483 \relates <qdrawutil.h>
484
485 Draws the Windows-style button specified by the given point (\a x,
486 \a y}, \a width and \a height using the provided \a painter with a
487 line width of 2 pixels. The button's interior is filled with the
488 \a{fill} brush unless \a fill is 0.
489
490 The given \a palette specifies the shading colors (\l
491 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
492 {QPalette::mid()}{middle} colors).
493
494 The button appears sunken if \a sunken is true, otherwise raised.
495
496 \warning This function does not look at QWidget::style() or
497 QApplication::style()-> Use the drawing functions in QStyle to make
498 widgets that follow the current GUI style.
499
500 \sa qDrawWinPanel(), QStyle
501*/
502
503void qDrawWinButton(QPainter *p, int x, int y, int w, int h,
504 const QPalette &pal, bool sunken,
505 const QBrush *fill)
506{
507 if (sunken)
508 qDrawWinShades(p, x, y, w, h,
509 pal.shadow().color(), pal.light().color(), pal.dark().color(),
510 pal.button().color(), fill);
511 else
512 qDrawWinShades(p, x, y, w, h,
513 pal.light().color(), pal.shadow().color(), pal.button().color(),
514 pal.dark().color(), fill);
515}
516
517/*!
518 \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height,
519 const QPalette &palette, bool sunken,
520 const QBrush *fill)
521 \relates <qdrawutil.h>
522
523 Draws the Windows-style panel specified by the given point(\a x,
524 \a y), \a width and \a height using the provided \a painter with a
525 line width of 2 pixels. The button's interior is filled with the
526 \a fill brush unless \a fill is 0.
527
528 The given \a palette specifies the shading colors. The panel
529 appears sunken if \a sunken is true, otherwise raised.
530
531 \warning This function does not look at QWidget::style() or
532 QApplication::style(). Use the drawing functions in QStyle to make
533 widgets that follow the current GUI style.
534
535 Alternatively you can use a QFrame widget and apply the
536 QFrame::setFrameStyle() function to display a shaded panel:
537
538 \snippet code/src_gui_painting_qdrawutil.cpp 3
539
540 \sa qDrawShadePanel(), qDrawWinButton(), QStyle
541*/
542
543void qDrawWinPanel(QPainter *p, int x, int y, int w, int h,
544 const QPalette &pal, bool sunken,
545 const QBrush *fill)
546{
547 if (sunken)
548 qDrawWinShades(p, x, y, w, h,
549 pal.dark().color(), pal.light().color(), pal.shadow().color(),
550 pal.midlight().color(), fill);
551 else
552 qDrawWinShades(p, x, y, w, h,
554 pal.dark().color(), fill);
555}
556
557/*!
558 \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor,
559 int lineWidth, const QBrush *fill)
560 \relates <qdrawutil.h>
561
562 Draws the plain rectangle beginning at (\a x, \a y) with the given
563 \a width and \a height, using the specified \a painter, \a lineColor
564 and \a lineWidth. The rectangle's interior is filled with the \a
565 fill brush unless \a fill is 0.
566
567 \warning This function does not look at QWidget::style() or
568 QApplication::style(). Use the drawing functions in QStyle to make
569 widgets that follow the current GUI style.
570
571 Alternatively you can use a QFrame widget and apply the
572 QFrame::setFrameStyle() function to display a plain rectangle:
573
574 \snippet code/src_gui_painting_qdrawutil.cpp 4
575
576 \sa qDrawShadeRect(), QStyle
577*/
578
579void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
580 int lineWidth, const QBrush *fill)
581{
582 if (w == 0 || h == 0)
583 return;
584 if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
585 qWarning("qDrawPlainRect: Invalid parameters");
586 }
587
599 p->translate(0.5, 0.5);
600 }
601
602 QPen oldPen = p->pen();
603 QBrush oldBrush = p->brush();
604 p->setPen(c);
605 p->setBrush(Qt::NoBrush);
606 for (int i=0; i<lineWidth; i++)
607 p->drawRect(x+i, y+i, w-i*2 - 1, h-i*2 - 1);
608 if (fill) { // fill with fill color
609 p->setPen(Qt::NoPen);
610 p->setBrush(*fill);
612 }
613 p->setPen(oldPen);
615}
616
617/*****************************************************************************
618 Overloaded functions.
619 *****************************************************************************/
620
621/*!
622 \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2,
623 const QPalette &palette, bool sunken, int lineWidth, int midLineWidth)
624 \relates <qdrawutil.h>
625 \overload
626
627 Draws a horizontal or vertical shaded line between \a p1 and \a p2
628 using the given \a painter. Note that nothing is drawn if the line
629 between the points would be neither horizontal nor vertical.
630
631 The provided \a palette specifies the shading colors (\l
632 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
633 {QPalette::mid()}{middle} colors). The given \a lineWidth
634 specifies the line width for each of the lines; it is not the
635 total line width. The given \a midLineWidth specifies the width of
636 a middle line drawn in the QPalette::mid() color.
637
638 The line appears sunken if \a sunken is true, otherwise raised.
639
640 \warning This function does not look at QWidget::style() or
641 QApplication::style(). Use the drawing functions in QStyle to
642 make widgets that follow the current GUI style.
643
644
645 Alternatively you can use a QFrame widget and apply the
646 QFrame::setFrameStyle() function to display a shaded line:
647
648 \snippet code/src_gui_painting_qdrawutil.cpp 5
649
650 \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
651*/
652
653void qDrawShadeLine(QPainter *p, const QPoint &p1, const QPoint &p2,
654 const QPalette &pal, bool sunken,
655 int lineWidth, int midLineWidth)
656{
657 qDrawShadeLine(p, p1.x(), p1.y(), p2.x(), p2.y(), pal, sunken,
659}
660
661/*!
662 \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette,
663 bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
664 \relates <qdrawutil.h>
665 \overload
666
667 Draws the shaded rectangle specified by \a rect using the given \a painter.
668
669 The provide \a palette specifies the shading colors (\l
670 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
671 {QPalette::mid()}{middle} colors. The given \a lineWidth
672 specifies the line width for each of the lines; it is not the
673 total line width. The \a midLineWidth specifies the width of a
674 middle line drawn in the QPalette::mid() color. The rectangle's
675 interior is filled with the \a fill brush unless \a fill is 0.
676
677 The rectangle appears sunken if \a sunken is true, otherwise
678 raised.
679
680 \warning This function does not look at QWidget::style() or
681 QApplication::style(). Use the drawing functions in QStyle to make
682 widgets that follow the current GUI style.
683
684 Alternatively you can use a QFrame widget and apply the
685 QFrame::setFrameStyle() function to display a shaded rectangle:
686
687 \snippet code/src_gui_painting_qdrawutil.cpp 6
688
689 \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
690*/
691
693 const QPalette &pal, bool sunken,
694 int lineWidth, int midLineWidth,
695 const QBrush *fill)
696{
697 qDrawShadeRect(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
699}
700
701/*!
702 \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette,
703 bool sunken, int lineWidth, const QBrush *fill)
704 \relates <qdrawutil.h>
705 \overload
706
707 Draws the shaded panel at the rectangle specified by \a rect using the
708 given \a painter and the given \a lineWidth.
709
710 The given \a palette specifies the shading colors (\l
711 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
712 {QPalette::mid()}{middle} colors). The panel's interior is filled
713 with the \a fill brush unless \a fill is 0.
714
715 The panel appears sunken if \a sunken is true, otherwise raised.
716
717 \warning This function does not look at QWidget::style() or
718 QApplication::style(). Use the drawing functions in QStyle to make
719 widgets that follow the current GUI style.
720
721 Alternatively you can use a QFrame widget and apply the
722 QFrame::setFrameStyle() function to display a shaded panel:
723
724 \snippet code/src_gui_painting_qdrawutil.cpp 7
725
726 \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
727*/
728
730 const QPalette &pal, bool sunken,
731 int lineWidth, const QBrush *fill)
732{
733 qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken,
734 lineWidth, fill);
735}
736
737/*!
738 \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette,
739 bool sunken, const QBrush *fill)
740 \relates <qdrawutil.h>
741 \overload
742
743 Draws the Windows-style button at the rectangle specified by \a rect using
744 the given \a painter with a line width of 2 pixels. The button's interior
745 is filled with the \a{fill} brush unless \a fill is 0.
746
747 The given \a palette specifies the shading colors (\l
748 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
749 {QPalette::mid()}{middle} colors).
750
751 The button appears sunken if \a sunken is true, otherwise raised.
752
753 \warning This function does not look at QWidget::style() or
754 QApplication::style()-> Use the drawing functions in QStyle to make
755 widgets that follow the current GUI style.
756
757 \sa qDrawWinPanel(), QStyle
758*/
759
761 const QPalette &pal, bool sunken, const QBrush *fill)
762{
763 qDrawWinButton(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
764}
765
766/*!
767 \fn void qDrawWinPanel(QPainter *painter, const QRect &rect, const QPalette &palette,
768 bool sunken, const QBrush *fill)
769 \overload
770
771 Draws the Windows-style panel at the rectangle specified by \a rect using
772 the given \a painter with a line width of 2 pixels. The button's interior
773 is filled with the \a fill brush unless \a fill is 0.
774
775 The given \a palette specifies the shading colors. The panel
776 appears sunken if \a sunken is true, otherwise raised.
777
778 \warning This function does not look at QWidget::style() or
779 QApplication::style(). Use the drawing functions in QStyle to make
780 widgets that follow the current GUI style.
781
782 Alternatively you can use a QFrame widget and apply the
783 QFrame::setFrameStyle() function to display a shaded panel:
784
785 \snippet code/src_gui_painting_qdrawutil.cpp 8
786
787 \sa qDrawShadePanel(), qDrawWinButton(), QStyle
788*/
789
791 const QPalette &pal, bool sunken, const QBrush *fill)
792{
793 qDrawWinPanel(p, r.x(), r.y(), r.width(), r.height(), pal, sunken, fill);
794}
795
796/*!
797 \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill)
798 \relates <qdrawutil.h>
799 \overload
800
801 Draws the plain rectangle specified by \a rect using the given \a painter,
802 \a lineColor and \a lineWidth. The rectangle's interior is filled with the
803 \a fill brush unless \a fill is 0.
804
805 \warning This function does not look at QWidget::style() or
806 QApplication::style(). Use the drawing functions in QStyle to make
807 widgets that follow the current GUI style.
808
809 Alternatively you can use a QFrame widget and apply the
810 QFrame::setFrameStyle() function to display a plain rectangle:
811
812 \snippet code/src_gui_painting_qdrawutil.cpp 9
813
814 \sa qDrawShadeRect(), QStyle
815*/
816
817void qDrawPlainRect(QPainter *p, const QRect &r, const QColor &c,
818 int lineWidth, const QBrush *fill)
819{
820 qDrawPlainRect(p, r.x(), r.y(), r.width(), r.height(), c,
821 lineWidth, fill);
822}
823
824
825/*!
826 \class QTileRules
827 \since 4.6
828
829 \inmodule QtWidgets
830
831 \brief The QTileRules class provides the rules used to draw a
832 pixmap or image split into nine segments.
833
834 Spliiting is similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}.
835
836 \sa Qt::TileRule, QMargins
837*/
838
839/*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
840 Constructs a QTileRules with the given \a horizontalRule and
841 \a verticalRule.
842 */
843
844/*! \fn QTileRules::QTileRules(Qt::TileRule rule)
845 Constructs a QTileRules with the given \a rule used for both
846 the horizontal rule and the vertical rule.
847 */
848
849/*!
850 \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap)
851 \relates <qdrawutil.h>
852 \since 4.6
853
854 \brief The qDrawBorderPixmap function is for drawing a pixmap into
855 the margins of a rectangle.
856
857 Draws the given \a pixmap into the given \a target rectangle, using the
858 given \a painter. The pixmap will be split into nine segments and drawn
859 according to the \a margins structure.
860*/
861
863
864/*!
865 \since 4.6
866
867 Draws the indicated \a sourceRect rectangle from the given \a pixmap into
868 the given \a targetRect rectangle, using the given \a painter. The pixmap
869 will be split into nine segments according to the given \a targetMargins
870 and \a sourceMargins structures. Finally, the pixmap will be drawn
871 according to the given \a rules.
872
873 This function is used to draw a scaled pixmap, similar to
874 \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}
875
876 \sa Qt::TileRule, QTileRules, QMargins
877*/
878
880 const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
881 const QTileRules &rules
882#ifndef Q_QDOC
884#endif
885 )
886{
888 d.opacity = 1.0;
889 d.rotation = 0.0;
890
893
894 // source center
901 // target center
908
909 QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles
910 QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles
911
912 int columns = 3;
913 int rows = 3;
918
920 yTarget.resize(rows + 1);
921
927 }
928
929 xTarget[0] = targetRect.left();
933
934 yTarget[0] = targetRect.top();
938
941
942 switch (rules.horizontal) {
943 case Qt::StretchTile:
945 break;
946 case Qt::RepeatTile:
948 break;
949 case Qt::RoundTile:
951 break;
952 }
953
954 for (int i = 2; i < columns - 1; ++i)
955 xTarget[i] = xTarget[i - 1] + dx;
956
957 switch (rules.vertical) {
958 case Qt::StretchTile:
960 break;
961 case Qt::RepeatTile:
963 break;
964 case Qt::RoundTile:
966 break;
967 }
968
969 for (int i = 2; i < rows - 1; ++i)
970 yTarget[i] = yTarget[i - 1] + dy;
971
972 // corners
973 if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
974 d.x = (0.5 * (xTarget[1] + xTarget[0]));
975 d.y = (0.5 * (yTarget[1] + yTarget[0]));
980 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
981 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
984 else
986 }
987 if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
988 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
989 d.y = (0.5 * (yTarget[1] + yTarget[0]));
995 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
998 else
1000 }
1001 if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
1002 d.x = (0.5 * (xTarget[1] + xTarget[0]));
1003 d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
1008 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
1009 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1012 else
1014 }
1015 if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
1016 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
1017 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
1023 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1026 else
1028 }
1029
1030 // horizontal edges
1031 if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
1032 if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
1038 d.y = (0.5 * (yTarget[1] + yTarget[0]));
1039 d.scaleX = dx / d.width;
1040 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
1041 for (int i = 1; i < columns - 1; ++i) {
1042 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1043 data.append(d);
1044 }
1045 if (rules.horizontal == Qt::RepeatTile)
1046 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
1047 }
1048 if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
1054 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
1055 d.scaleX = dx / d.width;
1056 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
1057 for (int i = 1; i < columns - 1; ++i) {
1058 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1059 data.append(d);
1060 }
1061 if (rules.horizontal == Qt::RepeatTile)
1062 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
1063 }
1064 }
1065
1066 // vertical edges
1067 if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
1068 if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
1074 d.x = (0.5 * (xTarget[1] + xTarget[0]));
1075 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
1076 d.scaleY = dy / d.height;
1077 for (int i = 1; i < rows - 1; ++i) {
1078 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
1079 data.append(d);
1080 }
1081 if (rules.vertical == Qt::RepeatTile)
1082 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
1083 }
1084 if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
1090 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
1092 d.scaleY = dy / d.height;
1093 for (int i = 1; i < rows - 1; ++i) {
1094 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
1095 data.append(d);
1096 }
1097 if (rules.vertical == Qt::RepeatTile)
1098 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
1099 }
1100 }
1101
1102 // center
1109 d.scaleX = dx / d.width;
1110 d.scaleY = dy / d.height;
1111
1113 qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
1114
1115 for (int j = 1; j < rows - 1; ++j) {
1116 d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
1117 for (int i = 1; i < columns - 1; ++i) {
1118 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
1119 data.append(d);
1120 }
1121 if (rules.horizontal == Qt::RepeatTile)
1122 data[data.size() - 1].width = repeatWidth;
1123 }
1124 if (rules.vertical == Qt::RepeatTile) {
1125 for (int i = 1; i < columns - 1; ++i)
1127 }
1128 }
1129
1130 if (opaqueData.size())
1132 if (translucentData.size())
1134
1135 if (oldAA)
1137}
1138
1139} // namespace QQC2
1140
1141QT_END_NAMESPACE
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 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)
QVarLengthArray< QPainter::PixmapFragment, 16 > QPixmapFragmentsArray
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)