Bug 742736 - Change box shadows to match rounded or sharp corners of shadowed object when round/sharp alternate corners; r=dbaron

This commit is contained in:
Thomas Powell 2012-04-29 22:37:04 -04:00
parent 40e869505f
commit c9dde4a2f2
8 changed files with 59 additions and 21 deletions

View File

@ -1247,30 +1247,16 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
shadowContext->NewPath();
if (hasBorderRadius) {
gfxCornerSizes clipRectRadii;
gfxFloat spreadDistance = -shadowItem->mSpread / twipsPerPixel;
gfxFloat borderSizes[4] = { 0, 0, 0, 0 };
gfxFloat spreadDistance = shadowItem->mSpread / twipsPerPixel;
// We only give the spread radius to corners with a radius on them, otherwise we'll
// give a rounded shadow corner to a frame corner with 0 border radius, should
// the author use non-uniform border radii sizes (border-top-left-radius etc)
// (bug 514670)
if (borderRadii[C_TL].width > 0 || borderRadii[C_BL].width > 0) {
borderSizes[NS_SIDE_LEFT] = spreadDistance;
}
gfxFloat borderSizes[4];
if (borderRadii[C_TL].height > 0 || borderRadii[C_TR].height > 0) {
borderSizes[NS_SIDE_TOP] = spreadDistance;
}
borderSizes[NS_SIDE_LEFT] = spreadDistance;
borderSizes[NS_SIDE_TOP] = spreadDistance;
borderSizes[NS_SIDE_RIGHT] = spreadDistance;
borderSizes[NS_SIDE_BOTTOM] = spreadDistance;
if (borderRadii[C_TR].width > 0 || borderRadii[C_BR].width > 0) {
borderSizes[NS_SIDE_RIGHT] = spreadDistance;
}
if (borderRadii[C_BL].height > 0 || borderRadii[C_BR].height > 0) {
borderSizes[NS_SIDE_BOTTOM] = spreadDistance;
}
nsCSSBorderRenderer::ComputeInnerRadii(borderRadii, borderSizes,
nsCSSBorderRenderer::ComputeOuterRadii(borderRadii, borderSizes,
&clipRectRadii);
shadowContext->RoundedRectangle(shadowGfxRect, clipRectRadii);
} else {

View File

@ -221,6 +221,38 @@ nsCSSBorderRenderer::ComputeInnerRadii(const gfxCornerSizes& aRadii,
iRadii[C_BL].height = NS_MAX(0.0, aRadii[C_BL].height - aBorderSizes[NS_SIDE_BOTTOM]);
}
/* static */ void
nsCSSBorderRenderer::ComputeOuterRadii(const gfxCornerSizes& aRadii,
const gfxFloat *aBorderSizes,
gfxCornerSizes *aOuterRadiiRet)
{
gfxCornerSizes& oRadii = *aOuterRadiiRet;
// default all corners to sharp corners
oRadii = gfxCornerSizes(0.0);
// round the edges that have radii > 0.0 to start with
if (aRadii[C_TL].width > 0.0 && aRadii[C_TL].height > 0.0) {
oRadii[C_TL].width = NS_MAX(0.0, aRadii[C_TL].width + aBorderSizes[NS_SIDE_LEFT]);
oRadii[C_TL].height = NS_MAX(0.0, aRadii[C_TL].height + aBorderSizes[NS_SIDE_TOP]);
}
if (aRadii[C_TR].width > 0.0 && aRadii[C_TR].height > 0.0) {
oRadii[C_TR].width = NS_MAX(0.0, aRadii[C_TR].width + aBorderSizes[NS_SIDE_RIGHT]);
oRadii[C_TR].height = NS_MAX(0.0, aRadii[C_TR].height + aBorderSizes[NS_SIDE_TOP]);
}
if (aRadii[C_BR].width > 0.0 && aRadii[C_BR].height > 0.0) {
oRadii[C_BR].width = NS_MAX(0.0, aRadii[C_BR].width + aBorderSizes[NS_SIDE_RIGHT]);
oRadii[C_BR].height = NS_MAX(0.0, aRadii[C_BR].height + aBorderSizes[NS_SIDE_BOTTOM]);
}
if (aRadii[C_BL].width > 0.0 && aRadii[C_BL].height > 0.0) {
oRadii[C_BL].width = NS_MAX(0.0, aRadii[C_BL].width + aBorderSizes[NS_SIDE_LEFT]);
oRadii[C_BL].height = NS_MAX(0.0, aRadii[C_BL].height + aBorderSizes[NS_SIDE_BOTTOM]);
}
}
/*static*/ void
ComputeBorderCornerDimensions(const gfxRect& aOuterRect,
const gfxRect& aInnerRect,

View File

@ -236,6 +236,14 @@ struct nsCSSBorderRenderer {
static void ComputeInnerRadii(const gfxCornerSizes& aRadii,
const gfxFloat *aBorderSizes,
gfxCornerSizes *aInnerRadiiRet);
// 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 gfxCornerSizes& aRadii,
const gfxFloat *aBorderSizes,
gfxCornerSizes *aOuterRadiiRet);
};
#ifdef DEBUG_NEW_BORDERS

View File

@ -0,0 +1,3 @@
<!DOCTYPE HTML>
<div style="position: absolute; top: 300px; left: 70px; width: 360px; height: 160px; border-bottom-left-radius: 40px; border-top-left-radius: 40px; border-top-right-radius: 40px; background: red;">&nbsp;</div>
<div style="position: absolute; top: 30px; left: 100px; width: 300px; height: 100px; border-bottom-left-radius: 10px; border-top-left-radius: 10px; border-top-right-radius: 10px; background: yellow;">Test</div>

View File

@ -0,0 +1,2 @@
<!DOCTYPE HTML>
<div style="position: absolute; top: 30px; left: 100px; width: 300px; height: 100px; border-bottom-left-radius: 10px; border-top-left-radius: 10px; border-top-right-radius: 10px; box-shadow: 0 300px 0 30px red; background: yellow;">Test</div>

View File

@ -0,0 +1,3 @@
<!DOCTYPE HTML>
<div style="position: absolute; top: 300px; left: 70px; width: 360px; height: 160px; border-bottom-left-radius: 40px; border-top-right-radius: 40px; background: red;">&nbsp;</div>
<div style="position: absolute; top: 30px; left: 100px; width: 300px; height: 100px; border-bottom-left-radius: 10px; border-top-right-radius: 10px; background: yellow;">Test</div>

View File

@ -0,0 +1,2 @@
<!DOCTYPE HTML>
<div style="position: absolute; top: 30px; left: 100px; width: 300px; height: 100px; border-bottom-left-radius: 10px; border-top-right-radius: 10px; box-shadow: 0 300px 0 30px red; background: yellow;">Test</div>

View File

@ -16,6 +16,8 @@ random-if(layersGPUAccelerated) == boxshadow-mixed.html boxshadow-mixed-ref.html
random-if(d2d) == boxshadow-rounded-spread.html boxshadow-rounded-spread-ref.html
HTTP(..) == boxshadow-dynamic.xul boxshadow-dynamic-ref.xul
random-if(d2d) == boxshadow-onecorner.html boxshadow-onecorner-ref.html
random-if(d2d) == boxshadow-twocorners.html boxshadow-twocorners-ref.html
random-if(d2d) == boxshadow-threecorners.html boxshadow-threecorners-ref.html
== boxshadow-skiprect.html boxshadow-skiprect-ref.html
== overflow-not-scrollable-1.html overflow-not-scrollable-1-ref.html