Bug 1047973 - pattern with patternUnits=objectBoundingBox and preserveAspectRatio=... meet stretches to the size of a shape. r=dholbert
authorRobert Longson <longsonr@gmail.com>
Tue, 07 Apr 2015 08:45:59 +0100
changeset 237883 731579510beffbf6d9d9e192bb9de9f613d84a6a
parent 237882 d23df90fc306fcd63b87a606f48d1a491a8040a9
child 237884 86a2315700550aa754bf13c83b74fe0415b6a1a9
push id28552
push userryanvm@gmail.com
push dateTue, 07 Apr 2015 19:53:37 +0000
treeherderautoland@c13b6926e6eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1047973
milestone40.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 1047973 - pattern with patternUnits=objectBoundingBox and preserveAspectRatio=... meet stretches to the size of a shape. r=dholbert
layout/reftests/svg/reftest.list
layout/reftests/svg/viewBox-and-pattern-04.svg
layout/svg/nsSVGPatternFrame.cpp
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -381,16 +381,17 @@ random-if(/^Windows\x20NT\x205\.1/.test(
 == tspan-xy-05.svg tspan-xy-ref.svg # bug 773482
 == tspan-xy-06.svg tspan-xy-ref.svg # bug 773482
 == tspan-xy-anchor-middle-01.svg tspan-xy-anchor-middle-ref.svg # bug 773482
 == tspan-xy-anchor-end-01.svg tspan-xy-anchor-end-ref.svg # bug 773482
 == userSpaceOnUse-and-pattern-01.svg userSpaceOnUse-and-pattern-01-ref.svg
 == viewBox-and-pattern-01.svg pass.svg
 == viewBox-and-pattern-02.svg pass.svg
 == viewBox-and-pattern-03.svg pass.svg
+== viewBox-and-pattern-04.svg pass.svg
 == viewBox-invalid-01.svg pass.svg
 == viewBox-valid-01.svg pass.svg
 == viewBox-valid-02.xhtml pass.svg
 == viewport-percent-graphic-user-01.svg pass.svg
 == winding-01.svg pass.svg
 
 == svg-effects-area-unzoomed.xhtml svg-effects-area-unzoomed-ref.xhtml
 == svg-effects-area-zoomed-in.xhtml svg-effects-area-zoomed-in-ref.xhtml
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/viewBox-and-pattern-04.svg
@@ -0,0 +1,17 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <defs>
+    <pattern id="p2"
+             height="1" width="1"
+             viewBox="0 0 10 10"
+             preserveAspectRatio="xMidYMid meet">
+      <circle cx="5" cy="5" r="5px" fill="red"/>
+    </pattern>
+  </defs>
+  <rect width="100%" height="100%" fill="lime"/>
+  <rect width="300" height="100" fill="url(#p2)"/>
+  <rect x="100" width="100" height="100" fill="lime"/>
+</svg>
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -356,19 +356,19 @@ nsSVGPatternFrame::PaintPattern(const Dr
   gfxFloat patternWidth = bbox.Width();
   gfxFloat patternHeight = bbox.Height();
 
   if (resultOverflows ||
       patternWidth != surfaceSize.width ||
       patternHeight != surfaceSize.height) {
     // scale drawing to pattern surface size
     gfxMatrix tempTM =
-      gfxMatrix(surfaceSize.width / patternWidth, 0.0f,
-                0.0f, surfaceSize.height / patternHeight,
-                0.0f, 0.0f);
+      gfxMatrix(surfaceSize.width / patternWidth, 0.0,
+                0.0, surfaceSize.height / patternHeight,
+                0.0, 0.0);
     patternWithChildren->mCTM->PreMultiply(tempTM);
 
     // and rescale pattern to compensate
     patternMatrix->PreScale(patternWidth / surfaceSize.width,
                             patternHeight / surfaceSize.height);
   }
 
   RefPtr<DrawTarget> dt =
@@ -634,33 +634,33 @@ nsSVGPatternFrame::GetPatternRect(uint16
 gfxMatrix
 nsSVGPatternFrame::ConstructCTM(const nsSVGViewBox& aViewBox,
                                 uint16_t aPatternContentUnits,
                                 uint16_t aPatternUnits,
                                 const gfxRect &callerBBox,
                                 const Matrix &callerCTM,
                                 nsIFrame *aTarget)
 {
-  gfxMatrix tCTM;
   SVGSVGElement *ctx = nullptr;
   nsIContent* targetContent = aTarget->GetContent();
+  gfxFloat scaleX, scaleY;
 
   // The objectBoundingBox conversion must be handled in the CTM:
   if (IncludeBBoxScale(aViewBox, aPatternContentUnits, aPatternUnits)) {
-    tCTM.Scale(callerBBox.Width(), callerBBox.Height());
+    scaleX = callerBBox.Width();
+    scaleY = callerBBox.Height();
   } else {
     if (targetContent->IsSVGElement()) {
       ctx = static_cast<nsSVGElement*>(targetContent)->GetCtx();
     }
-    float scale = MaxExpansion(callerCTM);
-    tCTM.Scale(scale, scale);
+    scaleX = scaleY = MaxExpansion(callerCTM);
   }
 
   if (!aViewBox.IsExplicitlySet()) {
-    return tCTM;
+    return gfxMatrix(scaleX, 0.0, 0.0, scaleY, 0.0, 0.0);
   }
   const nsSVGViewBoxRect viewBoxRect = aViewBox.GetAnimValue();
 
   if (viewBoxRect.height <= 0.0f || viewBoxRect.width <= 0.0f) {
     return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
   }
 
   float viewportWidth, viewportHeight;
@@ -680,22 +680,22 @@ nsSVGPatternFrame::ConstructCTM(const ns
       GetLengthValue(SVGPatternElement::ATTR_HEIGHT)->GetAnimValue(aTarget);
   }
 
   if (viewportWidth <= 0.0f || viewportHeight <= 0.0f) {
     return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
   }
 
   Matrix tm = SVGContentUtils::GetViewBoxTransform(
-    viewportWidth, viewportHeight,
+    viewportWidth * scaleX, viewportHeight * scaleY,
     viewBoxRect.x, viewBoxRect.y,
     viewBoxRect.width, viewBoxRect.height,
     GetPreserveAspectRatio());
 
-  return ThebesMatrix(tm) * tCTM;
+  return ThebesMatrix(tm);
 }
 
 //----------------------------------------------------------------------
 // nsSVGPaintServerFrame methods:
 
 already_AddRefed<gfxPattern>
 nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
                                          const DrawTarget* aDrawTarget,