initial import
[vuplus_webkit] / Source / WebCore / platform / graphics / qt / TextureMapperQt.cpp
1 /*
2  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
3
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  Library General Public License for more details.
13
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB.  If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "TextureMapperQt.h"
22
23 #include <QtCore/qdebug.h>
24 #include <QtGui/qpaintengine.h>
25 #include <QtGui/qpixmap.h>
26
27 #if USE(TEXTURE_MAPPER_GL)
28 # include "opengl/TextureMapperGL.h"
29 #endif
30
31 namespace WebCore {
32
33 void BitmapTextureQt::destroy()
34 {
35     if (m_pixmap.paintingActive())
36         qFatal("Destroying an active pixmap");
37     m_pixmap = QPixmap();
38 }
39
40 void BitmapTextureQt::reset(const IntSize& size, bool isOpaque)
41 {
42     BitmapTexture::reset(size, isOpaque);
43
44     if (size.width() > m_pixmap.size().width() || size.height() > m_pixmap.size().height() || m_pixmap.isNull())
45         m_pixmap = QPixmap(size.width(), size.height());
46     if (!isOpaque)
47         m_pixmap.fill(Qt::transparent);
48 }
49
50 PlatformGraphicsContext* BitmapTextureQt::beginPaint(const IntRect& dirtyRect)
51 {
52     m_painter.begin(&m_pixmap);
53     TextureMapperQt::initialize(&m_painter);
54     m_painter.setCompositionMode(QPainter::CompositionMode_Clear);
55     m_painter.fillRect(QRect(dirtyRect), Qt::transparent);
56     m_painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
57     return &m_painter;
58 }
59
60 void BitmapTextureQt::endPaint()
61 {
62     m_painter.end();
63 }
64
65 bool BitmapTextureQt::save(const String& path)
66 {
67     return m_pixmap.save(path, "PNG");
68 }
69
70 void BitmapTextureQt::setContentsToImage(Image* image)
71 {
72     if (!image)
73         return;
74     const QPixmap* pixmap = image->nativeImageForCurrentFrame();
75     if (!pixmap)
76         return;
77     BitmapTexture::reset(pixmap->size(), !pixmap->hasAlphaChannel());
78     m_pixmap = *pixmap;
79 }
80
81 void BitmapTextureQt::pack()
82 {
83     if (m_pixmap.isNull())
84         return;
85
86     m_image = m_pixmap.toImage();
87     m_pixmap = QPixmap();
88     m_isPacked = true;
89 }
90
91 void BitmapTextureQt::unpack()
92 {
93     m_isPacked = false;
94     if (m_image.isNull())
95         return;
96
97     m_pixmap = QPixmap::fromImage(m_image);
98     m_image = QImage();
99 }
100
101 void TextureMapperQt::beginClip(const TransformationMatrix& matrix, const FloatRect& rect)
102 {
103      QPainter* painter = currentPainter();
104      painter->save();
105      QTransform prevTransform = painter->transform();
106      painter->setTransform(matrix, false);
107      painter->setClipRect(rect);
108      painter->setTransform(prevTransform, false);
109 }
110
111 void TextureMapperQt::endClip()
112 {
113     currentPainter()->restore();
114 }
115
116 IntSize TextureMapperQt::viewportSize() const
117 {
118     return IntSize(m_painter->device()->width(), m_painter->device()->height());
119 }
120
121
122 TextureMapperQt::TextureMapperQt()
123     : m_currentSurface(0)
124 {
125 }
126
127 void TextureMapperQt::setGraphicsContext(GraphicsContext* context)
128 {
129     m_context = context;
130     m_painter = context->platformContext();
131     initialize(m_painter);
132 }
133
134 GraphicsContext* TextureMapperQt::graphicsContext()
135 {
136     return m_context;
137 }
138
139 void TextureMapperQt::bindSurface(BitmapTexture* surface)
140 {
141     if (m_currentSurface == surface)
142         return;
143     if (m_currentSurface)
144         m_currentSurface->m_painter.end();
145     if (!surface) {
146         m_currentSurface = 0;
147         return;
148     }
149     BitmapTextureQt* surfaceQt = static_cast<BitmapTextureQt*>(surface);
150     if (!surfaceQt->m_painter.isActive())
151         surfaceQt->m_painter.begin(&surfaceQt->m_pixmap);
152     m_currentSurface = surfaceQt;
153 }
154
155
156 void TextureMapperQt::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture)
157 {
158     const BitmapTextureQt& textureQt = static_cast<const BitmapTextureQt&>(texture);
159     QPainter* painter = m_painter;
160     QPixmap pixmap = textureQt.m_pixmap;
161     if (m_currentSurface)
162         painter = &m_currentSurface->m_painter;
163
164     if (maskTexture && maskTexture->isValid()) {
165         const BitmapTextureQt* mask = static_cast<const BitmapTextureQt*>(maskTexture);
166         QPixmap intermediatePixmap(pixmap.size());
167         intermediatePixmap.fill(Qt::transparent);
168         QPainter maskPainter(&intermediatePixmap);
169         maskPainter.setCompositionMode(QPainter::CompositionMode_Source);
170         maskPainter.drawPixmap(0, 0, pixmap);
171         maskPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
172         maskPainter.drawPixmap(QRect(0, 0, pixmap.width(), pixmap.height()), mask->m_pixmap, mask->sourceRect());
173         maskPainter.end();
174         pixmap = intermediatePixmap;
175     }
176
177     const qreal prevOpacity = painter->opacity();
178     const QTransform prevTransform = painter->transform();
179     painter->setOpacity(opacity);
180     painter->setTransform(matrix, true);
181     painter->drawPixmap(targetRect, pixmap, FloatRect(textureQt.sourceRect()));
182     painter->setTransform(prevTransform);
183     painter->setOpacity(prevOpacity);
184 }
185
186 PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
187 {
188 #if USE(TEXTURE_MAPPER_GL)
189     if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2)
190         return adoptPtr(new TextureMapperGL);
191 #endif
192     return adoptPtr(new TextureMapperQt);
193 }
194
195 PassRefPtr<BitmapTexture> TextureMapperQt::createTexture()
196 {
197     return adoptRef(new BitmapTextureQt());
198 }
199
200 BitmapTextureQt::BitmapTextureQt()
201     : m_isPacked(false)
202 {
203
204 }
205
206 void TextureMapperQt::beginPainting()
207 {
208     m_painter->save();
209 }
210
211 void TextureMapperQt::endPainting()
212 {
213     m_painter->restore();
214 }
215
216 #if USE(TEXTURE_MAPPER_GL)
217 class RGBA32PremultimpliedBufferQt : public RGBA32PremultimpliedBuffer {
218 public:
219     virtual PlatformGraphicsContext* beginPaint(const IntRect& rect, bool opaque)
220     {
221         // m_image is only using during paint, it's safe to override it.
222         m_image = QImage(rect.size().width(), rect.size().height(), opaque ? QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied);
223         if (!opaque)
224             m_image.fill(0);
225         m_painter.begin(&m_image);
226         TextureMapperQt::initialize(&m_painter);
227         m_painter.translate(-rect.x(), -rect.y());
228         return &m_painter;
229     }
230
231     virtual void endPaint() { m_painter.end(); }
232     virtual const void* data() const { return m_image.constBits(); }
233
234 private:
235     QPainter m_painter;
236     QImage m_image;
237 };
238
239 PassRefPtr<RGBA32PremultimpliedBuffer> RGBA32PremultimpliedBuffer::create()
240 {
241     return adoptRef(new RGBA32PremultimpliedBufferQt());
242 }
243
244 uint64_t uidForImage(Image* image)
245 {
246     return image->nativeImageForCurrentFrame()->serialNumber();
247 }
248 #endif
249 };