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 #ifdef QT_OPENGL_LIB
28 # include "opengl/TextureMapperGL.h"
29 #endif
30
31 namespace WebCore {
32
destroy()33 void BitmapTextureQt::destroy()
34 {
35 if (m_pixmap.paintingActive())
36 qFatal("Destroying an active pixmap");
37 m_pixmap = QPixmap();
38 }
39
reset(const IntSize & size,bool isOpaque)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
beginPaint(const IntRect & dirtyRect)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
endPaint()60 void BitmapTextureQt::endPaint()
61 {
62 m_painter.end();
63 }
64
save(const String & path)65 bool BitmapTextureQt::save(const String& path)
66 {
67 return m_pixmap.save(path, "PNG");
68 }
69
setContentsToImage(Image * image)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
pack()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
unpack()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
setClip(const IntRect & rect)101 void TextureMapperQt::setClip(const IntRect& rect)
102 {
103 QPainter* painter = m_currentSurface ? &m_currentSurface->m_painter : m_painter;
104 painter->setClipRect(rect);
105 }
106
TextureMapperQt()107 TextureMapperQt::TextureMapperQt()
108 : m_currentSurface(0)
109 {
110 }
111
setGraphicsContext(GraphicsContext * context)112 void TextureMapperQt::setGraphicsContext(GraphicsContext* context)
113 {
114 m_painter = context->platformContext();
115 initialize(m_painter);
116 }
117
bindSurface(BitmapTexture * surface)118 void TextureMapperQt::bindSurface(BitmapTexture* surface)
119 {
120 if (m_currentSurface == surface)
121 return;
122 if (m_currentSurface)
123 m_currentSurface->m_painter.end();
124 if (!surface) {
125 m_currentSurface = 0;
126 return;
127 }
128 BitmapTextureQt* surfaceQt = static_cast<BitmapTextureQt*>(surface);
129 if (!surfaceQt->m_painter.isActive())
130 surfaceQt->m_painter.begin(&surfaceQt->m_pixmap);
131 m_currentSurface = surfaceQt;
132 }
133
134
drawTexture(const BitmapTexture & texture,const IntRect & targetRect,const TransformationMatrix & matrix,float opacity,const BitmapTexture * maskTexture)135 void TextureMapperQt::drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture)
136 {
137 const BitmapTextureQt& textureQt = static_cast<const BitmapTextureQt&>(texture);
138 QPainter* painter = m_painter;
139 QPixmap pixmap = textureQt.m_pixmap;
140 if (m_currentSurface)
141 painter = &m_currentSurface->m_painter;
142
143 if (maskTexture && maskTexture->isValid()) {
144 const BitmapTextureQt* mask = static_cast<const BitmapTextureQt*>(maskTexture);
145 QPixmap intermediatePixmap(pixmap.size());
146 intermediatePixmap.fill(Qt::transparent);
147 QPainter maskPainter(&intermediatePixmap);
148 maskPainter.setCompositionMode(QPainter::CompositionMode_Source);
149 maskPainter.drawPixmap(0, 0, pixmap);
150 maskPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
151 maskPainter.drawPixmap(QRect(0, 0, pixmap.width(), pixmap.height()), mask->m_pixmap, mask->sourceRect());
152 maskPainter.end();
153 pixmap = intermediatePixmap;
154 }
155
156 const qreal prevOpacity = painter->opacity();
157 const QTransform prevTransform = painter->transform();
158 painter->setOpacity(opacity);
159 painter->setTransform(matrix, true);
160 painter->drawPixmap(targetRect, pixmap, textureQt.sourceRect());
161 painter->setTransform(prevTransform);
162 painter->setOpacity(prevOpacity);
163 }
164
create(GraphicsContext * context)165 PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
166 {
167 #ifdef QT_OPENGL_LIB
168 if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2)
169 return new TextureMapperGL;
170 #endif
171 return new TextureMapperQt;
172 }
173
createTexture()174 PassRefPtr<BitmapTexture> TextureMapperQt::createTexture()
175 {
176 return adoptRef(new BitmapTextureQt());
177 }
178
BitmapTextureQt()179 BitmapTextureQt::BitmapTextureQt()
180 : m_isPacked(false)
181 {
182
183 }
184
185 #ifdef QT_OPENGL_LIB
186 class RGBA32PremultimpliedBufferQt : public RGBA32PremultimpliedBuffer {
187 public:
beginPaint(const IntRect & rect,bool opaque)188 virtual PlatformGraphicsContext* beginPaint(const IntRect& rect, bool opaque)
189 {
190 // m_image is only using during paint, it's safe to override it.
191 m_image = QImage(rect.size().width(), rect.size().height(), QImage::Format_ARGB32_Premultiplied);
192 if (!opaque)
193 m_image.fill(0);
194 m_painter.begin(&m_image);
195 TextureMapperQt::initialize(&m_painter);
196 m_painter.translate(-rect.x(), -rect.y());
197 return &m_painter;
198 }
199
endPaint()200 virtual void endPaint() { m_painter.end(); }
data() const201 virtual const void* data() const { return m_image.constBits(); }
202
203 private:
204 QPainter m_painter;
205 QImage m_image;
206 };
207
create()208 PassRefPtr<RGBA32PremultimpliedBuffer> RGBA32PremultimpliedBuffer::create()
209 {
210 return adoptRef(new RGBA32PremultimpliedBufferQt());
211 }
212
213 #endif
214 };
215