1/*
2 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
3 * Copyright (C) 2013 Google Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#ifndef Filter_h
22#define Filter_h
23
24#include "platform/PlatformExport.h"
25#include "platform/geometry/FloatRect.h"
26#include "platform/geometry/FloatSize.h"
27#include "platform/graphics/ImageBuffer.h"
28#include "third_party/skia/include/core/SkImageFilter.h"
29#include "wtf/RefCounted.h"
30
31namespace WebCore {
32
33class FilterEffect;
34
35class PLATFORM_EXPORT Filter : public RefCounted<Filter> {
36public:
37    Filter(const AffineTransform& absoluteTransform)
38    : m_absoluteTransform(absoluteTransform)
39    , m_inverseTransform(absoluteTransform.inverse())
40    {
41        // Filters can only accept scaling and translating transformations, as coordinates
42        // in most primitives are given in horizontal and vertical directions.
43        ASSERT(!absoluteTransform.b() && !absoluteTransform.c());
44    }
45    virtual ~Filter() { }
46
47    void setSourceImage(PassOwnPtr<ImageBuffer> sourceImage) { m_sourceImage = sourceImage; }
48    ImageBuffer* sourceImage() { return m_sourceImage.get(); }
49
50    const AffineTransform& absoluteTransform() const { return m_absoluteTransform; }
51
52    void setAbsoluteTransform(const AffineTransform& absoluteTransform)
53    {
54        // Filters can only accept scaling and translating transformations, as coordinates
55        // in most primitives are given in horizontal and vertical directions.
56        ASSERT(!absoluteTransform.b() && !absoluteTransform.c());
57        m_absoluteTransform = absoluteTransform;
58        m_inverseTransform = absoluteTransform.inverse();
59        m_absoluteFilterRegion = m_absoluteTransform.mapRect(m_filterRegion);
60    }
61    FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint& point) const { return m_inverseTransform.mapPoint(point); }
62    FloatRect mapLocalRectToAbsoluteRect(const FloatRect& rect) const { return m_absoluteTransform.mapRect(rect); }
63    FloatRect mapAbsoluteRectToLocalRect(const FloatRect& rect) const { return m_inverseTransform.mapRect(rect); }
64
65    virtual float applyHorizontalScale(float value) const
66    {
67        return value * m_absoluteTransform.a();
68    }
69    virtual float applyVerticalScale(float value) const
70    {
71        return value * m_absoluteTransform.d();
72    }
73    virtual FloatPoint3D resolve3dPoint(const FloatPoint3D& point) const { return point; }
74
75    virtual IntRect sourceImageRect() const = 0;
76
77    FloatRect absoluteFilterRegion() const { return m_absoluteFilterRegion; }
78
79    FloatRect filterRegion() const { return m_filterRegion; }
80    void setFilterRegion(const FloatRect& rect)
81    {
82        m_filterRegion = rect;
83        m_absoluteFilterRegion = m_absoluteTransform.mapRect(m_filterRegion);
84    }
85
86    // The methods enableCache() and disableCache() are temporary, and we
87    // should address the real issue inside skia, thus simplifying what the
88    // clients have to know, and can remove these.
89    // Also note that this cache should no longer be used by Blink once the
90    // NON impl-side painting path is removed.
91    void enableCache()
92    {
93        if (!m_cache)
94            m_cache = adoptRef(SkImageFilter::Cache::Create(1));
95        SkImageFilter::SetExternalCache(m_cache.get());
96    }
97
98    void disableCache()
99    {
100        SkImageFilter::SetExternalCache(0);
101    }
102
103    void removeFromCache(SkImageFilter* filter)
104    {
105        if (m_cache)
106            m_cache->remove(filter);
107    }
108
109private:
110    OwnPtr<ImageBuffer> m_sourceImage;
111    AffineTransform m_absoluteTransform;
112    AffineTransform m_inverseTransform;
113    FloatRect m_absoluteFilterRegion;
114    FloatRect m_filterRegion;
115    RefPtr<SkImageFilter::Cache> m_cache;
116};
117
118} // namespace WebCore
119
120#endif // Filter_h
121