Replace 'i < len-1 && func(i+1)' by 'i+1 < len && func(i+1)'
[profile/ivi/qtbase.git] / src / gui / painting / qpaintengine.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 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 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
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(), {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 #ifndef Q_WS_MAC
756     path.setFillRule(Qt::WindingFill);
757 #endif
758     if (ti.glyphs.numGlyphs)
759         ti.fontEngine->addOutlineToPath(p.x(), p.y(), ti.glyphs, &path, ti.flags);
760     if (!path.isEmpty()) {
761         bool oldAA = painter()->renderHints() & QPainter::Antialiasing;
762         painter()->setRenderHint(QPainter::Antialiasing,
763                                  bool((painter()->renderHints() & QPainter::TextAntialiasing)
764                                       && !(painter()->font().styleStrategy() & QFont::NoAntialias)));
765         painter()->fillPath(path, state->pen().brush());
766         painter()->setRenderHint(QPainter::Antialiasing, oldAA);
767     }
768 }
769
770 /*!
771     The default implementation splits the list of lines in \a lines
772     into \a lineCount separate calls to drawPath() or drawPolygon()
773     depending on the feature set of the paint engine.
774 */
775 void QPaintEngine::drawLines(const QLineF *lines, int lineCount)
776 {
777     for (int i=0; i<lineCount; ++i) {
778         QPointF pts[2] = { lines[i].p1(), lines[i].p2() };
779
780         if (pts[0] == pts[1]) {
781             if (state->pen().capStyle() != Qt::FlatCap)
782                 drawPoints(pts, 1);
783             continue;
784         }
785
786         drawPolygon(pts, 2, PolylineMode);
787     }
788 }
789
790 /*!
791     \overload
792
793     The default implementation converts the first \a lineCount lines
794     in \a lines to a QLineF and calls the floating point version of
795     this function.
796 */
797 void QPaintEngine::drawLines(const QLine *lines, int lineCount)
798 {
799     struct PointF {
800         qreal x;
801         qreal y;
802     };
803     struct LineF {
804         PointF p1;
805         PointF p2;
806     };
807     Q_ASSERT(sizeof(PointF) == sizeof(QPointF));
808     Q_ASSERT(sizeof(LineF) == sizeof(QLineF));
809     LineF fl[256];
810     while (lineCount) {
811         int i = 0;
812         while (i < lineCount && i < 256) {
813             fl[i].p1.x = lines[i].x1();
814             fl[i].p1.y = lines[i].y1();
815             fl[i].p2.x = lines[i].x2();
816             fl[i].p2.y = lines[i].y2();
817             ++i;
818         }
819         drawLines((QLineF *)(void *)fl, i);
820         lines += i;
821         lineCount -= i;
822     }
823 }
824
825
826 /*!
827     \overload
828
829     The default implementation converts the first \a rectCount
830     rectangles in the buffer \a rects to a QRectF and calls the
831     floating point version of this function.
832 */
833 void QPaintEngine::drawRects(const QRect *rects, int rectCount)
834 {
835     struct RectF {
836         qreal x;
837         qreal y;
838         qreal w;
839         qreal h;
840     };
841     Q_ASSERT(sizeof(RectF) == sizeof(QRectF));
842     RectF fr[256];
843     while (rectCount) {
844         int i = 0;
845         while (i < rectCount && i < 256) {
846             fr[i].x = rects[i].x();
847             fr[i].y = rects[i].y();
848             fr[i].w = rects[i].width();
849             fr[i].h = rects[i].height();
850             ++i;
851         }
852         drawRects((QRectF *)(void *)fr, i);
853         rects += i;
854         rectCount -= i;
855     }
856 }
857
858 /*!
859     Draws the first \a rectCount rectangles in the buffer \a
860     rects. The default implementation of this function calls drawPath()
861     or drawPolygon() depending on the feature set of the paint engine.
862 */
863 void QPaintEngine::drawRects(const QRectF *rects, int rectCount)
864 {
865     if (hasFeature(PainterPaths) &&
866         !state->penNeedsResolving() &&
867         !state->brushNeedsResolving()) {
868         for (int i=0; i<rectCount; ++i) {
869             QPainterPath path;
870             path.addRect(rects[i]);
871             if (path.isEmpty())
872                 continue;
873             drawPath(path);
874         }
875     } else {
876         for (int i=0; i<rectCount; ++i) {
877             QRectF rf = rects[i];
878             QPointF pts[4] = { QPointF(rf.x(), rf.y()),
879                                QPointF(rf.x() + rf.width(), rf.y()),
880                                QPointF(rf.x() + rf.width(), rf.y() + rf.height()),
881                                QPointF(rf.x(), rf.y() + rf.height()) };
882             drawPolygon(pts, 4, ConvexMode);
883         }
884     }
885 }
886
887 /*!
888     \internal
889     Sets the paintdevice that this engine operates on to \a device
890 */
891 void QPaintEngine::setPaintDevice(QPaintDevice *device)
892 {
893     d_func()->pdev = device;
894 }
895
896 /*!
897     Returns the device that this engine is painting on, if painting is
898     active; otherwise returns 0.
899 */
900 QPaintDevice *QPaintEngine::paintDevice() const
901 {
902     return d_func()->pdev;
903 }
904
905 #ifdef Q_WS_WIN
906 /*!
907     \internal
908
909     Empty default implementation.
910 */
911
912 HDC QPaintEngine::getDC() const
913 {
914     return 0;
915 }
916
917
918 /*!
919     \internal
920
921     Empty default implementation.
922 */
923
924 void QPaintEngine::releaseDC(HDC) const
925 {
926 }
927
928 #endif
929
930 /*!
931     \internal
932
933     Returns the offset from the painters origo to the engines
934     origo. This value is used by QPainter for engines who have
935     internal double buffering.
936
937     This function only makes sense when the engine is active.
938 */
939 QPoint QPaintEngine::coordinateOffset() const
940 {
941     return QPoint();
942 }
943
944 /*!
945     \internal
946
947     Sets the system clip for this engine. The system clip defines the
948     basis area that the engine has to draw in. All clips that are
949     set will be be an intersection with the system clip.
950
951     Reset the systemclip to no clip by setting an empty region.
952 */
953 void QPaintEngine::setSystemClip(const QRegion &region)
954 {
955     Q_D(QPaintEngine);
956     d->systemClip = region;
957     // Be backward compatible and only call d->systemStateChanged()
958     // if we currently have a system transform/viewport set.
959     if (d->hasSystemTransform || d->hasSystemViewport) {
960         d->transformSystemClip();
961         d->systemStateChanged();
962     }
963 }
964
965 /*!
966     \internal
967
968     Returns the system clip. The system clip is read only while the
969     painter is active. An empty region indicates that system clip
970     is not in use.
971 */
972
973 QRegion QPaintEngine::systemClip() const
974 {
975     return d_func()->systemClip;
976 }
977
978 /*!
979     \internal
980
981     Sets the target rect for drawing within the backing store. This
982     function should ONLY be used by the backing store.
983 */
984 void QPaintEngine::setSystemRect(const QRect &rect)
985 {
986     if (isActive()) {
987         qWarning("QPaintEngine::setSystemRect: Should not be changed while engine is active");
988         return;
989     }
990     d_func()->systemRect = rect;
991 }
992
993 /*!
994     \internal
995
996     Retrieves the rect for drawing within the backing store. This
997     function should ONLY be used by the backing store.
998  */
999 QRect QPaintEngine::systemRect() const
1000 {
1001     return d_func()->systemRect;
1002 }
1003
1004 void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt &ti)
1005 {
1006     if (!ti.glyphs.numGlyphs)
1007         return;
1008
1009     // any fixes here should probably also be done in QFontEngineBox::draw
1010     const int size = qRound(ti.fontEngine->ascent());
1011     QVarLengthArray<QFixedPoint> positions;
1012     QVarLengthArray<glyph_t> glyphs;
1013     QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - size);
1014     ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
1015     if (glyphs.size() == 0)
1016         return;
1017
1018     QSize s(size - 3, size - 3);
1019
1020     QPainter *painter = q_func()->state->painter();
1021     painter->save();
1022     painter->setBrush(Qt::NoBrush);
1023     QPen pen = painter->pen();
1024     pen.setWidthF(ti.fontEngine->lineThickness().toReal());
1025     painter->setPen(pen);
1026     for (int k = 0; k < positions.size(); k++)
1027         painter->drawRect(QRectF(positions[k].toPointF(), s));
1028     painter->restore();
1029 }
1030
1031 QT_END_NAMESPACE