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