src/gui/painting/qpainter.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     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
       
    14 ** this package.
       
    15 **
       
    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.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 // QtCore
       
    42 #include <qdebug.h>
       
    43 #include <qmath.h>
       
    44 #include <qmutex.h>
       
    45 
       
    46 // QtGui
       
    47 #include "qbitmap.h"
       
    48 #include "qimage.h"
       
    49 #include "qpaintdevice.h"
       
    50 #include "qpaintengine.h"
       
    51 #include "qpainter.h"
       
    52 #include "qpainter_p.h"
       
    53 #include "qpainterpath.h"
       
    54 #include "qpicture.h"
       
    55 #include "qpixmapcache.h"
       
    56 #include "qpolygon.h"
       
    57 #include "qtextlayout.h"
       
    58 #include "qwidget.h"
       
    59 #include "qapplication.h"
       
    60 #include "qstyle.h"
       
    61 #include "qthread.h"
       
    62 #include "qvarlengtharray.h"
       
    63 
       
    64 #include <private/qfontengine_p.h>
       
    65 #include <private/qpaintengine_p.h>
       
    66 #include <private/qemulationpaintengine_p.h>
       
    67 #include <private/qpainterpath_p.h>
       
    68 #include <private/qtextengine_p.h>
       
    69 #include <private/qwidget_p.h>
       
    70 #include <private/qpaintengine_raster_p.h>
       
    71 #include <private/qmath_p.h>
       
    72 
       
    73 QT_BEGIN_NAMESPACE
       
    74 
       
    75 #define QGradient_StretchToDevice 0x10000000
       
    76 #define QPaintEngine_OpaqueBackground 0x40000000
       
    77 
       
    78 // #define QT_DEBUG_DRAW
       
    79 #ifdef QT_DEBUG_DRAW
       
    80 bool qt_show_painter_debug_output = true;
       
    81 #endif
       
    82 
       
    83 extern QPixmap qt_pixmapForBrush(int style, bool invert);
       
    84 
       
    85 void qt_format_text(const QFont &font,
       
    86                     const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect,
       
    87                     int tabstops, int* tabarray, int tabarraylen,
       
    88                     QPainter *painter);
       
    89 
       
    90 static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
       
    91 {
       
    92     switch (brush.style()) {
       
    93     case Qt::LinearGradientPattern:
       
    94     case Qt::RadialGradientPattern:
       
    95     case Qt::ConicalGradientPattern:
       
    96         return brush.gradient()->coordinateMode();
       
    97     default:
       
    98         ;
       
    99     }
       
   100     return QGradient::LogicalMode;
       
   101 }
       
   102 
       
   103 /* Returns true if the gradient requires stretch to device...*/
       
   104 static inline bool check_gradient(const QBrush &brush)
       
   105 {
       
   106     return coordinateMode(brush) == QGradient::StretchToDeviceMode;
       
   107 }
       
   108 
       
   109 extern bool qHasPixmapTexture(const QBrush &);
       
   110 
       
   111 static inline bool is_brush_transparent(const QBrush &brush) {
       
   112     Qt::BrushStyle s = brush.style();
       
   113     bool brushBitmap = qHasPixmapTexture(brush)
       
   114                        ? brush.texture().isQBitmap()
       
   115                        : (brush.textureImage().depth() == 1);
       
   116     return ((s >= Qt::Dense1Pattern && s <= Qt::DiagCrossPattern)
       
   117             || (s == Qt::TexturePattern && brushBitmap));
       
   118 }
       
   119 
       
   120 static inline bool is_pen_transparent(const QPen &pen) {
       
   121     return pen.style() > Qt::SolidLine || is_brush_transparent(pen.brush());
       
   122 }
       
   123 
       
   124 /* Discards the emulation flags that are not relevant for line drawing
       
   125    and returns the result
       
   126 */
       
   127 static inline uint line_emulation(uint emulation)
       
   128 {
       
   129     return emulation & (QPaintEngine::PrimitiveTransform
       
   130                         | QPaintEngine::AlphaBlend
       
   131                         | QPaintEngine::Antialiasing
       
   132                         | QPaintEngine::BrushStroke
       
   133                         | QPaintEngine::ConstantOpacity
       
   134                         | QGradient_StretchToDevice
       
   135                         | QPaintEngine::ObjectBoundingModeGradients
       
   136                         | QPaintEngine_OpaqueBackground);
       
   137 }
       
   138 
       
   139 #ifndef QT_NO_DEBUG
       
   140 static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false)
       
   141 {
       
   142     switch (devType) {
       
   143     case QInternal::Image:
       
   144     case QInternal::Printer:
       
   145     case QInternal::Picture:
       
   146         // can be drawn onto these devices safely from any thread
       
   147 #ifndef Q_WS_WIN
       
   148         if (extraCondition)
       
   149 #endif
       
   150             break;
       
   151     default:
       
   152         if (!extraCondition && QThread::currentThread() != qApp->thread()) {
       
   153             qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
       
   154             return false;
       
   155         }
       
   156         break;
       
   157     }
       
   158     return true;
       
   159 }
       
   160 #endif
       
   161 
       
   162 void QPainterPrivate::checkEmulation()
       
   163 {
       
   164     Q_ASSERT(extended);
       
   165     if (extended->flags() & QPaintEngineEx::DoNotEmulate)
       
   166         return;
       
   167 
       
   168     bool doEmulation = false;
       
   169     if (state->bgMode == Qt::OpaqueMode)
       
   170         doEmulation = true;
       
   171 
       
   172     const QGradient *bg = state->brush.gradient();
       
   173     if (bg && bg->coordinateMode() > QGradient::LogicalMode)
       
   174         doEmulation = true;
       
   175 
       
   176     const QGradient *pg = qpen_brush(state->pen).gradient();
       
   177     if (pg && pg->coordinateMode() > QGradient::LogicalMode)
       
   178         doEmulation = true;
       
   179 
       
   180     if (doEmulation) {
       
   181         if (extended != emulationEngine) {
       
   182             if (!emulationEngine)
       
   183                 emulationEngine = new QEmulationPaintEngine(extended);
       
   184             extended = emulationEngine;
       
   185             extended->setState(state);
       
   186         }
       
   187     } else if (emulationEngine == extended) {
       
   188         extended = emulationEngine->real_engine;
       
   189     }
       
   190 }
       
   191 
       
   192 
       
   193 QPainterPrivate::~QPainterPrivate()
       
   194 {
       
   195     delete emulationEngine;
       
   196     for (int i=0; i<states.size(); ++i)
       
   197         delete states.at(i);
       
   198 
       
   199     if (dummyState)
       
   200         delete dummyState;
       
   201 }
       
   202 
       
   203 
       
   204 QTransform QPainterPrivate::viewTransform() const
       
   205 {
       
   206     if (state->VxF) {
       
   207         qreal scaleW = qreal(state->vw)/qreal(state->ww);
       
   208         qreal scaleH = qreal(state->vh)/qreal(state->wh);
       
   209         return QTransform(scaleW, 0, 0, scaleH,
       
   210                           state->vx - state->wx*scaleW, state->vy - state->wy*scaleH);
       
   211     }
       
   212     return QTransform();
       
   213 }
       
   214 
       
   215 
       
   216 /*
       
   217    \internal
       
   218    Returns true if using a shared painter; otherwise false.
       
   219 */
       
   220 bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
       
   221 {
       
   222     Q_ASSERT(q);
       
   223     Q_ASSERT(pdev);
       
   224 
       
   225     if (pdev->devType() != QInternal::Widget)
       
   226         return false;
       
   227 
       
   228     QWidget *widget = static_cast<QWidget *>(pdev);
       
   229     Q_ASSERT(widget);
       
   230 
       
   231     // Someone either called QPainter::setRedirected in the widget's paint event
       
   232     // right before this painter was created (or begin was called) or
       
   233     // sent a paint event directly to the widget.
       
   234     if (!widget->d_func()->redirectDev)
       
   235         return false;
       
   236 
       
   237     QPainter *sp = widget->d_func()->sharedPainter();
       
   238     if (!sp || !sp->isActive())
       
   239         return false;
       
   240 
       
   241     if (sp->paintEngine()->paintDevice() != widget->d_func()->redirectDev)
       
   242         return false;
       
   243 
       
   244     // Check if we're attempting to paint outside a paint event.
       
   245     if (!sp->d_ptr->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
       
   246         && !widget->testAttribute(Qt::WA_PaintOutsidePaintEvent)
       
   247         && !widget->testAttribute(Qt::WA_WState_InPaintEvent)) {
       
   248 
       
   249         qWarning("QPainter::begin: Widget painting can only begin as a result of a paintEvent");
       
   250         return false;
       
   251     }
       
   252 
       
   253     // Save the current state of the shared painter and assign
       
   254     // the current d_ptr to the shared painter's d_ptr.
       
   255     sp->save();
       
   256     if (!sp->d_ptr->d_ptrs) {
       
   257         // Allocate space for 4 d-pointers (enough for up to 4 sub-sequent
       
   258         // redirections within the same paintEvent(), which should be enough
       
   259         // in 99% of all cases). E.g: A renders B which renders C which renders D.
       
   260         sp->d_ptr->d_ptrs_size = 4;
       
   261         sp->d_ptr->d_ptrs = (QPainterPrivate **)malloc(4 * sizeof(QPainterPrivate *));
       
   262         Q_CHECK_PTR(sp->d_ptr->d_ptrs);
       
   263     } else if (sp->d_ptr->refcount - 1 == sp->d_ptr->d_ptrs_size) {
       
   264         // However, to support corner cases we grow the array dynamically if needed.
       
   265         sp->d_ptr->d_ptrs_size <<= 1;
       
   266         const int newSize = sp->d_ptr->d_ptrs_size * sizeof(QPainterPrivate *);
       
   267         sp->d_ptr->d_ptrs = q_check_ptr((QPainterPrivate **)realloc(sp->d_ptr->d_ptrs, newSize));
       
   268     }
       
   269     sp->d_ptr->d_ptrs[++sp->d_ptr->refcount - 2] = q->d_ptr.data();
       
   270     q->d_ptr.take();
       
   271     q->d_ptr.reset(sp->d_ptr.data());
       
   272 
       
   273     Q_ASSERT(q->d_ptr->state);
       
   274 
       
   275     // Now initialize the painter with correct widget properties.
       
   276     q->initFrom(widget);
       
   277     QPoint offset;
       
   278     widget->d_func()->redirected(&offset);
       
   279     offset += q->d_ptr->engine->coordinateOffset();
       
   280 
       
   281     // Update system rect.
       
   282     q->d_ptr->state->ww = q->d_ptr->state->vw = widget->width();
       
   283     q->d_ptr->state->wh = q->d_ptr->state->vh = widget->height();
       
   284 
       
   285     // Update matrix.
       
   286     if (q->d_ptr->state->WxF) {
       
   287         q->d_ptr->state->redirectionMatrix *= q->d_ptr->state->worldMatrix;
       
   288         q->d_ptr->state->redirectionMatrix.translate(-offset.x(), -offset.y());
       
   289         q->d_ptr->state->worldMatrix = QTransform();
       
   290         q->d_ptr->state->WxF = false;
       
   291     } else {
       
   292         q->d_ptr->state->redirectionMatrix = QTransform::fromTranslate(-offset.x(), -offset.y());
       
   293     }
       
   294     q->d_ptr->updateMatrix();
       
   295 
       
   296     QPaintEnginePrivate *enginePrivate = q->d_ptr->engine->d_func();
       
   297     if (enginePrivate->currentClipWidget == widget) {
       
   298         enginePrivate->systemStateChanged();
       
   299         return true;
       
   300     }
       
   301 
       
   302     // Update system transform and clip.
       
   303     enginePrivate->currentClipWidget = widget;
       
   304     enginePrivate->setSystemTransform(q->d_ptr->state->matrix);
       
   305     return true;
       
   306 }
       
   307 
       
   308 void QPainterPrivate::detachPainterPrivate(QPainter *q)
       
   309 {
       
   310     Q_ASSERT(refcount > 1);
       
   311     Q_ASSERT(q);
       
   312 
       
   313     QPainterPrivate *original = d_ptrs[--refcount - 1];
       
   314     if (inDestructor) {
       
   315         inDestructor = false;
       
   316         if (original)
       
   317             original->inDestructor = true;
       
   318     } else if (!original) {
       
   319         original = new QPainterPrivate(q);
       
   320     }
       
   321 
       
   322     d_ptrs[refcount - 1] = 0;
       
   323     q->restore();
       
   324     q->d_ptr.take();
       
   325     q->d_ptr.reset(original);
       
   326 
       
   327     if (emulationEngine) {
       
   328         extended = emulationEngine->real_engine;
       
   329         delete emulationEngine;
       
   330         emulationEngine = 0;
       
   331     }
       
   332 }
       
   333 
       
   334 
       
   335 void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperation op)
       
   336 {
       
   337 #ifdef QT_DEBUG_DRAW
       
   338     if (qt_show_painter_debug_output) {
       
   339         printf("QPainter::drawHelper\n");
       
   340     }
       
   341 #endif
       
   342 
       
   343     if (originalPath.isEmpty())
       
   344         return;
       
   345 
       
   346     QPaintEngine::PaintEngineFeatures gradientStretch =
       
   347         QPaintEngine::PaintEngineFeatures(QGradient_StretchToDevice
       
   348                                           | QPaintEngine::ObjectBoundingModeGradients);
       
   349 
       
   350     const bool mustEmulateObjectBoundingModeGradients = extended
       
   351                                                         || ((state->emulationSpecifier & QPaintEngine::ObjectBoundingModeGradients)
       
   352                                                             && !engine->hasFeature(QPaintEngine::PatternTransform));
       
   353 
       
   354     if (!(state->emulationSpecifier & ~gradientStretch)
       
   355         && !mustEmulateObjectBoundingModeGradients) {
       
   356         drawStretchedGradient(originalPath, op);
       
   357         return;
       
   358     } else if (state->emulationSpecifier & QPaintEngine_OpaqueBackground) {
       
   359         drawOpaqueBackground(originalPath, op);
       
   360         return;
       
   361     }
       
   362 
       
   363     Q_Q(QPainter);
       
   364 
       
   365     qreal strokeOffsetX = 0, strokeOffsetY = 0;
       
   366 
       
   367     QPainterPath path = originalPath * state->matrix;
       
   368     QRectF pathBounds = path.boundingRect();
       
   369     QRectF strokeBounds;
       
   370     bool doStroke = (op & StrokeDraw) && (state->pen.style() != Qt::NoPen);
       
   371     if (doStroke) {
       
   372         qreal penWidth = state->pen.widthF();
       
   373         if (penWidth == 0) {
       
   374             strokeOffsetX = 1;
       
   375             strokeOffsetY = 1;
       
   376         } else {
       
   377             // In case of complex xform
       
   378             if (state->matrix.type() > QTransform::TxScale) {
       
   379                 QPainterPathStroker stroker;
       
   380                 stroker.setWidth(penWidth);
       
   381                 stroker.setJoinStyle(state->pen.joinStyle());
       
   382                 stroker.setCapStyle(state->pen.capStyle());
       
   383                 QPainterPath stroke = stroker.createStroke(originalPath);
       
   384                 strokeBounds = (stroke * state->matrix).boundingRect();
       
   385             } else {
       
   386                 strokeOffsetX = qAbs(penWidth * state->matrix.m11() / 2.0);
       
   387                 strokeOffsetY = qAbs(penWidth * state->matrix.m22() / 2.0);
       
   388             }
       
   389         }
       
   390     }
       
   391 
       
   392     QRect absPathRect;
       
   393     if (!strokeBounds.isEmpty()) {
       
   394         absPathRect = strokeBounds.intersected(QRectF(0, 0, device->width(), device->height())).toAlignedRect();
       
   395     } else {
       
   396         absPathRect = pathBounds.adjusted(-strokeOffsetX, -strokeOffsetY, strokeOffsetX, strokeOffsetY)
       
   397             .intersected(QRectF(0, 0, device->width(), device->height())).toAlignedRect();
       
   398     }
       
   399 
       
   400     if (q->hasClipping()) {
       
   401         bool hasPerspectiveTransform = false;
       
   402         for (int i = 0; i < state->clipInfo.size(); ++i) {
       
   403             const QPainterClipInfo &info = state->clipInfo.at(i);
       
   404             if (info.matrix.type() == QTransform::TxProject) {
       
   405                 hasPerspectiveTransform = true;
       
   406                 break;
       
   407             }
       
   408         }
       
   409         // avoid mapping QRegions with perspective transforms
       
   410         if (!hasPerspectiveTransform) {
       
   411             // The trick with txinv and invMatrix is done in order to
       
   412             // avoid transforming the clip to logical coordinates, and
       
   413             // then back to device coordinates. This is a problem with
       
   414             // QRegion/QRect based clips, since they use integer
       
   415             // coordinates and converting to/from logical coordinates will
       
   416             // lose precision.
       
   417             bool old_txinv = txinv;
       
   418             QTransform old_invMatrix = invMatrix;
       
   419             txinv = true;
       
   420             invMatrix = QTransform();
       
   421             QPainterPath clipPath = q->clipPath();
       
   422             QRectF r = clipPath.boundingRect().intersected(absPathRect);
       
   423             absPathRect = r.toAlignedRect();
       
   424             txinv = old_txinv;
       
   425             invMatrix = old_invMatrix;
       
   426         }
       
   427     }
       
   428 
       
   429 //     qDebug("\nQPainterPrivate::draw_helper(), x=%d, y=%d, w=%d, h=%d",
       
   430 //            devMinX, devMinY, device->width(), device->height());
       
   431 //     qDebug() << " - matrix" << state->matrix;
       
   432 //     qDebug() << " - originalPath.bounds" << originalPath.boundingRect();
       
   433 //     qDebug() << " - path.bounds" << path.boundingRect();
       
   434 
       
   435     if (absPathRect.width() <= 0 || absPathRect.height() <= 0)
       
   436         return;
       
   437 
       
   438     QImage image(absPathRect.width(), absPathRect.height(), QImage::Format_ARGB32_Premultiplied);
       
   439     image.fill(0);
       
   440 
       
   441     QPainter p(&image);
       
   442 
       
   443     p.d_ptr->helper_device = helper_device;
       
   444 
       
   445     p.setOpacity(state->opacity);
       
   446     p.translate(-absPathRect.x(), -absPathRect.y());
       
   447     p.setTransform(state->matrix, true);
       
   448     p.setPen(doStroke ? state->pen : QPen(Qt::NoPen));
       
   449     p.setBrush((op & FillDraw) ? state->brush : QBrush(Qt::NoBrush));
       
   450     p.setBackground(state->bgBrush);
       
   451     p.setBackgroundMode(state->bgMode);
       
   452     p.setBrushOrigin(state->brushOrigin);
       
   453 
       
   454     p.setRenderHint(QPainter::Antialiasing, state->renderHints & QPainter::Antialiasing);
       
   455     p.setRenderHint(QPainter::SmoothPixmapTransform,
       
   456                     state->renderHints & QPainter::SmoothPixmapTransform);
       
   457 
       
   458     p.drawPath(originalPath);
       
   459 
       
   460 #ifndef QT_NO_DEBUG
       
   461     static bool do_fallback_overlay = qgetenv("QT_PAINT_FALLBACK_OVERLAY").size() > 0;
       
   462     if (do_fallback_overlay) {
       
   463         QImage block(8, 8, QImage::Format_ARGB32_Premultiplied);
       
   464         QPainter pt(&block);
       
   465         pt.fillRect(0, 0, 8, 8, QColor(196, 0, 196));
       
   466         pt.drawLine(0, 0, 8, 8);
       
   467         pt.end();
       
   468         p.resetTransform();
       
   469         p.setCompositionMode(QPainter::CompositionMode_SourceAtop);
       
   470         p.setOpacity(0.5);
       
   471         p.fillRect(0, 0, image.width(), image.height(), QBrush(block));
       
   472     }
       
   473 #endif
       
   474 
       
   475     p.end();
       
   476 
       
   477     q->save();
       
   478     state->matrix = QTransform();
       
   479     state->dirtyFlags |= QPaintEngine::DirtyTransform;
       
   480     updateState(state);
       
   481     engine->drawImage(absPathRect,
       
   482                  image,
       
   483                  QRectF(0, 0, absPathRect.width(), absPathRect.height()),
       
   484                  Qt::OrderedDither | Qt::OrderedAlphaDither);
       
   485     q->restore();
       
   486 }
       
   487 
       
   488 void QPainterPrivate::drawOpaqueBackground(const QPainterPath &path, DrawOperation op)
       
   489 {
       
   490     Q_Q(QPainter);
       
   491 
       
   492     q->setBackgroundMode(Qt::TransparentMode);
       
   493 
       
   494     if (op & FillDraw && state->brush.style() != Qt::NoBrush) {
       
   495         q->fillPath(path, state->bgBrush.color());
       
   496         q->fillPath(path, state->brush);
       
   497     }
       
   498 
       
   499     if (op & StrokeDraw && state->pen.style() != Qt::NoPen) {
       
   500         q->strokePath(path, QPen(state->bgBrush.color(), state->pen.width()));
       
   501         q->strokePath(path, state->pen);
       
   502     }
       
   503 
       
   504     q->setBackgroundMode(Qt::OpaqueMode);
       
   505 }
       
   506 
       
   507 static inline QBrush stretchGradientToUserSpace(const QBrush &brush, const QRectF &boundingRect)
       
   508 {
       
   509     Q_ASSERT(brush.style() >= Qt::LinearGradientPattern
       
   510              && brush.style() <= Qt::ConicalGradientPattern);
       
   511 
       
   512     QTransform gradientToUser(boundingRect.width(), 0, 0, boundingRect.height(),
       
   513                               boundingRect.x(), boundingRect.y());
       
   514 
       
   515     QGradient g = *brush.gradient();
       
   516     g.setCoordinateMode(QGradient::LogicalMode);
       
   517 
       
   518     QBrush b(g);
       
   519     b.setTransform(gradientToUser * b.transform());
       
   520     return b;
       
   521 }
       
   522 
       
   523 void QPainterPrivate::drawStretchedGradient(const QPainterPath &path, DrawOperation op)
       
   524 {
       
   525     Q_Q(QPainter);
       
   526 
       
   527     const qreal sw = helper_device->width();
       
   528     const qreal sh = helper_device->height();
       
   529 
       
   530     bool changedPen = false;
       
   531     bool changedBrush = false;
       
   532     bool needsFill = false;
       
   533 
       
   534     const QPen pen = state->pen;
       
   535     const QBrush brush = state->brush;
       
   536 
       
   537     const QGradient::CoordinateMode penMode = coordinateMode(pen.brush());
       
   538     const QGradient::CoordinateMode brushMode = coordinateMode(brush);
       
   539 
       
   540     QRectF boundingRect;
       
   541 
       
   542     // Draw the xformed fill if the brush is a stretch gradient.
       
   543     if ((op & FillDraw) && brush.style() != Qt::NoBrush) {
       
   544         if (brushMode == QGradient::StretchToDeviceMode) {
       
   545             q->setPen(Qt::NoPen);
       
   546             changedPen = pen.style() != Qt::NoPen;
       
   547             q->scale(sw, sh);
       
   548             updateState(state);
       
   549 
       
   550             const qreal isw = 1.0 / sw;
       
   551             const qreal ish = 1.0 / sh;
       
   552             QTransform inv(isw, 0, 0, ish, 0, 0);
       
   553             engine->drawPath(path * inv);
       
   554             q->scale(isw, ish);
       
   555         } else {
       
   556             needsFill = true;
       
   557 
       
   558             if (brushMode == QGradient::ObjectBoundingMode) {
       
   559                 Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));
       
   560                 boundingRect = path.boundingRect();
       
   561                 q->setBrush(stretchGradientToUserSpace(brush, boundingRect));
       
   562                 changedBrush = true;
       
   563             }
       
   564         }
       
   565     }
       
   566 
       
   567     if ((op & StrokeDraw) && pen.style() != Qt::NoPen) {
       
   568         // Draw the xformed outline if the pen is a stretch gradient.
       
   569         if (penMode == QGradient::StretchToDeviceMode) {
       
   570             q->setPen(Qt::NoPen);
       
   571             changedPen = true;
       
   572 
       
   573             if (needsFill) {
       
   574                 updateState(state);
       
   575                 engine->drawPath(path);
       
   576             }
       
   577 
       
   578             q->scale(sw, sh);
       
   579             q->setBrush(pen.brush());
       
   580             changedBrush = true;
       
   581             updateState(state);
       
   582 
       
   583             QPainterPathStroker stroker;
       
   584             stroker.setDashPattern(pen.style());
       
   585             stroker.setWidth(pen.widthF());
       
   586             stroker.setJoinStyle(pen.joinStyle());
       
   587             stroker.setCapStyle(pen.capStyle());
       
   588             stroker.setMiterLimit(pen.miterLimit());
       
   589             QPainterPath stroke = stroker.createStroke(path);
       
   590 
       
   591             const qreal isw = 1.0 / sw;
       
   592             const qreal ish = 1.0 / sh;
       
   593             QTransform inv(isw, 0, 0, ish, 0, 0);
       
   594             engine->drawPath(stroke * inv);
       
   595             q->scale(isw, ish);
       
   596         } else {
       
   597             if (!needsFill && brush.style() != Qt::NoBrush) {
       
   598                 q->setBrush(Qt::NoBrush);
       
   599                 changedBrush = true;
       
   600             }
       
   601 
       
   602             if (penMode == QGradient::ObjectBoundingMode) {
       
   603                 Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));
       
   604 
       
   605                 // avoid computing the bounding rect twice
       
   606                 if (!needsFill || brushMode != QGradient::ObjectBoundingMode)
       
   607                     boundingRect = path.boundingRect();
       
   608 
       
   609                 QPen p = pen;
       
   610                 p.setBrush(stretchGradientToUserSpace(pen.brush(), boundingRect));
       
   611                 q->setPen(p);
       
   612                 changedPen = true;
       
   613             } else if (changedPen) {
       
   614                 q->setPen(pen);
       
   615                 changedPen = false;
       
   616             }
       
   617 
       
   618             updateState(state);
       
   619             engine->drawPath(path);
       
   620         }
       
   621     } else if (needsFill) {
       
   622         if (pen.style() != Qt::NoPen) {
       
   623             q->setPen(Qt::NoPen);
       
   624             changedPen = true;
       
   625         }
       
   626 
       
   627         updateState(state);
       
   628         engine->drawPath(path);
       
   629     }
       
   630 
       
   631     if (changedPen)
       
   632         q->setPen(pen);
       
   633     if (changedBrush)
       
   634         q->setBrush(brush);
       
   635 }
       
   636 
       
   637 
       
   638 void QPainterPrivate::updateMatrix()
       
   639 {
       
   640     state->matrix = state->WxF ? state->worldMatrix : QTransform();
       
   641     if (state->VxF)
       
   642         state->matrix *= viewTransform();
       
   643 
       
   644     txinv = false;                                // no inverted matrix
       
   645     state->matrix *= state->redirectionMatrix;
       
   646     if (extended)
       
   647         extended->transformChanged();
       
   648     else
       
   649         state->dirtyFlags |= QPaintEngine::DirtyTransform;
       
   650 
       
   651 //     printf("VxF=%d, WxF=%d\n", state->VxF, state->WxF);
       
   652 //     qDebug() << " --- using matrix" << state->matrix << redirection_offset;
       
   653 }
       
   654 
       
   655 /*! \internal */
       
   656 void QPainterPrivate::updateInvMatrix()
       
   657 {
       
   658     Q_ASSERT(txinv == false);
       
   659     txinv = true;                                // creating inverted matrix
       
   660     invMatrix = state->matrix.inverted();
       
   661 }
       
   662 
       
   663 void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
       
   664 {
       
   665     bool alpha = false;
       
   666     bool linearGradient = false;
       
   667     bool radialGradient = false;
       
   668     bool conicalGradient = false;
       
   669     bool patternBrush = false;
       
   670     bool xform = false;
       
   671     bool complexXform = false;
       
   672 
       
   673     bool skip = true;
       
   674 
       
   675     // Pen and brush properties (we have to check both if one changes because the
       
   676     // one that's unchanged can still be in a state which requires emulation)
       
   677     if (s->state() & (QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush | QPaintEngine::DirtyHints)) {
       
   678         // Check Brush stroke emulation
       
   679         if (!s->pen.isSolid() && !engine->hasFeature(QPaintEngine::BrushStroke))
       
   680             s->emulationSpecifier |= QPaintEngine::BrushStroke;
       
   681         else
       
   682             s->emulationSpecifier &= ~QPaintEngine::BrushStroke;
       
   683 
       
   684         skip = false;
       
   685 
       
   686         QBrush penBrush = s->pen.brush();
       
   687         Qt::BrushStyle brushStyle = s->brush.style();
       
   688         Qt::BrushStyle penBrushStyle = penBrush.style();
       
   689         alpha = (penBrushStyle != Qt::NoBrush
       
   690                  && (penBrushStyle < Qt::LinearGradientPattern && penBrush.color().alpha() != 255)
       
   691                  && !penBrush.isOpaque())
       
   692                 || (brushStyle != Qt::NoBrush
       
   693                     && (brushStyle < Qt::LinearGradientPattern && s->brush.color().alpha() != 255)
       
   694                     && !s->brush.isOpaque());
       
   695         linearGradient = ((penBrushStyle == Qt::LinearGradientPattern) ||
       
   696                            (brushStyle == Qt::LinearGradientPattern));
       
   697         radialGradient = ((penBrushStyle == Qt::RadialGradientPattern) ||
       
   698                            (brushStyle == Qt::RadialGradientPattern));
       
   699         conicalGradient = ((penBrushStyle == Qt::ConicalGradientPattern) ||
       
   700                             (brushStyle == Qt::ConicalGradientPattern));
       
   701         patternBrush = (((penBrushStyle > Qt::SolidPattern
       
   702                            && penBrushStyle < Qt::LinearGradientPattern)
       
   703                           || penBrushStyle == Qt::TexturePattern) ||
       
   704                          ((brushStyle > Qt::SolidPattern
       
   705                            && brushStyle < Qt::LinearGradientPattern)
       
   706                           || brushStyle == Qt::TexturePattern));
       
   707 
       
   708         bool penTextureAlpha = false;
       
   709         if (penBrush.style() == Qt::TexturePattern)
       
   710             penTextureAlpha = qHasPixmapTexture(penBrush)
       
   711                               ? penBrush.texture().hasAlpha()
       
   712                               : penBrush.textureImage().hasAlphaChannel();
       
   713         bool brushTextureAlpha = false;
       
   714         if (s->brush.style() == Qt::TexturePattern)
       
   715             brushTextureAlpha = qHasPixmapTexture(s->brush)
       
   716                                 ? s->brush.texture().hasAlpha()
       
   717                                 : s->brush.textureImage().hasAlphaChannel();
       
   718         if (((penBrush.style() == Qt::TexturePattern && penTextureAlpha)
       
   719              || (s->brush.style() == Qt::TexturePattern && brushTextureAlpha))
       
   720             && !engine->hasFeature(QPaintEngine::MaskedBrush))
       
   721             s->emulationSpecifier |= QPaintEngine::MaskedBrush;
       
   722         else
       
   723             s->emulationSpecifier &= ~QPaintEngine::MaskedBrush;
       
   724     }
       
   725 
       
   726     if (s->state() & (QPaintEngine::DirtyHints
       
   727                       | QPaintEngine::DirtyOpacity
       
   728                       | QPaintEngine::DirtyBackgroundMode)) {
       
   729         skip = false;
       
   730     }
       
   731 
       
   732     if (skip)
       
   733         return;
       
   734 
       
   735 #if 0
       
   736     qDebug("QPainterPrivate::updateEmulationSpecifier, state=%p\n"
       
   737            " - alpha: %d\n"
       
   738            " - linearGradient: %d\n"
       
   739            " - radialGradient: %d\n"
       
   740            " - conicalGradient: %d\n"
       
   741            " - patternBrush: %d\n"
       
   742            " - hints: %x\n"
       
   743            " - xform: %d\n",
       
   744            s,
       
   745            alpha,
       
   746            linearGradient,
       
   747            radialGradient,
       
   748            conicalGradient,
       
   749            patternBrush,
       
   750            uint(s->renderHints),
       
   751            xform);
       
   752 #endif
       
   753 
       
   754     // XForm properties
       
   755     if (s->state() & QPaintEngine::DirtyTransform) {
       
   756         xform = !s->matrix.isIdentity();
       
   757         complexXform = !s->matrix.isAffine();
       
   758     } else if (s->matrix.type() >= QTransform::TxTranslate) {
       
   759         xform = true;
       
   760         complexXform = !s->matrix.isAffine();
       
   761     }
       
   762 
       
   763     const bool brushXform = (!s->brush.transform().type() == QTransform::TxNone);
       
   764     const bool penXform = (!s->pen.brush().transform().type() == QTransform::TxNone);
       
   765 
       
   766     const bool patternXform = patternBrush && (xform || brushXform || penXform);
       
   767 
       
   768     // Check alphablending
       
   769     if (alpha && !engine->hasFeature(QPaintEngine::AlphaBlend))
       
   770         s->emulationSpecifier |= QPaintEngine::AlphaBlend;
       
   771     else
       
   772         s->emulationSpecifier &= ~QPaintEngine::AlphaBlend;
       
   773 
       
   774     // Linear gradient emulation
       
   775     if (linearGradient && !engine->hasFeature(QPaintEngine::LinearGradientFill))
       
   776         s->emulationSpecifier |= QPaintEngine::LinearGradientFill;
       
   777     else
       
   778         s->emulationSpecifier &= ~QPaintEngine::LinearGradientFill;
       
   779 
       
   780     // Radial gradient emulation
       
   781     if (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill))
       
   782         s->emulationSpecifier |= QPaintEngine::RadialGradientFill;
       
   783     else
       
   784         s->emulationSpecifier &= ~QPaintEngine::RadialGradientFill;
       
   785 
       
   786     // Conical gradient emulation
       
   787     if (conicalGradient && !engine->hasFeature(QPaintEngine::ConicalGradientFill))
       
   788         s->emulationSpecifier |= QPaintEngine::ConicalGradientFill;
       
   789     else
       
   790         s->emulationSpecifier &= ~QPaintEngine::ConicalGradientFill;
       
   791 
       
   792     // Pattern brushes
       
   793     if (patternBrush && !engine->hasFeature(QPaintEngine::PatternBrush))
       
   794         s->emulationSpecifier |= QPaintEngine::PatternBrush;
       
   795     else
       
   796         s->emulationSpecifier &= ~QPaintEngine::PatternBrush;
       
   797 
       
   798     // Pattern XForms
       
   799     if (patternXform && !engine->hasFeature(QPaintEngine::PatternTransform))
       
   800         s->emulationSpecifier |= QPaintEngine::PatternTransform;
       
   801     else
       
   802         s->emulationSpecifier &= ~QPaintEngine::PatternTransform;
       
   803 
       
   804     // Primitive XForms
       
   805     if (xform && !engine->hasFeature(QPaintEngine::PrimitiveTransform))
       
   806         s->emulationSpecifier |= QPaintEngine::PrimitiveTransform;
       
   807     else
       
   808         s->emulationSpecifier &= ~QPaintEngine::PrimitiveTransform;
       
   809 
       
   810     // Perspective XForms
       
   811     if (complexXform && !engine->hasFeature(QPaintEngine::PerspectiveTransform))
       
   812         s->emulationSpecifier |= QPaintEngine::PerspectiveTransform;
       
   813     else
       
   814         s->emulationSpecifier &= ~QPaintEngine::PerspectiveTransform;
       
   815 
       
   816     // Constant opacity
       
   817     if (state->opacity != 1 && !engine->hasFeature(QPaintEngine::ConstantOpacity))
       
   818         s->emulationSpecifier |= QPaintEngine::ConstantOpacity;
       
   819     else
       
   820         s->emulationSpecifier &= ~QPaintEngine::ConstantOpacity;
       
   821 
       
   822     bool gradientStretch = false;
       
   823     bool objectBoundingMode = false;
       
   824     if (linearGradient || conicalGradient || radialGradient) {
       
   825         QGradient::CoordinateMode brushMode = coordinateMode(s->brush);
       
   826         QGradient::CoordinateMode penMode = coordinateMode(s->pen.brush());
       
   827 
       
   828         gradientStretch |= (brushMode == QGradient::StretchToDeviceMode);
       
   829         gradientStretch |= (penMode == QGradient::StretchToDeviceMode);
       
   830 
       
   831         objectBoundingMode |= (brushMode == QGradient::ObjectBoundingMode);
       
   832         objectBoundingMode |= (penMode == QGradient::ObjectBoundingMode);
       
   833     }
       
   834     if (gradientStretch)
       
   835         s->emulationSpecifier |= QGradient_StretchToDevice;
       
   836     else
       
   837         s->emulationSpecifier &= ~QGradient_StretchToDevice;
       
   838 
       
   839     if (objectBoundingMode && !engine->hasFeature(QPaintEngine::ObjectBoundingModeGradients))
       
   840         s->emulationSpecifier |= QPaintEngine::ObjectBoundingModeGradients;
       
   841     else
       
   842         s->emulationSpecifier &= ~QPaintEngine::ObjectBoundingModeGradients;
       
   843 
       
   844     // Opaque backgrounds...
       
   845     if (s->bgMode == Qt::OpaqueMode &&
       
   846         (is_pen_transparent(s->pen) || is_brush_transparent(s->brush)))
       
   847         s->emulationSpecifier |= QPaintEngine_OpaqueBackground;
       
   848     else
       
   849         s->emulationSpecifier &= ~QPaintEngine_OpaqueBackground;
       
   850 
       
   851 #if 0
       
   852     //won't be correct either way because the device can already have
       
   853     // something rendered to it in which case subsequent emulation
       
   854     // on a fully transparent qimage and then blitting the results
       
   855     // won't produce correct results
       
   856     // Blend modes
       
   857     if (state->composition_mode > QPainter::CompositionMode_Xor &&
       
   858         !engine->hasFeature(QPaintEngine::BlendModes))
       
   859         s->emulationSpecifier |= QPaintEngine::BlendModes;
       
   860     else
       
   861         s->emulationSpecifier &= ~QPaintEngine::BlendModes;
       
   862 #endif
       
   863 }
       
   864 
       
   865 void QPainterPrivate::updateStateImpl(QPainterState *newState)
       
   866 {
       
   867     // ### we might have to call QPainter::begin() here...
       
   868     if (!engine->state) {
       
   869         engine->state = newState;
       
   870         engine->setDirty(QPaintEngine::AllDirty);
       
   871     }
       
   872 
       
   873     if (engine->state->painter() != newState->painter)
       
   874         // ### this could break with clip regions vs paths.
       
   875         engine->setDirty(QPaintEngine::AllDirty);
       
   876 
       
   877     // Upon restore, revert all changes since last save
       
   878     else if (engine->state != newState)
       
   879         newState->dirtyFlags |= QPaintEngine::DirtyFlags(static_cast<QPainterState *>(engine->state)->changeFlags);
       
   880 
       
   881     // We need to store all changes made so that restore can deal with them
       
   882     else
       
   883         newState->changeFlags |= newState->dirtyFlags;
       
   884 
       
   885     updateEmulationSpecifier(newState);
       
   886 
       
   887     // Unset potential dirty background mode
       
   888     newState->dirtyFlags &= ~(QPaintEngine::DirtyBackgroundMode
       
   889             | QPaintEngine::DirtyBackground);
       
   890 
       
   891     engine->state = newState;
       
   892     engine->updateState(*newState);
       
   893     engine->clearDirty(QPaintEngine::AllDirty);
       
   894 
       
   895 }
       
   896 
       
   897 void QPainterPrivate::updateState(QPainterState *newState)
       
   898 {
       
   899 
       
   900     if (!newState) {
       
   901         engine->state = newState;
       
   902 
       
   903     } else if (newState->state() || engine->state!=newState) {
       
   904         bool setNonCosmeticPen = (newState->renderHints & QPainter::NonCosmeticDefaultPen)
       
   905                                  && newState->pen.widthF() == 0;
       
   906         if (setNonCosmeticPen) {
       
   907             // Override the default pen's cosmetic state if the
       
   908             // NonCosmeticDefaultPen render hint is used.
       
   909             QPen oldPen = newState->pen;
       
   910             newState->pen.setWidth(1);
       
   911             newState->pen.setCosmetic(false);
       
   912             newState->dirtyFlags |= QPaintEngine::DirtyPen;
       
   913 
       
   914             updateStateImpl(newState);
       
   915 
       
   916             // Restore the state pen back to its default to preserve visible
       
   917             // state.
       
   918             newState->pen = oldPen;
       
   919         } else {
       
   920             updateStateImpl(newState);
       
   921         }
       
   922     }
       
   923 }
       
   924 
       
   925 
       
   926 /*!
       
   927     \class QPainter
       
   928     \brief The QPainter class performs low-level painting on widgets and
       
   929     other paint devices.
       
   930 
       
   931     \ingroup painting
       
   932 
       
   933     \reentrant
       
   934 
       
   935     QPainter provides highly optimized functions to do most of the
       
   936     drawing GUI programs require. It can draw everything from simple
       
   937     lines to complex shapes like pies and chords. It can also draw
       
   938     aligned text and pixmaps. Normally, it draws in a "natural"
       
   939     coordinate system, but it can also do view and world
       
   940     transformation. QPainter can operate on any object that inherits
       
   941     the QPaintDevice class.
       
   942 
       
   943     The common use of QPainter is inside a widget's paint event:
       
   944     Construct and customize (e.g. set the pen or the brush) the
       
   945     painter. Then draw. Remember to destroy the QPainter object after
       
   946     drawing. For example:
       
   947 
       
   948     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 0
       
   949 
       
   950     The core functionality of QPainter is drawing, but the class also
       
   951     provide several functions that allows you to customize QPainter's
       
   952     settings and its rendering quality, and others that enable
       
   953     clipping. In addition you can control how different shapes are
       
   954     merged together by specifying the painter's composition mode.
       
   955 
       
   956     The isActive() function indicates whether the painter is active. A
       
   957     painter is activated by the begin() function and the constructor
       
   958     that takes a QPaintDevice argument. The end() function, and the
       
   959     destructor, deactivates it.
       
   960 
       
   961     Together with the QPaintDevice and QPaintEngine classes, QPainter
       
   962     form the basis for Qt's paint system. QPainter is the class used
       
   963     to perform drawing operations. QPaintDevice represents a device
       
   964     that can be painted on using a QPainter. QPaintEngine provides the
       
   965     interface that the painter uses to draw onto different types of
       
   966     devices. If the painter is active, device() returns the paint
       
   967     device on which the painter paints, and paintEngine() returns the
       
   968     paint engine that the painter is currently operating on. For more
       
   969     information, see \l {The Paint System} documentation.
       
   970 
       
   971     Sometimes it is desirable to make someone else paint on an unusual
       
   972     QPaintDevice. QPainter supports a static function to do this,
       
   973     setRedirected().
       
   974 
       
   975     \warning When the paintdevice is a widget, QPainter can only be
       
   976     used inside a paintEvent() function or in a function called by
       
   977     paintEvent(); that is unless the Qt::WA_PaintOutsidePaintEvent
       
   978     widget attribute is set. On Mac OS X and Windows, you can only
       
   979     paint in a paintEvent() function regardless of this attribute's
       
   980     setting.
       
   981 
       
   982     \tableofcontents
       
   983 
       
   984     \section1 Settings
       
   985 
       
   986     There are several settings that you can customize to make QPainter
       
   987     draw according to your preferences:
       
   988 
       
   989     \list
       
   990 
       
   991     \o font() is the font used for drawing text. If the painter
       
   992         isActive(), you can retrieve information about the currently set
       
   993         font, and its metrics, using the fontInfo() and fontMetrics()
       
   994         functions respectively.
       
   995 
       
   996     \o brush() defines the color or pattern that is used for filling
       
   997        shapes.
       
   998 
       
   999     \o pen() defines the color or stipple that is used for drawing
       
  1000        lines or boundaries.
       
  1001 
       
  1002     \o backgroundMode() defines whether there is a background() or
       
  1003        not, i.e it is either Qt::OpaqueMode or Qt::TransparentMode.
       
  1004 
       
  1005     \o background() only applies when backgroundMode() is \l
       
  1006        Qt::OpaqueMode and pen() is a stipple. In that case, it
       
  1007        describes the color of the background pixels in the stipple.
       
  1008 
       
  1009     \o brushOrigin() defines the origin of the tiled brushes, normally
       
  1010        the origin of widget's background.
       
  1011 
       
  1012     \o viewport(), window(), worldTransform() make up the painter's coordinate
       
  1013         transformation system. For more information, see the \l
       
  1014         {Coordinate Transformations} section and the \l {The Coordinate
       
  1015         System} documentation.
       
  1016 
       
  1017     \o hasClipping() tells whether the painter clips at all. (The paint
       
  1018        device clips, too.) If the painter clips, it clips to clipRegion().
       
  1019 
       
  1020     \o layoutDirection() defines the layout direction used by the
       
  1021        painter when drawing text.
       
  1022 
       
  1023     \o worldMatrixEnabled() tells whether world transformation is enabled.
       
  1024 
       
  1025     \o viewTransformEnabled() tells whether view transformation is
       
  1026         enabled.
       
  1027 
       
  1028     \endlist
       
  1029 
       
  1030     Note that some of these settings mirror settings in some paint
       
  1031     devices, e.g.  QWidget::font(). The QPainter::begin() function (or
       
  1032     equivalently the QPainter constructor) copies these attributes
       
  1033     from the paint device.
       
  1034 
       
  1035     You can at any time save the QPainter's state by calling the
       
  1036     save() function which saves all the available settings on an
       
  1037     internal stack. The restore() function pops them back.
       
  1038 
       
  1039     \section1 Drawing
       
  1040 
       
  1041     QPainter provides functions to draw most primitives: drawPoint(),
       
  1042     drawPoints(), drawLine(), drawRect(), drawRoundedRect(),
       
  1043     drawEllipse(), drawArc(), drawPie(), drawChord(), drawPolyline(),
       
  1044     drawPolygon(), drawConvexPolygon() and drawCubicBezier().  The two
       
  1045     convenience functions, drawRects() and drawLines(), draw the given
       
  1046     number of rectangles or lines in the given array of \l
       
  1047     {QRect}{QRects} or \l {QLine}{QLines} using the current pen and
       
  1048     brush.
       
  1049 
       
  1050     The QPainter class also provides the fillRect() function which
       
  1051     fills the given QRect, with the given QBrush, and the eraseRect()
       
  1052     function that erases the area inside the given rectangle.
       
  1053 
       
  1054     All of these functions have both integer and floating point
       
  1055     versions.
       
  1056 
       
  1057     \table 100%
       
  1058     \row
       
  1059     \o \inlineimage qpainter-basicdrawing.png
       
  1060     \o
       
  1061     \bold {Basic Drawing Example}
       
  1062 
       
  1063     The \l {painting/basicdrawing}{Basic Drawing} example shows how to
       
  1064     display basic graphics primitives in a variety of styles using the
       
  1065     QPainter class.
       
  1066 
       
  1067     \endtable
       
  1068 
       
  1069     If you need to draw a complex shape, especially if you need to do
       
  1070     so repeatedly, consider creating a QPainterPath and drawing it
       
  1071     using drawPath().
       
  1072 
       
  1073     \table 100%
       
  1074     \row
       
  1075     \o
       
  1076     \bold {Painter Paths example}
       
  1077 
       
  1078     The QPainterPath class provides a container for painting
       
  1079     operations, enabling graphical shapes to be constructed and
       
  1080     reused.
       
  1081 
       
  1082     The \l {painting/painterpaths}{Painter Paths} example shows how
       
  1083     painter paths can be used to build complex shapes for rendering.
       
  1084 
       
  1085     \o \inlineimage qpainter-painterpaths.png
       
  1086     \endtable
       
  1087 
       
  1088     QPainter also provides the fillPath() function which fills the
       
  1089     given QPainterPath with the given QBrush, and the strokePath()
       
  1090     function that draws the outline of the given path (i.e. strokes
       
  1091     the path).
       
  1092 
       
  1093     See also the \l {demos/deform}{Vector Deformation} demo which
       
  1094     shows how to use advanced vector techniques to draw text using a
       
  1095     QPainterPath, the \l {demos/gradients}{Gradients} demo which shows
       
  1096     the different types of gradients that are available in Qt, and the \l
       
  1097     {demos/pathstroke}{Path Stroking} demo which shows Qt's built-in
       
  1098     dash patterns and shows how custom patterns can be used to extend
       
  1099     the range of available patterns.
       
  1100 
       
  1101     \table
       
  1102     \row
       
  1103     \o \inlineimage qpainter-vectordeformation.png
       
  1104     \o \inlineimage qpainter-gradients.png
       
  1105     \o \inlineimage qpainter-pathstroking.png
       
  1106     \header
       
  1107     \o \l {demos/deform}{Vector Deformation}
       
  1108     \o \l {demos/gradients}{Gradients}
       
  1109     \o \l {demos/pathstroke}{Path Stroking}
       
  1110     \endtable
       
  1111 
       
  1112 
       
  1113     There are functions to draw pixmaps/images, namely drawPixmap(),
       
  1114     drawImage() and drawTiledPixmap(). Both drawPixmap() and drawImage()
       
  1115     produce the same result, except that drawPixmap() is faster
       
  1116     on-screen while drawImage() may be faster on a QPrinter or other
       
  1117     devices.
       
  1118 
       
  1119     Text drawing is done using drawText(). When you need
       
  1120     fine-grained positioning, boundingRect() tells you where a given
       
  1121     drawText() command will draw.
       
  1122 
       
  1123     There is a drawPicture() function that draws the contents of an
       
  1124     entire QPicture. The drawPicture() function is the only function
       
  1125     that disregards all the painter's settings as QPicture has its own
       
  1126     settings.
       
  1127 
       
  1128     \section1 Rendering Quality
       
  1129 
       
  1130     To get the optimal rendering result using QPainter, you should use
       
  1131     the platform independent QImage as paint device; i.e. using QImage
       
  1132     will ensure that the result has an identical pixel representation
       
  1133     on any platform.
       
  1134 
       
  1135     The QPainter class also provides a means of controlling the
       
  1136     rendering quality through its RenderHint enum and the support for
       
  1137     floating point precision: All the functions for drawing primitives
       
  1138     has a floating point version. These are often used in combination
       
  1139     with the \l {RenderHint}{QPainter::Antialiasing} render hint.
       
  1140 
       
  1141     \table 100%
       
  1142     \row
       
  1143     \o \inlineimage qpainter-concentriccircles.png
       
  1144     \o
       
  1145     \bold {Concentric Circles Example}
       
  1146 
       
  1147     The \l {painting/concentriccircles}{Concentric Circles} example
       
  1148     shows the improved rendering quality that can be obtained using
       
  1149     floating point precision and anti-aliasing when drawing custom
       
  1150     widgets.
       
  1151 
       
  1152     The application's main window displays several widgets which are
       
  1153     drawn using the various combinations of precision and
       
  1154     anti-aliasing.
       
  1155 
       
  1156     \endtable
       
  1157 
       
  1158     The RenderHint enum specifies flags to QPainter that may or may
       
  1159     not be respected by any given engine.  \l
       
  1160     {RenderHint}{QPainter::Antialiasing} indicates that the engine
       
  1161     should antialias edges of primitives if possible, \l
       
  1162     {RenderHint}{QPainter::TextAntialiasing} indicates that the engine
       
  1163     should antialias text if possible, and the \l
       
  1164     {RenderHint}{QPainter::SmoothPixmapTransform} indicates that the
       
  1165     engine should use a smooth pixmap transformation algorithm.
       
  1166     \l {RenderHint}{HighQualityAntialiasing} is an OpenGL-specific rendering hint
       
  1167     indicating that the engine should use fragment programs and offscreen
       
  1168     rendering for antialiasing.
       
  1169 
       
  1170     The renderHints() function returns a flag that specifies the
       
  1171     rendering hints that are set for this painter.  Use the
       
  1172     setRenderHint() function to set or clear the currently set
       
  1173     RenderHints.
       
  1174 
       
  1175     \section1 Coordinate Transformations
       
  1176 
       
  1177     Normally, the QPainter operates on the device's own coordinate
       
  1178     system (usually pixels), but QPainter has good support for
       
  1179     coordinate transformations.
       
  1180 
       
  1181     \table
       
  1182     \row
       
  1183     \o \inlineimage qpainter-clock.png
       
  1184     \o \inlineimage qpainter-rotation.png
       
  1185     \o \inlineimage qpainter-scale.png
       
  1186     \o \inlineimage qpainter-translation.png
       
  1187     \header
       
  1188     \o  nop \o rotate() \o scale() \o translate()
       
  1189     \endtable
       
  1190 
       
  1191     The most commonly used transformations are scaling, rotation,
       
  1192     translation and shearing. Use the scale() function to scale the
       
  1193     coordinate system by a given offset, the rotate() function to
       
  1194     rotate it clockwise and translate() to translate it (i.e. adding a
       
  1195     given offset to the points). You can also twist the coordinate
       
  1196     system around the origin using the shear() function. See the \l
       
  1197     {demos/affine}{Affine Transformations} demo for a visualization of
       
  1198     a sheared coordinate system.
       
  1199 
       
  1200     See also the \l {painting/transformations}{Transformations}
       
  1201     example which shows how transformations influence the way that
       
  1202     QPainter renders graphics primitives. In particular it shows how
       
  1203     the order of transformations affects the result.
       
  1204 
       
  1205     \table 100%
       
  1206     \row
       
  1207     \o
       
  1208     \bold {Affine Transformations Demo}
       
  1209 
       
  1210     The \l {demos/affine}{Affine Transformations} demo show Qt's
       
  1211     ability to perform affine transformations on painting
       
  1212     operations. The demo also allows the user to experiment with the
       
  1213     transformation operations and see the results immediately.
       
  1214 
       
  1215     \o \inlineimage qpainter-affinetransformations.png
       
  1216     \endtable
       
  1217 
       
  1218     All the tranformation operations operate on the transformation
       
  1219     worldTransform(). A matrix transforms a point in the plane to another
       
  1220     point. For more information about the transformation matrix, see
       
  1221     the \l {The Coordinate System} and QTransform documentation.
       
  1222 
       
  1223     The setWorldTransform() function can replace or add to the currently
       
  1224     set worldTransform(). The resetTransform() function resets any
       
  1225     transformations that were made using translate(), scale(),
       
  1226     shear(), rotate(), setWorldTransform(), setViewport() and setWindow()
       
  1227     functions. The deviceTransform() returns the matrix that transforms
       
  1228     from logical coordinates to device coordinates of the platform
       
  1229     dependent paint device. The latter function is only needed when
       
  1230     using platform painting commands on the platform dependent handle,
       
  1231     and the platform does not do transformations nativly.
       
  1232 
       
  1233     When drawing with QPainter, we specify points using logical
       
  1234     coordinates which then are converted into the physical coordinates
       
  1235     of the paint device. The mapping of the logical coordinates to the
       
  1236     physical coordinates are handled by QPainter's combinedTransform(), a
       
  1237     combination of viewport() and window() and worldTransform(). The
       
  1238     viewport() represents the physical coordinates specifying an
       
  1239     arbitrary rectangle, the window() describes the same rectangle in
       
  1240     logical coordinates, and the worldTransform() is identical with the
       
  1241     transformation matrix.
       
  1242 
       
  1243     See also \l {The Coordinate System} documentation.
       
  1244 
       
  1245     \section1 Clipping
       
  1246 
       
  1247     QPainter can clip any drawing operation to a rectangle, a region,
       
  1248     or a vector path. The current clip is available using the
       
  1249     functions clipRegion() and clipPath(). Whether paths or regions are
       
  1250     preferred (faster) depends on the underlying paintEngine(). For
       
  1251     example, the QImage paint engine prefers paths while the X11 paint
       
  1252     engine prefers regions. Setting a clip is done in the painters
       
  1253     logical coordinates.
       
  1254 
       
  1255     After QPainter's clipping, the paint device may also clip. For
       
  1256     example, most widgets clip away the pixels used by child widgets,
       
  1257     and most printers clip away an area near the edges of the paper.
       
  1258     This additional clipping is not reflected by the return value of
       
  1259     clipRegion() or hasClipping().
       
  1260 
       
  1261     \section1 Composition Modes
       
  1262     \target Composition Modes
       
  1263 
       
  1264     QPainter provides the CompositionMode enum which defines the
       
  1265     Porter-Duff rules for digital image compositing; it describes a
       
  1266     model for combining the pixels in one image, the source, with the
       
  1267     pixels in another image, the destination.
       
  1268 
       
  1269     The two most common forms of composition are \l
       
  1270     {QPainter::CompositionMode}{Source} and \l
       
  1271     {QPainter::CompositionMode}{SourceOver}.  \l
       
  1272     {QPainter::CompositionMode}{Source} is used to draw opaque objects
       
  1273     onto a paint device. In this mode, each pixel in the source
       
  1274     replaces the corresponding pixel in the destination. In \l
       
  1275     {QPainter::CompositionMode}{SourceOver} composition mode, the
       
  1276     source object is transparent and is drawn on top of the
       
  1277     destination.
       
  1278 
       
  1279     Note that composition transformation operates pixelwise. For that
       
  1280     reason, there is a difference between using the graphic primitive
       
  1281     itself and its bounding rectangle: The bounding rect contains
       
  1282     pixels with alpha == 0 (i.e the pixels surrounding the
       
  1283     primitive). These pixels will overwrite the other image's pixels,
       
  1284     affectively clearing those, while the primitive only overwrites
       
  1285     its own area.
       
  1286 
       
  1287     \table 100%
       
  1288     \row
       
  1289     \o \inlineimage qpainter-compositiondemo.png
       
  1290 
       
  1291     \o
       
  1292     \bold {Composition Modes Demo}
       
  1293 
       
  1294     The \l {demos/composition}{Composition Modes} demo, available in
       
  1295     Qt's demo directory, allows you to experiment with the various
       
  1296     composition modes and see the results immediately.
       
  1297 
       
  1298     \endtable
       
  1299 
       
  1300     \section1 Limitations
       
  1301     \target Limitations
       
  1302 
       
  1303     If you are using coordinates with Qt's raster-based paint engine, it is
       
  1304     important to note that, while coordinates greater than +/- 2\sup 15 can
       
  1305     be used, any painting performed with coordinates outside this range is not
       
  1306     guaranteed to be shown; the drawing may be clipped. This is due to the
       
  1307     use of \c{short int} in the implementation.
       
  1308 
       
  1309     The outlines generated by Qt's stroker are only an approximation when dealing
       
  1310     with curved shapes. It is in most cases impossible to represent the outline of
       
  1311     a bezier curve segment using another bezier curve segment, and so Qt approximates
       
  1312     the curve outlines by using several smaller curves. For performance reasons there
       
  1313     is a limit to how many curves Qt uses for these outlines, and thus when using
       
  1314     large pen widths or scales the outline error increases. To generate outlines with
       
  1315     smaller errors it is possible to use the QPainterPathStroker class, which has the
       
  1316     setCurveThreshold member function which let's the user specify the error tolerance.
       
  1317     Another workaround is to convert the paths to polygons first and then draw the
       
  1318     polygons instead.
       
  1319 
       
  1320     \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example},
       
  1321         {Drawing Utility Functions}
       
  1322 */
       
  1323 
       
  1324 /*!
       
  1325     \enum QPainter::RenderHint
       
  1326 
       
  1327     Renderhints are used to specify flags to QPainter that may or
       
  1328     may not be respected by any given engine.
       
  1329 
       
  1330     \value Antialiasing Indicates that the engine should antialias
       
  1331     edges of primitives if possible.
       
  1332 
       
  1333     \value TextAntialiasing Indicates that the engine should antialias
       
  1334     text if possible. To forcibly disable antialiasing for text, do not
       
  1335     use this hint. Instead, set QFont::NoAntialias on your font's style
       
  1336     strategy.
       
  1337 
       
  1338     \value SmoothPixmapTransform Indicates that the engine should use
       
  1339     a smooth pixmap transformation algorithm (such as bilinear) rather
       
  1340     than nearest neighbor.
       
  1341 
       
  1342     \value HighQualityAntialiasing An OpenGL-specific rendering hint
       
  1343     indicating that the engine should use fragment programs and offscreen
       
  1344     rendering for antialiasing.
       
  1345 
       
  1346     \value NonCosmeticDefaultPen The engine should interpret pens with a width
       
  1347     of 0 (which otherwise enables QPen::isCosmetic()) as being a non-cosmetic
       
  1348     pen with a width of 1.
       
  1349 
       
  1350     \sa renderHints(), setRenderHint(), {QPainter#Rendering
       
  1351     Quality}{Rendering Quality}, {Concentric Circles Example}
       
  1352 
       
  1353 */
       
  1354 
       
  1355 /*!
       
  1356     Constructs a painter.
       
  1357 
       
  1358     \sa begin(), end()
       
  1359 */
       
  1360 
       
  1361 QPainter::QPainter()
       
  1362     : d_ptr(new QPainterPrivate(this))
       
  1363 {
       
  1364 }
       
  1365 
       
  1366 /*!
       
  1367     \fn QPainter::QPainter(QPaintDevice *device)
       
  1368 
       
  1369     Constructs a painter that begins painting the paint \a device
       
  1370     immediately.
       
  1371 
       
  1372     This constructor is convenient for short-lived painters, e.g. in a
       
  1373     QWidget::paintEvent() and should be used only once. The
       
  1374     constructor calls begin() for you and the QPainter destructor
       
  1375     automatically calls end().
       
  1376 
       
  1377     Here's an example using begin() and end():
       
  1378     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 1
       
  1379 
       
  1380     The same example using this constructor:
       
  1381     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 2
       
  1382 
       
  1383     Since the constructor cannot provide feedback when the initialization
       
  1384     of the painter failed you should rather use begin() and end() to paint
       
  1385     on external devices, e.g. printers.
       
  1386 
       
  1387     \sa begin(), end()
       
  1388 */
       
  1389 
       
  1390 QPainter::QPainter(QPaintDevice *pd)
       
  1391     : d_ptr(0)
       
  1392 {
       
  1393     Q_ASSERT(pd != 0);
       
  1394     if (!QPainterPrivate::attachPainterPrivate(this, pd)) {
       
  1395         d_ptr.reset(new QPainterPrivate(this));
       
  1396         begin(pd);
       
  1397     }
       
  1398     Q_ASSERT(d_ptr);
       
  1399 }
       
  1400 
       
  1401 /*!
       
  1402     Destroys the painter.
       
  1403 */
       
  1404 QPainter::~QPainter()
       
  1405 {
       
  1406     d_ptr->inDestructor = true;
       
  1407     QT_TRY {
       
  1408         if (isActive())
       
  1409             end();
       
  1410         else if (d_ptr->refcount > 1)
       
  1411             d_ptr->detachPainterPrivate(this);
       
  1412     } QT_CATCH(...) {
       
  1413         // don't throw anything in the destructor.
       
  1414     }
       
  1415     if (d_ptr) {
       
  1416         // Make sure we haven't messed things up.
       
  1417         Q_ASSERT(d_ptr->inDestructor);
       
  1418         d_ptr->inDestructor = false;
       
  1419         Q_ASSERT(d_ptr->refcount == 1);
       
  1420         if (d_ptr->d_ptrs)
       
  1421             free(d_ptr->d_ptrs);
       
  1422     }
       
  1423 }
       
  1424 
       
  1425 /*!
       
  1426     Returns the paint device on which this painter is currently
       
  1427     painting, or 0 if the painter is not active.
       
  1428 
       
  1429     \sa isActive()
       
  1430 */
       
  1431 
       
  1432 QPaintDevice *QPainter::device() const
       
  1433 {
       
  1434     Q_D(const QPainter);
       
  1435     if (isActive() && d->engine->d_func()->currentClipWidget)
       
  1436         return d->engine->d_func()->currentClipWidget;
       
  1437     return d->original_device;
       
  1438 }
       
  1439 
       
  1440 /*!
       
  1441     Returns true if begin() has been called and end() has not yet been
       
  1442     called; otherwise returns false.
       
  1443 
       
  1444     \sa begin(), QPaintDevice::paintingActive()
       
  1445 */
       
  1446 
       
  1447 bool QPainter::isActive() const
       
  1448 {
       
  1449     Q_D(const QPainter);
       
  1450     return d->engine;
       
  1451 }
       
  1452 
       
  1453 /*!
       
  1454     Initializes the painters pen, background and font to the same as
       
  1455     the given \a widget. This function is called automatically when the
       
  1456     painter is opened on a QWidget.
       
  1457 
       
  1458     \sa begin(), {QPainter#Settings}{Settings}
       
  1459 */
       
  1460 void QPainter::initFrom(const QWidget *widget)
       
  1461 {
       
  1462     Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0");
       
  1463     Q_D(QPainter);
       
  1464     if (!d->engine) {
       
  1465         qWarning("QPainter::initFrom: Painter not active, aborted");
       
  1466         return;
       
  1467     }
       
  1468 
       
  1469     const QPalette &pal = widget->palette();
       
  1470     d->state->pen = QPen(pal.brush(widget->foregroundRole()), 0);
       
  1471     d->state->bgBrush = pal.brush(widget->backgroundRole());
       
  1472     d->state->deviceFont = QFont(widget->font(), const_cast<QWidget*> (widget));
       
  1473     d->state->font = d->state->deviceFont;
       
  1474     if (d->extended) {
       
  1475         d->extended->penChanged();
       
  1476     } else if (d->engine) {
       
  1477         d->engine->setDirty(QPaintEngine::DirtyPen);
       
  1478         d->engine->setDirty(QPaintEngine::DirtyBrush);
       
  1479         d->engine->setDirty(QPaintEngine::DirtyFont);
       
  1480     }
       
  1481     d->state->layoutDirection = widget->layoutDirection();
       
  1482 }
       
  1483 
       
  1484 
       
  1485 /*!
       
  1486     Saves the current painter state (pushes the state onto a stack). A
       
  1487     save() must be followed by a corresponding restore(); the end()
       
  1488     function unwinds the stack.
       
  1489 
       
  1490     \sa restore()
       
  1491 */
       
  1492 
       
  1493 void QPainter::save()
       
  1494 {
       
  1495 #ifdef QT_DEBUG_DRAW
       
  1496     if (qt_show_painter_debug_output)
       
  1497         printf("QPainter::save()\n");
       
  1498 #endif
       
  1499     Q_D(QPainter);
       
  1500     if (!d->engine) {
       
  1501         qWarning("QPainter::save: Painter not active");
       
  1502         return;
       
  1503     }
       
  1504 
       
  1505     if (d->extended) {
       
  1506         d->state = d->extended->createState(d->states.back());
       
  1507         d->extended->setState(d->state);
       
  1508     } else {
       
  1509         d->updateState(d->state);
       
  1510         d->state = new QPainterState(d->states.back());
       
  1511         d->engine->state = d->state;
       
  1512     }
       
  1513     d->states.push_back(d->state);
       
  1514 }
       
  1515 
       
  1516 /*!
       
  1517     Restores the current painter state (pops a saved state off the
       
  1518     stack).
       
  1519 
       
  1520     \sa save()
       
  1521 */
       
  1522 
       
  1523 void QPainter::restore()
       
  1524 {
       
  1525 #ifdef QT_DEBUG_DRAW
       
  1526     if (qt_show_painter_debug_output)
       
  1527         printf("QPainter::restore()\n");
       
  1528 #endif
       
  1529     Q_D(QPainter);
       
  1530     if (d->states.size()<=1) {
       
  1531         qWarning("QPainter::restore: Unbalanced save/restore");
       
  1532         return;
       
  1533     } else if (!d->engine) {
       
  1534         qWarning("QPainter::restore: Painter not active");
       
  1535         return;
       
  1536     }
       
  1537 
       
  1538     QPainterState *tmp = d->state;
       
  1539     d->states.pop_back();
       
  1540     d->state = d->states.back();
       
  1541     d->txinv = false;
       
  1542 
       
  1543     if (d->extended) {
       
  1544         d->checkEmulation();
       
  1545         d->extended->setState(d->state);
       
  1546         delete tmp;
       
  1547         return;
       
  1548     }
       
  1549 
       
  1550     // trigger clip update if the clip path/region has changed since
       
  1551     // last save
       
  1552     if (!d->state->clipInfo.isEmpty()
       
  1553         && (tmp->changeFlags & (QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipPath))) {
       
  1554         // reuse the tmp state to avoid any extra allocs...
       
  1555         tmp->dirtyFlags = QPaintEngine::DirtyClipPath;
       
  1556         tmp->clipOperation = Qt::NoClip;
       
  1557         tmp->clipPath = QPainterPath();
       
  1558         d->engine->updateState(*tmp);
       
  1559         // replay the list of clip states,
       
  1560         for (int i=0; i<d->state->clipInfo.size(); ++i) {
       
  1561             const QPainterClipInfo &info = d->state->clipInfo.at(i);
       
  1562             tmp->matrix = info.matrix;
       
  1563             tmp->matrix *= d->state->redirectionMatrix;
       
  1564             tmp->clipOperation = info.operation;
       
  1565             if (info.clipType == QPainterClipInfo::RectClip) {
       
  1566                 tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform;
       
  1567                 tmp->clipRegion = info.rect;
       
  1568             } else if (info.clipType == QPainterClipInfo::RegionClip) {
       
  1569                 tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform;
       
  1570                 tmp->clipRegion = info.region;
       
  1571             } else { // clipType == QPainterClipInfo::PathClip
       
  1572                 tmp->dirtyFlags = QPaintEngine::DirtyClipPath | QPaintEngine::DirtyTransform;
       
  1573                 tmp->clipPath = info.path;
       
  1574             }
       
  1575             d->engine->updateState(*tmp);
       
  1576         }
       
  1577 
       
  1578 
       
  1579         //Since we've updated the clip region anyway, pretend that the clip path hasn't changed:
       
  1580         d->state->dirtyFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
       
  1581         tmp->changeFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
       
  1582         tmp->changeFlags |= QPaintEngine::DirtyTransform;
       
  1583     }
       
  1584 
       
  1585     d->updateState(d->state);
       
  1586     delete tmp;
       
  1587 }
       
  1588 
       
  1589 
       
  1590 /*!
       
  1591 
       
  1592     \fn bool QPainter::begin(QPaintDevice *device)
       
  1593 
       
  1594     Begins painting the paint \a device and returns true if
       
  1595     successful; otherwise returns false.
       
  1596 
       
  1597     Notice that all painter settings (setPen(), setBrush() etc.) are reset
       
  1598     to default values when begin() is called.
       
  1599 
       
  1600     The errors that can occur are serious problems, such as these:
       
  1601 
       
  1602     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 3
       
  1603 
       
  1604     Note that most of the time, you can use one of the constructors
       
  1605     instead of begin(), and that end() is automatically done at
       
  1606     destruction.
       
  1607 
       
  1608     \warning A paint device can only be painted by one painter at a
       
  1609     time.
       
  1610 
       
  1611     \warning Painting on a QImage with the format
       
  1612     QImage::Format_Indexed8 is not supported.
       
  1613 
       
  1614     \sa end(), QPainter()
       
  1615 */
       
  1616 
       
  1617 static inline void qt_cleanup_painter_state(QPainterPrivate *d)
       
  1618 {
       
  1619     d->states.clear();
       
  1620     delete d->state;
       
  1621     d->state = 0;
       
  1622     d->engine = 0;
       
  1623     d->device = 0;
       
  1624 }
       
  1625 
       
  1626 bool QPainter::begin(QPaintDevice *pd)
       
  1627 {
       
  1628     Q_ASSERT(pd);
       
  1629 
       
  1630     if (pd->painters > 0) {
       
  1631         qWarning("QPainter::begin: A paint device can only be painted by one painter at a time.");
       
  1632         return false;
       
  1633     }
       
  1634 
       
  1635     if (d_ptr->engine) {
       
  1636         qWarning("QPainter::begin: Painter already active");
       
  1637         return false;
       
  1638     }
       
  1639 
       
  1640     if (QPainterPrivate::attachPainterPrivate(this, pd))
       
  1641         return true;
       
  1642 
       
  1643     Q_D(QPainter);
       
  1644 
       
  1645     d->helper_device = pd;
       
  1646     d->original_device = pd;
       
  1647     QPaintDevice *rpd = 0;
       
  1648 
       
  1649     QPoint redirectionOffset;
       
  1650     // We know for sure that redirection is broken when the widget is inside
       
  1651     // its paint event, so it's safe to use our hard-coded redirection. However,
       
  1652     // there IS one particular case we still need to support, and that's
       
  1653     // when people call QPainter::setRedirected in the widget's paint event right
       
  1654     // before any painter is created (or QPainter::begin is called). In that
       
  1655     // particular case our hard-coded redirection is restored and the redirection
       
  1656     // is retrieved from QPainter::redirected (as before).
       
  1657     if (pd->devType() == QInternal::Widget)
       
  1658         rpd = static_cast<QWidget *>(pd)->d_func()->redirected(&redirectionOffset);
       
  1659 
       
  1660     if (!rpd)
       
  1661         rpd = redirected(pd, &redirectionOffset);
       
  1662 
       
  1663     if (rpd)
       
  1664         pd = rpd;
       
  1665 
       
  1666 #ifdef QT_DEBUG_DRAW
       
  1667     if (qt_show_painter_debug_output)
       
  1668         printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType());
       
  1669 #endif
       
  1670 
       
  1671     if (pd->devType() == QInternal::Pixmap)
       
  1672         static_cast<QPixmap *>(pd)->detach();
       
  1673     else if (pd->devType() == QInternal::Image)
       
  1674         static_cast<QImage *>(pd)->detach();
       
  1675 
       
  1676     d->engine = pd->paintEngine();
       
  1677 
       
  1678     if (!d->engine) {
       
  1679         qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType());
       
  1680         return false;
       
  1681     }
       
  1682 
       
  1683     d->device = pd;
       
  1684 
       
  1685     d->extended = d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0;
       
  1686     if (d->emulationEngine)
       
  1687         d->emulationEngine->real_engine = d->extended;
       
  1688 
       
  1689     // Setup new state...
       
  1690     Q_ASSERT(!d->state);
       
  1691     d->state = d->extended ? d->extended->createState(0) : new QPainterState;
       
  1692     d->state->painter = this;
       
  1693     d->states.push_back(d->state);
       
  1694 
       
  1695     d->state->redirectionMatrix.translate(-redirectionOffset.x(), -redirectionOffset.y());
       
  1696     d->state->brushOrigin = QPointF();
       
  1697 
       
  1698     // Slip a painter state into the engine before we do any other operations
       
  1699     if (d->extended)
       
  1700         d->extended->setState(d->state);
       
  1701     else
       
  1702         d->engine->state = d->state;
       
  1703 
       
  1704     switch (pd->devType()) {
       
  1705         case QInternal::Widget:
       
  1706         {
       
  1707             const QWidget *widget = static_cast<const QWidget *>(pd);
       
  1708             Q_ASSERT(widget);
       
  1709 
       
  1710             const bool paintOutsidePaintEvent = widget->testAttribute(Qt::WA_PaintOutsidePaintEvent);
       
  1711             const bool inPaintEvent = widget->testAttribute(Qt::WA_WState_InPaintEvent);
       
  1712             if(!d->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
       
  1713                 && !paintOutsidePaintEvent && !inPaintEvent) {
       
  1714                 qWarning("QPainter::begin: Widget painting can only begin as a "
       
  1715                          "result of a paintEvent");
       
  1716                 qt_cleanup_painter_state(d);
       
  1717                 return false;
       
  1718             }
       
  1719 
       
  1720             // Adjust offset for alien widgets painting outside the paint event.
       
  1721             if (!inPaintEvent && paintOutsidePaintEvent && !widget->internalWinId()
       
  1722                 && widget->testAttribute(Qt::WA_WState_Created)) {
       
  1723                 const QPoint offset = widget->mapTo(widget->nativeParentWidget(), QPoint());
       
  1724                 d->state->redirectionMatrix.translate(offset.x(), offset.y());
       
  1725             }
       
  1726             break;
       
  1727         }
       
  1728         case QInternal::Pixmap:
       
  1729         {
       
  1730             QPixmap *pm = static_cast<QPixmap *>(pd);
       
  1731             Q_ASSERT(pm);
       
  1732             if (pm->isNull()) {
       
  1733                 qWarning("QPainter::begin: Cannot paint on a null pixmap");
       
  1734                 qt_cleanup_painter_state(d);
       
  1735                 return false;
       
  1736             }
       
  1737 
       
  1738             if (pm->depth() == 1) {
       
  1739                 d->state->pen = QPen(Qt::color1);
       
  1740                 d->state->brush = QBrush(Qt::color0);
       
  1741             }
       
  1742             break;
       
  1743         }
       
  1744         case QInternal::Image:
       
  1745         {
       
  1746             QImage *img = static_cast<QImage *>(pd);
       
  1747             Q_ASSERT(img);
       
  1748             if (img->isNull()) {
       
  1749                 qWarning("QPainter::begin: Cannot paint on a null image");
       
  1750                 qt_cleanup_painter_state(d);
       
  1751                 return false;
       
  1752             } else if (img->format() == QImage::Format_Indexed8) {
       
  1753                 // Painting on indexed8 images is not supported.
       
  1754                 qWarning("QPainter::begin: Cannot paint on an image with the QImage::Format_Indexed8 format");
       
  1755                 qt_cleanup_painter_state(d);
       
  1756                 return false;
       
  1757             }
       
  1758             if (img->depth() == 1) {
       
  1759                 d->state->pen = QPen(Qt::color1);
       
  1760                 d->state->brush = QBrush(Qt::color0);
       
  1761             }
       
  1762             break;
       
  1763         }
       
  1764         default:
       
  1765             break;
       
  1766     }
       
  1767     if (d->state->ww == 0) // For compat with 3.x painter defaults
       
  1768         d->state->ww = d->state->wh = d->state->vw = d->state->vh = 1024;
       
  1769 
       
  1770     d->engine->setPaintDevice(pd);
       
  1771 
       
  1772     bool begun = d->engine->begin(pd);
       
  1773     if (!begun) {
       
  1774         qWarning("QPainter::begin(): Returned false");
       
  1775         if (d->engine->isActive()) {
       
  1776             end();
       
  1777         } else {
       
  1778             qt_cleanup_painter_state(d);
       
  1779         }
       
  1780         return false;
       
  1781     } else {
       
  1782         d->engine->setActive(begun);
       
  1783     }
       
  1784 
       
  1785     // Copy painter properties from original paint device,
       
  1786     // required for QPixmap::grabWidget()
       
  1787     if (d->original_device->devType() == QInternal::Widget) {
       
  1788         QWidget *widget = static_cast<QWidget *>(d->original_device);
       
  1789         initFrom(widget);
       
  1790     } else {
       
  1791         d->state->layoutDirection = QApplication::layoutDirection();
       
  1792         // make sure we have a font compatible with the paintdevice
       
  1793         d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device());
       
  1794     }
       
  1795 
       
  1796     QRect systemRect = d->engine->systemRect();
       
  1797     if (!systemRect.isEmpty()) {
       
  1798         d->state->ww = d->state->vw = systemRect.width();
       
  1799         d->state->wh = d->state->vh = systemRect.height();
       
  1800     } else {
       
  1801         d->state->ww = d->state->vw = pd->metric(QPaintDevice::PdmWidth);
       
  1802         d->state->wh = d->state->vh = pd->metric(QPaintDevice::PdmHeight);
       
  1803     }
       
  1804 
       
  1805     const QPoint coordinateOffset = d->engine->coordinateOffset();
       
  1806     d->state->redirectionMatrix.translate(-coordinateOffset.x(), -coordinateOffset.y());
       
  1807 
       
  1808     Q_ASSERT(d->engine->isActive());
       
  1809 
       
  1810     if (!d->state->redirectionMatrix.isIdentity())
       
  1811         d->updateMatrix();
       
  1812 
       
  1813     Q_ASSERT(d->engine->isActive());
       
  1814     d->state->renderHints = QPainter::TextAntialiasing;
       
  1815     ++d->device->painters;
       
  1816 
       
  1817     d->state->emulationSpecifier = 0;
       
  1818 
       
  1819     return true;
       
  1820 }
       
  1821 
       
  1822 /*!
       
  1823     Ends painting. Any resources used while painting are released. You
       
  1824     don't normally need to call this since it is called by the
       
  1825     destructor.
       
  1826 
       
  1827     Returns true if the painter is no longer active; otherwise returns false.
       
  1828 
       
  1829     \sa begin(), isActive()
       
  1830 */
       
  1831 
       
  1832 bool QPainter::end()
       
  1833 {
       
  1834 #ifdef QT_DEBUG_DRAW
       
  1835     if (qt_show_painter_debug_output)
       
  1836         printf("QPainter::end()\n");
       
  1837 #endif
       
  1838     Q_D(QPainter);
       
  1839 
       
  1840     if (!d->engine) {
       
  1841         qWarning("QPainter::end: Painter not active, aborted");
       
  1842         qt_cleanup_painter_state(d);
       
  1843         return false;
       
  1844     }
       
  1845 
       
  1846     if (d->refcount > 1) {
       
  1847         d->detachPainterPrivate(this);
       
  1848         return true;
       
  1849     }
       
  1850 
       
  1851     bool ended = true;
       
  1852 
       
  1853     if (d->engine->isActive()) {
       
  1854         ended = d->engine->end();
       
  1855         d->updateState(0);
       
  1856 
       
  1857         --d->device->painters;
       
  1858         if (d->device->painters == 0) {
       
  1859             d->engine->setPaintDevice(0);
       
  1860             d->engine->setActive(false);
       
  1861         }
       
  1862     }
       
  1863 
       
  1864     if (d->states.size() > 1) {
       
  1865         qWarning("QPainter::end: Painter ended with %d saved states",
       
  1866                  d->states.size());
       
  1867     }
       
  1868 
       
  1869     if (d->engine->autoDestruct()) {
       
  1870         delete d->engine;
       
  1871     }
       
  1872 
       
  1873     if (d->emulationEngine) {
       
  1874         delete d->emulationEngine;
       
  1875         d->emulationEngine = 0;
       
  1876     }
       
  1877 
       
  1878     if (d->extended) {
       
  1879         d->extended = 0;
       
  1880     }
       
  1881 
       
  1882     qt_cleanup_painter_state(d);
       
  1883 
       
  1884     return ended;
       
  1885 }
       
  1886 
       
  1887 
       
  1888 /*!
       
  1889     Returns the paint engine that the painter is currently operating
       
  1890     on if the painter is active; otherwise 0.
       
  1891 
       
  1892     \sa isActive()
       
  1893 */
       
  1894 QPaintEngine *QPainter::paintEngine() const
       
  1895 {
       
  1896     Q_D(const QPainter);
       
  1897     return d->engine;
       
  1898 }
       
  1899 
       
  1900 /*!
       
  1901     \since 4.6
       
  1902 
       
  1903     Flushes the painting pipeline and prepares for the user issuing
       
  1904     commands directly to the underlying graphics context. Must be
       
  1905     followed by a call to endNativePainting().
       
  1906 
       
  1907     Here is an example that shows intermixing of painter commands
       
  1908     and raw OpenGL commands:
       
  1909 
       
  1910     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21
       
  1911 
       
  1912     \sa endNativePainting()
       
  1913 */
       
  1914 void QPainter::beginNativePainting()
       
  1915 {
       
  1916     Q_D(QPainter);
       
  1917     if (!d->engine) {
       
  1918         qWarning("QPainter::beginNativePainting: Painter not active");
       
  1919         return;
       
  1920     }
       
  1921 
       
  1922     if (d->extended)
       
  1923         d->extended->beginNativePainting();
       
  1924 }
       
  1925 
       
  1926 /*!
       
  1927     \since 4.6
       
  1928 
       
  1929     Restores the painter after manually issuing native painting commands.
       
  1930     Lets the painter restore any native state that it relies on before
       
  1931     calling any other painter commands.
       
  1932 
       
  1933     \sa beginNativePainting()
       
  1934 */
       
  1935 void QPainter::endNativePainting()
       
  1936 {
       
  1937     Q_D(const QPainter);
       
  1938     if (!d->engine) {
       
  1939         qWarning("QPainter::beginNativePainting: Painter not active");
       
  1940         return;
       
  1941     }
       
  1942 
       
  1943     if (d->extended)
       
  1944         d->extended->endNativePainting();
       
  1945     else
       
  1946         d->engine->syncState();
       
  1947 }
       
  1948 
       
  1949 /*!
       
  1950     Returns the font metrics for the painter if the painter is
       
  1951     active. Otherwise, the return value is undefined.
       
  1952 
       
  1953     \sa font(), isActive(), {QPainter#Settings}{Settings}
       
  1954 */
       
  1955 
       
  1956 QFontMetrics QPainter::fontMetrics() const
       
  1957 {
       
  1958     Q_D(const QPainter);
       
  1959     if (!d->engine) {
       
  1960         qWarning("QPainter::fontMetrics: Painter not active");
       
  1961         return QFontMetrics(QFont());
       
  1962     }
       
  1963     return QFontMetrics(d->state->font);
       
  1964 }
       
  1965 
       
  1966 
       
  1967 /*!
       
  1968     Returns the font info for the painter if the painter is
       
  1969     active. Otherwise, the return value is undefined.
       
  1970 
       
  1971     \sa font(), isActive(), {QPainter#Settings}{Settings}
       
  1972 */
       
  1973 
       
  1974 QFontInfo QPainter::fontInfo() const
       
  1975 {
       
  1976     Q_D(const QPainter);
       
  1977     if (!d->engine) {
       
  1978         qWarning("QPainter::fontInfo: Painter not active");
       
  1979         return QFontInfo(QFont());
       
  1980     }
       
  1981     return QFontInfo(d->state->font);
       
  1982 }
       
  1983 
       
  1984 /*!
       
  1985     \since 4.2
       
  1986 
       
  1987     Returns the opacity of the painter. The default value is
       
  1988     1.
       
  1989 */
       
  1990 
       
  1991 qreal QPainter::opacity() const
       
  1992 {
       
  1993     Q_D(const QPainter);
       
  1994     if (!d->engine) {
       
  1995         qWarning("QPainter::opacity: Painter not active");
       
  1996         return 1.0;
       
  1997     }
       
  1998     return d->state->opacity;
       
  1999 }
       
  2000 
       
  2001 /*!
       
  2002     \since 4.2
       
  2003 
       
  2004     Sets the opacity of the painter to \a opacity. The value should
       
  2005     be in the range 0.0 to 1.0, where 0.0 is fully transparent and
       
  2006     1.0 is fully opaque.
       
  2007 
       
  2008     Opacity set on the painter will apply to all drawing operations
       
  2009     individually.
       
  2010 */
       
  2011 
       
  2012 void QPainter::setOpacity(qreal opacity)
       
  2013 {
       
  2014     Q_D(QPainter);
       
  2015 
       
  2016     if (!d->engine) {
       
  2017         qWarning("QPainter::setOpacity: Painter not active");
       
  2018         return;
       
  2019     }
       
  2020 
       
  2021     opacity = qMin(qreal(1), qMax(qreal(0), opacity));
       
  2022 
       
  2023     if (opacity == d->state->opacity)
       
  2024         return;
       
  2025 
       
  2026     d->state->opacity = opacity;
       
  2027 
       
  2028     if (d->extended)
       
  2029         d->extended->opacityChanged();
       
  2030     else
       
  2031         d->state->dirtyFlags |= QPaintEngine::DirtyOpacity;
       
  2032 }
       
  2033 
       
  2034 
       
  2035 /*!
       
  2036     Returns the currently set brush origin.
       
  2037 
       
  2038     \sa setBrushOrigin(), {QPainter#Settings}{Settings}
       
  2039 */
       
  2040 
       
  2041 QPoint QPainter::brushOrigin() const
       
  2042 {
       
  2043     Q_D(const QPainter);
       
  2044     if (!d->engine) {
       
  2045         qWarning("QPainter::brushOrigin: Painter not active");
       
  2046         return QPoint();
       
  2047     }
       
  2048     return QPointF(d->state->brushOrigin).toPoint();
       
  2049 }
       
  2050 
       
  2051 /*!
       
  2052     \fn void QPainter::setBrushOrigin(const QPointF &position)
       
  2053 
       
  2054     Sets the brush origin to \a position.
       
  2055 
       
  2056     The brush origin specifies the (0, 0) coordinate of the painter's
       
  2057     brush.
       
  2058 
       
  2059     Note that while the brushOrigin() was necessary to adopt the
       
  2060     parent's background for a widget in Qt 3, this is no longer the
       
  2061     case since the Qt 4 painter doesn't paint the background unless
       
  2062     you explicitly tell it to do so by setting the widget's \l
       
  2063     {QWidget::autoFillBackground}{autoFillBackground} property to
       
  2064     true.
       
  2065 
       
  2066     \sa brushOrigin(), {QPainter#Settings}{Settings}
       
  2067 */
       
  2068 
       
  2069 void QPainter::setBrushOrigin(const QPointF &p)
       
  2070 {
       
  2071     Q_D(QPainter);
       
  2072 #ifdef QT_DEBUG_DRAW
       
  2073     if (qt_show_painter_debug_output)
       
  2074         printf("QPainter::setBrushOrigin(), (%.2f,%.2f)\n", p.x(), p.y());
       
  2075 #endif
       
  2076 
       
  2077     if (!d->engine) {
       
  2078         qWarning("QPainter::setBrushOrigin: Painter not active");
       
  2079         return;
       
  2080     }
       
  2081 
       
  2082     d->state->brushOrigin = p;
       
  2083 
       
  2084     if (d->extended) {
       
  2085         d->extended->brushOriginChanged();
       
  2086         return;
       
  2087     }
       
  2088 
       
  2089     d->state->dirtyFlags |= QPaintEngine::DirtyBrushOrigin;
       
  2090 }
       
  2091 
       
  2092 /*!
       
  2093     \fn void QPainter::setBrushOrigin(const QPoint &position)
       
  2094     \overload
       
  2095 
       
  2096     Sets the brush's origin to the given \a position.
       
  2097 */
       
  2098 
       
  2099 /*!
       
  2100     \fn void QPainter::setBrushOrigin(int x, int y)
       
  2101 
       
  2102     \overload
       
  2103 
       
  2104     Sets the brush's origin to point (\a x, \a y).
       
  2105 */
       
  2106 
       
  2107 /*!
       
  2108     \enum QPainter::CompositionMode
       
  2109 
       
  2110     Defines the modes supported for digital image compositing.
       
  2111     Composition modes are used to specify how the pixels in one image,
       
  2112     the source, are merged with the pixel in another image, the
       
  2113     destination.
       
  2114 
       
  2115     Please note that the bitwise raster operation modes, denoted with
       
  2116     a RasterOp prefix, are only natively supported in the X11 and
       
  2117     raster paint engines. This means that the only way to utilize
       
  2118     these modes on the Mac is via a QImage. The RasterOp denoted blend
       
  2119     modes are \e not supported for pens and brushes with alpha
       
  2120     components. Also, turning on the QPainter::Antialiasing render
       
  2121     hint will effectively disable the RasterOp modes.
       
  2122 
       
  2123 
       
  2124      \image qpainter-compositionmode1.png
       
  2125      \image qpainter-compositionmode2.png
       
  2126 
       
  2127     The most common type is SourceOver (often referred to as just
       
  2128     alpha blending) where the source pixel is blended on top of the
       
  2129     destination pixel in such a way that the alpha component of the
       
  2130     source defines the translucency of the pixel.
       
  2131 
       
  2132     When the paint device is a QImage, the image format must be set to
       
  2133     \l {QImage::Format}{Format_ARGB32Premultiplied} or
       
  2134     \l {QImage::Format}{Format_ARGB32} for the composition modes to have
       
  2135     any effect. For performance the premultiplied version is the preferred
       
  2136     format.
       
  2137 
       
  2138     When a composition mode is set it applies to all painting
       
  2139     operator, pens, brushes, gradients and pixmap/image drawing.
       
  2140 
       
  2141     \value CompositionMode_SourceOver This is the default mode. The
       
  2142     alpha of the source is used to blend the pixel on top of the
       
  2143     destination.
       
  2144 
       
  2145     \value CompositionMode_DestinationOver The alpha of the
       
  2146     destination is used to blend it on top of the source pixels. This
       
  2147     mode is the inverse of CompositionMode_SourceOver.
       
  2148 
       
  2149     \value CompositionMode_Clear The pixels in the destination are
       
  2150     cleared (set to fully transparent) independent of the source.
       
  2151 
       
  2152     \value CompositionMode_Source The output is the source
       
  2153     pixel. (This means a basic copy operation and is identical to
       
  2154     SourceOver when the source pixel is opaque).
       
  2155 
       
  2156     \value CompositionMode_Destination The output is the destination
       
  2157     pixel. This means that the blending has no effect. This mode is
       
  2158     the inverse of CompositionMode_Source.
       
  2159 
       
  2160     \value CompositionMode_SourceIn The output is the source, where
       
  2161     the alpha is reduced by that of the destination.
       
  2162 
       
  2163     \value CompositionMode_DestinationIn The output is the
       
  2164     destination, where the alpha is reduced by that of the
       
  2165     source. This mode is the inverse of CompositionMode_SourceIn.
       
  2166 
       
  2167     \value CompositionMode_SourceOut The output is the source, where
       
  2168     the alpha is reduced by the inverse of destination.
       
  2169 
       
  2170     \value CompositionMode_DestinationOut The output is the
       
  2171     destination, where the alpha is reduced by the inverse of the
       
  2172     source. This mode is the inverse of CompositionMode_SourceOut.
       
  2173 
       
  2174     \value CompositionMode_SourceAtop The source pixel is blended on
       
  2175     top of the destination, with the alpha of the source pixel reduced
       
  2176     by the alpha of the destination pixel.
       
  2177 
       
  2178     \value CompositionMode_DestinationAtop The destination pixel is
       
  2179     blended on top of the source, with the alpha of the destination
       
  2180     pixel is reduced by the alpha of the destination pixel. This mode
       
  2181     is the inverse of CompositionMode_SourceAtop.
       
  2182 
       
  2183     \value CompositionMode_Xor The source, whose alpha is reduced with
       
  2184     the inverse of the destination alpha, is merged with the
       
  2185     destination, whose alpha is reduced by the inverse of the source
       
  2186     alpha. CompositionMode_Xor is not the same as the bitwise Xor.
       
  2187 
       
  2188     \value CompositionMode_Plus Both the alpha and color of the source
       
  2189     and destination pixels are added together.
       
  2190 
       
  2191     \value CompositionMode_Multiply The output is the source color
       
  2192     multiplied by the destination. Multiplying a color with white
       
  2193     leaves the color unchanged, while multiplying a color
       
  2194     with black produces black.
       
  2195 
       
  2196     \value CompositionMode_Screen The source and destination colors
       
  2197     are inverted and then multiplied. Screening a color with white
       
  2198     produces white, whereas screening a color with black leaves the
       
  2199     color unchanged.
       
  2200 
       
  2201     \value CompositionMode_Overlay Multiplies or screens the colors
       
  2202     depending on the destination color. The destination color is mixed
       
  2203     with the source color to reflect the lightness or darkness of the
       
  2204     destination.
       
  2205 
       
  2206     \value CompositionMode_Darken The darker of the source and
       
  2207     destination colors is selected.
       
  2208 
       
  2209     \value CompositionMode_Lighten The lighter of the source and
       
  2210     destination colors is selected.
       
  2211 
       
  2212     \value CompositionMode_ColorDodge The destination color is
       
  2213     brightened to reflect the source color. A black source color
       
  2214     leaves the destination color unchanged.
       
  2215 
       
  2216     \value CompositionMode_ColorBurn The destination color is darkened
       
  2217     to reflect the source color. A white source color leaves the
       
  2218     destination color unchanged.
       
  2219 
       
  2220     \value CompositionMode_HardLight Multiplies or screens the colors
       
  2221     depending on the source color. A light source color will lighten
       
  2222     the destination color, whereas a dark source color will darken the
       
  2223     destination color.
       
  2224 
       
  2225     \value CompositionMode_SoftLight Darkens or lightens the colors
       
  2226     depending on the source color. Similar to
       
  2227     CompositionMode_HardLight.
       
  2228 
       
  2229     \value CompositionMode_Difference Subtracts the darker of the
       
  2230     colors from the lighter.  Painting with white inverts the
       
  2231     destination color, whereas painting with black leaves the
       
  2232     destination color unchanged.
       
  2233 
       
  2234     \value CompositionMode_Exclusion Similar to
       
  2235     CompositionMode_Difference, but with a lower contrast. Painting
       
  2236     with white inverts the destination color, whereas painting with
       
  2237     black leaves the destination color unchanged.
       
  2238 
       
  2239     \value RasterOp_SourceOrDestination Does a bitwise OR operation on
       
  2240     the source and destination pixels (src OR dst).
       
  2241 
       
  2242     \value RasterOp_SourceAndDestination Does a bitwise AND operation
       
  2243     on the source and destination pixels (src AND dst).
       
  2244 
       
  2245     \value RasterOp_SourceXorDestination Does a bitwise XOR operation
       
  2246     on the source and destination pixels (src XOR dst).
       
  2247 
       
  2248     \value RasterOp_NotSourceAndNotDestination Does a bitwise NOR
       
  2249     operation on the source and destination pixels ((NOT src) AND (NOT
       
  2250     dst)).
       
  2251 
       
  2252     \value RasterOp_NotSourceOrNotDestination Does a bitwise NAND
       
  2253     operation on the source and destination pixels ((NOT src) OR (NOT
       
  2254     dst)).
       
  2255 
       
  2256     \value RasterOp_NotSourceXorDestination Does a bitwise operation
       
  2257     where the source pixels are inverted and then XOR'ed with the
       
  2258     destination ((NOT src) XOR dst).
       
  2259 
       
  2260     \value RasterOp_NotSource Does a bitwise operation where the
       
  2261     source pixels are inverted (NOT src).
       
  2262 
       
  2263     \value RasterOp_NotSourceAndDestination Does a bitwise operation
       
  2264     where the source is inverted and then AND'ed with the destination
       
  2265     ((NOT src) AND dst).
       
  2266 
       
  2267     \value RasterOp_SourceAndNotDestination Does a bitwise operation
       
  2268     where the source is AND'ed with the inverted destination pixels
       
  2269     (src AND (NOT dst)).
       
  2270 
       
  2271     \sa compositionMode(), setCompositionMode(), {QPainter#Composition
       
  2272     Modes}{Composition Modes}, {Image Composition Example}
       
  2273 */
       
  2274 
       
  2275 /*!
       
  2276     Sets the composition mode to the given \a mode.
       
  2277 
       
  2278     \warning You can only set the composition mode for QPainter
       
  2279     objects that operates on a QImage.
       
  2280 
       
  2281     \sa compositionMode()
       
  2282 */
       
  2283 void QPainter::setCompositionMode(CompositionMode mode)
       
  2284 {
       
  2285     Q_D(QPainter);
       
  2286     if (!d->engine) {
       
  2287         qWarning("QPainter::setCompositionMode: Painter not active");
       
  2288         return;
       
  2289     }
       
  2290     if (d->extended) {
       
  2291         d->state->composition_mode = mode;
       
  2292         d->extended->compositionModeChanged();
       
  2293         return;
       
  2294     }
       
  2295 
       
  2296     if (mode >= QPainter::RasterOp_SourceOrDestination) {
       
  2297         if (!d->engine->hasFeature(QPaintEngine::RasterOpModes)) {
       
  2298             qWarning("QPainter::setCompositionMode: "
       
  2299                      "Raster operation modes not supported on device");
       
  2300             return;
       
  2301         }
       
  2302     } else if (mode >= QPainter::CompositionMode_Plus) {
       
  2303         if (!d->engine->hasFeature(QPaintEngine::BlendModes)) {
       
  2304             qWarning("QPainter::setCompositionMode: "
       
  2305                      "Blend modes not supported on device");
       
  2306             return;
       
  2307         }
       
  2308     } else if (!d->engine->hasFeature(QPaintEngine::PorterDuff)) {
       
  2309         if (mode != CompositionMode_Source && mode != CompositionMode_SourceOver) {
       
  2310             qWarning("QPainter::setCompositionMode: "
       
  2311                      "PorterDuff modes not supported on device");
       
  2312             return;
       
  2313         }
       
  2314     }
       
  2315 
       
  2316     d->state->composition_mode = mode;
       
  2317     d->state->dirtyFlags |= QPaintEngine::DirtyCompositionMode;
       
  2318 }
       
  2319 
       
  2320 /*!
       
  2321   Returns the current composition mode.
       
  2322 
       
  2323   \sa CompositionMode, setCompositionMode()
       
  2324 */
       
  2325 QPainter::CompositionMode QPainter::compositionMode() const
       
  2326 {
       
  2327     Q_D(const QPainter);
       
  2328     if (!d->engine) {
       
  2329         qWarning("QPainter::compositionMode: Painter not active");
       
  2330         return QPainter::CompositionMode_SourceOver;
       
  2331     }
       
  2332     return d->state->composition_mode;
       
  2333 }
       
  2334 
       
  2335 /*!
       
  2336     Returns the current background brush.
       
  2337 
       
  2338     \sa setBackground(), {QPainter#Settings}{Settings}
       
  2339 */
       
  2340 
       
  2341 const QBrush &QPainter::background() const
       
  2342 {
       
  2343     Q_D(const QPainter);
       
  2344     if (!d->engine) {
       
  2345         qWarning("QPainter::background: Painter not active");
       
  2346         return d->fakeState()->brush;
       
  2347     }
       
  2348     return d->state->bgBrush;
       
  2349 }
       
  2350 
       
  2351 
       
  2352 /*!
       
  2353     Returns true if clipping has been set; otherwise returns false.
       
  2354 
       
  2355     \sa setClipping(), {QPainter#Clipping}{Clipping}
       
  2356 */
       
  2357 
       
  2358 bool QPainter::hasClipping() const
       
  2359 {
       
  2360     Q_D(const QPainter);
       
  2361     if (!d->engine) {
       
  2362         qWarning("QPainter::hasClipping: Painter not active");
       
  2363         return false;
       
  2364     }
       
  2365     return d->state->clipEnabled && d->state->clipOperation != Qt::NoClip;
       
  2366 }
       
  2367 
       
  2368 
       
  2369 /*!
       
  2370     Enables clipping if  \a enable is true, or disables clipping if  \a
       
  2371     enable is false.
       
  2372 
       
  2373     \sa hasClipping(), {QPainter#Clipping}{Clipping}
       
  2374 */
       
  2375 
       
  2376 void QPainter::setClipping(bool enable)
       
  2377 {
       
  2378     Q_D(QPainter);
       
  2379 #ifdef QT_DEBUG_DRAW
       
  2380     if (qt_show_painter_debug_output)
       
  2381         printf("QPainter::setClipping(), enable=%s, was=%s\n",
       
  2382                enable ? "on" : "off",
       
  2383                hasClipping() ? "on" : "off");
       
  2384 #endif
       
  2385     if (!d->engine) {
       
  2386         qWarning("QPainter::setClipping: Painter not active, state will be reset by begin");
       
  2387         return;
       
  2388     }
       
  2389 
       
  2390     if (hasClipping() == enable)
       
  2391         return;
       
  2392 
       
  2393     // we can't enable clipping if we don't have a clip
       
  2394     if (enable
       
  2395         && (d->state->clipInfo.isEmpty() || d->state->clipInfo.last().operation == Qt::NoClip))
       
  2396         return;
       
  2397     d->state->clipEnabled = enable;
       
  2398 
       
  2399     if (d->extended) {
       
  2400         d->extended->clipEnabledChanged();
       
  2401         return;
       
  2402     }
       
  2403 
       
  2404     d->state->dirtyFlags |= QPaintEngine::DirtyClipEnabled;
       
  2405     d->updateState(d->state);
       
  2406 }
       
  2407 
       
  2408 
       
  2409 /*!
       
  2410     Returns the currently set clip region. Note that the clip region
       
  2411     is given in logical coordinates.
       
  2412 
       
  2413     \warning QPainter does not store the combined clip explicitly as
       
  2414     this is handled by the underlying QPaintEngine, so the path is
       
  2415     recreated on demand and transformed to the current logical
       
  2416     coordinate system. This is potentially an expensive operation.
       
  2417 
       
  2418     \sa setClipRegion(), clipPath(), setClipping()
       
  2419 */
       
  2420 
       
  2421 QRegion QPainter::clipRegion() const
       
  2422 {
       
  2423     Q_D(const QPainter);
       
  2424     if (!d->engine) {
       
  2425         qWarning("QPainter::clipRegion: Painter not active");
       
  2426         return QRegion();
       
  2427     }
       
  2428 
       
  2429     QRegion region;
       
  2430     bool lastWasNothing = true;
       
  2431 
       
  2432     if (!d->txinv)
       
  2433         const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
       
  2434 
       
  2435     // ### Falcon: Use QPainterPath
       
  2436     for (int i=0; i<d->state->clipInfo.size(); ++i) {
       
  2437         const QPainterClipInfo &info = d->state->clipInfo.at(i);
       
  2438         switch (info.clipType) {
       
  2439 
       
  2440         case QPainterClipInfo::RegionClip: {
       
  2441             QTransform matrix = (info.matrix * d->invMatrix);
       
  2442             if (lastWasNothing) {
       
  2443                 region = info.region * matrix;
       
  2444                 lastWasNothing = false;
       
  2445                 continue;
       
  2446             }
       
  2447             if (info.operation == Qt::IntersectClip)
       
  2448                 region &= info.region * matrix;
       
  2449             else if (info.operation == Qt::UniteClip)
       
  2450                 region |= info.region * matrix;
       
  2451             else if (info.operation == Qt::NoClip) {
       
  2452                 lastWasNothing = true;
       
  2453                 region = QRegion();
       
  2454             } else
       
  2455                 region = info.region * matrix;
       
  2456             break;
       
  2457         }
       
  2458 
       
  2459         case QPainterClipInfo::PathClip: {
       
  2460             QTransform matrix = (info.matrix * d->invMatrix);
       
  2461             if (lastWasNothing) {
       
  2462                 region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
       
  2463                                  info.path.fillRule());
       
  2464                 lastWasNothing = false;
       
  2465                 continue;
       
  2466             }
       
  2467             if (info.operation == Qt::IntersectClip) {
       
  2468                 region &= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
       
  2469                                   info.path.fillRule());
       
  2470             } else if (info.operation == Qt::UniteClip) {
       
  2471                 region |= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
       
  2472                                   info.path.fillRule());
       
  2473             } else if (info.operation == Qt::NoClip) {
       
  2474                 lastWasNothing = true;
       
  2475                 region = QRegion();
       
  2476             } else {
       
  2477                 region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
       
  2478                                  info.path.fillRule());
       
  2479             }
       
  2480             break;
       
  2481         }
       
  2482 
       
  2483         case QPainterClipInfo::RectClip: {
       
  2484             QTransform matrix = (info.matrix * d->invMatrix);
       
  2485             if (lastWasNothing) {
       
  2486                 region = QRegion(info.rect) * matrix;
       
  2487                 lastWasNothing = false;
       
  2488                 continue;
       
  2489             }
       
  2490             if (info.operation == Qt::IntersectClip) {
       
  2491                 // Use rect intersection if possible.
       
  2492                 if (matrix.type() <= QTransform::TxScale)
       
  2493                     region &= matrix.mapRect(info.rect);
       
  2494                 else
       
  2495                     region &= matrix.map(QRegion(info.rect));
       
  2496             } else if (info.operation == Qt::UniteClip) {
       
  2497                 region |= QRegion(info.rect) * matrix;
       
  2498             } else if (info.operation == Qt::NoClip) {
       
  2499                 lastWasNothing = true;
       
  2500                 region = QRegion();
       
  2501             } else {
       
  2502                 region = QRegion(info.rect) * matrix;
       
  2503             }
       
  2504             break;
       
  2505         }
       
  2506 
       
  2507         case QPainterClipInfo::RectFClip: {
       
  2508             QTransform matrix = (info.matrix * d->invMatrix);
       
  2509             if (lastWasNothing) {
       
  2510                 region = QRegion(info.rectf.toRect()) * matrix;
       
  2511                 lastWasNothing = false;
       
  2512                 continue;
       
  2513             }
       
  2514             if (info.operation == Qt::IntersectClip) {
       
  2515                 // Use rect intersection if possible.
       
  2516                 if (matrix.type() <= QTransform::TxScale)
       
  2517                     region &= matrix.mapRect(info.rectf.toRect());
       
  2518                 else
       
  2519                     region &= matrix.map(QRegion(info.rectf.toRect()));
       
  2520             } else if (info.operation == Qt::UniteClip) {
       
  2521                 region |= QRegion(info.rectf.toRect()) * matrix;
       
  2522             } else if (info.operation == Qt::NoClip) {
       
  2523                 lastWasNothing = true;
       
  2524                 region = QRegion();
       
  2525             } else {
       
  2526                 region = QRegion(info.rectf.toRect()) * matrix;
       
  2527             }
       
  2528             break;
       
  2529         }
       
  2530         }
       
  2531     }
       
  2532 
       
  2533     return region;
       
  2534 }
       
  2535 
       
  2536 extern QPainterPath qt_regionToPath(const QRegion &region);
       
  2537 
       
  2538 /*!
       
  2539     Returns the currently clip as a path. Note that the clip path is
       
  2540     given in logical coordinates.
       
  2541 
       
  2542     \warning QPainter does not store the combined clip explicitly as
       
  2543     this is handled by the underlying QPaintEngine, so the path is
       
  2544     recreated on demand and transformed to the current logical
       
  2545     coordinate system. This is potentially an expensive operation.
       
  2546 
       
  2547     \sa setClipPath(), clipRegion(), setClipping()
       
  2548 */
       
  2549 QPainterPath QPainter::clipPath() const
       
  2550 {
       
  2551     Q_D(const QPainter);
       
  2552 
       
  2553     // ### Since we do not support path intersections and path unions yet,
       
  2554     // we just use clipRegion() here...
       
  2555     if (!d->engine) {
       
  2556         qWarning("QPainter::clipPath: Painter not active");
       
  2557         return QPainterPath();
       
  2558     }
       
  2559 
       
  2560     // No clip, return empty
       
  2561     if (d->state->clipInfo.size() == 0) {
       
  2562         return QPainterPath();
       
  2563     } else {
       
  2564 
       
  2565         // Update inverse matrix, used below.
       
  2566         if (!d->txinv)
       
  2567             const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
       
  2568 
       
  2569         // For the simple case avoid conversion.
       
  2570         if (d->state->clipInfo.size() == 1
       
  2571             && d->state->clipInfo.at(0).clipType == QPainterClipInfo::PathClip) {
       
  2572             QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
       
  2573             return d->state->clipInfo.at(0).path * matrix;
       
  2574 
       
  2575         } else if (d->state->clipInfo.size() == 1
       
  2576                    && d->state->clipInfo.at(0).clipType == QPainterClipInfo::RectClip) {
       
  2577             QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
       
  2578             QPainterPath path;
       
  2579             path.addRect(d->state->clipInfo.at(0).rect);
       
  2580             return path * matrix;
       
  2581         } else {
       
  2582             // Fallback to clipRegion() for now, since we don't have isect/unite for paths
       
  2583             return qt_regionToPath(clipRegion());
       
  2584         }
       
  2585     }
       
  2586 }
       
  2587 
       
  2588 /*!
       
  2589     \fn void QPainter::setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
       
  2590 
       
  2591     Enables clipping, and sets the clip region to the given \a
       
  2592     rectangle using the given clip \a operation. The default operation
       
  2593     is to replace the current clip rectangle.
       
  2594 
       
  2595     Note that the clip rectangle is specified in logical (painter)
       
  2596     coordinates.
       
  2597 
       
  2598     \sa clipRegion(), setClipping(), {QPainter#Clipping}{Clipping}
       
  2599 */
       
  2600 void QPainter::setClipRect(const QRectF &rect, Qt::ClipOperation op)
       
  2601 {
       
  2602     Q_D(QPainter);
       
  2603 
       
  2604     if (d->extended) {
       
  2605         if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
       
  2606             op = Qt::ReplaceClip;
       
  2607 
       
  2608         if (!d->engine) {
       
  2609             qWarning("QPainter::setClipRect: Painter not active");
       
  2610             return;
       
  2611         }
       
  2612         qreal right = rect.x() + rect.width();
       
  2613         qreal bottom = rect.y() + rect.height();
       
  2614         qreal pts[] = { rect.x(), rect.y(),
       
  2615                         right, rect.y(),
       
  2616                         right, bottom,
       
  2617                         rect.x(), bottom };
       
  2618         QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
       
  2619         d->state->clipEnabled = true;
       
  2620         d->extended->clip(vp, op);
       
  2621         if (op == Qt::ReplaceClip || op == Qt::NoClip)
       
  2622             d->state->clipInfo.clear();
       
  2623         d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
       
  2624         d->state->clipOperation = op;
       
  2625         return;
       
  2626     }
       
  2627 
       
  2628     if (qreal(int(rect.top())) == rect.top()
       
  2629         && qreal(int(rect.bottom())) == rect.bottom()
       
  2630         && qreal(int(rect.left())) == rect.left()
       
  2631         && qreal(int(rect.right())) == rect.right())
       
  2632     {
       
  2633         setClipRect(rect.toRect(), op);
       
  2634         return;
       
  2635     }
       
  2636 
       
  2637     if (rect.isEmpty()) {
       
  2638         setClipRegion(QRegion(), op);
       
  2639         return;
       
  2640     }
       
  2641 
       
  2642     QPainterPath path;
       
  2643     path.addRect(rect);
       
  2644     setClipPath(path, op);
       
  2645 }
       
  2646 
       
  2647 /*!
       
  2648     \fn void QPainter::setClipRect(const QRect &rectangle, Qt::ClipOperation operation)
       
  2649     \overload
       
  2650 
       
  2651     Enables clipping, and sets the clip region to the given \a rectangle using the given
       
  2652     clip \a operation.
       
  2653 */
       
  2654 void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
       
  2655 {
       
  2656     Q_D(QPainter);
       
  2657 
       
  2658     if (!d->engine) {
       
  2659         qWarning("QPainter::setClipRect: Painter not active");
       
  2660         return;
       
  2661     }
       
  2662 
       
  2663     if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
       
  2664         op = Qt::ReplaceClip;
       
  2665 
       
  2666     if (d->extended) {
       
  2667         d->state->clipEnabled = true;
       
  2668         d->extended->clip(rect, op);
       
  2669         if (op == Qt::ReplaceClip || op == Qt::NoClip)
       
  2670             d->state->clipInfo.clear();
       
  2671         d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
       
  2672         d->state->clipOperation = op;
       
  2673         return;
       
  2674     }
       
  2675 
       
  2676     d->state->clipRegion = rect;
       
  2677     d->state->clipOperation = op;
       
  2678     if (op == Qt::NoClip || op == Qt::ReplaceClip)
       
  2679         d->state->clipInfo.clear();
       
  2680     d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
       
  2681     d->state->clipEnabled = true;
       
  2682     d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
       
  2683     d->updateState(d->state);
       
  2684 }
       
  2685 
       
  2686 /*!
       
  2687     \fn void QPainter::setClipRect(int x, int y, int width, int height, Qt::ClipOperation operation)
       
  2688 
       
  2689     Enables clipping, and sets the clip region to the rectangle beginning at (\a x, \a y)
       
  2690     with the given \a width and \a height.
       
  2691 */
       
  2692 
       
  2693 /*!
       
  2694     \fn void QPainter::setClipRegion(const QRegion &region, Qt::ClipOperation operation)
       
  2695 
       
  2696     Sets the clip region to the given \a region using the specified clip
       
  2697     \a operation. The default clip operation is to replace the current
       
  2698     clip region.
       
  2699 
       
  2700     Note that the clip region is given in logical coordinates.
       
  2701 
       
  2702     \sa clipRegion(), setClipRect(), {QPainter#Clipping}{Clipping}
       
  2703 */
       
  2704 void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
       
  2705 {
       
  2706     Q_D(QPainter);
       
  2707 #ifdef QT_DEBUG_DRAW
       
  2708     QRect rect = r.boundingRect();
       
  2709     if (qt_show_painter_debug_output)
       
  2710         printf("QPainter::setClipRegion(), size=%d, [%d,%d,%d,%d]\n",
       
  2711            r.rects().size(), rect.x(), rect.y(), rect.width(), rect.height());
       
  2712 #endif
       
  2713     if (!d->engine) {
       
  2714         qWarning("QPainter::setClipRegion: Painter not active");
       
  2715         return;
       
  2716     }
       
  2717 
       
  2718     if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
       
  2719         op = Qt::ReplaceClip;
       
  2720 
       
  2721     if (d->extended) {
       
  2722         d->state->clipEnabled = true;
       
  2723         d->extended->clip(r, op);
       
  2724         if (op == Qt::NoClip || op == Qt::ReplaceClip)
       
  2725             d->state->clipInfo.clear();
       
  2726         d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
       
  2727         d->state->clipOperation = op;
       
  2728         return;
       
  2729     }
       
  2730 
       
  2731     d->state->clipRegion = r;
       
  2732     d->state->clipOperation = op;
       
  2733     if (op == Qt::NoClip || op == Qt::ReplaceClip)
       
  2734         d->state->clipInfo.clear();
       
  2735     d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
       
  2736     d->state->clipEnabled = true;
       
  2737     d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
       
  2738     d->updateState(d->state);
       
  2739 }
       
  2740 
       
  2741 /*!
       
  2742     \since 4.2
       
  2743     \obsolete
       
  2744 
       
  2745     Sets the transformation matrix to \a matrix and enables transformations.
       
  2746 
       
  2747     \note It is advisable to use setWorldTransform() instead of this function to
       
  2748     preserve the properties of perspective transformations.
       
  2749 
       
  2750     If \a combine is true, then \a matrix is combined with the current
       
  2751     transformation matrix; otherwise \a matrix replaces the current
       
  2752     transformation matrix.
       
  2753 
       
  2754     If \a matrix is the identity matrix and \a combine is false, this
       
  2755     function calls setWorldMatrixEnabled(false). (The identity matrix is the
       
  2756     matrix where QMatrix::m11() and QMatrix::m22() are 1.0 and the
       
  2757     rest are 0.0.)
       
  2758 
       
  2759     The following functions can transform the coordinate system without using
       
  2760     a QMatrix:
       
  2761     \list
       
  2762     \i translate()
       
  2763     \i scale()
       
  2764     \i shear()
       
  2765     \i rotate()
       
  2766     \endlist
       
  2767 
       
  2768     They operate on the painter's worldMatrix() and are implemented like this:
       
  2769 
       
  2770     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 4
       
  2771 
       
  2772     Note that when using setWorldMatrix() function you should always have
       
  2773     \a combine be true when you are drawing into a QPicture. Otherwise
       
  2774     it may not be possible to replay the picture with additional
       
  2775     transformations; using the translate(), scale(), etc. convenience
       
  2776     functions is safe.
       
  2777 
       
  2778     For more information about the coordinate system, transformations
       
  2779     and window-viewport conversion, see \l {The Coordinate System}
       
  2780     documentation.
       
  2781 
       
  2782     \sa setWorldTransform(), QTransform
       
  2783 */
       
  2784 
       
  2785 void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine)
       
  2786 {
       
  2787     setWorldTransform(QTransform(matrix), combine);
       
  2788 }
       
  2789 
       
  2790 /*!
       
  2791     \since 4.2
       
  2792     \obsolete
       
  2793 
       
  2794     Returns the world transformation matrix.
       
  2795 
       
  2796     It is advisable to use worldTransform() because worldMatrix() does not
       
  2797     preserve the properties of perspective transformations.
       
  2798 
       
  2799     \sa {QPainter#Coordinate Transformations}{Coordinate Transformations},
       
  2800     {The Coordinate System}
       
  2801 */
       
  2802 
       
  2803 const QMatrix &QPainter::worldMatrix() const
       
  2804 {
       
  2805     Q_D(const QPainter);
       
  2806     if (!d->engine) {
       
  2807         qWarning("QPainter::worldMatrix: Painter not active");
       
  2808         return d->fakeState()->transform.toAffine();
       
  2809     }
       
  2810     return d->state->worldMatrix.toAffine();
       
  2811 }
       
  2812 
       
  2813 /*!
       
  2814     \obsolete
       
  2815 
       
  2816     Use setWorldTransform() instead.
       
  2817 
       
  2818     \sa setWorldTransform()
       
  2819 */
       
  2820 
       
  2821 void QPainter::setMatrix(const QMatrix &matrix, bool combine)
       
  2822 {
       
  2823     setWorldTransform(QTransform(matrix), combine);
       
  2824 }
       
  2825 
       
  2826 /*!
       
  2827     \obsolete
       
  2828 
       
  2829     Use worldTransform() instead.
       
  2830 
       
  2831     \sa worldTransform()
       
  2832 */
       
  2833 
       
  2834 const QMatrix &QPainter::matrix() const
       
  2835 {
       
  2836     return worldMatrix();
       
  2837 }
       
  2838 
       
  2839 
       
  2840 /*!
       
  2841     \since 4.2
       
  2842     \obsolete
       
  2843 
       
  2844     Returns the transformation matrix combining the current
       
  2845     window/viewport and world transformation.
       
  2846 
       
  2847     It is advisable to use combinedTransform() instead of this
       
  2848     function to preserve the properties of perspective transformations.
       
  2849 
       
  2850     \sa setWorldTransform(), setWindow(), setViewport()
       
  2851 */
       
  2852 QMatrix QPainter::combinedMatrix() const
       
  2853 {
       
  2854     return combinedTransform().toAffine();
       
  2855 }
       
  2856 
       
  2857 
       
  2858 /*!
       
  2859     \obsolete
       
  2860 
       
  2861     Returns the matrix that transforms from logical coordinates to
       
  2862     device coordinates of the platform dependent paint device.
       
  2863 
       
  2864     \note It is advisable to use deviceTransform() instead of this
       
  2865     function to preserve the properties of perspective transformations.
       
  2866 
       
  2867     This function is \e only needed when using platform painting
       
  2868     commands on the platform dependent handle (Qt::HANDLE), and the
       
  2869     platform does not do transformations nativly.
       
  2870 
       
  2871     The QPaintEngine::PaintEngineFeature enum can be queried to
       
  2872     determine whether the platform performs the transformations or
       
  2873     not.
       
  2874 
       
  2875     \sa worldMatrix(), QPaintEngine::hasFeature(),
       
  2876 */
       
  2877 const QMatrix &QPainter::deviceMatrix() const
       
  2878 {
       
  2879     Q_D(const QPainter);
       
  2880     if (!d->engine) {
       
  2881         qWarning("QPainter::deviceMatrix: Painter not active");
       
  2882         return d->fakeState()->transform.toAffine();
       
  2883     }
       
  2884     return d->state->matrix.toAffine();
       
  2885 }
       
  2886 
       
  2887 /*!
       
  2888     \obsolete
       
  2889 
       
  2890     Resets any transformations that were made using translate(), scale(),
       
  2891     shear(), rotate(), setWorldMatrix(), setViewport() and
       
  2892     setWindow().
       
  2893 
       
  2894     It is advisable to use resetTransform() instead of this function
       
  2895     to preserve the properties of perspective transformations.
       
  2896 
       
  2897     \sa {QPainter#Coordinate Transformations}{Coordinate
       
  2898     Transformations}
       
  2899 */
       
  2900 
       
  2901 void QPainter::resetMatrix()
       
  2902 {
       
  2903     resetTransform();
       
  2904 }
       
  2905 
       
  2906 
       
  2907 /*!
       
  2908     \since 4.2
       
  2909 
       
  2910     Enables transformations if \a enable is true, or disables
       
  2911     transformations if \a enable is false. The world transformation
       
  2912     matrix is not changed.
       
  2913 
       
  2914     \sa worldMatrixEnabled(), worldTransform(), {QPainter#Coordinate
       
  2915     Transformations}{Coordinate Transformations}
       
  2916 */
       
  2917 
       
  2918 void QPainter::setWorldMatrixEnabled(bool enable)
       
  2919 {
       
  2920     Q_D(QPainter);
       
  2921 #ifdef QT_DEBUG_DRAW
       
  2922     if (qt_show_painter_debug_output)
       
  2923         printf("QPainter::setMatrixEnabled(), enable=%d\n", enable);
       
  2924 #endif
       
  2925 
       
  2926     if (!d->engine) {
       
  2927         qWarning("QPainter::setMatrixEnabled: Painter not active");
       
  2928         return;
       
  2929     }
       
  2930     if (enable == d->state->WxF)
       
  2931         return;
       
  2932 
       
  2933     d->state->WxF = enable;
       
  2934     d->updateMatrix();
       
  2935 }
       
  2936 
       
  2937 /*!
       
  2938     \since 4.2
       
  2939 
       
  2940     Returns true if world transformation is enabled; otherwise returns
       
  2941     false.
       
  2942 
       
  2943     \sa setWorldMatrixEnabled(), worldTransform(), {The Coordinate System}
       
  2944 */
       
  2945 
       
  2946 bool QPainter::worldMatrixEnabled() const
       
  2947 {
       
  2948     Q_D(const QPainter);
       
  2949     if (!d->engine) {
       
  2950         qWarning("QPainter::worldMatrixEnabled: Painter not active");
       
  2951         return false;
       
  2952     }
       
  2953     return d->state->WxF;
       
  2954 }
       
  2955 
       
  2956 /*!
       
  2957     \obsolete
       
  2958 
       
  2959     Use setWorldMatrixEnabled() instead.
       
  2960 
       
  2961     \sa setWorldMatrixEnabled()
       
  2962 */
       
  2963 
       
  2964 void QPainter::setMatrixEnabled(bool enable)
       
  2965 {
       
  2966     setWorldMatrixEnabled(enable);
       
  2967 }
       
  2968 
       
  2969 /*!
       
  2970     \obsolete
       
  2971 
       
  2972     Use worldMatrixEnabled() instead
       
  2973 
       
  2974     \sa worldMatrixEnabled()
       
  2975 */
       
  2976 
       
  2977 bool QPainter::matrixEnabled() const
       
  2978 {
       
  2979     return worldMatrixEnabled();
       
  2980 }
       
  2981 
       
  2982 /*!
       
  2983     Scales the coordinate system by (\a{sx}, \a{sy}).
       
  2984 
       
  2985     \sa setWorldTransform() {QPainter#Coordinate Transformations}{Coordinate
       
  2986     Transformations}
       
  2987 */
       
  2988 
       
  2989 void QPainter::scale(qreal sx, qreal sy)
       
  2990 {
       
  2991 #ifdef QT_DEBUG_DRAW
       
  2992     if (qt_show_painter_debug_output)
       
  2993         printf("QPainter::scale(), sx=%f, sy=%f\n", sx, sy);
       
  2994 #endif
       
  2995     Q_D(QPainter);
       
  2996     if (!d->engine) {
       
  2997         qWarning("QPainter::scale: Painter not active");
       
  2998         return;
       
  2999     }
       
  3000 
       
  3001     d->state->worldMatrix.scale(sx,sy);
       
  3002     d->state->WxF = true;
       
  3003     d->updateMatrix();
       
  3004 }
       
  3005 
       
  3006 /*!
       
  3007     Shears the coordinate system by (\a{sh}, \a{sv}).
       
  3008 
       
  3009     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
       
  3010     Transformations}
       
  3011 */
       
  3012 
       
  3013 void QPainter::shear(qreal sh, qreal sv)
       
  3014 {
       
  3015 #ifdef QT_DEBUG_DRAW
       
  3016     if (qt_show_painter_debug_output)
       
  3017         printf("QPainter::shear(), sh=%f, sv=%f\n", sh, sv);
       
  3018 #endif
       
  3019     Q_D(QPainter);
       
  3020     if (!d->engine) {
       
  3021         qWarning("QPainter::shear: Painter not active");
       
  3022         return;
       
  3023     }
       
  3024 
       
  3025     d->state->worldMatrix.shear(sh, sv);
       
  3026     d->state->WxF = true;
       
  3027     d->updateMatrix();
       
  3028 }
       
  3029 
       
  3030 /*!
       
  3031     \fn void QPainter::rotate(qreal angle)
       
  3032 
       
  3033     Rotates the coordinate system the given \a angle clockwise.
       
  3034 
       
  3035     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
       
  3036     Transformations}
       
  3037 */
       
  3038 
       
  3039 void QPainter::rotate(qreal a)
       
  3040 {
       
  3041 #ifdef QT_DEBUG_DRAW
       
  3042     if (qt_show_painter_debug_output)
       
  3043         printf("QPainter::rotate(), angle=%f\n", a);
       
  3044 #endif
       
  3045     Q_D(QPainter);
       
  3046     if (!d->engine) {
       
  3047         qWarning("QPainter::rotate: Painter not active");
       
  3048         return;
       
  3049     }
       
  3050 
       
  3051     d->state->worldMatrix.rotate(a);
       
  3052     d->state->WxF = true;
       
  3053     d->updateMatrix();
       
  3054 }
       
  3055 
       
  3056 /*!
       
  3057     Translates the coordinate system by the given \a offset; i.e. the
       
  3058     given \a offset is added to points.
       
  3059 
       
  3060     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
       
  3061     Transformations}
       
  3062 */
       
  3063 void QPainter::translate(const QPointF &offset)
       
  3064 {
       
  3065     qreal dx = offset.x();
       
  3066     qreal dy = offset.y();
       
  3067 #ifdef QT_DEBUG_DRAW
       
  3068     if (qt_show_painter_debug_output)
       
  3069         printf("QPainter::translate(), dx=%f, dy=%f\n", dx, dy);
       
  3070 #endif
       
  3071     Q_D(QPainter);
       
  3072     if (!d->engine) {
       
  3073         qWarning("QPainter::translate: Painter not active");
       
  3074         return;
       
  3075     }
       
  3076 
       
  3077     d->state->worldMatrix.translate(dx, dy);
       
  3078     d->state->WxF = true;
       
  3079     d->updateMatrix();
       
  3080 }
       
  3081 
       
  3082 /*!
       
  3083     \fn void QPainter::translate(const QPoint &offset)
       
  3084     \overload
       
  3085 
       
  3086     Translates the coordinate system by the given \a offset.
       
  3087 */
       
  3088 
       
  3089 /*!
       
  3090     \fn void QPainter::translate(qreal dx, qreal dy)
       
  3091     \overload
       
  3092 
       
  3093     Translates the coordinate system by the vector (\a dx, \a dy).
       
  3094 */
       
  3095 
       
  3096 /*!
       
  3097     \fn void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation operation)
       
  3098 
       
  3099     Enables clipping, and sets the clip path for the painter to the
       
  3100     given \a path, with the clip \a operation.
       
  3101 
       
  3102     Note that the clip path is specified in logical (painter)
       
  3103     coordinates.
       
  3104 
       
  3105     \sa clipPath(), clipRegion(), {QPainter#Clipping}{Clipping}
       
  3106 
       
  3107 */
       
  3108 void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
       
  3109 {
       
  3110 #ifdef QT_DEBUG_DRAW
       
  3111     if (qt_show_painter_debug_output) {
       
  3112         QRectF b = path.boundingRect();
       
  3113         printf("QPainter::setClipPath(), size=%d, op=%d, bounds=[%.2f,%.2f,%.2f,%.2f]\n",
       
  3114                path.elementCount(), op, b.x(), b.y(), b.width(), b.height());
       
  3115     }
       
  3116 #endif
       
  3117     Q_D(QPainter);
       
  3118 
       
  3119     if (!d->engine) {
       
  3120         qWarning("QPainter::setClipPath: Painter not active");
       
  3121         return;
       
  3122     }
       
  3123 
       
  3124     if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
       
  3125         op = Qt::ReplaceClip;
       
  3126 
       
  3127     if (d->extended) {
       
  3128         d->state->clipEnabled = true;
       
  3129         d->extended->clip(path, op);
       
  3130         if (op == Qt::NoClip || op == Qt::ReplaceClip)
       
  3131             d->state->clipInfo.clear();
       
  3132         d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
       
  3133         d->state->clipOperation = op;
       
  3134         return;
       
  3135     }
       
  3136 
       
  3137     d->state->clipPath = path;
       
  3138     d->state->clipOperation = op;
       
  3139     if (op == Qt::NoClip || op == Qt::ReplaceClip)
       
  3140         d->state->clipInfo.clear();
       
  3141     d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
       
  3142     d->state->clipEnabled = true;
       
  3143     d->state->dirtyFlags |= QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipEnabled;
       
  3144     d->updateState(d->state);
       
  3145 }
       
  3146 
       
  3147 /*!
       
  3148     Draws the outline (strokes) the path \a path with the pen specified
       
  3149     by \a pen
       
  3150 
       
  3151     \sa fillPath(), {QPainter#Drawing}{Drawing}
       
  3152 */
       
  3153 void QPainter::strokePath(const QPainterPath &path, const QPen &pen)
       
  3154 {
       
  3155     Q_D(QPainter);
       
  3156 
       
  3157     if (!d->engine) {
       
  3158         qWarning("QPainter::strokePath: Painter not active");
       
  3159         return;
       
  3160     }
       
  3161 
       
  3162     if (path.isEmpty())
       
  3163         return;
       
  3164 
       
  3165     if (d->extended) {
       
  3166         const QGradient *g = qpen_brush(pen).gradient();
       
  3167         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
       
  3168             d->extended->stroke(qtVectorPathForPath(path), pen);
       
  3169             return;
       
  3170         }
       
  3171     }
       
  3172 
       
  3173     QBrush oldBrush = d->state->brush;
       
  3174     QPen oldPen = d->state->pen;
       
  3175 
       
  3176     setPen(pen);
       
  3177     setBrush(Qt::NoBrush);
       
  3178 
       
  3179     drawPath(path);
       
  3180 
       
  3181     // Reset old state
       
  3182     setPen(oldPen);
       
  3183     setBrush(oldBrush);
       
  3184 }
       
  3185 
       
  3186 /*!
       
  3187     Fills the given \a path using the given \a brush. The outline is
       
  3188     not drawn.
       
  3189 
       
  3190     Alternatively, you can specify a QColor instead of a QBrush; the
       
  3191     QBrush constructor (taking a QColor argument) will automatically
       
  3192     create a solid pattern brush.
       
  3193 
       
  3194     \sa drawPath()
       
  3195 */
       
  3196 void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
       
  3197 {
       
  3198     Q_D(QPainter);
       
  3199 
       
  3200     if (!d->engine) {
       
  3201         qWarning("QPainter::fillPath: Painter not active");
       
  3202         return;
       
  3203     }
       
  3204 
       
  3205     if (path.isEmpty())
       
  3206         return;
       
  3207 
       
  3208     if (d->extended) {
       
  3209         const QGradient *g = brush.gradient();
       
  3210         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
       
  3211             d->extended->fill(qtVectorPathForPath(path), brush);
       
  3212             return;
       
  3213         }
       
  3214     }
       
  3215 
       
  3216     QBrush oldBrush = d->state->brush;
       
  3217     QPen oldPen = d->state->pen;
       
  3218 
       
  3219     setPen(Qt::NoPen);
       
  3220     setBrush(brush);
       
  3221 
       
  3222     drawPath(path);
       
  3223 
       
  3224     // Reset old state
       
  3225     setPen(oldPen);
       
  3226     setBrush(oldBrush);
       
  3227 }
       
  3228 
       
  3229 /*!
       
  3230     Draws the given painter \a path using the current pen for outline
       
  3231     and the current brush for filling.
       
  3232 
       
  3233     \table 100%
       
  3234     \row
       
  3235     \o \inlineimage qpainter-path.png
       
  3236     \o
       
  3237     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 5
       
  3238     \endtable
       
  3239 
       
  3240     \sa {painting/painterpaths}{the Painter Paths
       
  3241     example},{demos/deform}{the Vector Deformation demo}
       
  3242 */
       
  3243 void QPainter::drawPath(const QPainterPath &path)
       
  3244 {
       
  3245 #ifdef QT_DEBUG_DRAW
       
  3246     QRectF pathBounds = path.boundingRect();
       
  3247     if (qt_show_painter_debug_output)
       
  3248         printf("QPainter::drawPath(), size=%d, [%.2f,%.2f,%.2f,%.2f]\n",
       
  3249                path.elementCount(),
       
  3250                pathBounds.x(), pathBounds.y(), pathBounds.width(), pathBounds.height());
       
  3251 #endif
       
  3252 
       
  3253     Q_D(QPainter);
       
  3254 
       
  3255     if (!d->engine) {
       
  3256         qWarning("QPainter::drawPath: Painter not active");
       
  3257         return;
       
  3258     }
       
  3259 
       
  3260     if (d->extended) {
       
  3261         d->extended->drawPath(path);
       
  3262         return;
       
  3263     }
       
  3264     d->updateState(d->state);
       
  3265 
       
  3266     if (d->engine->hasFeature(QPaintEngine::PainterPaths) && d->state->emulationSpecifier == 0) {
       
  3267         d->engine->drawPath(path);
       
  3268     } else {
       
  3269         d->draw_helper(path);
       
  3270     }
       
  3271 }
       
  3272 
       
  3273 /*!
       
  3274     \fn void QPainter::drawLine(const QLineF &line)
       
  3275 
       
  3276     Draws a line defined by \a line.
       
  3277 
       
  3278     \table 100%
       
  3279     \row
       
  3280     \o \inlineimage qpainter-line.png
       
  3281     \o
       
  3282     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6
       
  3283     \endtable
       
  3284 
       
  3285     \sa drawLines(), drawPolyline(), {The Coordinate System}
       
  3286 */
       
  3287 
       
  3288 /*!
       
  3289     \fn void QPainter::drawLine(const QLine &line)
       
  3290     \overload
       
  3291 
       
  3292     Draws a line defined by \a line.
       
  3293 */
       
  3294 
       
  3295 /*!
       
  3296     \fn void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
       
  3297     \overload
       
  3298 
       
  3299     Draws a line from \a p1 to \a p2.
       
  3300 */
       
  3301 
       
  3302 /*!
       
  3303     \fn void QPainter::drawLine(const QPointF &p1, const QPointF &p2)
       
  3304     \overload
       
  3305 
       
  3306     Draws a line from \a p1 to \a p2.
       
  3307 */
       
  3308 
       
  3309 /*!
       
  3310     \fn void QPainter::drawLine(int x1, int y1, int x2, int y2)
       
  3311     \overload
       
  3312 
       
  3313     Draws a line from (\a x1, \a y1) to (\a x2, \a y2) and sets the
       
  3314     current pen position to (\a x2, \a y2).
       
  3315 */
       
  3316 
       
  3317 /*!
       
  3318     \fn void QPainter::drawRect(const QRectF &rectangle)
       
  3319 
       
  3320     Draws the current \a rectangle with the current pen and brush.
       
  3321 
       
  3322     A filled rectangle has a size of \a{rectangle}.size(). A stroked
       
  3323     rectangle has a size of \a{rectangle}.size() plus the pen width.
       
  3324 
       
  3325     \table 100%
       
  3326     \row
       
  3327     \o \inlineimage qpainter-rectangle.png
       
  3328     \o
       
  3329     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7
       
  3330     \endtable
       
  3331 
       
  3332     \sa drawRects(), drawPolygon(), {The Coordinate System}
       
  3333 */
       
  3334 
       
  3335 /*!
       
  3336     \fn void QPainter::drawRect(const QRect &rectangle)
       
  3337 
       
  3338     \overload
       
  3339 
       
  3340     Draws the current \a rectangle with the current pen and brush.
       
  3341 */
       
  3342 
       
  3343 /*!
       
  3344     \fn void QPainter::drawRect(int x, int y, int width, int height)
       
  3345 
       
  3346     \overload
       
  3347 
       
  3348     Draws a rectangle with upper left corner at (\a{x}, \a{y}) and
       
  3349     with the given \a width and \a height.
       
  3350 */
       
  3351 
       
  3352 /*!
       
  3353     \fn void QPainter::drawRects(const QRectF *rectangles, int rectCount)
       
  3354 
       
  3355     Draws the first \a rectCount of the given \a rectangles using the
       
  3356     current pen and brush.
       
  3357 
       
  3358     \sa drawRect()
       
  3359 */
       
  3360 void QPainter::drawRects(const QRectF *rects, int rectCount)
       
  3361 {
       
  3362 #ifdef QT_DEBUG_DRAW
       
  3363     if (qt_show_painter_debug_output)
       
  3364         printf("QPainter::drawRects(), count=%d\n", rectCount);
       
  3365 #endif
       
  3366     Q_D(QPainter);
       
  3367 
       
  3368     if (!d->engine) {
       
  3369         qWarning("QPainter::drawRects: Painter not active");
       
  3370         return;
       
  3371     }
       
  3372 
       
  3373     if (rectCount <= 0)
       
  3374         return;
       
  3375 
       
  3376     if (d->extended) {
       
  3377         d->extended->drawRects(rects, rectCount);
       
  3378         return;
       
  3379     }
       
  3380 
       
  3381     d->updateState(d->state);
       
  3382 
       
  3383     if (!d->state->emulationSpecifier) {
       
  3384         d->engine->drawRects(rects, rectCount);
       
  3385         return;
       
  3386     }
       
  3387 
       
  3388     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
       
  3389         && d->state->matrix.type() == QTransform::TxTranslate) {
       
  3390         for (int i=0; i<rectCount; ++i) {
       
  3391             QRectF r(rects[i].x() + d->state->matrix.dx(),
       
  3392                      rects[i].y() + d->state->matrix.dy(),
       
  3393                      rects[i].width(),
       
  3394                      rects[i].height());
       
  3395             d->engine->drawRects(&r, 1);
       
  3396         }
       
  3397     } else {
       
  3398         if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
       
  3399             for (int i=0; i<rectCount; ++i) {
       
  3400                 QPainterPath rectPath;
       
  3401                 rectPath.addRect(rects[i]);
       
  3402                 d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
       
  3403             }
       
  3404         } else {
       
  3405             QPainterPath rectPath;
       
  3406             for (int i=0; i<rectCount; ++i)
       
  3407                 rectPath.addRect(rects[i]);
       
  3408             d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
       
  3409         }
       
  3410     }
       
  3411 }
       
  3412 
       
  3413 /*!
       
  3414     \fn void QPainter::drawRects(const QRect *rectangles, int rectCount)
       
  3415     \overload
       
  3416 
       
  3417     Draws the first \a rectCount of the given \a rectangles using the
       
  3418     current pen and brush.
       
  3419 */
       
  3420 void QPainter::drawRects(const QRect *rects, int rectCount)
       
  3421 {
       
  3422 #ifdef QT_DEBUG_DRAW
       
  3423     if (qt_show_painter_debug_output)
       
  3424         printf("QPainter::drawRects(), count=%d\n", rectCount);
       
  3425 #endif
       
  3426     Q_D(QPainter);
       
  3427 
       
  3428     if (!d->engine) {
       
  3429         qWarning("QPainter::drawRects: Painter not active");
       
  3430         return;
       
  3431     }
       
  3432 
       
  3433     if (rectCount <= 0)
       
  3434         return;
       
  3435 
       
  3436     if (d->extended) {
       
  3437         d->extended->drawRects(rects, rectCount);
       
  3438         return;
       
  3439     }
       
  3440 
       
  3441     d->updateState(d->state);
       
  3442 
       
  3443     if (!d->state->emulationSpecifier) {
       
  3444         d->engine->drawRects(rects, rectCount);
       
  3445         return;
       
  3446     }
       
  3447 
       
  3448     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
       
  3449         && d->state->matrix.type() == QTransform::TxTranslate) {
       
  3450         for (int i=0; i<rectCount; ++i) {
       
  3451             QRectF r(rects[i].x() + d->state->matrix.dx(),
       
  3452                      rects[i].y() + d->state->matrix.dy(),
       
  3453                      rects[i].width(),
       
  3454                      rects[i].height());
       
  3455 
       
  3456             d->engine->drawRects(&r, 1);
       
  3457         }
       
  3458     } else {
       
  3459         if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
       
  3460             for (int i=0; i<rectCount; ++i) {
       
  3461                 QPainterPath rectPath;
       
  3462                 rectPath.addRect(rects[i]);
       
  3463                 d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
       
  3464             }
       
  3465         } else {
       
  3466             QPainterPath rectPath;
       
  3467             for (int i=0; i<rectCount; ++i)
       
  3468                 rectPath.addRect(rects[i]);
       
  3469 
       
  3470             d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
       
  3471         }
       
  3472     }
       
  3473 }
       
  3474 
       
  3475 /*!
       
  3476     \fn void QPainter::drawRects(const QVector<QRectF> &rectangles)
       
  3477     \overload
       
  3478 
       
  3479     Draws the given \a rectangles using the current pen and brush.
       
  3480 */
       
  3481 
       
  3482 /*!
       
  3483     \fn void QPainter::drawRects(const QVector<QRect> &rectangles)
       
  3484 
       
  3485     \overload
       
  3486 
       
  3487     Draws the given \a rectangles using the current pen and brush.
       
  3488 */
       
  3489 
       
  3490 /*!
       
  3491   \fn void QPainter::drawPoint(const QPointF &position)
       
  3492 
       
  3493     Draws a single point at the given \a position using the current
       
  3494     pen's color.
       
  3495 
       
  3496     \sa {The Coordinate System}
       
  3497 */
       
  3498 
       
  3499 /*!
       
  3500     \fn void QPainter::drawPoint(const QPoint &position)
       
  3501     \overload
       
  3502 
       
  3503     Draws a single point at the given \a position using the current
       
  3504     pen's color.
       
  3505 */
       
  3506 
       
  3507 /*! \fn void QPainter::drawPoint(int x, int y)
       
  3508 
       
  3509     \overload
       
  3510 
       
  3511     Draws a single point at position (\a x, \a y).
       
  3512 */
       
  3513 
       
  3514 /*!
       
  3515     Draws the first \a pointCount points in the array \a points using
       
  3516     the current pen's color.
       
  3517 
       
  3518     \sa {The Coordinate System}
       
  3519 */
       
  3520 void QPainter::drawPoints(const QPointF *points, int pointCount)
       
  3521 {
       
  3522 #ifdef QT_DEBUG_DRAW
       
  3523     if (qt_show_painter_debug_output)
       
  3524         printf("QPainter::drawPoints(), count=%d\n", pointCount);
       
  3525 #endif
       
  3526     Q_D(QPainter);
       
  3527 
       
  3528     if (!d->engine) {
       
  3529         qWarning("QPainter::drawPoints: Painter not active");
       
  3530         return;
       
  3531     }
       
  3532 
       
  3533     if (pointCount <= 0)
       
  3534         return;
       
  3535 
       
  3536     if (d->extended) {
       
  3537         d->extended->drawPoints(points, pointCount);
       
  3538         return;
       
  3539     }
       
  3540 
       
  3541     d->updateState(d->state);
       
  3542 
       
  3543     if (!d->state->emulationSpecifier) {
       
  3544         d->engine->drawPoints(points, pointCount);
       
  3545         return;
       
  3546     }
       
  3547 
       
  3548     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
       
  3549         && d->state->matrix.type() == QTransform::TxTranslate) {
       
  3550         // ### use drawPoints function
       
  3551         for (int i=0; i<pointCount; ++i) {
       
  3552             QPointF pt(points[i].x() + d->state->matrix.dx(),
       
  3553                        points[i].y() + d->state->matrix.dy());
       
  3554             d->engine->drawPoints(&pt, 1);
       
  3555         }
       
  3556     } else {
       
  3557         QPen pen = d->state->pen;
       
  3558         bool flat_pen = pen.capStyle() == Qt::FlatCap;
       
  3559         if (flat_pen) {
       
  3560             save();
       
  3561             pen.setCapStyle(Qt::SquareCap);
       
  3562             setPen(pen);
       
  3563         }
       
  3564         QPainterPath path;
       
  3565         for (int i=0; i<pointCount; ++i) {
       
  3566             path.moveTo(points[i].x(), points[i].y());
       
  3567             path.lineTo(points[i].x() + 0.0001, points[i].y());
       
  3568         }
       
  3569         d->draw_helper(path, QPainterPrivate::StrokeDraw);
       
  3570         if (flat_pen)
       
  3571             restore();
       
  3572     }
       
  3573 }
       
  3574 
       
  3575 /*!
       
  3576     \overload
       
  3577 
       
  3578     Draws the first \a pointCount points in the array \a points using
       
  3579     the current pen's color.
       
  3580 */
       
  3581 
       
  3582 void QPainter::drawPoints(const QPoint *points, int pointCount)
       
  3583 {
       
  3584 #ifdef QT_DEBUG_DRAW
       
  3585     if (qt_show_painter_debug_output)
       
  3586         printf("QPainter::drawPoints(), count=%d\n", pointCount);
       
  3587 #endif
       
  3588     Q_D(QPainter);
       
  3589 
       
  3590     if (!d->engine) {
       
  3591         qWarning("QPainter::drawPoints: Painter not active");
       
  3592         return;
       
  3593     }
       
  3594 
       
  3595     if (pointCount <= 0)
       
  3596         return;
       
  3597 
       
  3598     if (d->extended) {
       
  3599         d->extended->drawPoints(points, pointCount);
       
  3600         return;
       
  3601     }
       
  3602 
       
  3603     d->updateState(d->state);
       
  3604 
       
  3605     if (!d->state->emulationSpecifier) {
       
  3606         d->engine->drawPoints(points, pointCount);
       
  3607         return;
       
  3608     }
       
  3609 
       
  3610     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
       
  3611         && d->state->matrix.type() == QTransform::TxTranslate) {
       
  3612         // ### use drawPoints function
       
  3613         for (int i=0; i<pointCount; ++i) {
       
  3614             QPointF pt(points[i].x() + d->state->matrix.dx(),
       
  3615                        points[i].y() + d->state->matrix.dy());
       
  3616             d->engine->drawPoints(&pt, 1);
       
  3617         }
       
  3618     } else {
       
  3619         QPen pen = d->state->pen;
       
  3620         bool flat_pen = (pen.capStyle() == Qt::FlatCap);
       
  3621         if (flat_pen) {
       
  3622             save();
       
  3623             pen.setCapStyle(Qt::SquareCap);
       
  3624             setPen(pen);
       
  3625         }
       
  3626         QPainterPath path;
       
  3627         for (int i=0; i<pointCount; ++i) {
       
  3628             path.moveTo(points[i].x(), points[i].y());
       
  3629             path.lineTo(points[i].x() + 0.0001, points[i].y());
       
  3630         }
       
  3631         d->draw_helper(path, QPainterPrivate::StrokeDraw);
       
  3632         if (flat_pen)
       
  3633             restore();
       
  3634     }
       
  3635 }
       
  3636 
       
  3637 /*!
       
  3638     \fn void QPainter::drawPoints(const QPolygonF &points)
       
  3639 
       
  3640     \overload
       
  3641 
       
  3642     Draws the points in the vector  \a points.
       
  3643 */
       
  3644 
       
  3645 /*!
       
  3646     \fn void QPainter::drawPoints(const QPolygon &points)
       
  3647 
       
  3648     \overload
       
  3649 
       
  3650     Draws the points in the vector  \a points.
       
  3651 */
       
  3652 
       
  3653 /*!
       
  3654     \fn void QPainter::drawPoints(const QPolygon &polygon, int index,
       
  3655     int count)
       
  3656 
       
  3657     \overload
       
  3658     \compat
       
  3659 
       
  3660     Draws \a count points in the vector \a polygon starting on \a index
       
  3661     using the current pen.
       
  3662 
       
  3663     Use drawPoints() combined with QPolygon::constData() instead.
       
  3664 
       
  3665     \oldcode
       
  3666         QPainter painter(this);
       
  3667         painter.drawPoints(polygon, index, count);
       
  3668     \newcode
       
  3669         int pointCount = (count == -1) ?  polygon.size() - index : count;
       
  3670 
       
  3671         QPainter painter(this);
       
  3672         painter.drawPoints(polygon.constData() + index, pointCount);
       
  3673     \endcode
       
  3674 */
       
  3675 
       
  3676 /*!
       
  3677     Sets the background mode of the painter to the given \a mode
       
  3678 
       
  3679     Qt::TransparentMode (the default) draws stippled lines and text
       
  3680     without setting the background pixels.  Qt::OpaqueMode fills these
       
  3681     space with the current background color.
       
  3682 
       
  3683     Note that in order to draw a bitmap or pixmap transparently, you
       
  3684     must use QPixmap::setMask().
       
  3685 
       
  3686     \sa backgroundMode(), setBackground(),
       
  3687     {QPainter#Settings}{Settings}
       
  3688 */
       
  3689 
       
  3690 void QPainter::setBackgroundMode(Qt::BGMode mode)
       
  3691 {
       
  3692 #ifdef QT_DEBUG_DRAW
       
  3693     if (qt_show_painter_debug_output)
       
  3694         printf("QPainter::setBackgroundMode(), mode=%d\n", mode);
       
  3695 #endif
       
  3696 
       
  3697     Q_D(QPainter);
       
  3698     if (!d->engine) {
       
  3699         qWarning("QPainter::setBackgroundMode: Painter not active");
       
  3700         return;
       
  3701     }
       
  3702     if (d->state->bgMode == mode)
       
  3703         return;
       
  3704 
       
  3705     d->state->bgMode = mode;
       
  3706     if (d->extended) {
       
  3707         d->checkEmulation();
       
  3708     } else {
       
  3709         d->state->dirtyFlags |= QPaintEngine::DirtyBackgroundMode;
       
  3710     }
       
  3711 }
       
  3712 
       
  3713 /*!
       
  3714     Returns the current background mode.
       
  3715 
       
  3716     \sa setBackgroundMode(), {QPainter#Settings}{Settings}
       
  3717 */
       
  3718 Qt::BGMode QPainter::backgroundMode() const
       
  3719 {
       
  3720     Q_D(const QPainter);
       
  3721     if (!d->engine) {
       
  3722         qWarning("QPainter::backgroundMode: Painter not active");
       
  3723         return Qt::TransparentMode;
       
  3724     }
       
  3725     return d->state->bgMode;
       
  3726 }
       
  3727 
       
  3728 
       
  3729 /*!
       
  3730     \overload
       
  3731 
       
  3732     Sets the painter's pen to have style Qt::SolidLine, width 0 and the
       
  3733     specified \a color.
       
  3734 */
       
  3735 
       
  3736 void QPainter::setPen(const QColor &color)
       
  3737 {
       
  3738 #ifdef QT_DEBUG_DRAW
       
  3739     if (qt_show_painter_debug_output)
       
  3740         printf("QPainter::setPen(), color=%04x\n", color.rgb());
       
  3741 #endif
       
  3742     Q_D(QPainter);
       
  3743     if (!d->engine) {
       
  3744         qWarning("QPainter::setPen: Painter not active");
       
  3745         return;
       
  3746     }
       
  3747 
       
  3748     if (d->state->pen.style() == Qt::SolidLine
       
  3749         && d->state->pen.widthF() == 0
       
  3750         && d->state->pen.isSolid()
       
  3751         && d->state->pen.color() == color)
       
  3752         return;
       
  3753 
       
  3754     QPen pen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine);
       
  3755 
       
  3756     d->state->pen = pen;
       
  3757     if (d->extended)
       
  3758         d->extended->penChanged();
       
  3759     else
       
  3760         d->state->dirtyFlags |= QPaintEngine::DirtyPen;
       
  3761 }
       
  3762 
       
  3763 /*!
       
  3764     Sets the painter's pen to be the given \a pen.
       
  3765 
       
  3766     The \a pen defines how to draw lines and outlines, and it also
       
  3767     defines the text color.
       
  3768 
       
  3769     \sa pen(), {QPainter#Settings}{Settings}
       
  3770 */
       
  3771 
       
  3772 void QPainter::setPen(const QPen &pen)
       
  3773 {
       
  3774 
       
  3775 #ifdef QT_DEBUG_DRAW
       
  3776     if (qt_show_painter_debug_output)
       
  3777         printf("QPainter::setPen(), color=%04x, (brushStyle=%d) style=%d, cap=%d, join=%d\n",
       
  3778            pen.color().rgb(), pen.brush().style(), pen.style(), pen.capStyle(), pen.joinStyle());
       
  3779 #endif
       
  3780     Q_D(QPainter);
       
  3781     if (!d->engine) {
       
  3782         qWarning("QPainter::setPen: Painter not active");
       
  3783         return;
       
  3784     }
       
  3785 
       
  3786     if (d->state->pen == pen)
       
  3787         return;
       
  3788 
       
  3789     if (d->extended) {
       
  3790         d->state->pen = pen;
       
  3791         d->checkEmulation();
       
  3792         d->extended->penChanged();
       
  3793         return;
       
  3794     }
       
  3795 
       
  3796     // Do some checks to see if we are the same pen.
       
  3797     Qt::PenStyle currentStyle = d->state->pen.style();
       
  3798     if (currentStyle == pen.style() && currentStyle != Qt::CustomDashLine) {
       
  3799         if (currentStyle == Qt::NoPen ||
       
  3800             (d->state->pen.isSolid() && pen.isSolid()
       
  3801              && d->state->pen.color() == pen.color()
       
  3802              && d->state->pen.widthF() == pen.widthF()
       
  3803              && d->state->pen.capStyle() == pen.capStyle()
       
  3804              && d->state->pen.joinStyle() == pen.joinStyle()
       
  3805              && d->state->pen.isCosmetic() == pen.isCosmetic()))
       
  3806             return;
       
  3807     }
       
  3808 
       
  3809     d->state->pen = pen;
       
  3810     d->state->dirtyFlags |= QPaintEngine::DirtyPen;
       
  3811 }
       
  3812 
       
  3813 /*!
       
  3814     \overload
       
  3815 
       
  3816     Sets the painter's pen to have the given \a style, width 0 and
       
  3817     black color.
       
  3818 */
       
  3819 
       
  3820 void QPainter::setPen(Qt::PenStyle style)
       
  3821 {
       
  3822     Q_D(QPainter);
       
  3823     if (!d->engine) {
       
  3824         qWarning("QPainter::setPen: Painter not active");
       
  3825         return;
       
  3826     }
       
  3827 
       
  3828     if (d->state->pen.style() == style
       
  3829         && (style == Qt::NoPen || (d->state->pen.widthF() == 0
       
  3830                                    && d->state->pen.isSolid()
       
  3831                                    && d->state->pen.color() == QColor(Qt::black))))
       
  3832         return;
       
  3833 
       
  3834     // QPen(Qt::NoPen) is to avoid creating QPenData, including its brush (from the color)
       
  3835     // Note that this works well as long as QPen(Qt::NoPen) returns a black, zero-width pen
       
  3836     d->state->pen = (style == Qt::NoPen) ? QPen(Qt::NoPen) : QPen(Qt::black, 0, style);
       
  3837 
       
  3838     if (d->extended)
       
  3839         d->extended->penChanged();
       
  3840     else
       
  3841         d->state->dirtyFlags |= QPaintEngine::DirtyPen;
       
  3842 
       
  3843 }
       
  3844 
       
  3845 /*!
       
  3846     Returns the painter's current pen.
       
  3847 
       
  3848     \sa setPen(), {QPainter#Settings}{Settings}
       
  3849 */
       
  3850 
       
  3851 const QPen &QPainter::pen() const
       
  3852 {
       
  3853     Q_D(const QPainter);
       
  3854     if (!d->engine) {
       
  3855         qWarning("QPainter::pen: Painter not active");
       
  3856         return d->fakeState()->pen;
       
  3857     }
       
  3858     return d->state->pen;
       
  3859 }
       
  3860 
       
  3861 
       
  3862 /*!
       
  3863     Sets the painter's brush to the given \a brush.
       
  3864 
       
  3865     The painter's brush defines how shapes are filled.
       
  3866 
       
  3867     \sa brush(), {QPainter#Settings}{Settings}
       
  3868 */
       
  3869 
       
  3870 void QPainter::setBrush(const QBrush &brush)
       
  3871 {
       
  3872 #ifdef QT_DEBUG_DRAW
       
  3873     if (qt_show_painter_debug_output)
       
  3874         printf("QPainter::setBrush(), color=%04x, style=%d\n", brush.color().rgb(), brush.style());
       
  3875 #endif
       
  3876     Q_D(QPainter);
       
  3877     if (!d->engine) {
       
  3878         qWarning("QPainter::setBrush: Painter not active");
       
  3879         return;
       
  3880     }
       
  3881 
       
  3882     if (d->state->brush.d == brush.d)
       
  3883         return;
       
  3884 
       
  3885     if (d->extended) {
       
  3886         d->state->brush = brush;
       
  3887         d->checkEmulation();
       
  3888         d->extended->brushChanged();
       
  3889         return;
       
  3890     }
       
  3891 
       
  3892     Qt::BrushStyle currentStyle = d->state->brush.style();
       
  3893     if (currentStyle == brush.style()) {
       
  3894         if (currentStyle == Qt::NoBrush
       
  3895             || (currentStyle == Qt::SolidPattern
       
  3896                 && d->state->brush.color() == brush.color()))
       
  3897             return;
       
  3898     }
       
  3899 
       
  3900     d->state->brush = brush;
       
  3901     d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
       
  3902 }
       
  3903 
       
  3904 
       
  3905 /*!
       
  3906     \overload
       
  3907 
       
  3908     Sets the painter's brush to black color and the specified \a
       
  3909     style.
       
  3910 */
       
  3911 
       
  3912 void QPainter::setBrush(Qt::BrushStyle style)
       
  3913 {
       
  3914     Q_D(QPainter);
       
  3915     if (!d->engine) {
       
  3916         qWarning("QPainter::setBrush: Painter not active");
       
  3917         return;
       
  3918     }
       
  3919     if (d->state->brush.style() == style &&
       
  3920         (style == Qt::NoBrush
       
  3921          || (style == Qt::SolidPattern && d->state->brush.color() == QColor(0, 0, 0))))
       
  3922         return;
       
  3923     d->state->brush = QBrush(Qt::black, style);
       
  3924     if (d->extended)
       
  3925         d->extended->brushChanged();
       
  3926     else
       
  3927         d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
       
  3928 }
       
  3929 
       
  3930 /*!
       
  3931     Returns the painter's current brush.
       
  3932 
       
  3933     \sa QPainter::setBrush(), {QPainter#Settings}{Settings}
       
  3934 */
       
  3935 
       
  3936 const QBrush &QPainter::brush() const
       
  3937 {
       
  3938     Q_D(const QPainter);
       
  3939     if (!d->engine) {
       
  3940         qWarning("QPainter::brush: Painter not active");
       
  3941         return d->fakeState()->brush;
       
  3942     }
       
  3943     return d->state->brush;
       
  3944 }
       
  3945 
       
  3946 /*!
       
  3947     \fn void QPainter::setBackground(const QBrush &brush)
       
  3948 
       
  3949     Sets the background brush of the painter to the given \a brush.
       
  3950 
       
  3951     The background brush is the brush that is filled in when drawing
       
  3952     opaque text, stippled lines and bitmaps. The background brush has
       
  3953     no effect in transparent background mode (which is the default).
       
  3954 
       
  3955     \sa background(), setBackgroundMode(),
       
  3956     {QPainter#Settings}{Settings}
       
  3957 */
       
  3958 
       
  3959 void QPainter::setBackground(const QBrush &bg)
       
  3960 {
       
  3961 #ifdef QT_DEBUG_DRAW
       
  3962     if (qt_show_painter_debug_output)
       
  3963         printf("QPainter::setBackground(), color=%04x, style=%d\n", bg.color().rgb(), bg.style());
       
  3964 #endif
       
  3965 
       
  3966     Q_D(QPainter);
       
  3967     if (!d->engine) {
       
  3968         qWarning("QPainter::setBackground: Painter not active");
       
  3969         return;
       
  3970     }
       
  3971     d->state->bgBrush = bg;
       
  3972     if (!d->extended)
       
  3973         d->state->dirtyFlags |= QPaintEngine::DirtyBackground;
       
  3974 }
       
  3975 
       
  3976 /*!
       
  3977     Sets the painter's font to the given \a font.
       
  3978 
       
  3979     This font is used by subsequent drawText() functions. The text
       
  3980     color is the same as the pen color.
       
  3981 
       
  3982     If you set a font that isn't available, Qt finds a close match.
       
  3983     font() will return what you set using setFont() and fontInfo() returns the
       
  3984     font actually being used (which may be the same).
       
  3985 
       
  3986     \sa font(), drawText(), {QPainter#Settings}{Settings}
       
  3987 */
       
  3988 
       
  3989 void QPainter::setFont(const QFont &font)
       
  3990 {
       
  3991     Q_D(QPainter);
       
  3992 
       
  3993 #ifdef QT_DEBUG_DRAW
       
  3994     if (qt_show_painter_debug_output)
       
  3995         printf("QPainter::setFont(), family=%s, pointSize=%d\n", font.family().toLatin1().constData(), font.pointSize());
       
  3996 #endif
       
  3997 
       
  3998     if (!d->engine) {
       
  3999         qWarning("QPainter::setFont: Painter not active");
       
  4000         return;
       
  4001     }
       
  4002 
       
  4003     d->state->font = QFont(font.resolve(d->state->deviceFont), device());
       
  4004     if (!d->extended)
       
  4005         d->state->dirtyFlags |= QPaintEngine::DirtyFont;
       
  4006 }
       
  4007 
       
  4008 /*!
       
  4009     Returns the currently set font used for drawing text.
       
  4010 
       
  4011     \sa setFont(), drawText(), {QPainter#Settings}{Settings}
       
  4012 */
       
  4013 const QFont &QPainter::font() const
       
  4014 {
       
  4015     Q_D(const QPainter);
       
  4016     if (!d->engine) {
       
  4017         qWarning("QPainter::font: Painter not active");
       
  4018         return d->fakeState()->font;
       
  4019     }
       
  4020     return d->state->font;
       
  4021 }
       
  4022 
       
  4023 /*!
       
  4024     \since 4.4
       
  4025 
       
  4026     Draws the given rectangle \a rect with rounded corners.
       
  4027 
       
  4028     The \a xRadius and \a yRadius arguments specify the radii
       
  4029     of the ellipses defining the corners of the rounded rectangle.
       
  4030     When \a mode is Qt::RelativeSize, \a xRadius and
       
  4031     \a yRadius are specified in percentage of half the rectangle's
       
  4032     width and height respectively, and should be in the range
       
  4033     0.0 to 100.0.
       
  4034 
       
  4035     A filled rectangle has a size of rect.size(). A stroked rectangle
       
  4036     has a size of rect.size() plus the pen width.
       
  4037 
       
  4038     \table 100%
       
  4039     \row
       
  4040     \o \inlineimage qpainter-roundrect.png
       
  4041     \o
       
  4042     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 8
       
  4043     \endtable
       
  4044 
       
  4045     \sa drawRect(), QPen
       
  4046 */
       
  4047 void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
       
  4048 {
       
  4049 #ifdef QT_DEBUG_DRAW
       
  4050     if (qt_show_painter_debug_output)
       
  4051         printf("QPainter::drawRoundedRect(), [%.2f,%.2f,%.2f,%.2f]\n", rect.x(), rect.y(), rect.width(), rect.height());
       
  4052 #endif
       
  4053     Q_D(QPainter);
       
  4054 
       
  4055     if (!d->engine)
       
  4056         return;
       
  4057 
       
  4058     if (xRadius <= 0 || yRadius <= 0) {             // draw normal rectangle
       
  4059         drawRect(rect);
       
  4060         return;
       
  4061     }
       
  4062 
       
  4063     if (d->extended) {
       
  4064         d->extended->drawRoundedRect(rect, xRadius, yRadius, mode);
       
  4065         return;
       
  4066     }
       
  4067 
       
  4068     QPainterPath path;
       
  4069     path.addRoundedRect(rect, xRadius, yRadius, mode);
       
  4070     drawPath(path);
       
  4071 }
       
  4072 
       
  4073 /*!
       
  4074     \fn void QPainter::drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius,
       
  4075                                        Qt::SizeMode mode = Qt::AbsoluteSize);
       
  4076     \since 4.4
       
  4077     \overload
       
  4078 
       
  4079     Draws the given rectangle \a rect with rounded corners.
       
  4080 */
       
  4081 
       
  4082 /*!
       
  4083     \fn void QPainter::drawRoundedRect(int x, int y, int w, int h, qreal xRadius, qreal yRadius,
       
  4084                                        Qt::SizeMode mode = Qt::AbsoluteSize);
       
  4085     \since 4.4
       
  4086     \overload
       
  4087 
       
  4088     Draws the given rectangle \a x, \a y, \a w, \a h with rounded corners.
       
  4089 */
       
  4090 
       
  4091 /*!
       
  4092     \obsolete
       
  4093 
       
  4094     Draws a rectangle \a r with rounded corners.
       
  4095 
       
  4096     The \a xRnd and \a yRnd arguments specify how rounded the corners
       
  4097     should be. 0 is angled corners, 99 is maximum roundedness.
       
  4098 
       
  4099     A filled rectangle has a size of r.size(). A stroked rectangle
       
  4100     has a size of r.size() plus the pen width.
       
  4101 
       
  4102     \sa drawRoundedRect()
       
  4103 */
       
  4104 void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
       
  4105 {
       
  4106     drawRoundedRect(r, xRnd, yRnd, Qt::RelativeSize);
       
  4107 }
       
  4108 
       
  4109 
       
  4110 /*!
       
  4111     \fn void QPainter::drawRoundRect(const QRect &r, int xRnd = 25, int yRnd = 25)
       
  4112 
       
  4113     \overload
       
  4114     \obsolete
       
  4115 
       
  4116     Draws the rectangle \a r with rounded corners.
       
  4117 */
       
  4118 
       
  4119 /*!
       
  4120     \obsolete
       
  4121 
       
  4122     \fn QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
       
  4123 
       
  4124     \overload
       
  4125 
       
  4126     Draws the rectangle \a x, \a y, \a w, \a h with rounded corners.
       
  4127 */
       
  4128 
       
  4129 /*!
       
  4130     \fn void QPainter::drawEllipse(const QRectF &rectangle)
       
  4131 
       
  4132     Draws the ellipse defined by the given \a rectangle.
       
  4133 
       
  4134     A filled ellipse has a size of \a{rectangle}.\l
       
  4135     {QRect::size()}{size()}. A stroked ellipse has a size of
       
  4136     \a{rectangle}.\l {QRect::size()}{size()} plus the pen width.
       
  4137 
       
  4138     \table 100%
       
  4139     \row
       
  4140     \o \inlineimage qpainter-ellipse.png
       
  4141     \o
       
  4142     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9
       
  4143     \endtable
       
  4144 
       
  4145     \sa drawPie(), {The Coordinate System}
       
  4146 */
       
  4147 void QPainter::drawEllipse(const QRectF &r)
       
  4148 {
       
  4149 #ifdef QT_DEBUG_DRAW
       
  4150     if (qt_show_painter_debug_output)
       
  4151         printf("QPainter::drawEllipse(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height());
       
  4152 #endif
       
  4153     Q_D(QPainter);
       
  4154 
       
  4155     if (!d->engine)
       
  4156         return;
       
  4157 
       
  4158     QRectF rect(r.normalized());
       
  4159     if (rect.isEmpty())
       
  4160         return;
       
  4161 
       
  4162     if (d->extended) {
       
  4163         d->extended->drawEllipse(rect);
       
  4164         return;
       
  4165     }
       
  4166 
       
  4167     d->updateState(d->state);
       
  4168     if (d->state->emulationSpecifier) {
       
  4169         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
       
  4170             && d->state->matrix.type() == QTransform::TxTranslate) {
       
  4171             rect.translate(QPointF(d->state->matrix.dx(), d->state->matrix.dy()));
       
  4172         } else {
       
  4173             QPainterPath path;
       
  4174             path.addEllipse(rect);
       
  4175             d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
       
  4176             return;
       
  4177         }
       
  4178     }
       
  4179 
       
  4180     d->engine->drawEllipse(rect);
       
  4181 }
       
  4182 
       
  4183 /*!
       
  4184     \fn QPainter::drawEllipse(const QRect &rectangle)
       
  4185 
       
  4186     \overload
       
  4187 
       
  4188     Draws the ellipse defined by the given \a rectangle.
       
  4189 */
       
  4190 void QPainter::drawEllipse(const QRect &r)
       
  4191 {
       
  4192 #ifdef QT_DEBUG_DRAW
       
  4193     if (qt_show_painter_debug_output)
       
  4194         printf("QPainter::drawEllipse(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
       
  4195 #endif
       
  4196     Q_D(QPainter);
       
  4197 
       
  4198     if (!d->engine)
       
  4199         return;
       
  4200 
       
  4201     QRect rect(r.normalized());
       
  4202     if (rect.isEmpty())
       
  4203         return;
       
  4204 
       
  4205     if (d->extended) {
       
  4206         d->extended->drawEllipse(rect);
       
  4207         return;
       
  4208     }
       
  4209 
       
  4210     d->updateState(d->state);
       
  4211 
       
  4212     if (d->state->emulationSpecifier) {
       
  4213         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
       
  4214             && d->state->matrix.type() == QTransform::TxTranslate) {
       
  4215             rect.translate(QPoint(qRound(d->state->matrix.dx()), qRound(d->state->matrix.dy())));
       
  4216         } else {
       
  4217             QPainterPath path;
       
  4218             path.addEllipse(rect);
       
  4219             d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
       
  4220             return;
       
  4221         }
       
  4222     }
       
  4223 
       
  4224     d->engine->drawEllipse(rect);
       
  4225 }
       
  4226 
       
  4227 /*!
       
  4228     \fn QPainter::drawEllipse(int x, int y, int width, int height)
       
  4229 
       
  4230     \overload
       
  4231 
       
  4232     Draws the ellipse defined by the rectangle beginning at (\a{x},
       
  4233     \a{y}) with the given \a width and \a height.
       
  4234 */
       
  4235 
       
  4236 /*!
       
  4237     \since 4.4
       
  4238 
       
  4239     \fn QPainter::drawEllipse(const QPointF &center, qreal rx, qreal ry)
       
  4240 
       
  4241     \overload
       
  4242 
       
  4243     Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
       
  4244 */
       
  4245 
       
  4246 /*!
       
  4247     \since 4.4
       
  4248 
       
  4249     \fn QPainter::drawEllipse(const QPoint &center, int rx, int ry)
       
  4250 
       
  4251     \overload
       
  4252 
       
  4253     Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
       
  4254 */
       
  4255 
       
  4256 /*!
       
  4257     \fn void QPainter::drawArc(const QRectF &rectangle, int startAngle, int spanAngle)
       
  4258 
       
  4259     Draws the arc defined by the given \a rectangle, \a startAngle and
       
  4260     \a spanAngle.
       
  4261 
       
  4262     The \a startAngle and \a spanAngle must be specified in 1/16th of
       
  4263     a degree, i.e. a full circle equals 5760 (16 * 360). Positive
       
  4264     values for the angles mean counter-clockwise while negative values
       
  4265     mean the clockwise direction. Zero degrees is at the 3 o'clock
       
  4266     position.
       
  4267 
       
  4268     \table 100%
       
  4269     \row
       
  4270     \o \inlineimage qpainter-arc.png
       
  4271     \o
       
  4272     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10
       
  4273     \endtable
       
  4274 
       
  4275     \sa drawPie(), drawChord(), {The Coordinate System}
       
  4276 */
       
  4277 
       
  4278 void QPainter::drawArc(const QRectF &r, int a, int alen)
       
  4279 {
       
  4280 #ifdef QT_DEBUG_DRAW
       
  4281     if (qt_show_painter_debug_output)
       
  4282         printf("QPainter::drawArc(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
       
  4283            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
       
  4284 #endif
       
  4285     Q_D(QPainter);
       
  4286 
       
  4287     if (!d->engine)
       
  4288         return;
       
  4289 
       
  4290     QRectF rect = r.normalized();
       
  4291 
       
  4292     QPainterPath path;
       
  4293     path.arcMoveTo(rect, a/16.0);
       
  4294     path.arcTo(rect, a/16.0, alen/16.0);
       
  4295     strokePath(path, d->state->pen);
       
  4296 }
       
  4297 
       
  4298 /*! \fn void QPainter::drawArc(const QRect &rectangle, int startAngle,
       
  4299                                int spanAngle)
       
  4300 
       
  4301     \overload
       
  4302 
       
  4303     Draws the arc defined by the given \a rectangle, \a startAngle and
       
  4304     \a spanAngle.
       
  4305 */
       
  4306 
       
  4307 /*!
       
  4308     \fn void QPainter::drawArc(int x, int y, int width, int height,
       
  4309                                int startAngle, int spanAngle)
       
  4310 
       
  4311     \overload
       
  4312 
       
  4313     Draws the arc defined by the rectangle beginning at (\a x, \a y)
       
  4314     with the specified \a width and \a height, and the given \a
       
  4315     startAngle and \a spanAngle.
       
  4316 */
       
  4317 
       
  4318 /*!
       
  4319     \fn void QPainter::drawPie(const QRectF &rectangle, int startAngle, int spanAngle)
       
  4320 
       
  4321     Draws a pie defined by the given \a rectangle, \a startAngle and
       
  4322     and \a spanAngle.
       
  4323 
       
  4324     The pie is filled with the current brush().
       
  4325 
       
  4326     The startAngle and spanAngle must be specified in 1/16th of a
       
  4327     degree, i.e. a full circle equals 5760 (16 * 360). Positive values
       
  4328     for the angles mean counter-clockwise while negative values mean
       
  4329     the clockwise direction. Zero degrees is at the 3 o'clock
       
  4330     position.
       
  4331 
       
  4332     \table 100%
       
  4333     \row
       
  4334     \o \inlineimage qpainter-pie.png
       
  4335     \o
       
  4336     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11
       
  4337     \endtable
       
  4338 
       
  4339     \sa drawEllipse(), drawChord(), {The Coordinate System}
       
  4340 */
       
  4341 void QPainter::drawPie(const QRectF &r, int a, int alen)
       
  4342 {
       
  4343 #ifdef QT_DEBUG_DRAW
       
  4344     if (qt_show_painter_debug_output)
       
  4345         printf("QPainter::drawPie(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
       
  4346            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
       
  4347 #endif
       
  4348     Q_D(QPainter);
       
  4349 
       
  4350     if (!d->engine)
       
  4351         return;
       
  4352 
       
  4353     if (a > (360*16)) {
       
  4354         a = a % (360*16);
       
  4355     } else if (a < 0) {
       
  4356         a = a % (360*16);
       
  4357         if (a < 0) a += (360*16);
       
  4358     }
       
  4359 
       
  4360     QRectF rect = r.normalized();
       
  4361 
       
  4362     QPainterPath path;
       
  4363     path.moveTo(rect.center());
       
  4364     path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0);
       
  4365     path.closeSubpath();
       
  4366     drawPath(path);
       
  4367 
       
  4368 }
       
  4369 
       
  4370 /*!
       
  4371     \fn void QPainter::drawPie(const QRect &rectangle, int startAngle, int spanAngle)
       
  4372     \overload
       
  4373 
       
  4374     Draws a pie defined by the given \a rectangle, \a startAngle and
       
  4375     and \a spanAngle.
       
  4376 */
       
  4377 
       
  4378 /*!
       
  4379     \fn void QPainter::drawPie(int x, int y, int width, int height, int
       
  4380     startAngle, int spanAngle)
       
  4381 
       
  4382     \overload
       
  4383 
       
  4384     Draws the pie defined by the rectangle beginning at (\a x, \a y) with
       
  4385     the specified \a width and \a height, and the given \a startAngle and
       
  4386     \a spanAngle.
       
  4387 */
       
  4388 
       
  4389 /*!
       
  4390     \fn void QPainter::drawChord(const QRectF &rectangle, int startAngle, int spanAngle)
       
  4391 
       
  4392     Draws the chord defined by the given \a rectangle, \a startAngle and
       
  4393     \a spanAngle.  The chord is filled with the current brush().
       
  4394 
       
  4395     The startAngle and spanAngle must be specified in 1/16th of a
       
  4396     degree, i.e. a full circle equals 5760 (16 * 360). Positive values
       
  4397     for the angles mean counter-clockwise while negative values mean
       
  4398     the clockwise direction. Zero degrees is at the 3 o'clock
       
  4399     position.
       
  4400 
       
  4401     \table 100%
       
  4402     \row
       
  4403     \o \inlineimage qpainter-chord.png
       
  4404     \o
       
  4405     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12
       
  4406     \endtable
       
  4407 
       
  4408     \sa drawArc(), drawPie(), {The Coordinate System}
       
  4409 */
       
  4410 void QPainter::drawChord(const QRectF &r, int a, int alen)
       
  4411 {
       
  4412 #ifdef QT_DEBUG_DRAW
       
  4413     if (qt_show_painter_debug_output)
       
  4414         printf("QPainter::drawChord(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
       
  4415            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
       
  4416 #endif
       
  4417     Q_D(QPainter);
       
  4418 
       
  4419     if (!d->engine)
       
  4420         return;
       
  4421 
       
  4422     QRectF rect = r.normalized();
       
  4423 
       
  4424     QPainterPath path;
       
  4425     path.arcMoveTo(rect, a/16.0);
       
  4426     path.arcTo(rect, a/16.0, alen/16.0);
       
  4427     path.closeSubpath();
       
  4428     drawPath(path);
       
  4429 }
       
  4430 /*!
       
  4431     \fn void QPainter::drawChord(const QRect &rectangle, int startAngle, int spanAngle)
       
  4432 
       
  4433     \overload
       
  4434 
       
  4435     Draws the chord defined by the given \a rectangle, \a startAngle and
       
  4436     \a spanAngle.
       
  4437 */
       
  4438 
       
  4439 /*!
       
  4440     \fn void QPainter::drawChord(int x, int y, int width, int height, int
       
  4441     startAngle, int spanAngle)
       
  4442 
       
  4443     \overload
       
  4444 
       
  4445    Draws the chord defined by the rectangle beginning at (\a x, \a y)
       
  4446    with the specified \a width and \a height, and the given \a
       
  4447    startAngle and \a spanAngle.
       
  4448 */
       
  4449 
       
  4450 #ifdef QT3_SUPPORT
       
  4451 /*!
       
  4452     \fn void QPainter::drawLineSegments(const QPolygon &polygon, int
       
  4453     index, int count)
       
  4454 
       
  4455     Draws \a count separate lines from points defined by the \a
       
  4456     polygon, starting at \a{polygon}\e{[index]} (\a index defaults to
       
  4457     0). If \a count is -1 (the default) all points until the end of
       
  4458     the array are used.
       
  4459 
       
  4460     Use drawLines() combined with QPolygon::constData() instead.
       
  4461 
       
  4462     \oldcode
       
  4463         QPainter painter(this);
       
  4464         painter.drawLineSegments(polygon, index, count);
       
  4465     \newcode
       
  4466         int lineCount = (count == -1) ?  (polygon.size() - index) / 2  : count;
       
  4467 
       
  4468         QPainter painter(this);
       
  4469         painter.drawLines(polygon.constData() + index * 2, lineCount);
       
  4470     \endcode
       
  4471 */
       
  4472 
       
  4473 void QPainter::drawLineSegments(const QPolygon &a, int index, int nlines)
       
  4474 {
       
  4475 #ifdef QT_DEBUG_DRAW
       
  4476     if (qt_show_painter_debug_output)
       
  4477         printf("QPainter::drawLineSegments(), count=%d\n", a.size()/2);
       
  4478 #endif
       
  4479     Q_D(QPainter);
       
  4480 
       
  4481     if (!d->engine)
       
  4482         return;
       
  4483 
       
  4484     if (nlines < 0)
       
  4485         nlines = a.size()/2 - index/2;
       
  4486     if (index + nlines*2 > (int)a.size())
       
  4487         nlines = (a.size() - index)/2;
       
  4488     if (nlines < 1 || index < 0)
       
  4489         return;
       
  4490 
       
  4491     if (d->extended) {
       
  4492         // FALCON: Use QVectorPath
       
  4493         QVector<QLineF> lines;
       
  4494         for (int i=index; i<index + nlines*2; i+=2)
       
  4495             lines << QLineF(a.at(i), a.at(i+1));
       
  4496         d->extended->drawLines(lines.data(), lines.size());
       
  4497         return;
       
  4498     }
       
  4499 
       
  4500     d->updateState(d->state);
       
  4501 
       
  4502     QVector<QLineF> lines;
       
  4503     if (d->state->emulationSpecifier) {
       
  4504         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
       
  4505             && d->state->matrix.type() == QTransform::TxTranslate) {
       
  4506             QPointF offset(d->state->matrix.dx(), d->state->matrix.dy());
       
  4507             for (int i=index; i<index + nlines*2; i+=2)
       
  4508                 lines << QLineF(a.at(i) + offset, a.at(i+1) + offset);
       
  4509         } else {
       
  4510             QPainterPath linesPath;
       
  4511             for (int i=index; i<index + nlines*2; i+=2) {
       
  4512                 linesPath.moveTo(a.at(i));
       
  4513                 linesPath.lineTo(a.at(i+1));
       
  4514             }
       
  4515             d->draw_helper(linesPath, QPainterPrivate::StrokeDraw);
       
  4516             return;
       
  4517         }
       
  4518     } else {
       
  4519         for (int i=index; i<index + nlines*2; i+=2)
       
  4520             lines << QLineF(a.at(i), a.at(i+1));
       
  4521     }
       
  4522 
       
  4523     d->engine->drawLines(lines.data(), lines.size());
       
  4524 }
       
  4525 #endif // QT3_SUPPORT
       
  4526 
       
  4527 /*!
       
  4528     Draws the first \a lineCount lines in the array \a lines
       
  4529     using the current pen.
       
  4530 
       
  4531     \sa drawLine(), drawPolyline()
       
  4532 */
       
  4533 void QPainter::drawLines(const QLineF *lines, int lineCount)
       
  4534 {
       
  4535 #ifdef QT_DEBUG_DRAW
       
  4536     if (qt_show_painter_debug_output)
       
  4537         printf("QPainter::drawLines(), line count=%d\n", lineCount);
       
  4538 #endif
       
  4539 
       
  4540     Q_D(QPainter);
       
  4541 
       
  4542     if (!d->engine || lineCount < 1)
       
  4543         return;
       
  4544 
       
  4545     if (d->extended) {
       
  4546         d->extended->drawLines(lines, lineCount);
       
  4547         return;
       
  4548     }
       
  4549 
       
  4550     d->updateState(d->state);
       
  4551 
       
  4552     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
       
  4553 
       
  4554     if (lineEmulation) {
       
  4555         if (lineEmulation == QPaintEngine::PrimitiveTransform
       
  4556             && d->state->matrix.type() == QTransform::TxTranslate) {
       
  4557             for (int i = 0; i < lineCount; ++i) {
       
  4558                 QLineF line = lines[i];
       
  4559                 line.translate(d->state->matrix.dx(), d->state->matrix.dy());
       
  4560                 d->engine->drawLines(&line, 1);
       
  4561             }
       
  4562         } else {
       
  4563             QPainterPath linePath;
       
  4564             for (int i = 0; i < lineCount; ++i) {
       
  4565                 linePath.moveTo(lines[i].p1());
       
  4566                 linePath.lineTo(lines[i].p2());
       
  4567             }
       
  4568             d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
       
  4569         }
       
  4570         return;
       
  4571     }
       
  4572     d->engine->drawLines(lines, lineCount);
       
  4573 }
       
  4574 
       
  4575 /*!
       
  4576     \fn void QPainter::drawLines(const QLine *lines, int lineCount)
       
  4577     \overload
       
  4578 
       
  4579     Draws the first \a lineCount lines in the array \a lines
       
  4580     using the current pen.
       
  4581 */
       
  4582 void QPainter::drawLines(const QLine *lines, int lineCount)
       
  4583 {
       
  4584 #ifdef QT_DEBUG_DRAW
       
  4585     if (qt_show_painter_debug_output)
       
  4586         printf("QPainter::drawLine(), line count=%d\n", lineCount);
       
  4587 #endif
       
  4588 
       
  4589     Q_D(QPainter);
       
  4590 
       
  4591     if (!d->engine || lineCount < 1)
       
  4592         return;
       
  4593 
       
  4594     if (d->extended) {
       
  4595         d->extended->drawLines(lines, lineCount);
       
  4596         return;
       
  4597     }
       
  4598 
       
  4599     d->updateState(d->state);
       
  4600 
       
  4601     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
       
  4602 
       
  4603     if (lineEmulation) {
       
  4604         if (lineEmulation == QPaintEngine::PrimitiveTransform
       
  4605             && d->state->matrix.type() == QTransform::TxTranslate) {
       
  4606             for (int i = 0; i < lineCount; ++i) {
       
  4607                 QLineF line = lines[i];
       
  4608                 line.translate(d->state->matrix.dx(), d->state->matrix.dy());
       
  4609                 d->engine->drawLines(&line, 1);
       
  4610             }
       
  4611         } else {
       
  4612             QPainterPath linePath;
       
  4613             for (int i = 0; i < lineCount; ++i) {
       
  4614                 linePath.moveTo(lines[i].p1());
       
  4615                 linePath.lineTo(lines[i].p2());
       
  4616             }
       
  4617             d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
       
  4618         }
       
  4619         return;
       
  4620     }
       
  4621     d->engine->drawLines(lines, lineCount);
       
  4622 }
       
  4623 
       
  4624 /*!
       
  4625     \overload
       
  4626 
       
  4627     Draws the first \a lineCount lines in the array \a pointPairs
       
  4628     using the current pen.  The lines are specified as pairs of points
       
  4629     so the number of entries in \a pointPairs must be at least \a
       
  4630     lineCount * 2.
       
  4631 */
       
  4632 void QPainter::drawLines(const QPointF *pointPairs, int lineCount)
       
  4633 {
       
  4634     Q_ASSERT(sizeof(QLineF) == 2*sizeof(QPointF));
       
  4635 
       
  4636     drawLines((QLineF*)pointPairs, lineCount);
       
  4637 }
       
  4638 
       
  4639 /*!
       
  4640     \overload
       
  4641 
       
  4642     Draws the first \a lineCount lines in the array \a pointPairs
       
  4643     using the current pen.
       
  4644 */
       
  4645 void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
       
  4646 {
       
  4647     Q_ASSERT(sizeof(QLine) == 2*sizeof(QPoint));
       
  4648 
       
  4649     drawLines((QLine*)pointPairs, lineCount);
       
  4650 }
       
  4651 
       
  4652 
       
  4653 /*!
       
  4654     \fn void QPainter::drawLines(const QVector<QPointF> &pointPairs)
       
  4655     \overload
       
  4656 
       
  4657     Draws a line for each pair of points in the vector \a pointPairs
       
  4658     using the current pen. If there is an odd number of points in the
       
  4659     array, the last point will be ignored.
       
  4660 */
       
  4661 
       
  4662 /*!
       
  4663     \fn void QPainter::drawLines(const QVector<QPoint> &pointPairs)
       
  4664     \overload
       
  4665 
       
  4666     Draws a line for each pair of points in the vector \a pointPairs
       
  4667     using the current pen.
       
  4668 */
       
  4669 
       
  4670 /*!
       
  4671     \fn void QPainter::drawLines(const QVector<QLineF> &lines)
       
  4672     \overload
       
  4673 
       
  4674     Draws the set of lines defined by the list \a lines using the
       
  4675     current pen and brush.
       
  4676 */
       
  4677 
       
  4678 /*!
       
  4679     \fn void QPainter::drawLines(const QVector<QLine> &lines)
       
  4680     \overload
       
  4681 
       
  4682     Draws the set of lines defined by the list \a lines using the
       
  4683     current pen and brush.
       
  4684 */
       
  4685 
       
  4686 /*!
       
  4687     Draws the polyline defined by the first \a pointCount points in \a
       
  4688     points using the current pen.
       
  4689 
       
  4690     Note that unlike the drawPolygon() function the last point is \e
       
  4691     not connected to the first, neither is the polyline filled.
       
  4692 
       
  4693     \table 100%
       
  4694     \row
       
  4695     \o
       
  4696     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13
       
  4697     \endtable
       
  4698 
       
  4699     \sa drawLines(), drawPolygon(), {The Coordinate System}
       
  4700 */
       
  4701 void QPainter::drawPolyline(const QPointF *points, int pointCount)
       
  4702 {
       
  4703 #ifdef QT_DEBUG_DRAW
       
  4704     if (qt_show_painter_debug_output)
       
  4705         printf("QPainter::drawPolyline(), count=%d\n", pointCount);
       
  4706 #endif
       
  4707     Q_D(QPainter);
       
  4708 
       
  4709     if (!d->engine || pointCount < 2)
       
  4710         return;
       
  4711 
       
  4712     if (d->extended) {
       
  4713         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
       
  4714         return;
       
  4715     }
       
  4716 
       
  4717     d->updateState(d->state);
       
  4718 
       
  4719     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
       
  4720 
       
  4721     if (lineEmulation) {
       
  4722         // ###
       
  4723 //         if (lineEmulation == QPaintEngine::PrimitiveTransform
       
  4724 //             && d->state->matrix.type() == QTransform::TxTranslate) {
       
  4725 //         } else {
       
  4726         QPainterPath polylinePath(points[0]);
       
  4727         for (int i=1; i<pointCount; ++i)
       
  4728             polylinePath.lineTo(points[i]);
       
  4729         d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
       
  4730 //         }
       
  4731     } else {
       
  4732         d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
       
  4733     }
       
  4734 }
       
  4735 
       
  4736 /*!
       
  4737     \overload
       
  4738 
       
  4739     Draws the polyline defined by the first \a pointCount points in \a
       
  4740     points using the current pen.
       
  4741  */
       
  4742 void QPainter::drawPolyline(const QPoint *points, int pointCount)
       
  4743 {
       
  4744 #ifdef QT_DEBUG_DRAW
       
  4745     if (qt_show_painter_debug_output)
       
  4746         printf("QPainter::drawPolyline(), count=%d\n", pointCount);
       
  4747 #endif
       
  4748     Q_D(QPainter);
       
  4749 
       
  4750     if (!d->engine || pointCount < 2)
       
  4751         return;
       
  4752 
       
  4753     if (d->extended) {
       
  4754         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
       
  4755         return;
       
  4756     }
       
  4757 
       
  4758     d->updateState(d->state);
       
  4759 
       
  4760     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
       
  4761 
       
  4762     if (lineEmulation) {
       
  4763         // ###
       
  4764 //         if (lineEmulation == QPaintEngine::PrimitiveTransform
       
  4765 //             && d->state->matrix.type() == QTransform::TxTranslate) {
       
  4766 //         } else {
       
  4767         QPainterPath polylinePath(points[0]);
       
  4768         for (int i=1; i<pointCount; ++i)
       
  4769             polylinePath.lineTo(points[i]);
       
  4770         d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
       
  4771 //         }
       
  4772     } else {
       
  4773         d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
       
  4774     }
       
  4775 }
       
  4776 
       
  4777 /*!
       
  4778     \fn void QPainter::drawPolyline(const QPolygon &polygon, int index, int
       
  4779     count)
       
  4780 
       
  4781     \overload
       
  4782     \compat
       
  4783 
       
  4784     Draws the polyline defined by the \a count lines of the given \a
       
  4785     polygon starting at \a index (\a index defaults to 0).
       
  4786 
       
  4787     Use drawPolyline() combined with QPolygon::constData() instead.
       
  4788 
       
  4789     \oldcode
       
  4790         QPainter painter(this);
       
  4791         painter.drawPolyline(polygon, index, count);
       
  4792     \newcode
       
  4793         int pointCount = (count == -1) ?  polygon.size() - index : count;
       
  4794 
       
  4795         QPainter painter(this);
       
  4796         painter.drawPolyline(polygon.constData() + index, pointCount);
       
  4797     \endcode
       
  4798 */
       
  4799 
       
  4800 /*!
       
  4801     \fn void QPainter::drawPolyline(const QPolygonF &points)
       
  4802 
       
  4803     \overload
       
  4804 
       
  4805     Draws the polyline defined by the given \a points using the
       
  4806     current pen.
       
  4807 */
       
  4808 
       
  4809 /*!
       
  4810     \fn void QPainter::drawPolyline(const QPolygon &points)
       
  4811 
       
  4812     \overload
       
  4813 
       
  4814     Draws the polyline defined by the given \a points using the
       
  4815     current pen.
       
  4816 */
       
  4817 
       
  4818 /*!
       
  4819     Draws the polygon defined by the first \a pointCount points in the
       
  4820     array \a points using the current pen and brush.
       
  4821 
       
  4822     \table 100%
       
  4823     \row
       
  4824     \o \inlineimage qpainter-polygon.png
       
  4825     \o
       
  4826     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 14
       
  4827     \endtable
       
  4828 
       
  4829     The first point is implicitly connected to the last point, and the
       
  4830     polygon is filled with the current brush().
       
  4831 
       
  4832     If \a fillRule is Qt::WindingFill, the polygon is filled using the
       
  4833     winding fill algorithm.  If \a fillRule is Qt::OddEvenFill, the
       
  4834     polygon is filled using the odd-even fill algorithm. See
       
  4835     \l{Qt::FillRule} for a more detailed description of these fill
       
  4836     rules.
       
  4837 
       
  4838     \sa  drawConvexPolygon(), drawPolyline(), {The Coordinate System}
       
  4839 */
       
  4840 void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
       
  4841 {
       
  4842 #ifdef QT_DEBUG_DRAW
       
  4843     if (qt_show_painter_debug_output)
       
  4844         printf("QPainter::drawPolygon(), count=%d\n", pointCount);
       
  4845 #endif
       
  4846 
       
  4847     Q_D(QPainter);
       
  4848 
       
  4849     if (!d->engine || pointCount < 2)
       
  4850         return;
       
  4851 
       
  4852     if (d->extended) {
       
  4853         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
       
  4854         return;
       
  4855     }
       
  4856 
       
  4857     d->updateState(d->state);
       
  4858 
       
  4859     uint emulationSpecifier = d->state->emulationSpecifier;
       
  4860 
       
  4861     if (emulationSpecifier) {
       
  4862         QPainterPath polygonPath(points[0]);
       
  4863         for (int i=1; i<pointCount; ++i)
       
  4864             polygonPath.lineTo(points[i]);
       
  4865         polygonPath.closeSubpath();
       
  4866         polygonPath.setFillRule(fillRule);
       
  4867         d->draw_helper(polygonPath);
       
  4868         return;
       
  4869     }
       
  4870 
       
  4871     d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
       
  4872 }
       
  4873 
       
  4874 /*! \overload
       
  4875 
       
  4876     Draws the polygon defined by the first \a pointCount points in the
       
  4877     array \a points.
       
  4878 */
       
  4879 void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
       
  4880 {
       
  4881 #ifdef QT_DEBUG_DRAW
       
  4882     if (qt_show_painter_debug_output)
       
  4883         printf("QPainter::drawPolygon(), count=%d\n", pointCount);
       
  4884 #endif
       
  4885 
       
  4886     Q_D(QPainter);
       
  4887 
       
  4888     if (!d->engine || pointCount < 2)
       
  4889         return;
       
  4890 
       
  4891     if (d->extended) {
       
  4892         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
       
  4893         return;
       
  4894     }
       
  4895 
       
  4896     d->updateState(d->state);
       
  4897 
       
  4898     uint emulationSpecifier = d->state->emulationSpecifier;
       
  4899 
       
  4900     if (emulationSpecifier) {
       
  4901         QPainterPath polygonPath(points[0]);
       
  4902         for (int i=1; i<pointCount; ++i)
       
  4903             polygonPath.lineTo(points[i]);
       
  4904         polygonPath.closeSubpath();
       
  4905         polygonPath.setFillRule(fillRule);
       
  4906         d->draw_helper(polygonPath);
       
  4907         return;
       
  4908     }
       
  4909 
       
  4910     d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
       
  4911 }
       
  4912 
       
  4913 /*! \fn void QPainter::drawPolygon(const QPolygonF &polygon, bool winding, int index = 0,
       
  4914                                    int count = -1)
       
  4915     \compat
       
  4916     \overload
       
  4917 
       
  4918     Use drawPolygon() combined with QPolygonF::constData() instead.
       
  4919 
       
  4920     \oldcode
       
  4921         QPainter painter(this);
       
  4922         painter.drawPolygon(polygon, winding, index, count);
       
  4923     \newcode
       
  4924         int pointCount = (count == -1) ?  polygon.size() - index : count;
       
  4925         int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;
       
  4926 
       
  4927         QPainter painter(this);
       
  4928         painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
       
  4929     \endcode
       
  4930 */
       
  4931 
       
  4932 /*! \fn void QPainter::drawPolygon(const QPolygon &polygon, bool winding,
       
  4933                                    int index = 0, int count = -1)
       
  4934 
       
  4935     \compat
       
  4936     \overload
       
  4937 
       
  4938     Use drawPolygon() combined with QPolygon::constData() instead.
       
  4939 
       
  4940     \oldcode
       
  4941         QPainter painter(this);
       
  4942         painter.drawPolygon(polygon, winding, index, count);
       
  4943     \newcode
       
  4944         int pointCount = (count == -1) ?  polygon.size() - index : count;
       
  4945         int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;
       
  4946 
       
  4947         QPainter painter(this);
       
  4948         painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
       
  4949     \endcode
       
  4950 */
       
  4951 
       
  4952 /*! \fn void QPainter::drawPolygon(const QPolygonF &points, Qt::FillRule fillRule)
       
  4953 
       
  4954     \overload
       
  4955 
       
  4956     Draws the polygon defined by the given \a points using the fill
       
  4957     rule \a fillRule.
       
  4958 */
       
  4959 
       
  4960 /*! \fn void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule)
       
  4961 
       
  4962     \overload
       
  4963 
       
  4964     Draws the polygon defined by the given \a points using the fill
       
  4965     rule \a fillRule.
       
  4966 */
       
  4967 
       
  4968 /*!
       
  4969     \fn void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
       
  4970 
       
  4971     Draws the convex polygon defined by the first \a pointCount points
       
  4972     in the array \a points using the current pen.
       
  4973 
       
  4974     \table 100%
       
  4975     \row
       
  4976     \o \inlineimage qpainter-polygon.png
       
  4977     \o
       
  4978     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 15
       
  4979     \endtable
       
  4980 
       
  4981     The first point is implicitly connected to the last point, and the
       
  4982     polygon is filled with the current brush().  If the supplied
       
  4983     polygon is not convex, i.e. it contains at least one angle larger
       
  4984     than 180 degrees, the results are undefined.
       
  4985 
       
  4986     On some platforms (e.g. X11), the drawConvexPolygon() function can
       
  4987     be faster than the drawPolygon() function.
       
  4988 
       
  4989     \sa drawPolygon(), drawPolyline(), {The Coordinate System}
       
  4990 */
       
  4991 
       
  4992 /*!
       
  4993     \fn void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
       
  4994     \overload
       
  4995 
       
  4996     Draws the convex polygon defined by the first \a pointCount points
       
  4997     in the array \a points using the current pen.
       
  4998 */
       
  4999 
       
  5000 /*!
       
  5001     \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon)
       
  5002 
       
  5003     \overload
       
  5004 
       
  5005     Draws the convex polygon defined by \a polygon using the current
       
  5006     pen and brush.
       
  5007 */
       
  5008 
       
  5009 /*!
       
  5010     \fn void QPainter::drawConvexPolygon(const QPolygon &polygon)
       
  5011     \overload
       
  5012 
       
  5013     Draws the convex polygon defined by \a polygon using the current
       
  5014     pen and brush.
       
  5015 */
       
  5016 
       
  5017 /*!
       
  5018     \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon, int
       
  5019     index, int count)
       
  5020 
       
  5021     \compat
       
  5022     \overload
       
  5023 
       
  5024     Use drawConvexPolygon() combined with QPolygonF::constData()
       
  5025     instead.
       
  5026 
       
  5027     \oldcode
       
  5028         QPainter painter(this);
       
  5029         painter.drawConvexPolygon(polygon, index, count);
       
  5030     \newcode
       
  5031         int pointCount = (count == -1) ?  polygon.size() - index : count;
       
  5032 
       
  5033         QPainter painter(this);
       
  5034         painter.drawConvexPolygon(polygon.constData() + index, pointCount);
       
  5035     \endcode
       
  5036 */
       
  5037 
       
  5038 /*!
       
  5039     \fn void QPainter::drawConvexPolygon(const QPolygon &polygon, int
       
  5040     index, int count)
       
  5041 
       
  5042     \compat
       
  5043     \overload
       
  5044 
       
  5045     Use drawConvexPolygon() combined with QPolygon::constData()
       
  5046     instead.
       
  5047 
       
  5048     \oldcode
       
  5049         QPainter painter(this);
       
  5050         painter.drawConvexPolygon(polygon, index, count);
       
  5051     \newcode
       
  5052         int pointCount = (count == -1) ?  polygon.size() - index : count;
       
  5053 
       
  5054         QPainter painter(this);
       
  5055         painter.drawConvexPolygon(polygon.constData() + index, pointCount);
       
  5056     \endcode
       
  5057 */
       
  5058 
       
  5059 void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
       
  5060 {
       
  5061 #ifdef QT_DEBUG_DRAW
       
  5062     if (qt_show_painter_debug_output)
       
  5063         printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
       
  5064 #endif
       
  5065 
       
  5066     Q_D(QPainter);
       
  5067 
       
  5068     if (!d->engine || pointCount < 2)
       
  5069         return;
       
  5070 
       
  5071     if (d->extended) {
       
  5072         d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
       
  5073         return;
       
  5074     }
       
  5075 
       
  5076     d->updateState(d->state);
       
  5077 
       
  5078     uint emulationSpecifier = d->state->emulationSpecifier;
       
  5079 
       
  5080     if (emulationSpecifier) {
       
  5081         QPainterPath polygonPath(points[0]);
       
  5082         for (int i=1; i<pointCount; ++i)
       
  5083             polygonPath.lineTo(points[i]);
       
  5084         polygonPath.closeSubpath();
       
  5085         polygonPath.setFillRule(Qt::WindingFill);
       
  5086         d->draw_helper(polygonPath);
       
  5087         return;
       
  5088     }
       
  5089 
       
  5090     d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
       
  5091 }
       
  5092 
       
  5093 void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
       
  5094 {
       
  5095 #ifdef QT_DEBUG_DRAW
       
  5096     if (qt_show_painter_debug_output)
       
  5097         printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
       
  5098 #endif
       
  5099 
       
  5100     Q_D(QPainter);
       
  5101 
       
  5102     if (!d->engine || pointCount < 2)
       
  5103         return;
       
  5104 
       
  5105     if (d->extended) {
       
  5106         d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
       
  5107         return;
       
  5108     }
       
  5109 
       
  5110     d->updateState(d->state);
       
  5111 
       
  5112     uint emulationSpecifier = d->state->emulationSpecifier;
       
  5113 
       
  5114     if (emulationSpecifier) {
       
  5115         QPainterPath polygonPath(points[0]);
       
  5116         for (int i=1; i<pointCount; ++i)
       
  5117             polygonPath.lineTo(points[i]);
       
  5118         polygonPath.closeSubpath();
       
  5119         polygonPath.setFillRule(Qt::WindingFill);
       
  5120         d->draw_helper(polygonPath);
       
  5121         return;
       
  5122     }
       
  5123 
       
  5124     d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
       
  5125 }
       
  5126 
       
  5127 static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransform &m)
       
  5128 {
       
  5129     return m.inverted().map(QPointF(m.map(p).toPoint()));
       
  5130 }
       
  5131 
       
  5132 /*!
       
  5133     \fn void QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
       
  5134 
       
  5135     Draws the rectangular portion \a source of the given \a pixmap
       
  5136     into the given \a target in the paint device.
       
  5137 
       
  5138     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
       
  5139 
       
  5140     \table 100%
       
  5141     \row
       
  5142     \o
       
  5143     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 16
       
  5144     \endtable
       
  5145 
       
  5146     If \a pixmap is a QBitmap it is drawn with the bits that are "set"
       
  5147     using the pens color. If backgroundMode is Qt::OpaqueMode, the
       
  5148     "unset" bits are drawn using the color of the background brush; if
       
  5149     backgroundMode is Qt::TransparentMode, the "unset" bits are
       
  5150     transparent. Drawing bitmaps with gradient or texture colors is
       
  5151     not supported.
       
  5152 
       
  5153     \sa drawImage()
       
  5154 */
       
  5155 void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
       
  5156 {
       
  5157 #if defined QT_DEBUG_DRAW
       
  5158     if (qt_show_painter_debug_output)
       
  5159         printf("QPainter::drawPixmap(), p=[%.2f,%.2f], pix=[%d,%d]\n",
       
  5160                p.x(), p.y(),
       
  5161                pm.width(), pm.height());
       
  5162 #endif
       
  5163 
       
  5164     Q_D(QPainter);
       
  5165 
       
  5166     if (!d->engine)
       
  5167         return;
       
  5168 
       
  5169 #ifndef QT_NO_DEBUG
       
  5170     qt_painter_thread_test(d->device->devType(), "drawPixmap()");
       
  5171 #endif
       
  5172 
       
  5173     if (d->extended) {
       
  5174         d->extended->drawPixmap(p, pm);
       
  5175         return;
       
  5176     }
       
  5177 
       
  5178     qreal x = p.x();
       
  5179     qreal y = p.y();
       
  5180 
       
  5181     int w = pm.width();
       
  5182     int h = pm.height();
       
  5183 
       
  5184     if (w <= 0)
       
  5185         return;
       
  5186 
       
  5187     // Emulate opaque background for bitmaps
       
  5188     if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
       
  5189         fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
       
  5190     }
       
  5191 
       
  5192     d->updateState(d->state);
       
  5193 
       
  5194     if ((d->state->matrix.type() > QTransform::TxTranslate
       
  5195          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
       
  5196         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
       
  5197         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
       
  5198     {
       
  5199         save();
       
  5200         // If there is no rotation involved we have to make sure we use the
       
  5201         // antialiased and not the aliased coordinate system by rounding the coordinates.
       
  5202         if (d->state->matrix.type() <= QTransform::TxScale) {
       
  5203             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
       
  5204             x = p.x();
       
  5205             y = p.y();
       
  5206         }
       
  5207         translate(x, y);
       
  5208         setBackgroundMode(Qt::TransparentMode);
       
  5209         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
       
  5210         QBrush brush(d->state->pen.color(), pm);
       
  5211         setBrush(brush);
       
  5212         setPen(Qt::NoPen);
       
  5213         setBrushOrigin(QPointF(0, 0));
       
  5214 
       
  5215         drawRect(pm.rect());
       
  5216         restore();
       
  5217     } else {
       
  5218         if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
       
  5219             x += d->state->matrix.dx();
       
  5220             y += d->state->matrix.dy();
       
  5221         }
       
  5222         d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(0, 0, w, h));
       
  5223     }
       
  5224 }
       
  5225 
       
  5226 void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
       
  5227 {
       
  5228 #if defined QT_DEBUG_DRAW
       
  5229     if (qt_show_painter_debug_output)
       
  5230         printf("QPainter::drawPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], source=[%.2f,%.2f,%.2f,%.2f]\n",
       
  5231                r.x(), r.y(), r.width(), r.height(),
       
  5232                pm.width(), pm.height(),
       
  5233                sr.x(), sr.y(), sr.width(), sr.height());
       
  5234 #endif
       
  5235 
       
  5236     Q_D(QPainter);
       
  5237     if (!d->engine || pm.isNull())
       
  5238         return;
       
  5239 #ifndef QT_NO_DEBUG
       
  5240     qt_painter_thread_test(d->device->devType(), "drawPixmap()");
       
  5241 #endif
       
  5242 
       
  5243     qreal x = r.x();
       
  5244     qreal y = r.y();
       
  5245     qreal w = r.width();
       
  5246     qreal h = r.height();
       
  5247     qreal sx = sr.x();
       
  5248     qreal sy = sr.y();
       
  5249     qreal sw = sr.width();
       
  5250     qreal sh = sr.height();
       
  5251 
       
  5252     // Sanity-check clipping
       
  5253     if (sw <= 0)
       
  5254         sw = pm.width() - sx;
       
  5255 
       
  5256     if (sh <= 0)
       
  5257         sh = pm.height() - sy;
       
  5258 
       
  5259     if (w < 0)
       
  5260         w = sw;
       
  5261     if (h < 0)
       
  5262         h = sh;
       
  5263 
       
  5264     if (sx < 0) {
       
  5265         qreal w_ratio = sx * w/sw;
       
  5266         x -= w_ratio;
       
  5267         w += w_ratio;
       
  5268         sw += sx;
       
  5269         sx = 0;
       
  5270     }
       
  5271 
       
  5272     if (sy < 0) {
       
  5273         qreal h_ratio = sy * h/sh;
       
  5274         y -= h_ratio;
       
  5275         h += h_ratio;
       
  5276         sh += sy;
       
  5277         sy = 0;
       
  5278     }
       
  5279 
       
  5280     if (sw + sx > pm.width()) {
       
  5281         qreal delta = sw - (pm.width() - sx);
       
  5282         qreal w_ratio = delta * w/sw;
       
  5283         sw -= delta;
       
  5284         w -= w_ratio;
       
  5285     }
       
  5286 
       
  5287     if (sh + sy > pm.height()) {
       
  5288         qreal delta = sh - (pm.height() - sy);
       
  5289         qreal h_ratio = delta * h/sh;
       
  5290         sh -= delta;
       
  5291         h -= h_ratio;
       
  5292     }
       
  5293 
       
  5294     if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
       
  5295         return;
       
  5296 
       
  5297     if (d->extended) {
       
  5298         d->extended->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
       
  5299         return;
       
  5300     }
       
  5301 
       
  5302     // Emulate opaque background for bitmaps
       
  5303     if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap())
       
  5304         fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
       
  5305 
       
  5306     d->updateState(d->state);
       
  5307 
       
  5308     if ((d->state->matrix.type() > QTransform::TxTranslate
       
  5309          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
       
  5310         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
       
  5311         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity))
       
  5312         || ((sw != w || sh != h) && !d->engine->hasFeature(QPaintEngine::PixmapTransform)))
       
  5313     {
       
  5314         save();
       
  5315         // If there is no rotation involved we have to make sure we use the
       
  5316         // antialiased and not the aliased coordinate system by rounding the coordinates.
       
  5317         if (d->state->matrix.type() <= QTransform::TxScale) {
       
  5318             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
       
  5319             x = p.x();
       
  5320             y = p.y();
       
  5321         }
       
  5322 
       
  5323         if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
       
  5324             sx = qRound(sx);
       
  5325             sy = qRound(sy);
       
  5326             sw = qRound(sw);
       
  5327             sh = qRound(sh);
       
  5328         }
       
  5329 
       
  5330         translate(x, y);
       
  5331         scale(w / sw, h / sh);
       
  5332         setBackgroundMode(Qt::TransparentMode);
       
  5333         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
       
  5334         QBrush brush(d->state->pen.color(), pm);
       
  5335         setBrush(brush);
       
  5336         setPen(Qt::NoPen);
       
  5337         setBrushOrigin(QPointF(-sx, -sy));
       
  5338 
       
  5339         drawRect(QRectF(0, 0, sw, sh));
       
  5340         restore();
       
  5341     } else {
       
  5342         if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
       
  5343             x += d->state->matrix.dx();
       
  5344             y += d->state->matrix.dy();
       
  5345         }
       
  5346         d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
       
  5347     }
       
  5348 }
       
  5349 
       
  5350 
       
  5351 /*!
       
  5352     \fn void QPainter::drawPixmap(const QRect &target, const QPixmap &pixmap,
       
  5353                                   const QRect &source)
       
  5354     \overload
       
  5355 
       
  5356     Draws the rectangular portion \a source of the given \a pixmap
       
  5357     into the given \a target in the paint device.
       
  5358 
       
  5359     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
       
  5360 */
       
  5361 
       
  5362 /*!
       
  5363     \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap,
       
  5364                                   const QRectF &source)
       
  5365     \overload
       
  5366 
       
  5367     Draws the rectangular portion \a source of the given \a pixmap
       
  5368     with its origin at the given \a point.
       
  5369 */
       
  5370 
       
  5371 /*!
       
  5372     \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap,
       
  5373                                   const QRect &source)
       
  5374 
       
  5375     \overload
       
  5376 
       
  5377     Draws the rectangular portion \a source of the given \a pixmap
       
  5378     with its origin at the given \a point.
       
  5379 */
       
  5380 
       
  5381 /*!
       
  5382     \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap)
       
  5383     \overload
       
  5384 
       
  5385     Draws the given \a pixmap with its origin at the given \a point.
       
  5386 */
       
  5387 
       
  5388 /*!
       
  5389     \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap)
       
  5390     \overload
       
  5391 
       
  5392     Draws the given \a pixmap with its origin at the given \a point.
       
  5393 */
       
  5394 
       
  5395 /*!
       
  5396     \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap)
       
  5397 
       
  5398     \overload
       
  5399 
       
  5400     Draws the given \a pixmap at position (\a{x}, \a{y}).
       
  5401 */
       
  5402 
       
  5403 /*!
       
  5404     \fn void QPainter::drawPixmap(const QRect &rectangle, const QPixmap &pixmap)
       
  5405     \overload
       
  5406 
       
  5407     Draws the given \a  pixmap into the given \a rectangle.
       
  5408 
       
  5409     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
       
  5410 */
       
  5411 
       
  5412 /*!
       
  5413     \fn void QPainter::drawPixmap(int x, int y, int width, int height,
       
  5414     const QPixmap &pixmap)
       
  5415 
       
  5416     \overload
       
  5417 
       
  5418     Draws the \a pixmap into the rectangle at position (\a{x}, \a{y})
       
  5419     with  the given \a width and \a height.
       
  5420 */
       
  5421 
       
  5422 /*!
       
  5423     \fn void QPainter::drawPixmap(int x, int y, int w, int h, const QPixmap &pixmap,
       
  5424                                   int sx, int sy, int sw, int sh)
       
  5425 
       
  5426     \overload
       
  5427 
       
  5428     Draws the rectangular portion with the origin (\a{sx}, \a{sy}),
       
  5429     width \a sw and height \a sh, of the given \a pixmap , at the
       
  5430     point (\a{x}, \a{y}), with a width of \a w and a height of \a h.
       
  5431     If sw or sh are equal to zero the width/height of the pixmap
       
  5432     is used and adjusted by the offset sx/sy;
       
  5433 */
       
  5434 
       
  5435 /*!
       
  5436     \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap,
       
  5437                                   int sx, int sy, int sw, int sh)
       
  5438 
       
  5439     \overload
       
  5440 
       
  5441     Draws a pixmap at (\a{x}, \a{y}) by copying a part of the given \a
       
  5442     pixmap into the paint device.
       
  5443 
       
  5444     (\a{x}, \a{y}) specifies the top-left point in the paint device that is
       
  5445     to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
       
  5446     pixmap that is to be drawn. The default is (0, 0).
       
  5447 
       
  5448     (\a{sw}, \a{sh}) specifies the size of the pixmap that is to be drawn.
       
  5449     The default, (0, 0) (and negative) means all the way to the
       
  5450     bottom-right of the pixmap.
       
  5451 */
       
  5452 
       
  5453 void QPainter::drawImage(const QPointF &p, const QImage &image)
       
  5454 {
       
  5455     Q_D(QPainter);
       
  5456 
       
  5457     if (!d->engine || image.isNull())
       
  5458         return;
       
  5459 
       
  5460     if (d->extended) {
       
  5461         d->extended->drawImage(p, image);
       
  5462         return;
       
  5463     }
       
  5464 
       
  5465     qreal x = p.x();
       
  5466     qreal y = p.y();
       
  5467 
       
  5468     int w = image.width();
       
  5469     int h = image.height();
       
  5470 
       
  5471     d->updateState(d->state);
       
  5472 
       
  5473     if (((d->state->matrix.type() > QTransform::TxTranslate)
       
  5474          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
       
  5475         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
       
  5476         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
       
  5477     {
       
  5478         save();
       
  5479         // If there is no rotation involved we have to make sure we use the
       
  5480         // antialiased and not the aliased coordinate system by rounding the coordinates.
       
  5481         if (d->state->matrix.type() <= QTransform::TxScale) {
       
  5482             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
       
  5483             x = p.x();
       
  5484             y = p.y();
       
  5485         }
       
  5486         translate(x, y);
       
  5487         setBackgroundMode(Qt::TransparentMode);
       
  5488         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
       
  5489         QBrush brush(image);
       
  5490         setBrush(brush);
       
  5491         setPen(Qt::NoPen);
       
  5492         setBrushOrigin(QPointF(0, 0));
       
  5493 
       
  5494         drawRect(image.rect());
       
  5495         restore();
       
  5496         return;
       
  5497     }
       
  5498 
       
  5499     if (d->state->matrix.type() == QTransform::TxTranslate
       
  5500         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
       
  5501         x += d->state->matrix.dx();
       
  5502         y += d->state->matrix.dy();
       
  5503     }
       
  5504 
       
  5505     d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(0, 0, w, h), Qt::AutoColor);
       
  5506 }
       
  5507 
       
  5508 void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
       
  5509                          Qt::ImageConversionFlags flags)
       
  5510 {
       
  5511     Q_D(QPainter);
       
  5512 
       
  5513     if (!d->engine || image.isNull())
       
  5514         return;
       
  5515 
       
  5516     qreal x = targetRect.x();
       
  5517     qreal y = targetRect.y();
       
  5518     qreal w = targetRect.width();
       
  5519     qreal h = targetRect.height();
       
  5520     qreal sx = sourceRect.x();
       
  5521     qreal sy = sourceRect.y();
       
  5522     qreal sw = sourceRect.width();
       
  5523     qreal sh = sourceRect.height();
       
  5524 
       
  5525     // Sanity-check clipping
       
  5526     if (sw <= 0)
       
  5527         sw = image.width() - sx;
       
  5528 
       
  5529     if (sh <= 0)
       
  5530         sh = image.height() - sy;
       
  5531 
       
  5532     if (w < 0)
       
  5533         w = sw;
       
  5534     if (h < 0)
       
  5535         h = sh;
       
  5536 
       
  5537     if (sx < 0) {
       
  5538         qreal w_ratio = sx * w/sw;
       
  5539         x -= w_ratio;
       
  5540         w += w_ratio;
       
  5541         sw += sx;
       
  5542         sx = 0;
       
  5543     }
       
  5544 
       
  5545     if (sy < 0) {
       
  5546         qreal h_ratio = sy * h/sh;
       
  5547         y -= h_ratio;
       
  5548         h += h_ratio;
       
  5549         sh += sy;
       
  5550         sy = 0;
       
  5551     }
       
  5552 
       
  5553     if (sw + sx > image.width()) {
       
  5554         qreal delta = sw - (image.width() - sx);
       
  5555         qreal w_ratio = delta * w/sw;
       
  5556         sw -= delta;
       
  5557         w -= w_ratio;
       
  5558     }
       
  5559 
       
  5560     if (sh + sy > image.height()) {
       
  5561         qreal delta = sh - (image.height() - sy);
       
  5562         qreal h_ratio = delta * h/sh;
       
  5563         sh -= delta;
       
  5564         h -= h_ratio;
       
  5565     }
       
  5566 
       
  5567     if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
       
  5568         return;
       
  5569 
       
  5570     if (d->extended) {
       
  5571         d->extended->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
       
  5572         return;
       
  5573     }
       
  5574 
       
  5575     d->updateState(d->state);
       
  5576 
       
  5577     if (((d->state->matrix.type() > QTransform::TxTranslate || (sw != w || sh != h))
       
  5578          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
       
  5579         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
       
  5580         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
       
  5581     {
       
  5582         save();
       
  5583         // If there is no rotation involved we have to make sure we use the
       
  5584         // antialiased and not the aliased coordinate system by rounding the coordinates.
       
  5585         if (d->state->matrix.type() <= QTransform::TxScale) {
       
  5586             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
       
  5587             x = p.x();
       
  5588             y = p.y();
       
  5589         }
       
  5590 
       
  5591         if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
       
  5592             sx = qRound(sx);
       
  5593             sy = qRound(sy);
       
  5594             sw = qRound(sw);
       
  5595             sh = qRound(sh);
       
  5596         }
       
  5597         translate(x, y);
       
  5598         scale(w / sw, h / sh);
       
  5599         setBackgroundMode(Qt::TransparentMode);
       
  5600         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
       
  5601         QBrush brush(image);
       
  5602         setBrush(brush);
       
  5603         setPen(Qt::NoPen);
       
  5604         setBrushOrigin(QPointF(-sx, -sy));
       
  5605 
       
  5606         drawRect(QRectF(0, 0, sw, sh));
       
  5607         restore();
       
  5608         return;
       
  5609     }
       
  5610 
       
  5611     if (d->state->matrix.type() == QTransform::TxTranslate
       
  5612         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
       
  5613         x += d->state->matrix.dx();
       
  5614         y += d->state->matrix.dy();
       
  5615     }
       
  5616 
       
  5617     d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
       
  5618 }
       
  5619 
       
  5620 /*!
       
  5621     \fn void QPainter::drawText(const QPointF &position, const QString &text)
       
  5622 
       
  5623     Draws the given \a text with the currently defined text direction,
       
  5624     beginning at the given \a position.
       
  5625 
       
  5626     This function does not handle the newline character (\n), as it cannot
       
  5627     break text into multiple lines, and it cannot display the newline character.
       
  5628     Use the QPainter::drawText() overload that takes a rectangle instead
       
  5629     if you want to draw multiple lines of text with the newline character, or
       
  5630     if you want the text to be wrapped.
       
  5631 
       
  5632     By default, QPainter draws text anti-aliased.
       
  5633 
       
  5634     \note The y-position is used as the baseline of the font.
       
  5635 */
       
  5636 
       
  5637 void QPainter::drawText(const QPointF &p, const QString &str)
       
  5638 {
       
  5639     drawText(p, str, 0, 0);
       
  5640 }
       
  5641 
       
  5642 /*!
       
  5643    \internal
       
  5644 */
       
  5645 void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justificationPadding)
       
  5646 {
       
  5647 #ifdef QT_DEBUG_DRAW
       
  5648     if (qt_show_painter_debug_output)
       
  5649         printf("QPainter::drawText(), pos=[%.2f,%.2f], str='%s'\n", p.x(), p.y(), str.toLatin1().constData());
       
  5650 #endif
       
  5651 
       
  5652     Q_D(QPainter);
       
  5653 
       
  5654     if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen)
       
  5655         return;
       
  5656 
       
  5657     QStackTextEngine engine(str, d->state->font);
       
  5658     engine.option.setTextDirection(d->state->layoutDirection);
       
  5659     if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) {
       
  5660         engine.ignoreBidi = true;
       
  5661         engine.option.setTextDirection((tf & Qt::TextForceLeftToRight) ? Qt::LeftToRight : Qt::RightToLeft);
       
  5662     }
       
  5663     engine.itemize();
       
  5664     QScriptLine line;
       
  5665     line.length = str.length();
       
  5666     engine.shapeLine(line);
       
  5667 
       
  5668     int nItems = engine.layoutData->items.size();
       
  5669     QVarLengthArray<int> visualOrder(nItems);
       
  5670     QVarLengthArray<uchar> levels(nItems);
       
  5671     for (int i = 0; i < nItems; ++i)
       
  5672         levels[i] = engine.layoutData->items[i].analysis.bidiLevel;
       
  5673     QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
       
  5674 
       
  5675     if (justificationPadding > 0) {
       
  5676         engine.option.setAlignment(Qt::AlignJustify);
       
  5677         engine.forceJustification = true;
       
  5678         // this works because justify() is only interested in the difference between width and textWidth
       
  5679         line.width = justificationPadding;
       
  5680         engine.justify(line);
       
  5681     }
       
  5682     QFixed x = QFixed::fromReal(p.x());
       
  5683 
       
  5684     for (int i = 0; i < nItems; ++i) {
       
  5685         int item = visualOrder[i];
       
  5686         const QScriptItem &si = engine.layoutData->items.at(item);
       
  5687         if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
       
  5688             x += si.width;
       
  5689             continue;
       
  5690         }
       
  5691         QFont f = engine.font(si);
       
  5692         QTextItemInt gf(si, &f);
       
  5693         gf.glyphs = engine.shapedGlyphs(&si);
       
  5694         gf.chars = engine.layoutData->string.unicode() + si.position;
       
  5695         gf.num_chars = engine.length(item);
       
  5696         gf.width = si.width;
       
  5697         gf.logClusters = engine.logClusters(&si);
       
  5698 
       
  5699         drawTextItem(QPointF(x.toReal(), p.y()), gf);
       
  5700 
       
  5701         x += si.width;
       
  5702     }
       
  5703 }
       
  5704 
       
  5705 void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br)
       
  5706 {
       
  5707 #ifdef QT_DEBUG_DRAW
       
  5708     if (qt_show_painter_debug_output)
       
  5709         printf("QPainter::drawText(), r=[%d,%d,%d,%d], flags=%d, str='%s'\n",
       
  5710            r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
       
  5711 #endif
       
  5712 
       
  5713     Q_D(QPainter);
       
  5714 
       
  5715     if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
       
  5716         return;
       
  5717 
       
  5718     if (!d->extended)
       
  5719         d->updateState(d->state);
       
  5720 
       
  5721     QRectF bounds;
       
  5722     qt_format_text(d->state->font, r, flags, 0, str, br ? &bounds : 0, 0, 0, 0, this);
       
  5723     if (br)
       
  5724         *br = bounds.toAlignedRect();
       
  5725 }
       
  5726 
       
  5727 /*!
       
  5728     \fn void QPainter::drawText(const QPoint &position, const QString &text)
       
  5729 
       
  5730     \overload
       
  5731 
       
  5732     Draws the given \a text with the currently defined text direction,
       
  5733     beginning at the given \a position.
       
  5734 
       
  5735     By default, QPainter draws text anti-aliased.
       
  5736 
       
  5737     \note The y-position is used as the baseline of the font.
       
  5738 
       
  5739 */
       
  5740 
       
  5741 /*!
       
  5742     \fn void QPainter::drawText(const QRectF &rectangle, int flags, const QString &text, QRectF *boundingRect)
       
  5743     \overload
       
  5744 
       
  5745     Draws the given \a text within the provided \a rectangle.
       
  5746 
       
  5747     \table 100%
       
  5748     \row
       
  5749     \o \inlineimage qpainter-text.png
       
  5750     \o
       
  5751     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 17
       
  5752     \endtable
       
  5753 
       
  5754     The \a boundingRect (if not null) is set to the what the bounding rectangle
       
  5755     should be in order to enclose the whole text. The \a flags argument is a bitwise
       
  5756     OR of the following flags:
       
  5757 
       
  5758     \list
       
  5759     \o Qt::AlignLeft
       
  5760     \o Qt::AlignRight
       
  5761     \o Qt::AlignHCenter
       
  5762     \o Qt::AlignJustify
       
  5763     \o Qt::AlignTop
       
  5764     \o Qt::AlignBottom
       
  5765     \o Qt::AlignVCenter
       
  5766     \o Qt::AlignCenter
       
  5767     \o Qt::TextDontClip
       
  5768     \o Qt::TextSingleLine
       
  5769     \o Qt::TextExpandTabs
       
  5770     \o Qt::TextShowMnemonic
       
  5771     \o Qt::TextWordWrap
       
  5772     \o Qt::TextIncludeTrailingSpaces
       
  5773     \endlist
       
  5774 
       
  5775     \sa Qt::AlignmentFlag, Qt::TextFlag, boundingRect(), layoutDirection()
       
  5776 
       
  5777     By default, QPainter draws text anti-aliased.
       
  5778 
       
  5779     \note The y-coordinate of \a rectangle is used as the top of the font.
       
  5780 */
       
  5781 void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *br)
       
  5782 {
       
  5783 #ifdef QT_DEBUG_DRAW
       
  5784     if (qt_show_painter_debug_output)
       
  5785         printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], flags=%d, str='%s'\n",
       
  5786            r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
       
  5787 #endif
       
  5788 
       
  5789     Q_D(QPainter);
       
  5790 
       
  5791     if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
       
  5792         return;
       
  5793 
       
  5794     if (!d->extended)
       
  5795         d->updateState(d->state);
       
  5796 
       
  5797     qt_format_text(d->state->font, r, flags, 0, str, br, 0, 0, 0, this);
       
  5798 }
       
  5799 
       
  5800 /*!
       
  5801     \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text, QRect *boundingRect)
       
  5802     \overload
       
  5803 
       
  5804     Draws the given \a text within the provided \a rectangle according
       
  5805     to the specified \a flags. The \a boundingRect (if not null) is set to
       
  5806     the what the bounding rectangle should be in order to enclose the whole text.
       
  5807 
       
  5808     By default, QPainter draws text anti-aliased.
       
  5809 
       
  5810     \note The y-coordinate of \a rectangle is used as the top of the font.
       
  5811 */
       
  5812 
       
  5813 /*!
       
  5814     \fn void QPainter::drawText(int x, int y, const QString &text)
       
  5815 
       
  5816     \overload
       
  5817 
       
  5818     Draws the given \a text at position (\a{x}, \a{y}), using the painter's
       
  5819     currently defined text direction.
       
  5820 
       
  5821     By default, QPainter draws text anti-aliased.
       
  5822 
       
  5823     \note The y-position is used as the baseline of the font.
       
  5824 
       
  5825 */
       
  5826 
       
  5827 /*!
       
  5828     \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
       
  5829                                 const QString &text, QRect *boundingRect)
       
  5830 
       
  5831     \overload
       
  5832 
       
  5833     Draws the given \a text within the rectangle with origin (\a{x},
       
  5834     \a{y}), \a width and \a height.
       
  5835 
       
  5836     The \a boundingRect (if not null) is set to the actual bounding
       
  5837     rectangle of the output.  The \a flags argument is a bitwise OR of
       
  5838     the following flags:
       
  5839 
       
  5840     \list
       
  5841     \o Qt::AlignLeft
       
  5842     \o Qt::AlignRight
       
  5843     \o Qt::AlignHCenter
       
  5844     \o Qt::AlignJustify
       
  5845     \o Qt::AlignTop
       
  5846     \o Qt::AlignBottom
       
  5847     \o Qt::AlignVCenter
       
  5848     \o Qt::AlignCenter
       
  5849     \o Qt::TextSingleLine
       
  5850     \o Qt::TextExpandTabs
       
  5851     \o Qt::TextShowMnemonic
       
  5852     \o Qt::TextWordWrap
       
  5853     \endlist
       
  5854 
       
  5855     By default, QPainter draws text anti-aliased.
       
  5856 
       
  5857     \note The y-position is used as the baseline of the font.
       
  5858 
       
  5859     \sa Qt::AlignmentFlag, Qt::TextFlag
       
  5860 */
       
  5861 
       
  5862 /*!
       
  5863     \fn void QPainter::drawText(const QRectF &rectangle, const QString &text,
       
  5864         const QTextOption &option)
       
  5865     \overload
       
  5866 
       
  5867     Draws the given \a text in the \a rectangle specified using the \a option
       
  5868     to control its positioning and orientation.
       
  5869 
       
  5870     By default, QPainter draws text anti-aliased.
       
  5871 
       
  5872     \note The y-coordinate of \a rectangle is used as the top of the font.
       
  5873 */
       
  5874 void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o)
       
  5875 {
       
  5876 #ifdef QT_DEBUG_DRAW
       
  5877     if (qt_show_painter_debug_output)
       
  5878         printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], str='%s'\n",
       
  5879            r.x(), r.y(), r.width(), r.height(), text.toLatin1().constData());
       
  5880 #endif
       
  5881 
       
  5882     Q_D(QPainter);
       
  5883 
       
  5884     if (!d->engine || text.length() == 0 || pen().style() == Qt::NoPen)
       
  5885         return;
       
  5886 
       
  5887     if (!d->extended)
       
  5888         d->updateState(d->state);
       
  5889 
       
  5890     qt_format_text(d->state->font, r, 0, &o, text, 0, 0, 0, 0, this);
       
  5891 }
       
  5892 
       
  5893 /*!
       
  5894     \fn void QPainter::drawTextItem(int x, int y, const QTextItem &ti)
       
  5895 
       
  5896     \internal
       
  5897     \overload
       
  5898 */
       
  5899 
       
  5900 /*!
       
  5901     \fn void QPainter::drawTextItem(const QPoint &p, const QTextItem &ti)
       
  5902 
       
  5903     \internal
       
  5904     \overload
       
  5905 
       
  5906     Draws the text item \a ti at position \a p.
       
  5907 */
       
  5908 
       
  5909 /*! \internal
       
  5910     Draws the text item \a ti at position \a p.
       
  5911 
       
  5912     This method ignores the painters background mode and
       
  5913     color. drawText and qt_format_text have to do it themselves, as
       
  5914     only they know the extents of the complete string.
       
  5915 
       
  5916     It ignores the font set on the painter as the text item has one of its own.
       
  5917 
       
  5918     The underline and strikeout parameters of the text items font are
       
  5919     ignored aswell. You'll need to pass in the correct flags to get
       
  5920     underlining and strikeout.
       
  5921 */
       
  5922 static QPainterPath generateWavyPath(qreal minWidth, qreal maxRadius, QPaintDevice *device)
       
  5923 {
       
  5924     extern int qt_defaultDpi();
       
  5925     QPainterPath path;
       
  5926 
       
  5927     bool up = true;
       
  5928     const qreal radius = qMax(qreal(.5), qMin(qreal(1.25 * device->logicalDpiY() / qt_defaultDpi()), maxRadius));
       
  5929     qreal xs, ys;
       
  5930     int i = 0;
       
  5931     path.moveTo(0, radius);
       
  5932     do {
       
  5933         xs = i*(2*radius);
       
  5934         ys = 0;
       
  5935 
       
  5936         qreal remaining = minWidth - xs;
       
  5937         qreal angle = 180;
       
  5938 
       
  5939         // cut-off at the last arc segment
       
  5940         if (remaining < 2 * radius)
       
  5941             angle = 180 * remaining / (2 * radius);
       
  5942 
       
  5943         path.arcTo(xs, ys, 2*radius, 2*radius, 180, up ? angle : -angle);
       
  5944 
       
  5945         up = !up;
       
  5946         ++i;
       
  5947     } while (xs + 2*radius < minWidth);
       
  5948 
       
  5949     return path;
       
  5950 }
       
  5951 
       
  5952 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti)
       
  5953 {
       
  5954     QTextCharFormat::UnderlineStyle underlineStyle = ti.underlineStyle;
       
  5955     if (underlineStyle == QTextCharFormat::NoUnderline
       
  5956         && !(ti.flags & (QTextItem::StrikeOut | QTextItem::Overline)))
       
  5957         return;
       
  5958 
       
  5959     QFontEngine *fe = ti.fontEngine;
       
  5960 
       
  5961     const QPen oldPen = painter->pen();
       
  5962     const QBrush oldBrush = painter->brush();
       
  5963     painter->setBrush(Qt::NoBrush);
       
  5964     QPen pen = oldPen;
       
  5965     pen.setStyle(Qt::SolidLine);
       
  5966     pen.setWidthF(fe->lineThickness().toReal());
       
  5967     pen.setCapStyle(Qt::FlatCap);
       
  5968 
       
  5969     QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y());
       
  5970     // deliberately ceil the offset to avoid the underline coming too close to
       
  5971     // the text above it.
       
  5972     const qreal underlinePos = pos.y() + qCeil(fe->underlinePosition().toReal());
       
  5973 
       
  5974     if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
       
  5975         underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
       
  5976     }
       
  5977 
       
  5978     if (underlineStyle == QTextCharFormat::WaveUnderline) {
       
  5979         painter->save();
       
  5980         painter->setRenderHint(QPainter::Antialiasing);
       
  5981         painter->translate(pos.x(), underlinePos);
       
  5982 
       
  5983         QColor uc = ti.charFormat.underlineColor();
       
  5984         if (uc.isValid())
       
  5985             painter->setPen(uc);
       
  5986 
       
  5987         painter->drawPath(generateWavyPath(ti.width.toReal(),
       
  5988                                            fe->underlinePosition().toReal(),
       
  5989                                            painter->device()));
       
  5990         painter->restore();
       
  5991     } else if (underlineStyle != QTextCharFormat::NoUnderline) {
       
  5992         QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos);
       
  5993 
       
  5994         QColor uc = ti.charFormat.underlineColor();
       
  5995         if (uc.isValid())
       
  5996             pen.setColor(uc);
       
  5997 
       
  5998         pen.setStyle((Qt::PenStyle)(underlineStyle));
       
  5999         painter->setPen(pen);
       
  6000         painter->drawLine(underLine);
       
  6001     }
       
  6002 
       
  6003     pen.setStyle(Qt::SolidLine);
       
  6004     pen.setColor(oldPen.color());
       
  6005 
       
  6006     if (ti.flags & QTextItem::StrikeOut) {
       
  6007         QLineF strikeOutLine = line;
       
  6008         strikeOutLine.translate(0., - fe->ascent().toReal() / 3.);
       
  6009         painter->setPen(pen);
       
  6010         painter->drawLine(strikeOutLine);
       
  6011     }
       
  6012 
       
  6013     if (ti.flags & QTextItem::Overline) {
       
  6014         QLineF overLine = line;
       
  6015         overLine.translate(0., - fe->ascent().toReal());
       
  6016         painter->setPen(pen);
       
  6017         painter->drawLine(overLine);
       
  6018     }
       
  6019 
       
  6020     painter->setPen(oldPen);
       
  6021     painter->setBrush(oldBrush);
       
  6022 }
       
  6023 
       
  6024 /*!
       
  6025     \internal
       
  6026     \since 4.1
       
  6027 */
       
  6028 void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
       
  6029 {
       
  6030 #ifdef QT_DEBUG_DRAW
       
  6031     if (qt_show_painter_debug_output)
       
  6032         printf("QPainter::drawTextItem(), pos=[%.f,%.f], str='%s'\n",
       
  6033                p.x(), p.y(), qPrintable(_ti.text()));
       
  6034 #endif
       
  6035 
       
  6036     Q_D(QPainter);
       
  6037 
       
  6038     if (!d->engine)
       
  6039         return;
       
  6040 
       
  6041 #ifndef QT_NO_DEBUG
       
  6042     qt_painter_thread_test(d->device->devType(),
       
  6043                            "text and fonts",
       
  6044                            QFontDatabase::supportsThreadedFontRendering());
       
  6045 #endif
       
  6046 
       
  6047     QTextItemInt &ti = const_cast<QTextItemInt &>(static_cast<const QTextItemInt &>(_ti));
       
  6048 
       
  6049     if (!d->extended && d->state->bgMode == Qt::OpaqueMode) {
       
  6050         QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
       
  6051         fillRect(rect, d->state->bgBrush);
       
  6052     }
       
  6053 
       
  6054     if (pen().style() == Qt::NoPen)
       
  6055         return;
       
  6056 
       
  6057     const RenderHints oldRenderHints = d->state->renderHints;
       
  6058     if (!d->state->renderHints & QPainter::Antialiasing && d->state->matrix.type() >= QTransform::TxScale) {
       
  6059         // draw antialias decoration (underline/overline/strikeout) with
       
  6060         // transformed text
       
  6061 
       
  6062         bool aa = true;
       
  6063         const QTransform &m = d->state->matrix;
       
  6064         if (d->state->matrix.type() < QTransform::TxShear) {
       
  6065             bool isPlain90DegreeRotation =
       
  6066                 (qFuzzyIsNull(m.m11())
       
  6067                  && qFuzzyIsNull(m.m12() - qreal(1))
       
  6068                  && qFuzzyIsNull(m.m21() + qreal(1))
       
  6069                  && qFuzzyIsNull(m.m22())
       
  6070                     )
       
  6071                 ||
       
  6072                 (qFuzzyIsNull(m.m11() + qreal(1))
       
  6073                  && qFuzzyIsNull(m.m12())
       
  6074                  && qFuzzyIsNull(m.m21())
       
  6075                  && qFuzzyIsNull(m.m22() + qreal(1))
       
  6076                     )
       
  6077                 ||
       
  6078                 (qFuzzyIsNull(m.m11())
       
  6079                  && qFuzzyIsNull(m.m12() + qreal(1))
       
  6080                  && qFuzzyIsNull(m.m21() - qreal(1))
       
  6081                  && qFuzzyIsNull(m.m22())
       
  6082                     )
       
  6083                 ;
       
  6084             aa = !isPlain90DegreeRotation;
       
  6085         }
       
  6086         if (aa)
       
  6087             setRenderHint(QPainter::Antialiasing, true);
       
  6088     }
       
  6089 
       
  6090     if (!d->extended)
       
  6091         d->updateState(d->state);
       
  6092 
       
  6093     if (!ti.glyphs.numGlyphs) {
       
  6094         // nothing to do
       
  6095     } else if (ti.fontEngine->type() == QFontEngine::Multi) {
       
  6096         QFontEngineMulti *multi = static_cast<QFontEngineMulti *>(ti.fontEngine);
       
  6097 
       
  6098         const QGlyphLayout &glyphs = ti.glyphs;
       
  6099         int which = glyphs.glyphs[0] >> 24;
       
  6100 
       
  6101         qreal x = p.x();
       
  6102         qreal y = p.y();
       
  6103 
       
  6104         int start = 0;
       
  6105         int end, i;
       
  6106         for (end = 0; end < ti.glyphs.numGlyphs; ++end) {
       
  6107             const int e = glyphs.glyphs[end] >> 24;
       
  6108             if (e == which)
       
  6109                 continue;
       
  6110 
       
  6111 
       
  6112             QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
       
  6113             ti2.width = 0;
       
  6114             // set the high byte to zero and calc the width
       
  6115             for (i = start; i < end; ++i) {
       
  6116                 glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
       
  6117                 ti2.width += ti.glyphs.effectiveAdvance(i);
       
  6118             }
       
  6119 
       
  6120             d->engine->drawTextItem(QPointF(x, y), ti2);
       
  6121 
       
  6122             // reset the high byte for all glyphs and advance to the next sub-string
       
  6123             const int hi = which << 24;
       
  6124             for (i = start; i < end; ++i) {
       
  6125                 glyphs.glyphs[i] = hi | glyphs.glyphs[i];
       
  6126             }
       
  6127             x += ti2.width.toReal();
       
  6128 
       
  6129             // change engine
       
  6130             start = end;
       
  6131             which = e;
       
  6132         }
       
  6133 
       
  6134         QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
       
  6135         ti2.width = 0;
       
  6136         // set the high byte to zero and calc the width
       
  6137         for (i = start; i < end; ++i) {
       
  6138             glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
       
  6139             ti2.width += ti.glyphs.effectiveAdvance(i);
       
  6140         }
       
  6141 
       
  6142         if (d->extended)
       
  6143             d->extended->drawTextItem(QPointF(x, y), ti2);
       
  6144         else
       
  6145             d->engine->drawTextItem(QPointF(x,y), ti2);
       
  6146 
       
  6147         // reset the high byte for all glyphs
       
  6148         const int hi = which << 24;
       
  6149         for (i = start; i < end; ++i)
       
  6150             glyphs.glyphs[i] = hi | glyphs.glyphs[i];
       
  6151 
       
  6152     } else {
       
  6153         if (d->extended)
       
  6154             d->extended->drawTextItem(p, ti);
       
  6155         else
       
  6156             d->engine->drawTextItem(p, ti);
       
  6157     }
       
  6158     drawTextItemDecoration(this, p, ti);
       
  6159 
       
  6160     if (d->state->renderHints != oldRenderHints) {
       
  6161         d->state->renderHints = oldRenderHints;
       
  6162         if (d->extended)
       
  6163             d->extended->renderHintsChanged();
       
  6164         else
       
  6165             d->state->dirtyFlags |= QPaintEngine::DirtyHints;
       
  6166     }
       
  6167 }
       
  6168 
       
  6169 /*!
       
  6170     \fn QRectF QPainter::boundingRect(const QRectF &rectangle, int flags, const QString &text)
       
  6171 
       
  6172     Returns the bounding rectangle of the \a text as it will appear
       
  6173     when drawn inside the given \a rectangle with the specified \a
       
  6174     flags using the currently set font(); i.e the function tells you
       
  6175     where the drawText() function will draw when given the same
       
  6176     arguments.
       
  6177 
       
  6178     If the \a text does not fit within the given \a rectangle using
       
  6179     the specified \a flags, the function returns the required
       
  6180     rectangle.
       
  6181 
       
  6182     The \a flags argument is a bitwise OR of the following flags:
       
  6183     \list
       
  6184          \o Qt::AlignLeft
       
  6185          \o Qt::AlignRight
       
  6186          \o Qt::AlignHCenter
       
  6187          \o Qt::AlignTop
       
  6188          \o Qt::AlignBottom
       
  6189          \o Qt::AlignVCenter
       
  6190          \o Qt::AlignCenter
       
  6191          \o Qt::TextSingleLine
       
  6192          \o Qt::TextExpandTabs
       
  6193          \o Qt::TextShowMnemonic
       
  6194          \o Qt::TextWordWrap
       
  6195          \o Qt::TextIncludeTrailingSpaces
       
  6196     \endlist
       
  6197     If several of the horizontal or several of the vertical alignment
       
  6198     flags are set, the resulting alignment is undefined.
       
  6199 
       
  6200     \sa drawText(), Qt::Alignment, Qt::TextFlag
       
  6201 */
       
  6202 
       
  6203 /*!
       
  6204     \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
       
  6205                                      const QString &text)
       
  6206 
       
  6207     \overload
       
  6208 
       
  6209     Returns the bounding rectangle of the \a text as it will appear
       
  6210     when drawn inside the given \a rectangle with the specified \a
       
  6211     flags using the currently set font().
       
  6212 */
       
  6213 
       
  6214 /*!
       
  6215     \fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
       
  6216                                      const QString &text);
       
  6217 
       
  6218     \overload
       
  6219 
       
  6220     Returns the bounding rectangle of the given \a text as it will
       
  6221     appear when drawn inside the rectangle beginning at the point
       
  6222     (\a{x}, \a{y}) with width \a w and height \a h.
       
  6223 */
       
  6224 QRect QPainter::boundingRect(const QRect &rect, int flags, const QString &str)
       
  6225 {
       
  6226     if (str.isEmpty())
       
  6227         return QRect(rect.x(),rect.y(), 0,0);
       
  6228     QRect brect;
       
  6229     drawText(rect, flags | Qt::TextDontPrint, str, &brect);
       
  6230     return brect;
       
  6231 }
       
  6232 
       
  6233 
       
  6234 
       
  6235 QRectF QPainter::boundingRect(const QRectF &rect, int flags, const QString &str)
       
  6236 {
       
  6237     if (str.isEmpty())
       
  6238         return QRectF(rect.x(),rect.y(), 0,0);
       
  6239     QRectF brect;
       
  6240     drawText(rect, flags | Qt::TextDontPrint, str, &brect);
       
  6241     return brect;
       
  6242 }
       
  6243 
       
  6244 /*!
       
  6245     \fn QRectF QPainter::boundingRect(const QRectF &rectangle,
       
  6246         const QString &text, const QTextOption &option)
       
  6247 
       
  6248     \overload
       
  6249 
       
  6250     Instead of specifying flags as a bitwise OR of the
       
  6251     Qt::AlignmentFlag and Qt::TextFlag, this overloaded function takes
       
  6252     an \a option argument. The QTextOption class provides a
       
  6253     description of general rich text properties.
       
  6254 
       
  6255     \sa QTextOption
       
  6256 */
       
  6257 QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextOption &o)
       
  6258 {
       
  6259     Q_D(QPainter);
       
  6260 
       
  6261     if (!d->engine || text.length() == 0)
       
  6262         return QRectF(r.x(),r.y(), 0,0);
       
  6263 
       
  6264     QRectF br;
       
  6265     qt_format_text(d->state->font, r, Qt::TextDontPrint, &o, text, &br, 0, 0, 0, this);
       
  6266     return br;
       
  6267 }
       
  6268 
       
  6269 /*!
       
  6270     \fn void QPainter::drawTiledPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QPointF &position)
       
  6271 
       
  6272     Draws a tiled \a pixmap, inside the given \a rectangle with its
       
  6273     origin at the given \a position.
       
  6274 
       
  6275     Calling drawTiledPixmap() is similar to calling drawPixmap()
       
  6276     several times to fill (tile) an area with a pixmap, but is
       
  6277     potentially much more efficient depending on the underlying window
       
  6278     system.
       
  6279 
       
  6280     \sa drawPixmap()
       
  6281 */
       
  6282 void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp)
       
  6283 {
       
  6284 #ifdef QT_DEBUG_DRAW
       
  6285     if (qt_show_painter_debug_output)
       
  6286         printf("QPainter::drawTiledPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], offset=[%.2f,%.2f]\n",
       
  6287                r.x(), r.y(), r.width(), r.height(),
       
  6288                pixmap.width(), pixmap.height(),
       
  6289                sp.x(), sp.y());
       
  6290 #endif
       
  6291 
       
  6292     Q_D(QPainter);
       
  6293     if (!d->engine || pixmap.isNull() || r.isEmpty())
       
  6294         return;
       
  6295 
       
  6296 #ifndef QT_NO_DEBUG
       
  6297     qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()");
       
  6298 #endif
       
  6299 
       
  6300     qreal sw = pixmap.width();
       
  6301     qreal sh = pixmap.height();
       
  6302     qreal sx = sp.x();
       
  6303     qreal sy = sp.y();
       
  6304     if (sx < 0)
       
  6305         sx = qRound(sw) - qRound(-sx) % qRound(sw);
       
  6306     else
       
  6307         sx = qRound(sx) % qRound(sw);
       
  6308     if (sy < 0)
       
  6309         sy = qRound(sh) - -qRound(sy) % qRound(sh);
       
  6310     else
       
  6311         sy = qRound(sy) % qRound(sh);
       
  6312 
       
  6313 
       
  6314     if (d->extended) {
       
  6315         d->extended->drawTiledPixmap(r, pixmap, QPointF(sx, sy));
       
  6316         return;
       
  6317     }
       
  6318 
       
  6319     if (d->state->bgMode == Qt::OpaqueMode && pixmap.isQBitmap())
       
  6320         fillRect(r, d->state->bgBrush);
       
  6321 
       
  6322     d->updateState(d->state);
       
  6323     if ((d->state->matrix.type() > QTransform::TxTranslate
       
  6324         && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
       
  6325         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
       
  6326     {
       
  6327         save();
       
  6328         setBackgroundMode(Qt::TransparentMode);
       
  6329         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
       
  6330         setBrush(QBrush(d->state->pen.color(), pixmap));
       
  6331         setPen(Qt::NoPen);
       
  6332 
       
  6333         // If there is no rotation involved we have to make sure we use the
       
  6334         // antialiased and not the aliased coordinate system by rounding the coordinates.
       
  6335         if (d->state->matrix.type() <= QTransform::TxScale) {
       
  6336             const QPointF p = roundInDeviceCoordinates(r.topLeft(), d->state->matrix);
       
  6337 
       
  6338             if (d->state->matrix.type() <= QTransform::TxTranslate) {
       
  6339                 sx = qRound(sx);
       
  6340                 sy = qRound(sy);
       
  6341             }
       
  6342 
       
  6343             setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
       
  6344             drawRect(QRectF(p, r.size()));
       
  6345         } else {
       
  6346             setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
       
  6347             drawRect(r);
       
  6348         }
       
  6349         restore();
       
  6350         return;
       
  6351     }
       
  6352 
       
  6353     qreal x = r.x();
       
  6354     qreal y = r.y();
       
  6355     if (d->state->matrix.type() == QTransform::TxTranslate
       
  6356         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
       
  6357         x += d->state->matrix.dx();
       
  6358         y += d->state->matrix.dy();
       
  6359     }
       
  6360 
       
  6361     d->engine->drawTiledPixmap(QRectF(x, y, r.width(), r.height()), pixmap, QPointF(sx, sy));
       
  6362 }
       
  6363 
       
  6364 /*!
       
  6365     \fn QPainter::drawTiledPixmap(const QRect &rectangle, const QPixmap &pixmap,
       
  6366                                   const QPoint &position = QPoint())
       
  6367     \overload
       
  6368 
       
  6369     Draws a tiled \a pixmap, inside the given \a rectangle with its
       
  6370     origin at the given \a position.
       
  6371 */
       
  6372 
       
  6373 /*!
       
  6374     \fn void QPainter::drawTiledPixmap(int x, int y, int width, int height, const
       
  6375          QPixmap &pixmap, int sx, int sy);
       
  6376     \overload
       
  6377 
       
  6378     Draws a tiled \a pixmap in the specified rectangle.
       
  6379 
       
  6380     (\a{x}, \a{y}) specifies the top-left point in the paint device
       
  6381     that is to be drawn onto; with the given \a width and \a
       
  6382     height. (\a{sx}, \a{sy}) specifies the top-left point in the \a
       
  6383     pixmap that is to be drawn; this defaults to (0, 0).
       
  6384 */
       
  6385 
       
  6386 #ifndef QT_NO_PICTURE
       
  6387 
       
  6388 /*!
       
  6389     \fn void QPainter::drawPicture(const QPointF &point, const QPicture &picture)
       
  6390 
       
  6391     Replays the given \a picture at the given \a point.
       
  6392 
       
  6393     The QPicture class is a paint device that records and replays
       
  6394     QPainter commands. A picture serializes the painter commands to an
       
  6395     IO device in a platform-independent format. Everything that can be
       
  6396     painted on a widget or pixmap can also be stored in a picture.
       
  6397 
       
  6398     This function does exactly the same as QPicture::play() when
       
  6399     called with \a point = QPoint(0, 0).
       
  6400 
       
  6401     \table 100%
       
  6402     \row
       
  6403     \o
       
  6404     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 18
       
  6405     \endtable
       
  6406 
       
  6407     \sa QPicture::play()
       
  6408 */
       
  6409 
       
  6410 void QPainter::drawPicture(const QPointF &p, const QPicture &picture)
       
  6411 {
       
  6412     Q_D(QPainter);
       
  6413 
       
  6414     if (!d->engine)
       
  6415         return;
       
  6416 
       
  6417     if (!d->extended)
       
  6418         d->updateState(d->state);
       
  6419 
       
  6420     save();
       
  6421     translate(p);
       
  6422     const_cast<QPicture *>(&picture)->play(this);
       
  6423     restore();
       
  6424 }
       
  6425 
       
  6426 /*!
       
  6427     \fn void QPainter::drawPicture(const QPoint &point, const QPicture &picture)
       
  6428     \overload
       
  6429 
       
  6430     Replays the given \a picture at the given \a point.
       
  6431 */
       
  6432 
       
  6433 /*!
       
  6434     \fn void QPainter::drawPicture(int x, int y, const QPicture &picture)
       
  6435     \overload
       
  6436 
       
  6437     Draws the given \a picture at point (\a x, \a y).
       
  6438 */
       
  6439 
       
  6440 #endif // QT_NO_PICTURE
       
  6441 
       
  6442 /*!
       
  6443     \fn void QPainter::eraseRect(const QRectF &rectangle)
       
  6444 
       
  6445     Erases the area inside the given \a rectangle. Equivalent to
       
  6446     calling
       
  6447     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 19
       
  6448 
       
  6449     \sa fillRect()
       
  6450 */
       
  6451 void QPainter::eraseRect(const QRectF &r)
       
  6452 {
       
  6453     Q_D(QPainter);
       
  6454 
       
  6455     fillRect(r, d->state->bgBrush);
       
  6456 }
       
  6457 
       
  6458 static inline bool needsResolving(const QBrush &brush)
       
  6459 {
       
  6460     Qt::BrushStyle s = brush.style();
       
  6461     return ((s == Qt::LinearGradientPattern || s == Qt::RadialGradientPattern ||
       
  6462              s == Qt::ConicalGradientPattern) &&
       
  6463             brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode);
       
  6464 }
       
  6465 
       
  6466 /*!
       
  6467     \fn void QPainter::eraseRect(const QRect &rectangle)
       
  6468     \overload
       
  6469 
       
  6470     Erases the area inside the given  \a rectangle.
       
  6471 */
       
  6472 
       
  6473 /*!
       
  6474     \fn void QPainter::eraseRect(int x, int y, int width, int height)
       
  6475     \overload
       
  6476 
       
  6477     Erases the area inside the rectangle beginning at (\a x, \a y)
       
  6478     with the given \a width and \a height.
       
  6479 */
       
  6480 
       
  6481 
       
  6482 /*!
       
  6483     \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::BrushStyle style)
       
  6484     \overload
       
  6485 
       
  6486     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
       
  6487     width and \a height, using the brush \a style specified.
       
  6488 
       
  6489     \since 4.5
       
  6490 */
       
  6491 
       
  6492 /*!
       
  6493     \fn void QPainter::fillRect(const QRect &rectangle, Qt::BrushStyle style)
       
  6494     \overload
       
  6495 
       
  6496     Fills the given \a rectangle  with the brush \a style specified.
       
  6497 
       
  6498     \since 4.5
       
  6499 */
       
  6500 
       
  6501 /*!
       
  6502     \fn void QPainter::fillRect(const QRectF &rectangle, Qt::BrushStyle style)
       
  6503     \overload
       
  6504 
       
  6505     Fills the given \a rectangle  with the brush \a style specified.
       
  6506 
       
  6507     \since 4.5
       
  6508 */
       
  6509 
       
  6510 /*!
       
  6511     \fn void QPainter::fillRect(const QRectF &rectangle, const QBrush &brush)
       
  6512 
       
  6513     Fills the given \a rectangle  with the \a brush specified.
       
  6514 
       
  6515     Alternatively, you can specify a QColor instead of a QBrush; the
       
  6516     QBrush constructor (taking a QColor argument) will automatically
       
  6517     create a solid pattern brush.
       
  6518 
       
  6519     \sa drawRect()
       
  6520 */
       
  6521 void QPainter::fillRect(const QRectF &r, const QBrush &brush)
       
  6522 {
       
  6523     Q_D(QPainter);
       
  6524 
       
  6525     if (!d->engine)
       
  6526         return;
       
  6527 
       
  6528     if (d->extended) {
       
  6529         const QGradient *g = brush.gradient();
       
  6530         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
       
  6531             d->extended->fillRect(r, brush);
       
  6532             return;
       
  6533         }
       
  6534     }
       
  6535 
       
  6536     QPen oldPen = pen();
       
  6537     QBrush oldBrush = this->brush();
       
  6538     setPen(Qt::NoPen);
       
  6539     if (brush.style() == Qt::SolidPattern) {
       
  6540         d->colorBrush.setStyle(Qt::SolidPattern);
       
  6541         d->colorBrush.setColor(brush.color());
       
  6542         setBrush(d->colorBrush);
       
  6543     } else {
       
  6544         setBrush(brush);
       
  6545     }
       
  6546 
       
  6547     drawRect(r);
       
  6548     setBrush(oldBrush);
       
  6549     setPen(oldPen);
       
  6550 }
       
  6551 
       
  6552 /*!
       
  6553     \fn void QPainter::fillRect(const QRect &rectangle, const QBrush &brush)
       
  6554     \overload
       
  6555 
       
  6556     Fills the given \a rectangle with the specified \a brush.
       
  6557 */
       
  6558 
       
  6559 void QPainter::fillRect(const QRect &r, const QBrush &brush)
       
  6560 {
       
  6561     Q_D(QPainter);
       
  6562 
       
  6563     if (!d->engine)
       
  6564         return;
       
  6565 
       
  6566     if (d->extended) {
       
  6567         const QGradient *g = brush.gradient();
       
  6568         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
       
  6569             d->extended->fillRect(r, brush);
       
  6570             return;
       
  6571         }
       
  6572     }
       
  6573 
       
  6574     QPen oldPen = pen();
       
  6575     QBrush oldBrush = this->brush();
       
  6576     setPen(Qt::NoPen);
       
  6577     if (brush.style() == Qt::SolidPattern) {
       
  6578         d->colorBrush.setStyle(Qt::SolidPattern);
       
  6579         d->colorBrush.setColor(brush.color());
       
  6580         setBrush(d->colorBrush);
       
  6581     } else {
       
  6582         setBrush(brush);
       
  6583     }
       
  6584 
       
  6585     drawRect(r);
       
  6586     setBrush(oldBrush);
       
  6587     setPen(oldPen);
       
  6588 }
       
  6589 
       
  6590 
       
  6591 
       
  6592 /*!
       
  6593     \fn void QPainter::fillRect(const QRect &rectangle, const QColor &color)
       
  6594     \overload
       
  6595 
       
  6596     Fills the given \a rectangle with the \a color specified.
       
  6597 
       
  6598     \since 4.5
       
  6599 */
       
  6600 void QPainter::fillRect(const QRect &r, const QColor &color)
       
  6601 {
       
  6602     Q_D(QPainter);
       
  6603 
       
  6604     if (!d->engine)
       
  6605         return;
       
  6606 
       
  6607     if (d->extended) {
       
  6608         d->extended->fillRect(r, color);
       
  6609         return;
       
  6610     }
       
  6611 
       
  6612     fillRect(r, QBrush(color));
       
  6613 }
       
  6614 
       
  6615 
       
  6616 /*!
       
  6617     \fn void QPainter::fillRect(const QRectF &rectangle, const QColor &color)
       
  6618     \overload
       
  6619 
       
  6620     Fills the given \a rectangle with the \a color specified.
       
  6621 
       
  6622     \since 4.5
       
  6623 */
       
  6624 void QPainter::fillRect(const QRectF &r, const QColor &color)
       
  6625 {
       
  6626     Q_D(QPainter);
       
  6627 
       
  6628     if (!d->engine)
       
  6629         return;
       
  6630 
       
  6631     if (d->extended) {
       
  6632         d->extended->fillRect(r, color);
       
  6633         return;
       
  6634     }
       
  6635 
       
  6636     fillRect(r, QBrush(color));
       
  6637 }
       
  6638 
       
  6639 /*!
       
  6640     \fn void QPainter::fillRect(int x, int y, int width, int height, const QBrush &brush)
       
  6641 
       
  6642     \overload
       
  6643 
       
  6644     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
       
  6645     width and \a height, using the given \a brush.
       
  6646 */
       
  6647 
       
  6648 /*!
       
  6649     \fn void QPainter::fillRect(int x, int y, int width, int height, const QColor &color)
       
  6650 
       
  6651     \overload
       
  6652 
       
  6653     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
       
  6654     width and \a height, using the given \a color.
       
  6655 
       
  6656     \since 4.5
       
  6657 */
       
  6658 
       
  6659 /*!
       
  6660     \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::GlobalColor color)
       
  6661 
       
  6662     \overload
       
  6663 
       
  6664     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
       
  6665     width and \a height, using the given \a color.
       
  6666 
       
  6667     \since 4.5
       
  6668 */
       
  6669 
       
  6670 /*!
       
  6671     \fn void QPainter::fillRect(const QRect &rectangle, Qt::GlobalColor color);
       
  6672 
       
  6673     \overload
       
  6674 
       
  6675     Fills the given \a rectangle with the specified \a color.
       
  6676 
       
  6677     \since 4.5
       
  6678 */
       
  6679 
       
  6680 /*!
       
  6681     \fn void QPainter::fillRect(const QRectF &rectangle, Qt::GlobalColor color);
       
  6682 
       
  6683     \overload
       
  6684 
       
  6685     Fills the given \a rectangle with the specified \a color.
       
  6686 
       
  6687     \since 4.5
       
  6688 */
       
  6689 
       
  6690 /*!
       
  6691     Sets the given render \a hint on the painter if \a on is true;
       
  6692     otherwise clears the render hint.
       
  6693 
       
  6694     \sa setRenderHints(), renderHints(), {QPainter#Rendering
       
  6695     Quality}{Rendering Quality}
       
  6696 */
       
  6697 void QPainter::setRenderHint(RenderHint hint, bool on)
       
  6698 {
       
  6699 #ifdef QT_DEBUG_DRAW
       
  6700     if (qt_show_painter_debug_output)
       
  6701         printf("QPainter::setRenderHint: hint=%x, %s\n", hint, on ? "on" : "off");
       
  6702 #endif
       
  6703 
       
  6704 #ifndef QT_NO_DEBUG
       
  6705     static const bool antialiasingDisabled = qgetenv("QT_NO_ANTIALIASING").toInt();
       
  6706     if (hint == QPainter::Antialiasing && antialiasingDisabled)
       
  6707         return;
       
  6708 #endif
       
  6709 
       
  6710     setRenderHints(hint, on);
       
  6711 }
       
  6712 
       
  6713 /*!
       
  6714     \since 4.2
       
  6715 
       
  6716     Sets the given render \a hints on the painter if \a on is true;
       
  6717     otherwise clears the render hints.
       
  6718 
       
  6719     \sa setRenderHint(), renderHints(), {QPainter#Rendering
       
  6720     Quality}{Rendering Quality}
       
  6721 */
       
  6722 
       
  6723 void QPainter::setRenderHints(RenderHints hints, bool on)
       
  6724 {
       
  6725     Q_D(QPainter);
       
  6726 
       
  6727     if (!d->engine) {
       
  6728         qWarning("QPainter::setRenderHint: Painter must be active to set rendering hints");
       
  6729         return;
       
  6730     }
       
  6731 
       
  6732     if (on)
       
  6733         d->state->renderHints |= hints;
       
  6734     else
       
  6735         d->state->renderHints &= ~hints;
       
  6736 
       
  6737     if (d->extended)
       
  6738         d->extended->renderHintsChanged();
       
  6739     else
       
  6740         d->state->dirtyFlags |= QPaintEngine::DirtyHints;
       
  6741 }
       
  6742 
       
  6743 /*!
       
  6744     Returns a flag that specifies the rendering hints that are set for
       
  6745     this painter.
       
  6746 
       
  6747     \sa testRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}
       
  6748 */
       
  6749 QPainter::RenderHints QPainter::renderHints() const
       
  6750 {
       
  6751     Q_D(const QPainter);
       
  6752 
       
  6753     if (!d->engine)
       
  6754         return 0;
       
  6755 
       
  6756     return d->state->renderHints;
       
  6757 }
       
  6758 
       
  6759 /*!
       
  6760     \fn bool QPainter::testRenderHint(RenderHint hint) const
       
  6761     \since 4.3
       
  6762 
       
  6763     Returns true if \a hint is set; otherwise returns false.
       
  6764 
       
  6765     \sa renderHints(), setRenderHint()
       
  6766 */
       
  6767 
       
  6768 /*!
       
  6769     Returns true if view transformation is enabled; otherwise returns
       
  6770     false.
       
  6771 
       
  6772     \sa setViewTransformEnabled(), worldTransform()
       
  6773 */
       
  6774 
       
  6775 bool QPainter::viewTransformEnabled() const
       
  6776 {
       
  6777     Q_D(const QPainter);
       
  6778     if (!d->engine) {
       
  6779         qWarning("QPainter::viewTransformEnabled: Painter not active");
       
  6780         return false;
       
  6781     }
       
  6782     return d->state->VxF;
       
  6783 }
       
  6784 
       
  6785 /*!
       
  6786     \fn void QPainter::setWindow(const QRect &rectangle)
       
  6787 
       
  6788     Sets the painter's window to the given \a rectangle, and enables
       
  6789     view transformations.
       
  6790 
       
  6791     The window rectangle is part of the view transformation. The
       
  6792     window specifies the logical coordinate system. Its sister, the
       
  6793     viewport(), specifies the device coordinate system.
       
  6794 
       
  6795     The default window rectangle is the same as the device's
       
  6796     rectangle.
       
  6797 
       
  6798     \sa window(), viewTransformEnabled(), {The Coordinate
       
  6799     System#Window-Viewport Conversion}{Window-Viewport Conversion}
       
  6800 */
       
  6801 
       
  6802 /*!
       
  6803     \fn void QPainter::setWindow(int x, int y, int width, int height)
       
  6804     \overload
       
  6805 
       
  6806     Sets the painter's window to the rectangle beginning at (\a x, \a
       
  6807     y) and the given \a width and \a height.
       
  6808 */
       
  6809 
       
  6810 void QPainter::setWindow(const QRect &r)
       
  6811 {
       
  6812 #ifdef QT_DEBUG_DRAW
       
  6813     if (qt_show_painter_debug_output)
       
  6814         printf("QPainter::setWindow(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
       
  6815 #endif
       
  6816 
       
  6817     Q_D(QPainter);
       
  6818 
       
  6819     if (!d->engine) {
       
  6820         qWarning("QPainter::setWindow: Painter not active");
       
  6821         return;
       
  6822     }
       
  6823 
       
  6824     d->state->wx = r.x();
       
  6825     d->state->wy = r.y();
       
  6826     d->state->ww = r.width();
       
  6827     d->state->wh = r.height();
       
  6828 
       
  6829     d->state->VxF = true;
       
  6830     d->updateMatrix();
       
  6831 }
       
  6832 
       
  6833 /*!
       
  6834     Returns the window rectangle.
       
  6835 
       
  6836     \sa setWindow(), setViewTransformEnabled()
       
  6837 */
       
  6838 
       
  6839 QRect QPainter::window() const
       
  6840 {
       
  6841     Q_D(const QPainter);
       
  6842     if (!d->engine) {
       
  6843         qWarning("QPainter::window: Painter not active");
       
  6844         return QRect();
       
  6845     }
       
  6846     return QRect(d->state->wx, d->state->wy, d->state->ww, d->state->wh);
       
  6847 }
       
  6848 
       
  6849 /*!
       
  6850     \fn void QPainter::setViewport(const QRect &rectangle)
       
  6851 
       
  6852     Sets the painter's viewport rectangle to the given \a rectangle,
       
  6853     and enables view transformations.
       
  6854 
       
  6855     The viewport rectangle is part of the view transformation. The
       
  6856     viewport specifies the device coordinate system. Its sister, the
       
  6857     window(), specifies the logical coordinate system.
       
  6858 
       
  6859     The default viewport rectangle is the same as the device's
       
  6860     rectangle.
       
  6861 
       
  6862     \sa viewport(), viewTransformEnabled() {The Coordinate
       
  6863     System#Window-Viewport Conversion}{Window-Viewport Conversion}
       
  6864 */
       
  6865 
       
  6866 /*!
       
  6867     \fn void QPainter::setViewport(int x, int y, int width, int height)
       
  6868     \overload
       
  6869 
       
  6870     Sets the painter's viewport rectangle to be the rectangle
       
  6871     beginning at (\a x, \a y) with the given \a width and \a height.
       
  6872 */
       
  6873 
       
  6874 void QPainter::setViewport(const QRect &r)
       
  6875 {
       
  6876 #ifdef QT_DEBUG_DRAW
       
  6877     if (qt_show_painter_debug_output)
       
  6878         printf("QPainter::setViewport(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
       
  6879 #endif
       
  6880 
       
  6881     Q_D(QPainter);
       
  6882 
       
  6883     if (!d->engine) {
       
  6884         qWarning("QPainter::setViewport: Painter not active");
       
  6885         return;
       
  6886     }
       
  6887 
       
  6888     d->state->vx = r.x();
       
  6889     d->state->vy = r.y();
       
  6890     d->state->vw = r.width();
       
  6891     d->state->vh = r.height();
       
  6892 
       
  6893     d->state->VxF = true;
       
  6894     d->updateMatrix();
       
  6895 }
       
  6896 
       
  6897 /*!
       
  6898     Returns the viewport rectangle.
       
  6899 
       
  6900     \sa setViewport(), setViewTransformEnabled()
       
  6901 */
       
  6902 
       
  6903 QRect QPainter::viewport() const
       
  6904 {
       
  6905     Q_D(const QPainter);
       
  6906     if (!d->engine) {
       
  6907         qWarning("QPainter::viewport: Painter not active");
       
  6908         return QRect();
       
  6909     }
       
  6910     return QRect(d->state->vx, d->state->vy, d->state->vw, d->state->vh);
       
  6911 }
       
  6912 
       
  6913 /*! \fn bool QPainter::hasViewXForm() const
       
  6914     \compat
       
  6915 
       
  6916     Use viewTransformEnabled() instead.
       
  6917 */
       
  6918 
       
  6919 /*! \fn bool QPainter::hasWorldXForm() const
       
  6920     \compat
       
  6921 
       
  6922     Use worldMatrixEnabled() instead.
       
  6923 */
       
  6924 
       
  6925 /*! \fn void QPainter::resetXForm()
       
  6926     \compat
       
  6927 
       
  6928     Use resetTransform() instead.
       
  6929 */
       
  6930 
       
  6931 /*! \fn void QPainter::setViewXForm(bool enabled)
       
  6932     \compat
       
  6933 
       
  6934     Use setViewTransformEnabled() instead.
       
  6935 */
       
  6936 
       
  6937 /*! \fn void QPainter::setWorldXForm(bool enabled)
       
  6938     \compat
       
  6939 
       
  6940     Use setWorldMatrixEnabled() instead.
       
  6941 */
       
  6942 /*!
       
  6943     Enables view transformations if \a enable is true, or disables
       
  6944     view transformations if \a enable is false.
       
  6945 
       
  6946     \sa viewTransformEnabled(), {The Coordinate System#Window-Viewport
       
  6947     Conversion}{Window-Viewport Conversion}
       
  6948 */
       
  6949 
       
  6950 void QPainter::setViewTransformEnabled(bool enable)
       
  6951 {
       
  6952 #ifdef QT_DEBUG_DRAW
       
  6953     if (qt_show_painter_debug_output)
       
  6954         printf("QPainter::setViewTransformEnabled(), enable=%d\n", enable);
       
  6955 #endif
       
  6956 
       
  6957     Q_D(QPainter);
       
  6958 
       
  6959     if (!d->engine) {
       
  6960         qWarning("QPainter::setViewTransformEnabled: Painter not active");
       
  6961         return;
       
  6962     }
       
  6963 
       
  6964     if (enable == d->state->VxF)
       
  6965         return;
       
  6966 
       
  6967     d->state->VxF = enable;
       
  6968     d->updateMatrix();
       
  6969 }
       
  6970 
       
  6971 #ifdef QT3_SUPPORT
       
  6972 
       
  6973 /*!
       
  6974     \obsolete
       
  6975 
       
  6976     Use the worldTransform() combined with QTransform::dx() instead.
       
  6977 
       
  6978     \oldcode
       
  6979         QPainter painter(this);
       
  6980         qreal x = painter.translationX();
       
  6981     \newcode
       
  6982         QPainter painter(this);
       
  6983         qreal x = painter.worldTransform().dx();
       
  6984     \endcode
       
  6985 */
       
  6986 qreal QPainter::translationX() const
       
  6987 {
       
  6988     Q_D(const QPainter);
       
  6989     if (!d->engine) {
       
  6990         qWarning("QPainter::translationX: Painter not active");
       
  6991         return 0.0;
       
  6992     }
       
  6993     return d->state->worldMatrix.dx();
       
  6994 }
       
  6995 
       
  6996 /*!
       
  6997     \obsolete
       
  6998 
       
  6999     Use the worldTransform() combined with QTransform::dy() instead.
       
  7000 
       
  7001     \oldcode
       
  7002         QPainter painter(this);
       
  7003         qreal y = painter.translationY();
       
  7004     \newcode
       
  7005         QPainter painter(this);
       
  7006         qreal y = painter.worldTransform().dy();
       
  7007     \endcode
       
  7008 */
       
  7009 qreal QPainter::translationY() const
       
  7010 {
       
  7011     Q_D(const QPainter);
       
  7012     if (!d->engine) {
       
  7013         qWarning("QPainter::translationY: Painter not active");
       
  7014         return 0.0;
       
  7015     }
       
  7016     return d->state->worldMatrix.dy();
       
  7017 }
       
  7018 
       
  7019 /*!
       
  7020     \fn void QPainter::map(int x, int y, int *rx, int *ry) const
       
  7021 
       
  7022     \internal
       
  7023 
       
  7024     Sets (\a{rx}, \a{ry}) to the point that results from applying the
       
  7025     painter's current transformation on the point (\a{x}, \a{y}).
       
  7026 */
       
  7027 void QPainter::map(int x, int y, int *rx, int *ry) const
       
  7028 {
       
  7029     QPoint p(x, y);
       
  7030     p = p * combinedMatrix();
       
  7031     *rx = p.x();
       
  7032     *ry = p.y();
       
  7033 }
       
  7034 
       
  7035 /*!
       
  7036     \fn QPoint QPainter::xForm(const QPoint &point) const
       
  7037 
       
  7038     Use combinedTransform() instead.
       
  7039 */
       
  7040 
       
  7041 QPoint QPainter::xForm(const QPoint &p) const
       
  7042 {
       
  7043     Q_D(const QPainter);
       
  7044     if (!d->engine) {
       
  7045         qWarning("QPainter::xForm: Painter not active");
       
  7046         return QPoint();
       
  7047     }
       
  7048     if (d->state->matrix.type() == QTransform::TxNone)
       
  7049         return p;
       
  7050     return p * combinedMatrix();
       
  7051 }
       
  7052 
       
  7053 
       
  7054 /*!
       
  7055     \fn QRect QPainter::xForm(const QRect &rectangle) const
       
  7056     \overload
       
  7057 
       
  7058     Use combinedTransform() instead of this function and call
       
  7059     mapRect() on the result to obtain a QRect.
       
  7060 */
       
  7061 
       
  7062 QRect QPainter::xForm(const QRect &r) const
       
  7063 {
       
  7064     Q_D(const QPainter);
       
  7065     if (!d->engine) {
       
  7066         qWarning("QPainter::xForm: Painter not active");
       
  7067         return QRect();
       
  7068     }
       
  7069     if (d->state->matrix.type() == QTransform::TxNone)
       
  7070         return r;
       
  7071     return combinedMatrix().mapRect(r);
       
  7072 }
       
  7073 
       
  7074 /*!
       
  7075     \fn QPolygon QPainter::xForm(const QPolygon &polygon) const
       
  7076     \overload
       
  7077 
       
  7078     Use combinedTransform() instead.
       
  7079 */
       
  7080 
       
  7081 QPolygon QPainter::xForm(const QPolygon &a) const
       
  7082 {
       
  7083     Q_D(const QPainter);
       
  7084     if (!d->engine) {
       
  7085         qWarning("QPainter::xForm: Painter not active");
       
  7086         return QPolygon();
       
  7087     }
       
  7088     if (d->state->matrix.type() == QTransform::TxNone)
       
  7089         return a;
       
  7090     return a * combinedMatrix();
       
  7091 }
       
  7092 
       
  7093 /*!
       
  7094     \fn QPolygon QPainter::xForm(const QPolygon &polygon, int index, int count) const
       
  7095     \overload
       
  7096 
       
  7097     Use combinedTransform() combined with QPolygon::mid() instead.
       
  7098 
       
  7099     \oldcode
       
  7100         QPainter painter(this);
       
  7101         QPolygon transformed = painter.xForm(polygon, index, count)
       
  7102     \newcode
       
  7103         QPainter painter(this);
       
  7104         QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform();
       
  7105     \endcode
       
  7106 */
       
  7107 
       
  7108 QPolygon QPainter::xForm(const QPolygon &av, int index, int npoints) const
       
  7109 {
       
  7110     int lastPoint = npoints < 0 ? av.size() : index+npoints;
       
  7111     QPolygon a(lastPoint-index);
       
  7112     memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint));
       
  7113     return a * combinedMatrix();
       
  7114 }
       
  7115 
       
  7116 /*!
       
  7117     \fn QPoint QPainter::xFormDev(const QPoint &point) const
       
  7118     \overload
       
  7119     \obsolete
       
  7120 
       
  7121     Use combinedTransform() combined with QTransform::inverted() instead.
       
  7122 
       
  7123     \oldcode
       
  7124         QPainter painter(this);
       
  7125         QPoint transformed = painter.xFormDev(point);
       
  7126     \newcode
       
  7127         QPainter painter(this);
       
  7128         QPoint transformed = point * painter.combinedTransform().inverted();
       
  7129     \endcode
       
  7130 */
       
  7131 
       
  7132 QPoint QPainter::xFormDev(const QPoint &p) const
       
  7133 {
       
  7134     Q_D(const QPainter);
       
  7135     if (!d->engine) {
       
  7136         qWarning("QPainter::xFormDev: Painter not active");
       
  7137         return QPoint();
       
  7138     }
       
  7139     if(d->state->matrix.type() == QTransform::TxNone)
       
  7140         return p;
       
  7141     return p * combinedMatrix().inverted();
       
  7142 }
       
  7143 
       
  7144 /*!
       
  7145     \fn QRect QPainter::xFormDev(const QRect &rectangle) const
       
  7146     \overload
       
  7147     \obsolete
       
  7148 
       
  7149     Use combinedTransform() combined with QTransform::inverted() instead.
       
  7150 
       
  7151     \oldcode
       
  7152         QPainter painter(this);
       
  7153         QRect transformed = painter.xFormDev(rectangle);
       
  7154     \newcode
       
  7155         QPainter painter(this);
       
  7156         QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted();
       
  7157         QRect transformed = region.boundingRect();
       
  7158     \endcode
       
  7159 */
       
  7160 
       
  7161 QRect QPainter::xFormDev(const QRect &r)  const
       
  7162 {
       
  7163     Q_D(const QPainter);
       
  7164     if (!d->engine) {
       
  7165         qWarning("QPainter::xFormDev: Painter not active");
       
  7166         return QRect();
       
  7167     }
       
  7168     if (d->state->matrix.type() == QTransform::TxNone)
       
  7169         return r;
       
  7170     return combinedMatrix().inverted().mapRect(r);
       
  7171 }
       
  7172 
       
  7173 /*!
       
  7174     \overload
       
  7175 
       
  7176     \fn QPoint QPainter::xFormDev(const QPolygon &polygon) const
       
  7177     \obsolete
       
  7178 
       
  7179     Use  combinedTransform() combined with QTransform::inverted() instead.
       
  7180 
       
  7181     \oldcode
       
  7182         QPainter painter(this);
       
  7183         QPolygon transformed = painter.xFormDev(rectangle);
       
  7184     \newcode
       
  7185         QPainter painter(this);
       
  7186         QPolygon transformed = polygon * painter.combinedTransform().inverted();
       
  7187     \endcode
       
  7188 */
       
  7189 
       
  7190 QPolygon QPainter::xFormDev(const QPolygon &a) const
       
  7191 {
       
  7192     Q_D(const QPainter);
       
  7193     if (!d->engine) {
       
  7194         qWarning("QPainter::xFormDev: Painter not active");
       
  7195         return QPolygon();
       
  7196     }
       
  7197     if (d->state->matrix.type() == QTransform::TxNone)
       
  7198         return a;
       
  7199     return a * combinedMatrix().inverted();
       
  7200 }
       
  7201 
       
  7202 /*!
       
  7203     \fn QPolygon QPainter::xFormDev(const QPolygon &polygon, int index, int count) const
       
  7204     \overload
       
  7205     \obsolete
       
  7206 
       
  7207     Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead.
       
  7208 
       
  7209     \oldcode
       
  7210         QPainter painter(this);
       
  7211         QPolygon transformed = painter.xFormDev(polygon, index, count);
       
  7212     \newcode
       
  7213         QPainter painter(this);
       
  7214         QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted();
       
  7215     \endcode
       
  7216 */
       
  7217 
       
  7218 QPolygon QPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
       
  7219 {
       
  7220     Q_D(const QPainter);
       
  7221     int lastPoint = npoints < 0 ? ad.size() : index+npoints;
       
  7222     QPolygon a(lastPoint-index);
       
  7223     memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint));
       
  7224     if (d->state->matrix.type() == QTransform::TxNone)
       
  7225         return a;
       
  7226     return a * combinedMatrix().inverted();
       
  7227 }
       
  7228 
       
  7229 /*!
       
  7230     \fn void QPainter::drawCubicBezier(const QPolygon &controlPoints, int index)
       
  7231 
       
  7232     Draws a cubic Bezier curve defined by the \a controlPoints,
       
  7233     starting at \a{controlPoints}\e{[index]} (\a index defaults to 0).
       
  7234     Points after \a{controlPoints}\e{[index + 3]} are ignored. Nothing
       
  7235     happens if there aren't enough control points.
       
  7236 
       
  7237     Use strokePath() instead.
       
  7238 
       
  7239     \oldcode
       
  7240              QPainter painter(this);
       
  7241              painter.drawCubicBezier(controlPoints, index)
       
  7242     \newcode
       
  7243              QPainterPath path;
       
  7244              path.moveTo(controlPoints.at(index));
       
  7245              path.cubicTo(controlPoints.at(index+1),
       
  7246                                  controlPoints.at(index+2),
       
  7247                                  controlPoints.at(index+3));
       
  7248 
       
  7249              QPainter painter(this);
       
  7250              painter.strokePath(path, painter.pen());
       
  7251     \endcode
       
  7252 */
       
  7253 void QPainter::drawCubicBezier(const QPolygon &a, int index)
       
  7254 {
       
  7255     Q_D(QPainter);
       
  7256 
       
  7257     if (!d->engine)
       
  7258         return;
       
  7259 
       
  7260     if ((int)a.size() - index < 4) {
       
  7261         qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control "
       
  7262                   "points");
       
  7263         return;
       
  7264     }
       
  7265 
       
  7266     QPainterPath path;
       
  7267     path.moveTo(a.at(index));
       
  7268     path.cubicTo(a.at(index+1), a.at(index+2), a.at(index+3));
       
  7269     strokePath(path, d->state->pen);
       
  7270 }
       
  7271 #endif
       
  7272 
       
  7273 struct QPaintDeviceRedirection
       
  7274 {
       
  7275     QPaintDeviceRedirection() : device(0), replacement(0), internalWidgetRedirectionIndex(-1) {}
       
  7276     QPaintDeviceRedirection(const QPaintDevice *device, QPaintDevice *replacement,
       
  7277                             const QPoint& offset, int internalWidgetRedirectionIndex)
       
  7278         : device(device), replacement(replacement), offset(offset),
       
  7279           internalWidgetRedirectionIndex(internalWidgetRedirectionIndex) { }
       
  7280     const QPaintDevice *device;
       
  7281     QPaintDevice *replacement;
       
  7282     QPoint offset;
       
  7283     int internalWidgetRedirectionIndex;
       
  7284     bool operator==(const QPaintDevice *pdev) const { return device == pdev; }
       
  7285     Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection)
       
  7286 };
       
  7287 
       
  7288 typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
       
  7289 Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
       
  7290 Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
       
  7291 
       
  7292 /*!
       
  7293     \threadsafe
       
  7294 
       
  7295     Redirects all paint commands for the given paint \a device, to the
       
  7296     \a replacement device. The optional point \a offset defines an
       
  7297     offset within the source device.
       
  7298 
       
  7299     The redirection will not be effective until the begin() function
       
  7300     has been called; make sure to call end() for the given \a
       
  7301     device's painter (if any) before redirecting. Call
       
  7302     restoreRedirected() to restore the previous redirection.
       
  7303 
       
  7304     In general, you'll probably find that calling
       
  7305     QPixmap::grabWidget() or QPixmap::grabWindow() is an easier
       
  7306     solution.
       
  7307 
       
  7308     \sa redirected(), restoreRedirected()
       
  7309 */
       
  7310 void QPainter::setRedirected(const QPaintDevice *device,
       
  7311                              QPaintDevice *replacement,
       
  7312                              const QPoint &offset)
       
  7313 {
       
  7314     Q_ASSERT(device != 0);
       
  7315 
       
  7316     bool hadInternalWidgetRedirection = false;
       
  7317     if (device->devType() == QInternal::Widget) {
       
  7318         const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
       
  7319         // This is the case when the widget is in a paint event.
       
  7320         if (widgetPrivate->redirectDev) {
       
  7321             // Remove internal redirection and put it back into the global redirection list.
       
  7322             QPoint oldOffset;
       
  7323             QPaintDevice *oldReplacement = widgetPrivate->redirected(&oldOffset);
       
  7324             const_cast<QWidgetPrivate *>(widgetPrivate)->restoreRedirected();
       
  7325             setRedirected(device, oldReplacement, oldOffset);
       
  7326             hadInternalWidgetRedirection = true;
       
  7327         }
       
  7328     }
       
  7329 
       
  7330     QPoint roffset;
       
  7331     QPaintDevice *rdev = redirected(replacement, &roffset);
       
  7332 
       
  7333     QMutexLocker locker(globalRedirectionsMutex());
       
  7334     QPaintDeviceRedirectionList *redirections = globalRedirections();
       
  7335     Q_ASSERT(redirections != 0);
       
  7336     *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
       
  7337                                              hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
       
  7338 }
       
  7339 
       
  7340 /*!
       
  7341     \threadsafe
       
  7342 
       
  7343     Restores the previous redirection for the given \a device after a
       
  7344     call to setRedirected().
       
  7345 
       
  7346     \sa redirected()
       
  7347  */
       
  7348 void QPainter::restoreRedirected(const QPaintDevice *device)
       
  7349 {
       
  7350     Q_ASSERT(device != 0);
       
  7351     QMutexLocker locker(globalRedirectionsMutex());
       
  7352     QPaintDeviceRedirectionList *redirections = globalRedirections();
       
  7353     Q_ASSERT(redirections != 0);
       
  7354     for (int i = redirections->size()-1; i >= 0; --i) {
       
  7355         if (redirections->at(i) == device) {
       
  7356             const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
       
  7357             redirections->removeAt(i);
       
  7358             // Restore the internal widget redirection, i.e. remove it from the global
       
  7359             // redirection list and put it back into QWidgetPrivate. The index is only set when
       
  7360             // someone call QPainter::setRedirected in a widget's paint event and we internally
       
  7361             // have a redirection set (typically set in QWidgetPrivate::drawWidget).
       
  7362             if (internalWidgetRedirectionIndex >= 0) {
       
  7363                 Q_ASSERT(internalWidgetRedirectionIndex < redirections->size());
       
  7364                 const QPaintDeviceRedirection &redirectionDevice = redirections->at(internalWidgetRedirectionIndex);
       
  7365                 QWidget *widget = static_cast<QWidget *>(const_cast<QPaintDevice *>(device));
       
  7366                 widget->d_func()->setRedirected(redirectionDevice.replacement, redirectionDevice.offset);
       
  7367                 redirections->removeAt(internalWidgetRedirectionIndex);
       
  7368             }
       
  7369             return;
       
  7370         }
       
  7371     }
       
  7372 }
       
  7373 
       
  7374 /*!
       
  7375     \threadsafe
       
  7376 
       
  7377     Returns the replacement for given \a device. The optional out
       
  7378     parameter \a offset returns the offset within the replaced device.
       
  7379 
       
  7380     \sa setRedirected(), restoreRedirected()
       
  7381 */
       
  7382 QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
       
  7383 {
       
  7384     Q_ASSERT(device != 0);
       
  7385 
       
  7386     if (device->devType() == QInternal::Widget) {
       
  7387         const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
       
  7388         if (widgetPrivate->redirectDev)
       
  7389             return widgetPrivate->redirected(offset);
       
  7390     }
       
  7391 
       
  7392     QMutexLocker locker(globalRedirectionsMutex());
       
  7393     QPaintDeviceRedirectionList *redirections = globalRedirections();
       
  7394     Q_ASSERT(redirections != 0);
       
  7395     for (int i = redirections->size()-1; i >= 0; --i)
       
  7396         if (redirections->at(i) == device) {
       
  7397             if (offset)
       
  7398                 *offset = redirections->at(i).offset;
       
  7399             return redirections->at(i).replacement;
       
  7400         }
       
  7401     if (offset)
       
  7402         *offset = QPoint(0, 0);
       
  7403     return 0;
       
  7404 }
       
  7405 
       
  7406 
       
  7407 void qt_painter_removePaintDevice(QPaintDevice *dev)
       
  7408 {
       
  7409     QMutex *mutex = 0;
       
  7410     QT_TRY {
       
  7411         mutex = globalRedirectionsMutex();
       
  7412     } QT_CATCH(...) {
       
  7413         // ignore the missing mutex, since we could be called from
       
  7414         // a destructor, and destructors shall not throw
       
  7415     }
       
  7416     QMutexLocker locker(mutex);
       
  7417     QPaintDeviceRedirectionList *redirections = 0;
       
  7418     QT_TRY {
       
  7419         redirections = globalRedirections();
       
  7420     } QT_CATCH(...) {
       
  7421         // do nothing - code below is safe with redirections being 0.
       
  7422     }
       
  7423     if (redirections) {
       
  7424         for (int i = 0; i < redirections->size(); ) {
       
  7425             if(redirections->at(i) == dev || redirections->at(i).replacement == dev)
       
  7426                 redirections->removeAt(i);
       
  7427             else
       
  7428                 ++i;
       
  7429         }
       
  7430     }
       
  7431 }
       
  7432 
       
  7433 void qt_format_text(const QFont &fnt, const QRectF &_r,
       
  7434                     int tf, const QString& str, QRectF *brect,
       
  7435                     int tabstops, int *ta, int tabarraylen,
       
  7436                     QPainter *painter)
       
  7437 {
       
  7438     qt_format_text(fnt, _r,
       
  7439                     tf, 0, str, brect,
       
  7440                     tabstops, ta, tabarraylen,
       
  7441                     painter);
       
  7442 }
       
  7443 void qt_format_text(const QFont &fnt, const QRectF &_r,
       
  7444                     int tf, const QTextOption *option, const QString& str, QRectF *brect,
       
  7445                     int tabstops, int *, int tabarraylen,
       
  7446                     QPainter *painter)
       
  7447 {
       
  7448 
       
  7449     Q_ASSERT( !((tf & ~Qt::TextDontPrint)!=0 && option!=0) ); // we either have an option or flags
       
  7450 
       
  7451     if (option) {
       
  7452         tf |= option->alignment();
       
  7453         if (option->wrapMode() != QTextOption::NoWrap)
       
  7454             tf |= Qt::TextWordWrap;
       
  7455 
       
  7456         if (option->flags() & QTextOption::IncludeTrailingSpaces)
       
  7457             tf |= Qt::TextIncludeTrailingSpaces;
       
  7458 
       
  7459         if (option->tabStop() >= 0 || !option->tabArray().isEmpty())
       
  7460             tf |= Qt::TextExpandTabs;
       
  7461     }
       
  7462 
       
  7463     // we need to copy r here to protect against the case (&r == brect).
       
  7464     QRectF r(_r);
       
  7465 
       
  7466     bool dontclip  = (tf & Qt::TextDontClip);
       
  7467     bool wordwrap  = (tf & Qt::TextWordWrap) || (tf & Qt::TextWrapAnywhere);
       
  7468     bool singleline = (tf & Qt::TextSingleLine);
       
  7469     bool showmnemonic = (tf & Qt::TextShowMnemonic);
       
  7470     bool hidemnmemonic = (tf & Qt::TextHideMnemonic);
       
  7471 
       
  7472     Qt::LayoutDirection layout_direction;
       
  7473     if (tf & Qt::TextForceLeftToRight)
       
  7474         layout_direction = Qt::LeftToRight;
       
  7475     else if (tf & Qt::TextForceRightToLeft)
       
  7476         layout_direction = Qt::RightToLeft;
       
  7477     else if (option)
       
  7478         layout_direction = option->textDirection();
       
  7479     else if (painter)
       
  7480         layout_direction = painter->layoutDirection();
       
  7481     else
       
  7482         layout_direction = Qt::LeftToRight;
       
  7483 
       
  7484     tf = QStyle::visualAlignment(layout_direction, QFlag(tf));
       
  7485 
       
  7486     bool isRightToLeft = layout_direction == Qt::RightToLeft;
       
  7487     bool expandtabs = ((tf & Qt::TextExpandTabs) &&
       
  7488                         (((tf & Qt::AlignLeft) && !isRightToLeft) ||
       
  7489                           ((tf & Qt::AlignRight) && isRightToLeft)));
       
  7490 
       
  7491     if (!painter)
       
  7492         tf |= Qt::TextDontPrint;
       
  7493 
       
  7494     uint maxUnderlines = 0;
       
  7495     int numUnderlines = 0;
       
  7496     QVarLengthArray<int, 32> underlinePositions(1);
       
  7497 
       
  7498     QFontMetricsF fm(fnt);
       
  7499     QString text = str;
       
  7500     int offset = 0;
       
  7501 start_lengthVariant:
       
  7502     bool hasMoreLengthVariants = false;
       
  7503     // compatible behaviour to the old implementation. Replace
       
  7504     // tabs by spaces
       
  7505     int old_offset = offset;
       
  7506     for (; offset < text.length(); offset++) {
       
  7507         QChar chr = text.at(offset);
       
  7508         if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) {
       
  7509             text[offset] = QLatin1Char(' ');
       
  7510         } else if (chr == QLatin1Char('\n')) {
       
  7511             text[offset] = QChar::LineSeparator;
       
  7512         } else if (chr == QLatin1Char('&')) {
       
  7513             ++maxUnderlines;
       
  7514         } else if (chr == QLatin1Char('\t')) {
       
  7515             if (!expandtabs) {
       
  7516                 text[offset] = QLatin1Char(' ');
       
  7517             } else if (!tabarraylen && !tabstops) {
       
  7518                 tabstops = qRound(fm.width(QLatin1Char('x'))*8);
       
  7519             }
       
  7520         } else if (chr == QChar(ushort(0x9c))) {
       
  7521             // string with multiple length variants
       
  7522             hasMoreLengthVariants = true;
       
  7523             break;
       
  7524         }
       
  7525     }
       
  7526 
       
  7527     int length = offset - old_offset;
       
  7528     if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
       
  7529         underlinePositions.resize(maxUnderlines + 1);
       
  7530 
       
  7531         QChar *cout = text.data() + old_offset;
       
  7532         QChar *cin = cout;
       
  7533         int l = length;
       
  7534         while (l) {
       
  7535             if (*cin == QLatin1Char('&')) {
       
  7536                 ++cin;
       
  7537                 --length;
       
  7538                 --l;
       
  7539                 if (!l)
       
  7540                     break;
       
  7541                 if (*cin != QLatin1Char('&') && !hidemnmemonic)
       
  7542                     underlinePositions[numUnderlines++] = cout - text.data() - old_offset;
       
  7543             }
       
  7544             *cout = *cin;
       
  7545             ++cout;
       
  7546             ++cin;
       
  7547             --l;
       
  7548         }
       
  7549     }
       
  7550 
       
  7551     // no need to do extra work for underlines if we don't paint
       
  7552     if (tf & Qt::TextDontPrint)
       
  7553         numUnderlines = 0;
       
  7554 
       
  7555     underlinePositions[numUnderlines] = -1;
       
  7556     qreal height = 0;
       
  7557     qreal width = 0;
       
  7558 
       
  7559     QString finalText = text.mid(old_offset, length);
       
  7560     QStackTextEngine engine(finalText, fnt);
       
  7561     if (option) {
       
  7562         engine.option = *option;
       
  7563     }
       
  7564 
       
  7565     engine.option.setTextDirection(layout_direction);
       
  7566     if (tf & Qt::AlignJustify)
       
  7567         engine.option.setAlignment(Qt::AlignJustify);
       
  7568     else
       
  7569         engine.option.setAlignment(Qt::AlignLeft); // do not do alignment twice
       
  7570 
       
  7571     if (!option && (tf & Qt::TextWrapAnywhere))
       
  7572         engine.option.setWrapMode(QTextOption::WrapAnywhere);
       
  7573 
       
  7574     if (tf & Qt::TextJustificationForced)
       
  7575         engine.forceJustification = true;
       
  7576     QTextLayout textLayout(&engine);
       
  7577     textLayout.setCacheEnabled(true);
       
  7578     textLayout.engine()->underlinePositions = underlinePositions.data();
       
  7579 
       
  7580     if (finalText.isEmpty()) {
       
  7581         height = fm.height();
       
  7582         width = 0;
       
  7583         tf |= Qt::TextDontPrint;
       
  7584     } else {
       
  7585         qreal lineWidth = 0x01000000;
       
  7586         if (wordwrap || (tf & Qt::TextJustificationForced))
       
  7587             lineWidth = qMax<qreal>(0, r.width());
       
  7588         if(!wordwrap)
       
  7589             tf |= Qt::TextIncludeTrailingSpaces;
       
  7590         textLayout.engine()->ignoreBidi = bool(tf & Qt::TextDontPrint);
       
  7591         textLayout.beginLayout();
       
  7592 
       
  7593         qreal leading = fm.leading();
       
  7594         height = -leading;
       
  7595 
       
  7596         while (1) {
       
  7597             QTextLine l = textLayout.createLine();
       
  7598             if (!l.isValid())
       
  7599                 break;
       
  7600 
       
  7601             l.setLineWidth(lineWidth);
       
  7602             height += leading;
       
  7603             l.setPosition(QPointF(0., height));
       
  7604             height += l.height();
       
  7605             width = qMax(width, l.naturalTextWidth());
       
  7606             if (!brect && height >= r.height())
       
  7607                 break;
       
  7608         }
       
  7609         textLayout.endLayout();
       
  7610     }
       
  7611 
       
  7612     qreal yoff = 0;
       
  7613     qreal xoff = 0;
       
  7614     if (tf & Qt::AlignBottom) {
       
  7615         yoff = r.height() - height;
       
  7616     } else if (tf & Qt::AlignVCenter) {
       
  7617         yoff = (r.height() - height)/2;
       
  7618         if (painter) {
       
  7619             QTransform::TransformationType type = painter->transform().type();
       
  7620             if (type <= QTransform::TxScale) {
       
  7621                 // do the rounding manually to work around inconsistencies
       
  7622                 // in the paint engines when drawing on floating point offsets
       
  7623                 const qreal scale = painter->transform().m22();
       
  7624                 if (scale != 0)
       
  7625                     yoff = qRound(yoff * scale) / scale;
       
  7626             }
       
  7627         }
       
  7628     }
       
  7629     if (tf & Qt::AlignRight) {
       
  7630         xoff = r.width() - width;
       
  7631     } else if (tf & Qt::AlignHCenter) {
       
  7632         xoff = (r.width() - width)/2;
       
  7633         if (painter) {
       
  7634             QTransform::TransformationType type = painter->transform().type();
       
  7635             if (type <= QTransform::TxScale) {
       
  7636                 // do the rounding manually to work around inconsistencies
       
  7637                 // in the paint engines when drawing on floating point offsets
       
  7638                 const qreal scale = painter->transform().m11();
       
  7639                 if (scale != 0)
       
  7640                     xoff = qRound(xoff * scale) / scale;
       
  7641             }
       
  7642         }
       
  7643     }
       
  7644     QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);
       
  7645 
       
  7646     if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) {
       
  7647         offset++;
       
  7648         goto start_lengthVariant;
       
  7649     }
       
  7650     if (brect)
       
  7651         *brect = bounds;
       
  7652 
       
  7653     if (!(tf & Qt::TextDontPrint)) {
       
  7654         bool restore = false;
       
  7655         if (!dontclip && !r.contains(bounds)) {
       
  7656             restore = true;
       
  7657             painter->save();
       
  7658             painter->setClipRect(r, Qt::IntersectClip);
       
  7659         }
       
  7660 
       
  7661         for (int i = 0; i < textLayout.lineCount(); i++) {
       
  7662             QTextLine line = textLayout.lineAt(i);
       
  7663 
       
  7664             if (tf & Qt::AlignRight)
       
  7665                 xoff = r.width() - line.naturalTextWidth();
       
  7666             else if (tf & Qt::AlignHCenter)
       
  7667                 xoff = (r.width() - line.naturalTextWidth())/2;
       
  7668 
       
  7669             line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff));
       
  7670         }
       
  7671 
       
  7672         if (restore) {
       
  7673             painter->restore();
       
  7674         }
       
  7675     }
       
  7676 }
       
  7677 
       
  7678 /*!
       
  7679     Sets the layout direction used by the painter when drawing text,
       
  7680     to the specified \a direction.
       
  7681 
       
  7682     \sa layoutDirection(), drawText(), {QPainter#Settings}{Settings}
       
  7683 */
       
  7684 void QPainter::setLayoutDirection(Qt::LayoutDirection direction)
       
  7685 {
       
  7686     Q_D(QPainter);
       
  7687     if (d->state)
       
  7688         d->state->layoutDirection = direction;
       
  7689 }
       
  7690 
       
  7691 /*!
       
  7692     Returns the layout direction used by the painter when drawing text.
       
  7693 
       
  7694     \sa setLayoutDirection(), drawText(), {QPainter#Settings}{Settings}
       
  7695 */
       
  7696 Qt::LayoutDirection QPainter::layoutDirection() const
       
  7697 {
       
  7698     Q_D(const QPainter);
       
  7699     return d->state ? d->state->layoutDirection : Qt::LeftToRight;
       
  7700 }
       
  7701 
       
  7702 QPainterState::QPainterState(const QPainterState *s)
       
  7703     : brushOrigin(s->brushOrigin), font(s->font), deviceFont(s->deviceFont),
       
  7704       pen(s->pen), brush(s->brush), bgBrush(s->bgBrush),
       
  7705       clipRegion(s->clipRegion), clipPath(s->clipPath),
       
  7706       clipOperation(s->clipOperation),
       
  7707       renderHints(s->renderHints), clipInfo(s->clipInfo),
       
  7708       worldMatrix(s->worldMatrix), matrix(s->matrix), redirectionMatrix(s->redirectionMatrix),
       
  7709       wx(s->wx), wy(s->wy), ww(s->ww), wh(s->wh),
       
  7710       vx(s->vx), vy(s->vy), vw(s->vw), vh(s->vh),
       
  7711       opacity(s->opacity), WxF(s->WxF), VxF(s->VxF),
       
  7712       clipEnabled(s->clipEnabled), bgMode(s->bgMode), painter(s->painter),
       
  7713       layoutDirection(s->layoutDirection),
       
  7714       composition_mode(s->composition_mode),
       
  7715       emulationSpecifier(s->emulationSpecifier), changeFlags(0)
       
  7716 {
       
  7717     dirtyFlags = s->dirtyFlags;
       
  7718 }
       
  7719 
       
  7720 QPainterState::QPainterState()
       
  7721     : brushOrigin(0, 0), bgBrush(Qt::white), clipOperation(Qt::NoClip),
       
  7722       renderHints(0),
       
  7723       wx(0), wy(0), ww(0), wh(0), vx(0), vy(0), vw(0), vh(0),
       
  7724       opacity(1), WxF(false), VxF(false), clipEnabled(true),
       
  7725       bgMode(Qt::TransparentMode), painter(0),
       
  7726       layoutDirection(QApplication::layoutDirection()),
       
  7727       composition_mode(QPainter::CompositionMode_SourceOver),
       
  7728       emulationSpecifier(0), changeFlags(0)
       
  7729 {
       
  7730     dirtyFlags = 0;
       
  7731 }
       
  7732 
       
  7733 QPainterState::~QPainterState()
       
  7734 {
       
  7735 }
       
  7736 
       
  7737 void QPainterState::init(QPainter *p) {
       
  7738     bgBrush = Qt::white;
       
  7739     bgMode = Qt::TransparentMode;
       
  7740     WxF = false;
       
  7741     VxF = false;
       
  7742     clipEnabled = true;
       
  7743     wx = wy = ww = wh = 0;
       
  7744     vx = vy = vw = vh = 0;
       
  7745     painter = p;
       
  7746     pen = QPen();
       
  7747     brushOrigin = QPointF(0, 0);
       
  7748     brush = QBrush();
       
  7749     font = deviceFont = QFont();
       
  7750     clipRegion = QRegion();
       
  7751     clipPath = QPainterPath();
       
  7752     clipOperation = Qt::NoClip;
       
  7753     clipInfo.clear();
       
  7754     worldMatrix.reset();
       
  7755     matrix.reset();
       
  7756     layoutDirection = QApplication::layoutDirection();
       
  7757     composition_mode = QPainter::CompositionMode_SourceOver;
       
  7758     emulationSpecifier = 0;
       
  7759     dirtyFlags = 0;
       
  7760     changeFlags = 0;
       
  7761     renderHints = 0;
       
  7762     opacity = 1;
       
  7763 }
       
  7764 
       
  7765 #ifdef QT3_SUPPORT
       
  7766 static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
       
  7767                           const QPaintDevice *src, const QRect &sr, bool)
       
  7768 {
       
  7769     Q_ASSERT(dst);
       
  7770     Q_ASSERT(src);
       
  7771 
       
  7772     if (src->devType() == QInternal::Pixmap) {
       
  7773         const QPixmap *pixmap = static_cast<const QPixmap *>(src);
       
  7774         QPainter pt(dst);
       
  7775         pt.drawPixmap(dp, *pixmap, sr);
       
  7776 
       
  7777     } else {
       
  7778         qWarning("QPainter: bitBlt only works when source is of type pixmap");
       
  7779     }
       
  7780 }
       
  7781 
       
  7782 void bitBlt(QPaintDevice *dst, int dx, int dy,
       
  7783              const QPaintDevice *src, int sx, int sy, int sw, int sh,
       
  7784              bool ignoreMask )
       
  7785 {
       
  7786     bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
       
  7787 }
       
  7788 
       
  7789 void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
       
  7790 {
       
  7791     bitBlt_helper(dst, dp, src, sr, ignoreMask);
       
  7792 }
       
  7793 
       
  7794 void bitBlt(QPaintDevice *dst, int dx, int dy,
       
  7795             const QImage *src, int sx, int sy, int sw, int sh, int fl)
       
  7796 {
       
  7797     Qt::ImageConversionFlags flags(fl);
       
  7798     QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
       
  7799     bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
       
  7800 }
       
  7801 
       
  7802 #endif // QT3_SUPPORT
       
  7803 
       
  7804 /*!
       
  7805     \fn void QPainter::setBackgroundColor(const QColor &color)
       
  7806 
       
  7807     Use setBackground() instead.
       
  7808 */
       
  7809 
       
  7810 /*!
       
  7811     \fn const QColor &QPainter::backgroundColor() const
       
  7812 
       
  7813     Use background() and QBrush::color() instead.
       
  7814 
       
  7815     \oldcode
       
  7816         QColor myColor = backgroundColor();
       
  7817     \newcode
       
  7818         QColor myColor = background().color();
       
  7819     \endcode
       
  7820 
       
  7821     Note that the background can be a complex brush such as a texture
       
  7822     or a gradient.
       
  7823 */
       
  7824 
       
  7825 /*!
       
  7826     \fn void QPainter::drawText(int x, int y, const QString &text, int pos, int length)
       
  7827     \compat
       
  7828 
       
  7829     Use drawText() combined with QString::mid() instead.
       
  7830 
       
  7831     \oldcode
       
  7832         QPainter painter(this);
       
  7833         painter.drawText(x, y, text, pos, length);
       
  7834     \newcode
       
  7835         QPainter painter(this);
       
  7836         painter.drawText(x, y, text.mid(pos, length));
       
  7837     \endcode
       
  7838 */
       
  7839 
       
  7840 /*!
       
  7841     \fn void QPainter::drawText(const QPoint &point, const QString &text, int pos, int length)
       
  7842     \compat
       
  7843 
       
  7844     Use drawText() combined with QString::mid() instead.
       
  7845 
       
  7846     \oldcode
       
  7847         QPainter painter(this);
       
  7848         painter.drawText(point, text, pos, length);
       
  7849     \newcode
       
  7850         QPainter painter(this);
       
  7851         painter.drawText(point, text.mid(pos, length));
       
  7852     \endcode
       
  7853 */
       
  7854 
       
  7855 /*!
       
  7856     \fn void QPainter::drawText(int x, int y, const QString &text, int length)
       
  7857     \compat
       
  7858 
       
  7859     Use drawText() combined with QString::left() instead.
       
  7860 
       
  7861     \oldcode
       
  7862         QPainter painter(this);
       
  7863         painter.drawText(x, y, text, length);
       
  7864     \newcode
       
  7865         QPainter painter(this);
       
  7866         painter.drawText(x, y, text.left(length));
       
  7867     \endcode
       
  7868 */
       
  7869 
       
  7870 /*!
       
  7871     \fn void QPainter::drawText(const QPoint &point, const QString &text, int length)
       
  7872     \compat
       
  7873 
       
  7874     Use drawText() combined with QString::left() instead.
       
  7875 
       
  7876     \oldcode
       
  7877         QPainter painter(this);
       
  7878         painter.drawText(point, text, length);
       
  7879     \newcode
       
  7880         QPainter painter(this);
       
  7881         painter.drawText(point, text.left(length));
       
  7882     \endcode
       
  7883 */
       
  7884 
       
  7885 /*!
       
  7886     \fn bool QPainter::begin(QPaintDevice *device, const QWidget *init)
       
  7887     \compat
       
  7888 
       
  7889     Use begin() instead.
       
  7890 
       
  7891     If the paint \a device is a QWidget, QPainter is initialized after
       
  7892     the widget's settings automatically. Otherwise, you must call the
       
  7893     initFrom() function to initialize the painters pen, background and
       
  7894     font to the same as any given widget.
       
  7895 
       
  7896     \oldcode
       
  7897         QPainter painter(this);
       
  7898         painter.begin(device, init);
       
  7899     \newcode
       
  7900         QPainter painter(this);
       
  7901         painter.begin(device);
       
  7902         painter.initFrom(init);
       
  7903     \endcode
       
  7904 */
       
  7905 
       
  7906 /*!
       
  7907     \fn void QPainter::drawImage(const QRectF &target, const QImage &image, const QRectF &source,
       
  7908                          Qt::ImageConversionFlags flags)
       
  7909 
       
  7910     Draws the rectangular portion \a source of the given \a image
       
  7911     into the \a target rectangle in the paint device.
       
  7912 
       
  7913     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
       
  7914 
       
  7915     If the image needs to be modified to fit in a lower-resolution
       
  7916     result (e.g. converting from 32-bit to 8-bit), use the \a flags to
       
  7917     specify how you would prefer this to happen.
       
  7918 
       
  7919     \table 100%
       
  7920     \row
       
  7921     \o
       
  7922     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 20
       
  7923     \endtable
       
  7924 
       
  7925     \sa drawPixmap()
       
  7926 */
       
  7927 
       
  7928 /*!
       
  7929     \fn void QPainter::drawImage(const QRect &target, const QImage &image, const QRect &source,
       
  7930                                  Qt::ImageConversionFlags flags)
       
  7931     \overload
       
  7932 
       
  7933     Draws the rectangular portion \a source of the given \a image
       
  7934     into the \a target rectangle in the paint device.
       
  7935 
       
  7936     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
       
  7937 */
       
  7938 
       
  7939 /*!
       
  7940     \fn void QPainter::drawImage(const QPointF &point, const QImage &image)
       
  7941 
       
  7942     \overload
       
  7943 
       
  7944     Draws the given \a image at the given \a point.
       
  7945 */
       
  7946 
       
  7947 /*!
       
  7948     \fn void QPainter::drawImage(const QPoint &point, const QImage &image)
       
  7949 
       
  7950     \overload
       
  7951 
       
  7952     Draws the given \a image at the given \a point.
       
  7953 */
       
  7954 
       
  7955 /*!
       
  7956     \fn void QPainter::drawImage(const QPointF &point, const QImage &image, const QRectF &source,
       
  7957                                  Qt::ImageConversionFlags flags = 0)
       
  7958 
       
  7959     \overload
       
  7960 
       
  7961     Draws the rectangular portion \a source of the given \a image with
       
  7962     its origin at the given \a point.
       
  7963 */
       
  7964 
       
  7965 /*!
       
  7966     \fn void QPainter::drawImage(const QPoint &point, const QImage &image, const QRect &source,
       
  7967                                  Qt::ImageConversionFlags flags = 0)
       
  7968     \overload
       
  7969 
       
  7970     Draws the rectangular portion \a source of the given \a image with
       
  7971     its origin at the given \a point.
       
  7972 */
       
  7973 
       
  7974 /*!
       
  7975     \fn void QPainter::drawImage(const QRectF &rectangle, const QImage &image)
       
  7976 
       
  7977     \overload
       
  7978 
       
  7979     Draws the given \a image into the given \a rectangle.
       
  7980 
       
  7981     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
       
  7982 */
       
  7983 
       
  7984 /*!
       
  7985     \fn void QPainter::drawImage(const QRect &rectangle, const QImage &image)
       
  7986 
       
  7987     \overload
       
  7988 
       
  7989     Draws the given \a image into the given \a rectangle.
       
  7990 
       
  7991    \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
       
  7992 */
       
  7993 
       
  7994 /*!
       
  7995     \fn void QPainter::drawImage(int x, int y, const QImage &image,
       
  7996                                  int sx, int sy, int sw, int sh,
       
  7997                                  Qt::ImageConversionFlags flags)
       
  7998     \overload
       
  7999 
       
  8000     Draws an image at (\a{x}, \a{y}) by copying a part of \a image into
       
  8001     the paint device.
       
  8002 
       
  8003     (\a{x}, \a{y}) specifies the top-left point in the paint device that is
       
  8004     to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
       
  8005     image that is to be drawn. The default is (0, 0).
       
  8006 
       
  8007     (\a{sw}, \a{sh}) specifies the size of the image that is to be drawn.
       
  8008     The default, (0, 0) (and negative) means all the way to the
       
  8009     bottom-right of the image.
       
  8010 */
       
  8011 
       
  8012 /*!
       
  8013     \fn void QPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement)
       
  8014 
       
  8015     Use setRedirected() instead.
       
  8016 */
       
  8017 
       
  8018 /*!
       
  8019     \fn QPaintDevice *QPainter::redirect(QPaintDevice *pdev)
       
  8020 
       
  8021     Use redirected() instead.
       
  8022 */
       
  8023 
       
  8024 /*!
       
  8025     \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
       
  8026                                      const QString &text, int length)
       
  8027     \compat
       
  8028 
       
  8029     Returns the bounding rectangle for the given \a length of the \a
       
  8030     text constrained by the provided \a rectangle.
       
  8031 
       
  8032     Use boundingRect() combined with QString::left() instead.
       
  8033 
       
  8034     \oldcode
       
  8035         QRect rectangle = boundingRect(rect, flags, text, length);
       
  8036     \newcode
       
  8037         QRect rectangle = boundingRect(rect, flags, text.left(length));
       
  8038     \endcode
       
  8039 */
       
  8040 
       
  8041 /*!
       
  8042     \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text,
       
  8043                                 int length, QRect *br)
       
  8044     \compat
       
  8045 
       
  8046     Use drawText() combined with QString::left() instead.
       
  8047 
       
  8048     \oldcode
       
  8049         QPainter painter(this);
       
  8050         painter.drawText(rectangle, flags, text, length, br );
       
  8051     \newcode
       
  8052         QPainter painter(this);
       
  8053         painter.drawText(rectangle, flags, text.left(length), br );
       
  8054     \endcode
       
  8055 */
       
  8056 
       
  8057 /*!
       
  8058     \fn QRect QPainter::boundingRect(int x, int y, int width, int height, int flags,
       
  8059                                      const QString &text, int length);
       
  8060 
       
  8061     \compat
       
  8062 
       
  8063     Returns the bounding rectangle for the given \a length of the \a
       
  8064     text constrained by the rectangle that begins at point (\a{x},
       
  8065     \a{y}) with the given \a width and \a height.
       
  8066 
       
  8067     Use boundingRect() combined with QString::left() instead.
       
  8068 
       
  8069     \oldcode
       
  8070         QRect rectangle = boundingRect(x, y, width, height, flags, text, length);
       
  8071     \newcode
       
  8072         QRect rectangle = boundingRect(x, y, width, height, flags, text.left(length));
       
  8073     \endcode
       
  8074 */
       
  8075 
       
  8076 /*!
       
  8077     \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
       
  8078                                 const QString &text, int length, QRect *br)
       
  8079 
       
  8080     \compat
       
  8081 
       
  8082     Use drawText() combined with QString::left() instead.
       
  8083 
       
  8084     \oldcode
       
  8085         QPainter painter(this);
       
  8086         painter.drawText(x, y, width, height, flags, text, length, br );
       
  8087     \newcode
       
  8088         QPainter painter(this);
       
  8089         painter.drawText(x, y, width, height, flags, text.left(length), br );
       
  8090     \endcode
       
  8091 */
       
  8092 
       
  8093 
       
  8094 /*!
       
  8095     \class QPaintEngineState
       
  8096     \since 4.1
       
  8097 
       
  8098     \brief The QPaintEngineState class provides information about the
       
  8099     active paint engine's current state.
       
  8100     \reentrant
       
  8101 
       
  8102     QPaintEngineState records which properties that have changed since
       
  8103     the last time the paint engine was updated, as well as their
       
  8104     current value.
       
  8105 
       
  8106     Which properties that have changed can at any time be retrieved
       
  8107     using the state() function. This function returns an instance of
       
  8108     the QPaintEngine::DirtyFlags type which stores an OR combination
       
  8109     of QPaintEngine::DirtyFlag values. The QPaintEngine::DirtyFlag
       
  8110     enum defines whether a property has changed since the last update
       
  8111     or not.
       
  8112 
       
  8113     If a property is marked with a dirty flag, its current value can
       
  8114     be retrieved using the corresponding get function:
       
  8115 
       
  8116     \target GetFunction
       
  8117 
       
  8118     \table
       
  8119     \header \o Property Flag \o Current Property Value
       
  8120     \row \o QPaintEngine::DirtyBackground \o backgroundBrush()
       
  8121     \row \o QPaintEngine::DirtyBackgroundMode \o backgroundMode()
       
  8122     \row \o QPaintEngine::DirtyBrush \o brush()
       
  8123     \row \o QPaintEngine::DirtyBrushOrigin \o brushOrigin()
       
  8124     \row \o QPaintEngine::DirtyClipRegion \e or QPaintEngine::DirtyClipPath
       
  8125          \o clipOperation()
       
  8126     \row \o QPaintEngine::DirtyClipPath \o clipPath()
       
  8127     \row \o QPaintEngine::DirtyClipRegion \o clipRegion()
       
  8128     \row \o QPaintEngine::DirtyCompositionMode \o compositionMode()
       
  8129     \row \o QPaintEngine::DirtyFont \o font()
       
  8130     \row \o QPaintEngine::DirtyTransform \o transform()
       
  8131     \row \o QPaintEngine::DirtyClipEnabled \o isClipEnabled()
       
  8132     \row \o QPaintEngine::DirtyPen \o pen()
       
  8133     \row \o QPaintEngine::DirtyHints \o renderHints()
       
  8134     \endtable
       
  8135 
       
  8136     The QPaintEngineState class also provide the painter() function
       
  8137     which returns a pointer to the painter that is currently updating
       
  8138     the paint engine.
       
  8139 
       
  8140     An instance of this class, representing the current state of the
       
  8141     active paint engine, is passed as argument to the
       
  8142     QPaintEngine::updateState() function. The only situation in which
       
  8143     you will have to use this class directly is when implementing your
       
  8144     own paint engine.
       
  8145 
       
  8146     \sa QPaintEngine
       
  8147 */
       
  8148 
       
  8149 
       
  8150 /*!
       
  8151     \fn QPaintEngine::DirtyFlags QPaintEngineState::state() const
       
  8152 
       
  8153     Returns a combination of flags identifying the set of properties
       
  8154     that need to be updated when updating the paint engine's state
       
  8155     (i.e. during a call to the QPaintEngine::updateState() function).
       
  8156 
       
  8157     \sa QPaintEngine::updateState()
       
  8158 */
       
  8159 
       
  8160 
       
  8161 /*!
       
  8162     Returns the pen in the current paint engine state.
       
  8163 
       
  8164     This variable should only be used when the state() returns a
       
  8165     combination which includes the QPaintEngine::DirtyPen flag.
       
  8166 
       
  8167     \sa state(), QPaintEngine::updateState()
       
  8168 */
       
  8169 
       
  8170 QPen QPaintEngineState::pen() const
       
  8171 {
       
  8172     return static_cast<const QPainterState *>(this)->pen;
       
  8173 }
       
  8174 
       
  8175 /*!
       
  8176     Returns the brush in the current paint engine state.
       
  8177 
       
  8178     This variable should only be used when the state() returns a
       
  8179     combination which includes the QPaintEngine::DirtyBrush flag.
       
  8180 
       
  8181     \sa state(), QPaintEngine::updateState()
       
  8182 */
       
  8183 
       
  8184 QBrush QPaintEngineState::brush() const
       
  8185 {
       
  8186     return static_cast<const QPainterState *>(this)->brush;
       
  8187 }
       
  8188 
       
  8189 /*!
       
  8190     Returns the brush origin in the current paint engine state.
       
  8191 
       
  8192     This variable should only be used when the state() returns a
       
  8193     combination which includes the QPaintEngine::DirtyBrushOrigin flag.
       
  8194 
       
  8195     \sa state(), QPaintEngine::updateState()
       
  8196 */
       
  8197 
       
  8198 QPointF QPaintEngineState::brushOrigin() const
       
  8199 {
       
  8200     return static_cast<const QPainterState *>(this)->brushOrigin;
       
  8201 }
       
  8202 
       
  8203 /*!
       
  8204     Returns the background brush in the current paint engine state.
       
  8205 
       
  8206     This variable should only be used when the state() returns a
       
  8207     combination which includes the QPaintEngine::DirtyBackground flag.
       
  8208 
       
  8209     \sa state(), QPaintEngine::updateState()
       
  8210 */
       
  8211 
       
  8212 QBrush QPaintEngineState::backgroundBrush() const
       
  8213 {
       
  8214     return static_cast<const QPainterState *>(this)->bgBrush;
       
  8215 }
       
  8216 
       
  8217 /*!
       
  8218     Returns the background mode in the current paint engine
       
  8219     state.
       
  8220 
       
  8221     This variable should only be used when the state() returns a
       
  8222     combination which includes the QPaintEngine::DirtyBackgroundMode flag.
       
  8223 
       
  8224     \sa state(), QPaintEngine::updateState()
       
  8225 */
       
  8226 
       
  8227 Qt::BGMode QPaintEngineState::backgroundMode() const
       
  8228 {
       
  8229     return static_cast<const QPainterState *>(this)->bgMode;
       
  8230 }
       
  8231 
       
  8232 /*!
       
  8233     Returns the font in the current paint engine
       
  8234     state.
       
  8235 
       
  8236     This variable should only be used when the state() returns a
       
  8237     combination which includes the QPaintEngine::DirtyFont flag.
       
  8238 
       
  8239     \sa state(), QPaintEngine::updateState()
       
  8240 */
       
  8241 
       
  8242 QFont QPaintEngineState::font() const
       
  8243 {
       
  8244     return static_cast<const QPainterState *>(this)->font;
       
  8245 }
       
  8246 
       
  8247 /*!
       
  8248     \since 4.2
       
  8249     \obsolete
       
  8250 
       
  8251     Returns the matrix in the current paint engine
       
  8252     state.
       
  8253 
       
  8254     \note It is advisable to use transform() instead of this function to
       
  8255     preserve the properties of perspective transformations.
       
  8256 
       
  8257     This variable should only be used when the state() returns a
       
  8258     combination which includes the QPaintEngine::DirtyTransform flag.
       
  8259 
       
  8260     \sa state(), QPaintEngine::updateState()
       
  8261 */
       
  8262 
       
  8263 QMatrix QPaintEngineState::matrix() const
       
  8264 {
       
  8265     const QPainterState *st = static_cast<const QPainterState *>(this);
       
  8266 
       
  8267     return st->matrix.toAffine();
       
  8268 }
       
  8269 
       
  8270 /*!
       
  8271     \since 4.3
       
  8272 
       
  8273     Returns the matrix in the current paint engine state.
       
  8274 
       
  8275     This variable should only be used when the state() returns a
       
  8276     combination which includes the QPaintEngine::DirtyTransform flag.
       
  8277 
       
  8278     \sa state(), QPaintEngine::updateState()
       
  8279 */
       
  8280 
       
  8281 
       
  8282 QTransform QPaintEngineState::transform() const
       
  8283 {
       
  8284     const QPainterState *st = static_cast<const QPainterState *>(this);
       
  8285 
       
  8286     return st->matrix;
       
  8287 }
       
  8288 
       
  8289 
       
  8290 /*!
       
  8291     Returns the clip operation in the current paint engine
       
  8292     state.
       
  8293 
       
  8294     This variable should only be used when the state() returns a
       
  8295     combination which includes either the QPaintEngine::DirtyClipPath
       
  8296     or the QPaintEngine::DirtyClipRegion flag.
       
  8297 
       
  8298     \sa state(), QPaintEngine::updateState()
       
  8299 */
       
  8300 
       
  8301 Qt::ClipOperation QPaintEngineState::clipOperation() const
       
  8302 {
       
  8303     return static_cast<const QPainterState *>(this)->clipOperation;
       
  8304 }
       
  8305 
       
  8306 /*!
       
  8307     \since 4.3
       
  8308 
       
  8309     Returns whether the coordinate of the fill have been specified
       
  8310     as bounded by the current rendering operation and have to be
       
  8311     resolved (about the currently rendered primitive).
       
  8312 */
       
  8313 bool QPaintEngineState::brushNeedsResolving() const
       
  8314 {
       
  8315     const QBrush &brush = static_cast<const QPainterState *>(this)->brush;
       
  8316     return needsResolving(brush);
       
  8317 }
       
  8318 
       
  8319 
       
  8320 /*!
       
  8321     \since 4.3
       
  8322 
       
  8323     Returns whether the coordinate of the stroke have been specified
       
  8324     as bounded by the current rendering operation and have to be
       
  8325     resolved (about the currently rendered primitive).
       
  8326 */
       
  8327 bool QPaintEngineState::penNeedsResolving() const
       
  8328 {
       
  8329     const QPen &pen = static_cast<const QPainterState *>(this)->pen;
       
  8330     return needsResolving(pen.brush());
       
  8331 }
       
  8332 
       
  8333 /*!
       
  8334     Returns the clip region in the current paint engine state.
       
  8335 
       
  8336     This variable should only be used when the state() returns a
       
  8337     combination which includes the QPaintEngine::DirtyClipRegion flag.
       
  8338 
       
  8339     \sa state(), QPaintEngine::updateState()
       
  8340 */
       
  8341 
       
  8342 QRegion QPaintEngineState::clipRegion() const
       
  8343 {
       
  8344     return static_cast<const QPainterState *>(this)->clipRegion;
       
  8345 }
       
  8346 
       
  8347 /*!
       
  8348     Returns the clip path in the current paint engine state.
       
  8349 
       
  8350     This variable should only be used when the state() returns a
       
  8351     combination which includes the QPaintEngine::DirtyClipPath flag.
       
  8352 
       
  8353     \sa state(), QPaintEngine::updateState()
       
  8354 */
       
  8355 
       
  8356 QPainterPath QPaintEngineState::clipPath() const
       
  8357 {
       
  8358     return static_cast<const QPainterState *>(this)->clipPath;
       
  8359 }
       
  8360 
       
  8361 /*!
       
  8362     Returns wether clipping is enabled or not in the current paint
       
  8363     engine state.
       
  8364 
       
  8365     This variable should only be used when the state() returns a
       
  8366     combination which includes the QPaintEngine::DirtyClipEnabled
       
  8367     flag.
       
  8368 
       
  8369     \sa state(), QPaintEngine::updateState()
       
  8370 */
       
  8371 
       
  8372 bool QPaintEngineState::isClipEnabled() const
       
  8373 {
       
  8374     return static_cast<const QPainterState *>(this)->clipEnabled;
       
  8375 }
       
  8376 
       
  8377 /*!
       
  8378     Returns the render hints in the current paint engine state.
       
  8379 
       
  8380     This variable should only be used when the state() returns a
       
  8381     combination which includes the QPaintEngine::DirtyHints
       
  8382     flag.
       
  8383 
       
  8384     \sa state(), QPaintEngine::updateState()
       
  8385 */
       
  8386 
       
  8387 QPainter::RenderHints QPaintEngineState::renderHints() const
       
  8388 {
       
  8389     return static_cast<const QPainterState *>(this)->renderHints;
       
  8390 }
       
  8391 
       
  8392 /*!
       
  8393     Returns the composition mode in the current paint engine state.
       
  8394 
       
  8395     This variable should only be used when the state() returns a
       
  8396     combination which includes the QPaintEngine::DirtyCompositionMode
       
  8397     flag.
       
  8398 
       
  8399     \sa state(), QPaintEngine::updateState()
       
  8400 */
       
  8401 
       
  8402 QPainter::CompositionMode QPaintEngineState::compositionMode() const
       
  8403 {
       
  8404     return static_cast<const QPainterState *>(this)->composition_mode;
       
  8405 }
       
  8406 
       
  8407 
       
  8408 /*!
       
  8409     Returns a pointer to the painter currently updating the paint
       
  8410     engine.
       
  8411 */
       
  8412 
       
  8413 QPainter *QPaintEngineState::painter() const
       
  8414 {
       
  8415     return static_cast<const QPainterState *>(this)->painter;
       
  8416 }
       
  8417 
       
  8418 
       
  8419 /*!
       
  8420     \since 4.2
       
  8421 
       
  8422     Returns the opacity in the current paint engine state.
       
  8423 */
       
  8424 
       
  8425 qreal QPaintEngineState::opacity() const
       
  8426 {
       
  8427     return static_cast<const QPainterState *>(this)->opacity;
       
  8428 }
       
  8429 
       
  8430 /*!
       
  8431     \since 4.3
       
  8432 
       
  8433     Sets the world transformation matrix.
       
  8434     If \a combine is true, the specified \a transform is combined with
       
  8435     the current matrix; otherwise it replaces the current matrix.
       
  8436 
       
  8437     \sa transform() setWorldTransform()
       
  8438 */
       
  8439 
       
  8440 void QPainter::setTransform(const QTransform &transform, bool combine )
       
  8441 {
       
  8442     setWorldTransform(transform, combine);
       
  8443 }
       
  8444 
       
  8445 /*!
       
  8446     Returns the world transformation matrix.
       
  8447 
       
  8448     \sa worldTransform()
       
  8449 */
       
  8450 
       
  8451 const QTransform & QPainter::transform() const
       
  8452 {
       
  8453     return worldTransform();
       
  8454 }
       
  8455 
       
  8456 
       
  8457 /*!
       
  8458     Returns the matrix that transforms from logical coordinates to
       
  8459     device coordinates of the platform dependent paint device.
       
  8460 
       
  8461     This function is \e only needed when using platform painting
       
  8462     commands on the platform dependent handle (Qt::HANDLE), and the
       
  8463     platform does not do transformations nativly.
       
  8464 
       
  8465     The QPaintEngine::PaintEngineFeature enum can be queried to
       
  8466     determine whether the platform performs the transformations or
       
  8467     not.
       
  8468 
       
  8469     \sa worldTransform(), QPaintEngine::hasFeature(),
       
  8470 */
       
  8471 
       
  8472 const QTransform & QPainter::deviceTransform() const
       
  8473 {
       
  8474     Q_D(const QPainter);
       
  8475     if (!d->engine) {
       
  8476         qWarning("QPainter::deviceTransform: Painter not active");
       
  8477         return d->fakeState()->transform;
       
  8478     }
       
  8479     return d->state->matrix;
       
  8480 }
       
  8481 
       
  8482 
       
  8483 /*!
       
  8484     Resets any transformations that were made using translate(),
       
  8485     scale(), shear(), rotate(), setWorldTransform(), setViewport()
       
  8486     and setWindow().
       
  8487 
       
  8488     \sa {Coordinate Transformations}
       
  8489 */
       
  8490 
       
  8491 void QPainter::resetTransform()
       
  8492 {
       
  8493      Q_D(QPainter);
       
  8494 #ifdef QT_DEBUG_DRAW
       
  8495     if (qt_show_painter_debug_output)
       
  8496         printf("QPainter::resetMatrix()\n");
       
  8497 #endif
       
  8498     if (!d->engine) {
       
  8499         qWarning("QPainter::resetMatrix: Painter not active");
       
  8500         return;
       
  8501     }
       
  8502 
       
  8503     d->state->wx = d->state->wy = d->state->vx = d->state->vy = 0;                        // default view origins
       
  8504     d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth);
       
  8505     d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight);
       
  8506     d->state->worldMatrix = QTransform();
       
  8507     setMatrixEnabled(false);
       
  8508     setViewTransformEnabled(false);
       
  8509     if (d->extended)
       
  8510         d->extended->transformChanged();
       
  8511     else
       
  8512         d->state->dirtyFlags |= QPaintEngine::DirtyTransform;
       
  8513 }
       
  8514 
       
  8515 /*!
       
  8516     Sets the world transformation matrix.
       
  8517     If \a combine is true, the specified \a matrix is combined with the current matrix;
       
  8518     otherwise it replaces the current matrix.
       
  8519 
       
  8520     \sa transform(), setTransform()
       
  8521 */
       
  8522 
       
  8523 void QPainter::setWorldTransform(const QTransform &matrix, bool combine )
       
  8524 {
       
  8525     Q_D(QPainter);
       
  8526 
       
  8527     if (!d->engine) {
       
  8528         qWarning("QPainter::setWorldTransform: Painter not active");
       
  8529         return;
       
  8530     }
       
  8531 
       
  8532     if (combine)
       
  8533         d->state->worldMatrix = matrix * d->state->worldMatrix;                        // combines
       
  8534     else
       
  8535         d->state->worldMatrix = matrix;                                // set new matrix
       
  8536 
       
  8537     d->state->WxF = true;
       
  8538     d->updateMatrix();
       
  8539 }
       
  8540 
       
  8541 /*!
       
  8542     Returns the world transformation matrix.
       
  8543 */
       
  8544 
       
  8545 const QTransform & QPainter::worldTransform() const
       
  8546 {
       
  8547     Q_D(const QPainter);
       
  8548     if (!d->engine) {
       
  8549         qWarning("QPainter::worldTransform: Painter not active");
       
  8550         return d->fakeState()->transform;
       
  8551     }
       
  8552     return d->state->worldMatrix;
       
  8553 }
       
  8554 
       
  8555 /*!
       
  8556     Returns the transformation matrix combining the current
       
  8557     window/viewport and world transformation.
       
  8558 
       
  8559     \sa setWorldTransform(), setWindow(), setViewport()
       
  8560 */
       
  8561 
       
  8562 QTransform QPainter::combinedTransform() const
       
  8563 {
       
  8564     Q_D(const QPainter);
       
  8565     if (!d->engine) {
       
  8566         qWarning("QPainter::combinedTransform: Painter not active");
       
  8567         return QTransform();
       
  8568     }
       
  8569     return d->state->worldMatrix * d->viewTransform();
       
  8570 }
       
  8571 
       
  8572 void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation)
       
  8573 {
       
  8574     p->draw_helper(path, operation);
       
  8575 }
       
  8576 
       
  8577 /*! \fn Display *QPaintDevice::x11Display() const
       
  8578     Use QX11Info::display() instead.
       
  8579 
       
  8580     \oldcode
       
  8581         Display *display = widget->x11Display();
       
  8582     \newcode
       
  8583         Display *display = QX11Info::display();
       
  8584     \endcode
       
  8585 
       
  8586     \sa QWidget::x11Info(), QX11Info::display()
       
  8587 */
       
  8588 
       
  8589 /*! \fn int QPaintDevice::x11Screen() const
       
  8590     Use QX11Info::screen() instead.
       
  8591 
       
  8592     \oldcode
       
  8593         int screen = widget->x11Screen();
       
  8594     \newcode
       
  8595         int screen = widget->x11Info().screen();
       
  8596     \endcode
       
  8597 
       
  8598     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8599 */
       
  8600 
       
  8601 /*! \fn void *QPaintDevice::x11Visual() const
       
  8602     Use QX11Info::visual() instead.
       
  8603 
       
  8604     \oldcode
       
  8605         void *visual = widget->x11Visual();
       
  8606     \newcode
       
  8607         void *visual = widget->x11Info().visual();
       
  8608     \endcode
       
  8609 
       
  8610     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8611 */
       
  8612 
       
  8613 /*! \fn int QPaintDevice::x11Depth() const
       
  8614     Use QX11Info::depth() instead.
       
  8615 
       
  8616     \oldcode
       
  8617         int depth = widget->x11Depth();
       
  8618     \newcode
       
  8619         int depth = widget->x11Info().depth();
       
  8620     \endcode
       
  8621 
       
  8622     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8623 */
       
  8624 
       
  8625 /*! \fn int QPaintDevice::x11Cells() const
       
  8626     Use QX11Info::cells() instead.
       
  8627 
       
  8628     \oldcode
       
  8629         int cells = widget->x11Cells();
       
  8630     \newcode
       
  8631         int cells = widget->x11Info().cells();
       
  8632     \endcode
       
  8633 
       
  8634     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8635 */
       
  8636 
       
  8637 /*! \fn Qt::HANDLE QPaintDevice::x11Colormap() const
       
  8638     Use QX11Info::colormap() instead.
       
  8639 
       
  8640     \oldcode
       
  8641         unsigned long screen = widget->x11Colormap();
       
  8642     \newcode
       
  8643         unsigned long screen = widget->x11Info().colormap();
       
  8644     \endcode
       
  8645 
       
  8646     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8647 */
       
  8648 
       
  8649 /*! \fn bool QPaintDevice::x11DefaultColormap() const
       
  8650     Use QX11Info::defaultColormap() instead.
       
  8651 
       
  8652     \oldcode
       
  8653         bool isDefault = widget->x11DefaultColormap();
       
  8654     \newcode
       
  8655         bool isDefault = widget->x11Info().defaultColormap();
       
  8656     \endcode
       
  8657 
       
  8658     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8659 */
       
  8660 
       
  8661 /*! \fn bool QPaintDevice::x11DefaultVisual() const
       
  8662     Use QX11Info::defaultVisual() instead.
       
  8663 
       
  8664     \oldcode
       
  8665         bool isDefault = widget->x11DefaultVisual();
       
  8666     \newcode
       
  8667         bool isDefault = widget->x11Info().defaultVisual();
       
  8668     \endcode
       
  8669 
       
  8670     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8671 */
       
  8672 
       
  8673 /*! \fn void *QPaintDevice::x11AppVisual(int screen)
       
  8674     Use QX11Info::visual() instead.
       
  8675 
       
  8676     \oldcode
       
  8677         void *visual = QPaintDevice::x11AppVisual(screen);
       
  8678     \newcode
       
  8679         void *visual = qApp->x11Info(screen).visual();
       
  8680     \endcode
       
  8681 
       
  8682     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8683 */
       
  8684 
       
  8685 /*! \fn Qt::HANDLE QPaintDevice::x11AppColormap(int screen)
       
  8686     Use QX11Info::colormap() instead.
       
  8687 
       
  8688     \oldcode
       
  8689         unsigned long colormap = QPaintDevice::x11AppColormap(screen);
       
  8690     \newcode
       
  8691         unsigned long colormap = qApp->x11Info(screen).colormap();
       
  8692     \endcode
       
  8693 
       
  8694     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8695 */
       
  8696 
       
  8697 /*! \fn Display *QPaintDevice::x11AppDisplay()
       
  8698     Use QX11Info::display() instead.
       
  8699 
       
  8700     \oldcode
       
  8701         Display *display = QPaintDevice::x11AppDisplay();
       
  8702     \newcode
       
  8703         Display *display = qApp->x11Info().display();
       
  8704     \endcode
       
  8705 
       
  8706     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8707 */
       
  8708 
       
  8709 /*! \fn int QPaintDevice::x11AppScreen()
       
  8710     Use QX11Info::screen() instead.
       
  8711 
       
  8712     \oldcode
       
  8713         int screen = QPaintDevice::x11AppScreen();
       
  8714     \newcode
       
  8715         int screen = qApp->x11Info().screen();
       
  8716     \endcode
       
  8717 
       
  8718     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8719 */
       
  8720 
       
  8721 /*! \fn int QPaintDevice::x11AppDepth(int screen)
       
  8722     Use QX11Info::depth() instead.
       
  8723 
       
  8724     \oldcode
       
  8725         int depth = QPaintDevice::x11AppDepth(screen);
       
  8726     \newcode
       
  8727         int depth = qApp->x11Info(screen).depth();
       
  8728     \endcode
       
  8729 
       
  8730     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8731 */
       
  8732 
       
  8733 /*! \fn int QPaintDevice::x11AppCells(int screen)
       
  8734     Use QX11Info::cells() instead.
       
  8735 
       
  8736     \oldcode
       
  8737         int cells = QPaintDevice::x11AppCells(screen);
       
  8738     \newcode
       
  8739         int cells = qApp->x11Info(screen).cells();
       
  8740     \endcode
       
  8741 
       
  8742     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8743 */
       
  8744 
       
  8745 /*! \fn Qt::HANDLE QPaintDevice::x11AppRootWindow(int screen)
       
  8746     Use QX11Info::appRootWindow() instead.
       
  8747 
       
  8748     \oldcode
       
  8749         unsigned long window = QPaintDevice::x11AppRootWindow(screen);
       
  8750     \newcode
       
  8751         unsigned long window = qApp->x11Info(screen).appRootWindow();
       
  8752     \endcode
       
  8753 
       
  8754     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8755 */
       
  8756 
       
  8757 /*! \fn bool QPaintDevice::x11AppDefaultColormap(int screen)
       
  8758     Use QX11Info::defaultColormap() instead.
       
  8759 
       
  8760     \oldcode
       
  8761         bool isDefault = QPaintDevice::x11AppDefaultColormap(screen);
       
  8762     \newcode
       
  8763         bool isDefault = qApp->x11Info(screen).defaultColormap();
       
  8764     \endcode
       
  8765 
       
  8766     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8767 */
       
  8768 
       
  8769 /*! \fn bool QPaintDevice::x11AppDefaultVisual(int screen)
       
  8770     Use QX11Info::defaultVisual() instead.
       
  8771 
       
  8772     \oldcode
       
  8773         bool isDefault = QPaintDevice::x11AppDefaultVisual(screen);
       
  8774     \newcode
       
  8775         bool isDefault = qApp->x11Info(screen).defaultVisual();
       
  8776     \endcode
       
  8777 
       
  8778     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8779 */
       
  8780 
       
  8781 /*! \fn void QPaintDevice::x11SetAppDpiX(int dpi, int screen)
       
  8782     Use QX11Info::setAppDpiX() instead.
       
  8783 */
       
  8784 
       
  8785 /*! \fn void QPaintDevice::x11SetAppDpiY(int dpi, int screen)
       
  8786     Use QX11Info::setAppDpiY() instead.
       
  8787 */
       
  8788 
       
  8789 /*! \fn int QPaintDevice::x11AppDpiX(int screen)
       
  8790     Use QX11Info::appDpiX() instead.
       
  8791 
       
  8792     \oldcode
       
  8793         bool isDefault = QPaintDevice::x11AppDpiX(screen);
       
  8794     \newcode
       
  8795         bool isDefault = qApp->x11Info(screen).appDpiX();
       
  8796     \endcode
       
  8797 
       
  8798     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8799 */
       
  8800 
       
  8801 /*! \fn int QPaintDevice::x11AppDpiY(int screen)
       
  8802     Use QX11Info::appDpiY() instead.
       
  8803 
       
  8804     \oldcode
       
  8805         bool isDefault = QPaintDevice::x11AppDpiY(screen);
       
  8806     \newcode
       
  8807         bool isDefault = qApp->x11Info(screen).appDpiY();
       
  8808     \endcode
       
  8809 
       
  8810     \sa QWidget::x11Info(), QPixmap::x11Info()
       
  8811 */
       
  8812 
       
  8813 /*! \fn HDC QPaintDevice::getDC() const
       
  8814   \internal
       
  8815 */
       
  8816 
       
  8817 /*! \fn void QPaintDevice::releaseDC(HDC) const
       
  8818   \internal
       
  8819 */
       
  8820 
       
  8821 /*! \fn QWSDisplay *QPaintDevice::qwsDisplay()
       
  8822     \internal
       
  8823 */
       
  8824 
       
  8825 QT_END_NAMESPACE