src/gui/painting/qpainter.cpp
changeset 30 5dc02b23752f
parent 29 b72c6db6890b
child 33 3e2da88830cd
equal deleted inserted replaced
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