Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/painting/qpainter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7676#define QPaintEngine_OpaqueBackground 0x40000000
    7777
    78 // use the same rounding as in qrasterizer.cpp (6 bit fixed point)
    79 static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
    80 
    8178// #define QT_DEBUG_DRAW
    8279#ifdef QT_DEBUG_DRAW
     
    166163{
    167164    Q_ASSERT(extended);
     165    if (extended->flags() & QPaintEngineEx::DoNotEmulate)
     166        return;
     167
    168168    bool doEmulation = false;
    169169    if (state->bgMode == Qt::OpaqueMode)
     
    185185            extended->setState(state);
    186186        }
    187     } else if (emulationEngine && emulationEngine != extended) {
     187    } else if (emulationEngine == extended) {
    188188        extended = emulationEngine->real_engine;
    189189    }
     
    260260        sp->d_ptr->d_ptrs_size = 4;
    261261        sp->d_ptr->d_ptrs = (QPainterPrivate **)malloc(4 * sizeof(QPainterPrivate *));
     262        Q_CHECK_PTR(sp->d_ptr->d_ptrs);
    262263    } else if (sp->d_ptr->refcount - 1 == sp->d_ptr->d_ptrs_size) {
    263264        // However, to support corner cases we grow the array dynamically if needed.
    264265        sp->d_ptr->d_ptrs_size <<= 1;
    265266        const int newSize = sp->d_ptr->d_ptrs_size * sizeof(QPainterPrivate *);
    266         sp->d_ptr->d_ptrs = (QPainterPrivate **)realloc(sp->d_ptr->d_ptrs, newSize);
    267     }
    268     sp->d_ptr->d_ptrs[++sp->d_ptr->refcount - 2] = q->d_ptr;
    269     q->d_ptr = sp->d_ptr;
     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());
    270272
    271273    Q_ASSERT(q->d_ptr->state);
     
    282284
    283285    // Update matrix.
    284     if (q->d_ptr->state->WxF)
    285         q->d_ptr->state->worldMatrix.translate(-offset.x(), -offset.y());
    286     else
    287         q->d_ptr->state->redirection_offset = offset;
     286    if (q->d_ptr->state->WxF) {
     287        q->d_ptr->state->redirectionMatrix = q->d_ptr->state->matrix;
     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    }
    288294    q->d_ptr->updateMatrix();
    289295
     
    316322    d_ptrs[refcount - 1] = 0;
    317323    q->restore();
    318     q->d_ptr = original;
     324    q->d_ptr.take();
     325    q->d_ptr.reset(original);
    319326
    320327    if (emulationEngine) {
     
    411418            QTransform old_invMatrix = invMatrix;
    412419            txinv = true;
    413             invMatrix = QTransform().translate(-state->redirection_offset.x(), -state->redirection_offset.y());
     420            invMatrix = QTransform();
    414421            QPainterPath clipPath = q->clipPath();
    415422            QRectF r = clipPath.boundingRect().intersected(absPathRect);
     
    469476
    470477    q->save();
    471     q->resetMatrix();
     478    state->matrix = QTransform();
     479    state->dirtyFlags |= QPaintEngine::DirtyTransform;
    472480    updateState(state);
    473481    engine->drawImage(absPathRect,
     
    635643
    636644    txinv = false;                                // no inverted matrix
    637     if (!state->redirection_offset.isNull()) {
    638         // We want to translate in dev space so we do the adding of the redirection
    639         // offset manually.
    640         if (state->matrix.isAffine()) {
    641             state->matrix = QTransform(state->matrix.m11(), state->matrix.m12(),
    642                                        state->matrix.m21(), state->matrix.m22(),
    643                                        state->matrix.dx()-state->redirection_offset.x(),
    644                                        state->matrix.dy()-state->redirection_offset.y());
    645         } else {
    646             QTransform temp;
    647             temp.translate(-state->redirection_offset.x(), -state->redirection_offset.y());
    648             state->matrix *= temp;
    649         }
    650     }
     645    state->matrix *= state->redirectionMatrix;
    651646    if (extended)
    652647        extended->transformChanged();
     
    663658    Q_ASSERT(txinv == false);
    664659    txinv = true;                                // creating inverted matrix
    665     QTransform m;
    666 
    667     if (state->VxF)
    668         m = viewTransform();
    669 
    670     if (state->WxF) {
    671         if (state->VxF)
    672             m = state->worldMatrix * m;
    673         else
    674             m = state->worldMatrix;
    675     }
    676     invMatrix = m.inverted();                // invert matrix
     660    invMatrix = state->matrix.inverted();
    677661}
    678662
     
    945929    other paint devices.
    946930
    947     \ingroup multimedia
    948     \mainclass
     931    \ingroup painting
     932
    949933    \reentrant
    950934
     
    10261010       the origin of widget's background.
    10271011
    1028     \o viewport(), window(), worldMatrix() make up the painter's coordinate
     1012    \o viewport(), window(), worldTransform() make up the painter's coordinate
    10291013        transformation system. For more information, see the \l
    10301014        {Coordinate Transformations} section and the \l {The Coordinate
     
    10371021       painter when drawing text.
    10381022
    1039     \o matrixEnabled() tells whether world transformation is enabled.
     1023    \o worldMatrixEnabled() tells whether world transformation is enabled.
    10401024
    10411025    \o viewTransformEnabled() tells whether view transformation is
     
    12331217
    12341218    All the tranformation operations operate on the transformation
    1235     worldMatrix(). A matrix transforms a point in the plane to another
     1219    worldTransform(). A matrix transforms a point in the plane to another
    12361220    point. For more information about the transformation matrix, see
    1237     the \l {The Coordinate System} and QMatrix documentation.
    1238 
    1239     The setWorldMatrix() function can replace or add to the currently
    1240     set worldMatrix(). The resetMatrix() function resets any
     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
    12411225    transformations that were made using translate(), scale(),
    1242     shear(), rotate(), setWorldMatrix(), setViewport() and setWindow()
    1243     functions. The deviceMatrix() returns the matrix that transforms
     1226    shear(), rotate(), setWorldTransform(), setViewport() and setWindow()
     1227    functions. The deviceTransform() returns the matrix that transforms
    12441228    from logical coordinates to device coordinates of the platform
    12451229    dependent paint device. The latter function is only needed when
     
    12501234    coordinates which then are converted into the physical coordinates
    12511235    of the paint device. The mapping of the logical coordinates to the
    1252     physical coordinates are handled by QPainter's combinedMatrix(), a
    1253     combination of viewport() and window() and worldMatrix(). The
     1236    physical coordinates are handled by QPainter's combinedTransform(), a
     1237    combination of viewport() and window() and worldTransform(). The
    12541238    viewport() represents the physical coordinates specifying an
    12551239    arbitrary rectangle, the window() describes the same rectangle in
    1256     logical coordinates, and the worldMatrix() is identical with the
     1240    logical coordinates, and the worldTransform() is identical with the
    12571241    transformation matrix.
    12581242
     
    13341318    polygons instead.
    13351319
    1336     \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example}
     1320    \section1 Performance
     1321
     1322    QPainter is a rich framework that allows developers to do a great
     1323    variety of graphical operations, such as gradients, composition
     1324    modes and vector graphics. And QPainter can do this across a
     1325    variety of different hardware and software stacks. Naturally the
     1326    underlying combination of hardware and software has some
     1327    implications for performance, and ensuring that every single
     1328    operation is fast in combination with all the various combinations
     1329    of composition modes, brushes, clipping, transformation, etc, is
     1330    close to an impossible task because of the number of
     1331    permutations. As a compromise we have selected a subset of the
     1332    QPainter API and backends, were performance is guaranteed to be as
     1333    good as we can sensibly get it for the given combination of
     1334    hardware and software.
     1335
     1336    The backends we focus on as high-performance engines are:
     1337
     1338    \list
     1339
     1340    \o Raster - This backend implements all rendering in pure software
     1341    and is always used to render into QImages. For optimal performance
     1342    only use the format types QImage::Format_ARGB32_Premultiplied,
     1343    QImage::Format_RGB32 or QImage::Format_RGB16. Any other format,
     1344    including QImage::Format_ARGB32, has significantly worse
     1345    performance. This engine is also used by default on Windows and on
     1346    QWS. It can be used as default graphics system on any
     1347    OS/hardware/software combination by passing \c {-graphicssystem
     1348    raster} on the command line
     1349
     1350    \o OpenGL 2.0 (ES) - This backend is the primary backend for
     1351    hardware accelerated graphics. It can be run on desktop machines
     1352    and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0
     1353    specification. This includes most graphics chips produced in the
     1354    last couple of years. The engine can be enabled by using QPainter
     1355    onto a QGLWidget or by passing \c {-graphicssystem opengl} on the
     1356    command line when the underlying system supports it.
     1357
     1358    \o OpenVG - This backend implements the Khronos standard for 2D
     1359    and Vector Graphics. It is primarily for embedded devices with
     1360    hardware support for OpenVG.  The engine can be enabled by
     1361    passing \c {-graphicssystem openvg} on the command line when
     1362    the underlying system supports it.
     1363
     1364    \endlist
     1365
     1366    These operations are:
     1367
     1368    \list
     1369
     1370    \o Simple transformations, meaning translation and scaling, pluss
     1371    0, 90, 180, 270 degree rotations.
     1372
     1373    \o \c drawPixmap() in combination with simple transformations and
     1374    opacity with non-smooth transformation mode
     1375    (\c QPainter::SmoothPixmapTransform not enabled as a render hint).
     1376
     1377    \o Text drawing with regular font sizes with simple
     1378    transformations with solid colors using no or 8-bit antialiasing.
     1379
     1380    \o Rectangle fills with solid color, two-color linear gradients
     1381    and simple transforms.
     1382
     1383    \o Rectangular clipping with simple transformations and intersect
     1384    clip.
     1385
     1386    \o Composition Modes \c QPainter::CompositionMode_Source and
     1387    QPainter::CompositionMode_SourceOver
     1388
     1389    \o Rounded rectangle filling using solid color and two-color
     1390    linear gradients fills.
     1391
     1392    \o 3x3 patched pixmaps, via qDrawBorderPixmap.
     1393
     1394    \endlist
     1395
     1396    This list gives an indication of which features to safely use in
     1397    an application where performance is critical. For certain setups,
     1398    other operations may be fast too, but before making extensive use
     1399    of them, it is recommended to benchmark and verify them on the
     1400    system where the software will run in the end. There are also
     1401    cases where expensive operations are ok to use, for instance when
     1402    the result is cached in a QPixmap.
     1403
     1404    \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example},
     1405        {Drawing Utility Functions}
    13371406*/
    13381407
     
    13751444
    13761445QPainter::QPainter()
    1377 {
    1378     d_ptr = new QPainterPrivate(this);
     1446    : d_ptr(new QPainterPrivate(this))
     1447{
    13791448}
    13801449
     
    14081477    Q_ASSERT(pd != 0);
    14091478    if (!QPainterPrivate::attachPainterPrivate(this, pd)) {
    1410         d_ptr = new QPainterPrivate(this);
     1479        d_ptr.reset(new QPainterPrivate(this));
    14111480        begin(pd);
    14121481    }
     
    14201489{
    14211490    d_ptr->inDestructor = true;
    1422     if (isActive())
    1423         end();
    1424     else if (d_ptr->refcount > 1)
    1425         d_ptr->detachPainterPrivate(this);
    1426 
     1491    QT_TRY {
     1492        if (isActive())
     1493            end();
     1494        else if (d_ptr->refcount > 1)
     1495            d_ptr->detachPainterPrivate(this);
     1496    } QT_CATCH(...) {
     1497        // don't throw anything in the destructor.
     1498    }
    14271499    if (d_ptr) {
    14281500        // Make sure we haven't messed things up.
     
    14321504        if (d_ptr->d_ptrs)
    14331505            free(d_ptr->d_ptrs);
    1434         delete d_ptr;
    14351506    }
    14361507}
     
    14851556    d->state->deviceFont = QFont(widget->font(), const_cast<QWidget*> (widget));
    14861557    d->state->font = d->state->deviceFont;
    1487     if (d->engine) {
     1558    if (d->extended) {
     1559        d->extended->penChanged();
     1560    } else if (d->engine) {
    14881561        d->engine->setDirty(QPaintEngine::DirtyPen);
    14891562        d->engine->setDirty(QPaintEngine::DirtyBrush);
     
    15711644        for (int i=0; i<d->state->clipInfo.size(); ++i) {
    15721645            const QPainterClipInfo &info = d->state->clipInfo.at(i);
    1573             tmp->matrix.setMatrix(info.matrix.m11(), info.matrix.m12(), info.matrix.m13(),
    1574                                   info.matrix.m21(), info.matrix.m22(), info.matrix.m23(),
    1575                                   info.matrix.dx() - d->state->redirection_offset.x(),
    1576                                   info.matrix.dy() - d->state->redirection_offset.y(), info.matrix.m33());
     1646            tmp->matrix = info.matrix;
     1647            tmp->matrix *= d->state->redirectionMatrix;
    15771648            tmp->clipOperation = info.operation;
    15781649            if (info.clipType == QPainterClipInfo::RectClip) {
     
    16221693    time.
    16231694
     1695    \warning Painting on a QImage with the format
     1696    QImage::Format_Indexed8 is not supported.
     1697
    16241698    \sa end(), QPainter()
    16251699*/
     1700
     1701static inline void qt_cleanup_painter_state(QPainterPrivate *d)
     1702{
     1703    d->states.clear();
     1704    delete d->state;
     1705    d->state = 0;
     1706    d->engine = 0;
     1707    d->device = 0;
     1708}
    16261709
    16271710bool QPainter::begin(QPaintDevice *pd)
     
    16701753#endif
    16711754
    1672 
    1673     d->device = pd;
    16741755    if (pd->devType() == QInternal::Pixmap)
    16751756        static_cast<QPixmap *>(pd)->detach();
     
    16781759
    16791760    d->engine = pd->paintEngine();
    1680     d->extended = d->engine && d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0;
     1761
     1762    if (!d->engine) {
     1763        qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType());
     1764        return false;
     1765    }
     1766
     1767    d->device = pd;
     1768
     1769    d->extended = d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0;
    16811770    if (d->emulationEngine)
    16821771        d->emulationEngine->real_engine = d->extended;
     
    16881777    d->states.push_back(d->state);
    16891778
    1690     d->state->redirection_offset = redirectionOffset;
     1779    d->state->redirectionMatrix.translate(-redirectionOffset.x(), -redirectionOffset.y());
    16911780    d->state->brushOrigin = QPointF();
    1692 
    1693     if (!d->engine) {
    1694         qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType());
    1695         return true;
    1696     }
    16971781
    16981782    // Slip a painter state into the engine before we do any other operations
     
    17141798                qWarning("QPainter::begin: Widget painting can only begin as a "
    17151799                         "result of a paintEvent");
    1716                 d->engine = 0;
    1717                 d->device = 0;
     1800                qt_cleanup_painter_state(d);
    17181801                return false;
    17191802            }
     
    17221805            if (!inPaintEvent && paintOutsidePaintEvent && !widget->internalWinId()
    17231806                && widget->testAttribute(Qt::WA_WState_Created)) {
    1724                 d->state->redirection_offset -= widget->mapTo(widget->nativeParentWidget(), QPoint());
     1807                const QPoint offset = widget->mapTo(widget->nativeParentWidget(), QPoint());
     1808                d->state->redirectionMatrix.translate(offset.x(), offset.y());
    17251809            }
    17261810            break;
     
    17321816            if (pm->isNull()) {
    17331817                qWarning("QPainter::begin: Cannot paint on a null pixmap");
    1734                 d->engine = 0;
    1735                 d->device = 0;
     1818                qt_cleanup_painter_state(d);
    17361819                return false;
    17371820            }
     
    17491832            if (img->isNull()) {
    17501833                qWarning("QPainter::begin: Cannot paint on a null image");
    1751                 d->engine = 0;
    1752                 d->device = 0;
     1834                qt_cleanup_painter_state(d);
     1835                return false;
     1836            } else if (img->format() == QImage::Format_Indexed8) {
     1837                // Painting on indexed8 images is not supported.
     1838                qWarning("QPainter::begin: Cannot paint on an image with the QImage::Format_Indexed8 format");
     1839                qt_cleanup_painter_state(d);
    17531840                return false;
    17541841            }
     
    17731860            end();
    17741861        } else {
    1775             d->states.clear();
    1776             delete d->state;
    1777             d->state = 0;
     1862            qt_cleanup_painter_state(d);
    17781863        }
    1779         d->engine = 0;
    1780         d->device = 0;
    17811864        return false;
    17821865    } else {
     
    18041887    }
    18051888
    1806     d->state->redirection_offset += d->engine->coordinateOffset();
     1889    const QPoint coordinateOffset = d->engine->coordinateOffset();
     1890    d->state->redirectionMatrix.translate(-coordinateOffset.x(), -coordinateOffset.y());
    18071891
    18081892    Q_ASSERT(d->engine->isActive());
    18091893
    1810     if (!d->state->redirection_offset.isNull())
     1894    if (!d->state->redirectionMatrix.isIdentity())
    18111895        d->updateMatrix();
    18121896
     
    18401924    if (!d->engine) {
    18411925        qWarning("QPainter::end: Painter not active, aborted");
    1842         d->states.clear();
    1843         delete d->state;
    1844         d->state = 0;
    1845         d->device = 0;
     1926        qt_cleanup_painter_state(d);
    18461927        return false;
    18471928    }
     
    18501931        d->detachPainterPrivate(this);
    18511932        return true;
    1852     }
    1853 
    1854     if (d->states.size() > 1) {
    1855         qWarning("QPainter::end: Painter ended with %d saved states",
    1856                  d->states.size());
    18571933    }
    18581934
     
    18701946    }
    18711947
     1948    if (d->states.size() > 1) {
     1949        qWarning("QPainter::end: Painter ended with %d saved states",
     1950                 d->states.size());
     1951    }
     1952
    18721953    if (d->engine->autoDestruct()) {
    18731954        delete d->engine;
    18741955    }
    1875 
    1876     d->engine = 0;
    18771956
    18781957    if (d->emulationEngine) {
     
    18851964    }
    18861965
    1887     d->states.clear();
    1888     delete d->state;
    1889     d->state = 0;
    1890 
    1891     d->device = 0;
     1966    qt_cleanup_painter_state(d);
     1967
    18921968    return ended;
    18931969}
     
    19061982}
    19071983
     1984/*!
     1985    \since 4.6
     1986
     1987    Flushes the painting pipeline and prepares for the user issuing
     1988    commands directly to the underlying graphics context. Must be
     1989    followed by a call to endNativePainting().
     1990
     1991    Here is an example that shows intermixing of painter commands
     1992    and raw OpenGL commands:
     1993
     1994    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21
     1995
     1996    \sa endNativePainting()
     1997*/
     1998void QPainter::beginNativePainting()
     1999{
     2000    Q_D(QPainter);
     2001    if (!d->engine) {
     2002        qWarning("QPainter::beginNativePainting: Painter not active");
     2003        return;
     2004    }
     2005
     2006    if (d->extended)
     2007        d->extended->beginNativePainting();
     2008}
     2009
     2010/*!
     2011    \since 4.6
     2012
     2013    Restores the painter after manually issuing native painting commands.
     2014    Lets the painter restore any native state that it relies on before
     2015    calling any other painter commands.
     2016
     2017    \sa beginNativePainting()
     2018*/
     2019void QPainter::endNativePainting()
     2020{
     2021    Q_D(const QPainter);
     2022    if (!d->engine) {
     2023        qWarning("QPainter::beginNativePainting: Painter not active");
     2024        return;
     2025    }
     2026
     2027    if (d->extended)
     2028        d->extended->endNativePainting();
     2029    else
     2030        d->engine->syncState();
     2031}
    19082032
    19092033/*!
     
    20152139
    20162140    The brush origin specifies the (0, 0) coordinate of the painter's
    2017     brush. This setting only applies to pattern brushes and pixmap
    2018     brushes.
     2141    brush.
    20192142
    20202143    Note that while the brushOrigin() was necessary to adopt the
     
    22372360    Sets the composition mode to the given \a mode.
    22382361
    2239     \warning You can only set the composition mode for QPainter
    2240     objects that operates on a QImage.
     2362    \warning Only a QPainter operating on a QImage fully supports all
     2363    composition modes. The RasterOp modes are supported for X11 as
     2364    described in compositionMode().
    22412365
    22422366    \sa compositionMode()
     
    23722496    is given in logical coordinates.
    23732497
     2498    \warning QPainter does not store the combined clip explicitly as
     2499    this is handled by the underlying QPaintEngine, so the path is
     2500    recreated on demand and transformed to the current logical
     2501    coordinate system. This is potentially an expensive operation.
     2502
    23742503    \sa setClipRegion(), clipPath(), setClipping()
    23752504*/
     
    23922521    for (int i=0; i<d->state->clipInfo.size(); ++i) {
    23932522        const QPainterClipInfo &info = d->state->clipInfo.at(i);
    2394         QRegion other;
    23952523        switch (info.clipType) {
    23962524
     
    24452573                continue;
    24462574            }
    2447             if (info.operation == Qt::IntersectClip)
    2448                 region &= QRegion(info.rect) * matrix;
    2449             else if (info.operation == Qt::UniteClip)
     2575            if (info.operation == Qt::IntersectClip) {
     2576                // Use rect intersection if possible.
     2577                if (matrix.type() <= QTransform::TxScale)
     2578                    region &= matrix.mapRect(info.rect);
     2579                else
     2580                    region &= matrix.map(QRegion(info.rect));
     2581            } else if (info.operation == Qt::UniteClip) {
    24502582                region |= QRegion(info.rect) * matrix;
    2451             else if (info.operation == Qt::NoClip) {
     2583            } else if (info.operation == Qt::NoClip) {
    24522584                lastWasNothing = true;
    24532585                region = QRegion();
    2454             } else
     2586            } else {
    24552587                region = QRegion(info.rect) * matrix;
     2588            }
    24562589            break;
    24572590        }
     
    24642597                continue;
    24652598            }
    2466             if (info.operation == Qt::IntersectClip)
    2467                 region &= QRegion(info.rectf.toRect()) * matrix;
    2468             else if (info.operation == Qt::UniteClip)
     2599            if (info.operation == Qt::IntersectClip) {
     2600                // Use rect intersection if possible.
     2601                if (matrix.type() <= QTransform::TxScale)
     2602                    region &= matrix.mapRect(info.rectf.toRect());
     2603                else
     2604                    region &= matrix.map(QRegion(info.rectf.toRect()));
     2605            } else if (info.operation == Qt::UniteClip) {
    24692606                region |= QRegion(info.rectf.toRect()) * matrix;
    2470             else if (info.operation == Qt::NoClip) {
     2607            } else if (info.operation == Qt::NoClip) {
    24712608                lastWasNothing = true;
    24722609                region = QRegion();
    2473             } else
     2610            } else {
    24742611                region = QRegion(info.rectf.toRect()) * matrix;
     2612            }
    24752613            break;
    24762614        }
     
    24862624    Returns the currently clip as a path. Note that the clip path is
    24872625    given in logical coordinates.
     2626
     2627    \warning QPainter does not store the combined clip explicitly as
     2628    this is handled by the underlying QPaintEngine, so the path is
     2629    recreated on demand and transformed to the current logical
     2630    coordinate system. This is potentially an expensive operation.
    24882631
    24892632    \sa setClipPath(), clipRegion(), setClipping()
     
    25452688
    25462689    if (d->extended) {
     2690        if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
     2691            op = Qt::ReplaceClip;
     2692
    25472693        if (!d->engine) {
    25482694            qWarning("QPainter::setClipRect: Painter not active");
     
    25582704        d->state->clipEnabled = true;
    25592705        d->extended->clip(vp, op);
    2560         d->state->clipInfo << QPainterClipInfo(rect, op, combinedTransform());
     2706        if (op == Qt::ReplaceClip || op == Qt::NoClip)
     2707            d->state->clipInfo.clear();
     2708        d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
    25612709        d->state->clipOperation = op;
    25622710        return;
     
    25982746    }
    25992747
     2748    if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
     2749        op = Qt::ReplaceClip;
     2750
    26002751    if (d->extended) {
    26012752        d->state->clipEnabled = true;
    26022753        d->extended->clip(rect, op);
    2603         d->state->clipInfo << QPainterClipInfo(rect, op, combinedTransform());
     2754        if (op == Qt::ReplaceClip || op == Qt::NoClip)
     2755            d->state->clipInfo.clear();
     2756        d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
    26042757        d->state->clipOperation = op;
    26052758        return;
    26062759    }
    2607 
    2608     if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
    2609         op = Qt::ReplaceClip;
    26102760
    26112761    d->state->clipRegion = rect;
     
    26132763    if (op == Qt::NoClip || op == Qt::ReplaceClip)
    26142764        d->state->clipInfo.clear();
    2615     d->state->clipInfo << QPainterClipInfo(rect, op, combinedTransform());
     2765    d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
    26162766    d->state->clipEnabled = true;
    26172767    d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
     
    26512801    }
    26522802
     2803    if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
     2804        op = Qt::ReplaceClip;
     2805
    26532806    if (d->extended) {
    26542807        d->state->clipEnabled = true;
    26552808        d->extended->clip(r, op);
    2656         d->state->clipInfo << QPainterClipInfo(r, op, combinedTransform());
     2809        if (op == Qt::NoClip || op == Qt::ReplaceClip)
     2810            d->state->clipInfo.clear();
     2811        d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
    26572812        d->state->clipOperation = op;
    26582813        return;
    26592814    }
    2660 
    2661     if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
    2662         op = Qt::ReplaceClip;
    26632815
    26642816    d->state->clipRegion = r;
     
    26662818    if (op == Qt::NoClip || op == Qt::ReplaceClip)
    26672819        d->state->clipInfo.clear();
    2668     d->state->clipInfo << QPainterClipInfo(r, op, combinedTransform());
     2820    d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
    26692821    d->state->clipEnabled = true;
    26702822    d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
     
    26742826/*!
    26752827    \since 4.2
     2828    \obsolete
    26762829
    26772830    Sets the transformation matrix to \a matrix and enables transformations.
     
    27122865    documentation.
    27132866
    2714     \sa worldMatrixEnabled(), QMatrix
     2867    \sa setWorldTransform(), QTransform
    27152868*/
    27162869
     
    27222875/*!
    27232876    \since 4.2
     2877    \obsolete
    27242878
    27252879    Returns the world transformation matrix.
     
    27712925/*!
    27722926    \since 4.2
     2927    \obsolete
    27732928
    27742929    Returns the transformation matrix combining the current
     
    27782933    function to preserve the properties of perspective transformations.
    27792934
    2780     \sa setWorldMatrix(), setWindow(), setViewport()
     2935    \sa setWorldTransform(), setWindow(), setViewport()
    27812936*/
    27822937QMatrix QPainter::combinedMatrix() const
     
    27872942
    27882943/*!
     2944    \obsolete
     2945
    27892946    Returns the matrix that transforms from logical coordinates to
    27902947    device coordinates of the platform dependent paint device.
     
    28142971
    28152972/*!
     2973    \obsolete
     2974
    28162975    Resets any transformations that were made using translate(), scale(),
    28172976    shear(), rotate(), setWorldMatrix(), setViewport() and
     
    28382997    matrix is not changed.
    28392998
    2840     \sa worldMatrixEnabled(), worldMatrix(), {QPainter#Coordinate
     2999    \sa worldMatrixEnabled(), worldTransform(), {QPainter#Coordinate
    28413000    Transformations}{Coordinate Transformations}
    28423001*/
     
    28673026    false.
    28683027
    2869     \sa setWorldMatrixEnabled(), worldMatrix(), {The Coordinate System}
     3028    \sa setWorldMatrixEnabled(), worldTransform(), {The Coordinate System}
    28703029*/
    28713030
     
    29093068    Scales the coordinate system by (\a{sx}, \a{sy}).
    29103069
    2911     \sa setWorldMatrix() {QPainter#Coordinate Transformations}{Coordinate
     3070    \sa setWorldTransform() {QPainter#Coordinate Transformations}{Coordinate
    29123071    Transformations}
    29133072*/
     
    29333092    Shears the coordinate system by (\a{sh}, \a{sv}).
    29343093
    2935     \sa setWorldMatrix(), {QPainter#Coordinate Transformations}{Coordinate
     3094    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
    29363095    Transformations}
    29373096*/
     
    29593118    Rotates the coordinate system the given \a angle clockwise.
    29603119
    2961     \sa setWorldMatrix(), {QPainter#Coordinate Transformations}{Coordinate
     3120    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
    29623121    Transformations}
    29633122*/
     
    29843143    given \a offset is added to points.
    29853144
    2986     \sa setWorldMatrix(), {QPainter#Coordinate Transformations}{Coordinate
     3145    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
    29873146    Transformations}
    29883147*/
     
    30483207    }
    30493208
     3209    if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
     3210        op = Qt::ReplaceClip;
     3211
    30503212    if (d->extended) {
    30513213        d->state->clipEnabled = true;
    30523214        d->extended->clip(path, op);
    3053         d->state->clipInfo << QPainterClipInfo(path, op, combinedTransform());
     3215        if (op == Qt::NoClip || op == Qt::ReplaceClip)
     3216            d->state->clipInfo.clear();
     3217        d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
    30543218        d->state->clipOperation = op;
    30553219        return;
    30563220    }
    3057 
    3058 
    3059 
    3060     if (!hasClipping() && (op == Qt::IntersectClip || op == Qt::UniteClip))
    3061         op = Qt::ReplaceClip;
    30623221
    30633222    d->state->clipPath = path;
     
    30653224    if (op == Qt::NoClip || op == Qt::ReplaceClip)
    30663225        d->state->clipInfo.clear();
    3067     d->state->clipInfo << QPainterClipInfo(path, op, combinedTransform());
     3226    d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
    30683227    d->state->clipEnabled = true;
    30693228    d->state->dirtyFlags |= QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipEnabled;
     
    37133872        return;
    37143873
     3874    d->state->pen = pen;
     3875
    37153876    if (d->extended) {
    3716         d->state->pen = pen;
    37173877        d->checkEmulation();
    37183878        d->extended->penChanged();
     
    37203880    }
    37213881
    3722     // Do some checks to see if we are the same pen.
    3723     Qt::PenStyle currentStyle = d->state->pen.style();
    3724     if (currentStyle == pen.style() && currentStyle != Qt::CustomDashLine) {
    3725         if (currentStyle == Qt::NoPen ||
    3726             (d->state->pen.isSolid() && pen.isSolid()
    3727              && d->state->pen.color() == pen.color()
    3728              && d->state->pen.widthF() == pen.widthF()
    3729              && d->state->pen.capStyle() == pen.capStyle()
    3730              && d->state->pen.joinStyle() == pen.joinStyle()
    3731              && d->state->pen.isCosmetic() == pen.isCosmetic()))
    3732             return;
    3733     }
    3734 
    3735     d->state->pen = pen;
    37363882    d->state->dirtyFlags |= QPaintEngine::DirtyPen;
    37373883}
     
    38163962    }
    38173963
    3818     Qt::BrushStyle currentStyle = d->state->brush.style();
    3819     if (currentStyle == brush.style()) {
    3820         if (currentStyle == Qt::NoBrush
    3821             || (currentStyle == Qt::SolidPattern
    3822                 && d->state->brush.color() == brush.color()))
    3823             return;
    3824     }
    3825 
    38263964    d->state->brush = brush;
    38273965    d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
     
    39714109    \sa drawRect(), QPen
    39724110*/
    3973 // FALCON: Should we add a specialized method in QPaintEngineEx?
    39744111void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
    39754112{
     
    39894126
    39904127    if (d->extended) {
    3991         QPainterPath::ElementType types[] = {
    3992             QPainterPath::MoveToElement,
    3993             QPainterPath::LineToElement,
    3994             QPainterPath::CurveToElement,
    3995             QPainterPath::CurveToDataElement,
    3996             QPainterPath::CurveToDataElement,
    3997             QPainterPath::LineToElement,
    3998             QPainterPath::CurveToElement,
    3999             QPainterPath::CurveToDataElement,
    4000             QPainterPath::CurveToDataElement,
    4001             QPainterPath::LineToElement,
    4002             QPainterPath::CurveToElement,
    4003             QPainterPath::CurveToDataElement,
    4004             QPainterPath::CurveToDataElement,
    4005             QPainterPath::LineToElement,
    4006             QPainterPath::CurveToElement,
    4007             QPainterPath::CurveToDataElement,
    4008             QPainterPath::CurveToDataElement
    4009         };
    4010 
    4011         qreal x1 = rect.left();
    4012         qreal x2 = rect.right();
    4013         qreal y1 = rect.top();
    4014         qreal y2 = rect.bottom();
    4015 
    4016         if (mode == Qt::RelativeSize) {
    4017             xRadius = xRadius * rect.width() / 200.;
    4018             yRadius = yRadius * rect.height() / 200.;
    4019         }
    4020 
    4021         xRadius = qMin(xRadius, rect.width() / 2);
    4022         yRadius = qMin(yRadius, rect.height() / 2);
    4023 
    4024         qreal pts[] = {
    4025             x1 + xRadius, y1,                   // MoveTo
    4026             x2 - xRadius, y1,                   // LineTo
    4027             x2 - (1 - KAPPA) * xRadius, y1,     // CurveTo
    4028             x2, y1 + (1 - KAPPA) * yRadius,
    4029             x2, y1 + yRadius,
    4030             x2, y2 - yRadius,                   // LineTo
    4031             x2, y2 - (1 - KAPPA) * yRadius,     // CurveTo
    4032             x2 - (1 - KAPPA) * xRadius, y2,
    4033             x2 - xRadius, y2,
    4034             x1 + xRadius, y2,                   // LineTo
    4035             x1 + (1 - KAPPA) * xRadius, y2,           // CurveTo
    4036             x1, y2 - (1 - KAPPA) * yRadius,
    4037             x1, y2 - yRadius,
    4038             x1, y1 + yRadius,                   // LineTo
    4039             x1, y1 + KAPPA * yRadius,           // CurveTo
    4040             x1 + (1 - KAPPA) * xRadius, y1,
    4041             x1 + xRadius, y1
    4042         };
    4043 
    4044         QVectorPath path(pts, 17, types);
    4045         d->extended->draw(path);
     4128        d->extended->drawRoundedRect(rect, xRadius, yRadius, mode);
    40464129        return;
    40474130    }
     
    40854168void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
    40864169{
    4087 #ifdef QT_DEBUG_DRAW
    4088     if (qt_show_painter_debug_output)
    4089         printf("QPainter::drawRoundRectangle(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height());
    4090 #endif
    4091     Q_D(QPainter);
    4092 
    4093     if (!d->engine)
    4094         return;
    4095 
    4096     if(xRnd <= 0 || yRnd <= 0) {             // draw normal rectangle
    4097         drawRect(r);
    4098         return;
    4099     }
    4100 
    4101     QPainterPath path;
    4102     path.addRoundRect(r, xRnd, yRnd);
    4103     drawPath(path);
     4170    drawRoundedRect(r, xRnd, yRnd, Qt::RelativeSize);
    41044171}
    41054172
     
    51225189}
    51235190
     5191static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransform &m)
     5192{
     5193    return m.inverted().map(QPointF(m.map(p).toPoint()));
     5194}
     5195
    51245196/*!
    51255197    \fn void QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
     
    51745246    int h = pm.height();
    51755247
     5248    if (w <= 0)
     5249        return;
     5250
    51765251    // Emulate opaque background for bitmaps
    51775252    if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
     
    51875262    {
    51885263        save();
    5189         // If there is no scaling or transformation involved we have to make sure we use the
     5264        // If there is no rotation involved we have to make sure we use the
    51905265        // antialiased and not the aliased coordinate system by rounding the coordinates.
    5191         if (d->state->matrix.type() <= QTransform::TxTranslate) {
    5192             x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx();
    5193             y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy();
     5266        if (d->state->matrix.type() <= QTransform::TxScale) {
     5267            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
     5268            x = p.x();
     5269            y = p.y();
    51945270        }
    51955271        translate(x, y);
     
    53015377    {
    53025378        save();
    5303         // If there is no scaling or transformation involved we have to make sure we use the
     5379        // If there is no rotation involved we have to make sure we use the
    53045380        // antialiased and not the aliased coordinate system by rounding the coordinates.
     5381        if (d->state->matrix.type() <= QTransform::TxScale) {
     5382            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
     5383            x = p.x();
     5384            y = p.y();
     5385        }
     5386
    53055387        if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
    5306             x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx();
    5307             y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy();
    53085388            sx = qRound(sx);
    53095389            sy = qRound(sy);
     
    53115391            sh = qRound(sh);
    53125392        }
     5393
    53135394        translate(x, y);
    53145395        scale(w / sw, h / sh);
     
    54605541    {
    54615542        save();
    5462         // If there is no scaling or transformation involved we have to make sure we use the
     5543        // If there is no rotation involved we have to make sure we use the
    54635544        // antialiased and not the aliased coordinate system by rounding the coordinates.
    5464         if (d->state->matrix.type() <= QTransform::TxTranslate) {
    5465             x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx();
    5466             y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy();
     5545        if (d->state->matrix.type() <= QTransform::TxScale) {
     5546            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
     5547            x = p.x();
     5548            y = p.y();
    54675549        }
    54685550        translate(x, y);
     
    55635645    {
    55645646        save();
    5565         // If there is no scaling or transformation involved we have to make sure we use the
     5647        // If there is no rotation involved we have to make sure we use the
    55665648        // antialiased and not the aliased coordinate system by rounding the coordinates.
     5649        if (d->state->matrix.type() <= QTransform::TxScale) {
     5650            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
     5651            x = p.x();
     5652            y = p.y();
     5653        }
     5654
    55675655        if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
    5568             x = qRound(x + d->state->matrix.dx()) - d->state->matrix.dx();
    5569             y = qRound(y + d->state->matrix.dy()) - d->state->matrix.dy();
    55705656            sx = qRound(sx);
    55715657            sy = qRound(sy);
     
    56595745    }
    56605746    QFixed x = QFixed::fromReal(p.x());
    5661     QFixed ox = x;
    56625747
    56635748    for (int i = 0; i < nItems; ++i) {
     
    58865971*/
    58875972
    5888 /*! \internal
     5973/*!
     5974    \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
     5975
     5976    \internal
     5977    \since 4.1
     5978
    58895979    Draws the text item \a ti at position \a p.
    58905980
     
    58995989    underlining and strikeout.
    59005990*/
    5901 static QPainterPath generateWavyPath(qreal minWidth, qreal maxRadius, QPaintDevice *device)
    5902 {
    5903     extern int qt_defaultDpi();
     5991
     5992static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
     5993{
     5994    const qreal radiusBase = qMax(qreal(1), maxRadius);
     5995
     5996    QString key = QLatin1String("WaveUnderline-");
     5997    key += pen.color().name();
     5998    key += QLatin1Char('-');
     5999    key += QString::number(radiusBase);
     6000
     6001    QPixmap pixmap;
     6002    if (QPixmapCache::find(key, pixmap))
     6003        return pixmap;
     6004
     6005    const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
     6006    const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
     6007    const int radius = qFloor(radiusBase);
     6008
    59046009    QPainterPath path;
    59056010
    5906     bool up = true;
    5907     const qreal radius = qMax(qreal(.5), qMin(qreal(1.25 * device->logicalDpiY() / qt_defaultDpi()), maxRadius));
    5908     qreal xs, ys;
    5909     int i = 0;
    5910     path.moveTo(0, radius);
    5911     do {
    5912         xs = i*(2*radius);
    5913         ys = 0;
    5914 
    5915         qreal remaining = minWidth - xs;
    5916         qreal angle = 180;
    5917 
    5918         // cut-off at the last arc segment
    5919         if (remaining < 2 * radius)
    5920             angle = 180 * remaining / (2 * radius);
    5921 
    5922         path.arcTo(xs, ys, 2*radius, 2*radius, 180, up ? angle : -angle);
    5923 
    5924         up = !up;
    5925         ++i;
    5926     } while (xs + 2*radius < minWidth);
    5927 
    5928     return path;
     6011    qreal xs = 0;
     6012    qreal ys = radius;
     6013
     6014    while (xs < width) {
     6015        xs += halfPeriod;
     6016        ys = -ys;
     6017        path.quadTo(xs - halfPeriod / 2, ys, xs, 0);
     6018    }
     6019
     6020    pixmap = QPixmap(width, radius * 2);
     6021    pixmap.fill(Qt::transparent);
     6022    {
     6023        QPen wavePen = pen;
     6024        wavePen.setCapStyle(Qt::SquareCap);
     6025
     6026        // This is to protect against making the line too fat, as happens on Mac OS X
     6027        // due to it having a rather thick width for the regular underline.
     6028        const qreal maxPenWidth = .8 * radius;
     6029        if (wavePen.widthF() > maxPenWidth)
     6030            wavePen.setWidth(maxPenWidth);
     6031
     6032        QPainter imgPainter(&pixmap);
     6033        imgPainter.setPen(wavePen);
     6034        imgPainter.setRenderHint(QPainter::Antialiasing);
     6035        imgPainter.translate(0, radius);
     6036        imgPainter.drawPath(path);
     6037    }
     6038
     6039    QPixmapCache::insert(key, pixmap);
     6040
     6041    return pixmap;
    59296042}
    59306043
     
    59476060
    59486061    QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y());
     6062
     6063    const qreal underlineOffset = fe->underlinePosition().toReal();
    59496064    // deliberately ceil the offset to avoid the underline coming too close to
    59506065    // the text above it.
    5951     const qreal underlinePos = pos.y() + qCeil(fe->underlinePosition().toReal());
     6066    const qreal underlinePos = pos.y() + qCeil(underlineOffset);
    59526067
    59536068    if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
     
    59576072    if (underlineStyle == QTextCharFormat::WaveUnderline) {
    59586073        painter->save();
    5959         painter->setRenderHint(QPainter::Antialiasing);
    5960         painter->translate(pos.x(), underlinePos);
     6074        painter->translate(0, pos.y() + 1);
    59616075
    59626076        QColor uc = ti.charFormat.underlineColor();
    59636077        if (uc.isValid())
    5964             painter->setPen(uc);
    5965 
    5966         painter->drawPath(generateWavyPath(ti.width.toReal(),
    5967                                            fe->underlinePosition().toReal(),
    5968                                            painter->device()));
     6078            pen.setColor(uc);
     6079
     6080        // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
     6081        const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
     6082        const int descent = (int) ti.descent.toReal();
     6083
     6084        painter->setBrushOrigin(painter->brushOrigin().x(), 0);
     6085        painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave);
    59696086        painter->restore();
    59706087    } else if (underlineStyle != QTextCharFormat::NoUnderline) {
     
    60016118}
    60026119
    6003 /*!
    6004     \internal
    6005     \since 4.1
    6006 */
    60076120void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
    60086121{
     
    60436156        if (d->state->matrix.type() < QTransform::TxShear) {
    60446157            bool isPlain90DegreeRotation =
    6045                 (qFuzzyCompare(m.m11() + 1, qreal(1))
    6046                  && qFuzzyCompare(m.m12(), qreal(1))
    6047                  && qFuzzyCompare(m.m21(), qreal(-1))
    6048                  && qFuzzyCompare(m.m22() + 1, qreal(1))
     6158                (qFuzzyIsNull(m.m11())
     6159                 && qFuzzyIsNull(m.m12() - qreal(1))
     6160                 && qFuzzyIsNull(m.m21() + qreal(1))
     6161                 && qFuzzyIsNull(m.m22())
    60496162                    )
    60506163                ||
    6051                 (qFuzzyCompare(m.m11(), qreal(-1))
    6052                  && qFuzzyCompare(m.m12() + 1, qreal(1))
    6053                  && qFuzzyCompare(m.m21() + 1, qreal(1))
    6054                  && qFuzzyCompare(m.m22(), qreal(-1))
     6164                (qFuzzyIsNull(m.m11() + qreal(1))
     6165                 && qFuzzyIsNull(m.m12())
     6166                 && qFuzzyIsNull(m.m21())
     6167                 && qFuzzyIsNull(m.m22() + qreal(1))
    60556168                    )
    60566169                ||
    6057                 (qFuzzyCompare(m.m11() + 1, qreal(1))
    6058                  && qFuzzyCompare(m.m12(), qreal(-1))
    6059                  && qFuzzyCompare(m.m21(), qreal(1))
    6060                  && qFuzzyCompare(m.m22() + 1, qreal(1))
     6170                (qFuzzyIsNull(m.m11())
     6171                 && qFuzzyIsNull(m.m12() + qreal(1))
     6172                 && qFuzzyIsNull(m.m21() - qreal(1))
     6173                 && qFuzzyIsNull(m.m22())
    60616174                    )
    60626175                ;
     
    63106423        setPen(Qt::NoPen);
    63116424
    6312         // If there is no scaling or transformation involved we have to make sure we use the
     6425        // If there is no rotation involved we have to make sure we use the
    63136426        // antialiased and not the aliased coordinate system by rounding the coordinates.
    6314         if (d->state->matrix.type() <= QTransform::TxTranslate) {
    6315             qreal x = qRound(r.x() + d->state->matrix.dx()) - d->state->matrix.dx();
    6316             qreal y = qRound(r.y() + d->state->matrix.dy()) - d->state->matrix.dy();
    6317             qreal w = qRound(r.width());
    6318             qreal h = qRound(r.height());
    6319             sx = qRound(sx);
    6320             sy = qRound(sy);
     6427        if (d->state->matrix.type() <= QTransform::TxScale) {
     6428            const QPointF p = roundInDeviceCoordinates(r.topLeft(), d->state->matrix);
     6429
     6430            if (d->state->matrix.type() <= QTransform::TxTranslate) {
     6431                sx = qRound(sx);
     6432                sy = qRound(sy);
     6433            }
     6434
    63216435            setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
    6322             drawRect(QRectF(x, y, w, h));
     6436            drawRect(QRectF(p, r.size()));
    63236437        } else {
    63246438            setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
     
    67486862    false.
    67496863
    6750     \sa setViewTransformEnabled(), worldMatrix()
     6864    \sa setViewTransformEnabled(), worldTransform()
    67516865*/
    67526866
     
    69047018    \compat
    69057019
    6906     Use resetMatrix() instead.
     7020    Use resetTransform() instead.
    69077021*/
    69087022
     
    69507064
    69517065/*!
    6952     Use the worldMatrix() combined with QMatrix::dx() instead.
     7066    \obsolete
     7067
     7068    Use the worldTransform() combined with QTransform::dx() instead.
    69537069
    69547070    \oldcode
     
    69577073    \newcode
    69587074        QPainter painter(this);
    6959         qreal x = painter.worldMatrix().dx();
     7075        qreal x = painter.worldTransform().dx();
    69607076    \endcode
    69617077*/
     
    69717087
    69727088/*!
    6973     Use the worldMatrix() combined with QMatrix::dy() instead.
     7089    \obsolete
     7090
     7091    Use the worldTransform() combined with QTransform::dy() instead.
    69747092
    69757093    \oldcode
     
    69787096    \newcode
    69797097        QPainter painter(this);
    6980         qreal y = painter.worldMatrix().dy();
     7098        qreal y = painter.worldTransform().dy();
    69817099    \endcode
    69827100*/
     
    70767194    \newcode
    70777195        QPainter painter(this);
    7078         QPolygon transformed = polygon.mid(index, count) * painter.combinedMatrix();
     7196        QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform();
    70797197    \endcode
    70807198*/
     
    70917209    \fn QPoint QPainter::xFormDev(const QPoint &point) const
    70927210    \overload
    7093 
    7094     Use combinedTransform() combined with QMatrix::inverted() instead.
     7211    \obsolete
     7212
     7213    Use combinedTransform() combined with QTransform::inverted() instead.
    70957214
    70967215    \oldcode
     
    70997218    \newcode
    71007219        QPainter painter(this);
    7101         QPoint transformed = point * painter.combinedMatrix().inverted();
     7220        QPoint transformed = point * painter.combinedTransform().inverted();
    71027221    \endcode
    71037222*/
     
    71187237    \fn QRect QPainter::xFormDev(const QRect &rectangle) const
    71197238    \overload
    7120 
    7121     Use  combineMatrix() combined with QMatrix::inverted() instead.
     7239    \obsolete
     7240
     7241    Use combinedTransform() combined with QTransform::inverted() instead.
    71227242
    71237243    \oldcode
     
    71267246    \newcode
    71277247        QPainter painter(this);
    7128         QRect transformed = rectangle * painter.combinedMatrix().inverted();
     7248        QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted();
     7249        QRect transformed = region.boundingRect();
    71297250    \endcode
    71307251*/
     
    71467267
    71477268    \fn QPoint QPainter::xFormDev(const QPolygon &polygon) const
    7148     \overload
    7149 
    7150     Use  combinedMatrix() combined with QMatrix::inverted() instead.
     7269    \obsolete
     7270
     7271    Use  combinedTransform() combined with QTransform::inverted() instead.
    71517272
    71527273    \oldcode
     
    71557276    \newcode
    71567277        QPainter painter(this);
    7157         QPolygon transformed = polygon * painter.combinedMatrix().inverted();
     7278        QPolygon transformed = polygon * painter.combinedTransform().inverted();
    71587279    \endcode
    71597280*/
     
    71747295    \fn QPolygon QPainter::xFormDev(const QPolygon &polygon, int index, int count) const
    71757296    \overload
    7176 
    7177     Use combinedMatrix() combined with QPolygon::mid() and QMatrix::inverted() instead.
     7297    \obsolete
     7298
     7299    Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead.
    71787300
    71797301    \oldcode
     
    71827304    \newcode
    71837305        QPainter painter(this);
    7184         QPolygon transformed = polygon.mid(index, count) * painter.combinedMatrix().inverted();
     7306        QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted();
    71857307    \endcode
    71867308*/
     
    73777499void qt_painter_removePaintDevice(QPaintDevice *dev)
    73787500{
    7379     QMutexLocker locker(globalRedirectionsMutex());
    7380     if(QPaintDeviceRedirectionList *redirections = globalRedirections()) {
     7501    QMutex *mutex = 0;
     7502    QT_TRY {
     7503        mutex = globalRedirectionsMutex();
     7504    } QT_CATCH(...) {
     7505        // ignore the missing mutex, since we could be called from
     7506        // a destructor, and destructors shall not throw
     7507    }
     7508    QMutexLocker locker(mutex);
     7509    QPaintDeviceRedirectionList *redirections = 0;
     7510    QT_TRY {
     7511        redirections = globalRedirections();
     7512    } QT_CATCH(...) {
     7513        // do nothing - code below is safe with redirections being 0.
     7514    }
     7515    if (redirections) {
    73817516        for (int i = 0; i < redirections->size(); ) {
    73827517            if(redirections->at(i) == dev || redirections->at(i).replacement == dev)
     
    74287563
    74297564    Qt::LayoutDirection layout_direction;
    7430     if(option)
     7565    if (tf & Qt::TextForceLeftToRight)
     7566        layout_direction = Qt::LeftToRight;
     7567    else if (tf & Qt::TextForceRightToLeft)
     7568        layout_direction = Qt::RightToLeft;
     7569    else if (option)
    74317570        layout_direction = option->textDirection();
    74327571    else if (painter)
     
    74457584        tf |= Qt::TextDontPrint;
    74467585
    7447     int maxUnderlines = 0;
     7586    uint maxUnderlines = 0;
    74487587    int numUnderlines = 0;
    7449     int underlinePositionStack[32];
    7450     int *underlinePositions = underlinePositionStack;
     7588    QVarLengthArray<int, 32> underlinePositions(1);
    74517589
    74527590    QFontMetricsF fm(fnt);
    7453 
    74547591    QString text = str;
     7592    int offset = 0;
     7593start_lengthVariant:
     7594    bool hasMoreLengthVariants = false;
    74557595    // compatible behaviour to the old implementation. Replace
    74567596    // tabs by spaces
    7457     QChar *chr = text.data();
    7458     const QChar *end = chr + str.length();
    7459     bool has_tab = false;
    7460     while (chr != end) {
    7461         if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) {
    7462             *chr = QLatin1Char(' ');
    7463         } else if (*chr == QLatin1Char('\n')) {
    7464             *chr = QChar::LineSeparator;
    7465         } else if (*chr == QLatin1Char('&')) {
     7597    int old_offset = offset;
     7598    for (; offset < text.length(); offset++) {
     7599        QChar chr = text.at(offset);
     7600        if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) {
     7601            text[offset] = QLatin1Char(' ');
     7602        } else if (chr == QLatin1Char('\n')) {
     7603            text[offset] = QChar::LineSeparator;
     7604        } else if (chr == QLatin1Char('&')) {
    74667605            ++maxUnderlines;
    7467         } else if (*chr == QLatin1Char('\t')) {
    7468             has_tab = true;
     7606        } else if (chr == QLatin1Char('\t')) {
     7607            if (!expandtabs) {
     7608                text[offset] = QLatin1Char(' ');
     7609            } else if (!tabarraylen && !tabstops) {
     7610                tabstops = qRound(fm.width(QLatin1Char('x'))*8);
     7611            }
     7612        } else if (chr == QChar(ushort(0x9c))) {
     7613            // string with multiple length variants
     7614            hasMoreLengthVariants = true;
     7615            break;
    74697616        }
    7470         ++chr;
    7471     }
    7472     if (has_tab) {
    7473         if (!expandtabs) {
    7474             chr = text.data();
    7475             while (chr != end) {
    7476                 if (*chr == QLatin1Char('\t'))
    7477                     *chr = QLatin1Char(' ');
    7478                 ++chr;
    7479             }
    7480         } else if (!tabarraylen && !tabstops) {
    7481             tabstops = qRound(fm.width(QLatin1Char('x'))*8);
    7482         }
    7483     }
    7484 
    7485     if (hidemnmemonic || showmnemonic) {
    7486         if (maxUnderlines > 32)
    7487             underlinePositions = new int[maxUnderlines];
    7488         QChar *cout = text.data();
     7617    }
     7618
     7619    int length = offset - old_offset;
     7620    if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
     7621        underlinePositions.resize(maxUnderlines + 1);
     7622
     7623        QChar *cout = text.data() + old_offset;
    74897624        QChar *cin = cout;
    7490         int l = str.length();
     7625        int l = length;
    74917626        while (l) {
    74927627            if (*cin == QLatin1Char('&')) {
    74937628                ++cin;
     7629                --length;
    74947630                --l;
    74957631                if (!l)
    74967632                    break;
    74977633                if (*cin != QLatin1Char('&') && !hidemnmemonic)
    7498                     underlinePositions[numUnderlines++] = cout - text.unicode();
     7634                    underlinePositions[numUnderlines++] = cout - text.data() - old_offset;
    74997635            }
    75007636            *cout = *cin;
     
    75037639            --l;
    75047640        }
    7505         int newlen = cout - text.unicode();
    7506         if (newlen != text.length())
    7507             text.resize(newlen);
    75087641    }
    75097642
     
    75167649    qreal width = 0;
    75177650
    7518     QStackTextEngine engine(text, fnt);
     7651    QString finalText = text.mid(old_offset, length);
     7652    QStackTextEngine engine(finalText, fnt);
    75197653    if (option) {
    75207654        engine.option = *option;
    75217655    }
    7522 
    7523 
    75247656
    75257657    engine.option.setTextDirection(layout_direction);
     
    75367668    QTextLayout textLayout(&engine);
    75377669    textLayout.setCacheEnabled(true);
    7538     textLayout.engine()->underlinePositions = underlinePositions;
    7539 
    7540     if (text.isEmpty()) {
     7670    textLayout.engine()->underlinePositions = underlinePositions.data();
     7671
     7672    if (finalText.isEmpty()) {
    75417673        height = fm.height();
    75427674        width = 0;
     
    75647696            height += l.height();
    75657697            width = qMax(width, l.naturalTextWidth());
    7566             if (!brect && height >= r.height())
     7698            if (!dontclip && !brect && height >= r.height())
    75677699                break;
    75687700        }
     
    75837715                const qreal scale = painter->transform().m22();
    75847716                if (scale != 0)
    7585                     yoff = qRound(yoff * scale) / scale;
     7717                    yoff = -qRound(-yoff * scale) / scale;
    75867718            }
    75877719        }
     
    76037735    }
    76047736    QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);
     7737
     7738    if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) {
     7739        offset++;
     7740        goto start_lengthVariant;
     7741    }
    76057742    if (brect)
    76067743        *brect = bounds;
     
    76297766        }
    76307767    }
    7631 
    7632     if (underlinePositions != underlinePositionStack)
    7633         delete [] underlinePositions;
    76347768}
    76357769
     
    76647798      clipOperation(s->clipOperation),
    76657799      renderHints(s->renderHints), clipInfo(s->clipInfo),
    7666       worldMatrix(s->worldMatrix), matrix(s->matrix), redirection_offset(s->redirection_offset),
     7800      worldMatrix(s->worldMatrix), matrix(s->matrix), redirectionMatrix(s->redirectionMatrix),
    76677801      wx(s->wx), wy(s->wy), ww(s->ww), wh(s->wh),
    76687802      vx(s->vx), vy(s->vy), vw(s->vw), vh(s->vh),
     
    80868220    \row \o QPaintEngine::DirtyCompositionMode \o compositionMode()
    80878221    \row \o QPaintEngine::DirtyFont \o font()
    8088     \row \o QPaintEngine::DirtyTransform \o matrix()
     8222    \row \o QPaintEngine::DirtyTransform \o transform()
    80898223    \row \o QPaintEngine::DirtyClipEnabled \o isClipEnabled()
    80908224    \row \o QPaintEngine::DirtyPen \o pen()
     
    82058339/*!
    82068340    \since 4.2
     8341    \obsolete
    82078342
    82088343    Returns the matrix in the current paint engine
    82098344    state.
     8345
     8346    \note It is advisable to use transform() instead of this function to
     8347    preserve the properties of perspective transformations.
    82108348
    82118349    This variable should only be used when the state() returns a
     
    83898527    the current matrix; otherwise it replaces the current matrix.
    83908528
    8391     This function has been added for compatibility with setMatrix(),
    8392     but as with setMatrix() the preferred method of setting a
    8393     transformation on the painter is through setWorldTransform().
    8394 
    8395     \sa transform()
     8529    \sa transform() setWorldTransform()
    83968530*/
    83978531
     
    84038537/*!
    84048538    Returns the world transformation matrix.
     8539
     8540    \sa worldTransform()
    84058541*/
    84068542
     
    85138649    window/viewport and world transformation.
    85148650
    8515     \sa setWorldMatrix(), setWindow(), setViewport()
     8651    \sa setWorldTransform(), setWindow(), setViewport()
    85168652*/
    85178653
     
    85318667}
    85328668
     8669/*! \fn Display *QPaintDevice::x11Display() const
     8670    Use QX11Info::display() instead.
     8671
     8672    \oldcode
     8673        Display *display = widget->x11Display();
     8674    \newcode
     8675        Display *display = QX11Info::display();
     8676    \endcode
     8677
     8678    \sa QWidget::x11Info(), QX11Info::display()
     8679*/
     8680
     8681/*! \fn int QPaintDevice::x11Screen() const
     8682    Use QX11Info::screen() instead.
     8683
     8684    \oldcode
     8685        int screen = widget->x11Screen();
     8686    \newcode
     8687        int screen = widget->x11Info().screen();
     8688    \endcode
     8689
     8690    \sa QWidget::x11Info(), QPixmap::x11Info()
     8691*/
     8692
     8693/*! \fn void *QPaintDevice::x11Visual() const
     8694    Use QX11Info::visual() instead.
     8695
     8696    \oldcode
     8697        void *visual = widget->x11Visual();
     8698    \newcode
     8699        void *visual = widget->x11Info().visual();
     8700    \endcode
     8701
     8702    \sa QWidget::x11Info(), QPixmap::x11Info()
     8703*/
     8704
     8705/*! \fn int QPaintDevice::x11Depth() const
     8706    Use QX11Info::depth() instead.
     8707
     8708    \oldcode
     8709        int depth = widget->x11Depth();
     8710    \newcode
     8711        int depth = widget->x11Info().depth();
     8712    \endcode
     8713
     8714    \sa QWidget::x11Info(), QPixmap::x11Info()
     8715*/
     8716
     8717/*! \fn int QPaintDevice::x11Cells() const
     8718    Use QX11Info::cells() instead.
     8719
     8720    \oldcode
     8721        int cells = widget->x11Cells();
     8722    \newcode
     8723        int cells = widget->x11Info().cells();
     8724    \endcode
     8725
     8726    \sa QWidget::x11Info(), QPixmap::x11Info()
     8727*/
     8728
     8729/*! \fn Qt::HANDLE QPaintDevice::x11Colormap() const
     8730    Use QX11Info::colormap() instead.
     8731
     8732    \oldcode
     8733        unsigned long screen = widget->x11Colormap();
     8734    \newcode
     8735        unsigned long screen = widget->x11Info().colormap();
     8736    \endcode
     8737
     8738    \sa QWidget::x11Info(), QPixmap::x11Info()
     8739*/
     8740
     8741/*! \fn bool QPaintDevice::x11DefaultColormap() const
     8742    Use QX11Info::defaultColormap() instead.
     8743
     8744    \oldcode
     8745        bool isDefault = widget->x11DefaultColormap();
     8746    \newcode
     8747        bool isDefault = widget->x11Info().defaultColormap();
     8748    \endcode
     8749
     8750    \sa QWidget::x11Info(), QPixmap::x11Info()
     8751*/
     8752
     8753/*! \fn bool QPaintDevice::x11DefaultVisual() const
     8754    Use QX11Info::defaultVisual() instead.
     8755
     8756    \oldcode
     8757        bool isDefault = widget->x11DefaultVisual();
     8758    \newcode
     8759        bool isDefault = widget->x11Info().defaultVisual();
     8760    \endcode
     8761
     8762    \sa QWidget::x11Info(), QPixmap::x11Info()
     8763*/
     8764
     8765/*! \fn void *QPaintDevice::x11AppVisual(int screen)
     8766    Use QX11Info::visual() instead.
     8767
     8768    \oldcode
     8769        void *visual = QPaintDevice::x11AppVisual(screen);
     8770    \newcode
     8771        void *visual = qApp->x11Info(screen).visual();
     8772    \endcode
     8773
     8774    \sa QWidget::x11Info(), QPixmap::x11Info()
     8775*/
     8776
     8777/*! \fn Qt::HANDLE QPaintDevice::x11AppColormap(int screen)
     8778    Use QX11Info::colormap() instead.
     8779
     8780    \oldcode
     8781        unsigned long colormap = QPaintDevice::x11AppColormap(screen);
     8782    \newcode
     8783        unsigned long colormap = qApp->x11Info(screen).colormap();
     8784    \endcode
     8785
     8786    \sa QWidget::x11Info(), QPixmap::x11Info()
     8787*/
     8788
     8789/*! \fn Display *QPaintDevice::x11AppDisplay()
     8790    Use QX11Info::display() instead.
     8791
     8792    \oldcode
     8793        Display *display = QPaintDevice::x11AppDisplay();
     8794    \newcode
     8795        Display *display = qApp->x11Info().display();
     8796    \endcode
     8797
     8798    \sa QWidget::x11Info(), QPixmap::x11Info()
     8799*/
     8800
     8801/*! \fn int QPaintDevice::x11AppScreen()
     8802    Use QX11Info::screen() instead.
     8803
     8804    \oldcode
     8805        int screen = QPaintDevice::x11AppScreen();
     8806    \newcode
     8807        int screen = qApp->x11Info().screen();
     8808    \endcode
     8809
     8810    \sa QWidget::x11Info(), QPixmap::x11Info()
     8811*/
     8812
     8813/*! \fn int QPaintDevice::x11AppDepth(int screen)
     8814    Use QX11Info::depth() instead.
     8815
     8816    \oldcode
     8817        int depth = QPaintDevice::x11AppDepth(screen);
     8818    \newcode
     8819        int depth = qApp->x11Info(screen).depth();
     8820    \endcode
     8821
     8822    \sa QWidget::x11Info(), QPixmap::x11Info()
     8823*/
     8824
     8825/*! \fn int QPaintDevice::x11AppCells(int screen)
     8826    Use QX11Info::cells() instead.
     8827
     8828    \oldcode
     8829        int cells = QPaintDevice::x11AppCells(screen);
     8830    \newcode
     8831        int cells = qApp->x11Info(screen).cells();
     8832    \endcode
     8833
     8834    \sa QWidget::x11Info(), QPixmap::x11Info()
     8835*/
     8836
     8837/*! \fn Qt::HANDLE QPaintDevice::x11AppRootWindow(int screen)
     8838    Use QX11Info::appRootWindow() instead.
     8839
     8840    \oldcode
     8841        unsigned long window = QPaintDevice::x11AppRootWindow(screen);
     8842    \newcode
     8843        unsigned long window = qApp->x11Info(screen).appRootWindow();
     8844    \endcode
     8845
     8846    \sa QWidget::x11Info(), QPixmap::x11Info()
     8847*/
     8848
     8849/*! \fn bool QPaintDevice::x11AppDefaultColormap(int screen)
     8850    Use QX11Info::defaultColormap() instead.
     8851
     8852    \oldcode
     8853        bool isDefault = QPaintDevice::x11AppDefaultColormap(screen);
     8854    \newcode
     8855        bool isDefault = qApp->x11Info(screen).defaultColormap();
     8856    \endcode
     8857
     8858    \sa QWidget::x11Info(), QPixmap::x11Info()
     8859*/
     8860
     8861/*! \fn bool QPaintDevice::x11AppDefaultVisual(int screen)
     8862    Use QX11Info::defaultVisual() instead.
     8863
     8864    \oldcode
     8865        bool isDefault = QPaintDevice::x11AppDefaultVisual(screen);
     8866    \newcode
     8867        bool isDefault = qApp->x11Info(screen).defaultVisual();
     8868    \endcode
     8869
     8870    \sa QWidget::x11Info(), QPixmap::x11Info()
     8871*/
     8872
     8873/*! \fn void QPaintDevice::x11SetAppDpiX(int dpi, int screen)
     8874    Use QX11Info::setAppDpiX() instead.
     8875*/
     8876
     8877/*! \fn void QPaintDevice::x11SetAppDpiY(int dpi, int screen)
     8878    Use QX11Info::setAppDpiY() instead.
     8879*/
     8880
     8881/*! \fn int QPaintDevice::x11AppDpiX(int screen)
     8882    Use QX11Info::appDpiX() instead.
     8883
     8884    \oldcode
     8885        bool isDefault = QPaintDevice::x11AppDpiX(screen);
     8886    \newcode
     8887        bool isDefault = qApp->x11Info(screen).appDpiX();
     8888    \endcode
     8889
     8890    \sa QWidget::x11Info(), QPixmap::x11Info()
     8891*/
     8892
     8893/*! \fn int QPaintDevice::x11AppDpiY(int screen)
     8894    Use QX11Info::appDpiY() instead.
     8895
     8896    \oldcode
     8897        bool isDefault = QPaintDevice::x11AppDpiY(screen);
     8898    \newcode
     8899        bool isDefault = qApp->x11Info(screen).appDpiY();
     8900    \endcode
     8901
     8902    \sa QWidget::x11Info(), QPixmap::x11Info()
     8903*/
     8904
     8905/*! \fn HDC QPaintDevice::getDC() const
     8906  \internal
     8907*/
     8908
     8909/*! \fn void QPaintDevice::releaseDC(HDC) const
     8910  \internal
     8911*/
     8912
     8913/*! \fn QWSDisplay *QPaintDevice::qwsDisplay()
     8914    \internal
     8915*/
     8916
    85338917QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.