Restrict SVG filters to accessible security origins
[WebKit-https.git] / Source / WebCore / rendering / FilterEffectRenderer.h
1 /*
2  * Copyright (C) 2011-2017 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 #pragma once
27
28 #include "Filter.h"
29 #include "IntRectExtent.h"
30 #include "LayoutRect.h"
31
32 namespace WebCore {
33
34 class Document;
35 class FilterEffect;
36 class FilterOperations;
37 class GraphicsContext;
38 class ReferenceFilterOperation;
39 class RenderElement;
40 class RenderLayer;
41 class SourceGraphic;
42
43 enum FilterConsumer { FilterProperty, FilterFunction };
44
45 class FilterEffectRendererHelper {
46     WTF_MAKE_FAST_ALLOCATED;
47 public:
48     FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext);
49
50     bool haveFilterEffect() const { return m_haveFilterEffect; }
51     bool hasStartedFilterEffect() const { return m_startedFilterEffect; }
52
53     bool prepareFilterEffect(RenderLayer&, const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect, const LayoutRect& layerRepaintRect);
54     bool beginFilterEffect();
55     void applyFilterEffect(GraphicsContext& destinationContext);
56     
57     GraphicsContext* filterContext() const;
58
59     const LayoutRect& repaintRect() const { return m_repaintRect; }
60
61 private:
62     RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the FilterEffectRenderer. FilterEffectRendererHelper should be weaned off it.
63     LayoutPoint m_paintOffset;
64     LayoutRect m_repaintRect;
65     const GraphicsContext& m_targetContext;
66     bool m_haveFilterEffect { false };
67     bool m_startedFilterEffect { false };
68 };
69
70 class FilterEffectRenderer final : public Filter {
71     WTF_MAKE_FAST_ALLOCATED;
72 public:
73     friend class FilterEffectRendererHelper;
74
75     static Ref<FilterEffectRenderer> create();
76
77     void setSourceImageRect(const FloatRect&);
78     void setFilterRegion(const FloatRect& filterRegion) { m_filterRegion = filterRegion; }
79
80     ImageBuffer* output() const;
81
82     bool build(RenderElement&, const FilterOperations&, FilterConsumer);
83     void clearIntermediateResults();
84     void apply();
85
86     bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
87     bool hasFilterThatShouldBeRestrictedBySecurityOrigin() const { return m_hasFilterThatShouldBeRestrictedBySecurityOrigin; }
88
89 private:
90     FilterEffectRenderer();
91     virtual ~FilterEffectRenderer();
92
93     FloatRect sourceImageRect() const final { return m_sourceDrawingRegion; }
94     FloatRect filterRegion() const final { return m_filterRegion; }
95
96     RefPtr<FilterEffect> buildReferenceFilter(RenderElement&, FilterEffect& previousEffect, ReferenceFilterOperation&);
97
98     void setMaxEffectRects(const FloatRect&);
99
100     GraphicsContext* inputContext();
101
102     bool updateBackingStoreRect(const FloatRect& filterRect);
103     void allocateBackingStoreIfNeeded(const GraphicsContext&);
104
105     IntRect outputRect() const;
106
107     LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
108
109     FloatRect m_sourceDrawingRegion;
110     FloatRect m_filterRegion;
111
112     Vector<Ref<FilterEffect>> m_effects;
113     Ref<SourceGraphic> m_sourceGraphic;
114
115     IntRectExtent m_outsets;
116
117     bool m_graphicsBufferAttached { false };
118     bool m_hasFilterThatMovesPixels { false };
119     bool m_hasFilterThatShouldBeRestrictedBySecurityOrigin { false };
120 };
121
122 inline FilterEffectRendererHelper::FilterEffectRendererHelper(bool haveFilterEffect, GraphicsContext& targetContext)
123     : m_targetContext(targetContext)
124     , m_haveFilterEffect(haveFilterEffect)
125 {
126 }
127
128 inline void FilterEffectRenderer::setSourceImageRect(const FloatRect& sourceImageRect)
129 {
130     m_sourceDrawingRegion = sourceImageRect;
131     setMaxEffectRects(sourceImageRect);
132     setFilterRegion(sourceImageRect);
133     m_graphicsBufferAttached = false;
134 }
135
136 } // namespace WebCore