| [2] | 1 | /****************************************************************************
 | 
|---|
 | 2 | **
 | 
|---|
| [846] | 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 | 
|---|
| [561] | 4 | ** All rights reserved.
 | 
|---|
 | 5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
 | 
|---|
| [2] | 6 | **
 | 
|---|
 | 7 | ** This file is part of the QtGui module of the Qt Toolkit.
 | 
|---|
 | 8 | **
 | 
|---|
 | 9 | ** $QT_BEGIN_LICENSE:LGPL$
 | 
|---|
 | 10 | ** Commercial Usage
 | 
|---|
 | 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
 | 
|---|
 | 12 | ** accordance with the Qt Commercial License Agreement provided with the
 | 
|---|
 | 13 | ** Software or, alternatively, in accordance with the terms contained in
 | 
|---|
 | 14 | ** a written agreement between you and Nokia.
 | 
|---|
 | 15 | **
 | 
|---|
 | 16 | ** GNU Lesser General Public License Usage
 | 
|---|
 | 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
 | 
|---|
 | 18 | ** General Public License version 2.1 as published by the Free Software
 | 
|---|
 | 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
 | 
|---|
 | 20 | ** packaging of this file.  Please review the following information to
 | 
|---|
 | 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
 | 
|---|
 | 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
|---|
 | 23 | **
 | 
|---|
| [561] | 24 | ** In addition, as a special exception, Nokia gives you certain additional
 | 
|---|
 | 25 | ** rights.  These rights are described in the Nokia Qt LGPL Exception
 | 
|---|
 | 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 | 
|---|
| [2] | 27 | **
 | 
|---|
 | 28 | ** GNU General Public License Usage
 | 
|---|
 | 29 | ** Alternatively, this file may be used under the terms of the GNU
 | 
|---|
 | 30 | ** General Public License version 3.0 as published by the Free Software
 | 
|---|
 | 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
 | 
|---|
 | 32 | ** packaging of this file.  Please review the following information to
 | 
|---|
 | 33 | ** ensure the GNU General Public License version 3.0 requirements will be
 | 
|---|
 | 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
 | 
|---|
 | 35 | **
 | 
|---|
| [561] | 36 | ** If you have questions regarding the use of this file, please contact
 | 
|---|
 | 37 | ** Nokia at qt-info@nokia.com.
 | 
|---|
| [2] | 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>
 | 
|---|
| [561] | 52 | #include <private/qpaintengineex_p.h>
 | 
|---|
| [2] | 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
 | 
|---|
| [561] | 148 |   \ingroup painting
 | 
|---|
| [2] | 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 | 
 | 
|---|
| [846] | 175 |   \sa QPainter, QPaintDevice::paintEngine(), {Paint System}
 | 
|---|
| [2] | 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);
 | 
|---|
| [561] | 306 | 
 | 
|---|
 | 307 |     if (isExtended())
 | 
|---|
 | 308 |         static_cast<QPaintEngineEx *>(this)->sync();
 | 
|---|
| [2] | 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
 | 
|---|
| [561] | 388 |     \value OpenGL2
 | 
|---|
 | 389 |     \value PaintBuffer
 | 
|---|
| [2] | 390 | */
 | 
|---|
 | 391 | 
 | 
|---|
 | 392 | /*!
 | 
|---|
 | 393 |     \fn bool QPaintEngine::isActive() const
 | 
|---|
 | 394 | 
 | 
|---|
 | 395 |     Returns true if the paint engine is actively drawing; otherwise
 | 
|---|
 | 396 |     returns false.
 | 
|---|
 | 397 | 
 | 
|---|
 | 398 |     \sa setActive()
 | 
|---|
 | 399 | */
 | 
|---|
 | 400 | 
 | 
|---|
 | 401 | /*!
 | 
|---|
 | 402 |     \fn void QPaintEngine::setActive(bool state)
 | 
|---|
 | 403 | 
 | 
|---|
 | 404 |     Sets the active state of the paint engine to \a state.
 | 
|---|
 | 405 | 
 | 
|---|
 | 406 |     \sa isActive()
 | 
|---|
 | 407 | */
 | 
|---|
 | 408 | 
 | 
|---|
 | 409 | /*!
 | 
|---|
 | 410 |     \fn bool QPaintEngine::begin(QPaintDevice *pdev)
 | 
|---|
 | 411 | 
 | 
|---|
 | 412 |     Reimplement this function to initialise your paint engine when
 | 
|---|
 | 413 |     painting is to start on the paint device \a pdev. Return true if
 | 
|---|
 | 414 |     the initialization was successful; otherwise return false.
 | 
|---|
 | 415 | 
 | 
|---|
 | 416 |     \sa end() isActive()
 | 
|---|
 | 417 | */
 | 
|---|
 | 418 | 
 | 
|---|
 | 419 | /*!
 | 
|---|
 | 420 |     \fn bool QPaintEngine::end()
 | 
|---|
 | 421 | 
 | 
|---|
 | 422 |     Reimplement this function to finish painting on the current paint
 | 
|---|
 | 423 |     device. Return true if painting was finished successfully;
 | 
|---|
 | 424 |     otherwise return false.
 | 
|---|
 | 425 | 
 | 
|---|
 | 426 |     \sa begin() isActive()
 | 
|---|
 | 427 | */
 | 
|---|
 | 428 | 
 | 
|---|
 | 429 | 
 | 
|---|
 | 430 | /*!
 | 
|---|
 | 431 |     Draws the first \a pointCount points in the buffer \a points
 | 
|---|
 | 432 | */
 | 
|---|
 | 433 | void QPaintEngine::drawPoints(const QPointF *points, int pointCount)
 | 
|---|
 | 434 | {
 | 
|---|
 | 435 |     QPainter *p = painter();
 | 
|---|
 | 436 |     if (!p)
 | 
|---|
 | 437 |         return;
 | 
|---|
 | 438 | 
 | 
|---|
 | 439 |     qreal penWidth = p->pen().widthF();
 | 
|---|
 | 440 |     if (penWidth == 0)
 | 
|---|
 | 441 |         penWidth = 1;
 | 
|---|
 | 442 | 
 | 
|---|
 | 443 |     bool ellipses = p->pen().capStyle() == Qt::RoundCap;
 | 
|---|
 | 444 | 
 | 
|---|
 | 445 |     p->save();
 | 
|---|
 | 446 | 
 | 
|---|
 | 447 |     QTransform transform;
 | 
|---|
 | 448 |     if (p->pen().isCosmetic()) {
 | 
|---|
 | 449 |         transform = p->transform();
 | 
|---|
 | 450 |         p->setTransform(QTransform());
 | 
|---|
 | 451 |     }
 | 
|---|
 | 452 | 
 | 
|---|
 | 453 |     p->setBrush(p->pen().brush());
 | 
|---|
 | 454 |     p->setPen(Qt::NoPen);
 | 
|---|
 | 455 | 
 | 
|---|
 | 456 |     for (int i=0; i<pointCount; ++i) {
 | 
|---|
 | 457 |         QPointF pos = transform.map(points[i]);
 | 
|---|
 | 458 |         QRectF rect(pos.x() - penWidth / 2, pos.y() - penWidth / 2, penWidth, penWidth);
 | 
|---|
 | 459 | 
 | 
|---|
 | 460 |         if (ellipses)
 | 
|---|
 | 461 |             p->drawEllipse(rect);
 | 
|---|
 | 462 |         else
 | 
|---|
 | 463 |             p->drawRect(rect);
 | 
|---|
 | 464 |     }
 | 
|---|
 | 465 | 
 | 
|---|
 | 466 |     p->restore();
 | 
|---|
 | 467 | }
 | 
|---|
 | 468 | 
 | 
|---|
 | 469 | 
 | 
|---|
 | 470 | /*!
 | 
|---|
 | 471 |     Draws the first \a pointCount points in the buffer \a points
 | 
|---|
 | 472 | 
 | 
|---|
 | 473 |     The default implementation converts the first \a pointCount QPoints in \a points
 | 
|---|
 | 474 |     to QPointFs and calls the floating point version of drawPoints.
 | 
|---|
 | 475 | 
 | 
|---|
 | 476 | */
 | 
|---|
 | 477 | void QPaintEngine::drawPoints(const QPoint *points, int pointCount)
 | 
|---|
 | 478 | {
 | 
|---|
 | 479 |     Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
 | 
|---|
 | 480 |     QT_PointF fp[256];
 | 
|---|
 | 481 |     while (pointCount) {
 | 
|---|
 | 482 |         int i = 0;
 | 
|---|
 | 483 |         while (i < pointCount && i < 256) {
 | 
|---|
 | 484 |             fp[i].x = points[i].x();
 | 
|---|
 | 485 |             fp[i].y = points[i].y();
 | 
|---|
 | 486 |             ++i;
 | 
|---|
 | 487 |         }
 | 
|---|
 | 488 |         drawPoints((QPointF *)(void *)fp, i);
 | 
|---|
 | 489 |         points += i;
 | 
|---|
 | 490 |         pointCount -= i;
 | 
|---|
 | 491 |     }
 | 
|---|
 | 492 | }
 | 
|---|
 | 493 | 
 | 
|---|
 | 494 | /*!
 | 
|---|
 | 495 |     \fn void QPaintEngine::drawEllipse(const QRectF &rect)
 | 
|---|
 | 496 | 
 | 
|---|
 | 497 |     Reimplement this function to draw the largest ellipse that can be
 | 
|---|
 | 498 |     contained within rectangle \a rect.
 | 
|---|
 | 499 | 
 | 
|---|
 | 500 |     The default implementation calls drawPolygon().
 | 
|---|
 | 501 | */
 | 
|---|
 | 502 | void QPaintEngine::drawEllipse(const QRectF &rect)
 | 
|---|
 | 503 | {
 | 
|---|
 | 504 |     QPainterPath path;
 | 
|---|
 | 505 |     path.addEllipse(rect);
 | 
|---|
 | 506 |     if (hasFeature(PainterPaths)) {
 | 
|---|
 | 507 |         drawPath(path);
 | 
|---|
 | 508 |     } else {
 | 
|---|
 | 509 |         QPolygonF polygon = path.toFillPolygon();
 | 
|---|
 | 510 |         drawPolygon(polygon.data(), polygon.size(), ConvexMode);
 | 
|---|
 | 511 |     }
 | 
|---|
 | 512 | }
 | 
|---|
 | 513 | 
 | 
|---|
 | 514 | /*!
 | 
|---|
 | 515 |     The default implementation of this function calls the floating
 | 
|---|
 | 516 |     point version of this function
 | 
|---|
 | 517 | */
 | 
|---|
 | 518 | void QPaintEngine::drawEllipse(const QRect &rect)
 | 
|---|
 | 519 | {
 | 
|---|
 | 520 |     drawEllipse(QRectF(rect));
 | 
|---|
 | 521 | }
 | 
|---|
 | 522 | 
 | 
|---|
 | 523 | /*!
 | 
|---|
 | 524 |     \fn void QPaintEngine::drawPixmap(const QRectF &r, const QPixmap
 | 
|---|
 | 525 |     &pm, const QRectF &sr)
 | 
|---|
 | 526 | 
 | 
|---|
 | 527 |     Reimplement this function to draw the part of the \a pm
 | 
|---|
 | 528 |     specified by the \a sr rectangle in the given \a r.
 | 
|---|
 | 529 | */
 | 
|---|
 | 530 | 
 | 
|---|
 | 531 | 
 | 
|---|
 | 532 | void qt_fill_tile(QPixmap *tile, const QPixmap &pixmap)
 | 
|---|
 | 533 | {
 | 
|---|
 | 534 |     QPainter p(tile);
 | 
|---|
 | 535 |     p.drawPixmap(0, 0, pixmap);
 | 
|---|
 | 536 |     int x = pixmap.width();
 | 
|---|
 | 537 |     while (x < tile->width()) {
 | 
|---|
 | 538 |         p.drawPixmap(x, 0, *tile, 0, 0, x, pixmap.height());
 | 
|---|
 | 539 |         x *= 2;
 | 
|---|
 | 540 |     }
 | 
|---|
 | 541 |     int y = pixmap.height();
 | 
|---|
 | 542 |     while (y < tile->height()) {
 | 
|---|
 | 543 |         p.drawPixmap(0, y, *tile, 0, 0, tile->width(), y);
 | 
|---|
 | 544 |         y *= 2;
 | 
|---|
 | 545 |     }
 | 
|---|
 | 546 | }
 | 
|---|
 | 547 | 
 | 
|---|
 | 548 | void qt_draw_tile(QPaintEngine *gc, qreal x, qreal y, qreal w, qreal h,
 | 
|---|
 | 549 |                   const QPixmap &pixmap, qreal xOffset, qreal yOffset)
 | 
|---|
 | 550 | {
 | 
|---|
 | 551 |     qreal yPos, xPos, drawH, drawW, yOff, xOff;
 | 
|---|
 | 552 |     yPos = y;
 | 
|---|
 | 553 |     yOff = yOffset;
 | 
|---|
 | 554 |     while(yPos < y + h) {
 | 
|---|
 | 555 |         drawH = pixmap.height() - yOff;    // Cropping first row
 | 
|---|
 | 556 |         if (yPos + drawH > y + h)           // Cropping last row
 | 
|---|
 | 557 |             drawH = y + h - yPos;
 | 
|---|
 | 558 |         xPos = x;
 | 
|---|
 | 559 |         xOff = xOffset;
 | 
|---|
 | 560 |         while(xPos < x + w) {
 | 
|---|
 | 561 |             drawW = pixmap.width() - xOff; // Cropping first column
 | 
|---|
 | 562 |             if (xPos + drawW > x + w)           // Cropping last column
 | 
|---|
 | 563 |                 drawW = x + w - xPos;
 | 
|---|
 | 564 |             if (drawW > 0 && drawH > 0)
 | 
|---|
 | 565 |                 gc->drawPixmap(QRectF(xPos, yPos, drawW, drawH), pixmap, QRectF(xOff, yOff, drawW, drawH));
 | 
|---|
 | 566 |             xPos += drawW;
 | 
|---|
 | 567 |             xOff = 0;
 | 
|---|
 | 568 |         }
 | 
|---|
 | 569 |         yPos += drawH;
 | 
|---|
 | 570 |         yOff = 0;
 | 
|---|
 | 571 |     }
 | 
|---|
 | 572 | }
 | 
|---|
 | 573 | 
 | 
|---|
 | 574 | 
 | 
|---|
 | 575 | /*!
 | 
|---|
 | 576 |     Reimplement this function to draw the \a pixmap in the given \a
 | 
|---|
 | 577 |     rect, starting at the given \a p. The pixmap will be
 | 
|---|
 | 578 |     drawn repeatedly until the \a rect is filled.
 | 
|---|
 | 579 | */
 | 
|---|
 | 580 | void QPaintEngine::drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p)
 | 
|---|
 | 581 | {
 | 
|---|
 | 582 |     int sw = pixmap.width();
 | 
|---|
 | 583 |     int sh = pixmap.height();
 | 
|---|
 | 584 | 
 | 
|---|
 | 585 |     if (sw*sh < 8192 && sw*sh < 16*rect.width()*rect.height()) {
 | 
|---|
 | 586 |         int tw = sw, th = sh;
 | 
|---|
 | 587 |         while (tw*th < 32678 && tw < rect.width()/2)
 | 
|---|
 | 588 |             tw *= 2;
 | 
|---|
 | 589 |         while (tw*th < 32678 && th < rect.height()/2)
 | 
|---|
 | 590 |             th *= 2;
 | 
|---|
 | 591 |         QPixmap tile;
 | 
|---|
 | 592 |         if (pixmap.depth() == 1) {
 | 
|---|
 | 593 |             tile = QBitmap(tw, th);
 | 
|---|
 | 594 |         } else {
 | 
|---|
 | 595 |             tile = QPixmap(tw, th);
 | 
|---|
 | 596 |             if (pixmap.hasAlphaChannel())
 | 
|---|
 | 597 |                 tile.fill(Qt::transparent);
 | 
|---|
 | 598 |         }
 | 
|---|
 | 599 |         qt_fill_tile(&tile, pixmap);
 | 
|---|
 | 600 |         qt_draw_tile(this, rect.x(), rect.y(), rect.width(), rect.height(), tile, p.x(), p.y());
 | 
|---|
 | 601 |     } else {
 | 
|---|
 | 602 |         qt_draw_tile(this, rect.x(), rect.y(), rect.width(), rect.height(), pixmap, p.x(), p.y());
 | 
|---|
 | 603 |     }
 | 
|---|
 | 604 | }
 | 
|---|
 | 605 | 
 | 
|---|
 | 606 | /*!
 | 
|---|
 | 607 |     \fn void QPaintEngine::drawImage(const QRectF &rectangle, const QImage
 | 
|---|
 | 608 |     &image, const QRectF &sr, Qt::ImageConversionFlags flags)
 | 
|---|
 | 609 | 
 | 
|---|
 | 610 |     Reimplement this function to draw the part of the \a image
 | 
|---|
 | 611 |     specified by the \a sr rectangle in the given \a rectangle using
 | 
|---|
 | 612 |     the given conversion flags \a flags, to convert it to a pixmap.
 | 
|---|
 | 613 | */
 | 
|---|
 | 614 | 
 | 
|---|
 | 615 | void QPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
 | 
|---|
 | 616 |                              Qt::ImageConversionFlags flags)
 | 
|---|
 | 617 | {
 | 
|---|
 | 618 |     QRectF baseSize(0, 0, image.width(), image.height());
 | 
|---|
 | 619 |     QImage im = image;
 | 
|---|
 | 620 |     if (baseSize != sr)
 | 
|---|
 | 621 |         im = im.copy(qFloor(sr.x()), qFloor(sr.y()),
 | 
|---|
 | 622 |                      qCeil(sr.width()), qCeil(sr.height()));
 | 
|---|
 | 623 |     QPixmap pm = QPixmap::fromImage(im, flags);
 | 
|---|
 | 624 |     drawPixmap(r, pm, QRectF(QPointF(0, 0), pm.size()));
 | 
|---|
 | 625 | }
 | 
|---|
 | 626 | 
 | 
|---|
 | 627 | /*!
 | 
|---|
 | 628 |     \fn Type QPaintEngine::type() const
 | 
|---|
 | 629 | 
 | 
|---|
 | 630 |     Reimplement this function to return the paint engine \l{Type}.
 | 
|---|
 | 631 | */
 | 
|---|
 | 632 | 
 | 
|---|
 | 633 | /*!
 | 
|---|
 | 634 |     \fn void QPaintEngine::fix_neg_rect(int *x, int *y, int *w, int *h);
 | 
|---|
 | 635 | 
 | 
|---|
 | 636 |     \internal
 | 
|---|
 | 637 | */
 | 
|---|
 | 638 | 
 | 
|---|
 | 639 | /*!
 | 
|---|
 | 640 |     \fn bool QPaintEngine::testDirty(DirtyFlags df)
 | 
|---|
 | 641 | 
 | 
|---|
 | 642 |     \internal
 | 
|---|
 | 643 | */
 | 
|---|
 | 644 | 
 | 
|---|
 | 645 | /*!
 | 
|---|
 | 646 |     \fn void QPaintEngine::clearDirty(DirtyFlags df)
 | 
|---|
 | 647 | 
 | 
|---|
 | 648 |     \internal
 | 
|---|
 | 649 | */
 | 
|---|
 | 650 | 
 | 
|---|
 | 651 | /*!
 | 
|---|
 | 652 |     \fn void QPaintEngine::setDirty(DirtyFlags df)
 | 
|---|
 | 653 | 
 | 
|---|
 | 654 |     \internal
 | 
|---|
 | 655 | */
 | 
|---|
 | 656 | 
 | 
|---|
 | 657 | /*!
 | 
|---|
 | 658 |     \fn bool QPaintEngine::hasFeature(PaintEngineFeatures feature) const
 | 
|---|
 | 659 | 
 | 
|---|
 | 660 |     Returns true if the paint engine supports the specified \a
 | 
|---|
 | 661 |     feature; otherwise returns false.
 | 
|---|
 | 662 | */
 | 
|---|
 | 663 | 
 | 
|---|
 | 664 | /*!
 | 
|---|
 | 665 |     \fn bool QPaintEngine::isExtended() const
 | 
|---|
 | 666 | 
 | 
|---|
 | 667 |     \internal
 | 
|---|
 | 668 | 
 | 
|---|
 | 669 |     Returns true if the paint engine is a QPaintEngineEx derivative.
 | 
|---|
 | 670 | */
 | 
|---|
 | 671 | 
 | 
|---|
 | 672 | /*!
 | 
|---|
 | 673 |     \fn void QPaintEngine::updateState(const QPaintEngineState &state)
 | 
|---|
 | 674 | 
 | 
|---|
 | 675 |     Reimplement this function to update the state of a paint engine.
 | 
|---|
 | 676 | 
 | 
|---|
 | 677 |     When implemented, this function is responsible for checking the
 | 
|---|
 | 678 |     paint engine's current \a state and update the properties that are
 | 
|---|
 | 679 |     changed. Use the QPaintEngineState::state() function to find out
 | 
|---|
 | 680 |     which properties that must be updated, then use the corresponding
 | 
|---|
 | 681 |     \l {GetFunction}{get function} to retrieve the current values for
 | 
|---|
 | 682 |     the given properties.
 | 
|---|
 | 683 | 
 | 
|---|
 | 684 |     \sa QPaintEngineState
 | 
|---|
 | 685 | */
 | 
|---|
 | 686 | 
 | 
|---|
 | 687 | /*!
 | 
|---|
 | 688 |     Creates a paint engine with the featureset specified by \a caps.
 | 
|---|
 | 689 | */
 | 
|---|
 | 690 | 
 | 
|---|
 | 691 | QPaintEngine::QPaintEngine(PaintEngineFeatures caps)
 | 
|---|
 | 692 |     : state(0),
 | 
|---|
 | 693 |       gccaps(caps),
 | 
|---|
 | 694 |       active(0),
 | 
|---|
 | 695 |       selfDestruct(false),
 | 
|---|
 | 696 |       extended(false),
 | 
|---|
 | 697 |       d_ptr(new QPaintEnginePrivate)
 | 
|---|
 | 698 | {
 | 
|---|
 | 699 |     d_ptr->q_ptr = this;
 | 
|---|
 | 700 | }
 | 
|---|
 | 701 | 
 | 
|---|
 | 702 | /*!
 | 
|---|
 | 703 |   \internal
 | 
|---|
 | 704 | */
 | 
|---|
 | 705 | 
 | 
|---|
 | 706 | QPaintEngine::QPaintEngine(QPaintEnginePrivate &dptr, PaintEngineFeatures caps)
 | 
|---|
 | 707 |     : state(0),
 | 
|---|
 | 708 |       gccaps(caps),
 | 
|---|
 | 709 |       active(0),
 | 
|---|
 | 710 |       selfDestruct(false),
 | 
|---|
 | 711 |       extended(false),
 | 
|---|
 | 712 |       d_ptr(&dptr)
 | 
|---|
 | 713 | {
 | 
|---|
 | 714 |     d_ptr->q_ptr = this;
 | 
|---|
 | 715 | }
 | 
|---|
 | 716 | 
 | 
|---|
 | 717 | /*!
 | 
|---|
 | 718 |     Destroys the paint engine.
 | 
|---|
 | 719 | */
 | 
|---|
 | 720 | QPaintEngine::~QPaintEngine()
 | 
|---|
 | 721 | {
 | 
|---|
 | 722 | }
 | 
|---|
 | 723 | 
 | 
|---|
 | 724 | /*!
 | 
|---|
 | 725 |     Returns the paint engine's painter.
 | 
|---|
 | 726 | */
 | 
|---|
 | 727 | QPainter *QPaintEngine::painter() const
 | 
|---|
 | 728 | {
 | 
|---|
 | 729 |     return state ? state->painter() : 0;
 | 
|---|
 | 730 | }
 | 
|---|
 | 731 | 
 | 
|---|
 | 732 | /*!
 | 
|---|
 | 733 |     The default implementation ignores the \a path and does nothing.
 | 
|---|
 | 734 | */
 | 
|---|
 | 735 | 
 | 
|---|
 | 736 | void QPaintEngine::drawPath(const QPainterPath &)
 | 
|---|
 | 737 | {
 | 
|---|
 | 738 |     if (hasFeature(PainterPaths)) {
 | 
|---|
 | 739 |         qWarning("QPaintEngine::drawPath: Must be implemented when feature PainterPaths is set");
 | 
|---|
 | 740 |     }
 | 
|---|
 | 741 | }
 | 
|---|
 | 742 | 
 | 
|---|
 | 743 | /*!
 | 
|---|
 | 744 |     This function draws the text item \a textItem at position \a p. The
 | 
|---|
 | 745 |     default implementation of this function converts the text to a
 | 
|---|
 | 746 |     QPainterPath and paints the resulting path.
 | 
|---|
 | 747 | */
 | 
|---|
 | 748 | 
 | 
|---|
 | 749 | void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
 | 
|---|
 | 750 | {
 | 
|---|
 | 751 |     const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
 | 
|---|
 | 752 | 
 | 
|---|
 | 753 |     QPainterPath path;
 | 
|---|
 | 754 | #ifndef Q_WS_MAC
 | 
|---|
 | 755 |     path.setFillRule(Qt::WindingFill);
 | 
|---|
 | 756 | #endif
 | 
|---|
 | 757 |     if (ti.glyphs.numGlyphs)
 | 
|---|
 | 758 |         ti.fontEngine->addOutlineToPath(p.x(), p.y(), ti.glyphs, &path, ti.flags);
 | 
|---|
 | 759 |     if (!path.isEmpty()) {
 | 
|---|
 | 760 |         bool oldAA = painter()->renderHints() & QPainter::Antialiasing;
 | 
|---|
 | 761 |         painter()->setRenderHint(QPainter::Antialiasing,
 | 
|---|
 | 762 |                                  bool((painter()->renderHints() & QPainter::TextAntialiasing)
 | 
|---|
 | 763 |                                       && !(painter()->font().styleStrategy() & QFont::NoAntialias)));
 | 
|---|
 | 764 |         painter()->fillPath(path, state->pen().brush());
 | 
|---|
 | 765 |         painter()->setRenderHint(QPainter::Antialiasing, oldAA);
 | 
|---|
 | 766 |     }
 | 
|---|
 | 767 | }
 | 
|---|
 | 768 | 
 | 
|---|
 | 769 | /*!
 | 
|---|
 | 770 |     The default implementation splits the list of lines in \a lines
 | 
|---|
 | 771 |     into \a lineCount separate calls to drawPath() or drawPolygon()
 | 
|---|
 | 772 |     depending on the feature set of the paint engine.
 | 
|---|
 | 773 | */
 | 
|---|
 | 774 | void QPaintEngine::drawLines(const QLineF *lines, int lineCount)
 | 
|---|
 | 775 | {
 | 
|---|
 | 776 |     for (int i=0; i<lineCount; ++i) {
 | 
|---|
 | 777 |         QPointF pts[2] = { lines[i].p1(), lines[i].p2() };
 | 
|---|
 | 778 | 
 | 
|---|
 | 779 |         if (pts[0] == pts[1]) {
 | 
|---|
 | 780 |             if (state->pen().capStyle() != Qt::FlatCap)
 | 
|---|
 | 781 |                 drawPoints(pts, 1);
 | 
|---|
 | 782 |             continue;
 | 
|---|
 | 783 |         }
 | 
|---|
 | 784 | 
 | 
|---|
 | 785 |         drawPolygon(pts, 2, PolylineMode);
 | 
|---|
 | 786 |     }
 | 
|---|
 | 787 | }
 | 
|---|
 | 788 | 
 | 
|---|
 | 789 | /*!
 | 
|---|
 | 790 |     \overload
 | 
|---|
 | 791 | 
 | 
|---|
 | 792 |     The default implementation converts the first \a lineCount lines
 | 
|---|
 | 793 |     in \a lines to a QLineF and calls the floating point version of
 | 
|---|
 | 794 |     this function.
 | 
|---|
 | 795 | */
 | 
|---|
 | 796 | void QPaintEngine::drawLines(const QLine *lines, int lineCount)
 | 
|---|
 | 797 | {
 | 
|---|
 | 798 |     struct PointF {
 | 
|---|
 | 799 |         qreal x;
 | 
|---|
 | 800 |         qreal y;
 | 
|---|
 | 801 |     };
 | 
|---|
 | 802 |     struct LineF {
 | 
|---|
 | 803 |         PointF p1;
 | 
|---|
 | 804 |         PointF p2;
 | 
|---|
 | 805 |     };
 | 
|---|
 | 806 |     Q_ASSERT(sizeof(PointF) == sizeof(QPointF));
 | 
|---|
 | 807 |     Q_ASSERT(sizeof(LineF) == sizeof(QLineF));
 | 
|---|
 | 808 |     LineF fl[256];
 | 
|---|
 | 809 |     while (lineCount) {
 | 
|---|
 | 810 |         int i = 0;
 | 
|---|
 | 811 |         while (i < lineCount && i < 256) {
 | 
|---|
 | 812 |             fl[i].p1.x = lines[i].x1();
 | 
|---|
 | 813 |             fl[i].p1.y = lines[i].y1();
 | 
|---|
 | 814 |             fl[i].p2.x = lines[i].x2();
 | 
|---|
 | 815 |             fl[i].p2.y = lines[i].y2();
 | 
|---|
 | 816 |             ++i;
 | 
|---|
 | 817 |         }
 | 
|---|
 | 818 |         drawLines((QLineF *)(void *)fl, i);
 | 
|---|
 | 819 |         lines += i;
 | 
|---|
 | 820 |         lineCount -= i;
 | 
|---|
 | 821 |     }
 | 
|---|
 | 822 | }
 | 
|---|
 | 823 | 
 | 
|---|
 | 824 | 
 | 
|---|
 | 825 | /*!
 | 
|---|
 | 826 |     \overload
 | 
|---|
 | 827 | 
 | 
|---|
 | 828 |     The default implementation converts the first \a rectCount
 | 
|---|
 | 829 |     rectangles in the buffer \a rects to a QRectF and calls the
 | 
|---|
 | 830 |     floating point version of this function.
 | 
|---|
 | 831 | */
 | 
|---|
 | 832 | void QPaintEngine::drawRects(const QRect *rects, int rectCount)
 | 
|---|
 | 833 | {
 | 
|---|
 | 834 |     struct RectF {
 | 
|---|
 | 835 |         qreal x;
 | 
|---|
 | 836 |         qreal y;
 | 
|---|
 | 837 |         qreal w;
 | 
|---|
 | 838 |         qreal h;
 | 
|---|
 | 839 |     };
 | 
|---|
 | 840 |     Q_ASSERT(sizeof(RectF) == sizeof(QRectF));
 | 
|---|
 | 841 |     RectF fr[256];
 | 
|---|
 | 842 |     while (rectCount) {
 | 
|---|
 | 843 |         int i = 0;
 | 
|---|
 | 844 |         while (i < rectCount && i < 256) {
 | 
|---|
 | 845 |             fr[i].x = rects[i].x();
 | 
|---|
 | 846 |             fr[i].y = rects[i].y();
 | 
|---|
 | 847 |             fr[i].w = rects[i].width();
 | 
|---|
 | 848 |             fr[i].h = rects[i].height();
 | 
|---|
 | 849 |             ++i;
 | 
|---|
 | 850 |         }
 | 
|---|
 | 851 |         drawRects((QRectF *)(void *)fr, i);
 | 
|---|
 | 852 |         rects += i;
 | 
|---|
 | 853 |         rectCount -= i;
 | 
|---|
 | 854 |     }
 | 
|---|
 | 855 | }
 | 
|---|
 | 856 | 
 | 
|---|
 | 857 | /*!
 | 
|---|
 | 858 |     Draws the first \a rectCount rectangles in the buffer \a
 | 
|---|
 | 859 |     rects. The default implementation of this function calls drawPath()
 | 
|---|
 | 860 |     or drawPolygon() depending on the feature set of the paint engine.
 | 
|---|
 | 861 | */
 | 
|---|
 | 862 | void QPaintEngine::drawRects(const QRectF *rects, int rectCount)
 | 
|---|
 | 863 | {
 | 
|---|
 | 864 |     if (hasFeature(PainterPaths) &&
 | 
|---|
 | 865 |         !state->penNeedsResolving() &&
 | 
|---|
 | 866 |         !state->brushNeedsResolving()) {
 | 
|---|
 | 867 |         for (int i=0; i<rectCount; ++i) {
 | 
|---|
 | 868 |             QPainterPath path;
 | 
|---|
 | 869 |             path.addRect(rects[i]);
 | 
|---|
 | 870 |             if (path.isEmpty())
 | 
|---|
 | 871 |                 continue;
 | 
|---|
 | 872 |             drawPath(path);
 | 
|---|
 | 873 |         }
 | 
|---|
 | 874 |     } else {
 | 
|---|
 | 875 |         for (int i=0; i<rectCount; ++i) {
 | 
|---|
 | 876 |             QRectF rf = rects[i];
 | 
|---|
 | 877 |             QPointF pts[4] = { QPointF(rf.x(), rf.y()),
 | 
|---|
 | 878 |                                QPointF(rf.x() + rf.width(), rf.y()),
 | 
|---|
 | 879 |                                QPointF(rf.x() + rf.width(), rf.y() + rf.height()),
 | 
|---|
 | 880 |                                QPointF(rf.x(), rf.y() + rf.height()) };
 | 
|---|
 | 881 |             drawPolygon(pts, 4, ConvexMode);
 | 
|---|
 | 882 |         }
 | 
|---|
 | 883 |     }
 | 
|---|
 | 884 | }
 | 
|---|
 | 885 | 
 | 
|---|
 | 886 | /*!
 | 
|---|
 | 887 |     \internal
 | 
|---|
 | 888 |     Sets the paintdevice that this engine operates on to \a device
 | 
|---|
 | 889 | */
 | 
|---|
 | 890 | void QPaintEngine::setPaintDevice(QPaintDevice *device)
 | 
|---|
 | 891 | {
 | 
|---|
 | 892 |     d_func()->pdev = device;
 | 
|---|
 | 893 | }
 | 
|---|
 | 894 | 
 | 
|---|
 | 895 | /*!
 | 
|---|
 | 896 |     Returns the device that this engine is painting on, if painting is
 | 
|---|
 | 897 |     active; otherwise returns 0.
 | 
|---|
 | 898 | */
 | 
|---|
 | 899 | QPaintDevice *QPaintEngine::paintDevice() const
 | 
|---|
 | 900 | {
 | 
|---|
 | 901 |     return d_func()->pdev;
 | 
|---|
 | 902 | }
 | 
|---|
 | 903 | 
 | 
|---|
 | 904 | #ifdef Q_WS_WIN
 | 
|---|
 | 905 | /*!
 | 
|---|
 | 906 |     \internal
 | 
|---|
 | 907 | 
 | 
|---|
 | 908 |     Empty default implementation.
 | 
|---|
 | 909 | */
 | 
|---|
 | 910 | 
 | 
|---|
 | 911 | HDC QPaintEngine::getDC() const
 | 
|---|
 | 912 | {
 | 
|---|
 | 913 |     return 0;
 | 
|---|
 | 914 | }
 | 
|---|
 | 915 | 
 | 
|---|
 | 916 | 
 | 
|---|
 | 917 | /*!
 | 
|---|
 | 918 |     \internal
 | 
|---|
 | 919 | 
 | 
|---|
 | 920 |     Empty default implementation.
 | 
|---|
 | 921 | */
 | 
|---|
 | 922 | 
 | 
|---|
 | 923 | void QPaintEngine::releaseDC(HDC) const
 | 
|---|
 | 924 | {
 | 
|---|
 | 925 | }
 | 
|---|
 | 926 | 
 | 
|---|
 | 927 | #endif
 | 
|---|
 | 928 | 
 | 
|---|
 | 929 | /*!
 | 
|---|
 | 930 |     \internal
 | 
|---|
 | 931 | 
 | 
|---|
 | 932 |     Returns the offset from the painters origo to the engines
 | 
|---|
 | 933 |     origo. This value is used by QPainter for engines who have
 | 
|---|
 | 934 |     internal double buffering.
 | 
|---|
 | 935 | 
 | 
|---|
 | 936 |     This function only makes sense when the engine is active.
 | 
|---|
 | 937 | */
 | 
|---|
 | 938 | QPoint QPaintEngine::coordinateOffset() const
 | 
|---|
 | 939 | {
 | 
|---|
 | 940 |     return QPoint();
 | 
|---|
 | 941 | }
 | 
|---|
 | 942 | 
 | 
|---|
 | 943 | /*!
 | 
|---|
 | 944 |     \internal
 | 
|---|
 | 945 | 
 | 
|---|
 | 946 |     Sets the system clip for this engine. The system clip defines the
 | 
|---|
 | 947 |     basis area that the engine has to draw in. All clips that are
 | 
|---|
 | 948 |     set will be be an intersection with the system clip.
 | 
|---|
 | 949 | 
 | 
|---|
 | 950 |     Reset the systemclip to no clip by setting an empty region.
 | 
|---|
 | 951 | */
 | 
|---|
 | 952 | void QPaintEngine::setSystemClip(const QRegion ®ion)
 | 
|---|
 | 953 | {
 | 
|---|
 | 954 |     Q_D(QPaintEngine);
 | 
|---|
 | 955 |     d->systemClip = region;
 | 
|---|
 | 956 |     // Be backward compatible and only call d->systemStateChanged()
 | 
|---|
| [561] | 957 |     // if we currently have a system transform/viewport set.
 | 
|---|
 | 958 |     if (d->hasSystemTransform || d->hasSystemViewport) {
 | 
|---|
| [2] | 959 |         d->transformSystemClip();
 | 
|---|
 | 960 |         d->systemStateChanged();
 | 
|---|
 | 961 |     }
 | 
|---|
 | 962 | }
 | 
|---|
 | 963 | 
 | 
|---|
 | 964 | /*!
 | 
|---|
 | 965 |     \internal
 | 
|---|
 | 966 | 
 | 
|---|
 | 967 |     Returns the system clip. The system clip is read only while the
 | 
|---|
 | 968 |     painter is active. An empty region indicates that system clip
 | 
|---|
 | 969 |     is not in use.
 | 
|---|
 | 970 | */
 | 
|---|
 | 971 | 
 | 
|---|
 | 972 | QRegion QPaintEngine::systemClip() const
 | 
|---|
 | 973 | {
 | 
|---|
 | 974 |     return d_func()->systemClip;
 | 
|---|
 | 975 | }
 | 
|---|
 | 976 | 
 | 
|---|
 | 977 | /*!
 | 
|---|
 | 978 |     \internal
 | 
|---|
 | 979 | 
 | 
|---|
 | 980 |     Sets the target rect for drawing within the backing store. This
 | 
|---|
 | 981 |     function should ONLY be used by the backing store.
 | 
|---|
 | 982 | */
 | 
|---|
 | 983 | void QPaintEngine::setSystemRect(const QRect &rect)
 | 
|---|
 | 984 | {
 | 
|---|
 | 985 |     if (isActive()) {
 | 
|---|
 | 986 |         qWarning("QPaintEngine::setSystemRect: Should not be changed while engine is active");
 | 
|---|
 | 987 |         return;
 | 
|---|
 | 988 |     }
 | 
|---|
 | 989 |     d_func()->systemRect = rect;
 | 
|---|
 | 990 | }
 | 
|---|
 | 991 | 
 | 
|---|
 | 992 | /*!
 | 
|---|
 | 993 |     \internal
 | 
|---|
 | 994 | 
 | 
|---|
| [846] | 995 |     Retrieves the rect for drawing within the backing store. This
 | 
|---|
| [2] | 996 |     function should ONLY be used by the backing store.
 | 
|---|
 | 997 |  */
 | 
|---|
 | 998 | QRect QPaintEngine::systemRect() const
 | 
|---|
 | 999 | {
 | 
|---|
 | 1000 |     return d_func()->systemRect;
 | 
|---|
 | 1001 | }
 | 
|---|
 | 1002 | 
 | 
|---|
 | 1003 | void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt &ti)
 | 
|---|
 | 1004 | {
 | 
|---|
 | 1005 |     if (!ti.glyphs.numGlyphs)
 | 
|---|
 | 1006 |         return;
 | 
|---|
 | 1007 | 
 | 
|---|
 | 1008 |     // any fixes here should probably also be done in QFontEngineBox::draw
 | 
|---|
 | 1009 |     const int size = qRound(ti.fontEngine->ascent());
 | 
|---|
 | 1010 |     QVarLengthArray<QFixedPoint> positions;
 | 
|---|
 | 1011 |     QVarLengthArray<glyph_t> glyphs;
 | 
|---|
| [561] | 1012 |     QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - size);
 | 
|---|
| [2] | 1013 |     ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
 | 
|---|
 | 1014 |     if (glyphs.size() == 0)
 | 
|---|
 | 1015 |         return;
 | 
|---|
 | 1016 | 
 | 
|---|
 | 1017 |     QSize s(size - 3, size - 3);
 | 
|---|
 | 1018 | 
 | 
|---|
 | 1019 |     QPainter *painter = q_func()->state->painter();
 | 
|---|
 | 1020 |     painter->save();
 | 
|---|
 | 1021 |     painter->setBrush(Qt::NoBrush);
 | 
|---|
 | 1022 |     QPen pen = painter->pen();
 | 
|---|
 | 1023 |     pen.setWidthF(ti.fontEngine->lineThickness().toReal());
 | 
|---|
 | 1024 |     painter->setPen(pen);
 | 
|---|
 | 1025 |     for (int k = 0; k < positions.size(); k++)
 | 
|---|
 | 1026 |         painter->drawRect(QRectF(positions[k].toPointF(), s));
 | 
|---|
 | 1027 |     painter->restore();
 | 
|---|
 | 1028 | }
 | 
|---|
 | 1029 | 
 | 
|---|
 | 1030 | QT_END_NAMESPACE
 | 
|---|