Bug 1227327 - Use regular background drawing for XUL groupbox frames. r?mattwoodrow draft
authorMarkus Stange <mstange@themasta.com>
Wed, 27 Apr 2016 17:45:21 -0400
changeset 363449 fa90206832ae7172c91bc1d5bbbf0d9469d68b4b
parent 363448 1c74c506186fbbcc1ea5006eb8bdc7f8b5e3dc20
child 363450 716be65eedcae9f80f1b227de91bd236b3fb53d9
push id17204
push usermstange@themasta.com
push dateWed, 04 May 2016 18:19:56 +0000
reviewersmattwoodrow
bugs1227327
milestone49.0a1
Bug 1227327 - Use regular background drawing for XUL groupbox frames. r?mattwoodrow MozReview-Commit-ID: 7S1gdZJgBCS
layout/xul/nsGroupBoxFrame.cpp
--- a/layout/xul/nsGroupBoxFrame.cpp
+++ b/layout/xul/nsGroupBoxFrame.cpp
@@ -34,19 +34,20 @@ public:
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override {
     return MakeFrameName(NS_LITERAL_STRING("GroupBoxFrame"), aResult);
   }
 #endif
 
   virtual bool HonorPrintBackgroundSettings() override { return false; }
 
-  DrawResult PaintBorderBackground(nsRenderingContext& aRenderingContext,
+  DrawResult PaintBorder(nsRenderingContext& aRenderingContext,
                                    nsPoint aPt,
                                    const nsRect& aDirtyRect);
+  nsRect GetBackgroundRectRelativeToSelf(nscoord* aOutYOffset = nullptr, nsRect* aOutGroupRect = nullptr);
 
   // make sure we our kids get our orient and align instead of us.
   // our child box has no content node so it will search for a parent with one.
   // that will be us.
   virtual void GetInitialOrientation(bool& aHorizontal) override { aHorizontal = false; }
   virtual bool GetInitialHAlignment(Halignment& aHalign) override { aHalign = hAlign_Left; return true; } 
   virtual bool GetInitialVAlignment(Valignment& aValign) override { aValign = vAlign_Top; return true; } 
   virtual bool GetInitialAutoStretch(bool& aStretch) override { aStretch = true; return true; } 
@@ -77,26 +78,26 @@ public:
 nsIFrame*
 NS_NewGroupBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsGroupBoxFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsGroupBoxFrame)
 
-class nsDisplayXULGroupBackground : public nsDisplayItem {
+class nsDisplayXULGroupBorder : public nsDisplayItem {
 public:
-  nsDisplayXULGroupBackground(nsDisplayListBuilder* aBuilder,
+  nsDisplayXULGroupBorder(nsDisplayListBuilder* aBuilder,
                               nsGroupBoxFrame* aFrame) :
     nsDisplayItem(aBuilder, aFrame) {
-    MOZ_COUNT_CTOR(nsDisplayXULGroupBackground);
+    MOZ_COUNT_CTOR(nsDisplayXULGroupBorder);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
-  virtual ~nsDisplayXULGroupBackground() {
-    MOZ_COUNT_DTOR(nsDisplayXULGroupBackground);
+  virtual ~nsDisplayXULGroupBorder() {
+    MOZ_COUNT_DTOR(nsDisplayXULGroupBorder);
   }
 #endif
 
   nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
   void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                  const nsDisplayItemGeometry* aGeometry,
                                  nsRegion *aInvalidRegion) override;
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
@@ -104,23 +105,23 @@ public:
     aOutFrames->AppendElement(mFrame);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx) override;
   NS_DISPLAY_DECL_NAME("XULGroupBackground", TYPE_XUL_GROUP_BACKGROUND)
 };
 
 nsDisplayItemGeometry*
-nsDisplayXULGroupBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
+nsDisplayXULGroupBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder)
 {
   return new nsDisplayItemGenericImageGeometry(this, aBuilder);
 }
 
 void
-nsDisplayXULGroupBackground::ComputeInvalidationRegion(
+nsDisplayXULGroupBorder::ComputeInvalidationRegion(
   nsDisplayListBuilder* aBuilder,
   const nsDisplayItemGeometry* aGeometry,
   nsRegion* aInvalidRegion)
 {
   auto geometry =
     static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
 
   if (aBuilder->ShouldSyncDecodeImages() &&
@@ -128,77 +129,95 @@ nsDisplayXULGroupBackground::ComputeInva
     bool snap;
     aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
   }
 
   nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
 }
 
 void
-nsDisplayXULGroupBackground::Paint(nsDisplayListBuilder* aBuilder,
+nsDisplayXULGroupBorder::Paint(nsDisplayListBuilder* aBuilder,
                                    nsRenderingContext* aCtx)
 {
   DrawResult result = static_cast<nsGroupBoxFrame*>(mFrame)
-    ->PaintBorderBackground(*aCtx, ToReferenceFrame(), mVisibleRect);
+    ->PaintBorder(*aCtx, ToReferenceFrame(), mVisibleRect);
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
 void
 nsGroupBoxFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                   const nsRect&           aDirtyRect,
                                   const nsDisplayListSet& aLists)
 {
   // Paint our background and border
   if (IsVisibleForPainting(aBuilder)) {
+    nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
+      aBuilder, this, GetBackgroundRectRelativeToSelf(),
+      aLists.BorderBackground());
     aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
-      nsDisplayXULGroupBackground(aBuilder, this));
+      nsDisplayXULGroupBorder(aBuilder, this));
     
     DisplayOutline(aBuilder, aLists);
   }
 
   BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
 }
 
+nsRect
+nsGroupBoxFrame::GetBackgroundRectRelativeToSelf(nscoord* aOutYOffset, nsRect* aOutGroupRect)
+{
+  const nsMargin& border = StyleBorder()->GetComputedBorder();
+
+  nsRect groupRect;
+  nsIFrame* groupBox = GetCaptionBox(groupRect);
+
+  nscoord yoff = 0;
+  if (groupBox) {
+    // If the border is smaller than the legend, move the border down
+    // to be centered on the legend.
+    nsMargin groupMargin;
+    groupBox->StyleMargin()->GetMargin(groupMargin);
+    groupRect.Inflate(groupMargin);
+
+    if (border.top < groupRect.height) {
+      yoff = (groupRect.height - border.top) / 2 + groupRect.y;
+    }
+  }
+
+  if (aOutYOffset) {
+    *aOutYOffset = yoff;
+  }
+  if (aOutGroupRect) {
+    *aOutGroupRect = groupRect;
+  }
+
+  return nsRect(0, yoff, mRect.width, mRect.height - yoff);
+}
+
 DrawResult
-nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
+nsGroupBoxFrame::PaintBorder(nsRenderingContext& aRenderingContext,
     nsPoint aPt, const nsRect& aDirtyRect) {
 
   DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
   gfxContext* gfx = aRenderingContext.ThebesContext();
 
   Sides skipSides;
   const nsStyleBorder* borderStyleData = StyleBorder();
   const nsMargin& border = borderStyleData->GetComputedBorder();
-  nscoord yoff = 0;
   nsPresContext* presContext = PresContext();
 
   nsRect groupRect;
   nsIFrame* groupBox = GetCaptionBox(groupRect);
 
-  if (groupBox) {        
-    // if the border is smaller than the legend. Move the border down
-    // to be centered on the legend. 
-    nsMargin groupMargin;
-    groupBox->StyleMargin()->GetMargin(groupMargin);
-    groupRect.Inflate(groupMargin);
- 
-    if (border.top < groupRect.height)
-        yoff = (groupRect.height - border.top)/2 + groupRect.y;
-  }
-
-  nsRect rect(aPt.x, aPt.y + yoff, mRect.width, mRect.height - yoff);
-
+  nscoord yoff = 0;
+  nsRect rect = GetBackgroundRectRelativeToSelf(&yoff, &groupRect) + aPt;
   groupRect += aPt;
 
-  DrawResult result =
-    nsCSSRendering::PaintBackground(presContext, aRenderingContext, this,
-                                    aDirtyRect, rect,
-                                    nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES);
-
+  DrawResult result = DrawResult::SUCCESS;
   if (groupBox) {
     int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
 
     // we should probably use PaintBorderEdges to do this but for now just use clipping
     // to achieve the same effect.
 
     // draw left side
     nsRect clipRect(rect);