Home | History | Annotate | Download | only in css
      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