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 blink { 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 // This struct is stack allocated and allocated as part of vectors. 51 // When allocated on the stack its members are found by conservative 52 // stack scanning. When allocated as part of Vectors in heap-allocated 53 // objects its members are visited via the containing object's 54 // (CSSGradientValue) traceAfterDispatch method. 55 struct CSSGradientColorStop { 56 ALLOW_ONLY_INLINE_ALLOCATION(); 57 public: 58 CSSGradientColorStop() : m_colorIsDerivedFromElement(false) { }; 59 RefPtrWillBeMember<CSSPrimitiveValue> m_position; // percentage or length 60 RefPtrWillBeMember<CSSPrimitiveValue> m_color; 61 Color m_resolvedColor; 62 bool m_colorIsDerivedFromElement; 63 bool operator==(const CSSGradientColorStop& other) const 64 { 65 return compareCSSValuePtr(m_color, other.m_color) 66 && compareCSSValuePtr(m_position, other.m_position); 67 } 68 69 void trace(Visitor*); 70 }; 71 72 } // namespace blink 73 74 75 // We have to declare the VectorTraits specialization before CSSGradientValue 76 // declares its inline capacity vector below. 77 WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::CSSGradientColorStop); 78 79 namespace blink { 80 81 class CSSGradientValue : public CSSImageGeneratorValue { 82 public: 83 PassRefPtr<Image> image(RenderObject*, const IntSize&); 84 85 void setFirstX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_firstX = val; } 86 void setFirstY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_firstY = val; } 87 void setSecondX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_secondX = val; } 88 void setSecondY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_secondY = val; } 89 90 void addStop(const CSSGradientColorStop& stop) { m_stops.append(stop); } 91 92 unsigned stopCount() const { return m_stops.size(); } 93 94 void sortStopsIfNeeded(); 95 96 bool isRepeating() const { return m_repeating; } 97 98 CSSGradientType gradientType() const { return m_gradientType; } 99 100 bool isFixedSize() const { return false; } 101 IntSize fixedSize(const RenderObject*) const { return IntSize(); } 102 103 bool isPending() const { return false; } 104 bool knownToBeOpaque(const RenderObject*) const; 105 106 void loadSubimages(ResourceFetcher*) { } 107 PassRefPtrWillBeRawPtr<CSSGradientValue> gradientWithStylesResolved(const TextLinkColors&, Color currentColor); 108 109 void traceAfterDispatch(Visitor*); 110 111 protected: 112 CSSGradientValue(ClassType classType, CSSGradientRepeat repeat, CSSGradientType gradientType) 113 : CSSImageGeneratorValue(classType) 114 , m_stopsSorted(false) 115 , m_gradientType(gradientType) 116 , m_repeating(repeat == Repeating) 117 { 118 } 119 120 CSSGradientValue(const CSSGradientValue& other, ClassType classType, CSSGradientType gradientType) 121 : CSSImageGeneratorValue(classType) 122 , m_firstX(other.m_firstX) 123 , m_firstY(other.m_firstY) 124 , m_secondX(other.m_secondX) 125 , m_secondY(other.m_secondY) 126 , m_stops(other.m_stops) 127 , m_stopsSorted(other.m_stopsSorted) 128 , m_gradientType(gradientType) 129 , m_repeating(other.isRepeating() ? Repeating : NonRepeating) 130 { 131 } 132 133 void addStops(Gradient*, const CSSToLengthConversionData&, float maxLengthForRepeat = 0); 134 135 // Resolve points/radii to front end values. 136 FloatPoint computeEndPoint(CSSPrimitiveValue*, CSSPrimitiveValue*, const CSSToLengthConversionData&, const IntSize&); 137 138 bool isCacheable() const; 139 140 // Points. Some of these may be null. 141 RefPtrWillBeMember<CSSPrimitiveValue> m_firstX; 142 RefPtrWillBeMember<CSSPrimitiveValue> m_firstY; 143 144 RefPtrWillBeMember<CSSPrimitiveValue> m_secondX; 145 RefPtrWillBeMember<CSSPrimitiveValue> m_secondY; 146 147 // Stops 148 WillBeHeapVector<CSSGradientColorStop, 2> m_stops; 149 bool m_stopsSorted; 150 CSSGradientType m_gradientType; 151 bool m_repeating; 152 }; 153 154 DEFINE_CSS_VALUE_TYPE_CASTS(CSSGradientValue, isGradientValue()); 155 156 class CSSLinearGradientValue : public CSSGradientValue { 157 public: 158 159 static PassRefPtrWillBeRawPtr<CSSLinearGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient) 160 { 161 return adoptRefWillBeNoop(new CSSLinearGradientValue(repeat, gradientType)); 162 } 163 164 void setAngle(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_angle = val; } 165 166 String customCSSText() const; 167 168 // Create the gradient for a given size. 169 PassRefPtr<Gradient> createGradient(const CSSToLengthConversionData&, const IntSize&); 170 171 PassRefPtrWillBeRawPtr<CSSLinearGradientValue> clone() const 172 { 173 return adoptRefWillBeNoop(new CSSLinearGradientValue(*this)); 174 } 175 176 bool equals(const CSSLinearGradientValue&) const; 177 178 void traceAfterDispatch(Visitor*); 179 180 private: 181 CSSLinearGradientValue(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient) 182 : CSSGradientValue(LinearGradientClass, repeat, gradientType) 183 { 184 } 185 186 explicit CSSLinearGradientValue(const CSSLinearGradientValue& other) 187 : CSSGradientValue(other, LinearGradientClass, other.gradientType()) 188 , m_angle(other.m_angle) 189 { 190 } 191 192 RefPtrWillBeMember<CSSPrimitiveValue> m_angle; // may be null. 193 }; 194 195 DEFINE_CSS_VALUE_TYPE_CASTS(CSSLinearGradientValue, isLinearGradientValue()); 196 197 class CSSRadialGradientValue : public CSSGradientValue { 198 public: 199 static PassRefPtrWillBeRawPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient) 200 { 201 return adoptRefWillBeNoop(new CSSRadialGradientValue(repeat, gradientType)); 202 } 203 204 PassRefPtrWillBeRawPtr<CSSRadialGradientValue> clone() const 205 { 206 return adoptRefWillBeNoop(new CSSRadialGradientValue(*this)); 207 } 208 209 String customCSSText() const; 210 211 void setFirstRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_firstRadius = val; } 212 void setSecondRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_secondRadius = val; } 213 214 void setShape(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_shape = val; } 215 void setSizingBehavior(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_sizingBehavior = val; } 216 217 void setEndHorizontalSize(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_endHorizontalSize = val; } 218 void setEndVerticalSize(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_endVerticalSize = val; } 219 220 // Create the gradient for a given size. 221 PassRefPtr<Gradient> createGradient(const CSSToLengthConversionData&, const IntSize&); 222 223 bool equals(const CSSRadialGradientValue&) const; 224 225 void traceAfterDispatch(Visitor*); 226 227 private: 228 CSSRadialGradientValue(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient) 229 : CSSGradientValue(RadialGradientClass, repeat, gradientType) 230 { 231 } 232 233 explicit CSSRadialGradientValue(const CSSRadialGradientValue& other) 234 : CSSGradientValue(other, RadialGradientClass, other.gradientType()) 235 , m_firstRadius(other.m_firstRadius) 236 , m_secondRadius(other.m_secondRadius) 237 , m_shape(other.m_shape) 238 , m_sizingBehavior(other.m_sizingBehavior) 239 , m_endHorizontalSize(other.m_endHorizontalSize) 240 , m_endVerticalSize(other.m_endVerticalSize) 241 { 242 } 243 244 245 // Resolve points/radii to front end values. 246 float resolveRadius(CSSPrimitiveValue*, const CSSToLengthConversionData&, float* widthOrHeight = 0); 247 248 // These may be null for non-deprecated gradients. 249 RefPtrWillBeMember<CSSPrimitiveValue> m_firstRadius; 250 RefPtrWillBeMember<CSSPrimitiveValue> m_secondRadius; 251 252 // The below are only used for non-deprecated gradients. Any of them may be null. 253 RefPtrWillBeMember<CSSPrimitiveValue> m_shape; 254 RefPtrWillBeMember<CSSPrimitiveValue> m_sizingBehavior; 255 256 RefPtrWillBeMember<CSSPrimitiveValue> m_endHorizontalSize; 257 RefPtrWillBeMember<CSSPrimitiveValue> m_endVerticalSize; 258 }; 259 260 DEFINE_CSS_VALUE_TYPE_CASTS(CSSRadialGradientValue, isRadialGradientValue()); 261 262 } // namespace blink 263 264 #endif // CSSGradientValue_h 265