Make QRegion not need to be friends with QVector
[profile/ivi/qtbase.git] / src / gui / painting / qpaintengine.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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 <qdebug.h>
47 #include <qmath.h>
48 #include <qguiapplication.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 : QGuiApplication::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 QOpenGLWidget) 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(), {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     \value Blitter
391 */
392
393 /*!
394     \fn bool QPaintEngine::isActive() const
395
396     Returns true if the paint engine is actively drawing; otherwise
397     returns false.
398
399     \sa setActive()
400 */
401
402 /*!
403     \fn void QPaintEngine::setActive(bool state)
404
405     Sets the active state of the paint engine to \a state.
406
407     \sa isActive()
408 */
409
410 /*!
411     \fn bool QPaintEngine::begin(QPaintDevice *pdev)
412
413     Reimplement this function to initialise your paint engine when
414     painting is to start on the paint device \a pdev. Return true if
415     the initialization was successful; otherwise return false.
416
417     \sa end(), isActive()
418 */
419
420 /*!
421     \fn bool QPaintEngine::end()
422
423     Reimplement this function to finish painting on the current paint
424     device. Return true if painting was finished successfully;
425     otherwise return false.
426
427     \sa begin(), isActive()
428 */
429
430
431 /*!
432     Draws the first \a pointCount points in the buffer \a points
433 */
434 void QPaintEngine::drawPoints(const QPointF *points, int pointCount)
435 {
436     QPainter *p = painter();
437     if (!p)
438         return;
439
440     qreal penWidth = p->pen().widthF();
441     if (penWidth == 0)
442         penWidth = 1;
443
444     bool ellipses = p->pen().capStyle() == Qt::RoundCap;
445
446     p->save();
447
448     QTransform transform;
449     if (p->pen().isCosmetic()) {
450         transform = p->transform();
451         p->setTransform(QTransform());
452     }
453
454     p->setBrush(p->pen().brush());
455     p->setPen(Qt::NoPen);
456
457     for (int i=0; i<pointCount; ++i) {
458         QPointF pos = transform.map(points[i]);
459         QRectF rect(pos.x() - penWidth / 2, pos.y() - penWidth / 2, penWidth, penWidth);
460
461         if (ellipses)
462             p->drawEllipse(rect);
463         else
464             p->drawRect(rect);
465     }
466
467     p->restore();
468 }
469
470
471 /*!
472     Draws the first \a pointCount points in the buffer \a points
473
474     The default implementation converts the first \a pointCount QPoints in \a points
475     to QPointFs and calls the floating point version of drawPoints.
476
477 */
478 void QPaintEngine::drawPoints(const QPoint *points, int pointCount)
479 {
480     Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
481     QT_PointF fp[256];
482     while (pointCount) {
483         int i = 0;
484         while (i < pointCount && i < 256) {
485             fp[i].x = points[i].x();
486             fp[i].y = points[i].y();
487             ++i;
488         }
489         drawPoints((QPointF *)(void *)fp, i);
490         points += i;
491         pointCount -= i;
492     }
493 }
494
495 /*!
496     \fn void QPaintEngine::drawEllipse(const QRectF &rect)
497
498     Reimplement this function to draw the largest ellipse that can be
499     contained within rectangle \a rect.
500
501     The default implementation calls drawPolygon().
502 */
503 void QPaintEngine::drawEllipse(const QRectF &rect)
504 {
505     QPainterPath path;
506     path.addEllipse(rect);
507     if (hasFeature(PainterPaths)) {
508         drawPath(path);
509     } else {
510         QPolygonF polygon = path.toFillPolygon();
511         drawPolygon(polygon.data(), polygon.size(), ConvexMode);
512     }
513 }
514
515 /*!
516     The default implementation of this function calls the floating
517     point version of this function
518 */
519 void QPaintEngine::drawEllipse(const QRect &rect)
520 {
521     drawEllipse(QRectF(rect));
522 }
523
524 /*!
525     \fn void QPaintEngine::drawPixmap(const QRectF &r, const QPixmap
526     &pm, const QRectF &sr)
527
528     Reimplement this function to draw the part of the \a pm
529     specified by the \a sr rectangle in the given \a r.
530 */
531
532
533 void qt_fill_tile(QPixmap *tile, const QPixmap &pixmap)
534 {
535     QPainter p(tile);
536     p.drawPixmap(0, 0, pixmap);
537     int x = pixmap.width();
538     while (x < tile->width()) {
539         p.drawPixmap(x, 0, *tile, 0, 0, x, pixmap.height());
540         x *= 2;
541     }
542     int y = pixmap.height();
543     while (y < tile->height()) {
544         p.drawPixmap(0, y, *tile, 0, 0, tile->width(), y);
545         y *= 2;
546     }
547 }
548
549 void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
550                   const QPixmap &pixmap, qreal xOffset, qreal yOffset)
551 {
552     qreal yPos, xPos, drawH, drawW, yOff, xOff;
553     yPos = y;
554     yOff = yOffset;
555     while(yPos < y + h) {
556         drawH = pixmap.height() - yOff;    // Cropping first row
557         if (yPos + drawH > y + h)           // Cropping last row
558             drawH = y + h - yPos;
559         xPos = x;
560         xOff = xOffset;
561         while(xPos < x + w) {
562             drawW = pixmap.width() - xOff; // Cropping first column
563             if (xPos + drawW > x + w)           // Cropping last column
564                 drawW = x + w - xPos;
565             if (drawW > 0 && drawH > 0)
566                 gc->drawPixmap(QRectF(xPos, yPos, drawW, drawH), pixmap, QRectF(xOff, yOff, drawW, drawH));
567             xPos += drawW;
568             xOff = 0;
569         }
570         yPos += drawH;
571         yOff = 0;
572     }
573 }
574
575
576 /*!
577     Reimplement this function to draw the \a pixmap in the given \a
578     rect, starting at the given \a p. The pixmap will be
579     drawn repeatedly until the \a rect is filled.
580 */
581 void QPaintEngine::drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p)
582 {
583     int sw = pixmap.width();
584     int sh = pixmap.height();
585
586     if (sw*sh < 8192 && sw*sh < 16*rect.width()*rect.height()) {
587         int tw = sw, th = sh;
588         while (tw*th < 32678 && tw < rect.width()/2)
589             tw *= 2;
590         while (tw*th < 32678 && th < rect.height()/2)
591             th *= 2;
592         QPixmap tile;
593         if (pixmap.depth() == 1) {
594             tile = QBitmap(tw, th);
595         } else {
596             tile = QPixmap(tw, th);
597             if (pixmap.hasAlphaChannel())
598                 tile.fill(Qt::transparent);
599         }
600         qt_fill_tile(&tile, pixmap);
601         qt_draw_tile(this, rect.x(), rect.y(), rect.width(), rect.height(), tile, p.x(), p.y());
602     } else {
603         qt_draw_tile(this, rect.x(), rect.y(), rect.width(), rect.height(), pixmap, p.x(), p.y());
604     }
605 }
606
607 /*!
608     \fn void QPaintEngine::drawImage(const QRectF &rectangle, const QImage
609     &image, const QRectF &sr, Qt::ImageConversionFlags flags)
610
611     Reimplement this function to draw the part of the \a image
612     specified by the \a sr rectangle in the given \a rectangle using
613     the given conversion flags \a flags, to convert it to a pixmap.
614 */
615
616 void QPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
617                              Qt::ImageConversionFlags flags)
618 {
619     QRectF baseSize(0, 0, image.width(), image.height());
620     QImage im = image;
621     if (baseSize != sr)
622         im = im.copy(qFloor(sr.x()), qFloor(sr.y()),
623                      qCeil(sr.width()), qCeil(sr.height()));
624     QPixmap pm = QPixmap::fromImage(im, flags);
625     drawPixmap(r, pm, QRectF(QPointF(0, 0), pm.size()));
626 }
627
628 /*!
629     \fn Type QPaintEngine::type() const
630
631     Reimplement this function to return the paint engine \l{Type}.
632 */
633
634 /*!
635     \fn void QPaintEngine::fix_neg_rect(int *x, int *y, int *w, int *h);
636
637     \internal
638 */
639
640 /*!
641     \fn bool QPaintEngine::testDirty(DirtyFlags df)
642
643     \internal
644 */
645
646 /*!
647     \fn void QPaintEngine::clearDirty(DirtyFlags df)
648
649     \internal
650 */
651
652 /*!
653     \fn void QPaintEngine::setDirty(DirtyFlags df)
654
655     \internal
656 */
657
658 /*!
659     \fn bool QPaintEngine::hasFeature(PaintEngineFeatures feature) const
660
661     Returns true if the paint engine supports the specified \a
662     feature; otherwise returns false.
663 */
664
665 /*!
666     \fn bool QPaintEngine::isExtended() const
667
668     \internal
669
670     Returns true if the paint engine is a QPaintEngineEx derivative.
671 */
672
673 /*!
674     \fn void QPaintEngine::updateState(const QPaintEngineState &state)
675
676     Reimplement this function to update the state of a paint engine.
677
678     When implemented, this function is responsible for checking the
679     paint engine's current \a state and update the properties that are
680     changed. Use the QPaintEngineState::state() function to find out
681     which properties that must be updated, then use the corresponding
682     \l {GetFunction}{get function} to retrieve the current values for
683     the given properties.
684
685     \sa QPaintEngineState
686 */
687
688 /*!
689     Creates a paint engine with the featureset specified by \a caps.
690 */
691
692 QPaintEngine::QPaintEngine(PaintEngineFeatures caps)
693     : state(0),
694       gccaps(caps),
695       active(0),
696       selfDestruct(false),
697       extended(false),
698       d_ptr(new QPaintEnginePrivate)
699 {
700     d_ptr->q_ptr = this;
701 }
702
703 /*!
704   \internal
705 */
706
707 QPaintEngine::QPaintEngine(QPaintEnginePrivate &dptr, PaintEngineFeatures caps)
708     : state(0),
709       gccaps(caps),
710       active(0),
711       selfDestruct(false),
712       extended(false),
713       d_ptr(&dptr)
714 {
715     d_ptr->q_ptr = this;
716 }
717
718 /*!
719     Destroys the paint engine.
720 */
721 QPaintEngine::~QPaintEngine()
722 {
723 }
724
725 /*!
726     Returns the paint engine's painter.
727 */
728 QPainter *QPaintEngine::painter() const
729 {
730     return state ? state->painter() : 0;
731 }
732
733 /*!
734     The default implementation ignores the \a path and does nothing.
735 */
736
737 void QPaintEngine::drawPath(const QPainterPath &)
738 {
739     if (hasFeature(PainterPaths)) {
740         qWarning("QPaintEngine::drawPath: Must be implemented when feature PainterPaths is set");
741     }
742 }
743
744 /*!
745     This function draws the text item \a textItem at position \a p. The
746     default implementation of this function converts the text to a
747     QPainterPath and paints the resulting path.
748 */
749
750 void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
751 {
752     const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
753
754     QPainterPath path;
755     path.setFillRule(Qt::WindingFill);
756     if (ti.glyphs.numGlyphs)
757         ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags);
758     if (!path.isEmpty()) {
759         painter()->save();
760         painter()->setRenderHint(QPainter::Antialiasing,
761                                  bool((painter()->renderHints() & QPainter::TextAntialiasing)
762                                       && !(painter()->font().styleStrategy() & QFont::NoAntialias)));
763         painter()->translate(p.x(), p.y());
764         painter()->fillPath(path, state->pen().brush());
765         painter()->restore();
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
905 /*!
906     \internal
907
908     Returns the offset from the painters origo to the engines
909     origo. This value is used by QPainter for engines who have
910     internal double buffering.
911
912     This function only makes sense when the engine is active.
913 */
914 QPoint QPaintEngine::coordinateOffset() const
915 {
916     return QPoint();
917 }
918
919 /*!
920     \internal
921
922     Sets the system clip for this engine. The system clip defines the
923     basis area that the engine has to draw in. All clips that are
924     set will be be an intersection with the system clip.
925
926     Reset the systemclip to no clip by setting an empty region.
927 */
928 void QPaintEngine::setSystemClip(const QRegion &region)
929 {
930     Q_D(QPaintEngine);
931     d->systemClip = region;
932     // Be backward compatible and only call d->systemStateChanged()
933     // if we currently have a system transform/viewport set.
934     if (d->hasSystemTransform || d->hasSystemViewport) {
935         d->transformSystemClip();
936         d->systemStateChanged();
937     }
938 }
939
940 /*!
941     \internal
942
943     Returns the system clip. The system clip is read only while the
944     painter is active. An empty region indicates that system clip
945     is not in use.
946 */
947
948 QRegion QPaintEngine::systemClip() const
949 {
950     return d_func()->systemClip;
951 }
952
953 /*!
954     \internal
955
956     Sets the target rect for drawing within the backing store. This
957     function should ONLY be used by the backing store.
958 */
959 void QPaintEngine::setSystemRect(const QRect &rect)
960 {
961     if (isActive()) {
962         qWarning("QPaintEngine::setSystemRect: Should not be changed while engine is active");
963         return;
964     }
965     d_func()->systemRect = rect;
966 }
967
968 /*!
969     \internal
970
971     Retrieves the rect for drawing within the backing store. This
972     function should ONLY be used by the backing store.
973  */
974 QRect QPaintEngine::systemRect() const
975 {
976     return d_func()->systemRect;
977 }
978
979 void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt &ti)
980 {
981     if (!ti.glyphs.numGlyphs)
982         return;
983
984     // any fixes here should probably also be done in QFontEngineBox::draw
985     const int size = qRound(ti.fontEngine->ascent());
986     QVarLengthArray<QFixedPoint> positions;
987     QVarLengthArray<glyph_t> glyphs;
988     QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - size);
989     ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
990     if (glyphs.size() == 0)
991         return;
992
993     QSize s(size - 3, size - 3);
994
995     QPainter *painter = q_func()->state->painter();
996     painter->save();
997     painter->setBrush(Qt::NoBrush);
998     QPen pen = painter->pen();
999     pen.setWidthF(ti.fontEngine->lineThickness().toReal());
1000     painter->setPen(pen);
1001     for (int k = 0; k < positions.size(); k++)
1002         painter->drawRect(QRectF(positions[k].toPointF(), s));
1003     painter->restore();
1004 }
1005
1006 QT_END_NAMESPACE