From 50c5f916d0162fade769b71098b42e39c4df27e2 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Fri, 29 Apr 2016 13:16:23 -0400 Subject: [PATCH] Bug 1227327 - Use regular background image display items for painting button backgrounds. r=mattwoodrow This has multiple benefits: - It makes DLBI detection of background-position changes work for buttons. - It makes background-attachment: fixed work for button backgrounds. - It allows the willPaintBorder optimization to be used for button background drawing, which reduces the background clip to not overlap with opaque borders. The willPaintBorder optimization requires a change to the reftest 611574-2.html. This reftest compares backgrounds to inset box shadows. Box shadows those don't have a willPaintBorder optimization, so we'd get different results due to the borders - inset box shadows will bleed through the rounded corner anti-aliasing of the border, backgrounds won't any more. So we just turn off button borders and cover the outer edges of the borders with an outline in that reftest. MozReview-Commit-ID: Lvx2p5szjw7 *** Cover the antialiasing in 611574-2.html with a black outline. MozReview-Commit-ID: IHC3B7Eq72j --HG-- extra : rebase_source : e2c625e25ebce052948dc39de6f9af91d4987315 --- layout/forms/nsButtonFrameRenderer.cpp | 47 +++++++++----------- layout/forms/nsButtonFrameRenderer.h | 10 ++--- layout/reftests/box-shadow/611574-2-ref.html | 1 + layout/reftests/box-shadow/611574-2.html | 1 + 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/layout/forms/nsButtonFrameRenderer.cpp b/layout/forms/nsButtonFrameRenderer.cpp index 35b3042ef99d..8769b2b0fe9d 100644 --- a/layout/forms/nsButtonFrameRenderer.cpp +++ b/layout/forms/nsButtonFrameRenderer.cpp @@ -112,19 +112,18 @@ nsDisplayButtonBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder, buttonRect, mVisibleRect); } -class nsDisplayButtonBorderBackground : public nsDisplayItem { +class nsDisplayButtonBorder : public nsDisplayItem { public: - nsDisplayButtonBorderBackground(nsDisplayListBuilder* aBuilder, + nsDisplayButtonBorder(nsDisplayListBuilder* aBuilder, nsButtonFrameRenderer* aRenderer) : nsDisplayItem(aBuilder, aRenderer->GetFrame()), mBFR(aRenderer) { - MOZ_COUNT_CTOR(nsDisplayButtonBorderBackground); + MOZ_COUNT_CTOR(nsDisplayButtonBorder); } #ifdef NS_BUILD_REFCNT_LOGGING - virtual ~nsDisplayButtonBorderBackground() { - MOZ_COUNT_DTOR(nsDisplayButtonBorderBackground); + virtual ~nsDisplayButtonBorder() { + MOZ_COUNT_DTOR(nsDisplayButtonBorder); } -#endif - +#endif virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray *aOutFrames) override { @@ -144,13 +143,13 @@ private: }; nsDisplayItemGeometry* -nsDisplayButtonBorderBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder) +nsDisplayButtonBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder) { return new nsDisplayItemGenericImageGeometry(this, aBuilder); } void -nsDisplayButtonBorderBackground::ComputeInvalidationRegion( +nsDisplayButtonBorder::ComputeInvalidationRegion( nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion *aInvalidRegion) @@ -167,22 +166,22 @@ nsDisplayButtonBorderBackground::ComputeInvalidationRegion( nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); } -void nsDisplayButtonBorderBackground::Paint(nsDisplayListBuilder* aBuilder, - nsRenderingContext* aCtx) +void nsDisplayButtonBorder::Paint(nsDisplayListBuilder* aBuilder, + nsRenderingContext* aCtx) { NS_ASSERTION(mFrame, "No frame?"); nsPresContext* pc = mFrame->PresContext(); nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize()); - + // draw the border and background inside the focus and outline borders DrawResult result = - mBFR->PaintBorderAndBackground(aBuilder, pc, *aCtx, mVisibleRect, r); + mBFR->PaintBorder(aBuilder, pc, *aCtx, mVisibleRect, r); nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); } nsRect -nsDisplayButtonBorderBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { +nsDisplayButtonBorder::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) { *aSnap = false; return aBuilder->IsForEventDelivery() ? nsRect(ToReferenceFrame(), mFrame->GetSize()) : mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame(); @@ -264,10 +263,14 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder, nsDisplayButtonBoxShadowOuter(aBuilder, this)); } - // Almost all buttons draw some kind of background so there's not much - // point in checking whether we should create this item. + nsRect buttonRect; + GetButtonRect(mFrame->GetRectRelativeToSelf(), buttonRect); + + nsDisplayBackgroundImage::AppendBackgroundItemsToTop( + aBuilder, mFrame, buttonRect, aBackground); + aBackground->AppendNewToTop(new (aBuilder) - nsDisplayButtonBorderBackground(aBuilder, this)); + nsDisplayButtonBorder(aBuilder, this)); // Only display focus rings if we actually have them. Since at most one // button would normally display a focus ring, most buttons won't have them. @@ -325,9 +328,8 @@ nsButtonFrameRenderer::PaintOutlineAndFocusBorders( return result; } - DrawResult -nsButtonFrameRenderer::PaintBorderAndBackground( +nsButtonFrameRenderer::PaintBorder( nsDisplayListBuilder* aBuilder, nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, @@ -340,19 +342,14 @@ nsButtonFrameRenderer::PaintBorderAndBackground( nsStyleContext* context = mFrame->StyleContext(); - uint32_t bgFlags = aBuilder->GetBackgroundPaintFlags(); PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages() ? PaintBorderFlags::SYNC_DECODE_IMAGES : PaintBorderFlags(); - DrawResult result = - nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, mFrame, - aDirtyRect, buttonRect, bgFlags); - nsCSSRendering::PaintBoxShadowInner(aPresContext, aRenderingContext, mFrame, buttonRect); - result &= + DrawResult result = nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame, aDirtyRect, buttonRect, context, borderFlags); diff --git a/layout/forms/nsButtonFrameRenderer.h b/layout/forms/nsButtonFrameRenderer.h index 1877a72965d7..ca536c47884c 100644 --- a/layout/forms/nsButtonFrameRenderer.h +++ b/layout/forms/nsButtonFrameRenderer.h @@ -45,11 +45,11 @@ public: const nsRect& aDirtyRect, const nsRect& aRect); - DrawResult PaintBorderAndBackground(nsDisplayListBuilder* aBuilder, - nsPresContext* aPresContext, - nsRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - const nsRect& aRect); + DrawResult PaintBorder(nsDisplayListBuilder* aBuilder, + nsPresContext* aPresContext, + nsRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + const nsRect& aRect); void SetFrame(nsFrame* aFrame, nsPresContext* aPresContext); diff --git a/layout/reftests/box-shadow/611574-2-ref.html b/layout/reftests/box-shadow/611574-2-ref.html index 9d1c2357d660..04004002426d 100644 --- a/layout/reftests/box-shadow/611574-2-ref.html +++ b/layout/reftests/box-shadow/611574-2-ref.html @@ -2,6 +2,7 @@
diff --git a/layout/reftests/box-shadow/611574-2.html b/layout/reftests/box-shadow/611574-2.html index 9469d1f36bba..1d37d61c9cc0 100644 --- a/layout/reftests/box-shadow/611574-2.html +++ b/layout/reftests/box-shadow/611574-2.html @@ -2,6 +2,7 @@