1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qdrawutil.h"
44 #include "qpixmapcache.h"
45 #include "qapplication.h"
48 #include <private/qpaintengineex_p.h>
49 #include <qvarlengtharray.h>
55 \headerfile <qdrawutil.h>
56 \title Drawing Utility Functions
62 \fn void qDrawShadeLine(QPainter *painter, int x1, int y1, int x2, int y2,
63 const QPalette &palette, bool sunken,
64 int lineWidth, int midLineWidth)
65 \relates <qdrawutil.h>
67 Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
68 shaded line using the given \a painter. Note that nothing is
69 drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the line is
70 neither horizontal nor vertical).
72 The provided \a palette specifies the shading colors (\l
73 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
74 {QPalette::mid()}{middle} colors). The given \a lineWidth
75 specifies the line width for each of the lines; it is not the
76 total line width. The given \a midLineWidth specifies the width of
77 a middle line drawn in the QPalette::mid() color.
79 The line appears sunken if \a sunken is true, otherwise raised.
81 \warning This function does not look at QWidget::style() or
82 QApplication::style(). Use the drawing functions in QStyle to
83 make widgets that follow the current GUI style.
86 Alternatively you can use a QFrame widget and apply the
87 QFrame::setFrameStyle() function to display a shaded line:
89 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 0
91 \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
94 void qDrawShadeLine(QPainter
*p
, int x1
, int y1
, int x2
, int y2
,
95 const QPalette
&pal
, bool sunken
,
96 int lineWidth
, int midLineWidth
)
98 if (!(p
&& lineWidth
>= 0 && midLineWidth
>= 0)) {
99 qWarning("qDrawShadeLine: Invalid parameters");
102 int tlw
= lineWidth
*2 + midLineWidth
; // total line width
103 QPen oldPen
= p
->pen(); // save pen
105 p
->setPen(pal
.color(QPalette::Dark
));
107 p
->setPen(pal
.light().color());
110 if (y1
== y2
) { // horizontal line
112 if (x1
> x2
) { // swap x1 and x2
118 for (i
=0; i
<lineWidth
; i
++) { // draw top shadow
119 a
.setPoints(3, x1
+i
, y
+tlw
-1-i
,
124 if (midLineWidth
> 0) {
125 p
->setPen(pal
.mid().color());
126 for (i
=0; i
<midLineWidth
; i
++) // draw lines in the middle
127 p
->drawLine(x1
+lineWidth
, y
+lineWidth
+i
,
128 x2
-lineWidth
, y
+lineWidth
+i
);
131 p
->setPen(pal
.light().color());
133 p
->setPen(pal
.dark().color());
134 for (i
=0; i
<lineWidth
; i
++) { // draw bottom shadow
135 a
.setPoints(3, x1
+i
, y
+tlw
-i
-1,
141 else if (x1
== x2
) { // vertical line
143 if (y1
> y2
) { // swap y1 and y2
149 for (i
=0; i
<lineWidth
; i
++) { // draw left shadow
150 a
.setPoints(3, x
+i
, y2
,
155 if (midLineWidth
> 0) {
156 p
->setPen(pal
.mid().color());
157 for (i
=0; i
<midLineWidth
; i
++) // draw lines in the middle
158 p
->drawLine(x
+lineWidth
+i
, y1
+lineWidth
, x
+lineWidth
+i
, y2
);
161 p
->setPen(pal
.light().color());
163 p
->setPen(pal
.dark().color());
164 for (i
=0; i
<lineWidth
; i
++) { // draw right shadow
165 a
.setPoints(3, x
+lineWidth
, y2
-i
,
167 x
+tlw
-i
-1, y1
+lineWidth
);
175 \fn void qDrawShadeRect(QPainter *painter, int x, int y, int width, int height,
176 const QPalette &palette, bool sunken,
177 int lineWidth, int midLineWidth,
179 \relates <qdrawutil.h>
181 Draws the shaded rectangle beginning at (\a x, \a y) with the
182 given \a width and \a height using the provided \a painter.
184 The provide \a palette specifies the shading colors (\l
185 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
186 {QPalette::mid()}{middle} colors. The given \a lineWidth
187 specifies the line width for each of the lines; it is not the
188 total line width. The \a midLineWidth specifies the width of a
189 middle line drawn in the QPalette::mid() color. The rectangle's
190 interior is filled with the \a fill brush unless \a fill is 0.
192 The rectangle appears sunken if \a sunken is true, otherwise
195 \warning This function does not look at QWidget::style() or
196 QApplication::style(). Use the drawing functions in QStyle to make
197 widgets that follow the current GUI style.
199 Alternatively you can use a QFrame widget and apply the
200 QFrame::setFrameStyle() function to display a shaded rectangle:
202 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 1
204 \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
207 void qDrawShadeRect(QPainter
*p
, int x
, int y
, int w
, int h
,
208 const QPalette
&pal
, bool sunken
,
209 int lineWidth
, int midLineWidth
,
212 if (w
== 0 || h
== 0)
214 if (! (w
> 0 && h
> 0 && lineWidth
>= 0 && midLineWidth
>= 0)) {
215 qWarning("qDrawShadeRect: Invalid parameters");
218 QPen oldPen
= p
->pen();
220 p
->setPen(pal
.dark().color());
222 p
->setPen(pal
.light().color());
223 int x1
=x
, y1
=y
, x2
=x
+w
-1, y2
=y
+h
-1;
225 if (lineWidth
== 1 && midLineWidth
== 0) {// standard shade rectangle
226 p
->drawRect(x1
, y1
, w
-2, h
-2);
228 p
->setPen(pal
.light().color());
230 p
->setPen(pal
.dark().color());
231 QLineF lines
[4] = { QLineF(x1
+1, y1
+1, x2
-2, y1
+1),
232 QLineF(x1
+1, y1
+2, x1
+1, y2
-2),
233 QLineF(x1
, y2
, x2
, y2
),
234 QLineF(x2
,y1
, x2
,y2
-1) };
235 p
->drawLines(lines
, 4); // draw bottom/right lines
236 } else { // more complicated
237 int m
= lineWidth
+midLineWidth
;
239 for (i
=0; i
<lineWidth
; i
++) { // draw top shadow
240 QLineF lines
[4] = { QLineF(x1
+i
, y2
-i
, x1
+i
, y1
+i
),
241 QLineF(x1
+i
, y1
+i
, x2
-i
, y1
+i
),
242 QLineF(x1
+k
, y2
-k
, x2
-k
, y2
-k
),
243 QLineF(x2
-k
, y2
-k
, x2
-k
, y1
+k
) };
244 p
->drawLines(lines
, 4);
247 p
->setPen(pal
.mid().color());
249 for (i
=0; i
<midLineWidth
; i
++) { // draw lines in the middle
250 p
->drawRect(x1
+lineWidth
+i
, y1
+lineWidth
+i
, w
-j
-1, h
-j
-1);
254 p
->setPen(pal
.light().color());
256 p
->setPen(pal
.dark().color());
258 for (i
=0; i
<lineWidth
; i
++) { // draw bottom shadow
259 QLineF lines
[4] = { QLineF(x1
+1+i
, y2
-i
, x2
-i
, y2
-i
),
260 QLineF(x2
-i
, y2
-i
, x2
-i
, y1
+i
+1),
261 QLineF(x1
+k
, y2
-k
, x1
+k
, y1
+k
),
262 QLineF(x1
+k
, y1
+k
, x2
-k
, y1
+k
) };
263 p
->drawLines(lines
, 4);
268 QBrush oldBrush
= p
->brush();
269 int tlw
= lineWidth
+ midLineWidth
;
270 p
->setPen(Qt::NoPen
);
272 p
->drawRect(x
+tlw
, y
+tlw
, w
-2*tlw
, h
-2*tlw
);
273 p
->setBrush(oldBrush
);
275 p
->setPen(oldPen
); // restore pen
280 \fn void qDrawShadePanel(QPainter *painter, int x, int y, int width, int height,
281 const QPalette &palette, bool sunken,
282 int lineWidth, const QBrush *fill)
283 \relates <qdrawutil.h>
285 Draws the shaded panel beginning at (\a x, \a y) with the given \a
286 width and \a height using the provided \a painter and the given \a
289 The given \a palette specifies the shading colors (\l
290 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
291 {QPalette::mid()}{middle} colors). The panel's interior is filled
292 with the \a fill brush unless \a fill is 0.
294 The panel appears sunken if \a sunken is true, otherwise raised.
296 \warning This function does not look at QWidget::style() or
297 QApplication::style(). Use the drawing functions in QStyle to make
298 widgets that follow the current GUI style.
300 Alternatively you can use a QFrame widget and apply the
301 QFrame::setFrameStyle() function to display a shaded panel:
303 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 2
305 \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
308 void qDrawShadePanel(QPainter
*p
, int x
, int y
, int w
, int h
,
309 const QPalette
&pal
, bool sunken
,
310 int lineWidth
, const QBrush
*fill
)
312 if (w
== 0 || h
== 0)
314 if (!(w
> 0 && h
> 0 && lineWidth
>= 0)) {
315 qWarning("qDrawShadePanel: Invalid parameters");
317 QColor shade
= pal
.dark().color();
318 QColor light
= pal
.light().color();
320 if (fill
->color() == shade
)
321 shade
= pal
.shadow().color();
322 if (fill
->color() == light
)
323 light
= pal
.midlight().color();
325 QPen oldPen
= p
->pen(); // save pen
326 QVector
<QLineF
> lines
;
327 lines
.reserve(2*lineWidth
);
338 for (i
=0; i
<lineWidth
; i
++) { // top shadow
339 lines
<< QLineF(x1
, y1
++, x2
--, y2
++);
343 for (i
=0; i
<lineWidth
; i
++) { // left shado
344 lines
<< QLineF(x1
++, y1
, x2
++, y2
--);
355 for (i
=0; i
<lineWidth
; i
++) { // bottom shadow
356 lines
<< QLineF(x1
++, y1
--, x2
, y2
--);
360 y2
= y
+h
-lineWidth
-1;
361 for (i
=0; i
<lineWidth
; i
++) { // right shadow
362 lines
<< QLineF(x1
--, y1
++, x2
--, y2
);
365 if (fill
) // fill with fill color
366 p
->fillRect(x
+lineWidth
, y
+lineWidth
, w
-lineWidth
*2, h
-lineWidth
*2, *fill
);
367 p
->setPen(oldPen
); // restore pen
373 This function draws a rectangle with two pixel line width.
374 It is called from qDrawWinButton() and qDrawWinPanel().
376 c1..c4 and fill are used:
386 static void qDrawWinShades(QPainter
*p
,
387 int x
, int y
, int w
, int h
,
388 const QColor
&c1
, const QColor
&c2
,
389 const QColor
&c3
, const QColor
&c4
,
392 if (w
< 2 || h
< 2) // can't do anything with that
394 QPen oldPen
= p
->pen();
395 QPoint a
[3] = { QPoint(x
, y
+h
-2), QPoint(x
, y
), QPoint(x
+w
-2, y
) };
397 p
->drawPolyline(a
, 3);
398 QPoint b
[3] = { QPoint(x
, y
+h
-1), QPoint(x
+w
-1, y
+h
-1), QPoint(x
+w
-1, y
) };
400 p
->drawPolyline(b
, 3);
401 if (w
> 4 && h
> 4) {
402 QPoint c
[3] = { QPoint(x
+1, y
+h
-3), QPoint(x
+1, y
+1), QPoint(x
+w
-3, y
+1) };
404 p
->drawPolyline(c
, 3);
405 QPoint d
[3] = { QPoint(x
+1, y
+h
-2), QPoint(x
+w
-2, y
+h
-2), QPoint(x
+w
-2, y
+1) };
407 p
->drawPolyline(d
, 3);
409 p
->fillRect(QRect(x
+2, y
+2, w
-4, h
-4), *fill
);
416 \fn void qDrawWinButton(QPainter *painter, int x, int y, int width, int height,
417 const QPalette &palette, bool sunken,
419 \relates <qdrawutil.h>
421 Draws the Windows-style button specified by the given point (\a x,
422 \a y}, \a width and \a height using the provided \a painter with a
423 line width of 2 pixels. The button's interior is filled with the
424 \a{fill} brush unless \a fill is 0.
426 The given \a palette specifies the shading colors (\l
427 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
428 {QPalette::mid()}{middle} colors).
430 The button appears sunken if \a sunken is true, otherwise raised.
432 \warning This function does not look at QWidget::style() or
433 QApplication::style()-> Use the drawing functions in QStyle to make
434 widgets that follow the current GUI style.
436 \sa qDrawWinPanel(), QStyle
439 void qDrawWinButton(QPainter
*p
, int x
, int y
, int w
, int h
,
440 const QPalette
&pal
, bool sunken
,
444 qDrawWinShades(p
, x
, y
, w
, h
,
445 pal
.shadow().color(), pal
.light().color(), pal
.dark().color(),
446 pal
.button().color(), fill
);
448 qDrawWinShades(p
, x
, y
, w
, h
,
449 pal
.light().color(), pal
.shadow().color(), pal
.button().color(),
450 pal
.dark().color(), fill
);
454 \fn void qDrawWinPanel(QPainter *painter, int x, int y, int width, int height,
455 const QPalette &palette, bool sunken,
457 \relates <qdrawutil.h>
459 Draws the Windows-style panel specified by the given point(\a x,
460 \a y), \a width and \a height using the provided \a painter with a
461 line width of 2 pixels. The button's interior is filled with the
462 \a fill brush unless \a fill is 0.
464 The given \a palette specifies the shading colors. The panel
465 appears sunken if \a sunken is true, otherwise raised.
467 \warning This function does not look at QWidget::style() or
468 QApplication::style(). Use the drawing functions in QStyle to make
469 widgets that follow the current GUI style.
471 Alternatively you can use a QFrame widget and apply the
472 QFrame::setFrameStyle() function to display a shaded panel:
474 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 3
476 \sa qDrawShadePanel(), qDrawWinButton(), QStyle
479 void qDrawWinPanel(QPainter
*p
, int x
, int y
, int w
, int h
,
480 const QPalette
&pal
, bool sunken
,
484 qDrawWinShades(p
, x
, y
, w
, h
,
485 pal
.dark().color(), pal
.light().color(), pal
.shadow().color(),
486 pal
.midlight().color(), fill
);
488 qDrawWinShades(p
, x
, y
, w
, h
,
489 pal
.light().color(), pal
.shadow().color(), pal
.midlight().color(),
490 pal
.dark().color(), fill
);
494 \fn void qDrawPlainRect(QPainter *painter, int x, int y, int width, int height, const QColor &lineColor,
495 int lineWidth, const QBrush *fill)
496 \relates <qdrawutil.h>
498 Draws the plain rectangle beginning at (\a x, \a y) with the given
499 \a width and \a height, using the specified \a painter, \a lineColor
500 and \a lineWidth. The rectangle's interior is filled with the \a
501 fill brush unless \a fill is 0.
503 \warning This function does not look at QWidget::style() or
504 QApplication::style(). Use the drawing functions in QStyle to make
505 widgets that follow the current GUI style.
507 Alternatively you can use a QFrame widget and apply the
508 QFrame::setFrameStyle() function to display a plain rectangle:
510 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 4
512 \sa qDrawShadeRect(), QStyle
515 void qDrawPlainRect(QPainter
*p
, int x
, int y
, int w
, int h
, const QColor
&c
,
516 int lineWidth
, const QBrush
*fill
)
518 if (w
== 0 || h
== 0)
520 if (!(w
> 0 && h
> 0 && lineWidth
>= 0)) {
521 qWarning("qDrawPlainRect: Invalid parameters");
523 QPen oldPen
= p
->pen();
524 QBrush oldBrush
= p
->brush();
526 p
->setBrush(Qt::NoBrush
);
527 for (int i
=0; i
<lineWidth
; i
++)
528 p
->drawRect(x
+i
, y
+i
, w
-i
*2 - 1, h
-i
*2 - 1);
529 if (fill
) { // fill with fill color
530 p
->setPen(Qt::NoPen
);
532 p
->drawRect(x
+lineWidth
, y
+lineWidth
, w
-lineWidth
*2, h
-lineWidth
*2);
535 p
->setBrush(oldBrush
);
538 /*****************************************************************************
539 Overloaded functions.
540 *****************************************************************************/
543 \fn void qDrawShadeLine(QPainter *painter, const QPoint &p1, const QPoint &p2,
544 const QPalette &palette, bool sunken, int lineWidth, int midLineWidth)
545 \relates <qdrawutil.h>
548 Draws a horizontal or vertical shaded line between \a p1 and \a p2
549 using the given \a painter. Note that nothing is drawn if the line
550 between the points would be neither horizontal nor vertical.
552 The provided \a palette specifies the shading colors (\l
553 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
554 {QPalette::mid()}{middle} colors). The given \a lineWidth
555 specifies the line width for each of the lines; it is not the
556 total line width. The given \a midLineWidth specifies the width of
557 a middle line drawn in the QPalette::mid() color.
559 The line appears sunken if \a sunken is true, otherwise raised.
561 \warning This function does not look at QWidget::style() or
562 QApplication::style(). Use the drawing functions in QStyle to
563 make widgets that follow the current GUI style.
566 Alternatively you can use a QFrame widget and apply the
567 QFrame::setFrameStyle() function to display a shaded line:
569 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 5
571 \sa qDrawShadeRect(), qDrawShadePanel(), QStyle
574 void qDrawShadeLine(QPainter
*p
, const QPoint
&p1
, const QPoint
&p2
,
575 const QPalette
&pal
, bool sunken
,
576 int lineWidth
, int midLineWidth
)
578 qDrawShadeLine(p
, p1
.x(), p1
.y(), p2
.x(), p2
.y(), pal
, sunken
,
579 lineWidth
, midLineWidth
);
583 \fn void qDrawShadeRect(QPainter *painter, const QRect &rect, const QPalette &palette,
584 bool sunken, int lineWidth, int midLineWidth, const QBrush *fill)
585 \relates <qdrawutil.h>
588 Draws the shaded rectangle specified by \a rect using the given \a painter.
590 The provide \a palette specifies the shading colors (\l
591 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
592 {QPalette::mid()}{middle} colors. The given \a lineWidth
593 specifies the line width for each of the lines; it is not the
594 total line width. The \a midLineWidth specifies the width of a
595 middle line drawn in the QPalette::mid() color. The rectangle's
596 interior is filled with the \a fill brush unless \a fill is 0.
598 The rectangle appears sunken if \a sunken is true, otherwise
601 \warning This function does not look at QWidget::style() or
602 QApplication::style(). Use the drawing functions in QStyle to make
603 widgets that follow the current GUI style.
605 Alternatively you can use a QFrame widget and apply the
606 QFrame::setFrameStyle() function to display a shaded rectangle:
608 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 6
610 \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(), QStyle
613 void qDrawShadeRect(QPainter
*p
, const QRect
&r
,
614 const QPalette
&pal
, bool sunken
,
615 int lineWidth
, int midLineWidth
,
618 qDrawShadeRect(p
, r
.x(), r
.y(), r
.width(), r
.height(), pal
, sunken
,
619 lineWidth
, midLineWidth
, fill
);
623 \fn void qDrawShadePanel(QPainter *painter, const QRect &rect, const QPalette &palette,
624 bool sunken, int lineWidth, const QBrush *fill)
625 \relates <qdrawutil.h>
628 Draws the shaded panel at the rectangle specified by \a rect using the
629 given \a painter and the given \a lineWidth.
631 The given \a palette specifies the shading colors (\l
632 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
633 {QPalette::mid()}{middle} colors). The panel's interior is filled
634 with the \a fill brush unless \a fill is 0.
636 The panel appears sunken if \a sunken is true, otherwise raised.
638 \warning This function does not look at QWidget::style() or
639 QApplication::style(). Use the drawing functions in QStyle to make
640 widgets that follow the current GUI style.
642 Alternatively you can use a QFrame widget and apply the
643 QFrame::setFrameStyle() function to display a shaded panel:
645 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 7
647 \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(), QStyle
650 void qDrawShadePanel(QPainter
*p
, const QRect
&r
,
651 const QPalette
&pal
, bool sunken
,
652 int lineWidth
, const QBrush
*fill
)
654 qDrawShadePanel(p
, r
.x(), r
.y(), r
.width(), r
.height(), pal
, sunken
,
659 \fn void qDrawWinButton(QPainter *painter, const QRect &rect, const QPalette &palette,
660 bool sunken, const QBrush *fill)
661 \relates <qdrawutil.h>
664 Draws the Windows-style button at the rectangle specified by \a rect using
665 the given \a painter with a line width of 2 pixels. The button's interior
666 is filled with the \a{fill} brush unless \a fill is 0.
668 The given \a palette specifies the shading colors (\l
669 {QPalette::light()}{light}, \l {QPalette::dark()}{dark} and \l
670 {QPalette::mid()}{middle} colors).
672 The button appears sunken if \a sunken is true, otherwise raised.
674 \warning This function does not look at QWidget::style() or
675 QApplication::style()-> Use the drawing functions in QStyle to make
676 widgets that follow the current GUI style.
678 \sa qDrawWinPanel(), QStyle
681 void qDrawWinButton(QPainter
*p
, const QRect
&r
,
682 const QPalette
&pal
, bool sunken
, const QBrush
*fill
)
684 qDrawWinButton(p
, r
.x(), r
.y(), r
.width(), r
.height(), pal
, sunken
, fill
);
688 \fn void qDrawWinPanel(QPainter *painter, const QRect &rect, const QPalette &palette,
689 bool sunken, const QBrush *fill)
692 Draws the Windows-style panel at the rectangle specified by \a rect using
693 the given \a painter with a line width of 2 pixels. The button's interior
694 is filled with the \a fill brush unless \a fill is 0.
696 The given \a palette specifies the shading colors. The panel
697 appears sunken if \a sunken is true, otherwise raised.
699 \warning This function does not look at QWidget::style() or
700 QApplication::style(). Use the drawing functions in QStyle to make
701 widgets that follow the current GUI style.
703 Alternatively you can use a QFrame widget and apply the
704 QFrame::setFrameStyle() function to display a shaded panel:
706 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 8
708 \sa qDrawShadePanel(), qDrawWinButton(), QStyle
711 void qDrawWinPanel(QPainter
*p
, const QRect
&r
,
712 const QPalette
&pal
, bool sunken
, const QBrush
*fill
)
714 qDrawWinPanel(p
, r
.x(), r
.y(), r
.width(), r
.height(), pal
, sunken
, fill
);
718 \fn void qDrawPlainRect(QPainter *painter, const QRect &rect, const QColor &lineColor, int lineWidth, const QBrush *fill)
719 \relates <qdrawutil.h>
722 Draws the plain rectangle specified by \a rect using the given \a painter,
723 \a lineColor and \a lineWidth. The rectangle's interior is filled with the
724 \a fill brush unless \a fill is 0.
726 \warning This function does not look at QWidget::style() or
727 QApplication::style(). Use the drawing functions in QStyle to make
728 widgets that follow the current GUI style.
730 Alternatively you can use a QFrame widget and apply the
731 QFrame::setFrameStyle() function to display a plain rectangle:
733 \snippet doc/src/snippets/code/src_gui_painting_qdrawutil.cpp 9
735 \sa qDrawShadeRect(), QStyle
738 void qDrawPlainRect(QPainter
*p
, const QRect
&r
, const QColor
&c
,
739 int lineWidth
, const QBrush
*fill
)
741 qDrawPlainRect(p
, r
.x(), r
.y(), r
.width(), r
.height(), c
,
746 static void qDrawWinArrow(QPainter
*p
, Qt::ArrowType type
, bool down
,
747 int x
, int y
, int w
, int h
,
748 const QPalette
&pal
, bool enabled
)
750 QPolygon a
; // arrow polygon
753 a
.setPoints(7, -3,1, 3,1, -2,0, 2,0, -1,-1, 1,-1, 0,-2);
756 a
.setPoints(7, -3,-1, 3,-1, -2,0, 2,0, -1,1, 1,1, 0,2);
759 a
.setPoints(7, 1,-3, 1,3, 0,-2, 0,2, -1,-1, -1,1, -2,0);
762 a
.setPoints(7, -1,-3, -1,3, 0,-2, 0,2, 1,-1, 1,1, 2,0);
775 QPen savePen
= p
->pen(); // save current pen
777 p
->setBrushOrigin(p
->brushOrigin() + QPoint(1,1));
778 p
->fillRect(x
, y
, w
, h
, pal
.brush(QPalette::Button
));
780 p
->setBrushOrigin(p
->brushOrigin() - QPoint(1,1));
782 a
.translate(x
+w
/2, y
+h
/2);
783 p
->setPen(pal
.foreground().color());
784 p
->drawLine(a
.at(0), a
.at(1));
785 p
->drawLine(a
.at(2), a
.at(2));
788 a
.translate(x
+w
/2+1, y
+h
/2+1);
789 p
->setPen(pal
.light().color());
790 p
->drawLine(a
.at(0), a
.at(1));
791 p
->drawLine(a
.at(2), a
.at(2));
794 p
->setPen(pal
.mid().color());
795 p
->drawLine(a
.at(0), a
.at(1));
796 p
->drawLine(a
.at(2), a
.at(2));
799 p
->setPen(savePen
); // restore pen
801 #endif // QT3_SUPPORT
803 #if defined(Q_CC_MSVC)
804 #pragma warning(disable: 4244)
808 #ifndef QT_NO_STYLE_MOTIF
809 // motif arrows look the same whether they are used or not
811 static void qDrawMotifArrow(QPainter
*p
, Qt::ArrowType type
, bool down
,
812 int x
, int y
, int w
, int h
,
813 const QPalette
&pal
, bool)
815 QPolygon bFill
; // fill polygon
816 QPolygon bTop
; // top shadow.
817 QPolygon bBot
; // bottom shadow.
818 QPolygon bLeft
; // left shadow.
819 QTransform matrix
; // xform matrix
820 bool vertical
= type
== Qt::UpArrow
|| type
== Qt::DownArrow
;
821 bool horizontal
= !vertical
;
822 int dim
= w
< h
? w
: h
;
823 int colspec
= 0x0000; // color specification array
825 if (dim
< 2) // too small arrow
830 bFill
.resize(dim
& 1 ? 3 : 4);
831 bTop
.resize((dim
/2)*2);
832 bBot
.resize(dim
& 1 ? dim
+ 1 : dim
);
833 bLeft
.resize(dim
> 4 ? 4 : 2);
834 bLeft
.putPoints(0, 2, 0,0, 0,dim
-1);
836 bLeft
.putPoints(2, 2, 1,2, 1,dim
-3);
837 bTop
.putPoints(0, 4, 1,0, 1,1, 2,1, 3,1);
838 bBot
.putPoints(0, 4, 1,dim
-1, 1,dim
-2, 2,dim
-2, 3,dim
-2);
840 for(int i
=0; i
<dim
/2-2 ; i
++) {
841 bTop
.putPoints(i
*2+4, 2, 2+i
*2,2+i
, 5+i
*2, 2+i
);
842 bBot
.putPoints(i
*2+4, 2, 2+i
*2,dim
-3-i
, 5+i
*2,dim
-3-i
);
844 if (dim
& 1) // odd number size: extra line
845 bBot
.putPoints(dim
-1, 2, dim
-3,dim
/2, dim
-1,dim
/2);
846 if (dim
> 6) { // dim>6: must fill interior
847 bFill
.putPoints(0, 2, 1,dim
-3, 1,2);
848 if (dim
& 1) // if size is an odd number
849 bFill
.setPoint(2, dim
- 3, dim
/ 2);
851 bFill
.putPoints(2, 2, dim
-4,dim
/2-1, dim
-4,dim
/2);
855 if (dim
== 3) { // 3x3 arrow pattern
856 bLeft
.setPoints(4, 0,0, 0,2, 1,1, 1,1);
857 bTop
.setPoints(2, 1,0, 1,0);
858 bBot
.setPoints(2, 1,2, 2,1);
860 else { // 2x2 arrow pattern
861 bLeft
.setPoints(2, 0,0, 0,1);
862 bTop
.setPoints(2, 1,0, 1,0);
863 bBot
.setPoints(2, 1,1, 1,1);
867 if (type
== Qt::UpArrow
|| type
== Qt::LeftArrow
) {
868 matrix
.translate(x
, y
);
870 matrix
.translate(0, h
- 1);
873 matrix
.translate(w
- 1, h
- 1);
877 colspec
= horizontal
? 0x2334 : 0x2343;
879 colspec
= horizontal
? 0x1443 : 0x1434;
881 else if (type
== Qt::DownArrow
|| type
== Qt::RightArrow
) {
882 matrix
.translate(x
, y
);
884 matrix
.translate(w
-1, 0);
888 colspec
= horizontal
? 0x2443 : 0x2434;
890 colspec
= horizontal
? 0x1334 : 0x1343;
893 const QColor
*cols
[5];
895 cols
[1] = &pal
.button().color();
896 cols
[2] = &pal
.mid().color();
897 cols
[3] = &pal
.light().color();
898 cols
[4] = &pal
.dark().color();
899 #define CMID *cols[(colspec>>12) & 0xf]
900 #define CLEFT *cols[(colspec>>8) & 0xf]
901 #define CTOP *cols[(colspec>>4) & 0xf]
902 #define CBOT *cols[colspec & 0xf]
904 QPen savePen
= p
->pen(); // save current pen
905 QBrush saveBrush
= p
->brush(); // save current brush
906 QTransform wxm
= p
->transform();
908 const QBrush
&brush
= pal
.brush(QPalette::Button
);
912 p
->setTransform(matrix
, true); // set transformation matrix
913 p
->drawPolygon(bFill
); // fill arrow
914 p
->setBrush(Qt::NoBrush
); // don't fill
923 p
->setTransform(wxm
);
924 p
->setBrush(saveBrush
); // restore brush
925 p
->setPen(savePen
); // restore pen
932 #endif // QT_NO_STYLE_MOTIF
934 QRect
qItemRect(QPainter
*p
, Qt::GUIStyle gs
,
935 int x
, int y
, int w
, int h
,
938 const QPixmap
*pixmap
,
939 const QString
& text
, int len
)
944 if ((flags
& Qt::AlignVCenter
) == Qt::AlignVCenter
)
945 y
+= h
/2 - pixmap
->height()/2;
946 else if ((flags
& Qt::AlignBottom
) == Qt::AlignBottom
)
947 y
+= h
- pixmap
->height();
948 if ((flags
& Qt::AlignRight
) == Qt::AlignRight
)
949 x
+= w
- pixmap
->width();
950 else if ((flags
& Qt::AlignHCenter
) == Qt::AlignHCenter
)
951 x
+= w
/2 - pixmap
->width()/2;
952 else if ((flags
& Qt::AlignLeft
) != Qt::AlignLeft
&& QApplication::isRightToLeft())
953 x
+= w
- pixmap
->width();
954 result
= QRect(x
, y
, pixmap
->width(), pixmap
->height());
955 } else if (!text
.isNull() && p
) {
956 result
= p
->boundingRect(QRect(x
, y
, w
, h
), flags
, text
.left(len
));
957 if (gs
== Qt::WindowsStyle
&& !enabled
) {
958 result
.setWidth(result
.width()+1);
959 result
.setHeight(result
.height()+1);
962 result
= QRect(x
, y
, w
, h
);
968 void qDrawArrow(QPainter
*p
, Qt::ArrowType type
, Qt::GUIStyle style
, bool down
,
969 int x
, int y
, int w
, int h
,
970 const QPalette
&pal
, bool enabled
)
973 case Qt::WindowsStyle
:
974 qDrawWinArrow(p
, type
, down
, x
, y
, w
, h
, pal
, enabled
);
976 #ifndef QT_NO_STYLE_MOTIF
978 qDrawMotifArrow(p
, type
, down
, x
, y
, w
, h
, pal
, enabled
);
982 qWarning("qDrawArrow: Requested unsupported GUI style");
986 void qDrawItem(QPainter
*p
, Qt::GUIStyle gs
,
987 int x
, int y
, int w
, int h
,
989 const QPalette
&pal
, bool enabled
,
990 const QPixmap
*pixmap
,
991 const QString
& text
, int len
, const QColor
* penColor
)
993 p
->setPen(penColor
?*penColor
:pal
.foreground().color());
996 bool clip
= (flags
& Qt::TextDontClip
) == 0;
998 if (pm
.width() < w
&& pm
.height() < h
)
1001 p
->setClipRect(x
, y
, w
, h
);
1003 if ((flags
& Qt::AlignVCenter
) == Qt::AlignVCenter
)
1004 y
+= h
/2 - pm
.height()/2;
1005 else if ((flags
& Qt::AlignBottom
) == Qt::AlignBottom
)
1006 y
+= h
- pm
.height();
1007 if ((flags
& Qt::AlignRight
) == Qt::AlignRight
)
1008 x
+= w
- pm
.width();
1009 else if ((flags
& Qt::AlignHCenter
) == Qt::AlignHCenter
)
1010 x
+= w
/2 - pm
.width()/2;
1011 else if (((flags
& Qt::AlignLeft
) != Qt::AlignLeft
) && QApplication::isRightToLeft()) // Qt::AlignAuto && rightToLeft
1012 x
+= w
- pm
.width();
1015 if (pm
.hasAlphaChannel()) { // pixmap with a mask
1017 } else if (pm
.depth() == 1) { // monochrome pixmap, no mask
1019 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
1020 } else { // color pixmap, no mask
1021 QString k
= QString::fromLatin1("$qt-drawitem-%1").arg(pm
.cacheKey());
1022 if (!QPixmapCache::find(k
, pm
)) {
1023 pm
= pm
.createHeuristicMask();
1024 pm
.setMask((QBitmap
&)pm
);
1025 QPixmapCache::insert(k
, pm
);
1029 if (gs
== Qt::WindowsStyle
) {
1030 p
->setPen(pal
.light().color());
1031 p
->drawPixmap(x
+1, y
+1, pm
);
1032 p
->setPen(pal
.text().color());
1035 p
->drawPixmap(x
, y
, pm
);
1037 p
->setClipping(false);
1038 } else if (!text
.isNull()) {
1039 if (gs
== Qt::WindowsStyle
&& !enabled
) {
1040 p
->setPen(pal
.light().color());
1041 p
->drawText(x
+1, y
+1, w
, h
, flags
, text
.left(len
));
1042 p
->setPen(pal
.text().color());
1044 p
->drawText(x
, y
, w
, h
, flags
, text
.left(len
));
1054 Holds the rules used to draw a pixmap or image split into nine segments,
1055 similar to \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}.
1057 \sa Qt::TileRule, QMargins
1060 /*! \fn QTileRules::QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
1061 Constructs a QTileRules with the given \a horizontalRule and
1065 /*! \fn QTileRules::QTileRules(Qt::TileRule rule)
1066 Constructs a QTileRules with the given \a rule used for both
1067 the horizontal rule and the vertical rule.
1071 \fn void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap)
1072 \relates <qdrawutil.h>
1076 \brief The qDrawBorderPixmap function is for drawing a pixmap into
1077 the margins of a rectangle.
1079 Draws the given \a pixmap into the given \a target rectangle, using the
1080 given \a painter. The pixmap will be split into nine segments and drawn
1081 according to the \a margins structure.
1084 typedef QVarLengthArray
<QDrawPixmaps::Data
, 16> QDrawPixmapsDataArray
;
1089 Draws the indicated \a sourceRect rectangle from the given \a pixmap into
1090 the given \a targetRect rectangle, using the given \a painter. The pixmap
1091 will be split into nine segments according to the given \a targetMargins
1092 and \a sourceMargins structures. Finally, the pixmap will be drawn
1093 according to the given \a rules.
1095 This function is used to draw a scaled pixmap, similar to
1096 \l{http://www.w3.org/TR/css3-background/}{CSS3 border-images}
1098 \sa Qt::TileRule, QTileRules, QMargins
1101 void qDrawBorderPixmap(QPainter
*painter
, const QRect
&targetRect
, const QMargins
&targetMargins
,
1102 const QPixmap
&pixmap
, const QRect
&sourceRect
,const QMargins
&sourceMargins
,
1103 const QTileRules
&rules
, QDrawBorderPixmap::DrawingHints hints
)
1105 QDrawPixmaps::Data d
;
1109 QDrawPixmapsDataArray opaqueData
;
1110 QDrawPixmapsDataArray translucentData
;
1113 const int sourceCenterTop
= sourceRect
.top() + sourceMargins
.top();
1114 const int sourceCenterLeft
= sourceRect
.left() + sourceMargins
.left();
1115 const int sourceCenterBottom
= sourceRect
.bottom() - sourceMargins
.bottom() + 1;
1116 const int sourceCenterRight
= sourceRect
.right() - sourceMargins
.right() + 1;
1117 const int sourceCenterWidth
= sourceCenterRight
- sourceCenterLeft
;
1118 const int sourceCenterHeight
= sourceCenterBottom
- sourceCenterTop
;
1120 const int targetCenterTop
= targetRect
.top() + targetMargins
.top();
1121 const int targetCenterLeft
= targetRect
.left() + targetMargins
.left();
1122 const int targetCenterBottom
= targetRect
.bottom() - targetMargins
.bottom() + 1;
1123 const int targetCenterRight
= targetRect
.right() - targetMargins
.right() + 1;
1124 const int targetCenterWidth
= targetCenterRight
- targetCenterLeft
;
1125 const int targetCenterHeight
= targetCenterBottom
- targetCenterTop
;
1127 QVarLengthArray
<qreal
, 16> xTarget
; // x-coordinates of target rectangles
1128 QVarLengthArray
<qreal
, 16> yTarget
; // y-coordinates of target rectangles
1132 if (rules
.horizontal
!= Qt::StretchTile
&& sourceCenterWidth
!= 0)
1133 columns
= qMax(3, 2 + qCeil(targetCenterWidth
/ qreal(sourceCenterWidth
)));
1134 if (rules
.vertical
!= Qt::StretchTile
&& sourceCenterHeight
!= 0)
1135 rows
= qMax(3, 2 + qCeil(targetCenterHeight
/ qreal(sourceCenterHeight
)));
1137 xTarget
.resize(columns
+ 1);
1138 yTarget
.resize(rows
+ 1);
1140 xTarget
[0] = targetRect
.left();
1141 xTarget
[1] = targetCenterLeft
;
1142 xTarget
[columns
- 1] = targetCenterRight
;
1143 xTarget
[columns
] = targetRect
.left() + targetRect
.width();
1145 yTarget
[0] = targetRect
.top();
1146 yTarget
[1] = targetCenterTop
;
1147 yTarget
[rows
- 1] = targetCenterBottom
;
1148 yTarget
[rows
] = targetRect
.top() + targetRect
.height();
1150 qreal dx
= targetCenterWidth
;
1151 qreal dy
= targetCenterHeight
;
1153 switch (rules
.horizontal
) {
1154 case Qt::StretchTile
:
1155 dx
= targetCenterWidth
;
1157 case Qt::RepeatTile
:
1158 dx
= sourceCenterWidth
;
1161 dx
= targetCenterWidth
/ qreal(columns
- 2);
1165 for (int i
= 2; i
< columns
- 1; ++i
)
1166 xTarget
[i
] = xTarget
[i
- 1] + dx
;
1168 switch (rules
.vertical
) {
1169 case Qt::StretchTile
:
1170 dy
= targetCenterHeight
;
1172 case Qt::RepeatTile
:
1173 dy
= sourceCenterHeight
;
1176 dy
= targetCenterHeight
/ qreal(rows
- 2);
1180 for (int i
= 2; i
< rows
- 1; ++i
)
1181 yTarget
[i
] = yTarget
[i
- 1] + dy
;
1184 if (targetMargins
.top() > 0 && targetMargins
.left() > 0 && sourceMargins
.top() > 0 && sourceMargins
.left() > 0) { // top left
1185 d
.point
.setX(0.5 * (xTarget
[1] + xTarget
[0]));
1186 d
.point
.setY(0.5 * (yTarget
[1] + yTarget
[0]));
1187 d
.source
= QRectF(sourceRect
.left(), sourceRect
.top(), sourceMargins
.left(), sourceMargins
.top());
1188 d
.scaleX
= qreal(xTarget
[1] - xTarget
[0]) / d
.source
.width();
1189 d
.scaleY
= qreal(yTarget
[1] - yTarget
[0]) / d
.source
.height();
1190 if (hints
& QDrawBorderPixmap::OpaqueTopLeft
)
1191 opaqueData
.append(d
);
1193 translucentData
.append(d
);
1195 if (targetMargins
.top() > 0 && targetMargins
.right() > 0 && sourceMargins
.top() > 0 && sourceMargins
.right() > 0) { // top right
1196 d
.point
.setX(0.5 * (xTarget
[columns
] + xTarget
[columns
- 1]));
1197 d
.point
.setY(0.5 * (yTarget
[1] + yTarget
[0]));
1198 d
.source
= QRectF(sourceCenterRight
, sourceRect
.top(), sourceMargins
.right(), sourceMargins
.top());
1199 d
.scaleX
= qreal(xTarget
[columns
] - xTarget
[columns
- 1]) / d
.source
.width();
1200 d
.scaleY
= qreal(yTarget
[1] - yTarget
[0]) / d
.source
.height();
1201 if (hints
& QDrawBorderPixmap::OpaqueTopRight
)
1202 opaqueData
.append(d
);
1204 translucentData
.append(d
);
1206 if (targetMargins
.bottom() > 0 && targetMargins
.left() > 0 && sourceMargins
.bottom() > 0 && sourceMargins
.left() > 0) { // bottom left
1207 d
.point
.setX(0.5 * (xTarget
[1] + xTarget
[0]));
1208 d
.point
.setY(0.5 * (yTarget
[rows
] + yTarget
[rows
- 1]));
1209 d
.source
= QRectF(sourceRect
.left(), sourceCenterBottom
, sourceMargins
.left(), sourceMargins
.bottom());
1210 d
.scaleX
= qreal(xTarget
[1] - xTarget
[0]) / d
.source
.width();
1211 d
.scaleY
= qreal(yTarget
[rows
] - yTarget
[rows
- 1]) / d
.source
.height();
1212 if (hints
& QDrawBorderPixmap::OpaqueBottomLeft
)
1213 opaqueData
.append(d
);
1215 translucentData
.append(d
);
1217 if (targetMargins
.bottom() > 0 && targetMargins
.right() > 0 && sourceMargins
.bottom() > 0 && sourceMargins
.right() > 0) { // bottom right
1218 d
.point
.setX(0.5 * (xTarget
[columns
] + xTarget
[columns
- 1]));
1219 d
.point
.setY(0.5 * (yTarget
[rows
] + yTarget
[rows
- 1]));
1220 d
.source
= QRectF(sourceCenterRight
, sourceCenterBottom
, sourceMargins
.right(), sourceMargins
.bottom());
1221 d
.scaleX
= qreal(xTarget
[columns
] - xTarget
[columns
- 1]) / d
.source
.width();
1222 d
.scaleY
= qreal(yTarget
[rows
] - yTarget
[rows
- 1]) / d
.source
.height();
1223 if (hints
& QDrawBorderPixmap::OpaqueBottomRight
)
1224 opaqueData
.append(d
);
1226 translucentData
.append(d
);
1230 if (targetCenterWidth
> 0 && sourceCenterWidth
> 0) {
1231 if (targetMargins
.top() > 0 && sourceMargins
.top() > 0) { // top
1232 QDrawPixmapsDataArray
&data
= hints
& QDrawBorderPixmap::OpaqueTop
? opaqueData
: translucentData
;
1233 d
.source
= QRectF(sourceCenterLeft
, sourceRect
.top(), sourceCenterWidth
, sourceMargins
.top());
1234 d
.point
.setY(0.5 * (yTarget
[1] + yTarget
[0]));
1235 d
.scaleX
= dx
/ d
.source
.width();
1236 d
.scaleY
= qreal(yTarget
[1] - yTarget
[0]) / d
.source
.height();
1237 for (int i
= 1; i
< columns
- 1; ++i
) {
1238 d
.point
.setX(0.5 * (xTarget
[i
+ 1] + xTarget
[i
]));
1241 if (rules
.horizontal
== Qt::RepeatTile
)
1242 data
[data
.size() - 1].source
.setWidth((xTarget
[columns
- 1] - xTarget
[columns
- 2]) / d
.scaleX
);
1244 if (targetMargins
.bottom() > 0 && sourceMargins
.bottom() > 0) { // bottom
1245 QDrawPixmapsDataArray
&data
= hints
& QDrawBorderPixmap::OpaqueBottom
? opaqueData
: translucentData
;
1246 d
.source
= QRectF(sourceCenterLeft
, sourceCenterBottom
, sourceCenterWidth
, sourceMargins
.bottom());;
1247 d
.point
.setY(0.5 * (yTarget
[rows
] + yTarget
[rows
- 1]));
1248 d
.scaleX
= dx
/ d
.source
.width();
1249 d
.scaleY
= qreal(yTarget
[rows
] - yTarget
[rows
- 1]) / d
.source
.height();
1250 for (int i
= 1; i
< columns
- 1; ++i
) {
1251 d
.point
.setX(0.5 * (xTarget
[i
+ 1] + xTarget
[i
]));
1254 if (rules
.horizontal
== Qt::RepeatTile
)
1255 data
[data
.size() - 1].source
.setWidth((xTarget
[columns
- 1] - xTarget
[columns
- 2]) / d
.scaleX
);
1260 if (targetCenterHeight
> 0 && sourceCenterHeight
> 0) {
1261 if (targetMargins
.left() > 0 && sourceMargins
.left() > 0) { // left
1262 QDrawPixmapsDataArray
&data
= hints
& QDrawBorderPixmap::OpaqueLeft
? opaqueData
: translucentData
;
1263 d
.source
= QRectF(sourceRect
.left(), sourceCenterTop
, sourceMargins
.left(), sourceCenterHeight
);
1264 d
.point
.setX(0.5 * (xTarget
[1] + xTarget
[0]));
1265 d
.scaleX
= qreal(xTarget
[1] - xTarget
[0]) / d
.source
.width();
1266 d
.scaleY
= dy
/ d
.source
.height();
1267 for (int i
= 1; i
< rows
- 1; ++i
) {
1268 d
.point
.setY(0.5 * (yTarget
[i
+ 1] + yTarget
[i
]));
1271 if (rules
.vertical
== Qt::RepeatTile
)
1272 data
[data
.size() - 1].source
.setHeight((yTarget
[rows
- 1] - yTarget
[rows
- 2]) / d
.scaleY
);
1274 if (targetMargins
.right() > 0 && sourceMargins
.right() > 0) { // right
1275 QDrawPixmapsDataArray
&data
= hints
& QDrawBorderPixmap::OpaqueRight
? opaqueData
: translucentData
;
1276 d
.source
= QRectF(sourceCenterRight
, sourceCenterTop
, sourceMargins
.right(), sourceCenterHeight
);
1277 d
.point
.setX(0.5 * (xTarget
[columns
] + xTarget
[columns
- 1]));
1278 d
.scaleX
= qreal(xTarget
[columns
] - xTarget
[columns
- 1]) / d
.source
.width();
1279 d
.scaleY
= dy
/ d
.source
.height();
1280 for (int i
= 1; i
< rows
- 1; ++i
) {
1281 d
.point
.setY(0.5 * (yTarget
[i
+ 1] + yTarget
[i
]));
1284 if (rules
.vertical
== Qt::RepeatTile
)
1285 data
[data
.size() - 1].source
.setHeight((yTarget
[rows
- 1] - yTarget
[rows
- 2]) / d
.scaleY
);
1290 if (targetCenterWidth
> 0 && targetCenterHeight
> 0 && sourceCenterWidth
> 0 && sourceCenterHeight
> 0) {
1291 QDrawPixmapsDataArray
&data
= hints
& QDrawBorderPixmap::OpaqueCenter
? opaqueData
: translucentData
;
1292 d
.source
= QRectF(sourceCenterLeft
, sourceCenterTop
, sourceCenterWidth
, sourceCenterHeight
);
1293 d
.scaleX
= dx
/ d
.source
.width();
1294 d
.scaleY
= dy
/ d
.source
.height();
1296 qreal repeatWidth
= (xTarget
[columns
- 1] - xTarget
[columns
- 2]) / d
.scaleX
;
1297 qreal repeatHeight
= (yTarget
[rows
- 1] - yTarget
[rows
- 2]) / d
.scaleY
;
1299 for (int j
= 1; j
< rows
- 1; ++j
) {
1300 d
.point
.setY(0.5 * (yTarget
[j
+ 1] + yTarget
[j
]));
1301 for (int i
= 1; i
< columns
- 1; ++i
) {
1302 d
.point
.setX(0.5 * (xTarget
[i
+ 1] + xTarget
[i
]));
1305 if (rules
.horizontal
== Qt::RepeatTile
)
1306 data
[data
.size() - 1].source
.setWidth(repeatWidth
);
1308 if (rules
.vertical
== Qt::RepeatTile
) {
1309 for (int i
= 1; i
< columns
- 1; ++i
)
1310 data
[data
.size() - i
].source
.setHeight(repeatHeight
);
1314 if (opaqueData
.size())
1315 qDrawPixmaps(painter
, opaqueData
.data(), opaqueData
.size(), pixmap
, QDrawPixmaps::OpaqueHint
);
1316 if (translucentData
.size())
1317 qDrawPixmaps(painter
, translucentData
.data(), translucentData
.size(), pixmap
);
1321 \class QDrawPixmaps::Data
1325 This structure is used with the qDrawPixmaps() function.
1327 QPointF point: Specifies the center of the target rectangle.
1328 QRectF source: Specifies the source rectangle in the pixmap passed into the qDrawPixmaps() call.
1329 qreal scaleX: Specifies the horizontal scale of the target rectangle.
1330 qreal scaleY: Specifies the vertical scale of the target rectangle.
1331 qreal rotation: Specifies the rotation of the target rectangle in degrees.
1332 The target rectangle is rotated after scaling.
1333 qreal opacity: Specifies the opacity of the rectangle.
1337 \enum QDrawPixmaps::DrawingHint
1345 This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, at multiple positions
1346 with different scale, rotation and opacity on \a painter. \a drawingData is an array of \a
1347 dataCount elements specifying the parameters used to draw each pixmap instance.
1348 This can be used for example to implement a particle system.
1350 void qDrawPixmaps(QPainter
*painter
, const QDrawPixmaps::Data
*drawingData
, int dataCount
, const QPixmap
&pixmap
, QDrawPixmaps::DrawingHints hints
)
1352 QPaintEngine
*engine
= painter
->paintEngine();
1356 if (engine
->isExtended()) {
1357 static_cast<QPaintEngineEx
*>(engine
)->drawPixmaps(drawingData
, dataCount
, pixmap
, hints
);
1359 qreal oldOpacity
= painter
->opacity();
1360 QTransform oldTransform
= painter
->transform();
1362 for (int i
= 0; i
< dataCount
; ++i
) {
1363 QTransform transform
= oldTransform
;
1364 transform
.translate(drawingData
[i
].point
.x(), drawingData
[i
].point
.y());
1365 transform
.rotate(drawingData
[i
].rotation
);
1366 painter
->setOpacity(oldOpacity
* drawingData
[i
].opacity
);
1367 painter
->setTransform(transform
);
1369 qreal w
= drawingData
[i
].scaleX
* drawingData
[i
].source
.width();
1370 qreal h
= drawingData
[i
].scaleY
* drawingData
[i
].source
.height();
1371 painter
->drawPixmap(QRectF(-0.5 * w
, -0.5 * h
, w
, h
), pixmap
, drawingData
[i
].source
);
1374 painter
->setOpacity(oldOpacity
);
1375 painter
->setTransform(oldTransform
);