changeset 30 | 5dc02b23752f |
parent 29 | b72c6db6890b |
child 33 | 3e2da88830cd |
29:b72c6db6890b | 30:5dc02b23752f |
---|---|
36 ** |
36 ** |
37 ** |
37 ** |
38 ** $QT_END_LICENSE$ |
38 ** $QT_END_LICENSE$ |
39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
|
41 // QtCore |
42 // QtCore |
42 #include <qdebug.h> |
43 #include <qdebug.h> |
43 #include <qmath.h> |
44 #include <qmath.h> |
44 #include <qmutex.h> |
45 #include <qmutex.h> |
45 |
46 |
67 #include <private/qpainterpath_p.h> |
68 #include <private/qpainterpath_p.h> |
68 #include <private/qtextengine_p.h> |
69 #include <private/qtextengine_p.h> |
69 #include <private/qwidget_p.h> |
70 #include <private/qwidget_p.h> |
70 #include <private/qpaintengine_raster_p.h> |
71 #include <private/qpaintengine_raster_p.h> |
71 #include <private/qmath_p.h> |
72 #include <private/qmath_p.h> |
73 #include <qstatictext.h> |
|
74 #include <private/qstatictext_p.h> |
|
72 |
75 |
73 QT_BEGIN_NAMESPACE |
76 QT_BEGIN_NAMESPACE |
74 |
77 |
75 #define QGradient_StretchToDevice 0x10000000 |
78 #define QGradient_StretchToDevice 0x10000000 |
76 #define QPaintEngine_OpaqueBackground 0x40000000 |
79 #define QPaintEngine_OpaqueBackground 0x40000000 |
965 that can be painted on using a QPainter. QPaintEngine provides the |
968 that can be painted on using a QPainter. QPaintEngine provides the |
966 interface that the painter uses to draw onto different types of |
969 interface that the painter uses to draw onto different types of |
967 devices. If the painter is active, device() returns the paint |
970 devices. If the painter is active, device() returns the paint |
968 device on which the painter paints, and paintEngine() returns the |
971 device on which the painter paints, and paintEngine() returns the |
969 paint engine that the painter is currently operating on. For more |
972 paint engine that the painter is currently operating on. For more |
970 information, see \l {The Paint System} documentation. |
973 information, see the \l {Paint System}. |
971 |
974 |
972 Sometimes it is desirable to make someone else paint on an unusual |
975 Sometimes it is desirable to make someone else paint on an unusual |
973 QPaintDevice. QPainter supports a static function to do this, |
976 QPaintDevice. QPainter supports a static function to do this, |
974 setRedirected(). |
977 setRedirected(). |
975 |
978 |
1010 \o brushOrigin() defines the origin of the tiled brushes, normally |
1013 \o brushOrigin() defines the origin of the tiled brushes, normally |
1011 the origin of widget's background. |
1014 the origin of widget's background. |
1012 |
1015 |
1013 \o viewport(), window(), worldTransform() make up the painter's coordinate |
1016 \o viewport(), window(), worldTransform() make up the painter's coordinate |
1014 transformation system. For more information, see the \l |
1017 transformation system. For more information, see the \l |
1015 {Coordinate Transformations} section and the \l {The Coordinate |
1018 {Coordinate Transformations} section and the \l {Coordinate |
1016 System} documentation. |
1019 System} documentation. |
1017 |
1020 |
1018 \o hasClipping() tells whether the painter clips at all. (The paint |
1021 \o hasClipping() tells whether the painter clips at all. (The paint |
1019 device clips, too.) If the painter clips, it clips to clipRegion(). |
1022 device clips, too.) If the painter clips, it clips to clipRegion(). |
1020 |
1023 |
1217 \endtable |
1220 \endtable |
1218 |
1221 |
1219 All the tranformation operations operate on the transformation |
1222 All the tranformation operations operate on the transformation |
1220 worldTransform(). A matrix transforms a point in the plane to another |
1223 worldTransform(). A matrix transforms a point in the plane to another |
1221 point. For more information about the transformation matrix, see |
1224 point. For more information about the transformation matrix, see |
1222 the \l {The Coordinate System} and QTransform documentation. |
1225 the \l {Coordinate System} and QTransform documentation. |
1223 |
1226 |
1224 The setWorldTransform() function can replace or add to the currently |
1227 The setWorldTransform() function can replace or add to the currently |
1225 set worldTransform(). The resetTransform() function resets any |
1228 set worldTransform(). The resetTransform() function resets any |
1226 transformations that were made using translate(), scale(), |
1229 transformations that were made using translate(), scale(), |
1227 shear(), rotate(), setWorldTransform(), setViewport() and setWindow() |
1230 shear(), rotate(), setWorldTransform(), setViewport() and setWindow() |
1239 viewport() represents the physical coordinates specifying an |
1242 viewport() represents the physical coordinates specifying an |
1240 arbitrary rectangle, the window() describes the same rectangle in |
1243 arbitrary rectangle, the window() describes the same rectangle in |
1241 logical coordinates, and the worldTransform() is identical with the |
1244 logical coordinates, and the worldTransform() is identical with the |
1242 transformation matrix. |
1245 transformation matrix. |
1243 |
1246 |
1244 See also \l {The Coordinate System} documentation. |
1247 See also \l {Coordinate System} |
1245 |
1248 |
1246 \section1 Clipping |
1249 \section1 Clipping |
1247 |
1250 |
1248 QPainter can clip any drawing operation to a rectangle, a region, |
1251 QPainter can clip any drawing operation to a rectangle, a region, |
1249 or a vector path. The current clip is available using the |
1252 or a vector path. The current clip is available using the |
2875 it may not be possible to replay the picture with additional |
2878 it may not be possible to replay the picture with additional |
2876 transformations; using the translate(), scale(), etc. convenience |
2879 transformations; using the translate(), scale(), etc. convenience |
2877 functions is safe. |
2880 functions is safe. |
2878 |
2881 |
2879 For more information about the coordinate system, transformations |
2882 For more information about the coordinate system, transformations |
2880 and window-viewport conversion, see \l {The Coordinate System} |
2883 and window-viewport conversion, see \l {Coordinate System}. |
2881 documentation. |
|
2882 |
2884 |
2883 \sa setWorldTransform(), QTransform |
2885 \sa setWorldTransform(), QTransform |
2884 */ |
2886 */ |
2885 |
2887 |
2886 void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine) |
2888 void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine) |
2896 |
2898 |
2897 It is advisable to use worldTransform() because worldMatrix() does not |
2899 It is advisable to use worldTransform() because worldMatrix() does not |
2898 preserve the properties of perspective transformations. |
2900 preserve the properties of perspective transformations. |
2899 |
2901 |
2900 \sa {QPainter#Coordinate Transformations}{Coordinate Transformations}, |
2902 \sa {QPainter#Coordinate Transformations}{Coordinate Transformations}, |
2901 {The Coordinate System} |
2903 {Coordinate System} |
2902 */ |
2904 */ |
2903 |
2905 |
2904 const QMatrix &QPainter::worldMatrix() const |
2906 const QMatrix &QPainter::worldMatrix() const |
2905 { |
2907 { |
2906 Q_D(const QPainter); |
2908 Q_D(const QPainter); |
3039 \since 4.2 |
3041 \since 4.2 |
3040 |
3042 |
3041 Returns true if world transformation is enabled; otherwise returns |
3043 Returns true if world transformation is enabled; otherwise returns |
3042 false. |
3044 false. |
3043 |
3045 |
3044 \sa setWorldMatrixEnabled(), worldTransform(), {The Coordinate System} |
3046 \sa setWorldMatrixEnabled(), worldTransform(), {Coordinate System} |
3045 */ |
3047 */ |
3046 |
3048 |
3047 bool QPainter::worldMatrixEnabled() const |
3049 bool QPainter::worldMatrixEnabled() const |
3048 { |
3050 { |
3049 Q_D(const QPainter); |
3051 Q_D(const QPainter); |
3381 \o \inlineimage qpainter-line.png |
3383 \o \inlineimage qpainter-line.png |
3382 \o |
3384 \o |
3383 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6 |
3385 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6 |
3384 \endtable |
3386 \endtable |
3385 |
3387 |
3386 \sa drawLines(), drawPolyline(), {The Coordinate System} |
3388 \sa drawLines(), drawPolyline(), {Coordinate System} |
3387 */ |
3389 */ |
3388 |
3390 |
3389 /*! |
3391 /*! |
3390 \fn void QPainter::drawLine(const QLine &line) |
3392 \fn void QPainter::drawLine(const QLine &line) |
3391 \overload |
3393 \overload |
3428 \o \inlineimage qpainter-rectangle.png |
3430 \o \inlineimage qpainter-rectangle.png |
3429 \o |
3431 \o |
3430 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7 |
3432 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7 |
3431 \endtable |
3433 \endtable |
3432 |
3434 |
3433 \sa drawRects(), drawPolygon(), {The Coordinate System} |
3435 \sa drawRects(), drawPolygon(), {Coordinate System} |
3434 */ |
3436 */ |
3435 |
3437 |
3436 /*! |
3438 /*! |
3437 \fn void QPainter::drawRect(const QRect &rectangle) |
3439 \fn void QPainter::drawRect(const QRect &rectangle) |
3438 |
3440 |
3592 \fn void QPainter::drawPoint(const QPointF &position) |
3594 \fn void QPainter::drawPoint(const QPointF &position) |
3593 |
3595 |
3594 Draws a single point at the given \a position using the current |
3596 Draws a single point at the given \a position using the current |
3595 pen's color. |
3597 pen's color. |
3596 |
3598 |
3597 \sa {The Coordinate System} |
3599 \sa {Coordinate System} |
3598 */ |
3600 */ |
3599 |
3601 |
3600 /*! |
3602 /*! |
3601 \fn void QPainter::drawPoint(const QPoint &position) |
3603 \fn void QPainter::drawPoint(const QPoint &position) |
3602 \overload |
3604 \overload |
3614 |
3616 |
3615 /*! |
3617 /*! |
3616 Draws the first \a pointCount points in the array \a points using |
3618 Draws the first \a pointCount points in the array \a points using |
3617 the current pen's color. |
3619 the current pen's color. |
3618 |
3620 |
3619 \sa {The Coordinate System} |
3621 \sa {Coordinate System} |
3620 */ |
3622 */ |
3621 void QPainter::drawPoints(const QPointF *points, int pointCount) |
3623 void QPainter::drawPoints(const QPointF *points, int pointCount) |
3622 { |
3624 { |
3623 #ifdef QT_DEBUG_DRAW |
3625 #ifdef QT_DEBUG_DRAW |
3624 if (qt_show_painter_debug_output) |
3626 if (qt_show_painter_debug_output) |
4220 \o \inlineimage qpainter-ellipse.png |
4222 \o \inlineimage qpainter-ellipse.png |
4221 \o |
4223 \o |
4222 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9 |
4224 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9 |
4223 \endtable |
4225 \endtable |
4224 |
4226 |
4225 \sa drawPie(), {The Coordinate System} |
4227 \sa drawPie(), {Coordinate System} |
4226 */ |
4228 */ |
4227 void QPainter::drawEllipse(const QRectF &r) |
4229 void QPainter::drawEllipse(const QRectF &r) |
4228 { |
4230 { |
4229 #ifdef QT_DEBUG_DRAW |
4231 #ifdef QT_DEBUG_DRAW |
4230 if (qt_show_painter_debug_output) |
4232 if (qt_show_painter_debug_output) |
4350 \o \inlineimage qpainter-arc.png |
4352 \o \inlineimage qpainter-arc.png |
4351 \o |
4353 \o |
4352 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10 |
4354 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10 |
4353 \endtable |
4355 \endtable |
4354 |
4356 |
4355 \sa drawPie(), drawChord(), {The Coordinate System} |
4357 \sa drawPie(), drawChord(), {Coordinate System} |
4356 */ |
4358 */ |
4357 |
4359 |
4358 void QPainter::drawArc(const QRectF &r, int a, int alen) |
4360 void QPainter::drawArc(const QRectF &r, int a, int alen) |
4359 { |
4361 { |
4360 #ifdef QT_DEBUG_DRAW |
4362 #ifdef QT_DEBUG_DRAW |
4414 \o \inlineimage qpainter-pie.png |
4416 \o \inlineimage qpainter-pie.png |
4415 \o |
4417 \o |
4416 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11 |
4418 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11 |
4417 \endtable |
4419 \endtable |
4418 |
4420 |
4419 \sa drawEllipse(), drawChord(), {The Coordinate System} |
4421 \sa drawEllipse(), drawChord(), {Coordinate System} |
4420 */ |
4422 */ |
4421 void QPainter::drawPie(const QRectF &r, int a, int alen) |
4423 void QPainter::drawPie(const QRectF &r, int a, int alen) |
4422 { |
4424 { |
4423 #ifdef QT_DEBUG_DRAW |
4425 #ifdef QT_DEBUG_DRAW |
4424 if (qt_show_painter_debug_output) |
4426 if (qt_show_painter_debug_output) |
4483 \o \inlineimage qpainter-chord.png |
4485 \o \inlineimage qpainter-chord.png |
4484 \o |
4486 \o |
4485 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12 |
4487 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12 |
4486 \endtable |
4488 \endtable |
4487 |
4489 |
4488 \sa drawArc(), drawPie(), {The Coordinate System} |
4490 \sa drawArc(), drawPie(), {Coordinate System} |
4489 */ |
4491 */ |
4490 void QPainter::drawChord(const QRectF &r, int a, int alen) |
4492 void QPainter::drawChord(const QRectF &r, int a, int alen) |
4491 { |
4493 { |
4492 #ifdef QT_DEBUG_DRAW |
4494 #ifdef QT_DEBUG_DRAW |
4493 if (qt_show_painter_debug_output) |
4495 if (qt_show_painter_debug_output) |
4774 \row |
4776 \row |
4775 \o |
4777 \o |
4776 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13 |
4778 \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13 |
4777 \endtable |
4779 \endtable |
4778 |
4780 |
4779 \sa drawLines(), drawPolygon(), {The Coordinate System} |
4781 \sa drawLines(), drawPolygon(), {Coordinate System} |
4780 */ |
4782 */ |
4781 void QPainter::drawPolyline(const QPointF *points, int pointCount) |
4783 void QPainter::drawPolyline(const QPointF *points, int pointCount) |
4782 { |
4784 { |
4783 #ifdef QT_DEBUG_DRAW |
4785 #ifdef QT_DEBUG_DRAW |
4784 if (qt_show_painter_debug_output) |
4786 if (qt_show_painter_debug_output) |
4913 winding fill algorithm. If \a fillRule is Qt::OddEvenFill, the |
4915 winding fill algorithm. If \a fillRule is Qt::OddEvenFill, the |
4914 polygon is filled using the odd-even fill algorithm. See |
4916 polygon is filled using the odd-even fill algorithm. See |
4915 \l{Qt::FillRule} for a more detailed description of these fill |
4917 \l{Qt::FillRule} for a more detailed description of these fill |
4916 rules. |
4918 rules. |
4917 |
4919 |
4918 \sa drawConvexPolygon(), drawPolyline(), {The Coordinate System} |
4920 \sa drawConvexPolygon(), drawPolyline(), {Coordinate System} |
4919 */ |
4921 */ |
4920 void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule) |
4922 void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule) |
4921 { |
4923 { |
4922 #ifdef QT_DEBUG_DRAW |
4924 #ifdef QT_DEBUG_DRAW |
4923 if (qt_show_painter_debug_output) |
4925 if (qt_show_painter_debug_output) |
5064 than 180 degrees, the results are undefined. |
5066 than 180 degrees, the results are undefined. |
5065 |
5067 |
5066 On some platforms (e.g. X11), the drawConvexPolygon() function can |
5068 On some platforms (e.g. X11), the drawConvexPolygon() function can |
5067 be faster than the drawPolygon() function. |
5069 be faster than the drawPolygon() function. |
5068 |
5070 |
5069 \sa drawPolygon(), drawPolyline(), {The Coordinate System} |
5071 \sa drawPolygon(), drawPolyline(), {Coordinate System} |
5070 */ |
5072 */ |
5071 |
5073 |
5072 /*! |
5074 /*! |
5073 \fn void QPainter::drawConvexPolygon(const QPoint *points, int pointCount) |
5075 \fn void QPainter::drawConvexPolygon(const QPoint *points, int pointCount) |
5074 \overload |
5076 \overload |
5409 |
5411 |
5410 translate(x, y); |
5412 translate(x, y); |
5411 scale(w / sw, h / sh); |
5413 scale(w / sw, h / sh); |
5412 setBackgroundMode(Qt::TransparentMode); |
5414 setBackgroundMode(Qt::TransparentMode); |
5413 setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform); |
5415 setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform); |
5414 QBrush brush(d->state->pen.color(), pm); |
5416 QBrush brush; |
5417 |
|
5418 if (sw == pm.width() && sh == pm.height()) |
|
5419 brush = QBrush(d->state->pen.color(), pm); |
|
5420 else |
|
5421 brush = QBrush(d->state->pen.color(), pm.copy(sx, sy, sw, sh)); |
|
5422 |
|
5415 setBrush(brush); |
5423 setBrush(brush); |
5416 setPen(Qt::NoPen); |
5424 setPen(Qt::NoPen); |
5417 setBrushOrigin(QPointF(-sx, -sy)); |
|
5418 |
5425 |
5419 drawRect(QRectF(0, 0, sw, sh)); |
5426 drawRect(QRectF(0, 0, sw, sh)); |
5420 restore(); |
5427 restore(); |
5421 } else { |
5428 } else { |
5422 if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) { |
5429 if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) { |
5695 } |
5702 } |
5696 |
5703 |
5697 d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags); |
5704 d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags); |
5698 } |
5705 } |
5699 |
5706 |
5707 |
|
5708 void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, const QPointF *positionArray, |
|
5709 int glyphCount) |
|
5710 { |
|
5711 QPainterPrivate *painter_d = QPainterPrivate::get(painter); |
|
5712 painter_d->drawGlyphs(glyphArray, positionArray, glyphCount); |
|
5713 } |
|
5714 |
|
5715 void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *positionArray, |
|
5716 int glyphCount) |
|
5717 { |
|
5718 updateState(state); |
|
5719 |
|
5720 QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common); |
|
5721 |
|
5722 while (fontEngine->type() == QFontEngine::Multi) { |
|
5723 // Pick engine based on first glyph in array if we are using a multi engine. |
|
5724 // (all glyphs must be for same font) |
|
5725 int engineIdx = 0; |
|
5726 if (glyphCount > 0) |
|
5727 engineIdx = glyphArray[0] >> 24; |
|
5728 |
|
5729 fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx); |
|
5730 } |
|
5731 |
|
5732 QVarLengthArray<QFixedPoint, 128> positions; |
|
5733 for (int i=0; i<glyphCount; ++i) { |
|
5734 QFixedPoint fp = QFixedPoint::fromPointF(positionArray[i]); |
|
5735 positions.append(fp); |
|
5736 } |
|
5737 |
|
5738 if (extended != 0) { |
|
5739 QStaticTextItem staticTextItem; |
|
5740 staticTextItem.color = state->pen.color(); |
|
5741 staticTextItem.font = state->font; |
|
5742 staticTextItem.fontEngine = fontEngine; |
|
5743 staticTextItem.numGlyphs = glyphCount; |
|
5744 staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray)); |
|
5745 staticTextItem.glyphPositions = positions.data(); |
|
5746 |
|
5747 extended->drawStaticTextItem(&staticTextItem); |
|
5748 } else { |
|
5749 QTextItemInt textItem; |
|
5750 textItem.f = &state->font; |
|
5751 textItem.fontEngine = fontEngine; |
|
5752 |
|
5753 QVarLengthArray<QFixed, 128> advances(glyphCount); |
|
5754 QVarLengthArray<QGlyphJustification, 128> glyphJustifications(glyphCount); |
|
5755 QVarLengthArray<HB_GlyphAttributes, 128> glyphAttributes(glyphCount); |
|
5756 qMemSet(glyphAttributes.data(), 0, glyphAttributes.size() * sizeof(HB_GlyphAttributes)); |
|
5757 qMemSet(advances.data(), 0, advances.size() * sizeof(QFixed)); |
|
5758 qMemSet(glyphJustifications.data(), 0, glyphJustifications.size() * sizeof(QGlyphJustification)); |
|
5759 |
|
5760 textItem.glyphs.numGlyphs = glyphCount; |
|
5761 textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray)); |
|
5762 textItem.glyphs.offsets = positions.data(); |
|
5763 textItem.glyphs.advances_x = advances.data(); |
|
5764 textItem.glyphs.advances_y = advances.data(); |
|
5765 textItem.glyphs.justifications = glyphJustifications.data(); |
|
5766 textItem.glyphs.attributes = glyphAttributes.data(); |
|
5767 |
|
5768 engine->drawTextItem(QPointF(0, 0), textItem); |
|
5769 } |
|
5770 } |
|
5771 |
|
5772 /*! |
|
5773 |
|
5774 \fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText) |
|
5775 \since 4.7 |
|
5776 \overload |
|
5777 |
|
5778 Draws the \a staticText at the \a topLeftPosition. |
|
5779 |
|
5780 \note The y-position is used as the top of the font. |
|
5781 |
|
5782 */ |
|
5783 |
|
5784 /*! |
|
5785 \fn void QPainter::drawStaticText(int left, int top, const QStaticText &staticText) |
|
5786 \since 4.7 |
|
5787 \overload |
|
5788 |
|
5789 Draws the \a staticText at coordinates \a left and \a top. |
|
5790 |
|
5791 \note The y-position is used as the top of the font. |
|
5792 */ |
|
5793 |
|
5700 /*! |
5794 /*! |
5701 \fn void QPainter::drawText(const QPointF &position, const QString &text) |
5795 \fn void QPainter::drawText(const QPointF &position, const QString &text) |
5702 |
5796 |
5703 Draws the given \a text with the currently defined text direction, |
5797 Draws the given \a text with the currently defined text direction, |
5704 beginning at the given \a position. |
5798 beginning at the given \a position. |
5715 */ |
5809 */ |
5716 |
5810 |
5717 void QPainter::drawText(const QPointF &p, const QString &str) |
5811 void QPainter::drawText(const QPointF &p, const QString &str) |
5718 { |
5812 { |
5719 drawText(p, str, 0, 0); |
5813 drawText(p, str, 0, 0); |
5814 } |
|
5815 |
|
5816 /*! |
|
5817 \since 4.7 |
|
5818 |
|
5819 Draws the given \a staticText at the given \a topLeftPosition. |
|
5820 |
|
5821 The text will be drawn using the font and the transformation set on the painter. If the |
|
5822 font and/or transformation set on the painter are different from the ones used to initialize |
|
5823 the layout of the QStaticText, then the layout will have to be recalculated. Use |
|
5824 QStaticText::prepare() to initialize \a staticText with the font and transformation with which |
|
5825 it will later be drawn. |
|
5826 |
|
5827 If \a topLeftPosition is not the same as when \a staticText was initialized, or when it was |
|
5828 last drawn, then there will be a slight overhead when translating the text to its new position. |
|
5829 |
|
5830 \note If the painter's transformation is not affine, then \a staticText will be drawn using |
|
5831 regular calls to drawText(), losing any potential for performance improvement. |
|
5832 |
|
5833 \note The y-position is used as the top of the font. |
|
5834 |
|
5835 \sa QStaticText |
|
5836 */ |
|
5837 void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText) |
|
5838 { |
|
5839 Q_D(QPainter); |
|
5840 if (!d->engine || staticText.text().isEmpty() || pen().style() == Qt::NoPen) |
|
5841 return; |
|
5842 |
|
5843 QStaticTextPrivate *staticText_d = |
|
5844 const_cast<QStaticTextPrivate *>(QStaticTextPrivate::get(&staticText)); |
|
5845 |
|
5846 if (font() != staticText_d->font) { |
|
5847 staticText_d->font = font(); |
|
5848 staticText_d->needsRelayout = true; |
|
5849 } |
|
5850 |
|
5851 // If we don't have an extended paint engine, or if the painter is projected, |
|
5852 // we go through standard code path |
|
5853 if (d->extended == 0 || !d->state->matrix.isAffine()) { |
|
5854 staticText_d->paintText(topLeftPosition, this); |
|
5855 return; |
|
5856 } |
|
5857 |
|
5858 // Don't recalculate entire layout because of translation, rather add the dx and dy |
|
5859 // into the position to move each text item the correct distance. |
|
5860 QPointF transformedPosition = topLeftPosition * d->state->matrix; |
|
5861 QTransform matrix = d->state->matrix; |
|
5862 |
|
5863 // The translation has been applied to transformedPosition. Remove translation |
|
5864 // component from matrix. |
|
5865 if (d->state->matrix.isTranslating()) { |
|
5866 qreal m11 = d->state->matrix.m11(); |
|
5867 qreal m12 = d->state->matrix.m12(); |
|
5868 qreal m13 = d->state->matrix.m13(); |
|
5869 qreal m21 = d->state->matrix.m21(); |
|
5870 qreal m22 = d->state->matrix.m22(); |
|
5871 qreal m23 = d->state->matrix.m23(); |
|
5872 qreal m33 = d->state->matrix.m33(); |
|
5873 |
|
5874 d->state->matrix.setMatrix(m11, m12, m13, |
|
5875 m21, m22, m23, |
|
5876 0.0, 0.0, m33); |
|
5877 } |
|
5878 |
|
5879 // If the transform is not identical to the text transform, |
|
5880 // we have to relayout the text (for other transformations than plain translation) |
|
5881 bool staticTextNeedsReinit = staticText_d->needsRelayout; |
|
5882 if (staticText_d->matrix != d->state->matrix) { |
|
5883 staticText_d->matrix = d->state->matrix; |
|
5884 staticTextNeedsReinit = true; |
|
5885 } |
|
5886 |
|
5887 // Recreate the layout of the static text because the matrix or font has changed |
|
5888 if (staticTextNeedsReinit) |
|
5889 staticText_d->init(); |
|
5890 |
|
5891 if (transformedPosition != staticText_d->position) { // Translate to actual position |
|
5892 QFixed fx = QFixed::fromReal(transformedPosition.x()); |
|
5893 QFixed fy = QFixed::fromReal(transformedPosition.y()); |
|
5894 QFixed oldX = QFixed::fromReal(staticText_d->position.x()); |
|
5895 QFixed oldY = QFixed::fromReal(staticText_d->position.y()); |
|
5896 for (int item=0; item<staticText_d->itemCount;++item) { |
|
5897 QStaticTextItem *textItem = staticText_d->items + item; |
|
5898 for (int i=0; i<textItem->numGlyphs; ++i) { |
|
5899 textItem->glyphPositions[i].x += fx - oldX; |
|
5900 textItem->glyphPositions[i].y += fy - oldY; |
|
5901 } |
|
5902 textItem->userDataNeedsUpdate = true; |
|
5903 } |
|
5904 |
|
5905 staticText_d->position = transformedPosition; |
|
5906 } |
|
5907 |
|
5908 QPen oldPen = d->state->pen; |
|
5909 QColor currentColor = oldPen.color(); |
|
5910 for (int i=0; i<staticText_d->itemCount; ++i) { |
|
5911 QStaticTextItem *item = staticText_d->items + i; |
|
5912 if (item->color.isValid() && currentColor != item->color) { |
|
5913 setPen(item->color); |
|
5914 currentColor = item->color; |
|
5915 } |
|
5916 d->extended->drawStaticTextItem(item); |
|
5917 } |
|
5918 if (currentColor != oldPen.color()) |
|
5919 setPen(oldPen); |
|
5920 |
|
5921 if (matrix.isTranslating()) |
|
5922 d->state->matrix = matrix; |
|
5720 } |
5923 } |
5721 |
5924 |
5722 /*! |
5925 /*! |
5723 \internal |
5926 \internal |
5724 */ |
5927 */ |
6906 viewport(), specifies the device coordinate system. |
7109 viewport(), specifies the device coordinate system. |
6907 |
7110 |
6908 The default window rectangle is the same as the device's |
7111 The default window rectangle is the same as the device's |
6909 rectangle. |
7112 rectangle. |
6910 |
7113 |
6911 \sa window(), viewTransformEnabled(), {The Coordinate |
7114 \sa window(), viewTransformEnabled(), {Coordinate |
6912 System#Window-Viewport Conversion}{Window-Viewport Conversion} |
7115 System#Window-Viewport Conversion}{Window-Viewport Conversion} |
6913 */ |
7116 */ |
6914 |
7117 |
6915 /*! |
7118 /*! |
6916 \fn void QPainter::setWindow(int x, int y, int width, int height) |
7119 \fn void QPainter::setWindow(int x, int y, int width, int height) |
6970 window(), specifies the logical coordinate system. |
7173 window(), specifies the logical coordinate system. |
6971 |
7174 |
6972 The default viewport rectangle is the same as the device's |
7175 The default viewport rectangle is the same as the device's |
6973 rectangle. |
7176 rectangle. |
6974 |
7177 |
6975 \sa viewport(), viewTransformEnabled() {The Coordinate |
7178 \sa viewport(), viewTransformEnabled() {Coordinate |
6976 System#Window-Viewport Conversion}{Window-Viewport Conversion} |
7179 System#Window-Viewport Conversion}{Window-Viewport Conversion} |
6977 */ |
7180 */ |
6978 |
7181 |
6979 /*! |
7182 /*! |
6980 \fn void QPainter::setViewport(int x, int y, int width, int height) |
7183 \fn void QPainter::setViewport(int x, int y, int width, int height) |
7054 */ |
7257 */ |
7055 /*! |
7258 /*! |
7056 Enables view transformations if \a enable is true, or disables |
7259 Enables view transformations if \a enable is true, or disables |
7057 view transformations if \a enable is false. |
7260 view transformations if \a enable is false. |
7058 |
7261 |
7059 \sa viewTransformEnabled(), {The Coordinate System#Window-Viewport |
7262 \sa viewTransformEnabled(), {Coordinate System#Window-Viewport |
7060 Conversion}{Window-Viewport Conversion} |
7263 Conversion}{Window-Viewport Conversion} |
7061 */ |
7264 */ |
7062 |
7265 |
7063 void QPainter::setViewTransformEnabled(bool enable) |
7266 void QPainter::setViewTransformEnabled(bool enable) |
7064 { |
7267 { |
7804 } |
8007 } |
7805 |
8008 |
7806 for (int i = 0; i < textLayout.lineCount(); i++) { |
8009 for (int i = 0; i < textLayout.lineCount(); i++) { |
7807 QTextLine line = textLayout.lineAt(i); |
8010 QTextLine line = textLayout.lineAt(i); |
7808 |
8011 |
7809 qreal advance = textLayout.engine()->lines[i].textAdvance.toReal(); |
8012 qreal advance = line.horizontalAdvance(); |
7810 if (tf & Qt::AlignRight) |
8013 if (tf & Qt::AlignRight) |
7811 xoff = r.width() - advance; |
8014 xoff = r.width() - advance; |
7812 else if (tf & Qt::AlignHCenter) |
8015 else if (tf & Qt::AlignHCenter) |
7813 xoff = (r.width() - advance)/2; |
8016 xoff = (r.width() - advance)/2; |
7814 |
8017 |
8713 return QTransform(); |
8916 return QTransform(); |
8714 } |
8917 } |
8715 return d->state->worldMatrix * d->viewTransform(); |
8918 return d->state->worldMatrix * d->viewTransform(); |
8716 } |
8919 } |
8717 |
8920 |
8921 /*! |
|
8922 \since 4.7 |
|
8923 |
|
8924 This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, |
|
8925 at multiple positions with different scale, rotation and opacity. \a |
|
8926 fragments is an array of \a fragmentCount elements specifying the |
|
8927 parameters used to draw each pixmap fragment. The \a hints |
|
8928 parameter can be used to pass in drawing hints. |
|
8929 |
|
8930 This function is potentially faster than multiple calls to drawPixmap(), |
|
8931 since the backend can optimize state changes. |
|
8932 |
|
8933 \sa QPainter::PixmapFragment, QPainter::PixmapFragmentHint |
|
8934 */ |
|
8935 |
|
8936 void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, |
|
8937 const QPixmap &pixmap, PixmapFragmentHints hints) |
|
8938 { |
|
8939 Q_D(QPainter); |
|
8940 |
|
8941 if (!d->engine) |
|
8942 return; |
|
8943 |
|
8944 if (d->engine->isExtended()) { |
|
8945 d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); |
|
8946 } else { |
|
8947 qreal oldOpacity = opacity(); |
|
8948 QTransform oldTransform = transform(); |
|
8949 |
|
8950 for (int i = 0; i < fragmentCount; ++i) { |
|
8951 QTransform transform = oldTransform; |
|
8952 qreal xOffset = 0; |
|
8953 qreal yOffset = 0; |
|
8954 if (fragments[i].rotation == 0) { |
|
8955 xOffset = fragments[i].x; |
|
8956 yOffset = fragments[i].y; |
|
8957 } else { |
|
8958 transform.translate(fragments[i].x, fragments[i].y); |
|
8959 transform.rotate(fragments[i].rotation); |
|
8960 } |
|
8961 setOpacity(oldOpacity * fragments[i].opacity); |
|
8962 setTransform(transform); |
|
8963 |
|
8964 qreal w = fragments[i].scaleX * fragments[i].width; |
|
8965 qreal h = fragments[i].scaleY * fragments[i].height; |
|
8966 QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop, |
|
8967 fragments[i].width, fragments[i].height); |
|
8968 drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, sourceRect); |
|
8969 } |
|
8970 |
|
8971 setOpacity(oldOpacity); |
|
8972 setTransform(oldTransform); |
|
8973 } |
|
8974 } |
|
8975 |
|
8976 /*! |
|
8977 \since 4.7 |
|
8978 \class QPainter::PixmapFragment |
|
8979 |
|
8980 \brief This class is used in conjunction with the |
|
8981 QPainter::drawPixmapFragments() function to specify how a pixmap, or |
|
8982 sub-rect of a pixmap, is drawn. |
|
8983 |
|
8984 The \a sourceLeft, \a sourceTop, \a width and \a height variables are used |
|
8985 as a source rectangle within the pixmap passed into the |
|
8986 QPainter::drawPixmapFragments() function. The variables \a x, \a y, \a |
|
8987 width and \a height are used to calculate the target rectangle that is |
|
8988 drawn. \a x and \a y denotes the center of the target rectangle. The \a |
|
8989 width and \a heigth in the target rectangle is scaled by the \a scaleX and |
|
8990 \a scaleY values. The resulting target rectangle is then rotated \a |
|
8991 rotation degrees around the \a x, \a y center point. |
|
8992 |
|
8993 \sa QPainter::drawPixmapFragments() |
|
8994 */ |
|
8995 |
|
8996 /*! |
|
8997 \since 4.7 |
|
8998 |
|
8999 This is a convenience function that returns a QPainter::PixmapFragment that is |
|
9000 initialized with the \a pos, \a sourceRect, \a scaleX, \a scaleY, \a |
|
9001 rotation, \a opacity parameters. |
|
9002 */ |
|
9003 |
|
9004 QPainter::PixmapFragment QPainter::PixmapFragment::create(const QPointF &pos, const QRectF &sourceRect, |
|
9005 qreal scaleX, qreal scaleY, qreal rotation, |
|
9006 qreal opacity) |
|
9007 { |
|
9008 PixmapFragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(), |
|
9009 sourceRect.height(), scaleX, scaleY, rotation, opacity}; |
|
9010 return fragment; |
|
9011 } |
|
9012 |
|
9013 /*! |
|
9014 \variable QPainter::PixmapFragment::x |
|
9015 \brief the x coordinate of center point in the target rectangle. |
|
9016 */ |
|
9017 |
|
9018 /*! |
|
9019 \variable QPainter::PixmapFragment::y |
|
9020 \brief the y coordinate of the center point in the target rectangle. |
|
9021 */ |
|
9022 |
|
9023 /*! |
|
9024 \variable QPainter::PixmapFragment::sourceLeft |
|
9025 \brief the left coordinate of the source rectangle. |
|
9026 */ |
|
9027 |
|
9028 /*! |
|
9029 \variable QPainter::PixmapFragment::sourceTop |
|
9030 \brief the top coordinate of the source rectangle. |
|
9031 */ |
|
9032 |
|
9033 /*! |
|
9034 \variable QPainter::PixmapFragment::width |
|
9035 |
|
9036 \brief the width of the source rectangle and is used to calculate the width |
|
9037 of the target rectangle. |
|
9038 */ |
|
9039 |
|
9040 /*! |
|
9041 \variable QPainter::PixmapFragment::height |
|
9042 |
|
9043 \brief the height of the source rectangle and is used to calculate the |
|
9044 height of the target rectangle. |
|
9045 */ |
|
9046 |
|
9047 /*! |
|
9048 \variable QPainter::PixmapFragment::scaleX |
|
9049 \brief the horizontal scale of the target rectangle. |
|
9050 */ |
|
9051 |
|
9052 /*! |
|
9053 \variable QPainter::PixmapFragment::scaleY |
|
9054 \brief the vertical scale of the target rectangle. |
|
9055 */ |
|
9056 |
|
9057 /*! |
|
9058 \variable QPainter::PixmapFragment::rotation |
|
9059 |
|
9060 \brief the rotation of the target rectangle in degrees. The target |
|
9061 rectangle is rotated after it has been scaled. |
|
9062 */ |
|
9063 |
|
9064 /*! |
|
9065 \variable QPainter::PixmapFragment::opacity |
|
9066 |
|
9067 \brief the opacity of the target rectangle, where 0.0 is fully transparent |
|
9068 and 1.0 is fully opaque. |
|
9069 */ |
|
9070 |
|
9071 /*! |
|
9072 \since 4.7 |
|
9073 |
|
9074 \enum QPainter::PixmapFragmentHint |
|
9075 |
|
9076 \value OpaqueHint Indicates that the pixmap fragments to be drawn are |
|
9077 opaque. Opaque fragments are potentially faster to draw. |
|
9078 |
|
9079 \sa QPainter::drawPixmapFragments(), QPainter::PixmapFragment |
|
9080 */ |
|
9081 |
|
8718 void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation) |
9082 void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation) |
8719 { |
9083 { |
8720 p->draw_helper(path, operation); |
9084 p->draw_helper(path, operation); |
8721 } |
9085 } |
8722 |
9086 |