1 | /* |
2 | * Copyright (C) 2012, 2013 Adobe Systems Incorporated. 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 | * |
8 | * 1. Redistributions of source code must retain the above |
9 | * copyright notice, this list of conditions and the following |
10 | * disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above |
12 | * copyright notice, this list of conditions and the following |
13 | * disclaimer in the documentation and/or other materials |
14 | * provided with the distribution. |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE |
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, |
21 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR |
25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF |
26 | * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. |
28 | */ |
29 | |
30 | #pragma once |
31 | |
32 | #include "BasicShapes.h" |
33 | #include "Path.h" |
34 | #include "RenderStyleConstants.h" |
35 | #include <wtf/RefCounted.h> |
36 | #include <wtf/TypeCasts.h> |
37 | #include <wtf/text/WTFString.h> |
38 | |
39 | namespace WebCore { |
40 | |
41 | class ClipPathOperation : public RefCounted<ClipPathOperation> { |
42 | public: |
43 | enum OperationType { |
44 | Reference, |
45 | Shape, |
46 | Box |
47 | }; |
48 | |
49 | virtual ~ClipPathOperation() = default; |
50 | |
51 | virtual bool operator==(const ClipPathOperation&) const = 0; |
52 | bool operator!=(const ClipPathOperation& o) const { return !(*this == o); } |
53 | |
54 | OperationType type() const { return m_type; } |
55 | bool isSameType(const ClipPathOperation& o) const { return o.type() == m_type; } |
56 | |
57 | protected: |
58 | explicit ClipPathOperation(OperationType type) |
59 | : m_type(type) |
60 | { |
61 | } |
62 | |
63 | OperationType m_type; |
64 | }; |
65 | |
66 | class ReferenceClipPathOperation final : public ClipPathOperation { |
67 | public: |
68 | static Ref<ReferenceClipPathOperation> create(const String& url, const String& fragment) |
69 | { |
70 | return adoptRef(*new ReferenceClipPathOperation(url, fragment)); |
71 | } |
72 | |
73 | const String& url() const { return m_url; } |
74 | const String& fragment() const { return m_fragment; } |
75 | |
76 | private: |
77 | bool operator==(const ClipPathOperation& other) const override |
78 | { |
79 | if (!isSameType(other)) |
80 | return false; |
81 | auto& referenceClip = downcast<ReferenceClipPathOperation>(other); |
82 | return m_url == referenceClip.m_url; |
83 | } |
84 | |
85 | ReferenceClipPathOperation(const String& url, const String& fragment) |
86 | : ClipPathOperation(Reference) |
87 | , m_url(url) |
88 | , m_fragment(fragment) |
89 | { |
90 | } |
91 | |
92 | String m_url; |
93 | String m_fragment; |
94 | }; |
95 | |
96 | class ShapeClipPathOperation final : public ClipPathOperation { |
97 | public: |
98 | static Ref<ShapeClipPathOperation> create(Ref<BasicShape>&& shape) |
99 | { |
100 | return adoptRef(*new ShapeClipPathOperation(WTFMove(shape))); |
101 | } |
102 | |
103 | const BasicShape& basicShape() const { return m_shape; } |
104 | WindRule windRule() const { return m_shape.get().windRule(); } |
105 | const Path& pathForReferenceRect(const FloatRect& boundingRect) { return m_shape.get().path(boundingRect); } |
106 | |
107 | void setReferenceBox(CSSBoxType referenceBox) { m_referenceBox = referenceBox; } |
108 | CSSBoxType referenceBox() const { return m_referenceBox; } |
109 | |
110 | private: |
111 | bool operator==(const ClipPathOperation& other) const override |
112 | { |
113 | if (!isSameType(other)) |
114 | return false; |
115 | auto& shapeClip = downcast<ShapeClipPathOperation>(other); |
116 | return m_referenceBox == shapeClip.referenceBox() |
117 | && (m_shape.ptr() == shapeClip.m_shape.ptr() || m_shape.get() == shapeClip.m_shape.get()); |
118 | } |
119 | |
120 | explicit ShapeClipPathOperation(Ref<BasicShape>&& shape) |
121 | : ClipPathOperation(Shape) |
122 | , m_shape(WTFMove(shape)) |
123 | , m_referenceBox(CSSBoxType::BoxMissing) |
124 | { |
125 | } |
126 | |
127 | Ref<BasicShape> m_shape; |
128 | CSSBoxType m_referenceBox; |
129 | }; |
130 | |
131 | class BoxClipPathOperation final : public ClipPathOperation { |
132 | public: |
133 | static Ref<BoxClipPathOperation> create(CSSBoxType referenceBox) |
134 | { |
135 | return adoptRef(*new BoxClipPathOperation(referenceBox)); |
136 | } |
137 | |
138 | const Path pathForReferenceRect(const FloatRoundedRect& boundingRect) const |
139 | { |
140 | Path path; |
141 | path.addRoundedRect(boundingRect); |
142 | return path; |
143 | } |
144 | CSSBoxType referenceBox() const { return m_referenceBox; } |
145 | |
146 | private: |
147 | bool operator==(const ClipPathOperation& other) const override |
148 | { |
149 | if (!isSameType(other)) |
150 | return false; |
151 | auto& boxClip = downcast<BoxClipPathOperation>(other); |
152 | return m_referenceBox == boxClip.m_referenceBox; |
153 | } |
154 | |
155 | explicit BoxClipPathOperation(CSSBoxType referenceBox) |
156 | : ClipPathOperation(Box) |
157 | , m_referenceBox(referenceBox) |
158 | { |
159 | } |
160 | |
161 | CSSBoxType m_referenceBox; |
162 | }; |
163 | |
164 | } // namespace WebCore |
165 | |
166 | #define SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(ToValueTypeName, predicate) \ |
167 | SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ |
168 | static bool isType(const WebCore::ClipPathOperation& operation) { return operation.type() == WebCore::predicate; } \ |
169 | SPECIALIZE_TYPE_TRAITS_END() |
170 | |
171 | SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(ReferenceClipPathOperation, ClipPathOperation::Reference) |
172 | SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(ShapeClipPathOperation, ClipPathOperation::Shape) |
173 | SPECIALIZE_TYPE_TRAITS_CLIP_PATH_OPERATION(BoxClipPathOperation, ClipPathOperation::Box) |
174 | |