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