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