зеркало из https://github.com/mozilla/gecko-dev.git
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
This commit is contained in:
Родитель
2fc65c65af
Коммит
50c5f916d0
|
@ -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<nsIFrame*> *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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head><style>
|
||||
button,span,fieldset { border-radius: 7px 3px; background-color: #0F0; }
|
||||
button { border: none; outline: 3px solid black; -moz-outline-radius: 7px 3px; outline-offset: -2px; }
|
||||
</style></head>
|
||||
<body style="margin:30px">
|
||||
<div style="-moz-column-count:3">
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html>
|
||||
<head><style>
|
||||
button,span,fieldset { border-radius: 7px 3px; background-color: #0F0; }
|
||||
button { border: none; outline: 3px solid black; -moz-outline-radius: 7px 3px; outline-offset: -2px; }
|
||||
</style></head>
|
||||
<body style="margin:30px">
|
||||
<div style="-moz-column-count:3">
|
||||
|
|
Загрузка…
Ссылка в новой задаче