[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-1049-g2e11a8e

simon.fraser at apple.com simon.fraser at apple.com
Fri Jan 21 14:58:38 UTC 2011


The following commit has been merged in the debian/experimental branch:
commit 3f478caa91301ed12f396ac393a5e9ecf948b49a
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jan 5 21:06:55 2011 +0000

    2011-01-05  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dave Hyatt.
    
            Implement repeating CSS3 gradients
            https://bugs.webkit.org/show_bug.cgi?id=51843
    
            Add support for repeating gradients, via the new gradient functions
            -webkit-repeating-linear-gradient and -webkit-repeating-radial-gradient.
    
            Tests: fast/gradients/css3-repeating-linear-gradients.html
                   fast/gradients/css3-repeating-radial-gradients.html
    
            * css/CSSGradientValue.h:
            (WebCore::CSSGradientValue::isRepeating): Accessor for whethe the gradient repeats.
            (WebCore::CSSGradientValue::CSSGradientValue): Pass CSSGradientRepeat in.
            (WebCore::CSSLinearGradientValue::create): Pass CSSGradientRepeat.
            (WebCore::CSSLinearGradientValue::CSSLinearGradientValue): Ditto
            (WebCore::CSSRadialGradientValue::create): Ditto.
            (WebCore::CSSRadialGradientValue::CSSRadialGradientValue): Ditto.
    
            * css/CSSGradientValue.cpp:
            (WebCore::CSSGradientValue::addStops): Pass maxLengthForRepeat, which
            is used for repeating radial gradients. Add code to repeat the stops,
            adding stops before the start, and after the end until the 0-N range is
            covered, where N is large enough to ensure the box is covered. Fix an issue
            with repeating gradients where if both stops were < 0, it would fail to clamp
            them to 0.
    
            (WebCore::CSSLinearGradientValue::cssText): Output strings for repeating gradients.
            (WebCore::CSSLinearGradientValue::createGradient): maxExtent for linear gradients is 1,
            because they are guaranteed to fill the box already.
            (WebCore::CSSRadialGradientValue::cssText): Output strings for repeating gradients.
            (WebCore::CSSRadialGradientValue::createGradient): Compute the distance to the furthest
            corner in order to inform addStops() how much additional extent is required.
    
            * css/CSSParser.cpp:
            (WebCore::CSSParser::parseDeprecatedGradient): Old gradients never repeat.
            (WebCore::CSSParser::parseLinearGradient): Pass down CSSGradientRepeat.
            (WebCore::CSSParser::parseRadialGradient): Ditto.
            (WebCore::CSSParser::isGeneratedImageValue): Add repeating gradient functions.
            (WebCore::CSSParser::parseGeneratedImage): Ditto.
            * css/CSSParser.h: Pass CSSGradientRepeat to gradient functions.
            * platform/graphics/cg/GradientCG.cpp: Remove unused #include.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75097 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index f53f464..1998362 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,23 @@
+2011-01-05  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        Implement repeating CSS3 gradients
+        https://bugs.webkit.org/show_bug.cgi?id=51843
+        
+        Tests for repeating gradient parsing, and repeating linear and radial gradients.
+
+        * fast/gradients/css3-gradient-parsing-expected.txt:
+        * fast/gradients/css3-gradient-parsing.html:
+        * fast/gradients/css3-repeating-linear-gradients-expected.txt: Added.
+        * fast/gradients/css3-repeating-linear-gradients.html: Added.
+        * fast/gradients/css3-repeating-radial-gradients-expected.txt: Added.
+        * fast/gradients/css3-repeating-radial-gradients.html: Added.
+        * platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.checksum: Added.
+        * platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.png: Added.
+        * platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.checksum: Added.
+        * platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.png: Added.
+
 2011-01-05  Stephen White  <senorblanco at chromium.org>
 
         Unreviewed; test expectations fix.
diff --git a/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt b/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt
index 3e6f187..005d30b 100644
--- a/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt
+++ b/LayoutTests/fast/gradients/css3-gradient-parsing-expected.txt
@@ -17,6 +17,10 @@ PASS testGradient("background-image: -webkit-linear-gradient(black 10px, white 2
 PASS testGradient("background-image: -webkit-linear-gradient(top left, black 0%)", "background-image") is "-webkit-linear-gradient(left top, black 0%)"
 PASS testGradient("background-image: -webkit-linear-gradient(top, black 0%)", "background-image") is "-webkit-linear-gradient(top, black 0%)"
 PASS testGradient("background-image: -webkit-linear-gradient(10deg, black 0%)", "background-image") is "-webkit-linear-gradient(10deg, black 0%)"
+-webkit-repeating-linear-gradient
+
+
+PASS testGradient("background-image: -webkit-repeating-linear-gradient(black, white)", "background-image") is "-webkit-repeating-linear-gradient(top, black, white)"
 -webkit-radial-gradient
 
 
@@ -35,6 +39,10 @@ PASS testGradient("background-image: -webkit-radial-gradient(center, 10px, white
 PASS testGradient("background-image: -webkit-radial-gradient(center, 10px 10px, white, black)", "background-image") is "-webkit-radial-gradient(50% 50%, 10px 10px, white, black)"
 PASS testGradient("background-image: -webkit-radial-gradient(ellipse farthest-corner, white, black)", "background-image") is "-webkit-radial-gradient(center, ellipse farthest-corner, white, black)"
 PASS testGradient("background-image: -webkit-radial-gradient(circle closest-side, white, black)", "background-image") is "-webkit-radial-gradient(center, circle closest-side, white, black)"
+-webkit-repeating-radial-gradient
+
+
+PASS testGradient("background-image: -webkit-repeating-radial-gradient(white, black)", "background-image") is "-webkit-repeating-radial-gradient(center, white, black)"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/gradients/css3-gradient-parsing.html b/LayoutTests/fast/gradients/css3-gradient-parsing.html
index 75c7f12..e193efc 100644
--- a/LayoutTests/fast/gradients/css3-gradient-parsing.html
+++ b/LayoutTests/fast/gradients/css3-gradient-parsing.html
@@ -48,6 +48,9 @@ shouldBe('testGradient("background-image: -webkit-linear-gradient(top left, blac
 shouldBe('testGradient("background-image: -webkit-linear-gradient(top, black 0%)", "background-image")', '"-webkit-linear-gradient(top, black 0%)"');
 shouldBe('testGradient("background-image: -webkit-linear-gradient(10deg, black 0%)", "background-image")', '"-webkit-linear-gradient(10deg, black 0%)"');
 
+debug('<p>-webkit-repeating-linear-gradient</p>');
+shouldBe('testGradient("background-image: -webkit-repeating-linear-gradient(black, white)", "background-image")', '"-webkit-repeating-linear-gradient(top, black, white)"');
+
 debug('<p>-webkit-radial-gradient</p>');
 
 shouldBe('testGradient("background-image: -webkit-radial-gradient(white, black)", "background-image")', '"-webkit-radial-gradient(center, white, black)"');
@@ -66,6 +69,9 @@ shouldBe('testGradient("background-image: -webkit-radial-gradient(center, 10px 1
 shouldBe('testGradient("background-image: -webkit-radial-gradient(ellipse farthest-corner, white, black)", "background-image")', '"-webkit-radial-gradient(center, ellipse farthest-corner, white, black)"');
 shouldBe('testGradient("background-image: -webkit-radial-gradient(circle closest-side, white, black)", "background-image")', '"-webkit-radial-gradient(center, circle closest-side, white, black)"');
 
+debug('<p>-webkit-repeating-radial-gradient</p>');
+shouldBe('testGradient("background-image: -webkit-repeating-radial-gradient(white, black)", "background-image")', '"-webkit-repeating-radial-gradient(center, white, black)"');
+
 successfullyParsed = true;
   
 </script>
diff --git a/LayoutTests/fast/gradients/css3-color-stops-expected.txt b/LayoutTests/fast/gradients/css3-repeating-linear-gradients-expected.txt
similarity index 100%
copy from LayoutTests/fast/gradients/css3-color-stops-expected.txt
copy to LayoutTests/fast/gradients/css3-repeating-linear-gradients-expected.txt
diff --git a/LayoutTests/fast/gradients/css3-repeating-linear-gradients.html b/LayoutTests/fast/gradients/css3-repeating-linear-gradients.html
new file mode 100644
index 0000000..d63ec02
--- /dev/null
+++ b/LayoutTests/fast/gradients/css3-repeating-linear-gradients.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    .box {
+      display: inline-block;
+      height: 120px;
+      width: 200px;
+      margin: 10px;
+      border: 1px solid black;
+      background-repeat: no-repeat;
+    }
+
+    .linear1 {
+      background-image: -webkit-repeating-linear-gradient(white, black 20%);
+      background-image: -moz-repeating-linear-gradient(white, black 20%);
+    }
+    
+    .linear2 {
+      background-image: -webkit-repeating-linear-gradient(white 80%, black);
+      background-image: -moz-repeating-linear-gradient(white 80%, black);
+    }
+
+    .linear3 {
+      background-image: -webkit-repeating-linear-gradient(top left, red, blue 20px, red 40px);
+      background-image: -moz-repeating-linear-gradient(top left, red, blue 20px, red 40px);
+    }
+
+    .linear4 {
+      background-image: -webkit-repeating-linear-gradient(left, red 10%, blue 30%);
+      background-image: -moz-repeating-linear-gradient(left, red 10%, blue 30%);
+    }
+
+    .linear5 {
+      background-image: -webkit-repeating-linear-gradient(left, red -10%, blue -5%);
+      background-image: -moz-repeating-linear-gradient(left, red -10%, blue -5%);
+    }
+
+    .linear6 {
+      background-image: -webkit-repeating-linear-gradient(left, red -10%, blue 105%);
+      background-image: -moz-repeating-linear-gradient(left, red -10%, blue 105%);
+    }
+
+    .linear7 {
+      background-image: -webkit-repeating-linear-gradient(left, red 90%, blue 105%);
+      background-image: -moz-repeating-linear-gradient(left, red 90%, blue 105%);
+    }
+
+    .linear8 {
+      background-image: -webkit-repeating-linear-gradient(left, red 2em, blue 3em);
+      background-image: -moz-repeating-linear-gradient(left, red 2em, blue 3em);
+    }
+
+    .linear9 {
+      background-image: -webkit-repeating-linear-gradient(left, red, orange, yellow, green, blue, red 60px);
+      background-image: -moz-repeating-linear-gradient(left, red, orange, yellow, green, blue, red 60px);
+    }
+
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController) {
+      var dumpPixels = true;
+      layoutTestController.dumpAsText(dumpPixels);
+    }
+  </script>
+</head>
+<body>
+
+  <div class="linear1 box"></div>
+  <div class="linear2 box"></div>
+  <div class="linear3 box"></div>
+  <br>
+  <div class="linear4 box"></div>
+  <div class="linear5 box"></div>
+  <div class="linear6 box"></div>
+  <br>
+  <div class="linear7 box"></div>
+  <div class="linear8 box"></div>
+  <div class="linear9 box"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/gradients/css3-color-stops-expected.txt b/LayoutTests/fast/gradients/css3-repeating-radial-gradients-expected.txt
similarity index 100%
copy from LayoutTests/fast/gradients/css3-color-stops-expected.txt
copy to LayoutTests/fast/gradients/css3-repeating-radial-gradients-expected.txt
diff --git a/LayoutTests/fast/gradients/css3-repeating-radial-gradients.html b/LayoutTests/fast/gradients/css3-repeating-radial-gradients.html
new file mode 100644
index 0000000..53c498f
--- /dev/null
+++ b/LayoutTests/fast/gradients/css3-repeating-radial-gradients.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    .box {
+      display: inline-block;
+      height: 120px;
+      width: 200px;
+      margin: 10px;
+      border: 1px solid black;
+      background-repeat: no-repeat;
+    }
+
+    .radial1 {
+      background-image: -webkit-repeating-radial-gradient(white, black 20%);
+      background-image: -moz-repeating-radial-gradient(white, black 20%);
+    }
+    
+    .radial2 {
+      background-image: -webkit-repeating-radial-gradient(white 80%, black);
+      background-image: -moz-repeating-radial-gradient(white 80%, black);
+    }
+
+    .radial3 {
+      background-image: -webkit-repeating-radial-gradient(top left, red, blue 20px, red 40px);
+      background-image: -moz-repeating-radial-gradient(top left, red, blue 20px, red 40px);
+    }
+
+    .radial4 {
+      background-image: -webkit-repeating-radial-gradient(bottom left, red 10%, blue 30%);
+      background-image: -moz-repeating-radial-gradient(bottom left, red 10%, blue 30%);
+    }
+
+    .radial5 {
+      background-image: -webkit-repeating-radial-gradient(left, red -10%, blue -5%);
+      background-image: -moz-repeating-radial-gradient(left, red -10%, blue -5%);
+    }
+
+    .radial6 {
+      background-image: -webkit-repeating-radial-gradient(left, red -10%, blue 105%);
+      background-image: -moz-repeating-radial-gradient(left, red -10%, blue 105%);
+    }
+
+    .radial7 {
+      background-image: -webkit-repeating-radial-gradient(left, red 90%, blue 105%);
+      background-image: -moz-repeating-radial-gradient(left, red 90%, blue 105%);
+    }
+
+    .radial8 {
+      background-image: -webkit-repeating-radial-gradient(top, red 2em, blue 3em);
+      background-image: -moz-repeating-radial-gradient(top, red 2em, blue 3em);
+    }
+
+    .radial9 {
+      background-image: -webkit-repeating-radial-gradient(left, circle, red, orange, yellow, green, blue, red 60px);
+      background-image: -moz-repeating-radial-gradient(left, circle, red, orange, yellow, green, blue, red 60px);
+    }
+
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController) {
+      var dumpPixels = true;
+      layoutTestController.dumpAsText(dumpPixels);
+    }
+  </script>
+</head>
+<body>
+
+  <div class="radial1 box"></div>
+  <div class="radial2 box"></div>
+  <div class="radial3 box"></div>
+  <br>
+  <div class="radial4 box"></div>
+  <div class="radial5 box"></div>
+  <div class="radial6 box"></div>
+  <br>
+  <div class="radial7 box"></div>
+  <div class="radial8 box"></div>
+  <div class="radial9 box"></div>
+
+</body>
+</html>
diff --git a/LayoutTests/platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.checksum b/LayoutTests/platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.checksum
new file mode 100644
index 0000000..3c1462f
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.checksum
@@ -0,0 +1 @@
+59e2f50c3eb72f148eca6459ff340a60
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.png b/LayoutTests/platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.png
new file mode 100644
index 0000000..c8a0633
Binary files /dev/null and b/LayoutTests/platform/mac/fast/gradients/css3-repeating-linear-gradients-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.checksum b/LayoutTests/platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.checksum
new file mode 100644
index 0000000..db7bd09
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.checksum
@@ -0,0 +1 @@
+6cdaf10e685f3ff61cd6ff52f590bd10
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.png b/LayoutTests/platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.png
new file mode 100644
index 0000000..3f3fabc
Binary files /dev/null and b/LayoutTests/platform/mac/fast/gradients/css3-repeating-radial-gradients-expected.png differ
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 344efe2..c551132 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,48 @@
+2011-01-05  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        Implement repeating CSS3 gradients
+        https://bugs.webkit.org/show_bug.cgi?id=51843
+        
+        Add support for repeating gradients, via the new gradient functions
+        -webkit-repeating-linear-gradient and -webkit-repeating-radial-gradient.
+
+        Tests: fast/gradients/css3-repeating-linear-gradients.html
+               fast/gradients/css3-repeating-radial-gradients.html
+
+        * css/CSSGradientValue.h:
+        (WebCore::CSSGradientValue::isRepeating): Accessor for whethe the gradient repeats.
+        (WebCore::CSSGradientValue::CSSGradientValue): Pass CSSGradientRepeat in.
+        (WebCore::CSSLinearGradientValue::create): Pass CSSGradientRepeat.
+        (WebCore::CSSLinearGradientValue::CSSLinearGradientValue): Ditto
+        (WebCore::CSSRadialGradientValue::create): Ditto.
+        (WebCore::CSSRadialGradientValue::CSSRadialGradientValue): Ditto.
+
+        * css/CSSGradientValue.cpp:
+        (WebCore::CSSGradientValue::addStops): Pass maxLengthForRepeat, which
+        is used for repeating radial gradients. Add code to repeat the stops,
+        adding stops before the start, and after the end until the 0-N range is
+        covered, where N is large enough to ensure the box is covered. Fix an issue
+        with repeating gradients where if both stops were < 0, it would fail to clamp
+        them to 0.
+        
+        (WebCore::CSSLinearGradientValue::cssText): Output strings for repeating gradients.
+        (WebCore::CSSLinearGradientValue::createGradient): maxExtent for linear gradients is 1,
+        because they are guaranteed to fill the box already.
+        (WebCore::CSSRadialGradientValue::cssText): Output strings for repeating gradients.
+        (WebCore::CSSRadialGradientValue::createGradient): Compute the distance to the furthest
+        corner in order to inform addStops() how much additional extent is required.
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseDeprecatedGradient): Old gradients never repeat.
+        (WebCore::CSSParser::parseLinearGradient): Pass down CSSGradientRepeat.
+        (WebCore::CSSParser::parseRadialGradient): Ditto.
+        (WebCore::CSSParser::isGeneratedImageValue): Add repeating gradient functions.
+        (WebCore::CSSParser::parseGeneratedImage): Ditto.
+        * css/CSSParser.h: Pass CSSGradientRepeat to gradient functions.
+        * platform/graphics/cg/GradientCG.cpp: Remove unused #include.
+
 2011-01-05  Martin Robinson  <mrobinson at igalia.com>
 
         Reviewed by Ariya Hidayat.
diff --git a/WebCore/css/CSSGradientValue.cpp b/WebCore/css/CSSGradientValue.cpp
index 7771acc..2a3b64a 100644
--- a/WebCore/css/CSSGradientValue.cpp
+++ b/WebCore/css/CSSGradientValue.cpp
@@ -107,7 +107,7 @@ struct GradientStop {
     { }
 };
 
-void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, RenderStyle* rootStyle)
+void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, RenderStyle* rootStyle, float maxLengthForRepeat)
 {
     RenderStyle* style = renderer->style();
     
@@ -224,8 +224,70 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend
             }
         }
     }
+
+    // If the gradient is repeating, repeat the color stops.
+    // We can't just push this logic down into the platform-specific Gradient code,
+    // because we have to know the extent of the gradient, and possible move the end points.
+    if (m_repeating && numStops > 1) {
+        float maxExtent = 1;
+
+        // Radial gradients may need to extend further than the endpoints, because they have
+        // to repeat out to the corners of the box.
+        if (isRadialGradient()) {
+            if (!computedGradientLength) {
+                FloatSize gradientSize(gradientStart - gradientEnd);
+                gradientLength = gradientSize.diagonalLength();
+            }
+            
+            if (maxLengthForRepeat > gradientLength)
+                maxExtent = maxLengthForRepeat / gradientLength;
+        }
+
+        size_t originalNumStops = numStops;
+        size_t originalFirstStopIndex = 0;
+
+        // Work backwards from the first, adding stops until we get one before 0.
+        float firstOffset = stops[0].offset;
+        if (firstOffset > 0) {
+            float currOffset = firstOffset;
+            size_t srcStopOrdinal = originalNumStops - 1;
+            
+            while (true) {
+                GradientStop newStop = stops[originalFirstStopIndex + srcStopOrdinal];
+                newStop.offset = currOffset;
+                stops.prepend(newStop);
+                ++originalFirstStopIndex;
+                if (currOffset < 0)
+                    break;
+
+                if (srcStopOrdinal)
+                    currOffset -= stops[originalFirstStopIndex + srcStopOrdinal].offset - stops[originalFirstStopIndex + srcStopOrdinal - 1].offset;
+                srcStopOrdinal = (srcStopOrdinal + originalNumStops - 1) % originalNumStops;
+            }
+        }
+        
+        // Work forwards from the end, adding stops until we get one after 1.
+        float lastOffset = stops[stops.size() - 1].offset;
+        if (lastOffset < maxExtent) {
+            float currOffset = lastOffset;
+            size_t srcStopOrdinal = 0;
+
+            while (true) {
+                GradientStop newStop = stops[srcStopOrdinal];
+                newStop.offset = currOffset;
+                stops.append(newStop);
+                if (currOffset > maxExtent)
+                    break;
+                if (srcStopOrdinal < originalNumStops - 1)
+                    currOffset += stops[originalFirstStopIndex + srcStopOrdinal + 1].offset - stops[originalFirstStopIndex + srcStopOrdinal].offset;
+                srcStopOrdinal = (srcStopOrdinal + 1) % originalNumStops;
+            }
+        }
+    }
+    
+    numStops = stops.size();
     
-    // If the gradient goes outside the 0-1 range, normalize it by moving the endpoints, and ajusting the stops.
+    // If the gradient goes outside the 0-1 range, normalize it by moving the endpoints, and adjusting the stops.
     if (numStops > 1 && (stops[0].offset < 0 || stops[numStops - 1].offset > 1)) {
         if (isLinearGradient()) {
             float firstOffset = stops[0].offset;
@@ -246,7 +308,7 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend
             float scale = lastOffset - firstOffset;
 
             // Reset points below 0 to the first visible color.
-            size_t firstZeroOrGreaterIndex = 0;
+            size_t firstZeroOrGreaterIndex = numStops;
             for (size_t i = 0; i < numStops; ++i) {
                 if (stops[i].offset >= 0) {
                     firstZeroOrGreaterIndex = i;
@@ -254,17 +316,23 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend
                 }
             }
             
-            if (firstZeroOrGreaterIndex > 0 && stops[firstZeroOrGreaterIndex].offset > 0) {
-                float prevOffset = stops[firstZeroOrGreaterIndex - 1].offset;
-                float nextOffset = stops[firstZeroOrGreaterIndex].offset;
-                
-                float interStopProportion = -prevOffset / (nextOffset - prevOffset);
-                Color blendedColor = blend(stops[firstZeroOrGreaterIndex - 1].color, stops[firstZeroOrGreaterIndex].color, interStopProportion);
-
-                // Clamp the positions to 0 and set the color.
-                for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i) {
-                    stops[i].offset = 0;
-                    stops[i].color = blendedColor;
+            if (firstZeroOrGreaterIndex > 0) {
+                if (firstZeroOrGreaterIndex < numStops && stops[firstZeroOrGreaterIndex].offset > 0) {
+                    float prevOffset = stops[firstZeroOrGreaterIndex - 1].offset;
+                    float nextOffset = stops[firstZeroOrGreaterIndex].offset;
+                    
+                    float interStopProportion = -prevOffset / (nextOffset - prevOffset);
+                    Color blendedColor = blend(stops[firstZeroOrGreaterIndex - 1].color, stops[firstZeroOrGreaterIndex].color, interStopProportion);
+
+                    // Clamp the positions to 0 and set the color.
+                    for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i) {
+                        stops[i].offset = 0;
+                        stops[i].color = blendedColor;
+                    }
+                } else {
+                    // All stops are below 0; just clamp them.
+                    for (size_t i = 0; i < firstZeroOrGreaterIndex; ++i)
+                        stops[i].offset = 0;
                 }
             }
             
@@ -348,7 +416,7 @@ String CSSLinearGradientValue::cssText() const
                 result += "color-stop(" + String::number(stop.m_position->getDoubleValue(CSSPrimitiveValue::CSS_NUMBER)) + ", " + stop.m_color->cssText() + ")";
         }
     } else {
-        result = "-webkit-linear-gradient(";
+        result = m_repeating ? "-webkit-repeating-linear-gradient(" : "-webkit-linear-gradient(";
         if (m_angle)
             result += m_angle->cssText();
         else {
@@ -458,7 +526,7 @@ PassRefPtr<Gradient> CSSLinearGradientValue::createGradient(RenderObject* render
     RefPtr<Gradient> gradient = Gradient::create(firstPoint, secondPoint);
 
     // Now add the stops.
-    addStops(gradient.get(), renderer, rootStyle);
+    addStops(gradient.get(), renderer, rootStyle, 1);
 
     return gradient.release();
 }
@@ -491,7 +559,7 @@ String CSSRadialGradientValue::cssText() const
         }
     } else {
 
-        result = "-webkit-radial-gradient(";
+        result = m_repeating ? "-webkit-repeating-radial-gradient(" : "-webkit-radial-gradient(";
         if (m_firstX && m_firstY) {
             result += m_firstX->cssText() + " " + m_firstY->cssText();
         } else if (m_firstX)
@@ -745,8 +813,15 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(RenderObject* render
 
     RefPtr<Gradient> gradient = Gradient::create(firstPoint, firstRadius, secondPoint, secondRadius, aspectRatio);
 
+    // addStops() only uses maxExtent for repeating gradients.
+    float maxExtent = 0;
+    if (m_repeating) {
+        FloatPoint corner;
+        maxExtent = distanceToFarthestCorner(secondPoint, size, corner);
+    }
+
     // Now add the stops.
-    addStops(gradient.get(), renderer, rootStyle);
+    addStops(gradient.get(), renderer, rootStyle, maxExtent);
 
     return gradient.release();
 }
diff --git a/WebCore/css/CSSGradientValue.h b/WebCore/css/CSSGradientValue.h
index 0988cb6..81b80f3 100644
--- a/WebCore/css/CSSGradientValue.h
+++ b/WebCore/css/CSSGradientValue.h
@@ -37,6 +37,7 @@ class FloatPoint;
 class Gradient;
 
 enum CSSGradientType { CSSLinearGradient, CSSRadialGradient };
+enum CSSGradientRepeat { NonRepeating, Repeating };
 
 struct CSSGradientColorStop {
     RefPtr<CSSPrimitiveValue> m_position; // percentage or length
@@ -60,17 +61,20 @@ public:
     
     virtual bool isLinearGradient() const { return false; }
     virtual bool isRadialGradient() const { return false; }
+    
+    bool isRepeating() const { return m_repeating; }
 
     bool deprecatedType() const { return m_deprecatedType; } // came from -webkit-gradient
 
 protected:
-    CSSGradientValue(bool deprecatedType = false)
+    CSSGradientValue(CSSGradientRepeat repeat, bool deprecatedType = false)
         : m_stopsSorted(false)
         , m_deprecatedType(deprecatedType)
+        , m_repeating(repeat == Repeating)
     {
     }
     
-    void addStops(Gradient*, RenderObject*, RenderStyle* rootStyle);
+    void addStops(Gradient*, RenderObject*, RenderStyle* rootStyle, float maxLengthForRepeat = 0);
 
     // Create the gradient for a given size.
     virtual PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&) = 0;
@@ -89,14 +93,15 @@ protected:
     Vector<CSSGradientColorStop> m_stops;
     bool m_stopsSorted;
     bool m_deprecatedType; // -webkit-gradient()
+    bool m_repeating;
 };
 
 
 class CSSLinearGradientValue : public CSSGradientValue {
 public:
-    static PassRefPtr<CSSLinearGradientValue> create(bool deprecatedType = false)
+    static PassRefPtr<CSSLinearGradientValue> create(CSSGradientRepeat repeat, bool deprecatedType = false)
     {
-        return adoptRef(new CSSLinearGradientValue(deprecatedType));
+        return adoptRef(new CSSLinearGradientValue(repeat, deprecatedType));
     }
 
     void setAngle(PassRefPtr<CSSPrimitiveValue> val) { m_angle = val; }
@@ -104,8 +109,8 @@ public:
     virtual String cssText() const;
 
 private:
-    CSSLinearGradientValue(bool deprecatedType = false)
-        : CSSGradientValue(deprecatedType)
+    CSSLinearGradientValue(CSSGradientRepeat repeat, bool deprecatedType = false)
+        : CSSGradientValue(repeat, deprecatedType)
     {
     }
 
@@ -119,9 +124,9 @@ private:
 
 class CSSRadialGradientValue : public CSSGradientValue {
 public:
-    static PassRefPtr<CSSRadialGradientValue> create(bool deprecatedType = false)
+    static PassRefPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, bool deprecatedType = false)
     {
-        return adoptRef(new CSSRadialGradientValue(deprecatedType));
+        return adoptRef(new CSSRadialGradientValue(repeat, deprecatedType));
     }
 
     virtual String cssText() const;
@@ -136,8 +141,8 @@ public:
     void setEndVerticalSize(PassRefPtr<CSSPrimitiveValue> val) { m_endVerticalSize = val; }
 
 private:
-    CSSRadialGradientValue(bool deprecatedType = false)
-        : CSSGradientValue(deprecatedType)
+    CSSRadialGradientValue(CSSGradientRepeat repeat, bool deprecatedType = false)
+        : CSSGradientValue(repeat, deprecatedType)
     {
     }
 
diff --git a/WebCore/css/CSSParser.cpp b/WebCore/css/CSSParser.cpp
index f817bb9..dd3e38d 100644
--- a/WebCore/css/CSSParser.cpp
+++ b/WebCore/css/CSSParser.cpp
@@ -4753,10 +4753,10 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
     RefPtr<CSSGradientValue> result;
     switch (gradientType) {
         case CSSLinearGradient:
-            result = CSSLinearGradientValue::create(true);
+            result = CSSLinearGradientValue::create(NonRepeating, true);
             break;
         case CSSRadialGradient:
-            result = CSSRadialGradientValue::create(true);
+            result = CSSRadialGradientValue::create(NonRepeating, true);
             break;
     }
 
@@ -4890,9 +4890,9 @@ static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, C
     return p->parseColor(value);
 }
 
-bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient)
+bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
 {
-    RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create();
+    RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating);
     
     // Walk the arguments.
     CSSParserValueList* args = m_valueList->current()->function->args.get();
@@ -4988,9 +4988,9 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient)
     return true;
 }
 
-bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient)
+bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
 {
-    RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create();
+    RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating);
     
     // Walk the arguments.
     CSSParserValueList* args = m_valueList->current()->function->args.get();
@@ -5143,7 +5143,9 @@ bool CSSParser::isGeneratedImageValue(CSSParserValue* val) const
 
     return equalIgnoringCase(val->function->name, "-webkit-gradient(")
         || equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")
+        || equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")
         || equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")
+        || equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")
         || equalIgnoringCase(val->function->name, "-webkit-canvas(");
 }
 
@@ -5158,10 +5160,16 @@ bool CSSParser::parseGeneratedImage(RefPtr<CSSValue>& value)
         return parseDeprecatedGradient(value);
 
     if (equalIgnoringCase(val->function->name, "-webkit-linear-gradient("))
-        return parseLinearGradient(value);
+        return parseLinearGradient(value, NonRepeating);
+
+    if (equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient("))
+        return parseLinearGradient(value, Repeating);
 
     if (equalIgnoringCase(val->function->name, "-webkit-radial-gradient("))
-        return parseRadialGradient(value);
+        return parseRadialGradient(value, NonRepeating);
+
+    if (equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient("))
+        return parseRadialGradient(value, Repeating);
 
     if (equalIgnoringCase(val->function->name, "-webkit-canvas("))
         return parseCanvas(value);
diff --git a/WebCore/css/CSSParser.h b/WebCore/css/CSSParser.h
index 6633072..9015f5b 100644
--- a/WebCore/css/CSSParser.h
+++ b/WebCore/css/CSSParser.h
@@ -158,8 +158,8 @@ namespace WebCore {
         bool parseCanvas(RefPtr<CSSValue>&);
 
         bool parseDeprecatedGradient(RefPtr<CSSValue>&);
-        bool parseLinearGradient(RefPtr<CSSValue>&);
-        bool parseRadialGradient(RefPtr<CSSValue>&);
+        bool parseLinearGradient(RefPtr<CSSValue>&, CSSGradientRepeat repeating);
+        bool parseRadialGradient(RefPtr<CSSValue>&, CSSGradientRepeat repeating);
 
         PassRefPtr<CSSValueList> parseTransform();
         bool parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
diff --git a/WebCore/platform/graphics/cg/GradientCG.cpp b/WebCore/platform/graphics/cg/GradientCG.cpp
index 0503400..21495b9 100644
--- a/WebCore/platform/graphics/cg/GradientCG.cpp
+++ b/WebCore/platform/graphics/cg/GradientCG.cpp
@@ -27,7 +27,6 @@
 #include "config.h"
 #include "Gradient.h"
 
-#include "CSSParser.h"
 #include "GraphicsContextCG.h"
 #include <ApplicationServices/ApplicationServices.h>
 #include <wtf/RetainPtr.h>

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list