Bug 441780. Fix radial gradient clamping to be more aggressive. r=jwatt,sr=roc
authorRobert Longson <longsonr@gmail.com>
Wed, 17 Dec 2008 20:28:33 +1300
changeset 22878 05bf7c30877e68432efedaed9fc75852a4e4649a
parent 22877 bb18fee38c6a8113f82ebed293b1bc90857bb11b
child 22879 79136a417a3a02212320410b7c3442008de1a482
push idunknown
push userunknown
push dateunknown
reviewersjwatt, roc
bugs441780
milestone1.9.2a1pre
Bug 441780. Fix radial gradient clamping to be more aggressive. r=jwatt,sr=roc
layout/reftests/svg/radialGradient-basic-03-ref.svg
layout/reftests/svg/radialGradient-basic-03.svg
layout/reftests/svg/reftest.list
layout/svg/base/src/nsSVGGradientFrame.cpp
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-basic-03-ref.svg
@@ -0,0 +1,34 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" >
+
+    <title>Reference for gradient</title>
+
+    <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=441780 -->
+
+    <defs>
+        <radialGradient id="gradient1" fx="0.002">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+        <radialGradient id="gradient2" r="0.4" fx="0.104">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+        <radialGradient id="gradient3" fx="0.998">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+        <radialGradient id="gradient4" r="0.7" fx="1.197">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+    </defs>
+
+    <circle cx="100" cy="100" r="50" fill="url(#gradient1)"/>
+    <circle cx="100" cy="200" r="50" fill="url(#gradient2)"/>
+    <circle cx="200" cy="100" r="50" fill="url(#gradient3)"/>
+    <circle cx="200" cy="200" r="50" fill="url(#gradient4)"/>
+</svg>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/radialGradient-basic-03.svg
@@ -0,0 +1,34 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" >
+
+    <title>Testcase for gradient</title>
+
+    <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=441780 -->
+
+    <defs>
+        <radialGradient id="gradient1" fx="0">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+        <radialGradient id="gradient2" r="0.4" fx="0.1">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+        <radialGradient id="gradient3" fx="1">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+        <radialGradient id="gradient4" r="0.7" fx="1.3">
+            <stop offset="0" stop-color="lime" />
+            <stop offset="1" stop-color="red"/>
+        </radialGradient>
+    </defs>
+
+    <circle cx="100" cy="100" r="50" fill="url(#gradient1)"/>
+    <circle cx="100" cy="200" r="50" fill="url(#gradient2)"/>
+    <circle cx="200" cy="100" r="50" fill="url(#gradient3)"/>
+    <circle cx="200" cy="200" r="50" fill="url(#gradient4)"/>
+</svg>
\ No newline at end of file
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -76,16 +76,17 @@ fails == inline-in-xul-basic-01.xul pass
 # skip the next test on cocoa, since behaviour depends on the -minor- version of the 10.4 OS.
 # See bugs 379610 and 432298.
 random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == opacity-and-gradient-01.svg pass.svg
 == opacity-and-pattern-01.svg pass.svg
 == pseudo-classes-01.svg pass.svg
 == pseudo-classes-02.svg pseudo-classes-02-ref.svg
 == radialGradient-basic-01.svg pass.svg
 == radialGradient-basic-02.svg pass.svg
+== radialGradient-basic-03.svg radialGradient-basic-03-ref.svg
 == rect-01.svg pass.svg
 == rect-with-rx-and-ry-01.svg pass.svg
 == rect-with-rx-or-ry-01.svg rect-with-rx-or-ry-01-ref.svg
 == rootElement-null-01.svg pass.svg
 == stroke-width-percentage-01.svg pass.svg
 == style-property-not-on-script-element-01.svg pass.svg
 == style-without-type-attribute.svg pass.svg
 == svg-in-foreignObject-01.xhtml svg-in-foreignObject-01-ref.xhtml
--- a/layout/svg/base/src/nsSVGGradientFrame.cpp
+++ b/layout/svg/base/src/nsSVGGradientFrame.cpp
@@ -558,21 +558,24 @@ nsSVGRadialGradientFrame::CreateGradient
     fy = cy;  // if fy isn't set, we must use cy
   else
     fy = GradientLookupAttribute(nsGkAtoms::fy, nsSVGRadialGradientElement::FY, gradient);
 
   if (fx != cx || fy != cy) {
     // The focal point (fFx and fFy) must be clamped to be *inside* - not on -
     // the circumference of the gradient or we'll get rendering anomalies. We
     // calculate the distance from the focal point to the gradient center and
-    // make sure it is *less* than the gradient radius. 0.999 is used as the
+    // make sure it is *less* than the gradient radius. 0.99 is used as the
     // factor of the radius because it's close enough to 1 that we won't get a
     // fringe at the edge of the gradient if we clamp, but not so close to 1
     // that rounding error will give us the same results as using fR itself.
-    double dMax = 0.999 * r;
+    // Also note that .99 < 255/256/2 which is the limit of the fractional part
+    // of cairo's 24.8 fixed point representation divided by 2 to ensure that
+    // we get different cairo fractions
+    double dMax = 0.99 * r;
     float dx = fx - cx;
     float dy = fy - cy;
     double d = sqrt((dx * dx) + (dy * dy));
     if (d > dMax) {
       double angle = atan2(dy, dx);
       fx = (float)(dMax * cos(angle)) + cx;
       fy = (float)(dMax * sin(angle)) + cy;
     }