1/*
2 Copyright (C) 2012 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 "TextureMapperImageBuffer.h"
22
23#include "GraphicsLayer.h"
24#if PLATFORM(QT)
25#include "NativeImageQt.h"
26#endif
27#include "NotImplemented.h"
28
29
30#if USE(TEXTURE_MAPPER)
31namespace WebCore {
32
33static const int s_maximumAllowedImageBufferDimension = 4096;
34
35void BitmapTextureImageBuffer::updateContents(const void* data, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine, UpdateContentsFlag)
36{
37#if PLATFORM(QT)
38    QImage image(reinterpret_cast<const uchar*>(data), targetRect.width(), targetRect.height(), bytesPerLine, NativeImageQt::defaultFormatForAlphaEnabledImages());
39
40    QPainter* painter = m_image->context()->platformContext();
41    painter->save();
42    painter->setCompositionMode(QPainter::CompositionMode_Source);
43    painter->drawImage(targetRect, image, IntRect(sourceOffset, targetRect.size()));
44    painter->restore();
45#elif PLATFORM(CAIRO)
46    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(data()),
47                                                                                   CAIRO_FORMAT_ARGB32,
48                                                                                   targetRect.width(), targetRect.height(),
49                                                                                   bytesPerLine));
50    m_image->context()->platformContext()->drawSurfaceToContext(surface.get(), targetRect,
51                                                                IntRect(sourceOffset, targetRect.size()), m_image->context());
52#else
53    UNUSED_PARAM(data);
54    UNUSED_PARAM(targetRect);
55    UNUSED_PARAM(sourceOffset);
56    UNUSED_PARAM(bytesPerLine);
57#endif
58}
59
60void BitmapTextureImageBuffer::updateContents(TextureMapper*, GraphicsLayer* sourceLayer, const IntRect& targetRect, const IntPoint& sourceOffset, UpdateContentsFlag)
61{
62    GraphicsContext* context = m_image->context();
63
64    context->clearRect(targetRect);
65
66    IntRect sourceRect(targetRect);
67    sourceRect.setLocation(sourceOffset);
68    context->save();
69    context->clip(targetRect);
70    context->translate(targetRect.x() - sourceOffset.x(), targetRect.y() - sourceOffset.y());
71    sourceLayer->paintGraphicsLayerContents(*context, sourceRect);
72    context->restore();
73}
74
75void BitmapTextureImageBuffer::didReset()
76{
77    m_image = ImageBuffer::create(contentSize());
78}
79
80void BitmapTextureImageBuffer::updateContents(Image* image, const IntRect& targetRect, const IntPoint& offset, UpdateContentsFlag)
81{
82    m_image->context()->drawImage(image, ColorSpaceDeviceRGB, targetRect, IntRect(offset, targetRect.size()), CompositeCopy);
83}
84
85IntSize TextureMapperImageBuffer::maxTextureSize() const
86{
87    return IntSize(s_maximumAllowedImageBufferDimension, s_maximumAllowedImageBufferDimension);
88}
89
90void TextureMapperImageBuffer::beginClip(const TransformationMatrix& matrix, const FloatRect& rect)
91{
92    GraphicsContext* context = currentContext();
93    if (!context)
94        return;
95#if ENABLE(3D_RENDERING)
96    TransformationMatrix previousTransform = context->get3DTransform();
97#else
98    AffineTransform previousTransform = context->getCTM();
99#endif
100    context->save();
101
102#if ENABLE(3D_RENDERING)
103    context->concat3DTransform(matrix);
104#else
105    context->concatCTM(matrix.toAffineTransform());
106#endif
107
108    context->clip(rect);
109
110#if ENABLE(3D_RENDERING)
111    context->set3DTransform(previousTransform);
112#else
113    context->setCTM(previousTransform);
114#endif
115}
116
117void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, unsigned /* exposedEdges */)
118{
119    GraphicsContext* context = currentContext();
120    if (!context)
121        return;
122
123    const BitmapTextureImageBuffer& textureImageBuffer = static_cast<const BitmapTextureImageBuffer&>(texture);
124    ImageBuffer* image = textureImageBuffer.m_image.get();
125    context->save();
126    context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
127    context->setAlpha(opacity);
128#if ENABLE(3D_RENDERING)
129    context->concat3DTransform(matrix);
130#else
131    context->concatCTM(matrix.toAffineTransform());
132#endif
133    context->drawImageBuffer(image, ColorSpaceDeviceRGB, targetRect);
134    context->restore();
135}
136
137void TextureMapperImageBuffer::drawSolidColor(const FloatRect& rect, const TransformationMatrix& matrix, const Color& color)
138{
139    GraphicsContext* context = currentContext();
140    if (!context)
141        return;
142
143    context->save();
144    context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
145#if ENABLE(3D_RENDERING)
146    context->concat3DTransform(matrix);
147#else
148    context->concatCTM(matrix.toAffineTransform());
149#endif
150
151    context->fillRect(rect, color, ColorSpaceDeviceRGB);
152    context->restore();
153}
154
155void TextureMapperImageBuffer::drawBorder(const Color&, float /* borderWidth */, const FloatRect&, const TransformationMatrix&)
156{
157    notImplemented();
158}
159
160void TextureMapperImageBuffer::drawNumber(int /* number */, const Color&, const FloatPoint&, const TransformationMatrix&)
161{
162    notImplemented();
163}
164
165#if ENABLE(CSS_FILTERS)
166PassRefPtr<BitmapTexture> BitmapTextureImageBuffer::applyFilters(TextureMapper*, const FilterOperations&)
167{
168    return this;
169}
170#endif
171
172}
173#endif
174