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