Unreviewed, rolling out r156253.
[WebKit-https.git] / Source / WebCore / css / CSSGradientValue.h
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 CSSGradientValue_h
27 #define CSSGradientValue_h
28
29 #include "CSSImageGeneratorValue.h"
30 #include "CSSPrimitiveValue.h"
31 #include <wtf/RefPtr.h>
32 #include <wtf/Vector.h>
33
34 namespace WebCore {
35
36 class FloatPoint;
37 class Gradient;
38
39 enum CSSGradientType {
40     CSSDeprecatedLinearGradient,
41     CSSDeprecatedRadialGradient,
42     CSSPrefixedLinearGradient,
43     CSSPrefixedRadialGradient,
44     CSSLinearGradient,
45     CSSRadialGradient
46 };
47 enum CSSGradientRepeat { NonRepeating, Repeating };
48
49 struct CSSGradientColorStop {
50     CSSGradientColorStop() : m_colorIsDerivedFromElement(false) { };
51     RefPtr<CSSPrimitiveValue> m_position; // percentage or length
52     RefPtr<CSSPrimitiveValue> m_color;
53     Color m_resolvedColor;
54     bool m_colorIsDerivedFromElement;
55     bool operator==(const CSSGradientColorStop& other) const
56     {
57         return compareCSSValuePtr(m_color, other.m_color)
58             && compareCSSValuePtr(m_position, other.m_position);
59     }
60 };
61
62 class CSSGradientValue : public CSSImageGeneratorValue {
63 public:
64     PassRefPtr<Image> image(RenderObject*, const IntSize&);
65
66     void setFirstX(PassRefPtr<CSSPrimitiveValue> val) { m_firstX = val; }
67     void setFirstY(PassRefPtr<CSSPrimitiveValue> val) { m_firstY = val; }
68     void setSecondX(PassRefPtr<CSSPrimitiveValue> val) { m_secondX = val; }
69     void setSecondY(PassRefPtr<CSSPrimitiveValue> val) { m_secondY = val; }
70
71     void addStop(const CSSGradientColorStop& stop) { m_stops.append(stop); }
72
73     unsigned stopCount() const { return m_stops.size(); }
74
75     void sortStopsIfNeeded();
76
77     bool isLinearGradient() const { return classType() == LinearGradientClass; }
78     bool isRadialGradient() const { return classType() == RadialGradientClass; }
79
80     bool isRepeating() const { return m_repeating; }
81
82     CSSGradientType gradientType() const { return m_gradientType; }
83
84     bool isFixedSize() const { return false; }
85     IntSize fixedSize(const RenderObject*) const { return IntSize(); }
86
87     bool isPending() const { return false; }
88     bool knownToBeOpaque(const RenderObject*) const;
89
90     void loadSubimages(CachedResourceLoader*) { }
91     PassRefPtr<CSSGradientValue> gradientWithStylesResolved(StyleResolver*);
92
93 protected:
94     CSSGradientValue(ClassType classType, CSSGradientRepeat repeat, CSSGradientType gradientType)
95         : CSSImageGeneratorValue(classType)
96         , m_stopsSorted(false)
97         , m_gradientType(gradientType)
98         , m_repeating(repeat == Repeating)
99     {
100     }
101
102     CSSGradientValue(const CSSGradientValue& other, ClassType classType, CSSGradientType gradientType)
103         : CSSImageGeneratorValue(classType)
104         , m_firstX(other.m_firstX)
105         , m_firstY(other.m_firstY)
106         , m_secondX(other.m_secondX)
107         , m_secondY(other.m_secondY)
108         , m_stops(other.m_stops)
109         , m_stopsSorted(other.m_stopsSorted)
110         , m_gradientType(gradientType)
111         , m_repeating(other.isRepeating() ? Repeating : NonRepeating)
112     {
113     }
114
115     void addStops(Gradient*, RenderObject*, RenderStyle* rootStyle, float maxLengthForRepeat = 0);
116
117     // Resolve points/radii to front end values.
118     FloatPoint computeEndPoint(CSSPrimitiveValue*, CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, const IntSize&);
119
120     bool isCacheable() const;
121
122     // Points. Some of these may be null.
123     RefPtr<CSSPrimitiveValue> m_firstX;
124     RefPtr<CSSPrimitiveValue> m_firstY;
125
126     RefPtr<CSSPrimitiveValue> m_secondX;
127     RefPtr<CSSPrimitiveValue> m_secondY;
128
129     // Stops
130     Vector<CSSGradientColorStop, 2> m_stops;
131     bool m_stopsSorted;
132     CSSGradientType m_gradientType;
133     bool m_repeating;
134 };
135
136
137 class CSSLinearGradientValue : public CSSGradientValue {
138 public:
139
140     static PassRefPtr<CSSLinearGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
141     {
142         return adoptRef(new CSSLinearGradientValue(repeat, gradientType));
143     }
144
145     void setAngle(PassRefPtr<CSSPrimitiveValue> val) { m_angle = val; }
146
147     String customCSSText() const;
148
149     // Create the gradient for a given size.
150     PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&);
151
152     PassRefPtr<CSSLinearGradientValue> clone() const
153     {
154         return adoptRef(new CSSLinearGradientValue(*this));
155     }
156
157     bool equals(const CSSLinearGradientValue&) const;
158
159 private:
160     CSSLinearGradientValue(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
161         : CSSGradientValue(LinearGradientClass, repeat, gradientType)
162     {
163     }
164
165     CSSLinearGradientValue(const CSSLinearGradientValue& other)
166         : CSSGradientValue(other, LinearGradientClass, other.gradientType())
167         , m_angle(other.m_angle)
168     {
169     }
170
171     RefPtr<CSSPrimitiveValue> m_angle; // may be null.
172 };
173
174 class CSSRadialGradientValue : public CSSGradientValue {
175 public:
176     static PassRefPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
177     {
178         return adoptRef(new CSSRadialGradientValue(repeat, gradientType));
179     }
180
181     PassRefPtr<CSSRadialGradientValue> clone() const
182     {
183         return adoptRef(new CSSRadialGradientValue(*this));
184     }
185
186     String customCSSText() const;
187
188     void setFirstRadius(PassRefPtr<CSSPrimitiveValue> val) { m_firstRadius = val; }
189     void setSecondRadius(PassRefPtr<CSSPrimitiveValue> val) { m_secondRadius = val; }
190
191     void setShape(PassRefPtr<CSSPrimitiveValue> val) { m_shape = val; }
192     void setSizingBehavior(PassRefPtr<CSSPrimitiveValue> val) { m_sizingBehavior = val; }
193
194     void setEndHorizontalSize(PassRefPtr<CSSPrimitiveValue> val) { m_endHorizontalSize = val; }
195     void setEndVerticalSize(PassRefPtr<CSSPrimitiveValue> val) { m_endVerticalSize = val; }
196
197     // Create the gradient for a given size.
198     PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&);
199
200     bool equals(const CSSRadialGradientValue&) const;
201
202 private:
203     CSSRadialGradientValue(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
204         : CSSGradientValue(RadialGradientClass, repeat, gradientType)
205     {
206     }
207
208     CSSRadialGradientValue(const CSSRadialGradientValue& other)
209         : CSSGradientValue(other, RadialGradientClass, other.gradientType())
210         , m_firstRadius(other.m_firstRadius)
211         , m_secondRadius(other.m_secondRadius)
212         , m_shape(other.m_shape)
213         , m_sizingBehavior(other.m_sizingBehavior)
214         , m_endHorizontalSize(other.m_endHorizontalSize)
215         , m_endVerticalSize(other.m_endVerticalSize)
216     {
217     }
218
219
220     // Resolve points/radii to front end values.
221     float resolveRadius(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, float* widthOrHeight = 0);
222
223     // These may be null for non-deprecated gradients.
224     RefPtr<CSSPrimitiveValue> m_firstRadius;
225     RefPtr<CSSPrimitiveValue> m_secondRadius;
226
227     // The below are only used for non-deprecated gradients. Any of them may be null.
228     RefPtr<CSSPrimitiveValue> m_shape;
229     RefPtr<CSSPrimitiveValue> m_sizingBehavior;
230
231     RefPtr<CSSPrimitiveValue> m_endHorizontalSize;
232     RefPtr<CSSPrimitiveValue> m_endVerticalSize;
233 };
234
235 } // namespace WebCore
236
237 #endif // CSSGradientValue_h