source: trunk/src/gui/painting/qpaintengine.cpp@ 938

Last change on this file since 938 was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 29.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
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**
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.
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**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41#include "qpaintengine.h"
42#include "qpaintengine_p.h"
43#include "qpainter_p.h"
44#include "qpolygon.h"
45#include "qbitmap.h"
46#include "qapplication.h"
47#include <qdebug.h>
48#include <qmath.h>
49#include <private/qtextengine_p.h>
50#include <qvarlengtharray.h>
51#include <private/qfontengine_p.h>
52#include <private/qpaintengineex_p.h>
53
54
55QT_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*/
84qreal 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*/
95qreal 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*/
106qreal 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*/
117QTextItem::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*/
128QString 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*/
139QFont QTextItem::font() const
140{
141 const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
142 return ti->f ? *ti->f : QApplication::font();
143}
144
145
146/*!
147 \class QPaintEngine
148 \ingroup painting
149
150 \brief The QPaintEngine class provides an abstract definition of how
151 QPainter draws to a given device on a given platform.
152
153 Qt 4.0 provides several premade implementations of QPaintEngine for the
154 different painter backends we support. We provide one paint engine for each
155 window system and painting framework we support. This includes X11 on
156 Unix/Linux and CoreGraphics on Mac OS X. In addition we provide QPaintEngine
157 implementations for OpenGL (accessible through QGLWidget) and PostScript
158 (accessible through QPSPrinter on X11). Additionally there is a raster-based
159 paint engine that is a fallback for when an engine does not support a certain
160 capability.
161
162 If one wants to use QPainter to draw to a different backend,
163 one must subclass QPaintEngine and reimplement all its virtual
164 functions. The QPaintEngine implementation is then made available by
165 subclassing QPaintDevice and reimplementing the virtual function
166 QPaintDevice::paintEngine().
167
168 QPaintEngine is created and owned by the QPaintDevice that created it.
169
170 The big advantage of the QPaintEngine approach opposed to
171 Qt 3's QPainter/QPaintDevice::cmd() approach is that it is now
172 possible to adapt to multiple technologies on each platform and take
173 advantage of each to the fullest.
174
175 \sa QPainter, QPaintDevice::paintEngine(), {Paint System}
176*/
177
178/*!
179 \enum QPaintEngine::PaintEngineFeature
180
181 This enum is used to describe the features or capabilities that the
182 paint engine has. If a feature is not supported by the engine,
183 QPainter will do a best effort to emulate that feature through other
184 means and pass on an alpha blended QImage to the engine with the
185 emulated results. Some features cannot be emulated: AlphaBlend and PorterDuff.
186
187 \value AlphaBlend The engine can alpha blend primitives.
188 \value Antialiasing The engine can use antialising to improve the appearance
189 of rendered primitives.
190 \value BlendModes The engine supports blending modes.
191 \value BrushStroke The engine supports drawing strokes that
192 contain brushes as fills, not just solid
193 colors (e.g. a dashed gradient line of
194 width 2).
195 \value ConicalGradientFill The engine supports conical gradient fills.
196 \value ConstantOpacity The engine supports the feature provided by
197 QPainter::setOpacity().
198 \value LinearGradientFill The engine supports linear gradient fills.
199 \value MaskedBrush The engine is capable of rendering brushes that has a
200 texture with an alpha channel or a mask.
201 \value ObjectBoundingModeGradients The engine has native support for gradients
202 with coordinate mode QGradient::ObjectBoundingMode.
203 Otherwise, if QPaintEngine::PatternTransform is
204 supported, object bounding mode gradients are
205 converted to gradients with coordinate mode
206 QGradient::LogicalMode and a brush transform for
207 the coordinate mapping.
208 \value PainterPaths The engine has path support.
209 \value PaintOutsidePaintEvent The engine is capable of painting outside of
210 paint events.
211 \value PatternBrush The engine is capable of rendering brushes with
212 the brush patterns specified in Qt::BrushStyle.
213 \value PatternTransform The engine has support for transforming brush
214 patterns.
215 \value PerspectiveTransform The engine has support for performing perspective
216 transformations on primitives.
217 \value PixmapTransform The engine can transform pixmaps, including
218 rotation and shearing.
219 \value PorterDuff The engine supports Porter-Duff operations
220 \value PrimitiveTransform The engine has support for transforming
221 drawing primitives.
222 \value RadialGradientFill The engine supports radial gradient fills.
223 \value RasterOpModes The engine supports bitwise raster operations.
224 \value AllFeatures All of the above features. This enum value is usually
225 used as a bit mask.
226*/
227
228/*!
229 \enum QPaintEngine::PolygonDrawMode
230
231 \value OddEvenMode The polygon should be drawn using OddEven fill
232 rule.
233
234 \value WindingMode The polygon should be drawn using Winding fill rule.
235
236 \value ConvexMode The polygon is a convex polygon and can be drawn
237 using specialized algorithms where available.
238
239 \value PolylineMode Only the outline of the polygon should be
240 drawn.
241
242*/
243
244/*!
245 \enum QPaintEngine::DirtyFlag
246
247 \value DirtyPen The pen is dirty and needs to be updated.
248
249 \value DirtyBrush The brush is dirty and needs to be updated.
250
251 \value DirtyBrushOrigin The brush origin is dirty and needs to
252 updated.
253
254 \value DirtyFont The font is dirty and needs to be updated.
255
256 \value DirtyBackground The background is dirty and needs to be
257 updated.
258
259 \value DirtyBackgroundMode The background mode is dirty and needs
260 to be updated.
261
262 \value DirtyTransform The transform is dirty and needs to be
263 updated.
264
265 \value DirtyClipRegion The clip region is dirty and needs to be
266 updated.
267
268 \value DirtyClipPath The clip path is dirty and needs to be
269 updated.
270
271 \value DirtyHints The render hints is dirty and needs to be
272 updated.
273
274 \value DirtyCompositionMode The composition mode is dirty and
275 needs to be updated.
276
277 \value DirtyClipEnabled Whether clipping is enabled or not is
278 dirty and needs to be updated.
279
280 \value DirtyOpacity The constant opacity has changed and needs to
281 be updated as part of the state change in
282 QPaintEngine::updateState().
283
284 \value AllDirty Convenience enum used internally.
285
286 These types are used by QPainter to trigger lazy updates of the
287 various states in the QPaintEngine using
288 QPaintEngine::updateState().
289
290 A paint engine must update every dirty state.
291*/
292
293/*!
294 \fn void QPaintEngine::syncState()
295
296 \internal
297
298 Updates all dirty states in this engine. This function should ONLY
299 be used when drawing with native handles directly and immediate sync
300 from QPainters state to the native state is required.
301*/
302void QPaintEngine::syncState()
303{
304 Q_ASSERT(state);
305 updateState(*state);
306
307 if (isExtended())
308 static_cast<QPaintEngineEx *>(this)->sync();
309}
310
311static QPaintEngine *qt_polygon_recursion = 0;
312struct 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*/
327void 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
342struct 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*/
354void 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