[Win][Direct2D] Implement basic SVG support
[WebKit-https.git] / Source / WebCore / rendering / FilterEffectRenderer.h
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef FilterEffectRenderer_h
27 #define FilterEffectRenderer_h
28
29 #include "Filter.h"
30 #include "FilterEffect.h"
31 #include "FilterOperations.h"
32 #include "FloatRect.h"
33 #include "GraphicsContext.h"
34 #include "ImageBuffer.h"
35 #include "IntRectExtent.h"
36 #include "LayoutRect.h"
37 #include "SVGFilterBuilder.h"
38 #include "SourceGraphic.h"
39 #include <wtf/PassRefPtr.h>
40 #include <wtf/RefCounted.h>
41 #include <wtf/RefPtr.h>
42
43
44 namespace WebCore {
45
46 class Document;
47 class GraphicsContext;
48 class RenderElement;
49 class RenderLayer;
50
51 typedef Vector<RefPtr<FilterEffect>> FilterEffectList;
52
53 enum FilterConsumer {
54     FilterProperty,
55     FilterFunction
56 };
57
58 class FilterEffectRendererHelper {
59     WTF_MAKE_FAST_ALLOCATED;
60 public:
61     FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext)
62         : m_targetContext(targetContext)
63         , m_haveFilterEffect(haveFilterEffect)
64     {
65     }
66     
67     bool haveFilterEffect() const { return m_haveFilterEffect; }
68     bool hasStartedFilterEffect() const { return m_startedFilterEffect; }
69
70     bool prepareFilterEffect(RenderLayer*, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect);
71     bool beginFilterEffect();
72     void applyFilterEffect(GraphicsContext& destinationContext);
73     
74     GraphicsContext* filterContext() const;
75
76     const LayoutRect& repaintRect() const { return m_repaintRect; }
77
78 private:
79     RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the FilterEffectRenderer. FilterEffectRendererHelper should be weaned off it.
80     LayoutPoint m_paintOffset;
81     LayoutRect m_repaintRect;
82     const GraphicsContext& m_targetContext;
83     bool m_haveFilterEffect { false };
84     bool m_startedFilterEffect { false };
85 };
86
87 class FilterEffectRenderer final : public Filter {
88     WTF_MAKE_FAST_ALLOCATED;
89 public:
90     static RefPtr<FilterEffectRenderer> create()
91     {
92         return adoptRef(new FilterEffectRenderer);
93     }
94
95     void setSourceImageRect(const FloatRect& sourceImageRect)
96     { 
97         m_sourceDrawingRegion = sourceImageRect;
98         setMaxEffectRects(sourceImageRect);
99         setFilterRegion(sourceImageRect);
100         m_graphicsBufferAttached = false;
101     }
102     FloatRect sourceImageRect() const override { return m_sourceDrawingRegion; }
103
104     void setFilterRegion(const FloatRect& filterRegion) { m_filterRegion = filterRegion; }
105     FloatRect filterRegion() const override { return m_filterRegion; }
106
107     GraphicsContext* inputContext();
108     ImageBuffer* output() const { return lastEffect()->asImageBuffer(); }
109
110     bool build(RenderElement*, const FilterOperations&, FilterConsumer);
111     PassRefPtr<FilterEffect> buildReferenceFilter(RenderElement*, PassRefPtr<FilterEffect> previousEffect, ReferenceFilterOperation*);
112     bool updateBackingStoreRect(const FloatRect& filterRect);
113     void allocateBackingStoreIfNeeded(const GraphicsContext&);
114     void clearIntermediateResults();
115     void apply();
116     
117     IntRect outputRect() const { return lastEffect()->hasResult() ? lastEffect()->requestedRegionOfInputImageData(IntRect(m_filterRegion)) : IntRect(); }
118
119     bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
120     LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
121
122 private:
123     void setMaxEffectRects(const FloatRect& effectRect)
124     {
125         for (size_t i = 0; i < m_effects.size(); ++i) {
126             RefPtr<FilterEffect> effect = m_effects.at(i);
127             effect->setMaxEffectRect(effectRect);
128         }
129     }
130
131     FilterEffect* lastEffect() const
132     {
133         if (!m_effects.isEmpty())
134             return m_effects.last().get();
135         return nullptr;
136     }
137
138     FilterEffectRenderer();
139     virtual ~FilterEffectRenderer();
140     
141     FloatRect m_sourceDrawingRegion;
142     FloatRect m_filterRegion;
143     
144     FilterEffectList m_effects;
145     RefPtr<SourceGraphic> m_sourceGraphic;
146     
147     IntRectExtent m_outsets;
148
149     bool m_graphicsBufferAttached { false };
150     bool m_hasFilterThatMovesPixels { false };
151 };
152
153 } // namespace WebCore
154
155 #endif // FilterEffectRenderer_h