[Conic Gradients] Add support for parsing conic gradients
[WebKit-https.git] / Source / WebCore / css / CSSGradientValue.h
index 3f1ec04..9f66aec 100644 (file)
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef CSSGradientValue_h
-#define CSSGradientValue_h
+#pragma once
 
 #include "CSSImageGeneratorValue.h"
 #include "CSSPrimitiveValue.h"
-#include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
 
 class FloatPoint;
 class Gradient;
+class StyleResolver;
 
 enum CSSGradientType {
     CSSDeprecatedLinearGradient,
@@ -42,16 +41,17 @@ enum CSSGradientType {
     CSSPrefixedLinearGradient,
     CSSPrefixedRadialGradient,
     CSSLinearGradient,
-    CSSRadialGradient
+    CSSRadialGradient,
+    CSSConicGradient
 };
 enum CSSGradientRepeat { NonRepeating, Repeating };
 
 struct CSSGradientColorStop {
-    CSSGradientColorStop() : m_colorIsDerivedFromElement(false) { };
     RefPtr<CSSPrimitiveValue> m_position; // percentage or length
     RefPtr<CSSPrimitiveValue> m_color;
     Color m_resolvedColor;
-    bool m_colorIsDerivedFromElement;
+    bool m_colorIsDerivedFromElement = false;
+    bool isMidpoint = false;
     bool operator==(const CSSGradientColorStop& other) const
     {
         return compareCSSValuePtr(m_color, other.m_color)
@@ -61,12 +61,12 @@ struct CSSGradientColorStop {
 
 class CSSGradientValue : public CSSImageGeneratorValue {
 public:
-    PassRefPtr<Image> image(RenderObject*, const IntSize&);
+    RefPtr<Image> image(RenderElement&, const FloatSize&);
 
-    void setFirstX(PassRefPtr<CSSPrimitiveValue> val) { m_firstX = val; }
-    void setFirstY(PassRefPtr<CSSPrimitiveValue> val) { m_firstY = val; }
-    void setSecondX(PassRefPtr<CSSPrimitiveValue> val) { m_secondX = val; }
-    void setSecondY(PassRefPtr<CSSPrimitiveValue> val) { m_secondY = val; }
+    void setFirstX(RefPtr<CSSPrimitiveValue>&& val) { m_firstX = WTFMove(val); }
+    void setFirstY(RefPtr<CSSPrimitiveValue>&& val) { m_firstY = WTFMove(val); }
+    void setSecondX(RefPtr<CSSPrimitiveValue>&& val) { m_secondX = WTFMove(val); }
+    void setSecondY(RefPtr<CSSPrimitiveValue>&& val) { m_secondY = WTFMove(val); }
 
     void addStop(const CSSGradientColorStop& stop) { m_stops.append(stop); }
 
@@ -74,21 +74,18 @@ public:
 
     void sortStopsIfNeeded();
 
-    bool isLinearGradient() const { return classType() == LinearGradientClass; }
-    bool isRadialGradient() const { return classType() == RadialGradientClass; }
-
     bool isRepeating() const { return m_repeating; }
 
     CSSGradientType gradientType() const { return m_gradientType; }
 
     bool isFixedSize() const { return false; }
-    IntSize fixedSize(const RenderObject*) const { return IntSize(); }
+    FloatSize fixedSize(const RenderElement&) const { return FloatSize(); }
 
     bool isPending() const { return false; }
-    bool knownToBeOpaque(const RenderObject*) const;
+    bool knownToBeOpaque() const;
 
-    void loadSubimages(CachedResourceLoader*) { }
-    PassRefPtr<CSSGradientValue> gradientWithStylesResolved(StyleResolver*);
+    void loadSubimages(CachedResourceLoader&, const ResourceLoaderOptions&) { }
+    Ref<CSSGradientValue> gradientWithStylesResolved(const StyleResolver&);
 
 protected:
     CSSGradientValue(ClassType classType, CSSGradientRepeat repeat, CSSGradientType gradientType)
@@ -112,10 +109,10 @@ protected:
     {
     }
 
-    void addStops(Gradient*, RenderObject*, RenderStyle* rootStyle, float maxLengthForRepeat = 0);
+    void addStops(Gradient&, const CSSToLengthConversionData&, float maxLengthForRepeat = 0);
 
     // Resolve points/radii to front end values.
-    FloatPoint computeEndPoint(CSSPrimitiveValue*, CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, const IntSize&);
+    FloatPoint computeEndPoint(CSSPrimitiveValue*, CSSPrimitiveValue*, const CSSToLengthConversionData&, const FloatSize&);
 
     bool isCacheable() const;
 
@@ -133,25 +130,23 @@ protected:
     bool m_repeating;
 };
 
-
-class CSSLinearGradientValue : public CSSGradientValue {
+class CSSLinearGradientValue final : public CSSGradientValue {
 public:
-
-    static PassRefPtr<CSSLinearGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
+    static Ref<CSSLinearGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
     {
-        return adoptRef(new CSSLinearGradientValue(repeat, gradientType));
+        return adoptRef(*new CSSLinearGradientValue(repeat, gradientType));
     }
 
-    void setAngle(PassRefPtr<CSSPrimitiveValue> val) { m_angle = val; }
+    void setAngle(Ref<CSSPrimitiveValue>&& val) { m_angle = WTFMove(val); }
 
     String customCSSText() const;
 
     // Create the gradient for a given size.
-    PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&);
+    Ref<Gradient> createGradient(RenderElement&, const FloatSize&);
 
-    PassRefPtr<CSSLinearGradientValue> clone() const
+    Ref<CSSLinearGradientValue> clone() const
     {
-        return adoptRef(new CSSLinearGradientValue(*this));
+        return adoptRef(*new CSSLinearGradientValue(*this));
     }
 
     bool equals(const CSSLinearGradientValue&) const;
@@ -171,31 +166,31 @@ private:
     RefPtr<CSSPrimitiveValue> m_angle; // may be null.
 };
 
-class CSSRadialGradientValue : public CSSGradientValue {
+class CSSRadialGradientValue final : public CSSGradientValue {
 public:
-    static PassRefPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
+    static Ref<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
     {
-        return adoptRef(new CSSRadialGradientValue(repeat, gradientType));
+        return adoptRef(*new CSSRadialGradientValue(repeat, gradientType));
     }
 
-    PassRefPtr<CSSRadialGradientValue> clone() const
+    Ref<CSSRadialGradientValue> clone() const
     {
-        return adoptRef(new CSSRadialGradientValue(*this));
+        return adoptRef(*new CSSRadialGradientValue(*this));
     }
 
     String customCSSText() const;
 
-    void setFirstRadius(PassRefPtr<CSSPrimitiveValue> val) { m_firstRadius = val; }
-    void setSecondRadius(PassRefPtr<CSSPrimitiveValue> val) { m_secondRadius = val; }
+    void setFirstRadius(RefPtr<CSSPrimitiveValue>&& val) { m_firstRadius = WTFMove(val); }
+    void setSecondRadius(RefPtr<CSSPrimitiveValue>&& val) { m_secondRadius = WTFMove(val); }
 
-    void setShape(PassRefPtr<CSSPrimitiveValue> val) { m_shape = val; }
-    void setSizingBehavior(PassRefPtr<CSSPrimitiveValue> val) { m_sizingBehavior = val; }
+    void setShape(RefPtr<CSSPrimitiveValue>&& val) { m_shape = WTFMove(val); }
+    void setSizingBehavior(RefPtr<CSSPrimitiveValue>&& val) { m_sizingBehavior = WTFMove(val); }
 
-    void setEndHorizontalSize(PassRefPtr<CSSPrimitiveValue> val) { m_endHorizontalSize = val; }
-    void setEndVerticalSize(PassRefPtr<CSSPrimitiveValue> val) { m_endVerticalSize = val; }
+    void setEndHorizontalSize(RefPtr<CSSPrimitiveValue>&& val) { m_endHorizontalSize = WTFMove(val); }
+    void setEndVerticalSize(RefPtr<CSSPrimitiveValue>&& val) { m_endVerticalSize = WTFMove(val); }
 
     // Create the gradient for a given size.
-    PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&);
+    Ref<Gradient> createGradient(RenderElement&, const FloatSize&);
 
     bool equals(const CSSRadialGradientValue&) const;
 
@@ -216,9 +211,8 @@ private:
     {
     }
 
-
     // Resolve points/radii to front end values.
-    float resolveRadius(CSSPrimitiveValue*, RenderStyle*, RenderStyle* rootStyle, float* widthOrHeight = 0);
+    float resolveRadius(CSSPrimitiveValue&, const CSSToLengthConversionData&, float* widthOrHeight = 0);
 
     // These may be null for non-deprecated gradients.
     RefPtr<CSSPrimitiveValue> m_firstRadius;
@@ -232,6 +226,45 @@ private:
     RefPtr<CSSPrimitiveValue> m_endVerticalSize;
 };
 
+class CSSConicGradientValue final : public CSSGradientValue {
+public:
+    static Ref<CSSConicGradientValue> create(CSSGradientRepeat repeat)
+    {
+        return adoptRef(*new CSSConicGradientValue(repeat));
+    }
+
+    Ref<CSSConicGradientValue> clone() const
+    {
+        return adoptRef(*new CSSConicGradientValue(*this));
+    }
+
+    String customCSSText() const;
+
+    void setAngle(RefPtr<CSSPrimitiveValue>&& val) { m_angle = WTFMove(val); }
+
+    // Create the gradient for a given size.
+    Ref<Gradient> createGradient(RenderElement&, const FloatSize&);
+
+    bool equals(const CSSConicGradientValue&) const;
+
+private:
+    CSSConicGradientValue(CSSGradientRepeat repeat)
+        : CSSGradientValue(ConicGradientClass, repeat, CSSConicGradient)
+    {
+    }
+
+    CSSConicGradientValue(const CSSConicGradientValue& other)
+        : CSSGradientValue(other, ConicGradientClass, other.gradientType())
+        , m_angle(other.m_angle)
+    {
+    }
+
+    RefPtr<CSSPrimitiveValue> m_angle; // may be null.
+};
+
 } // namespace WebCore
 
-#endif // CSSGradientValue_h
+SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSGradientValue, isGradientValue())
+SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSLinearGradientValue, isLinearGradientValue())
+SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSRadialGradientValue, isRadialGradientValue())
+SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSConicGradientValue, isConicGradientValue())