Bug 613659 - Implement box-decoration-break layout for backgrounds. r=cam,jmuizelaar
authorMats Palmgren <matspal@gmail.com>
Fri, 18 Apr 2014 23:01:23 +0000
changeset 179669 b786b54a4f85e0c9902417dd4b29fb12e416b71e
parent 179668 b6b5cdec48e8fb466804fdf817ba5eeb0aa3e3e6
child 179670 1668b5e299ab550b7d81a2230d1482267869043a
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewerscam, jmuizelaar
bugs613659
milestone31.0a1
Bug 613659 - Implement box-decoration-break layout for backgrounds. r=cam,jmuizelaar
gfx/thebes/gfxContext.h
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/base/nsDisplayList.cpp
layout/generic/crashtests/383089-1.html
layout/reftests/backgrounds/background-size-bounding-box.html
layout/reftests/backgrounds/background-size-clone.html
layout/reftests/backgrounds/background-size-continuous.html
layout/reftests/backgrounds/background-size-cover-bounding-box.html
layout/reftests/backgrounds/background-size-cover-clone.html
layout/reftests/backgrounds/background-size-cover-continuous.html
layout/reftests/backgrounds/background-size-cover-each-box.html
layout/reftests/backgrounds/background-size-cover-slice.html
layout/reftests/backgrounds/background-size-each-box.html
layout/reftests/backgrounds/background-size-slice.html
layout/reftests/backgrounds/reftest.list
layout/reftests/bugs/368020-3-ref.html
layout/reftests/bugs/368020-3.html
layout/reftests/bugs/368020-4-ref.html
layout/reftests/bugs/368020-4.html
layout/reftests/bugs/368020-5-ref.html
layout/reftests/bugs/368020-5.html
layout/reftests/bugs/reftest.list
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -826,24 +826,22 @@ public:
   }
 
   void SetContext(gfxContext *aContext) {
     NS_ASSERTION(!mContext, "Not going to call Restore() on some context!!!");
     mContext = aContext;
     mContext->Save();    
   }
 
-  void Reset(gfxContext *aContext) {
-    // Do the equivalent of destroying and re-creating this object.
-    NS_PRECONDITION(aContext, "must provide a context");
-    if (mContext) {
-      mContext->Restore();
+  void EnsureSaved(gfxContext *aContext) {
+    MOZ_ASSERT(!mContext || mContext == aContext, "wrong context");
+    if (!mContext) {
+        mContext = aContext;
+        mContext->Save();
     }
-    mContext = aContext;
-    mContext->Save();
   }
 
 private:
   gfxContext *mContext;
 };
 
 /**
  * Sentry helper class for functions with multiple return points that need to
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -522,16 +522,28 @@ BoxDecorationRectForBorder(nsIFrame* aFr
   if (!aStyleBorder) {
     aStyleBorder = aFrame->StyleBorder();
   }
   return ::IsBoxDecorationSlice(*aStyleBorder)
            ? ::JoinBoxesForSlice(aFrame, aBorderArea, eForBorder)
            : aBorderArea;
 }
 
+static nsRect
+BoxDecorationRectForBackground(nsIFrame* aFrame, const nsRect& aBorderArea,
+                               const nsStyleBorder* aStyleBorder = nullptr)
+{
+  if (!aStyleBorder) {
+    aStyleBorder = aFrame->StyleBorder();
+  }
+  return ::IsBoxDecorationSlice(*aStyleBorder)
+           ? ::JoinBoxesForSlice(aFrame, aBorderArea, eForBackground)
+           : aBorderArea;
+}
+
 //----------------------------------------------------------------------
 // Thebes Border Rendering Code Start
 
 /*
  * Compute the float-pixel radii that should be used for drawing
  * this border/outline, given the various input bits.
  */
 /* static */ void
@@ -1692,16 +1704,17 @@ GetBackgroundClip(gfxContext *aCtx, uint
                   const gfxCornerSizes& aBGRadii, nscoord aAppUnitsPerPixel,
                   /* out */ BackgroundClipState* aClipState)
 {
   aClipState->mBGClipArea = aBorderArea;
   aClipState->mHasAdditionalBGClipArea = false;
   aClipState->mCustomClip = false;
   aClipState->mRadiiAreOuter = true;
   aClipState->mClippedRadii = aBGRadii;
+
   if (aForFrame->GetType() == nsGkAtoms::scrollFrame &&
         NS_STYLE_BG_ATTACHMENT_LOCAL == aBackgroundAttachment) {
     // As of this writing, this is still in discussion in the CSS Working Group
     // http://lists.w3.org/Archives/Public/www-style/2013Jul/0250.html
 
     // The rectangle for 'background-clip' scrolls with the content,
     // but the background is also clipped at a non-scrolling 'padding-box'
     // like the content. (See below.)
@@ -1790,25 +1803,23 @@ SetupBackgroundClip(BackgroundClipState&
 
   // If we have rounded corners, clip all subsequent drawing to the
   // rounded rectangle defined by bgArea and bgRadii (we don't know
   // whether the rounded corners intrude on the dirtyRect or not).
   // Do not do this if we have a caller-provided clip rect --
   // as above with bgArea, arguably a bug, but table painting seems
   // to depend on it.
 
-  if (aHaveRoundedCorners || aClipState.mHasAdditionalBGClipArea) {
-    aAutoSR->Reset(aCtx);
-  }
-
   if (aClipState.mHasAdditionalBGClipArea) {
     gfxRect bgAreaGfx = nsLayoutUtils::RectToGfxRect(
       aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
     bgAreaGfx.Round();
     bgAreaGfx.Condition();
+
+    aAutoSR->EnsureSaved(aCtx);
     aCtx->NewPath();
     aCtx->Rectangle(bgAreaGfx, true);
     aCtx->Clip();
   }
 
   if (aHaveRoundedCorners) {
     gfxRect bgAreaGfx =
       nsLayoutUtils::RectToGfxRect(aClipState.mBGClipArea, aAppUnitsPerPixel);
@@ -1819,16 +1830,17 @@ SetupBackgroundClip(BackgroundClipState&
       // I think it's become possible to hit this since
       // http://hg.mozilla.org/mozilla-central/rev/50e934e4979b landed.
       NS_WARNING("converted background area should not be empty");
       // Make our caller not do anything.
       aClipState.mDirtyRectGfx.SizeTo(gfxSize(0.0, 0.0));
       return;
     }
 
+    aAutoSR->EnsureSaved(aCtx);
     aCtx->NewPath();
     aCtx->RoundedRectangle(bgAreaGfx, aClipState.mClippedRadii, aClipState.mRadiiAreOuter);
     aCtx->Clip();
   }
 }
 
 static void
 DrawBackgroundColor(BackgroundClipState& aClipState, gfxContext *aCtx,
@@ -2593,43 +2605,33 @@ nsCSSRendering::PaintBackgroundWithSC(ns
 
   // At this point, drawBackgroundImage and drawBackgroundColor are
   // true if and only if we are actually supposed to paint an image or
   // color into aDirtyRect, respectively.
   if (!drawBackgroundImage && !drawBackgroundColor)
     return;
 
   // Compute the outermost boundary of the area that might be painted.
-  gfxContext *ctx = aRenderingContext.ThebesContext();
-  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-
-  // Same coordinate space as aBorderArea & aBGClipRect
+  // Same coordinate space as aBorderArea & aBGClipRect.
+  nsRect paintBorderArea =
+    ::BoxDecorationRectForBackground(aForFrame, aBorderArea, &aBorder);
+  nsRect clipBorderArea =
+    ::BoxDecorationRectForBorder(aForFrame, aBorderArea, &aBorder);
   gfxCornerSizes bgRadii;
-  bool haveRoundedCorners;
-  {
-    nscoord radii[8];
-    nsSize frameSize = aForFrame->GetSize();
-    if (&aBorder == aForFrame->StyleBorder() &&
-        frameSize == aBorderArea.Size()) {
-      haveRoundedCorners = aForFrame->GetBorderRadii(radii);
-    } else {
-      haveRoundedCorners = nsIFrame::ComputeBorderRadii(aBorder.mBorderRadius,
-                                   frameSize, aBorderArea.Size(),
-                                   aForFrame->GetSkipSides(), radii);
-    }
-    if (haveRoundedCorners)
-      ComputePixelRadii(radii, appUnitsPerPixel, &bgRadii);
-  }
+  bool haveRoundedCorners =
+    ::GetRadii(aForFrame, aBorder, aBorderArea, clipBorderArea, &bgRadii);
 
   // The 'bgClipArea' (used only by the image tiling logic, far below)
   // is the caller-provided aBGClipRect if any, or else the area
   // determined by the value of 'background-clip' in
   // SetupCurrentBackgroundClip.  (Arguably it should be the
   // intersection, but that breaks the table painter -- in particular,
   // taking the intersection breaks reftests/bugs/403249-1[ab].)
+  gfxContext* ctx = aRenderingContext.ThebesContext();
+  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
   BackgroundClipState clipState;
   uint8_t currentBackgroundClip;
   bool isSolidBorder;
   if (aBGClipRect) {
     clipState.mBGClipArea = *aBGClipRect;
     clipState.mCustomClip = true;
     SetupDirtyRects(clipState.mBGClipArea, aDirtyRect, appUnitsPerPixel,
                     &clipState.mDirtyRect, &clipState.mDirtyRectGfx);
@@ -2649,25 +2651,27 @@ nsCSSRendering::PaintBackgroundWithSC(ns
       // If we have rounded corners, we need to inflate the background
       // drawing area a bit to avoid seams between the border and
       // background.
       currentBackgroundClip = haveRoundedCorners ?
         NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_BG_CLIP_PADDING;
     }
 
     GetBackgroundClip(ctx, currentBackgroundClip, bg->BottomLayer().mAttachment,
-                      aForFrame, aBorderArea,
+                      aForFrame, clipBorderArea,
                       aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
                       &clipState);
   }
 
   // If we might be using a background color, go ahead and set it now.
   if (drawBackgroundColor && !isCanvasFrame)
     ctx->SetColor(gfxRGBA(bgColor));
 
+  // NOTE: no Save() yet, we do that later by calling autoSR.EnsureSaved(ctx)
+  // in the cases we need it.
   gfxContextAutoSaveRestore autoSR;
 
   // If there is no background image, draw a color.  (If there is
   // neither a background image nor a color, we wouldn't have gotten
   // this far.)
   if (!drawBackgroundImage) {
     if (!isCanvasFrame) {
       DrawBackgroundColor(clipState, ctx, haveRoundedCorners, appUnitsPerPixel);
@@ -2717,38 +2721,49 @@ nsCSSRendering::PaintBackgroundWithSC(ns
             NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_BG_CLIP_PADDING;
         }
         if (currentBackgroundClip != newBackgroundClip || !clipSet) {
           currentBackgroundClip = newBackgroundClip;
           // If clipSet is false that means this is the bottom layer and we
           // already called GetBackgroundClip above and it stored its results
           // in clipState.
           if (clipSet) {
+            autoSR = gfxContextAutoSaveRestore(); // reset the previous one
             GetBackgroundClip(ctx, currentBackgroundClip, layer.mAttachment, aForFrame,
-                              aBorderArea, aDirtyRect, haveRoundedCorners,
+                              clipBorderArea, aDirtyRect, haveRoundedCorners,
                               bgRadii, appUnitsPerPixel, &clipState);
           }
           SetupBackgroundClip(clipState, ctx, haveRoundedCorners,
                               appUnitsPerPixel, &autoSR);
           clipSet = true;
+          if (!clipBorderArea.IsEqualEdges(aBorderArea)) {
+            // We're drawing the background for the joined continuation boxes
+            // so we need to clip that to the slice that we want for this frame.
+            gfxRect clip =
+              nsLayoutUtils::RectToGfxRect(aBorderArea, appUnitsPerPixel);
+            autoSR.EnsureSaved(ctx);
+            ctx->NewPath();
+            ctx->SnappedRectangle(clip);
+            ctx->Clip();
+          }
         }
       }
       if ((aLayer < 0 || i == (uint32_t)startLayer) &&
           !clipState.mDirtyRectGfx.IsEmpty()) {
         nsBackgroundLayerState state = PrepareBackgroundLayer(aPresContext, aForFrame,
-            aFlags, aBorderArea, clipState.mBGClipArea, *bg, layer);
+            aFlags, paintBorderArea, clipState.mBGClipArea, layer);
         if (!state.mFillArea.IsEmpty()) {
           if (state.mCompositingOp != gfxContext::OPERATOR_OVER) {
             NS_ASSERTION(ctx->CurrentOperator() == gfxContext::OPERATOR_OVER,
                          "It is assumed the initial operator is OPERATOR_OVER, when it is restored later");
             ctx->SetOperator(state.mCompositingOp);
           }
           state.mImageRenderer.DrawBackground(aPresContext, aRenderingContext,
                                               state.mDestArea, state.mFillArea,
-                                              state.mAnchor + aBorderArea.TopLeft(),
+                                              state.mAnchor + paintBorderArea.TopLeft(),
                                               clipState.mDirtyRect);
           if (state.mCompositingOp != gfxContext::OPERATOR_OVER) {
             ctx->SetOperator(gfxContext::OPERATOR_OVER);
           }
         }
       }
     }
   }
@@ -2793,60 +2808,48 @@ nsCSSRendering::PaintBackgroundColorWith
 
   NS_ASSERTION(drawBackgroundImage || drawBackgroundColor,
                "Should not be trying to paint a background if we don't have one");
   if (!drawBackgroundColor) {
     return;
   }
 
   // Compute the outermost boundary of the area that might be painted.
-  gfxContext *ctx = aRenderingContext.ThebesContext();
-  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-
-  // Same coordinate space as aBorderArea
+  // Same coordinate space as aBorderArea.
+  nsRect clipBorderArea =
+    ::BoxDecorationRectForBorder(aForFrame, aBorderArea, &aBorder);
   gfxCornerSizes bgRadii;
-  bool haveRoundedCorners;
-  {
-    nscoord radii[8];
-    nsSize frameSize = aForFrame->GetSize();
-    if (&aBorder == aForFrame->StyleBorder() &&
-        frameSize == aBorderArea.Size()) {
-      haveRoundedCorners = aForFrame->GetBorderRadii(radii);
-    } else {
-      haveRoundedCorners = nsIFrame::ComputeBorderRadii(aBorder.mBorderRadius,
-                                   frameSize, aBorderArea.Size(),
-                                   aForFrame->GetSkipSides(), radii);
-    }
-    if (haveRoundedCorners)
-      ComputePixelRadii(radii, appUnitsPerPixel, &bgRadii);
-  }
+  bool haveRoundedCorners =
+    ::GetRadii(aForFrame, aBorder, aBorderArea, clipBorderArea, &bgRadii);
 
   // The background is rendered over the 'background-clip' area,
   // which is normally equal to the border area but may be reduced
   // to the padding area by CSS.  Also, if the border is solid, we
   // don't need to draw outside the padding area.  In either case,
   // if the borders are rounded, make sure we use the same inner
   // radii as the border code will.
   // The background-color is drawn based on the bottom
   // background-clip.
+  gfxContext* ctx = aRenderingContext.ThebesContext();
+  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
   const nsStyleBackground *bg = aBackgroundSC->StyleBackground();
   uint8_t currentBackgroundClip = bg->BottomLayer().mClip;
   bool isSolidBorder =
     (aFlags & PAINTBG_WILL_PAINT_BORDER) && IsOpaqueBorder(aBorder);
   if (isSolidBorder && currentBackgroundClip == NS_STYLE_BG_CLIP_BORDER) {
     // If we have rounded corners, we need to inflate the background
     // drawing area a bit to avoid seams between the border and
     // background.
     currentBackgroundClip = haveRoundedCorners ?
       NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_BG_CLIP_PADDING;
   }
 
   BackgroundClipState clipState;
   GetBackgroundClip(ctx, currentBackgroundClip, bg->BottomLayer().mAttachment,
-                    aForFrame, aBorderArea,
+                    aForFrame, clipBorderArea,
                     aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
                     &clipState);
 
   ctx->SetColor(gfxRGBA(bgColor));
 
   gfxContextAutoSaveRestore autoSR;
   DrawBackgroundColor(clipState, ctx, haveRoundedCorners, appUnitsPerPixel);
 }
@@ -2861,57 +2864,27 @@ IsTransformed(nsIFrame* aForFrame, nsIFr
   }
   return false;
 }
 
 nsRect
 nsCSSRendering::ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
                                                  nsIFrame* aForFrame,
                                                  const nsRect& aBorderArea,
-                                                 const nsStyleBackground& aBackground,
                                                  const nsStyleBackground::Layer& aLayer,
                                                  nsIFrame** aAttachedToFrame)
 {
   // Compute background origin area relative to aBorderArea now as we may need
   // it to compute the effective image size for a CSS gradient.
-  nsRect bgPositioningArea(0, 0, 0, 0);
+  nsRect bgPositioningArea;
 
   nsIAtom* frameType = aForFrame->GetType();
   nsIFrame* geometryFrame = aForFrame;
-  if (frameType == nsGkAtoms::inlineFrame) {
-    // XXXjwalden Strictly speaking this is not quite faithful to how
-    // background-break is supposed to interact with background-origin values,
-    // but it's a non-trivial amount of work to make it fully conformant, and
-    // until the specification is more finalized (and assuming background-break
-    // even makes the cut) it doesn't make sense to hammer out exact behavior.
-    switch (aBackground.mBackgroundInlinePolicy) {
-    case NS_STYLE_BG_INLINE_POLICY_EACH_BOX:
-      bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
-      break;
-    case NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX:
-      bgPositioningArea = gInlineBGData->GetBoundingRect(aForFrame);
-      break;
-    default:
-      NS_ERROR("Unknown background-inline-policy value!  "
-               "Please, teach me what to do.");
-    case NS_STYLE_BG_INLINE_POLICY_CONTINUOUS:
-      bgPositioningArea = gInlineBGData->GetContinuousRect(aForFrame);
-      break;
-    }
-  } else if (frameType == nsGkAtoms::canvasFrame) {
-    geometryFrame = aForFrame->GetFirstPrincipalChild();
-    // geometryFrame might be null if this canvas is a page created
-    // as an overflow container (e.g. the in-flow content has already
-    // finished and this page only displays the continuations of
-    // absolutely positioned content).
-    if (geometryFrame) {
-      bgPositioningArea = geometryFrame->GetRect();
-    }
-  } else if (frameType == nsGkAtoms::scrollFrame &&
-             NS_STYLE_BG_ATTACHMENT_LOCAL == aLayer.mAttachment) {
+  if (MOZ_UNLIKELY(frameType == nsGkAtoms::scrollFrame &&
+                   NS_STYLE_BG_ATTACHMENT_LOCAL == aLayer.mAttachment)) {
     nsIScrollableFrame* scrollableFrame = do_QueryFrame(aForFrame);
     bgPositioningArea = nsRect(
       scrollableFrame->GetScrolledFrame()->GetPosition()
         // For the dir=rtl case:
         + scrollableFrame->GetScrollRange().TopLeft(),
       scrollableFrame->GetScrolledRect().Size());
     // The ScrolledRect’s size does not include the borders or scrollbars,
     // reverse the handling of background-origin
@@ -2925,30 +2898,40 @@ nsCSSRendering::ComputeBackgroundPositio
       nsMargin padding = geometryFrame->GetUsedPadding();
       geometryFrame->ApplySkipSides(padding);
       bgPositioningArea.Deflate(padding);
       NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                    "unknown background-origin value");
     }
     *aAttachedToFrame = aForFrame;
     return bgPositioningArea;
+  }
+
+  if (MOZ_UNLIKELY(frameType == nsGkAtoms::canvasFrame)) {
+    geometryFrame = aForFrame->GetFirstPrincipalChild();
+    // geometryFrame might be null if this canvas is a page created
+    // as an overflow container (e.g. the in-flow content has already
+    // finished and this page only displays the continuations of
+    // absolutely positioned content).
+    if (geometryFrame) {
+      bgPositioningArea = geometryFrame->GetRect();
+    }
   } else {
     bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
   }
 
   // Background images are tiled over the 'background-clip' area
   // but the origin of the tiling is based on the 'background-origin' area
   if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_BORDER && geometryFrame) {
     nsMargin border = geometryFrame->GetUsedBorder();
     if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
       border += geometryFrame->GetUsedPadding();
       NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                    "unknown background-origin value");
     }
-    geometryFrame->ApplySkipSides(border);
     bgPositioningArea.Deflate(border);
   }
 
   nsIFrame* attachedToFrame = aForFrame;
   if (NS_STYLE_BG_ATTACHMENT_FIXED == aLayer.mAttachment) {
     // If it's a fixed background attachment, then the image is placed
     // relative to the viewport, which is the area of the root frame
     // in a screen context or the page content frame in a print context.
@@ -3022,32 +3005,31 @@ ComputeDrawnSizeForBackground(const CSSS
 }
 
 nsBackgroundLayerState
 nsCSSRendering::PrepareBackgroundLayer(nsPresContext* aPresContext,
                                        nsIFrame* aForFrame,
                                        uint32_t aFlags,
                                        const nsRect& aBorderArea,
                                        const nsRect& aBGClipRect,
-                                       const nsStyleBackground& aBackground,
                                        const nsStyleBackground::Layer& aLayer)
 {
   /*
-   * The background properties we need to keep in mind when drawing background
+   * The properties we need to keep in mind when drawing background
    * layers are:
    *
    *   background-image
    *   background-repeat
    *   background-attachment
    *   background-position
    *   background-clip
    *   background-origin
    *   background-size
-   *   background-break (-moz-background-inline-policy)
    *   background-blend-mode
+   *   box-decoration-break
    *
    * (background-color applies to the entire element and not to individual
    * layers, so it is irrelevant to this method.)
    *
    * These properties have the following dependencies upon each other when
    * determining rendering:
    *
    *   background-image
@@ -3060,32 +3042,31 @@ nsCSSRendering::PrepareBackgroundLayer(n
    *     depends upon background-size (for the image's scaled size) and
    *     background-break (for the background positioning area)
    *   background-clip
    *     no dependencies
    *   background-origin
    *     depends upon background-attachment (only in the case where that value
    *     is 'fixed')
    *   background-size
-   *     depends upon background-break (for the background positioning area for
-   *     resolving percentages), background-image (for the image's intrinsic
+   *     depends upon box-decoration-break (for the background positioning area
+   *     for resolving percentages), background-image (for the image's intrinsic
    *     size), background-repeat (if that value is 'round'), and
    *     background-origin (for the background painting area, when
    *     background-repeat is 'round')
-   *   background-break
-   *     depends upon background-origin (specifying how the boxes making up the
-   *     background positioning area are determined)
+   *   box-decoration-break
+   *     no dependencies
    *
    * As a result of only-if dependencies we don't strictly do a topological
    * sort of the above properties when processing, but it's pretty close to one:
    *
    *   background-clip (by caller)
    *   background-image
-   *   background-break, background-origin
-   *   background-attachment (postfix for background-{origin,break} if 'fixed')
+   *   box-decoration-break, background-origin
+   *   background-attachment (postfix for background-origin if 'fixed')
    *   background-size
    *   background-position
    *   background-repeat
    */
 
   uint32_t irFlags = 0;
   if (aFlags & nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES) {
     irFlags |= nsImageRenderer::FLAG_SYNC_DECODE_IMAGES;
@@ -3101,17 +3082,17 @@ nsCSSRendering::PrepareBackgroundLayer(n
   }
 
   // The frame to which the background is attached
   nsIFrame* attachedToFrame = aForFrame;
   // Compute background origin area relative to aBorderArea now as we may need
   // it to compute the effective image size for a CSS gradient.
   nsRect bgPositioningArea =
     ComputeBackgroundPositioningArea(aPresContext, aForFrame, aBorderArea,
-                                     aBackground, aLayer, &attachedToFrame);
+                                     aLayer, &attachedToFrame);
 
   // For background-attachment:fixed backgrounds, we'll limit the area
   // where the background can be drawn to the viewport.
   nsRect bgClipRect = aBGClipRect;
 
   // Compute the anchor point.
   //
   // relative to aBorderArea.TopLeft() (which is where the top-left
@@ -3171,23 +3152,23 @@ nsCSSRendering::PrepareBackgroundLayer(n
   return state;
 }
 
 nsRect
 nsCSSRendering::GetBackgroundLayerRect(nsPresContext* aPresContext,
                                        nsIFrame* aForFrame,
                                        const nsRect& aBorderArea,
                                        const nsRect& aClipRect,
-                                       const nsStyleBackground& aBackground,
                                        const nsStyleBackground::Layer& aLayer,
                                        uint32_t aFlags)
 {
+  nsRect borderArea = ::BoxDecorationRectForBackground(aForFrame, aBorderArea);
   nsBackgroundLayerState state =
-      PrepareBackgroundLayer(aPresContext, aForFrame, aFlags, aBorderArea,
-                             aClipRect, aBackground, aLayer);
+      PrepareBackgroundLayer(aPresContext, aForFrame, aFlags, borderArea,
+                             aClipRect, aLayer);
   return state.mFillArea;
 }
 
 /* static */ bool
 nsCSSRendering::IsBackgroundImageDecodedForStyleContextAndLayer(
   const nsStyleBackground *aBackground, uint32_t aLayer)
 {
   const nsStyleImage* image = &aBackground->mLayers[aLayer].mImage;
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -451,27 +451,25 @@ struct nsCSSRendering {
                            nsIFrame* aFrame,
                            bool& aDrawBackgroundImage,
                            bool& aDrawBackgroundColor);
 
   static nsRect
   ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
                                    nsIFrame* aForFrame,
                                    const nsRect& aBorderArea,
-                                   const nsStyleBackground& aBackground,
                                    const nsStyleBackground::Layer& aLayer,
                                    nsIFrame** aAttachedToFrame);
 
   static nsBackgroundLayerState
   PrepareBackgroundLayer(nsPresContext* aPresContext,
                          nsIFrame* aForFrame,
                          uint32_t aFlags,
                          const nsRect& aBorderArea,
                          const nsRect& aBGClipRect,
-                         const nsStyleBackground& aBackground,
                          const nsStyleBackground::Layer& aLayer);
 
   /**
    * Render the background for an element using css rendering rules
    * for backgrounds.
    */
   enum {
     /**
@@ -537,17 +535,16 @@ struct nsCSSRendering {
    * Returns the rectangle covered by the given background layer image, taking
    * into account background positioning, sizing, and repetition, but not
    * clipping.
    */
   static nsRect GetBackgroundLayerRect(nsPresContext* aPresContext,
                                        nsIFrame* aForFrame,
                                        const nsRect& aBorderArea,
                                        const nsRect& aClipRect,
-                                       const nsStyleBackground& aBackground,
                                        const nsStyleBackground::Layer& aLayer,
                                        uint32_t aFlags);
 
   /**
    * Checks if image in layer aLayer of aBackground is currently decoded.
    */
   static bool IsBackgroundImageDecodedForStyleContextAndLayer(
     const nsStyleBackground *aBackground, uint32_t aLayer);
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1929,24 +1929,18 @@ nsDisplayBackgroundImage::IsSingleFixedP
   uint32_t flags = aBuilder->GetBackgroundPaintFlags();
   nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
   const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
 
   if (layer.mAttachment != NS_STYLE_BG_ATTACHMENT_FIXED)
     return false;
 
   nsBackgroundLayerState state =
-    nsCSSRendering::PrepareBackgroundLayer(presContext,
-                                           mFrame,
-                                           flags,
-                                           borderArea,
-                                           aClipRect,
-                                           *mBackgroundStyle,
-                                           layer);
-
+    nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
+                                           borderArea, aClipRect, layer);
   nsImageRenderer* imageRenderer = &state.mImageRenderer;
   // We only care about images here, not gradients.
   if (!imageRenderer->IsRasterImage())
     return false;
 
   int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
   *aDestRect = nsLayoutUtils::RectToGfxRect(state.mFillArea, appUnitsPerDevPixel);
 
@@ -1969,24 +1963,18 @@ nsDisplayBackgroundImage::TryOptimizeToI
     return false;
   }
   nscoord radii[8];
   if (mFrame->GetBorderRadii(radii)) {
     return false;
   }
 
   nsBackgroundLayerState state =
-    nsCSSRendering::PrepareBackgroundLayer(presContext,
-                                           mFrame,
-                                           flags,
-                                           borderArea,
-                                           borderArea,
-                                           *mBackgroundStyle,
-                                           layer);
-
+    nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
+                                           borderArea, borderArea, layer);
   nsImageRenderer* imageRenderer = &state.mImageRenderer;
   // We only care about images here, not gradients.
   if (!imageRenderer->IsRasterImage())
     return false;
 
   nsRefPtr<ImageContainer> imageContainer = imageRenderer->GetContainer(aManager);
   // Image is not ready to be made into a layer yet
   if (!imageContainer)
@@ -2242,17 +2230,17 @@ nsDisplayBackgroundImage::GetPositioning
 {
   if (!mBackgroundStyle) {
     return nsRect();
   }
   nsIFrame* attachedToFrame;
   return nsCSSRendering::ComputeBackgroundPositioningArea(
       mFrame->PresContext(), mFrame,
       nsRect(ToReferenceFrame(), mFrame->GetSize()),
-      *mBackgroundStyle, mBackgroundStyle->mLayers[mLayer],
+      mBackgroundStyle->mLayers[mLayer],
       &attachedToFrame) + ToReferenceFrame();
 }
 
 bool
 nsDisplayBackgroundImage::RenderingMightDependOnPositioningAreaSizeChange()
 {
   if (!mBackgroundStyle)
     return false;
@@ -2356,18 +2344,17 @@ nsDisplayBackgroundImage::GetBoundsInter
   nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
   nsRect clipRect = borderBox;
   if (mFrame->GetType() == nsGkAtoms::canvasFrame) {
     nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
     clipRect = frame->CanvasArea() + ToReferenceFrame();
   }
   const nsStyleBackground::Layer& layer = mBackgroundStyle->mLayers[mLayer];
   return nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
-                                                borderBox, clipRect,
-                                                *mBackgroundStyle, layer,
+                                                borderBox, clipRect, layer,
                                                 aBuilder->GetBackgroundPaintFlags());
 }
 
 uint32_t
 nsDisplayBackgroundImage::GetPerFrameKey()
 {
   return (mLayer << nsDisplayItem::TYPE_BITS) |
     nsDisplayItem::GetPerFrameKey();
--- a/layout/generic/crashtests/383089-1.html
+++ b/layout/generic/crashtests/383089-1.html
@@ -73,14 +73,14 @@ function foo()
 </style>
 
 </head><body onload="setTimeout(olo, 30);">
 
 <br style="overflow: visible;" id="br1">
 <br style="clear: none;" id="br2">
 <br style="height: auto; clear: both; width: auto;" id="br3">
 <br style="position: static;" id="br4">
-<br style="background: yellow none repeat scroll 0% 0%; background-clip: initial; background-origin: initial; -moz-background-inline-policy: initial; display: inline;" id="br5">
+<br style="background: yellow none repeat scroll 0% 0%; background-clip: initial; background-origin: initial; display: inline;" id="br5">
 <br style="width: 1px; visibility: visible;" id="br6">
 <br style="color: black; width: 2px; display: table-cell;" id="br7">
 <table border="1"><tbody><tr style="display: list-item;" id="tableRow"><td>x</td></tr></tbody></table>
 
 </body></html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/background-size-bounding-box.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>background-break: bounding-box</title>
-  <style type="text/css">
-@font-face
-{
-  font-family: Ahem;
-  src: url(../fonts/Ahem.ttf);
-}
-
-#outer
-{
-  border: 1px solid black;
-  width: 10em;
-}
-#ahem-lines
-{
-  font-family: Ahem;
-  font-size: 32px;
-  white-space: pre;
-  background-image: url(blue-8x20-green-8x20.png);
-  background-repeat: no-repeat;
-  -moz-background-inline-policy: bounding-box;
-}
-</style>
-</head>
-<body>
-<div id="outer">
-<span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
-      <!-- EOL -->
-      <!-- EOL -->
-      </span></div>
-</body>
-</html>
rename from layout/reftests/backgrounds/background-size-each-box.html
rename to layout/reftests/backgrounds/background-size-clone.html
--- a/layout/reftests/backgrounds/background-size-each-box.html
+++ b/layout/reftests/backgrounds/background-size-clone.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-break: each-box</title>
+  <title>box-decoration-break: clone</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -16,21 +16,21 @@
 }
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
-  -moz-background-inline-policy: each-box;
+  box-decoration-break: clone;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for clone --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/background-size-cover-bounding-box.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>background-size: cover; background-break: bounding-box</title>
-  <style type="text/css">
-@font-face
-{
-  font-family: Ahem;
-  src: url(../fonts/Ahem.ttf);
-}
-
-#outer
-{
-  border: 1px solid black;
-  width: 10em;
-}
-#ahem-lines
-{
-  font-family: Ahem;
-  font-size: 32px;
-  white-space: pre;
-  background-image: url(blue-8x20-green-8x20.png);
-  background-repeat: no-repeat;
-  background-size: cover;
-  -moz-background-inline-policy: bounding-box;
-}
-</style>
-</head>
-<body>
-<div id="outer">
-<span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
-      <!-- EOL -->
-      <!-- EOL -->
-      </span></div>
-</body>
-</html>
rename from layout/reftests/backgrounds/background-size-cover-each-box.html
rename to layout/reftests/backgrounds/background-size-cover-clone.html
--- a/layout/reftests/backgrounds/background-size-cover-each-box.html
+++ b/layout/reftests/backgrounds/background-size-cover-clone.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-size: cover; background-break: each-box</title>
+  <title>background-size: cover; box-decoration-break: clone</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -17,21 +17,21 @@
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
   background-size: cover;
-  -moz-background-inline-policy: each-box;
+  box-decoration-break: clone;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for clone --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
rename from layout/reftests/backgrounds/background-size-cover-continuous.html
rename to layout/reftests/backgrounds/background-size-cover-slice.html
--- a/layout/reftests/backgrounds/background-size-cover-continuous.html
+++ b/layout/reftests/backgrounds/background-size-cover-slice.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-size: cover; background-break: continuous</title>
+  <title>background-size: cover; box-decoration-break: slice</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -17,21 +17,21 @@
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
   background-size: cover;
-  -moz-background-inline-policy: continuous;
+  box-decoration-break: slice;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for slice --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
rename from layout/reftests/backgrounds/background-size-continuous.html
rename to layout/reftests/backgrounds/background-size-slice.html
--- a/layout/reftests/backgrounds/background-size-continuous.html
+++ b/layout/reftests/backgrounds/background-size-slice.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-break: continuous</title>
+  <title>box-decoration-break: slice</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -16,21 +16,21 @@
 }
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
-  -moz-background-inline-policy: continuous;
+  box-decoration-break: slice;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for slice --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -85,29 +85,25 @@ fails-if(smallScreen&&Android) != backgr
 == background-size-contain-clip-border.html background-size-contain-clip-border-ref.html
 == background-size-contain-position-fifty-fifty.html background-size-contain-position-fifty-fifty-ref.html
 == background-size-contain-clip-padding-origin-border.html background-size-contain-clip-padding-origin-border-ref.html
 == background-size-contain-clip-padding-origin-border-padding.html background-size-contain-clip-padding-origin-border-padding-ref.html
 
 skip-if(B2G) == background-layers-1a.html background-layers-1-ref.html # bug 773482
 == background-layers-1b.html background-layers-1-ref.html
 
-# -moz-background-inline-policy is touchy and hard to test due to stretching
-# artifacts and the difficulty of covering exact lines, and its CSS3 analog is
-# on the chopping block at the moment, so just make sure background-size results
-# in a different rendering when present.
-!= background-size-cover-continuous.html background-size-continuous.html
-!= background-size-cover-each-box.html background-size-each-box.html
-!= background-size-cover-bounding-box.html background-size-bounding-box.html
+# box-decoration-break's effect on backgrounds is touchy and hard to test due to stretching
+# artifacts and the difficulty of covering exact lines, so just make sure
+# background-size results in a different rendering when present.
+pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-slice.html background-size-slice.html
+pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-clone.html background-size-clone.html
 
 # ...and make sure each rendering with background-size is different from the
-# others
-!= background-size-cover-continuous.html background-size-cover-each-box.html
-!= background-size-cover-continuous.html background-size-cover-bounding-box.html
-!= background-size-cover-each-box.html background-size-cover-bounding-box.html
+# other
+pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-slice.html background-size-cover-clone.html
 
 == background-size-monster-ch.html background-size-monster-ref.html
 == background-size-monster-cm.html background-size-monster-ref.html
 == background-size-monster-em.html background-size-monster-ref.html
 == background-size-monster-ex.html background-size-monster-ref.html
 == background-size-monster-inches.html background-size-monster-ref.html
 == background-size-monster-mm.html background-size-monster-ref.html
 == background-size-monster-pc.html background-size-monster-ref.html
--- a/layout/reftests/bugs/368020-3-ref.html
+++ b/layout/reftests/bugs/368020-3-ref.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; -moz-background-inline-policy: continuous; background-inline-policy: continuous;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
--- a/layout/reftests/bugs/368020-3.html
+++ b/layout/reftests/bugs/368020-3.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 2% 3% 2px; -moz-background-inline-policy: continuous; background-inline-policy: continuous;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 2% 3% 2px;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/bugs/368020-4-ref.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Testcase, bug 368020</title>
-</head>
-<body style="line-height: 3; width: 500px; height: 250px;">
-
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; -moz-background-inline-policy: bounding-box; background-inline-policy: bounding-box;">
-        blah<br>
-        blah<br>
-        blah
-    </span>
-
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/368020-4.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Testcase, bug 368020</title>
-</head>
-<body style="line-height: 3; width: 500px; height: 250px;">
-
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 2% 3% 2px; -moz-background-inline-policy: bounding-box; background-inline-policy: bounding-box;">
-        blah<br>
-        blah<br>
-        blah
-    </span>
-
-</body>
-</html>
--- a/layout/reftests/bugs/368020-5-ref.html
+++ b/layout/reftests/bugs/368020-5-ref.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; -moz-background-inline-policy: each-box; background-inline-policy: each-box;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; box-decoration-break: clone;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
--- a/layout/reftests/bugs/368020-5.html
+++ b/layout/reftests/bugs/368020-5.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 10px 15px 2px; -moz-background-inline-policy: each-box; background-inline-policy: each-box;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 10px 15px 2px; box-decoration-break: clone;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -591,18 +591,17 @@ skip-if(B2G) == 367247-l-scroll.html 367
 == 367612-1c.html 367612-1-ref.html
 == 367612-1d.html 367612-1-ref.html
 == 367612-1e.html 367612-1-ref.html
 == 367612-1f.html 367612-1-ref.html
 != 367612-1g.html 367612-1-ref.html
 skip-if(B2G) random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == 368020-1.html 368020-1-ref.html
 == 368020-2.html 368020-2-ref.html
 fails == 368020-3.html 368020-3-ref.html # bug 368085
-fails == 368020-4.html 368020-4-ref.html # bug 368085
-== 368020-5.html 368020-5-ref.html
+pref(layout.css.box-decoration-break.enabled,true) == 368020-5.html 368020-5-ref.html
 == 368155-1.xhtml 368155-1-ref.xhtml
 asserts(4) == 368155-negative-margins-1.html 368155-negative-margins-1-ref.html # bug 387205 / bug 457397
 # we can't test this because there's antialiasing involved, and our comparison
 # is too exact
 # == 368247-1.html 368247-1-ref.html
 == 368247-2.html 368247-2-ref.html
 == 368504-1.html 368504-1-ref.html
 == 368504-2.html 368504-2-ref.html