src/gui/painting/qpaintengine.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
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 #include "qpaintengine.h"
       
    42 #include "qpaintengine_p.h"
       
    43 #include "qpainter_p.h"
       
    44 #include "qpolygon.h"
       
    45 #include "qbitmap.h"
       
    46 #include "qapplication.h"
       
    47 #include <qdebug.h>
       
    48 #include <qmath.h>
       
    49 #include <private/qtextengine_p.h>
       
    50 #include <qvarlengtharray.h>
       
    51 #include <private/qfontengine_p.h>
       
    52 #include <private/qpaintengineex_p.h>
       
    53 
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 /*!
       
    58     \class QTextItem
       
    59 
       
    60     \brief The QTextItem class provides all the information required to draw
       
    61     text in a custom paint engine.
       
    62 
       
    63     When you reimplement your own paint engine, you must reimplement
       
    64     QPaintEngine::drawTextItem(), a function that takes a QTextItem as
       
    65     one of its arguments.
       
    66 */
       
    67 
       
    68 /*!
       
    69   \enum QTextItem::RenderFlag
       
    70 
       
    71   \value  RightToLeft Render the text from right to left.
       
    72   \value  Overline    Paint a line above the text.
       
    73   \value  Underline   Paint a line under the text.
       
    74   \value  StrikeOut   Paint a line through the text.
       
    75   \omitvalue Dummy
       
    76 */
       
    77 
       
    78 
       
    79 /*!
       
    80     \fn qreal QTextItem::descent() const
       
    81 
       
    82     Corresponds to the \l{QFontMetrics::descent()}{descent} of the piece of text that is drawn.
       
    83 */
       
    84 qreal QTextItem::descent() const
       
    85 {
       
    86     const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
       
    87     return ti->descent.toReal();
       
    88 }
       
    89 
       
    90 /*!
       
    91     \fn qreal QTextItem::ascent() const
       
    92 
       
    93     Corresponds to the \l{QFontMetrics::ascent()}{ascent} of the piece of text that is drawn.
       
    94 */
       
    95 qreal QTextItem::ascent() const
       
    96 {
       
    97     const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
       
    98     return ti->ascent.toReal();
       
    99 }
       
   100 
       
   101 /*!
       
   102     \fn qreal QTextItem::width() const
       
   103 
       
   104     Specifies the total width of the text to be drawn.
       
   105 */
       
   106 qreal QTextItem::width() const
       
   107 {
       
   108     const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
       
   109     return ti->width.toReal();
       
   110 }
       
   111 
       
   112 /*!
       
   113     \fn QTextItem::RenderFlags QTextItem::renderFlags() const
       
   114 
       
   115     Returns the render flags used.
       
   116 */
       
   117 QTextItem::RenderFlags QTextItem::renderFlags() const
       
   118 {
       
   119     const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
       
   120     return ti->flags;
       
   121 }
       
   122 
       
   123 /*!
       
   124     \fn QString QTextItem::text() const
       
   125 
       
   126     Returns the text that should be drawn.
       
   127 */
       
   128 QString QTextItem::text() const
       
   129 {
       
   130     const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
       
   131     return QString(ti->chars, ti->num_chars);
       
   132 }
       
   133 
       
   134 /*!
       
   135     \fn QFont QTextItem::font() const
       
   136 
       
   137     Returns the font that should be used to draw the text.
       
   138 */
       
   139 QFont QTextItem::font() const
       
   140 {
       
   141     const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
       
   142     return ti->f ? *ti->f : QApplication::font();
       
   143 }
       
   144 
       
   145 
       
   146 /*!
       
   147   \class QPaintEngine
       
   148   \ingroup painting
       
   149 
       
   150   \brief The QPaintEngine class provides an abstract definition of how
       
   151   QPainter draws to a given device on a given platform.
       
   152 
       
   153   Qt 4.0 provides several premade implementations of QPaintEngine for the
       
   154   different painter backends we support. We provide one paint engine for each
       
   155   window system and painting framework we support. This includes X11 on
       
   156   Unix/Linux and CoreGraphics on Mac OS X. In addition we provide QPaintEngine
       
   157   implementations for OpenGL (accessible through QGLWidget) and PostScript
       
   158   (accessible through QPSPrinter on X11). Additionally there is a raster-based
       
   159   paint engine that is a fallback for when an engine does not support a certain
       
   160   capability.
       
   161 
       
   162   If one wants to use QPainter to draw to a different backend,
       
   163   one must subclass QPaintEngine and reimplement all its virtual
       
   164   functions. The QPaintEngine implementation is then made available by
       
   165   subclassing QPaintDevice and reimplementing the virtual function
       
   166   QPaintDevice::paintEngine().
       
   167 
       
   168   QPaintEngine is created and owned by the QPaintDevice that created it.
       
   169 
       
   170   The big advantage of the QPaintEngine approach opposed to
       
   171   Qt 3's QPainter/QPaintDevice::cmd() approach is that it is now
       
   172   possible to adapt to multiple technologies on each platform and take
       
   173   advantage of each to the fullest.
       
   174 
       
   175   \sa QPainter, QPaintDevice::paintEngine(), {The Paint System}
       
   176 */
       
   177 
       
   178 /*!
       
   179   \enum QPaintEngine::PaintEngineFeature
       
   180 
       
   181   This enum is used to describe the features or capabilities that the
       
   182   paint engine has. If a feature is not supported by the engine,
       
   183   QPainter will do a best effort to emulate that feature through other
       
   184   means and pass on an alpha blended QImage to the engine with the
       
   185   emulated results. Some features cannot be emulated: AlphaBlend and PorterDuff.
       
   186 
       
   187   \value AlphaBlend         The engine can alpha blend primitives.
       
   188   \value Antialiasing       The engine can use antialising to improve the appearance
       
   189                             of rendered primitives.
       
   190   \value BlendModes         The engine supports blending modes.
       
   191   \value BrushStroke        The engine supports drawing strokes that
       
   192                             contain brushes as fills, not just solid
       
   193                             colors (e.g. a dashed gradient line of
       
   194                             width 2).
       
   195   \value ConicalGradientFill The engine supports conical gradient fills.
       
   196   \value ConstantOpacity    The engine supports the feature provided by
       
   197                             QPainter::setOpacity().
       
   198   \value LinearGradientFill The engine supports linear gradient fills.
       
   199   \value MaskedBrush        The engine is capable of rendering brushes that has a
       
   200                             texture with an alpha channel or a mask.
       
   201   \value ObjectBoundingModeGradients The engine has native support for gradients
       
   202                             with coordinate mode QGradient::ObjectBoundingMode.
       
   203                             Otherwise, if QPaintEngine::PatternTransform is
       
   204                             supported, object bounding mode gradients are
       
   205                             converted to gradients with coordinate mode
       
   206                             QGradient::LogicalMode and a brush transform for
       
   207                             the coordinate mapping.
       
   208   \value PainterPaths       The engine has path support.
       
   209   \value PaintOutsidePaintEvent The engine is capable of painting outside of
       
   210                                 paint events.
       
   211   \value PatternBrush       The engine is capable of rendering brushes with
       
   212                             the brush patterns specified in Qt::BrushStyle.
       
   213   \value PatternTransform   The engine has support for transforming brush
       
   214                             patterns.
       
   215   \value PerspectiveTransform The engine has support for performing perspective
       
   216                             transformations on primitives.
       
   217   \value PixmapTransform    The engine can transform pixmaps, including
       
   218                             rotation and shearing.
       
   219   \value PorterDuff         The engine supports Porter-Duff operations
       
   220   \value PrimitiveTransform The engine has support for transforming
       
   221                             drawing primitives.
       
   222   \value RadialGradientFill The engine supports radial gradient fills.
       
   223   \value RasterOpModes      The engine supports bitwise raster operations.
       
   224   \value AllFeatures        All of the above features. This enum value is usually
       
   225                             used as a bit mask.
       
   226 */
       
   227 
       
   228 /*!
       
   229     \enum QPaintEngine::PolygonDrawMode
       
   230 
       
   231     \value OddEvenMode The polygon should be drawn using OddEven fill
       
   232     rule.
       
   233 
       
   234     \value WindingMode The polygon should be drawn using Winding fill rule.
       
   235 
       
   236     \value ConvexMode The polygon is a convex polygon and can be drawn
       
   237     using specialized algorithms where available.
       
   238 
       
   239     \value PolylineMode Only the outline of the polygon should be
       
   240     drawn.
       
   241 
       
   242 */
       
   243 
       
   244 /*!
       
   245     \enum QPaintEngine::DirtyFlag
       
   246 
       
   247     \value DirtyPen The pen is dirty and needs to be updated.
       
   248 
       
   249     \value DirtyBrush The brush is dirty and needs to be updated.
       
   250 
       
   251     \value DirtyBrushOrigin The brush origin is dirty and needs to
       
   252     updated.
       
   253 
       
   254     \value DirtyFont The font is dirty and needs to be updated.
       
   255 
       
   256     \value DirtyBackground The background is dirty and needs to be
       
   257     updated.
       
   258 
       
   259     \value DirtyBackgroundMode The background mode is dirty and needs
       
   260     to be updated.
       
   261 
       
   262     \value DirtyTransform The transform is dirty and needs to be
       
   263     updated.
       
   264 
       
   265     \value DirtyClipRegion The clip region is dirty and needs to be
       
   266     updated.
       
   267 
       
   268     \value DirtyClipPath The clip path is dirty and needs to be
       
   269     updated.
       
   270 
       
   271     \value DirtyHints The render hints is dirty and needs to be
       
   272     updated.
       
   273 
       
   274     \value DirtyCompositionMode The composition mode is dirty and
       
   275     needs to be updated.
       
   276 
       
   277     \value DirtyClipEnabled Whether clipping is enabled or not is
       
   278     dirty and needs to be updated.
       
   279 
       
   280     \value DirtyOpacity The constant opacity has changed and needs to
       
   281                         be updated as part of the state change in
       
   282                         QPaintEngine::updateState().
       
   283 
       
   284     \value AllDirty Convenience enum used internally.
       
   285 
       
   286     These types are used by QPainter to trigger lazy updates of the
       
   287     various states in the QPaintEngine using
       
   288     QPaintEngine::updateState().
       
   289 
       
   290     A paint engine must update every dirty state.
       
   291 */
       
   292 
       
   293 /*!
       
   294     \fn void QPaintEngine::syncState()
       
   295 
       
   296     \internal
       
   297 
       
   298     Updates all dirty states in this engine. This function should ONLY
       
   299     be used when drawing with native handles directly and immediate sync
       
   300     from QPainters state to the native state is required.
       
   301 */
       
   302 void QPaintEngine::syncState()
       
   303 {
       
   304     Q_ASSERT(state);
       
   305     updateState(*state);
       
   306 
       
   307     if (isExtended())
       
   308         static_cast<QPaintEngineEx *>(this)->sync();
       
   309 }
       
   310 
       
   311 static QPaintEngine *qt_polygon_recursion = 0;
       
   312 struct QT_Point {
       
   313     int x;
       
   314     int y;
       
   315 };
       
   316 
       
   317 /*!
       
   318     \fn void QPaintEngine::drawPolygon(const QPointF *points, int pointCount,
       
   319     PolygonDrawMode mode)
       
   320 
       
   321     Reimplement this virtual function to draw the polygon defined
       
   322     by the \a pointCount first points in \a points, using mode \a
       
   323     mode.
       
   324 
       
   325     \note At least one of the drawPolygon() functions must be reimplemented.
       
   326 */
       
   327 void QPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
       
   328 {
       
   329     Q_ASSERT_X(qt_polygon_recursion != this, "QPaintEngine::drawPolygon",
       
   330                "At least one drawPolygon function must be implemented");
       
   331     qt_polygon_recursion = this;
       
   332     Q_ASSERT(sizeof(QT_Point) == sizeof(QPoint));
       
   333     QVarLengthArray<QT_Point> p(pointCount);
       
   334     for (int i = 0; i < pointCount; ++i) {
       
   335         p[i].x = qRound(points[i].x());
       
   336         p[i].y = qRound(points[i].y());
       
   337     }
       
   338     drawPolygon((QPoint *)p.data(), pointCount, mode);
       
   339     qt_polygon_recursion = 0;
       
   340 }
       
   341 
       
   342 struct QT_PointF {
       
   343     qreal x;
       
   344     qreal y;
       
   345 };
       
   346 /*!
       
   347     \overload
       
   348 
       
   349     Reimplement this virtual function to draw the polygon defined by the
       
   350     \a pointCount first points in \a points, using mode \a mode.
       
   351 
       
   352     \note At least one of the drawPolygon() functions must be reimplemented.
       
   353 */
       
   354 void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
       
   355 {
       
   356     Q_ASSERT_X(qt_polygon_recursion != this, "QPaintEngine::drawPolygon",
       
   357                "At least one drawPolygon function must be implemented");
       
   358     qt_polygon_recursion = this;
       
   359     Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
       
   360     QVarLengthArray<QT_PointF> p(pointCount);
       
   361     for (int i=0; i<pointCount; ++i) {
       
   362         p[i].x = points[i].x();
       
   363         p[i].y = points[i].y();
       
   364     }
       
   365     drawPolygon((QPointF *)p.data(), pointCount, mode);
       
   366     qt_polygon_recursion = 0;
       
   367 }
       
   368 
       
   369 /*!
       
   370     \enum QPaintEngine::Type
       
   371 
       
   372     \value X11
       
   373     \value Windows
       
   374     \value MacPrinter
       
   375     \value CoreGraphics Mac OS X's Quartz2D (CoreGraphics)
       
   376     \value QuickDraw Mac OS X's QuickDraw
       
   377     \value QWindowSystem Qt for Embedded Linux
       
   378     \value PostScript
       
   379     \value OpenGL
       
   380     \value Picture QPicture format
       
   381     \value SVG Scalable Vector Graphics XML format
       
   382     \value Raster
       
   383     \value Direct3D Windows only, Direct3D based engine
       
   384     \value Pdf Portable Document Format
       
   385     \value OpenVG
       
   386     \value User First user type ID
       
   387     \value MaxUser Last user type ID
       
   388     \value OpenGL2
       
   389     \value PaintBuffer
       
   390 */
       
   391 
       
   392 /*!
       
   393     \fn bool QPaintEngine::isActive() const
       
   394 
       
   395     Returns true if the paint engine is actively drawing; otherwise
       
   396     returns false.
       
   397 
       
   398     \sa setActive()
       
   399 */
       
   400 
       
   401 /*!
       
   402     \fn void QPaintEngine::setActive(bool state)
       
   403 
       
   404     Sets the active state of the paint engine to \a state.
       
   405 
       
   406     \sa isActive()
       
   407 */
       
   408 
       
   409 /*!
       
   410     \fn bool QPaintEngine::begin(QPaintDevice *pdev)
       
   411 
       
   412     Reimplement this function to initialise your paint engine when
       
   413     painting is to start on the paint device \a pdev. Return true if
       
   414     the initialization was successful; otherwise return false.
       
   415 
       
   416     \sa end() isActive()
       
   417 */
       
   418 
       
   419 /*!
       
   420     \fn bool QPaintEngine::end()
       
   421 
       
   422     Reimplement this function to finish painting on the current paint
       
   423     device. Return true if painting was finished successfully;
       
   424     otherwise return false.
       
   425 
       
   426     \sa begin() isActive()
       
   427 */
       
   428 
       
   429 
       
   430 /*!
       
   431     Draws the first \a pointCount points in the buffer \a points
       
   432 */
       
   433 void QPaintEngine::drawPoints(const QPointF *points, int pointCount)
       
   434 {
       
   435     QPainter *p = painter();
       
   436     if (!p)
       
   437         return;
       
   438 
       
   439     qreal penWidth = p->pen().widthF();
       
   440     if (penWidth == 0)
       
   441         penWidth = 1;
       
   442 
       
   443     bool ellipses = p->pen().capStyle() == Qt::RoundCap;
       
   444 
       
   445     p->save();
       
   446 
       
   447     QTransform transform;
       
   448     if (p->pen().isCosmetic()) {
       
   449         transform = p->transform();
       
   450         p->setTransform(QTransform());
       
   451     }
       
   452 
       
   453     p->setBrush(p->pen().brush());
       
   454     p->setPen(Qt::NoPen);
       
   455 
       
   456     for (int i=0; i<pointCount; ++i) {
       
   457         QPointF pos = transform.map(points[i]);
       
   458         QRectF rect(pos.x() - penWidth / 2, pos.y() - penWidth / 2, penWidth, penWidth);
       
   459 
       
   460         if (ellipses)
       
   461             p->drawEllipse(rect);
       
   462         else
       
   463             p->drawRect(rect);
       
   464     }
       
   465 
       
   466     p->restore();
       
   467 }
       
   468 
       
   469 
       
   470 /*!
       
   471     Draws the first \a pointCount points in the buffer \a points
       
   472 
       
   473     The default implementation converts the first \a pointCount QPoints in \a points
       
   474     to QPointFs and calls the floating point version of drawPoints.
       
   475 
       
   476 */
       
   477 void QPaintEngine::drawPoints(const QPoint *points, int pointCount)
       
   478 {
       
   479     Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
       
   480     QT_PointF fp[256];
       
   481     while (pointCount) {
       
   482         int i = 0;
       
   483         while (i < pointCount && i < 256) {
       
   484             fp[i].x = points[i].x();
       
   485             fp[i].y = points[i].y();
       
   486             ++i;
       
   487         }
       
   488         drawPoints((QPointF *)(void *)fp, i);
       
   489         points += i;
       
   490         pointCount -= i;
       
   491     }
       
   492 }
       
   493 
       
   494 /*!
       
   495     \fn void QPaintEngine::drawEllipse(const QRectF &rect)
       
   496 
       
   497     Reimplement this function to draw the largest ellipse that can be
       
   498     contained within rectangle \a rect.
       
   499 
       
   500     The default implementation calls drawPolygon().
       
   501 */
       
   502 void QPaintEngine::drawEllipse(const QRectF &rect)
       
   503 {
       
   504     QPainterPath path;
       
   505     path.addEllipse(rect);
       
   506     if (hasFeature(PainterPaths)) {
       
   507         drawPath(path);
       
   508     } else {
       
   509         QPolygonF polygon = path.toFillPolygon();
       
   510         drawPolygon(polygon.data(), polygon.size(), ConvexMode);
       
   511     }
       
   512 }
       
   513 
       
   514 /*!
       
   515     The default implementation of this function calls the floating
       
   516     point version of this function
       
   517 */
       
   518 void QPaintEngine::drawEllipse(const QRect &rect)
       
   519 {
       
   520     drawEllipse(QRectF(rect));
       
   521 }
       
   522 
       
   523 /*!
       
   524     \fn void QPaintEngine::drawPixmap(const QRectF &r, const QPixmap
       
   525     &pm, const QRectF &sr)
       
   526 
       
   527     Reimplement this function to draw the part of the \a pm
       
   528     specified by the \a sr rectangle in the given \a r.
       
   529 */
       
   530 
       
   531 
       
   532 void qt_fill_tile(QPixmap *tile, const QPixmap &pixmap)
       
   533 {
       
   534     QPainter p(tile);
       
   535     p.drawPixmap(0, 0, pixmap);
       
   536     int x = pixmap.width();
       
   537     while (x < tile->width()) {
       
   538         p.drawPixmap(x, 0, *tile, 0, 0, x, pixmap.height());
       
   539         x *= 2;
       
   540     }
       
   541     int y = pixmap.height();
       
   542     while (y < tile->height()) {
       
   543         p.drawPixmap(0, y, *tile, 0, 0, tile->width(), y);
       
   544         y *= 2;
       
   545     }
       
   546 }
       
   547 
       
   548 void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
       
   549                   const QPixmap &pixmap, qreal xOffset, qreal yOffset)
       
   550 {
       
   551     qreal yPos, xPos, drawH, drawW, yOff, xOff;
       
   552     yPos = y;
       
   553     yOff = yOffset;
       
   554     while(yPos < y + h) {
       
   555         drawH = pixmap.height() - yOff;    // Cropping first row
       
   556         if (yPos + drawH > y + h)           // Cropping last row
       
   557             drawH = y + h - yPos;
       
   558         xPos = x;
       
   559         xOff = xOffset;
       
   560         while(xPos < x + w) {
       
   561             drawW = pixmap.width() - xOff; // Cropping first column
       
   562             if (xPos + drawW > x + w)           // Cropping last column
       
   563                 drawW = x + w - xPos;
       
   564             if (drawW > 0 && drawH > 0)
       
   565                 gc->drawPixmap(QRectF(xPos, yPos, drawW, drawH), pixmap, QRectF(xOff, yOff, drawW, drawH));
       
   566             xPos += drawW;
       
   567             xOff = 0;
       
   568         }
       
   569         yPos += drawH;
       
   570         yOff = 0;
       
   571     }
       
   572 }
       
   573 
       
   574 
       
   575 /*!
       
   576     Reimplement this function to draw the \a pixmap in the given \a
       
   577     rect, starting at the given \a p. The pixmap will be
       
   578     drawn repeatedly until the \a rect is filled.
       
   579 */
       
   580 void QPaintEngine::drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p)
       
   581 {
       
   582     int sw = pixmap.width();
       
   583     int sh = pixmap.height();
       
   584 
       
   585     if (sw*sh < 8192 && sw*sh < 16*rect.width()*rect.height()) {
       
   586         int tw = sw, th = sh;
       
   587         while (tw*th < 32678 && tw < rect.width()/2)
       
   588             tw *= 2;
       
   589         while (tw*th < 32678 && th < rect.height()/2)
       
   590             th *= 2;
       
   591         QPixmap tile;
       
   592         if (pixmap.depth() == 1) {
       
   593             tile = QBitmap(tw, th);
       
   594         } else {
       
   595             tile = QPixmap(tw, th);
       
   596             if (pixmap.hasAlphaChannel())
       
   597                 tile.fill(Qt::transparent);
       
   598         }
       
   599         qt_fill_tile(&tile, pixmap);
       
   600         qt_draw_tile(this, rect.x(), rect.y(), rect.width(), rect.height(), tile, p.x(), p.y());
       
   601     } else {
       
   602         qt_draw_tile(this, rect.x(), rect.y(), rect.width(), rect.height(), pixmap, p.x(), p.y());
       
   603     }
       
   604 }
       
   605 
       
   606 /*!
       
   607     \fn void QPaintEngine::drawImage(const QRectF &rectangle, const QImage
       
   608     &image, const QRectF &sr, Qt::ImageConversionFlags flags)
       
   609 
       
   610     Reimplement this function to draw the part of the \a image
       
   611     specified by the \a sr rectangle in the given \a rectangle using
       
   612     the given conversion flags \a flags, to convert it to a pixmap.
       
   613 */
       
   614 
       
   615 void QPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
       
   616                              Qt::ImageConversionFlags flags)
       
   617 {
       
   618     QRectF baseSize(0, 0, image.width(), image.height());
       
   619     QImage im = image;
       
   620     if (baseSize != sr)
       
   621         im = im.copy(qFloor(sr.x()), qFloor(sr.y()),
       
   622                      qCeil(sr.width()), qCeil(sr.height()));
       
   623     QPixmap pm = QPixmap::fromImage(im, flags);
       
   624     drawPixmap(r, pm, QRectF(QPointF(0, 0), pm.size()));
       
   625 }
       
   626 
       
   627 /*!
       
   628     \fn Type QPaintEngine::type() const
       
   629 
       
   630     Reimplement this function to return the paint engine \l{Type}.
       
   631 */
       
   632 
       
   633 /*!
       
   634     \fn void QPaintEngine::fix_neg_rect(int *x, int *y, int *w, int *h);
       
   635 
       
   636     \internal
       
   637 */
       
   638 
       
   639 /*!
       
   640     \fn bool QPaintEngine::testDirty(DirtyFlags df)
       
   641 
       
   642     \internal
       
   643 */
       
   644 
       
   645 /*!
       
   646     \fn void QPaintEngine::clearDirty(DirtyFlags df)
       
   647 
       
   648     \internal
       
   649 */
       
   650 
       
   651 /*!
       
   652     \fn void QPaintEngine::setDirty(DirtyFlags df)
       
   653 
       
   654     \internal
       
   655 */
       
   656 
       
   657 /*!
       
   658     \fn bool QPaintEngine::hasFeature(PaintEngineFeatures feature) const
       
   659 
       
   660     Returns true if the paint engine supports the specified \a
       
   661     feature; otherwise returns false.
       
   662 */
       
   663 
       
   664 /*!
       
   665     \fn bool QPaintEngine::isExtended() const
       
   666 
       
   667     \internal
       
   668 
       
   669     Returns true if the paint engine is a QPaintEngineEx derivative.
       
   670 */
       
   671 
       
   672 /*!
       
   673     \fn void QPaintEngine::updateState(const QPaintEngineState &state)
       
   674 
       
   675     Reimplement this function to update the state of a paint engine.
       
   676 
       
   677     When implemented, this function is responsible for checking the
       
   678     paint engine's current \a state and update the properties that are
       
   679     changed. Use the QPaintEngineState::state() function to find out
       
   680     which properties that must be updated, then use the corresponding
       
   681     \l {GetFunction}{get function} to retrieve the current values for
       
   682     the given properties.
       
   683 
       
   684     \sa QPaintEngineState
       
   685 */
       
   686 
       
   687 /*!
       
   688     Creates a paint engine with the featureset specified by \a caps.
       
   689 */
       
   690 
       
   691 QPaintEngine::QPaintEngine(PaintEngineFeatures caps)
       
   692     : state(0),
       
   693       gccaps(caps),
       
   694       active(0),
       
   695       selfDestruct(false),
       
   696       extended(false),
       
   697       d_ptr(new QPaintEnginePrivate)
       
   698 {
       
   699     d_ptr->q_ptr = this;
       
   700 }
       
   701 
       
   702 /*!
       
   703   \internal
       
   704 */
       
   705 
       
   706 QPaintEngine::QPaintEngine(QPaintEnginePrivate &dptr, PaintEngineFeatures caps)
       
   707     : state(0),
       
   708       gccaps(caps),
       
   709       active(0),
       
   710       selfDestruct(false),
       
   711       extended(false),
       
   712       d_ptr(&dptr)
       
   713 {
       
   714     d_ptr->q_ptr = this;
       
   715 }
       
   716 
       
   717 /*!
       
   718     Destroys the paint engine.
       
   719 */
       
   720 QPaintEngine::~QPaintEngine()
       
   721 {
       
   722 }
       
   723 
       
   724 /*!
       
   725     Returns the paint engine's painter.
       
   726 */
       
   727 QPainter *QPaintEngine::painter() const
       
   728 {
       
   729     return state ? state->painter() : 0;
       
   730 }
       
   731 
       
   732 /*!
       
   733     The default implementation ignores the \a path and does nothing.
       
   734 */
       
   735 
       
   736 void QPaintEngine::drawPath(const QPainterPath &)
       
   737 {
       
   738     if (hasFeature(PainterPaths)) {
       
   739         qWarning("QPaintEngine::drawPath: Must be implemented when feature PainterPaths is set");
       
   740     }
       
   741 }
       
   742 
       
   743 /*!
       
   744     This function draws the text item \a textItem at position \a p. The
       
   745     default implementation of this function converts the text to a
       
   746     QPainterPath and paints the resulting path.
       
   747 */
       
   748 
       
   749 void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
       
   750 {
       
   751     const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
       
   752 
       
   753     QPainterPath path;
       
   754 #ifndef Q_WS_MAC
       
   755     path.setFillRule(Qt::WindingFill);
       
   756 #endif
       
   757     if (ti.glyphs.numGlyphs)
       
   758         ti.fontEngine->addOutlineToPath(p.x(), p.y(), ti.glyphs, &path, ti.flags);
       
   759     if (!path.isEmpty()) {
       
   760         bool oldAA = painter()->renderHints() & QPainter::Antialiasing;
       
   761         painter()->setRenderHint(QPainter::Antialiasing,
       
   762                                  bool((painter()->renderHints() & QPainter::TextAntialiasing)
       
   763                                       && !(painter()->font().styleStrategy() & QFont::NoAntialias)));
       
   764         painter()->fillPath(path, state->pen().brush());
       
   765         painter()->setRenderHint(QPainter::Antialiasing, oldAA);
       
   766     }
       
   767 }
       
   768 
       
   769 /*!
       
   770     The default implementation splits the list of lines in \a lines
       
   771     into \a lineCount separate calls to drawPath() or drawPolygon()
       
   772     depending on the feature set of the paint engine.
       
   773 */
       
   774 void QPaintEngine::drawLines(const QLineF *lines, int lineCount)
       
   775 {
       
   776     for (int i=0; i<lineCount; ++i) {
       
   777         QPointF pts[2] = { lines[i].p1(), lines[i].p2() };
       
   778 
       
   779         if (pts[0] == pts[1]) {
       
   780             if (state->pen().capStyle() != Qt::FlatCap)
       
   781                 drawPoints(pts, 1);
       
   782             continue;
       
   783         }
       
   784 
       
   785         drawPolygon(pts, 2, PolylineMode);
       
   786     }
       
   787 }
       
   788 
       
   789 /*!
       
   790     \overload
       
   791 
       
   792     The default implementation converts the first \a lineCount lines
       
   793     in \a lines to a QLineF and calls the floating point version of
       
   794     this function.
       
   795 */
       
   796 void QPaintEngine::drawLines(const QLine *lines, int lineCount)
       
   797 {
       
   798     struct PointF {
       
   799         qreal x;
       
   800         qreal y;
       
   801     };
       
   802     struct LineF {
       
   803         PointF p1;
       
   804         PointF p2;
       
   805     };
       
   806     Q_ASSERT(sizeof(PointF) == sizeof(QPointF));
       
   807     Q_ASSERT(sizeof(LineF) == sizeof(QLineF));
       
   808     LineF fl[256];
       
   809     while (lineCount) {
       
   810         int i = 0;
       
   811         while (i < lineCount && i < 256) {
       
   812             fl[i].p1.x = lines[i].x1();
       
   813             fl[i].p1.y = lines[i].y1();
       
   814             fl[i].p2.x = lines[i].x2();
       
   815             fl[i].p2.y = lines[i].y2();
       
   816             ++i;
       
   817         }
       
   818         drawLines((QLineF *)(void *)fl, i);
       
   819         lines += i;
       
   820         lineCount -= i;
       
   821     }
       
   822 }
       
   823 
       
   824 
       
   825 /*!
       
   826     \overload
       
   827 
       
   828     The default implementation converts the first \a rectCount
       
   829     rectangles in the buffer \a rects to a QRectF and calls the
       
   830     floating point version of this function.
       
   831 */
       
   832 void QPaintEngine::drawRects(const QRect *rects, int rectCount)
       
   833 {
       
   834     struct RectF {
       
   835         qreal x;
       
   836         qreal y;
       
   837         qreal w;
       
   838         qreal h;
       
   839     };
       
   840     Q_ASSERT(sizeof(RectF) == sizeof(QRectF));
       
   841     RectF fr[256];
       
   842     while (rectCount) {
       
   843         int i = 0;
       
   844         while (i < rectCount && i < 256) {
       
   845             fr[i].x = rects[i].x();
       
   846             fr[i].y = rects[i].y();
       
   847             fr[i].w = rects[i].width();
       
   848             fr[i].h = rects[i].height();
       
   849             ++i;
       
   850         }
       
   851         drawRects((QRectF *)(void *)fr, i);
       
   852         rects += i;
       
   853         rectCount -= i;
       
   854     }
       
   855 }
       
   856 
       
   857 /*!
       
   858     Draws the first \a rectCount rectangles in the buffer \a
       
   859     rects. The default implementation of this function calls drawPath()
       
   860     or drawPolygon() depending on the feature set of the paint engine.
       
   861 */
       
   862 void QPaintEngine::drawRects(const QRectF *rects, int rectCount)
       
   863 {
       
   864     if (hasFeature(PainterPaths) &&
       
   865         !state->penNeedsResolving() &&
       
   866         !state->brushNeedsResolving()) {
       
   867         for (int i=0; i<rectCount; ++i) {
       
   868             QPainterPath path;
       
   869             path.addRect(rects[i]);
       
   870             if (path.isEmpty())
       
   871                 continue;
       
   872             drawPath(path);
       
   873         }
       
   874     } else {
       
   875         for (int i=0; i<rectCount; ++i) {
       
   876             QRectF rf = rects[i];
       
   877             QPointF pts[4] = { QPointF(rf.x(), rf.y()),
       
   878                                QPointF(rf.x() + rf.width(), rf.y()),
       
   879                                QPointF(rf.x() + rf.width(), rf.y() + rf.height()),
       
   880                                QPointF(rf.x(), rf.y() + rf.height()) };
       
   881             drawPolygon(pts, 4, ConvexMode);
       
   882         }
       
   883     }
       
   884 }
       
   885 
       
   886 /*!
       
   887     \internal
       
   888     Sets the paintdevice that this engine operates on to \a device
       
   889 */
       
   890 void QPaintEngine::setPaintDevice(QPaintDevice *device)
       
   891 {
       
   892     d_func()->pdev = device;
       
   893 }
       
   894 
       
   895 /*!
       
   896     Returns the device that this engine is painting on, if painting is
       
   897     active; otherwise returns 0.
       
   898 */
       
   899 QPaintDevice *QPaintEngine::paintDevice() const
       
   900 {
       
   901     return d_func()->pdev;
       
   902 }
       
   903 
       
   904 #ifdef Q_WS_WIN
       
   905 /*!
       
   906     \internal
       
   907 
       
   908     Empty default implementation.
       
   909 */
       
   910 
       
   911 HDC QPaintEngine::getDC() const
       
   912 {
       
   913     return 0;
       
   914 }
       
   915 
       
   916 
       
   917 /*!
       
   918     \internal
       
   919 
       
   920     Empty default implementation.
       
   921 */
       
   922 
       
   923 void QPaintEngine::releaseDC(HDC) const
       
   924 {
       
   925 }
       
   926 
       
   927 #endif
       
   928 
       
   929 /*!
       
   930     \internal
       
   931 
       
   932     Returns the offset from the painters origo to the engines
       
   933     origo. This value is used by QPainter for engines who have
       
   934     internal double buffering.
       
   935 
       
   936     This function only makes sense when the engine is active.
       
   937 */
       
   938 QPoint QPaintEngine::coordinateOffset() const
       
   939 {
       
   940     return QPoint();
       
   941 }
       
   942 
       
   943 /*!
       
   944     \internal
       
   945 
       
   946     Sets the system clip for this engine. The system clip defines the
       
   947     basis area that the engine has to draw in. All clips that are
       
   948     set will be be an intersection with the system clip.
       
   949 
       
   950     Reset the systemclip to no clip by setting an empty region.
       
   951 */
       
   952 void QPaintEngine::setSystemClip(const QRegion &region)
       
   953 {
       
   954     Q_D(QPaintEngine);
       
   955     d->systemClip = region;
       
   956     // Be backward compatible and only call d->systemStateChanged()
       
   957     // if we currently have a system transform/viewport set.
       
   958     if (d->hasSystemTransform || d->hasSystemViewport) {
       
   959         d->transformSystemClip();
       
   960         d->systemStateChanged();
       
   961     }
       
   962 }
       
   963 
       
   964 /*!
       
   965     \internal
       
   966 
       
   967     Returns the system clip. The system clip is read only while the
       
   968     painter is active. An empty region indicates that system clip
       
   969     is not in use.
       
   970 */
       
   971 
       
   972 QRegion QPaintEngine::systemClip() const
       
   973 {
       
   974     return d_func()->systemClip;
       
   975 }
       
   976 
       
   977 /*!
       
   978     \internal
       
   979 
       
   980     Sets the target rect for drawing within the backing store. This
       
   981     function should ONLY be used by the backing store.
       
   982 */
       
   983 void QPaintEngine::setSystemRect(const QRect &rect)
       
   984 {
       
   985     if (isActive()) {
       
   986         qWarning("QPaintEngine::setSystemRect: Should not be changed while engine is active");
       
   987         return;
       
   988     }
       
   989     d_func()->systemRect = rect;
       
   990 }
       
   991 
       
   992 /*!
       
   993     \internal
       
   994 
       
   995     Retreives the rect for drawing within the backing store. This
       
   996     function should ONLY be used by the backing store.
       
   997  */
       
   998 QRect QPaintEngine::systemRect() const
       
   999 {
       
  1000     return d_func()->systemRect;
       
  1001 }
       
  1002 
       
  1003 void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt &ti)
       
  1004 {
       
  1005     if (!ti.glyphs.numGlyphs)
       
  1006         return;
       
  1007 
       
  1008     // any fixes here should probably also be done in QFontEngineBox::draw
       
  1009     const int size = qRound(ti.fontEngine->ascent());
       
  1010     QVarLengthArray<QFixedPoint> positions;
       
  1011     QVarLengthArray<glyph_t> glyphs;
       
  1012     QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - size);
       
  1013     ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
       
  1014     if (glyphs.size() == 0)
       
  1015         return;
       
  1016 
       
  1017     QSize s(size - 3, size - 3);
       
  1018 
       
  1019     QPainter *painter = q_func()->state->painter();
       
  1020     painter->save();
       
  1021     painter->setBrush(Qt::NoBrush);
       
  1022     QPen pen = painter->pen();
       
  1023     pen.setWidthF(ti.fontEngine->lineThickness().toReal());
       
  1024     painter->setPen(pen);
       
  1025     for (int k = 0; k < positions.size(); k++)
       
  1026         painter->drawRect(QRectF(positions[k].toPointF(), s));
       
  1027     painter->restore();
       
  1028 }
       
  1029 
       
  1030 QT_END_NAMESPACE