Bug 1319626 - Part 3: Refactor nsCSSRendering border painting so callers can access the border renderer. r?mstange draft
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 23 Nov 2016 14:35:54 +1300
changeset 442690 decd8d5d70febbf5394f21168d7a0ce1d571676c
parent 442689 156a9209f2c190f01a0feea69e2204a7e8c284eb
child 442691 87d7a3c73782f05eba8d70f1c4cfb87d42673633
push id36782
push usermwoodrow@mozilla.com
push dateWed, 23 Nov 2016 01:39:09 +0000
reviewersmstange
bugs1319626
milestone53.0a1
Bug 1319626 - Part 3: Refactor nsCSSRendering border painting so callers can access the border renderer. r?mstange MozReview-Commit-ID: 3PNSP4ZmBbK
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRendering.h
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsCSSRenderingBorders.h
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -668,24 +668,152 @@ nsCSSRendering::PaintBorder(nsPresContex
 
   nsStyleBorder newStyleBorder(*styleBorder);
 
   NS_FOR_CSS_SIDES(side) {
     nscolor color = aStyleContext->GetVisitedDependentColor(
       nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color)[side]);
     newStyleBorder.mBorderColor[side] = StyleComplexColor::FromColor(color);
   }
-  DrawResult result =
-    PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
-                               aDirtyRect, aBorderArea, newStyleBorder,
-                               aStyleContext, aFlags, aSkipSides);
-
-  return result;
+  return PaintBorderWithStyleBorder(aPresContext, aRenderingContext, aForFrame,
+                                    aDirtyRect, aBorderArea, newStyleBorder,
+                                    aStyleContext, aFlags, aSkipSides);
+}
+
+Maybe<nsCSSBorderRenderer>
+nsCSSRendering::CreateBorderRenderer(nsPresContext* aPresContext,
+                                     DrawTarget* aDrawTarget,
+                                     nsIFrame* aForFrame,
+                                     const nsRect& aDirtyRect,
+                                     const nsRect& aBorderArea,
+                                     nsStyleContext* aStyleContext,
+                                     Sides aSkipSides)
+{
+  nsStyleContext *styleIfVisited = aStyleContext->GetStyleIfVisited();
+  const nsStyleBorder *styleBorder = aStyleContext->StyleBorder();
+  // Don't check RelevantLinkVisited here, since we want to take the
+  // same amount of time whether or not it's true.
+  if (!styleIfVisited) {
+    return CreateBorderRendererWithStyleBorder(aPresContext, aDrawTarget,
+                                               aForFrame, aDirtyRect,
+                                               aBorderArea, *styleBorder,
+                                               aStyleContext, aSkipSides);
+  }
+
+  nsStyleBorder newStyleBorder(*styleBorder);
+
+  NS_FOR_CSS_SIDES(side) {
+    nscolor color = aStyleContext->GetVisitedDependentColor(
+      nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_color)[side]);
+    newStyleBorder.mBorderColor[side] = StyleComplexColor::FromColor(color);
+  }
+  return CreateBorderRendererWithStyleBorder(aPresContext, aDrawTarget,
+                                             aForFrame, aDirtyRect, aBorderArea,
+                                             newStyleBorder, aStyleContext,
+                                             aSkipSides);
 }
 
+nsCSSBorderRenderer
+ConstructBorderRenderer(nsPresContext* aPresContext,
+                        nsStyleContext* aStyleContext,
+                        DrawTarget* aDrawTarget,
+                        nsIFrame* aForFrame,
+                        const nsRect& aDirtyRect,
+                        const nsRect& aBorderArea,
+                        const nsStyleBorder& aStyleBorder,
+                        Sides aSkipSides,
+                        bool* aNeedsClip)
+{
+  nsMargin border = aStyleBorder.GetComputedBorder();
+
+  // Get our style context's color struct.
+  const nsStyleColor* ourColor = aStyleContext->StyleColor();
+
+  // In NavQuirks mode we want to use the parent's context as a starting point
+  // for determining the background color.
+  bool quirks = aPresContext->CompatibilityMode() == eCompatibility_NavQuirks;
+  nsIFrame* bgFrame = nsCSSRendering::FindNonTransparentBackgroundFrame(aForFrame, quirks);
+  nsStyleContext* bgContext = bgFrame->StyleContext();
+  nscolor bgColor =
+    bgContext->GetVisitedDependentColor(eCSSProperty_background_color);
+
+  // Compute the outermost boundary of the area that might be painted.
+  // Same coordinate space as aBorderArea & aBGClipRect.
+  nsRect joinedBorderArea =
+    ::BoxDecorationRectForBorder(aForFrame, aBorderArea, aSkipSides, &aStyleBorder);
+  RectCornerRadii bgRadii;
+  ::GetRadii(aForFrame, aStyleBorder, aBorderArea, joinedBorderArea, &bgRadii);
+
+  PrintAsFormatString(" joinedBorderArea: %d %d %d %d\n", joinedBorderArea.x, joinedBorderArea.y,
+     joinedBorderArea.width, joinedBorderArea.height);
+
+  // start drawing
+  if (::IsBoxDecorationSlice(aStyleBorder)) {
+    if (joinedBorderArea.IsEqualEdges(aBorderArea)) {
+      // No need for a clip, just skip the sides we don't want.
+      border.ApplySkipSides(aSkipSides);
+    } else {
+      // We're drawing borders around the joined continuation boxes so we need
+      // to clip that to the slice that we want for this frame.
+      *aNeedsClip = true;
+    }
+  } else {
+    MOZ_ASSERT(joinedBorderArea.IsEqualEdges(aBorderArea),
+               "Should use aBorderArea for box-decoration-break:clone");
+    MOZ_ASSERT(aForFrame->GetSkipSides().IsEmpty() ||
+               IS_TRUE_OVERFLOW_CONTAINER(aForFrame),
+               "Should not skip sides for box-decoration-break:clone except "
+               "::first-letter/line continuations or other frame types that "
+               "don't have borders but those shouldn't reach this point. "
+               "Overflow containers do reach this point though.");
+    border.ApplySkipSides(aSkipSides);
+  }
+
+  // Convert to dev pixels.
+  nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
+  Rect joinedBorderAreaPx = NSRectToRect(joinedBorderArea, twipsPerPixel);
+  Float borderWidths[4] = { Float(border.top / twipsPerPixel),
+                                   Float(border.right / twipsPerPixel),
+                                   Float(border.bottom / twipsPerPixel),
+                                   Float(border.left / twipsPerPixel) };
+  Rect dirtyRect = NSRectToRect(aDirtyRect, twipsPerPixel);
+
+  uint8_t borderStyles[4];
+  nscolor borderColors[4];
+  nsBorderColors* compositeColors[4];
+
+  // pull out styles, colors, composite colors
+  NS_FOR_CSS_SIDES (i) {
+    borderStyles[i] = aStyleBorder.GetBorderStyle(i);
+    borderColors[i] = ourColor->CalcComplexColor(aStyleBorder.mBorderColor[i]);
+    aStyleBorder.GetCompositeColors(i, &compositeColors[i]);
+  }
+
+  PrintAsFormatString(" borderStyles: %d %d %d %d\n", borderStyles[0], borderStyles[1], borderStyles[2], borderStyles[3]);
+
+  nsIDocument* document = nullptr;
+  nsIContent* content = aForFrame->GetContent();
+  if (content) {
+    document = content->OwnerDoc();
+  }
+
+  return nsCSSBorderRenderer(aPresContext,
+                             document,
+                             aDrawTarget,
+                             dirtyRect,
+                             joinedBorderAreaPx,
+                             borderStyles,
+                             borderWidths,
+                             bgRadii,
+                             borderColors,
+                             compositeColors,
+                             bgColor);
+}
+
+
 DrawResult
 nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
                                            nsRenderingContext& aRenderingContext,
                                            nsIFrame* aForFrame,
                                            const nsRect& aDirtyRect,
                                            const nsRect& aBorderArea,
                                            const nsStyleBorder& aStyleBorder,
                                            nsStyleContext* aStyleContext,
@@ -719,129 +847,99 @@ nsCSSRendering::PaintBorderWithStyleBord
 
   // If we had a border-image, but it wasn't loaded, then we should return
   // DrawResult::NOT_READY; we'll want to try again if we do a paint with sync
   // decoding enabled.
   if (aStyleBorder.mBorderImageSource.GetType() != eStyleImageType_Null) {
     result = DrawResult::NOT_READY;
   }
 
-  // Get our style context's color struct.
-  const nsStyleColor* ourColor = aStyleContext->StyleColor();
-
-  // In NavQuirks mode we want to use the parent's context as a starting point
-  // for determining the background color.
-  bool quirks = aPresContext->CompatibilityMode() == eCompatibility_NavQuirks;
-  nsIFrame* bgFrame = FindNonTransparentBackgroundFrame(aForFrame, quirks);
-  nsStyleContext* bgContext = bgFrame->StyleContext();
-  nscolor bgColor =
-    bgContext->GetVisitedDependentColor(eCSSProperty_background_color);
-
   nsMargin border = aStyleBorder.GetComputedBorder();
   if (0 == border.left && 0 == border.right &&
       0 == border.top  && 0 == border.bottom) {
     // Empty border area
     return result;
   }
 
-  // Compute the outermost boundary of the area that might be painted.
-  // Same coordinate space as aBorderArea & aBGClipRect.
-  nsRect joinedBorderArea =
-    ::BoxDecorationRectForBorder(aForFrame, aBorderArea, aSkipSides, &aStyleBorder);
-  RectCornerRadii bgRadii;
-  ::GetRadii(aForFrame, aStyleBorder, aBorderArea, joinedBorderArea, &bgRadii);
-
-  PrintAsFormatString(" joinedBorderArea: %d %d %d %d\n", joinedBorderArea.x, joinedBorderArea.y,
-     joinedBorderArea.width, joinedBorderArea.height);
-
-  // start drawing
-  bool needToPopClip = false;
-
-  if (::IsBoxDecorationSlice(aStyleBorder)) {
-    if (joinedBorderArea.IsEqualEdges(aBorderArea)) {
-      // No need for a clip, just skip the sides we don't want.
-      border.ApplySkipSides(aSkipSides);
-    } else {
-      // We're drawing borders around the joined continuation boxes so we need
-      // to clip that to the slice that we want for this frame.
-      aDrawTarget.PushClipRect(
+  bool needsClip = false;
+  nsCSSBorderRenderer br = ConstructBorderRenderer(aPresContext,
+                                                   aStyleContext,
+                                                   &aDrawTarget,
+                                                   aForFrame,
+                                                   aDirtyRect,
+                                                   aBorderArea,
+                                                   aStyleBorder,
+                                                   aSkipSides,
+                                                   &needsClip);
+
+  if (needsClip) {
+    aDrawTarget.PushClipRect(
         NSRectToSnappedRect(aBorderArea,
                             aForFrame->PresContext()->AppUnitsPerDevPixel(),
                             aDrawTarget));
-      needToPopClip = true;
-    }
-  } else {
-    MOZ_ASSERT(joinedBorderArea.IsEqualEdges(aBorderArea),
-               "Should use aBorderArea for box-decoration-break:clone");
-    MOZ_ASSERT(aForFrame->GetSkipSides().IsEmpty() ||
-               IS_TRUE_OVERFLOW_CONTAINER(aForFrame),
-               "Should not skip sides for box-decoration-break:clone except "
-               "::first-letter/line continuations or other frame types that "
-               "don't have borders but those shouldn't reach this point. "
-               "Overflow containers do reach this point though.");
-    border.ApplySkipSides(aSkipSides);
-  }
-
-  // Convert to dev pixels.
-  nscoord twipsPerPixel = aPresContext->DevPixelsToAppUnits(1);
-  Rect joinedBorderAreaPx = NSRectToRect(joinedBorderArea, twipsPerPixel);
-  Float borderWidths[4] = { Float(border.top / twipsPerPixel),
-                            Float(border.right / twipsPerPixel),
-                            Float(border.bottom / twipsPerPixel),
-                            Float(border.left / twipsPerPixel) };
-  Rect dirtyRect = NSRectToRect(aDirtyRect, twipsPerPixel);
-
-  uint8_t borderStyles[4];
-  nscolor borderColors[4];
-  nsBorderColors *compositeColors[4];
-
-  // pull out styles, colors, composite colors
-  NS_FOR_CSS_SIDES (i) {
-    borderStyles[i] = aStyleBorder.GetBorderStyle(i);
-    borderColors[i] = ourColor->CalcComplexColor(aStyleBorder.mBorderColor[i]);
-    aStyleBorder.GetCompositeColors(i, &compositeColors[i]);
-  }
-
-  PrintAsFormatString(" borderStyles: %d %d %d %d\n", borderStyles[0], borderStyles[1], borderStyles[2], borderStyles[3]);
-  //PrintAsFormatString ("bgRadii: %f %f %f %f\n", bgRadii[0], bgRadii[1], bgRadii[2], bgRadii[3]);
-
-#if 0
-  // this will draw a transparent red backround underneath the border area
-  ColorPattern color(ToDeviceColor(Color(1.f, 0.f, 0.f, 0.5f)));
-  aDrawTarget.FillRect(joinedBorderAreaPx, color);
-#endif
-
-  nsIDocument* document = nullptr;
-  nsIContent* content = aForFrame->GetContent();
-  if (content) {
-    document = content->OwnerDoc();
-  }
-
-  nsCSSBorderRenderer br(aPresContext,
-                         document,
-                         &aDrawTarget,
-                         dirtyRect,
-                         joinedBorderAreaPx,
-                         borderStyles,
-                         borderWidths,
-                         bgRadii,
-                         borderColors,
-                         compositeColors,
-                         bgColor);
+  }
+
   br.DrawBorders();
 
-  if (needToPopClip) {
+  if (needsClip) {
     aDrawTarget.PopClip();
   }
 
   PrintAsStringNewline();
 
   return result;
 }
 
+Maybe<nsCSSBorderRenderer>
+nsCSSRendering::CreateBorderRendererWithStyleBorder(nsPresContext* aPresContext,
+                                                    DrawTarget* aDrawTarget,
+                                                    nsIFrame* aForFrame,
+                                                    const nsRect& aDirtyRect,
+                                                    const nsRect& aBorderArea,
+                                                    const nsStyleBorder& aStyleBorder,
+                                                    nsStyleContext* aStyleContext,
+                                                    Sides aSkipSides)
+{
+  const nsStyleDisplay* displayData = aStyleContext->StyleDisplay();
+  if (displayData->mAppearance) {
+    nsITheme *theme = aPresContext->GetTheme();
+    if (theme &&
+        theme->ThemeSupportsWidget(aPresContext, aForFrame,
+                                   displayData->mAppearance)) {
+      return Nothing();
+    }
+  }
+
+  if (aStyleBorder.mBorderImageSource.GetType() != eStyleImageType_Null) {
+    return Nothing();
+  }
+
+  nsMargin border = aStyleBorder.GetComputedBorder();
+  if (0 == border.left && 0 == border.right &&
+      0 == border.top  && 0 == border.bottom) {
+    // Empty border area
+    return Nothing();
+  }
+
+  bool needsClip = false;
+  nsCSSBorderRenderer br = ConstructBorderRenderer(aPresContext,
+                                                   aStyleContext,
+                                                   aDrawTarget,
+                                                   aForFrame,
+                                                   aDirtyRect,
+                                                   aBorderArea,
+                                                   aStyleBorder,
+                                                   aSkipSides,
+                                                   &needsClip);
+  if (needsClip) {
+    return Nothing();
+  }
+  return Some(br);
+}
+
 static nsRect
 GetOutlineInnerRect(nsIFrame* aFrame)
 {
   nsRect* savedOutlineInnerRect =
     aFrame->Properties().Get(nsIFrame::OutlineInnerRectProperty());
   if (savedOutlineInnerRect)
     return *savedOutlineInnerRect;
   NS_NOTREACHED("we should have saved a frame property");
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -12,16 +12,17 @@
 #include "gfxContext.h"
 #include "imgIContainer.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/TypedEnumBits.h"
 #include "nsLayoutUtils.h"
 #include "nsStyleStruct.h"
 #include "nsIFrame.h"
+#include "nsCSSRenderingBorders.h"
 
 class gfxDrawable;
 class nsStyleContext;
 class nsPresContext;
 class nsRenderingContext;
 
 namespace mozilla {
 
@@ -411,16 +412,35 @@ struct nsCSSRendering {
                                                nsIFrame* aForFrame,
                                                const nsRect& aDirtyRect,
                                                const nsRect& aBorderArea,
                                                const nsStyleBorder& aBorderStyle,
                                                nsStyleContext* aStyleContext,
                                                mozilla::PaintBorderFlags aFlags,
                                                Sides aSkipSides = Sides());
 
+  static mozilla::Maybe<nsCSSBorderRenderer>
+  CreateBorderRenderer(nsPresContext* aPresContext,
+                       DrawTarget* aDrawTarget,
+                       nsIFrame* aForFrame,
+                       const nsRect& aDirtyRect,
+                       const nsRect& aBorderArea,
+                       nsStyleContext* aStyleContext,
+                       Sides aSkipSides = Sides());
+
+  static mozilla::Maybe<nsCSSBorderRenderer>
+  CreateBorderRendererWithStyleBorder(nsPresContext* aPresContext,
+                                      DrawTarget* aDrawTarget,
+                                      nsIFrame* aForFrame,
+                                      const nsRect& aDirtyRect,
+                                      const nsRect& aBorderArea,
+                                      const nsStyleBorder& aBorderStyle,
+                                      nsStyleContext* aStyleContext,
+                                      Sides aSkipSides = Sides());
+
 
   /**
    * Render the outline for an element using css rendering rules
    * for borders.
    */
   static void PaintOutline(nsPresContext* aPresContext,
                           nsRenderingContext& aRenderingContext,
                           nsIFrame* aForFrame,
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -101,18 +101,18 @@ CheckFourFloatsEqual(const Float *vals, 
           vals[3] == k);
 }
 
 static bool
 IsZeroSize(const Size& sz) {
   return sz.width == 0.0 || sz.height == 0.0;
 }
 
-static bool
-AllCornersZeroSize(const RectCornerRadii& corners) {
+/* static */ bool
+nsCSSBorderRenderer::AllCornersZeroSize(const RectCornerRadii& corners) {
   return IsZeroSize(corners[NS_CORNER_TOP_LEFT]) &&
     IsZeroSize(corners[NS_CORNER_TOP_RIGHT]) &&
     IsZeroSize(corners[NS_CORNER_BOTTOM_RIGHT]) &&
     IsZeroSize(corners[NS_CORNER_BOTTOM_LEFT]);
 }
 
 static mozilla::css::Side
 GetHorizontalSide(mozilla::css::Corner aCorner)
@@ -177,26 +177,27 @@ nsCSSBorderRenderer::nsCSSBorderRenderer
                                          const nscolor* aBorderColors,
                                          nsBorderColors* const* aCompositeColors,
                                          nscolor aBackgroundColor)
   : mPresContext(aPresContext),
     mDocument(aDocument),
     mDrawTarget(aDrawTarget),
     mDirtyRect(aDirtyRect),
     mOuterRect(aOuterRect),
-    mBorderStyles(aBorderStyles),
-    mBorderWidths(aBorderWidths),
     mBorderRadii(aBorderRadii),
-    mBorderColors(aBorderColors),
-    mCompositeColors(aCompositeColors),
     mBackgroundColor(aBackgroundColor)
 {
-  if (!mCompositeColors) {
+  PodCopy(mBorderStyles, aBorderStyles, 4);
+  PodCopy(mBorderWidths, aBorderWidths, 4);
+  PodCopy(mBorderColors, aBorderColors, 4);
+  if (aCompositeColors) {
+    PodCopy(mCompositeColors, aCompositeColors, 4);
+  } else {
     static nsBorderColors * const noColors[4] = { nullptr };
-    mCompositeColors = &noColors[0];
+    PodCopy(mCompositeColors, noColors, 4);
   }
 
   mInnerRect = mOuterRect;
   mInnerRect.Deflate(
       Margin(mBorderStyles[0] != NS_STYLE_BORDER_STYLE_NONE ? mBorderWidths[0] : 0,
              mBorderStyles[1] != NS_STYLE_BORDER_STYLE_NONE ? mBorderWidths[1] : 0,
              mBorderStyles[2] != NS_STYLE_BORDER_STYLE_NONE ? mBorderWidths[2] : 0,
              mBorderStyles[3] != NS_STYLE_BORDER_STYLE_NONE ? mBorderWidths[3] : 0));
@@ -266,17 +267,17 @@ ComputeBorderCornerDimensions(const Floa
                               const RectCornerRadii& aRadii,
                               RectCornerRadii* aDimsRet)
 {
   Float leftWidth = aBorderWidths[NS_SIDE_LEFT];
   Float topWidth = aBorderWidths[NS_SIDE_TOP];
   Float rightWidth = aBorderWidths[NS_SIDE_RIGHT];
   Float bottomWidth = aBorderWidths[NS_SIDE_BOTTOM];
 
-  if (AllCornersZeroSize(aRadii)) {
+  if (nsCSSBorderRenderer::AllCornersZeroSize(aRadii)) {
     // These will always be in pixel units from CSS
     (*aDimsRet)[C_TL] = Size(leftWidth, topWidth);
     (*aDimsRet)[C_TR] = Size(rightWidth, topWidth);
     (*aDimsRet)[C_BR] = Size(rightWidth, bottomWidth);
     (*aDimsRet)[C_BL] = Size(leftWidth, bottomWidth);
   } else {
     // Always round up to whole pixels for the corners; it's safe to
     // make the corners bigger than necessary, and this way we ensure
--- a/layout/painting/nsCSSRenderingBorders.h
+++ b/layout/painting/nsCSSRenderingBorders.h
@@ -11,19 +11,21 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/BezierUtils.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/RefPtr.h"
 #include "nsColor.h"
 #include "nsCOMPtr.h"
 #include "nsStyleConsts.h"
+#include "nsStyleStruct.h"
 #include "nsPresContext.h"
 
 struct nsBorderColors;
+class nsDisplayBorder;
 
 namespace mozilla {
 namespace gfx {
 class GradientStops;
 } // namespace gfx
 } // namespace mozilla
 
 // define this to enable a bunch of debug dump info
@@ -70,16 +72,18 @@ class nsCSSBorderRenderer final
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::Float Float;
   typedef mozilla::gfx::Path Path;
   typedef mozilla::gfx::Point Point;
   typedef mozilla::gfx::Rect Rect;
   typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
   typedef mozilla::gfx::StrokeOptions StrokeOptions;
 
+  friend class nsDisplayBorder;
+
 public:
 
   nsCSSBorderRenderer(nsPresContext* aPresContext,
                       const nsIDocument* aDocument,
                       DrawTarget* aDrawTarget,
                       const Rect& aDirtyRect,
                       Rect& aOuterRect,
                       const uint8_t* aBorderStyles,
@@ -100,40 +104,42 @@ public:
   // Given aRadii as the border radii for a rectangle, compute the
   // appropriate radii for another rectangle *outside* that rectangle
   // by increasing the radii, except keeping sharp corners sharp.
   // Used for spread box-shadows
   static void ComputeOuterRadii(const RectCornerRadii& aRadii,
                                 const Float* aBorderSizes,
                                 RectCornerRadii* aOuterRadiiRet);
 
+  static bool AllCornersZeroSize(const RectCornerRadii& corners);
+
 private:
 
   RectCornerRadii mBorderCornerDimensions;
 
   // Target document to report warning
   nsPresContext* mPresContext;
   const nsIDocument* mDocument;
 
   // destination DrawTarget and dirty rect
   DrawTarget* mDrawTarget;
-  const Rect& mDirtyRect;
+  const Rect mDirtyRect;
 
   // the rectangle of the outside and the inside of the border
   Rect mOuterRect;
   Rect mInnerRect;
 
   // the style and size of the border
-  const uint8_t* mBorderStyles;
-  const Float* mBorderWidths;
+  uint8_t mBorderStyles[4];
+  Float mBorderWidths[4];
   RectCornerRadii mBorderRadii;
 
   // colors
-  const nscolor* mBorderColors;
-  nsBorderColors* const* mCompositeColors;
+  nscolor mBorderColors[4];
+  nsBorderColors* mCompositeColors[4];
 
   // the background color
   nscolor mBackgroundColor;
 
   // calculated values
   bool mOneUnitBorder;
   bool mNoBorderRadius;
   bool mAvoidStroke;