Add support for calc() on -moz-border-radius and -moz-outline-radius. (Bug 585715) r=bzbarsky a2.0=blocking2.0:beta6

This commit is contained in:
L. David Baron 2010-09-09 08:21:45 -07:00
parent 8ffa58d3c2
commit b157c42495
9 changed files with 157 additions and 37 deletions

View File

@ -3262,14 +3262,13 @@ nsLayoutUtils::SetFontFromStyle(nsIRenderingContext* aRC, nsStyleContext* aSC)
static PRBool NonZeroStyleCoord(const nsStyleCoord& aCoord)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Percent:
return aCoord.GetPercentValue() > 0;
case eStyleUnit_Coord:
return aCoord.GetCoordValue() > 0;
default:
return PR_TRUE;
if (aCoord.IsCoordPercentCalcUnit()) {
// Since negative results are clamped to 0, check > 0.
return nsRuleNode::ComputeCoordPercentCalc(aCoord, nscoord_MAX) > 0 ||
nsRuleNode::ComputeCoordPercentCalc(aCoord, 0) > 0;
}
return PR_TRUE;
}
/* static */ PRBool

View File

@ -749,19 +749,15 @@ nsIFrame::ComputeBorderRadii(const nsStyleCorners& aBorderRadius,
nscoord axis =
NS_HALF_CORNER_IS_X(i) ? aFrameSize.width : aFrameSize.height;
switch (c.GetUnit()) {
case eStyleUnit_Percent:
aRadii[i] = (nscoord)(c.GetPercentValue() * axis);
break;
case eStyleUnit_Coord:
aRadii[i] = c.GetCoordValue();
break;
default:
NS_NOTREACHED("ComputeBorderRadii: bad unit");
if (c.IsCoordPercentCalcUnit()) {
aRadii[i] = nsRuleNode::ComputeCoordPercentCalc(c, axis);
if (aRadii[i] < 0) {
// clamp calc()
aRadii[i] = 0;
break;
}
} else {
NS_NOTREACHED("ComputeBorderRadii: bad unit");
aRadii[i] = 0;
}
}

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<title>test for border-radius: calc()</title>
<style>
p {
height: 200px;
width: 400px;
background: blue;
-moz-border-radius: 13px 14px 4px 8px / 5px 2px 10px 3px;
}
</style>
<p></p>

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<title>test for border-radius: calc()</title>
<style>
p {
height: 200px;
width: 400px;
background: blue;
-moz-border-radius: -moz-calc(2% + 5px) -moz-calc(4% - 2px) -moz-calc(min(20px, 1%)) -moz-max(3px, 2%) / -moz-calc(3% - min(1px, 1%)) -moz-calc(1%) -moz-calc(10px) 3px;
}
</style>
<p></p>

View File

@ -1,3 +1,4 @@
== border-radius-1.html border-radius-1-ref.html
== height-block-1.html height-block-1-ref.html
== height-table-1.html height-table-1-ref.html
== margin-block-1.html margin-block-1-ref.html

View File

@ -5068,13 +5068,13 @@ CSSParserImpl::ParseBoxCornerRadius(nsCSSProperty aPropID)
{
nsCSSValue dimenX, dimenY;
// required first value
if (! ParseNonNegativeVariant(dimenX, VARIANT_HLP, nsnull))
if (! ParseNonNegativeVariant(dimenX, VARIANT_HLP | VARIANT_CALC, nsnull))
return PR_FALSE;
// optional second value (forbidden if first value is inherit/initial)
if (dimenX.GetUnit() != eCSSUnit_Inherit &&
dimenX.GetUnit() != eCSSUnit_Initial) {
ParseNonNegativeVariant(dimenY, VARIANT_LP, nsnull);
ParseNonNegativeVariant(dimenY, VARIANT_LP | VARIANT_CALC, nsnull);
}
if (dimenX == dimenY || dimenY.GetUnit() == eCSSUnit_Null) {
@ -5098,7 +5098,9 @@ CSSParserImpl::ParseBoxCornerRadii(const nsCSSProperty aPropIDs[])
NS_FOR_CSS_SIDES (side) {
if (! ParseNonNegativeVariant(dimenX.*nsCSSRect::sides[side],
side > 0 ? VARIANT_LP : VARIANT_HLP, nsnull))
(side > 0 ? 0 : VARIANT_INHERIT) |
VARIANT_LP | VARIANT_CALC,
nsnull))
break;
countX++;
}
@ -5108,7 +5110,7 @@ CSSParserImpl::ParseBoxCornerRadii(const nsCSSProperty aPropIDs[])
if (ExpectSymbol('/', PR_TRUE)) {
NS_FOR_CSS_SIDES (side) {
if (! ParseNonNegativeVariant(dimenY.*nsCSSRect::sides[side],
VARIANT_LP, nsnull))
VARIANT_LP | VARIANT_CALC, nsnull))
break;
countY++;
}

View File

@ -5195,7 +5195,8 @@ nsRuleNode::ComputeBorderData(void* aStartStruct,
nsStyleCoord coordX, coordY;
if (SetPairCoords(radius, coordX, coordY, parentX, parentY,
SETCOORD_LPH | SETCOORD_INITIAL_ZERO,
SETCOORD_LPH | SETCOORD_INITIAL_ZERO |
SETCOORD_STORE_CALC,
aContext, mPresContext, canStoreInRuleTree)) {
border->mBorderRadius.Set(cx, coordX);
border->mBorderRadius.Set(cy, coordY);
@ -5406,7 +5407,8 @@ nsRuleNode::ComputeOutlineData(void* aStartStruct,
nsStyleCoord coordX, coordY;
if (SetPairCoords(radius, coordX, coordY, parentX, parentY,
SETCOORD_LPH | SETCOORD_INITIAL_ZERO,
SETCOORD_LPH | SETCOORD_INITIAL_ZERO |
SETCOORD_STORE_CALC,
aContext, mPresContext, canStoreInRuleTree)) {
outline->mOutlineRadius.Set(cx, coordX);
outline->mOutlineRadius.Set(cy, coordY);

View File

@ -749,7 +749,7 @@ struct nsStyleBorder {
static PRBool ForceCompare() { return PR_FALSE; }
PRBool ImageBorderDiffers() const;
nsStyleCorners mBorderRadius; // [reset] coord, percent
nsStyleCorners mBorderRadius; // [reset] coord, percent, calc
nsStyleSides mBorderImageSplit; // [reset] integer, percent
PRUint8 mFloatEdge; // [reset] see nsStyleConsts.h
PRUint8 mBorderImageHFill; // [reset]
@ -972,7 +972,7 @@ struct nsStyleOutline {
#endif
static PRBool ForceCompare() { return PR_FALSE; }
nsStyleCorners mOutlineRadius; // [reset] coord, percent
nsStyleCorners mOutlineRadius; // [reset] coord, percent, calc
// Note that this is a specified value. You can get the actual values
// with GetOutlineWidth. You cannot get the computed value directly.

View File

@ -165,7 +165,18 @@ var gCSSProperties = {
subproperties: [ "-moz-border-radius-bottomleft", "-moz-border-radius-bottomright", "-moz-border-radius-topleft", "-moz-border-radius-topright" ],
initial_values: [ "0", "0px", "0px 0 0 0px" ], /* 0% ? */
other_values: [ "3%", "1px", "2em", "3em 2px", "2pt 3% 4em", "2px 2px 2px 2px", // circular
"3% / 2%", "1px / 4px", "2em / 1em", "3em 2px / 2px 3em", "2pt 3% 4em / 4pt 1% 5em", "2px 2px 2px 2px / 4px 4px 4px 4px", "1pt / 2pt 3pt", "4pt 5pt / 3pt" // elliptical
"3% / 2%", "1px / 4px", "2em / 1em", "3em 2px / 2px 3em", "2pt 3% 4em / 4pt 1% 5em", "2px 2px 2px 2px / 4px 4px 4px 4px", "1pt / 2pt 3pt", "4pt 5pt / 3pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
"2px 2px -moz-calc(2px + 1%) 2px",
"1px 2px 2px 2px / 2px 2px -moz-calc(2px + 1%) 2px",
],
invalid_values: [ "2px -2px", "inherit 2px", "inherit / 2px", "2px inherit", "2px / inherit", "2px 2px 2px 2px 2px", "1px / 2px 2px 2px 2px 2px" ]
},
@ -175,7 +186,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px" ], /* 0% ? */
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},
@ -185,7 +205,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px" ], /* 0% ? */
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},
@ -195,7 +224,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px" ], /* 0% ? */
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},
@ -205,7 +243,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px" ], /* 0% ? */
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},
@ -607,7 +654,18 @@ var gCSSProperties = {
subproperties: [ "-moz-outline-radius-bottomleft", "-moz-outline-radius-bottomright", "-moz-outline-radius-topleft", "-moz-outline-radius-topright" ],
initial_values: [ "0", "0px", "0%" ],
other_values: [ "3%", "1px", "2em", "3em 2px", "2pt 3% 4em", "2px 2px 2px 2px", // circular
"3% / 2%", "1px / 4px", "2em / 1em", "3em 2px / 2px 3em", "2pt 3% 4em / 4pt 1% 5em", "2px 2px 2px 2px / 4px 4px 4px 4px", "1pt / 2pt 3pt", "4pt 5pt / 3pt" // elliptical
"3% / 2%", "1px / 4px", "2em / 1em", "3em 2px / 2px 3em", "2pt 3% 4em / 4pt 1% 5em", "2px 2px 2px 2px / 4px 4px 4px 4px", "1pt / 2pt 3pt", "4pt 5pt / 3pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
"2px 2px -moz-calc(2px + 1%) 2px",
"1px 2px 2px 2px / 2px 2px -moz-calc(2px + 1%) 2px",
],
invalid_values: [ "2px -2px", "inherit 2px", "inherit / 2px", "2px inherit", "2px / inherit", "2px 2px 2px 2px 2px", "1px / 2px 2px 2px 2px 2px" ]
},
@ -617,7 +675,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px", "0%" ],
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},
@ -627,7 +694,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px", "0%" ],
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},
@ -637,7 +713,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px", "0%" ],
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},
@ -647,7 +732,16 @@ var gCSSProperties = {
type: CSS_TYPE_LONGHAND,
initial_values: [ "0", "0px", "0%" ],
other_values: [ "3%", "1px", "2em", // circular
"3% 2%", "1px 4px", "2em 2pt" // elliptical
"3% 2%", "1px 4px", "2em 2pt", // elliptical
"-moz-calc(2px)",
"-moz-calc(50%)",
"-moz-calc(3*25px)",
"-moz-calc(3*25px) 5px",
"5px -moz-calc(3*25px)",
"-moz-calc(20%) -moz-calc(3*25px)",
"-moz-calc(25px*3)",
"-moz-calc(3*25px + 50%)",
"-moz-min(30%, 30em,200px, min(500px ,40em))",
],
invalid_values: [ "-1px", "4px -2px", "inherit 2px", "2px inherit" ]
},