Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / filters / FETile.cpp
1 /*
2  * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
3  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
4  * Copyright (C) 2013 Google Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #include "config.h"
23 #include "platform/graphics/filters/FETile.h"
24
25 #include "SkFlattenableBuffers.h"
26 #include "SkTileImageFilter.h"
27
28 #include "platform/graphics/GraphicsContext.h"
29 #include "platform/graphics/Pattern.h"
30 #include "platform/graphics/UnacceleratedImageBufferSurface.h"
31 #include "platform/graphics/filters/SkiaImageFilterBuilder.h"
32 #include "platform/text/TextStream.h"
33 #include "platform/transforms/AffineTransform.h"
34 #include "third_party/skia/include/core/SkDevice.h"
35
36 namespace WebCore {
37
38 FETile::FETile(Filter* filter)
39     : FilterEffect(filter)
40 {
41 }
42
43 PassRefPtr<FETile> FETile::create(Filter* filter)
44 {
45     return adoptRef(new FETile(filter));
46 }
47
48 FloatRect FETile::mapPaintRect(const FloatRect& rect, bool forward)
49 {
50     return forward ? maxEffectRect() : inputEffect(0)->maxEffectRect();
51 }
52
53 void FETile::applySoftware()
54 {
55     FilterEffect* in = inputEffect(0);
56
57     ImageBuffer* resultImage = createImageBufferResult();
58     if (!resultImage)
59         return;
60
61     setIsAlphaImage(in->isAlphaImage());
62
63     // Source input needs more attention. It has the size of the filterRegion but gives the
64     // size of the cutted sourceImage back. This is part of the specification and optimization.
65     FloatRect tileRect = in->maxEffectRect();
66     FloatPoint inMaxEffectLocation = tileRect.location();
67     FloatPoint maxEffectLocation = maxEffectRect().location();
68     if (in->filterEffectType() == FilterEffectTypeSourceInput) {
69         Filter* filter = this->filter();
70         tileRect = filter->absoluteFilterRegion();
71     }
72
73     OwnPtr<ImageBufferSurface> surface;
74     IntSize intTileSize = roundedIntSize(tileRect.size());
75     surface = adoptPtr(new UnacceleratedImageBufferSurface(intTileSize));
76     OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(surface.release());
77     if (!tileImage)
78         return;
79
80     GraphicsContext* tileImageContext = tileImage->context();
81     tileImageContext->scale(FloatSize(intTileSize.width() / tileRect.width(), intTileSize.height() / tileRect.height()));
82     tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
83
84     if (ImageBuffer* tileImageBuffer = in->asImageBuffer())
85         tileImageContext->drawImageBuffer(tileImageBuffer, IntRect(in->absolutePaintRect().location(), tileImageBuffer->size()));
86
87     RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(CopyBackingStore), true, true);
88
89     AffineTransform patternTransform;
90     patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y());
91     pattern->setPatternSpaceTransform(patternTransform);
92     GraphicsContext* filterContext = resultImage->context();
93     filterContext->setFillPattern(pattern);
94     filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
95 }
96
97 static FloatRect getRect(FilterEffect* effect)
98 {
99     FloatRect result = effect->filter()->filterRegion();
100     FloatRect boundaries = effect->effectBoundaries();
101     if (effect->hasX())
102         result.setX(boundaries.x());
103     if (effect->hasY())
104         result.setY(boundaries.y());
105     if (effect->hasWidth())
106         result.setWidth(boundaries.width());
107     if (effect->hasHeight())
108         result.setHeight(boundaries.height());
109     return result;
110 }
111
112 PassRefPtr<SkImageFilter> FETile::createImageFilter(SkiaImageFilterBuilder* builder)
113 {
114     RefPtr<SkImageFilter> input(builder->build(inputEffect(0), operatingColorSpace()));
115     FloatRect srcRect = inputEffect(0) ? getRect(inputEffect(0)) : filter()->filterRegion();
116     FloatRect dstRect = getRect(this);
117     return adoptRef(SkTileImageFilter::Create(srcRect, dstRect, input.get()));
118 }
119
120 TextStream& FETile::externalRepresentation(TextStream& ts, int indent) const
121 {
122     writeIndent(ts, indent);
123     ts << "[feTile";
124     FilterEffect::externalRepresentation(ts);
125     ts << "]\n";
126     inputEffect(0)->externalRepresentation(ts, indent + 1);
127
128     return ts;
129 }
130
131 } // namespace WebCore