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

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 17 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 29.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department 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
53
54QT_BEGIN_NAMESPACE
55
56/*!
57 \class QTextItem
58
59 \brief The QTextItem class provides all the information required to draw
60 text in a custom paint engine.
61
62 When you reimplement your own paint engine, you must reimplement
63 QPaintEngine::drawTextItem(), a function that takes a QTextItem as
64 one of its arguments.
65*/
66
67/*!
68 \enum QTextItem::RenderFlag
69
70 \value RightToLeft Render the text from right to left.
71 \value Overline Paint a line above the text.
72 \value Underline Paint a line under the text.
73 \value StrikeOut Paint a line through the text.
74 \omitvalue Dummy
75*/
76
77
78/*!
79 \fn qreal QTextItem::descent() const
80
81 Corresponds to the \l{QFontMetrics::descent()}{descent} of the piece of text that is drawn.
82*/
83qreal QTextItem::descent() const
84{
85 const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
86 return ti->descent.toReal();
87}
88
89/*!
90 \fn qreal QTextItem::ascent() const
91
92 Corresponds to the \l{QFontMetrics::ascent()}{ascent} of the piece of text that is drawn.
93*/
94qreal QTextItem::ascent() const
95{
96 const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
97 return ti->ascent.toReal();
98}
99
100/*!
101 \fn qreal QTextItem::width() const
102
103 Specifies the total width of the text to be drawn.
104*/
105qreal QTextItem::width() const
106{
107 const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
108 return ti->width.toReal();
109}
110
111/*!
112 \fn QTextItem::RenderFlags QTextItem::renderFlags() const
113
114 Returns the render flags used.
115*/
116QTextItem::RenderFlags QTextItem::renderFlags() const
117{
118 const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
119 return ti->flags;
120}
121
122/*!
123 \fn QString QTextItem::text() const
124
125 Returns the text that should be drawn.
126*/
127QString QTextItem::text() const
128{
129 const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
130 return QString(ti->chars, ti->num_chars);
131}
132
133/*!
134 \fn QFont QTextItem::font() const
135
136 Returns the font that should be used to draw the text.
137*/
138QFont QTextItem::font() const
139{
140 const QTextItemInt *ti = static_cast<const QTextItemInt *>(this);
141 return ti->f ? *ti->f : QApplication::font();
142}
143
144
145/*!
146 \class QPaintEngine
147 \ingroup multimedia
148
149 \brief The QPaintEngine class provides an abstract definition of how
150 QPainter draws to a given device on a given platform.
151
152 Qt 4.0 provides several premade implementations of QPaintEngine for the
153 different painter backends we support. We provide one paint engine for each
154 window system and painting framework we support. This includes X11 on
155 Unix/Linux and CoreGraphics on Mac OS X. In addition we provide QPaintEngine
156 implementations for OpenGL (accessible through QGLWidget) and PostScript
157 (accessible through QPSPrinter on X11). Additionally there is a raster-based
158 paint engine that is a fallback for when an engine does not support a certain
159 capability.
160
161 If one wants to use QPainter to draw to a different backend,
162 one must subclass QPaintEngine and reimplement all its virtual
163 functions. The QPaintEngine implementation is then made available by
164 subclassing QPaintDevice and reimplementing the virtual function
165 QPaintDevice::paintEngine().
166
167 QPaintEngine is created and owned by the QPaintDevice that created it.
168
169 The big advantage of the QPaintEngine approach opposed to
170 Qt 3's QPainter/QPaintDevice::cmd() approach is that it is now
171 possible to adapt to multiple technologies on each platform and take
172 advantage of each to the fullest.
173
174 \sa QPainter, QPaintDevice::paintEngine(), {The 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*/
301void QPaintEngine::syncState()
302{
303 Q_ASSERT(state);
304 updateState(*state);
305}
306
307static QPaintEngine *qt_polygon_recursion = 0;
308struct QT_Point {
309 int x;
310 int y;
311};
312
313/*!
314 \fn void QPaintEngine::drawPolygon(const QPointF *points, int pointCount,
315 PolygonDrawMode mode)
316
317 Reimplement this virtual function to draw the polygon defined
318 by the \a pointCount first points in \a points, using mode \a
319 mode.
320
321 \note At least one of the drawPolygon() functions must be reimplemented.
322*/
323void QPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
324{
325 Q_ASSERT_X(qt_polygon_recursion != this, "QPaintEngine::drawPolygon",
326 "At least one drawPolygon function must be implemented");
327 qt_polygon_recursion = this;
328 Q_ASSERT(sizeof(QT_Point) == sizeof(QPoint));
329 QVarLengthArray<QT_Point> p(pointCount);
330 for (int i = 0; i < pointCount; ++i) {
331 p[i].x = qRound(points[i].x());
332 p[i].y = qRound(points[i].y());
333 }
334 drawPolygon((QPoint *)p.data(), pointCount, mode);
335 qt_polygon_recursion = 0;
336}
337
338struct QT_PointF {
339 qreal x;
340 qreal y;
341};
342/*!
343 \overload
344
345 Reimplement this virtual function to draw the polygon defined by the
346 \a pointCount first points in \a points, using mode \a mode.
347
348 \note At least one of the drawPolygon() functions must be reimplemented.
349*/
350void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
351{
352 Q_ASSERT_X(qt_polygon_recursion != this, "QPaintEngine::drawPolygon",
353 "At least one drawPolygon function must be implemented");
354 qt_polygon_recursion = this;
355 Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
356 QVarLengthArray<QT_PointF> p(pointCount);
357 for (int i=0; i<pointCount; ++i) {
358 p[i].x = points[i].x();
359 p[i].y = points[i].y();
360 }
361 drawPolygon((QPointF *)p.data(), pointCount, mode);
362 qt_polygon_recursion = 0;
363}
364
365/*!
366 \enum QPaintEngine::Type
367
368 \value X11
369 \value Windows
370 \value MacPrinter
371 \value CoreGraphics Mac OS X's Quartz2D (CoreGraphics)
372 \value QuickDraw Mac OS X's QuickDraw
373 \value QWindowSystem Qt for Embedded Linux
374 \value PostScript
375 \value OpenGL
376 \value Picture QPicture format
377 \value SVG Scalable Vector Graphics XML format
378 \value Raster
379 \value Direct3D Windows only, Direct3D based engine
380 \value Pdf Portable Document Format
381 \value OpenVG
382 \value User First user type ID
383 \value MaxUser Last user type ID
384*/
385
386/*!
387 \fn bool QPaintEngine::isActive() const
388
389 Returns true if the paint engine is actively drawing; otherwise
390 returns false.
391
392 \sa setActive()
393*/
394
395/*!
396 \fn void QPaintEngine::setActive(bool state)
397
398 Sets the active state of the paint engine to \a state.
399
400 \sa isActive()
401*/
402
403/*!
404 \fn bool QPaintEngine::begin(QPaintDevice *pdev)
405
406 Reimplement this function to initialise your paint engine when
407 painting is to start on the paint device \a pdev. Return true if
408 the initialization was successful; otherwise return false.
409
410 \sa end() isActive()
411*/
412
413/*!
414 \fn bool QPaintEngine::end()
415
416 Reimplement this function to finish painting on the current paint
417 device. Return true if painting was finished successfully;
418 otherwise return false.
419
420 \sa begin() isActive()
421*/
422
423
424/*!
425 Draws the first \a pointCount points in the buffer \a points
426*/
427void QPaintEngine::drawPoints(const QPointF *points, int pointCount)
428{
429 QPainter *p = painter();