diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 0dc431ae6b5..e3fd99f9db7 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -1577,7 +1577,15 @@ GetBackgroundClip(gfxContext *aCtx, PRUint8 aBackgroundClip, aClipState->mClippedRadii = aBGRadii; if (aBackgroundClip != NS_STYLE_BG_CLIP_BORDER) { nsMargin border = aForFrame->GetUsedBorder(); - if (aBackgroundClip != NS_STYLE_BG_CLIP_PADDING) { + if (aBackgroundClip == NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING) { + // Reduce |border| by 1px (device pixels) on all sides, if + // possible, so that we don't get antialiasing seams between the + // background and border. + border.top = NS_MAX(0, border.top - aAppUnitsPerPixel); + border.right = NS_MAX(0, border.right - aAppUnitsPerPixel); + border.bottom = NS_MAX(0, border.bottom - aAppUnitsPerPixel); + border.left = NS_MAX(0, border.left - aAppUnitsPerPixel); + } else if (aBackgroundClip != NS_STYLE_BG_CLIP_PADDING) { NS_ASSERTION(aBackgroundClip == NS_STYLE_BG_CLIP_CONTENT, "unexpected background-clip"); border += aForFrame->GetUsedPadding(); @@ -2381,8 +2389,13 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, currentBackgroundClip = bg->BottomLayer().mClip; isSolidBorder = (aFlags & PAINTBG_WILL_PAINT_BORDER) && IsOpaqueBorder(aBorder); - if (isSolidBorder && currentBackgroundClip == NS_STYLE_BG_CLIP_BORDER) - currentBackgroundClip = NS_STYLE_BG_CLIP_PADDING; + 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; + } GetBackgroundClip(ctx, currentBackgroundClip, aForFrame, aBorderArea, aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel, @@ -2428,8 +2441,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, const nsStyleBackground::Layer &layer = bg->mLayers[i]; if (!aBGClipRect) { PRUint8 newBackgroundClip = layer.mClip; - if (isSolidBorder && newBackgroundClip == NS_STYLE_BG_CLIP_BORDER) - newBackgroundClip = NS_STYLE_BG_CLIP_PADDING; + if (isSolidBorder && newBackgroundClip == NS_STYLE_BG_CLIP_BORDER) { + newBackgroundClip = haveRoundedCorners ? + 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 diff --git a/layout/base/nsStyleConsts.h b/layout/base/nsStyleConsts.h index 7b0cec3c219..9addf7f458e 100644 --- a/layout/base/nsStyleConsts.h +++ b/layout/base/nsStyleConsts.h @@ -273,6 +273,12 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_BG_CLIP_BORDER 0 #define NS_STYLE_BG_CLIP_PADDING 1 #define NS_STYLE_BG_CLIP_CONTENT 2 +// A magic value that we use for our "pretend that background-clip is +// 'padding' when we have a solid border" optimization. This isn't +// actually equal to NS_STYLE_BG_CLIP_PADDING because using that +// causes antialiasing seams between the background and border. This +// is a backend-only value. +#define NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING 127 // See nsStyleBackground #define NS_STYLE_BG_INLINE_POLICY_EACH_BOX 0 diff --git a/layout/reftests/border-radius/curved-border-background-nogap-ref.html b/layout/reftests/border-radius/curved-border-background-nogap-ref.html new file mode 100644 index 00000000000..67aead2bcab --- /dev/null +++ b/layout/reftests/border-radius/curved-border-background-nogap-ref.html @@ -0,0 +1,9 @@ + + +
diff --git a/layout/reftests/border-radius/curved-border-background-nogap.html b/layout/reftests/border-radius/curved-border-background-nogap.html new file mode 100644 index 00000000000..01207e7f044 --- /dev/null +++ b/layout/reftests/border-radius/curved-border-background-nogap.html @@ -0,0 +1,36 @@ + + +
diff --git a/layout/reftests/border-radius/reftest.list b/layout/reftests/border-radius/reftest.list index 2a244d4e0d3..656eb46cca0 100644 --- a/layout/reftests/border-radius/reftest.list +++ b/layout/reftests/border-radius/reftest.list @@ -79,3 +79,6 @@ random-if(winWidget) HTTP(..) == corner-joins-2.xhtml corner-joins-2-ref.xhtml == zero-radius-clip-1.html zero-radius-clip-ref.html == iframe-1.html iframe-1-ref.html + +# Test for antialiasing gaps between background and border +fails-if(winWidget) == curved-border-background-nogap.html curved-border-background-nogap-ref.html diff --git a/layout/reftests/box-shadow/boxshadow-mixed-ref.html b/layout/reftests/box-shadow/boxshadow-mixed-ref.html index 542872343c4..3c71b12e200 100644 --- a/layout/reftests/box-shadow/boxshadow-mixed-ref.html +++ b/layout/reftests/box-shadow/boxshadow-mixed-ref.html @@ -1 +1 @@ -
inset and outset
 
+
inset and outset