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 34namespace WebCore { 35 36class FloatPoint; 37class Gradient; 38 39enum CSSGradientType { 40 CSSDeprecatedLinearGradient, 41 CSSDeprecatedRadialGradient, 42 CSSPrefixedLinearGradient, 43 CSSPrefixedRadialGradient, 44 CSSLinearGradient, 45 CSSRadialGradient 46}; 47enum CSSGradientRepeat { NonRepeating, Repeating }; 48 49struct 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 62class CSSGradientValue : public CSSImageGeneratorValue { 63public: 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 93protected: 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 137class CSSLinearGradientValue : public CSSGradientValue { 138public: 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 159private: 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 174class CSSRadialGradientValue : public CSSGradientValue { 175public: 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 202private: 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 238