Bug 743444 - Lighting Filter clipped when kernelUnitLength specified. r=roc
authorRobert Longson <longsonr@gmail.com>
Fri, 13 Apr 2012 08:01:55 +0100
changeset 91600 709a9867cc31314012a132f76bad041c61e64d61
parent 91599 2187cab0d2f6eed33fef23794a0d9a17fd01e048
child 91601 1587faab5e5c69818282a9943daad4fe4a33baa6
push id22465
push usermak77@bonardo.net
push dateSat, 14 Apr 2012 11:58:29 +0000
treeherdermozilla-central@6880c195054f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs743444
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 743444 - Lighting Filter clipped when kernelUnitLength specified. r=roc
content/svg/content/src/nsSVGFilters.cpp
layout/reftests/svg/filters/filter-kernelUnitLength-01-ref.svg
layout/reftests/svg/filters/filter-kernelUnitLength-01.svg
layout/reftests/svg/filters/reftest.list
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -95,16 +95,26 @@ CopyRect(const nsSVGFE::Image* aDest, co
   NS_ASSERTION(aDest->mImage->GetSize() == aSrc->mImage->GetSize(), "size mismatch");
   NS_ASSERTION(nsIntRect(0, 0, aDest->mImage->Width(), aDest->mImage->Height()).Contains(aDataRect),
                "aDataRect out of bounds");
 
   CopyDataRect(aDest->mImage->Data(), aSrc->mImage->Data(),
                aSrc->mImage->Stride(), aDataRect);
 }
 
+static void
+CopyAndScaleDeviceOffset(const gfxImageSurface *aImage, gfxImageSurface *aResult,
+                         gfxFloat kernelX, gfxFloat kernelY)
+{
+  gfxPoint deviceOffset = aImage->GetDeviceOffset();
+  deviceOffset.x /= kernelX;
+  deviceOffset.y /= kernelY;
+  aResult->SetDeviceOffset(deviceOffset);
+}
+
 //--------------------Filter Element Base Class-----------------------
 
 nsSVGElement::LengthInfo nsSVGFE::sLengthInfo[4] =
 {
   { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, nsSVGUtils::X },
   { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, nsSVGUtils::Y },
   { &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, nsSVGUtils::X },
   { &nsGkAtoms::height, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, nsSVGUtils::Y }
@@ -176,16 +186,20 @@ nsSVGFE::SetupScalingFilter(nsSVGFilterI
   result.mTarget = new gfxImageSurface(scaledSize,
                                        gfxASurface::ImageFormatARGB32);
   if (!result.mSource || result.mSource->CairoStatus() ||
       !result.mTarget || result.mTarget->CairoStatus()) {
     result.mSource = nsnull;
     result.mTarget = nsnull;
     return result;
   }
+
+  CopyAndScaleDeviceOffset(aSource->mImage, result.mSource, kernelX, kernelY);
+  CopyAndScaleDeviceOffset(aTarget->mImage, result.mTarget, kernelX, kernelY);
+
   result.mRealTarget = aTarget->mImage;
 
   gfxContext ctx(result.mSource);
   ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
   ctx.Scale(double(scaledSize.width) / aTarget->mImage->Width(),
             double(scaledSize.height) / aTarget->mImage->Height());
   ctx.SetSource(aSource->mImage);
   ctx.Paint();
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/filter-kernelUnitLength-01-ref.svg
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <defs>
+    <filter id="emboss">
+      <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/>
+      <!-- without kernelUnitLength attribute -->
+      <feSpecularLighting in="blur" result="spec" surfaceScale="-3"
+                          specularConstant="2" specularExponent="16"
+                          lighting-color="#ffb155">
+        <feDistantLight azimuth="45" elevation="45"/>
+      </feSpecularLighting>
+      <feComposite in="spec" in2="SourceGraphic" operator="in" result="specOut"/>
+    </filter>
+  </defs>
+  <path filter="url(#emboss)" d="M 44.408917,5.7095287 C 535.13945,101.91182 534.01725,101.52506 532.53904,101.52499 C 531.36871,101.52506 530.17420,101.85117 528.96683,102.49024 z "/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/filter-kernelUnitLength-01.svg
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <defs>
+    <filter id="emboss">
+      <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/>
+      <!-- with kernelUnitLength attribute -->
+      <feSpecularLighting in="blur" result="spec" surfaceScale="-3"
+                          specularConstant="2" specularExponent="16"
+                          lighting-color="#ffb155" kernelUnitLength="1">
+        <feDistantLight azimuth="45" elevation="45"/>
+      </feSpecularLighting>
+      <feComposite in="spec" in2="SourceGraphic" operator="in" result="specOut"/>
+    </filter>
+  </defs>
+  <path filter="url(#emboss)" d="M 44.408917,5.7095287 C 535.13945,101.91182 534.01725,101.52506 532.53904,101.52499 C 531.36871,101.52506 530.17420,101.85117 528.96683,102.49024 z "/>
+</svg>
--- a/layout/reftests/svg/filters/reftest.list
+++ b/layout/reftests/svg/filters/reftest.list
@@ -49,16 +49,17 @@
 == filter-clipped-rect-01.svg pass.svg
 == filter-filterRes-high-01.svg pass.svg
 == filter-filterRes-high-02.svg pass.svg
 random-if(d2d) == filter-filterRes-low-01.svg pass.svg
 == filter-inner-svg-01.svg pass.svg
 == filter-inner-svg-02.svg pass.svg
 == filter-inner-svg-03.svg pass.svg
 fails == filter-marked-line-01.svg pass.svg # bug 477704
+== filter-kernelUnitLength-01.svg filter-kernelUnitLength-01-ref.svg
 == filter-marked-line-02.svg pass.svg
 == filter-marked-line-03.svg pass.svg
 == filter-marked-line-04.svg pass.svg
 == filter-marked-line-05.svg pass.svg
 == filter-marked-line-06.svg pass.svg
 == filter-marked-line-07.svg pass.svg
 == filter-marked-line-08.svg pass.svg
 == filter-marked-line-09.svg pass.svg