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