1 /*
2 * Copyright (C) 2008 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 COMPUTER, 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 COMPUTER, 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 THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_GRADIENT_VALUE_H_
27 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_GRADIENT_VALUE_H_
28
29 #include "base/memory/scoped_refptr.h"
30 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
31 #include "third_party/blink/renderer/core/css/css_image_generator_value.h"
32 #include "third_party/blink/renderer/core/css/css_primitive_value.h"
33 #include "third_party/blink/renderer/platform/wtf/casting.h"
34 #include "third_party/blink/renderer/platform/wtf/vector.h"
35
36 namespace blink {
37
38 class Color;
39 class Gradient;
40 class Document;
41
42 namespace cssvalue {
43
44 enum CSSGradientType {
45 kCSSDeprecatedLinearGradient,
46 kCSSDeprecatedRadialGradient,
47 kCSSPrefixedLinearGradient,
48 kCSSPrefixedRadialGradient,
49 kCSSLinearGradient,
50 kCSSRadialGradient,
51 kCSSConicGradient
52 };
53 enum CSSGradientRepeat { kNonRepeating, kRepeating };
54
55 // This struct is stack allocated and allocated as part of vectors.
56 // When allocated on the stack its members are found by conservative
57 // stack scanning. When allocated as part of Vectors in heap-allocated
58 // objects its members are visited via the containing object's
59 // (CSSGradientValue) traceAfterDispatch method.
60 //
61 // http://www.w3.org/TR/css3-images/#color-stop-syntax
62 struct CSSGradientColorStop {
63 DISALLOW_NEW();
64
65 bool operator==(const CSSGradientColorStop& other) const {
66 return DataEquivalent(color_, other.color_) &&
67 DataEquivalent(offset_, other.offset_);
68 }
69
IsHintCSSGradientColorStop70 bool IsHint() const {
71 DCHECK(color_ || offset_);
72 return !color_;
73 }
74
75 bool IsCacheable() const;
76
77 void Trace(Visitor*);
78
79 Member<const CSSPrimitiveValue> offset_; // percentage | length | angle
80 Member<const CSSValue> color_;
81 };
82
83 } // namespace cssvalue
84 } // namespace blink
85
86 // We have to declare the VectorTraits specialization before CSSGradientValue
87 // declares its inline capacity vector below.
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::cssvalue::CSSGradientColorStop)88 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(
89 blink::cssvalue::CSSGradientColorStop)
90
91 namespace blink {
92 namespace cssvalue {
93
94 class CSSGradientValue : public CSSImageGeneratorValue {
95 public:
96 scoped_refptr<Image> GetImage(const ImageResourceObserver&,
97 const Document&,
98 const ComputedStyle&,
99 const FloatSize&) const;
100
101 void AddStop(const CSSGradientColorStop& stop) {
102 stops_.push_back(stop);
103 is_cacheable_ = is_cacheable_ && stop.IsCacheable();
104 }
105
106 size_t StopCount() const { return stops_.size(); }
107
108 bool IsRepeating() const { return repeating_; }
109
110 CSSGradientType GradientType() const { return gradient_type_; }
111
112 bool IsFixedSize() const { return false; }
113 FloatSize FixedSize(const Document&) const { return FloatSize(); }
114
115 bool IsPending() const { return false; }
116 bool KnownToBeOpaque(const Document&, const ComputedStyle&) const;
117
118 void LoadSubimages(const Document&) {}
119
120 Vector<Color> GetStopColors(const Document&, const ComputedStyle&) const;
121
122 void TraceAfterDispatch(blink::Visitor*) const;
123
124 struct GradientDesc;
125
126 protected:
127 CSSGradientValue(ClassType class_type,
128 CSSGradientRepeat repeat,
129 CSSGradientType gradient_type)
130 : CSSImageGeneratorValue(class_type),
131 gradient_type_(gradient_type),
132 repeating_(repeat == kRepeating),
133 is_cacheable_(true) {}
134
135 void AddStops(GradientDesc&,
136 const CSSToLengthConversionData&,
137 const Document&,
138 const ComputedStyle&) const;
139 void AddDeprecatedStops(GradientDesc&,
140 const Document&,
141 const ComputedStyle&) const;
142 void AddComputedStops(const ComputedStyle&,
143 bool allow_visited_style,
144 const HeapVector<CSSGradientColorStop, 2>& stops);
145
146 void AppendCSSTextForColorStops(StringBuilder&,
147 bool requires_separator) const;
148 void AppendCSSTextForDeprecatedColorStops(StringBuilder&) const;
149
150 // Stops
151 HeapVector<CSSGradientColorStop, 2> stops_;
152 CSSGradientType gradient_type_;
153 bool repeating_ : 1;
154 bool is_cacheable_ : 1;
155 };
156
157 class CSSLinearGradientValue final : public CSSGradientValue {
158 public:
159 CSSLinearGradientValue(const CSSValue* first_x,
160 const CSSValue* first_y,
161 const CSSValue* second_x,
162 const CSSValue* second_y,
163 const CSSPrimitiveValue* angle,
164 CSSGradientRepeat repeat,
165 CSSGradientType gradient_type = kCSSLinearGradient)
166 : CSSGradientValue(kLinearGradientClass, repeat, gradient_type),
167 first_x_(first_x),
168 first_y_(first_y),
169 second_x_(second_x),
170 second_y_(second_y),
171 angle_(angle) {}
172
173 String CustomCSSText() const;
174
175 // Create the gradient for a given size.
176 scoped_refptr<Gradient> CreateGradient(const CSSToLengthConversionData&,
177 const FloatSize&,
178 const Document&,
179 const ComputedStyle&) const;
180
181 bool Equals(const CSSLinearGradientValue&) const;
182
183 CSSLinearGradientValue* ComputedCSSValue(const ComputedStyle&,
184 bool allow_visited_style);
185
186 void TraceAfterDispatch(blink::Visitor*) const;
187
188 private:
189 // Any of these may be null.
190 Member<const CSSValue> first_x_;
191 Member<const CSSValue> first_y_;
192 Member<const CSSValue> second_x_;
193 Member<const CSSValue> second_y_;
194 Member<const CSSPrimitiveValue> angle_;
195 };
196
197 class CSSRadialGradientValue final : public CSSGradientValue {
198 public:
199 CSSRadialGradientValue(const CSSValue* first_x,
200 const CSSValue* first_y,
201 const CSSPrimitiveValue* first_radius,
202 const CSSValue* second_x,
203 const CSSValue* second_y,
204 const CSSPrimitiveValue* second_radius,
205 const CSSIdentifierValue* shape,
206 const CSSIdentifierValue* sizing_behavior,
207 const CSSPrimitiveValue* horizontal_size,
208 const CSSPrimitiveValue* vertical_size,
209 CSSGradientRepeat repeat,
210 CSSGradientType gradient_type = kCSSRadialGradient)
211 : CSSGradientValue(kRadialGradientClass, repeat, gradient_type),
212 first_x_(first_x),
213 first_y_(first_y),
214 second_x_(second_x),
215 second_y_(second_y),
216 first_radius_(first_radius),
217 second_radius_(second_radius),
218 shape_(shape),
219 sizing_behavior_(sizing_behavior),
220 end_horizontal_size_(horizontal_size),
221 end_vertical_size_(vertical_size) {}
222
223 CSSRadialGradientValue(const CSSValue* first_x,
224 const CSSValue* first_y,
225 const CSSPrimitiveValue* first_radius,
226 const CSSValue* second_x,
227 const CSSValue* second_y,
228 const CSSPrimitiveValue* second_radius,
229 CSSGradientRepeat repeat,
230 CSSGradientType gradient_type = kCSSRadialGradient)
231 : CSSGradientValue(kRadialGradientClass, repeat, gradient_type),
232 first_x_(first_x),
233 first_y_(first_y),
234 second_x_(second_x),
235 second_y_(second_y),
236 first_radius_(first_radius),
237 second_radius_(second_radius),
238 shape_(nullptr),
239 sizing_behavior_(nullptr),
240 end_horizontal_size_(nullptr),
241 end_vertical_size_(nullptr) {}
242
243 CSSRadialGradientValue(const CSSValue* center_x,
244 const CSSValue* center_y,
245 const CSSIdentifierValue* shape,
246 const CSSIdentifierValue* sizing_behavior,
247 const CSSPrimitiveValue* horizontal_size,
248 const CSSPrimitiveValue* vertical_size,
249 CSSGradientRepeat repeat,
250 CSSGradientType gradient_type)
251 : CSSGradientValue(kRadialGradientClass, repeat, gradient_type),
252 first_x_(center_x),
253 first_y_(center_y),
254 second_x_(center_x),
255 second_y_(center_y),
256 first_radius_(nullptr),
257 second_radius_(nullptr),
258 shape_(shape),
259 sizing_behavior_(sizing_behavior),
260 end_horizontal_size_(horizontal_size),
261 end_vertical_size_(vertical_size) {}
262
263 String CustomCSSText() const;
264
265 void SetShape(CSSIdentifierValue* val) { shape_ = val; }
266 void SetSizingBehavior(CSSIdentifierValue* val) { sizing_behavior_ = val; }
267
268 void SetEndHorizontalSize(CSSPrimitiveValue* val) {
269 end_horizontal_size_ = val;
270 }
271 void SetEndVerticalSize(CSSPrimitiveValue* val) { end_vertical_size_ = val; }
272
273 // Create the gradient for a given size.
274 scoped_refptr<Gradient> CreateGradient(const CSSToLengthConversionData&,
275 const FloatSize&,
276 const Document&,
277 const ComputedStyle&) const;
278
279 bool Equals(const CSSRadialGradientValue&) const;
280
281 CSSRadialGradientValue* ComputedCSSValue(const ComputedStyle&,
282 bool allow_visited_style);
283
284 void TraceAfterDispatch(blink::Visitor*) const;
285
286 private:
287 // Any of these may be null.
288 Member<const CSSValue> first_x_;
289 Member<const CSSValue> first_y_;
290 Member<const CSSValue> second_x_;
291 Member<const CSSValue> second_y_;
292
293 // These may be null for non-deprecated gradients.
294 Member<const CSSPrimitiveValue> first_radius_;
295 Member<const CSSPrimitiveValue> second_radius_;
296
297 // The below are only used for non-deprecated gradients. Any of them may be
298 // null.
299 Member<const CSSIdentifierValue> shape_;
300 Member<const CSSIdentifierValue> sizing_behavior_;
301
302 Member<const CSSPrimitiveValue> end_horizontal_size_;
303 Member<const CSSPrimitiveValue> end_vertical_size_;
304 };
305
306 class CSSConicGradientValue final : public CSSGradientValue {
307 public:
308 CSSConicGradientValue(const CSSValue* x,
309 const CSSValue* y,
310 const CSSPrimitiveValue* from_angle,
311 CSSGradientRepeat repeat)
312 : CSSGradientValue(kConicGradientClass, repeat, kCSSConicGradient),
313 x_(x),
314 y_(y),
315 from_angle_(from_angle) {}
316
317 String CustomCSSText() const;
318
319 // Create the gradient for a given size.
320 scoped_refptr<Gradient> CreateGradient(const CSSToLengthConversionData&,
321 const FloatSize&,
322 const Document&,
323 const ComputedStyle&) const;
324
325 bool Equals(const CSSConicGradientValue&) const;
326
327 CSSConicGradientValue* ComputedCSSValue(const ComputedStyle&,
328 bool allow_visited_style);
329
330 void TraceAfterDispatch(blink::Visitor*) const;
331
332 private:
333 // Any of these may be null.
334 Member<const CSSValue> x_;
335 Member<const CSSValue> y_;
336 Member<const CSSPrimitiveValue> from_angle_;
337 };
338
339 } // namespace cssvalue
340
341 template <>
342 struct DowncastTraits<cssvalue::CSSGradientValue> {
343 static bool AllowFrom(const CSSValue& value) {
344 return value.IsGradientValue();
345 }
346 };
347
348 template <>
349 struct DowncastTraits<cssvalue::CSSLinearGradientValue> {
350 static bool AllowFrom(const CSSValue& value) {
351 return value.IsLinearGradientValue();
352 }
353 };
354
355 template <>
356 struct DowncastTraits<cssvalue::CSSRadialGradientValue> {
357 static bool AllowFrom(const CSSValue& value) {
358 return value.IsRadialGradientValue();
359 }
360 };
361
362 template <>
363 struct DowncastTraits<cssvalue::CSSConicGradientValue> {
364 static bool AllowFrom(const CSSValue& value) {
365 return value.IsConicGradientValue();
366 }
367 };
368
369 } // namespace blink
370
371 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_GRADIENT_VALUE_H_
372