Bug 622818. Don't clip fixed backgrounds to the viewport if we are inside a transform. r=roc a=blocking
authorTimothy Nikkel <tnikkel@gmail.com>
Tue, 08 Feb 2011 13:29:28 -0600
changeset 62160 ffe65159d361f313c2f7dbf83e498acf112b0edd
parent 62159 78778779f3706333863ffcbe44ff2b35a57fe5ab
child 62161 5ed6c4935486d1aee52f9edcd96043b0fab86fb8
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersroc, blocking
bugs622818
milestone2.0b12pre
Bug 622818. Don't clip fixed backgrounds to the viewport if we are inside a transform. r=roc a=blocking
layout/base/nsCSSRendering.cpp
layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-1.html
layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-ref.html
layout/reftests/backgrounds/reftest.list
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2441,16 +2441,27 @@ ScaleDimension(const nsStyleBackground::
       NS_ABORT_IF_FALSE(PR_FALSE, "bad aDimension.mType");
       return 1.0f;
     case nsStyleBackground::Size::eAuto:
       NS_ABORT_IF_FALSE(PR_FALSE, "aDimension.mType == eAuto isn't handled");
       return 1.0f;
   }
 }
 
+static inline PRBool
+IsTransformed(nsIFrame* aForFrame, nsIFrame* aTopFrame)
+{
+  for (nsIFrame* f = aForFrame; f != aTopFrame; f = f->GetParent()) {
+    if (f->IsTransformed()) {
+      return PR_TRUE;
+    }
+  }
+  return PR_FALSE;
+}
+
 static BackgroundLayerState
 PrepareBackgroundLayer(nsPresContext* aPresContext,
                        nsIFrame* aForFrame,
                        PRUint32 aFlags,
                        const nsRect& aBorderArea,
                        const nsRect& aBGClipRect,
                        const nsStyleBackground& aBackground,
                        const nsStyleBackground::Layer& aLayer)
@@ -2611,23 +2622,25 @@ PrepareBackgroundLayer(nsPresContext* aP
       nsIScrollableFrame* scrollableFrame =
         aPresContext->PresShell()->GetRootScrollFrameAsScrollable();
       if (scrollableFrame) {
         nsMargin scrollbars = scrollableFrame->GetActualScrollbarSizes();
         bgPositioningArea.Deflate(scrollbars);
       }
     }
 
-    if (aFlags & nsCSSRendering::PAINTBG_TO_WINDOW) {
+    if (aFlags & nsCSSRendering::PAINTBG_TO_WINDOW &&
+        !IsTransformed(aForFrame, topFrame)) {
       // Clip background-attachment:fixed backgrounds to the viewport, if we're
-      // painting to the screen. This avoids triggering tiling in common cases,
-      // without affecting output since drawing is always clipped to the viewport
-      // when we draw to the screen. (But it's not a pure optimization since it
-      // can affect the values of pixels at the edge of the viewport ---
-      // whether they're sampled from a putative "next tile" or not.)
+      // painting to the screen and not transformed. This avoids triggering
+      // tiling in common cases, without affecting output since drawing is
+      // always clipped to the viewport when we draw to the screen. (But it's
+      // not a pure optimization since it can affect the values of pixels at the
+      // edge of the viewport --- whether they're sampled from a putative "next
+      // tile" or not.)
       bgClipRect.IntersectRect(bgClipRect, bgPositioningArea + aBorderArea.TopLeft());
     }
   }
 
   nsSize imageSize = state.mImageRenderer.ComputeSize(bgPositioningArea.Size());
   if (imageSize.width <= 0 || imageSize.height <= 0)
     return state;
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-1.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<style>
+	#thediv {
+		position: absolute; left: 0; top: 100%;
+		-moz-transform: rotate(-90deg);
+		-moz-transform-origin: 0 0;
+    background: red url("blue-32x32.png") 0 0 fixed repeat; width: 200px; height: 200px;
+  }
+</style>
+</head>
+<body>
+<div id="thediv"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/backgrounds/fixed-bg-with-transform-outside-viewport-ref.html
@@ -0,0 +1,15 @@
+<html>
+<head>
+<style>
+	#thediv {
+		position: absolute; left: 0; top: 100%;
+		-moz-transform: rotate(-90deg);
+		-moz-transform-origin: 0 0;
+    background: blue 0 0 fixed repeat; width: 200px; height: 200px;
+  }
+</style>
+</head>
+<body>
+<div id="thediv"></div>
+</body>
+</html>
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -103,10 +103,12 @@ fails == background-size-zoom-repeat.htm
 
 # background-size affects images without intrinsic dimensions specially; we may
 # not support such image formats right now, but when we do, we want
 # background-size to be changed accordingly, and hopefully these tests should
 # start failing when we do.
 fails == background-size-no-intrinsic-width-image.html background-size-no-intrinsic-width-image-ref.html
 fails == background-size-no-intrinsic-height-image.html background-size-no-intrinsic-height-image-ref.html
 
+== fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-ref.html
+
 HTTP == root-background-1.html root-background-ref.html
 HTTP != root-background-1.html about:blank