Make QRegion not need to be friends with QVector
[profile/ivi/qtbase.git] / src / gui / painting / qemulationpaintengine.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <private/qemulationpaintengine_p.h>
43 #include <private/qpainter_p.h>
44 #include <private/qtextengine_p.h>
45 #include <qdebug.h>
46
47 QT_BEGIN_NAMESPACE
48
49 QEmulationPaintEngine::QEmulationPaintEngine(QPaintEngineEx *engine)
50     : real_engine(engine)
51 {
52     QPaintEngine::state = real_engine->state();
53 }
54
55
56 QPaintEngine::Type QEmulationPaintEngine::type() const
57 {
58     return real_engine->type();
59 }
60
61 bool QEmulationPaintEngine::begin(QPaintDevice *)
62 {
63     return true;
64 }
65
66 bool QEmulationPaintEngine::end()
67 {
68     return true;
69 }
70
71
72 QPainterState *QEmulationPaintEngine::createState(QPainterState *orig) const
73 {
74     return real_engine->createState(orig);
75 }
76
77 void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
78 {
79     QPainterState *s = state();
80
81     if (s->bgMode == Qt::OpaqueMode) {
82         Qt::BrushStyle style = brush.style();
83         if ((style >= Qt::Dense1Pattern && style <= Qt::DiagCrossPattern) || (style == Qt::TexturePattern ))
84             real_engine->fill(path, s->bgBrush);
85     }
86
87     Qt::BrushStyle style = qbrush_style(brush);
88     if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
89         const QGradient *g = brush.gradient();
90
91         if (g->coordinateMode() > QGradient::LogicalMode) {
92             if (g->coordinateMode() == QGradient::StretchToDeviceMode) {
93                 QBrush copy = brush;
94                 QTransform mat = copy.transform();
95                 mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height());
96                 copy.setTransform(mat);
97                 real_engine->fill(path, copy);
98                 return;
99             } else if (g->coordinateMode() == QGradient::ObjectBoundingMode) {
100                 QBrush copy = brush;
101                 QTransform mat = copy.transform();
102                 QRectF r = path.controlPointRect();
103                 mat.translate(r.x(), r.y());
104                 mat.scale(r.width(), r.height());
105                 copy.setTransform(mat);
106                 real_engine->fill(path, copy);
107                 return;
108             }
109         }
110     }
111
112     real_engine->fill(path, brush);
113 }
114
115 void QEmulationPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
116 {
117     QPainterState *s = state();
118
119     if (s->bgMode == Qt::OpaqueMode && pen.style() > Qt::SolidLine) {
120         QPen bgPen = pen;
121         bgPen.setBrush(s->bgBrush);
122         bgPen.setStyle(Qt::SolidLine);
123         real_engine->stroke(path, bgPen);
124     }
125
126     QBrush brush = pen.brush();
127     QPen copy = pen;
128     Qt::BrushStyle style = qbrush_style(brush);
129     if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
130         const QGradient *g = brush.gradient();
131
132         if (g->coordinateMode() > QGradient::LogicalMode) {
133             if (g->coordinateMode() == QGradient::StretchToDeviceMode) {
134                 QTransform mat = brush.transform();
135                 mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height());
136                 brush.setTransform(mat);
137                 copy.setBrush(brush);
138                 real_engine->stroke(path, copy);
139                 return;
140             } else if (g->coordinateMode() == QGradient::ObjectBoundingMode) {
141                 QTransform mat = brush.transform();
142                 QRectF r = path.controlPointRect();
143                 mat.translate(r.x(), r.y());
144                 mat.scale(r.width(), r.height());
145                 brush.setTransform(mat);
146                 copy.setBrush(brush);
147                 real_engine->stroke(path, copy);
148                 return;
149             }
150         }
151     }
152
153     real_engine->stroke(path, pen);
154 }
155
156 void QEmulationPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
157 {
158     real_engine->clip(path, op);
159 }
160
161 void QEmulationPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
162 {
163     if (state()->bgMode == Qt::OpaqueMode && pm.isQBitmap())
164         fillBGRect(r);
165     real_engine->drawPixmap(r, pm, sr);
166 }
167
168 void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
169 {
170     if (state()->bgMode == Qt::OpaqueMode) {
171         const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
172         QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
173         fillBGRect(rect);
174     }
175
176     QPainterState *s = state();
177     Qt::BrushStyle style = qbrush_style(s->pen.brush());
178     if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern)
179     {
180         QPen savedPen = s->pen;
181         QGradient g = *s->pen.brush().gradient();
182
183         if (g.coordinateMode() > QGradient::LogicalMode) {
184             QTransform mat = s->pen.brush().transform();
185             if (g.coordinateMode() == QGradient::StretchToDeviceMode) {
186                 mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height());
187             } else if (g.coordinateMode() == QGradient::ObjectBoundingMode) {
188                 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
189                 QRectF r(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
190                 mat.translate(r.x(), r.y());
191                 mat.scale(r.width(), r.height());
192             }
193             g.setCoordinateMode(QGradient::LogicalMode);
194             QBrush brush(g);
195             brush.setTransform(mat);
196             s->pen.setBrush(brush);
197             penChanged();
198             real_engine->drawTextItem(p, textItem);
199             s->pen = savedPen;
200             penChanged();
201             return;
202         }
203     }
204
205     real_engine->drawTextItem(p, textItem);
206 }
207
208 void QEmulationPaintEngine::drawStaticTextItem(QStaticTextItem *item)
209 {
210     real_engine->drawStaticTextItem(item);
211 }
212
213 void QEmulationPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
214 {
215     if (state()->bgMode == Qt::OpaqueMode && pixmap.isQBitmap())
216         fillBGRect(r);
217     real_engine->drawTiledPixmap(r, pixmap, s);
218 }
219
220 void QEmulationPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags)
221 {
222     real_engine->drawImage(r, pm, sr, flags);
223 }
224
225 void QEmulationPaintEngine::clipEnabledChanged()
226 {
227     real_engine->clipEnabledChanged();
228 }
229
230 void QEmulationPaintEngine::penChanged()
231 {
232     real_engine->penChanged();
233 }
234
235 void QEmulationPaintEngine::brushChanged()
236 {
237     real_engine->brushChanged();
238 }
239
240 void QEmulationPaintEngine::brushOriginChanged()
241 {
242     real_engine->brushOriginChanged();
243 }
244
245 void QEmulationPaintEngine::opacityChanged()
246 {
247     real_engine->opacityChanged();
248 }
249
250 void QEmulationPaintEngine::compositionModeChanged()
251 {
252     real_engine->compositionModeChanged();
253 }
254
255 void QEmulationPaintEngine::renderHintsChanged()
256 {
257     real_engine->renderHintsChanged();
258 }
259
260 void QEmulationPaintEngine::transformChanged()
261 {
262     real_engine->transformChanged();
263 }
264
265 void QEmulationPaintEngine::setState(QPainterState *s)
266 {
267     QPaintEngine::state = s;
268     real_engine->setState(s);
269 }
270
271 void QEmulationPaintEngine::beginNativePainting()
272 {
273     real_engine->beginNativePainting();
274 }
275
276 void QEmulationPaintEngine::endNativePainting()
277 {
278     real_engine->endNativePainting();
279 }
280
281 void QEmulationPaintEngine::fillBGRect(const QRectF &r)
282 {
283     qreal pts[] = { r.x(), r.y(), r.x() + r.width(), r.y(),
284                     r.x() + r.width(), r.y() + r.height(), r.x(), r.y() + r.height() };
285     QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
286     real_engine->fill(vp, state()->bgBrush);
287 }
288
289 QT_END_NAMESPACE