2009-01-27 Evan Stade <estade@chromium.org>
authordglazkov@chromium.org <dglazkov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Jan 2009 17:13:59 +0000 (17:13 +0000)
committerdglazkov@chromium.org <dglazkov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 27 Jan 2009 17:13:59 +0000 (17:13 +0000)
        Reviewed by Nikolas Zimmermann.

        https://bugs.webkit.org/show_bug.cgi?id=23435
        Make spreadMethod a member of Gradient rather than GraphicsContext.
        Implement spreadMethod for Skia.

        * platform/graphics/Gradient.cpp:
        (WebCore::Gradient::Gradient):
        * platform/graphics/Gradient.h:
        (WebCore::Gradient::setSpreadMethod):
        (WebCore::Gradient::spreadMethod):
        * platform/graphics/GraphicsContext.cpp:
        * platform/graphics/GraphicsContext.h:
        * platform/graphics/GraphicsContextPrivate.h:
        * platform/graphics/GraphicsTypes.h:
        (WebCore::):
        * platform/graphics/cairo/GradientCairo.cpp:
        (WebCore::Gradient::platformGradient):
        * platform/graphics/cairo/GraphicsContextCairo.cpp:
        (WebCore::GraphicsContext::fillPath):
        (WebCore::GraphicsContext::strokePath):
        * platform/graphics/qt/GradientQt.cpp:
        (WebCore::Gradient::platformGradient):
        * platform/graphics/qt/GraphicsContextQt.cpp:
        (WebCore::GraphicsContext::fillPath):
        (WebCore::GraphicsContext::strokePath):
        * platform/graphics/skia/GradientSkia.cpp:
        (WebCore::Gradient::platformGradient):
        * svg/SVGLinearGradientElement.cpp:
        (WebCore::SVGLinearGradientElement::buildGradient):
        * svg/SVGRadialGradientElement.cpp:
        (WebCore::SVGRadialGradientElement::buildGradient):
        * svg/graphics/SVGPaintServerGradient.cpp:
        (WebCore::SVGPaintServerGradient::SVGPaintServerGradient):
        (WebCore::SVGPaintServerGradient::setup):
        (WebCore::SVGPaintServerGradient::externalRepresentation):
        * svg/graphics/SVGPaintServerGradient.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@40292 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
WebCore/ChangeLog
WebCore/platform/graphics/Gradient.cpp
WebCore/platform/graphics/Gradient.h
WebCore/platform/graphics/GraphicsContext.cpp
WebCore/platform/graphics/GraphicsContext.h
WebCore/platform/graphics/GraphicsContextPrivate.h
WebCore/platform/graphics/GraphicsTypes.h
WebCore/platform/graphics/cairo/GradientCairo.cpp
WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
WebCore/platform/graphics/qt/GradientQt.cpp
WebCore/platform/graphics/qt/GraphicsContextQt.cpp
WebCore/platform/graphics/skia/GradientSkia.cpp
WebCore/svg/SVGLinearGradientElement.cpp
WebCore/svg/SVGRadialGradientElement.cpp
WebCore/svg/graphics/SVGPaintServerGradient.cpp
WebCore/svg/graphics/SVGPaintServerGradient.h

index d64f261aee975556094c1931294e4e6e8bd27bf4..317f73ed04b8a373fd12396d8436831cbe412bb5 100644 (file)
@@ -1,3 +1,43 @@
+2009-01-27  Evan Stade  <estade@chromium.org>
+
+        Reviewed by Nikolas Zimmermann.
+
+        https://bugs.webkit.org/show_bug.cgi?id=23435
+        Make spreadMethod a member of Gradient rather than GraphicsContext.
+        Implement spreadMethod for Skia.
+
+        * platform/graphics/Gradient.cpp:
+        (WebCore::Gradient::Gradient):
+        * platform/graphics/Gradient.h:
+        (WebCore::Gradient::setSpreadMethod):
+        (WebCore::Gradient::spreadMethod):
+        * platform/graphics/GraphicsContext.cpp:
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/GraphicsContextPrivate.h:
+        * platform/graphics/GraphicsTypes.h:
+        (WebCore::):
+        * platform/graphics/cairo/GradientCairo.cpp:
+        (WebCore::Gradient::platformGradient):
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::fillPath):
+        (WebCore::GraphicsContext::strokePath):
+        * platform/graphics/qt/GradientQt.cpp:
+        (WebCore::Gradient::platformGradient):
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContext::fillPath):
+        (WebCore::GraphicsContext::strokePath):
+        * platform/graphics/skia/GradientSkia.cpp:
+        (WebCore::Gradient::platformGradient):
+        * svg/SVGLinearGradientElement.cpp:
+        (WebCore::SVGLinearGradientElement::buildGradient):
+        * svg/SVGRadialGradientElement.cpp:
+        (WebCore::SVGRadialGradientElement::buildGradient):
+        * svg/graphics/SVGPaintServerGradient.cpp:
+        (WebCore::SVGPaintServerGradient::SVGPaintServerGradient):
+        (WebCore::SVGPaintServerGradient::setup):
+        (WebCore::SVGPaintServerGradient::externalRepresentation):
+        * svg/graphics/SVGPaintServerGradient.h:
+
 2009-01-27  Ariya Hidayat  <ariya.hidayat@trolltech.com>
 
         Rubber-stamped by Simon Hausmann.
index 2e6a5d28e8ba08dd9d85641b725b24b8e649209e..0b5fda22f893f5be0fbe4c2fdce47921e341e992 100644 (file)
@@ -39,6 +39,7 @@ Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
     , m_r1(0)
     , m_stopsSorted(false)
     , m_lastStop(0)
+    , m_spreadMethod(SpreadMethodPad)
 {
     platformInit();
 }
@@ -146,4 +147,11 @@ int Gradient::findStop(float value) const
     return m_lastStop;
 }
 
+GradientSpreadMethod Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
+{
+    // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
+    ASSERT(m_gradient == 0);
+    m_spreadMethod = spreadMethod;
+}
+
 } //namespace
index e55923c1b6a9536ea2d2f506d29d75600554839d..bfd334ec600809ab626cd761afeb81384e13518a 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "FloatPoint.h"
 #include "Generator.h"
+#include "GraphicsTypes.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/Vector.h>
 
@@ -86,6 +87,9 @@ namespace WebCore {
 
         void setStopsSorted(bool s) { m_stopsSorted = s; }
 
+        void setSpreadMethod(GradientSpreadMethod);
+        GradientSpreadMethod spreadMethod() { return m_spreadMethod; }
+
         virtual void fill(GraphicsContext*, const FloatRect&);
 
     private:
@@ -105,6 +109,7 @@ namespace WebCore {
         mutable Vector<ColorStop> m_stops;
         mutable bool m_stopsSorted;
         mutable int m_lastStop;
+        GradientSpreadMethod m_spreadMethod;
 
         PlatformGradient m_gradient;
     };
index 8426011cb72ac4b5db2c05bcb1340af8d0efc17e..1ac91c0dc59b1a6addad2d3bc92b1166030e9aa7 100644 (file)
@@ -178,16 +178,6 @@ void GraphicsContext::setFillRule(WindRule fillRule)
     m_common->state.fillRule = fillRule;
 }
 
-GradientSpreadMethod GraphicsContext::spreadMethod() const
-{
-    return m_common->state.spreadMethod;
-}
-
-void GraphicsContext::setSpreadMethod(GradientSpreadMethod spreadMethod)
-{
-    m_common->state.spreadMethod = spreadMethod;
-}
-
 void GraphicsContext::setFillColor(const Color& color)
 {
     m_common->state.fillColorSpace = SolidColorSpace;
index f208b37c926945183577b98b1e285dc1ff67e8e7..28bb61311c74b819f2951b111000134e55094227 100644 (file)
@@ -125,14 +125,6 @@ namespace WebCore {
         InterpolationHigh
     };
 
-    // FIXME: Currently these constants have to match the values used in the SVG
-    // DOM API. That's a mistake. We need to make cut that dependency.
-    enum GradientSpreadMethod {
-        SpreadMethodPad = 1,
-        SpreadMethodReflect = 2,
-        SpreadMethodRepeat = 3
-    };
-
     class GraphicsContext : Noncopyable {
     public:
         GraphicsContext(PlatformGraphicsContext*);
@@ -151,8 +143,6 @@ namespace WebCore {
 
         WindRule fillRule() const;
         void setFillRule(WindRule);
-        GradientSpreadMethod spreadMethod() const;
-        void setSpreadMethod(GradientSpreadMethod);
         Color fillColor() const;
         void setFillColor(const Color&);
         void setFillPattern(PassRefPtr<Pattern>);
index 87123eba6febd8e9983b007319e9c4872ee1d671..4e6f68d2fbfd2e30f69a179c64c9ed5352d72620 100644 (file)
@@ -80,7 +80,6 @@ namespace WebCore {
         RefPtr<Pattern> strokePattern;
         
         WindRule fillRule;
-        GradientSpreadMethod spreadMethod;
         ColorSpace fillColorSpace;
         Color fillColor;
         RefPtr<Gradient> fillGradient;
index cdf5e31e4cc9be272b745b389cd919ba5f8620d0..769207aacab71e3c35f804b22801371cc8fba588 100644 (file)
@@ -50,6 +50,14 @@ namespace WebCore {
         CompositePlusLighter
     };
 
+    // FIXME: Currently these constants have to match the values used in the SVG
+    // DOM API. That's a mistake. We need to make cut that dependency.
+    enum GradientSpreadMethod {
+        SpreadMethodPad = 1,
+        SpreadMethodReflect = 2,
+        SpreadMethodRepeat = 3
+    };
+
     enum LineCap { ButtCap, RoundCap, SquareCap };
 
     enum LineJoin { MiterJoin, RoundJoin, BevelJoin };
index 77764241cb4167ca774b3b68113d2c8f930a38e3..271a6b3af4a7cb552ddcb6c8f8b6c9f7a808c2a4 100644 (file)
@@ -57,6 +57,18 @@ cairo_pattern_t* Gradient::platformGradient()
         ++stopIterator;
     }
 
+    switch (m_spreadMethod) {
+    case SpreadMethodPad:
+        cairo_pattern_set_extend(m_gradient, CAIRO_EXTEND_PAD);
+        break;
+    case SpreadMethodReflect:
+        cairo_pattern_set_extend(m_gradient, CAIRO_EXTEND_REFLECT);
+        break;
+    case SpreadMethodRepeat:
+        cairo_pattern_set_extend(m_gradient, CAIRO_EXTEND_REPEAT);
+        break;
+    }
+
     return m_gradient;
 }
 
index ef748cf866647380f215ae84662205e20f4b3530..2720dbde21acc40ae270cc2e330392934798f76c 100644 (file)
@@ -87,22 +87,6 @@ static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const
     cairo_fill(cr);
 }
 
-static inline cairo_pattern_t* applySpreadMethod(cairo_pattern_t* pattern, GradientSpreadMethod spreadMethod)
-{
-    switch (spreadMethod) {
-        case SpreadMethodPad:
-           cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD);
-           break;
-        case SpreadMethodReflect:
-            cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT);
-            break;
-        case SpreadMethodRepeat:
-            cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
-            break;
-    }
-    return pattern;
-}
-
 GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
     : m_common(createGraphicsContextPrivate())
     , m_data(new GraphicsContextPlatformPrivate)
@@ -463,7 +447,6 @@ void GraphicsContext::fillPath()
     }
     case GradientColorSpace:
         cairo_pattern_t* pattern = m_common->state.fillGradient->platformGradient();
-        pattern = applySpreadMethod(pattern, spreadMethod());
         cairo_set_source(cr, pattern);
         cairo_clip(cr);
         cairo_paint_with_alpha(cr, m_common->state.globalAlpha);
@@ -501,7 +484,6 @@ void GraphicsContext::strokePath()
     }
     case GradientColorSpace:
         cairo_pattern_t* pattern = m_common->state.strokeGradient->platformGradient();
-        pattern = applySpreadMethod(pattern, spreadMethod());
         cairo_set_source(cr, pattern);
         if (m_common->state.globalAlpha < 1.0f) {
             cairo_push_group(cr);
index a0edf8d20944c53b853821460714ffa6df5b336e..e9b2b9f9daf840264c224f630d1498198b627f1c 100644 (file)
@@ -66,6 +66,18 @@ QGradient* Gradient::platformGradient()
         ++stopIterator;
     }
 
+    switch(m_spreadMethod) {
+    case SpreadMethodPad:
+        m_gradient->setSpread(QGradient::PadSpread);
+        break;
+    case SpreadMethodReflect:
+        m_gradient->setSpread(QGradient::ReflectSpread);
+        break;
+    case SpreadMethodRepeat:
+        m_gradient->setSpread(QGradient::RepeatSpread);
+        break;
+    }
+
     return m_gradient;
 }
 
index 2e7cdcbda40f64286e7ade71b4a98989944bd603..2fe009a416e28632df121186cadd68dbea39dc06 100644 (file)
@@ -152,22 +152,6 @@ static Qt::PenStyle toQPenStyle(StrokeStyle style)
     return Qt::NoPen;
 }
 
-static inline QGradient applySpreadMethod(QGradient gradient, GradientSpreadMethod spreadMethod)
-{
-    switch (spreadMethod) {
-        case SpreadMethodPad:
-            gradient.setSpread(QGradient::PadSpread);
-           break;
-        case SpreadMethodReflect:
-            gradient.setSpread(QGradient::ReflectSpread);
-            break;
-        case SpreadMethodRepeat:
-            gradient.setSpread(QGradient::RepeatSpread);
-            break;
-    }
-    return gradient;
-}
-
 struct TransparencyLayer
 {
     TransparencyLayer(const QPainter* p, const QRect &rect)
@@ -554,7 +538,6 @@ void GraphicsContext::fillPath()
     }
     case GradientColorSpace:
         QGradient* gradient = m_common->state.fillGradient->platformGradient();
-        *gradient = applySpreadMethod(*gradient, spreadMethod());  
         p->fillPath(path, QBrush(*gradient));
         break;
     }
@@ -584,7 +567,6 @@ void GraphicsContext::strokePath()
     }
     case GradientColorSpace: {
         QGradient* gradient = m_common->state.strokeGradient->platformGradient();
-        *gradient = applySpreadMethod(*gradient, spreadMethod()); 
         pen.setBrush(QBrush(*gradient));
         p->setPen(pen);
         p->strokePath(path, pen);
index eff7c66148ab6f0173a5eda9b66a602cfda8d74a..0c0fc93ce42ee247925e973131b6972a77b32be4 100644 (file)
@@ -136,6 +136,19 @@ SkShader* Gradient::platformGradient()
 
     fillStops(m_stops.data(), m_stops.size(), pos, colors);
 
+    SkShader::TileMode tile = SkShader::kClamp_TileMode;
+    switch (m_spreadMethod) {
+    case SpreadMethodReflect:
+        tile = SkShader::kMirror_TileMode;
+        break;
+    case SpreadMethodRepeat:
+        tile = SkShader::kRepeat_TileMode;
+        break;
+    case SpreadMethodPad:
+        tile = SkShader::kClamp_TileMode;
+        break;
+    }
+
     if (m_radial) {
         // FIXME: CSS radial Gradients allow an offset focal point (the
         // "start circle"), but skia doesn't seem to support that, so this just
@@ -145,11 +158,11 @@ SkShader* Gradient::platformGradient()
         // description of the expected behavior.
         m_gradient = SkGradientShader::CreateRadial(m_p1,
             WebCoreFloatToSkScalar(m_r1), colors, pos,
-            static_cast<int>(countUsed), SkShader::kClamp_TileMode);
+            static_cast<int>(countUsed), tile);
     } else {
         SkPoint pts[2] = { m_p0, m_p1 };
         m_gradient = SkGradientShader::CreateLinear(pts, colors, pos,
-            static_cast<int>(countUsed), SkShader::kClamp_TileMode);
+            static_cast<int>(countUsed), tile);
     }
 
     return m_gradient;
index ac2b6b12822dd1afd4e3f55ec4fd5d22d95354ce..d2d17982b76184ddf147d6292f8ae482f0b84fae 100644 (file)
@@ -87,6 +87,7 @@ void SVGLinearGradientElement::buildGradient() const
     FloatPoint endPoint = FloatPoint::narrowPrecision(attributes.x2(), attributes.y2());
 
     RefPtr<Gradient> gradient = Gradient::create(startPoint, endPoint);
+    gradient->setSpreadMethod(attributes.spreadMethod());
 
     Vector<SVGGradientStop> m_stops = attributes.stops();
     float previousOffset = 0.0f;
@@ -107,7 +108,6 @@ void SVGLinearGradientElement::buildGradient() const
     linearGradient->setGradientStops(attributes.stops());
 
     // These should possibly be supported on Gradient
-    linearGradient->setGradientSpreadMethod(attributes.spreadMethod());
     linearGradient->setGradientTransform(attributes.gradientTransform());
     linearGradient->setGradientStart(startPoint);
     linearGradient->setGradientEnd(endPoint);
index 4f4fd8f165b66d9936e4bed2244b8b683990e1f8..abc11fb4acf2e60949746b84fd05d0f403305ec2 100644 (file)
@@ -114,6 +114,7 @@ void SVGRadialGradientElement::buildGradient() const
         0.f, // SVG does not support a "focus radius"
         centerPoint,
         narrowPrecisionToFloat(attributes.r()));
+    gradient->setSpreadMethod(attributes.spreadMethod());
 
     Vector<SVGGradientStop> stops = attributes.stops();
     float previousOffset = 0.0f;
@@ -129,7 +130,6 @@ void SVGRadialGradientElement::buildGradient() const
         return;
 
     radialGradient->setBoundingBoxMode(attributes.boundingBoxMode());
-    radialGradient->setGradientSpreadMethod(attributes.spreadMethod()); 
     radialGradient->setGradientTransform(attributes.gradientTransform());
     radialGradient->setGradientCenter(centerPoint);
     radialGradient->setGradientFocal(focalPoint);
index b06eca1cefa7e6ef2a1c66ea3a44d16e5be1d668..bbb72dd537060a2f8219650b7293057063164292 100644 (file)
@@ -76,8 +76,7 @@ static TextStream& operator<<(TextStream& ts, const Vector<SVGGradientStop>& l)
 }
 
 SVGPaintServerGradient::SVGPaintServerGradient(const SVGGradientElement* owner)
-    : m_spreadMethod(SpreadMethodPad)
-    , m_boundingBoxMode(true)
+    : m_boundingBoxMode(true)
     , m_ownerElement(owner)
 
 #if PLATFORM(CG)
@@ -102,16 +101,6 @@ void SVGPaintServerGradient::setGradient(PassRefPtr<Gradient> gradient)
     m_gradient = gradient;
 }
 
-GradientSpreadMethod SVGPaintServerGradient::spreadMethod() const
-{
-    return m_spreadMethod;
-}
-
-void SVGPaintServerGradient::setGradientSpreadMethod(const GradientSpreadMethod& method)
-{
-    m_spreadMethod = method;
-}
-
 bool SVGPaintServerGradient::boundingBoxMode() const
 {
     return m_boundingBoxMode;
@@ -252,7 +241,6 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject
         context->setStrokeThickness(strokeThickness);
     }
     context->concatCTM(gradientTransform());
-    context->setSpreadMethod(spreadMethod());
 
     return true;
 }
@@ -284,8 +272,8 @@ TextStream& SVGPaintServerGradient::externalRepresentation(TextStream& ts) const
 
     // abstract, don't stream type
     ts  << "[stops=" << gradientStops() << "]";
-    if (spreadMethod() != SpreadMethodPad)
-        ts << "[method=" << spreadMethod() << "]";
+    if (m_gradient->spreadMethod() != SpreadMethodPad)
+        ts << "[method=" << m_gradient->spreadMethod() << "]";
     if (!boundingBoxMode())
         ts << " [bounding box mode=" << boundingBoxMode() << "]";
     if (!gradientTransform().isIdentity())
index 16dab0b9ad09c4698f9ed58491a97bd9fe67bd34..b24c417be2709daaa5e5d8e31723db2d3bfb034d 100644 (file)
@@ -52,9 +52,6 @@ namespace WebCore {
         void setGradient(PassRefPtr<Gradient>);
         Gradient* gradient() const;
 
-        GradientSpreadMethod spreadMethod() const;
-        void setGradientSpreadMethod(const GradientSpreadMethod&);
-
         // Gradient start and end points are percentages when used in boundingBox mode.
         // For instance start point with value (0,0) is top-left and end point with
         // value (100, 100) is bottom-right. BoundingBox mode is enabled by default.
@@ -78,7 +75,6 @@ namespace WebCore {
     private:
         Vector<SVGGradientStop> m_stops;
         RefPtr<Gradient> m_gradient;
-        GradientSpreadMethod m_spreadMethod;
         bool m_boundingBoxMode;
         TransformationMatrix m_gradientTransform;
         const SVGGradientElement* m_ownerElement;