Instantiate the calc ops struct rather than a nested data struct inside of it. (Bug 363249) r=bzbarsky

This commit is contained in:
L. David Baron 2010-05-11 08:49:44 -07:00
parent 0d2dad97cf
commit 85e2b41165
3 changed files with 92 additions and 113 deletions

View File

@ -51,24 +51,23 @@ namespace css {
*
* typedef ... result_type;
*
* static result_type
* result_type
* MergeAdditive(nsCSSUnit aCalcFunction,
* result_type aValue1, result_type aValue2);
*
* static result_type
* result_type
* MergeMultiplicativeL(nsCSSUnit aCalcFunction,
* float aValue1, result_type aValue2);
*
* static result_type
* result_type
* MergeMultiplicativeR(nsCSSUnit aCalcFunction,
* result_type aValue1, float aValue2);
*
* struct ComputeData { ... };
* result_type
* ComputeLeafValue(const nsCSSValue& aValue);
*
* static result_type ComputeLeafValue(const nsCSSValue& aValue,
* const ComputeData& aClosure);
*
* static float ComputeNumber(const nsCSSValue& aValue);
* float
* ComputeNumber(const nsCSSValue& aValue);
*
* The CalcOps methods might compute the calc() expression down to a
* number, reduce some parts of it to a number but replicate other
@ -92,55 +91,49 @@ namespace css {
*/
template <class CalcOps>
static typename CalcOps::result_type
ComputeCalc(const nsCSSValue& aValue,
const typename CalcOps::ComputeData &aClosure)
ComputeCalc(const nsCSSValue& aValue, CalcOps &aOps)
{
switch (aValue.GetUnit()) {
case eCSSUnit_Calc: {
nsCSSValue::Array *arr = aValue.GetArrayValue();
NS_ABORT_IF_FALSE(arr->Count() == 1, "unexpected length");
return ComputeCalc<CalcOps>(arr->Item(0), aClosure);
return ComputeCalc(arr->Item(0), aOps);
}
case eCSSUnit_Calc_Plus:
case eCSSUnit_Calc_Minus: {
nsCSSValue::Array *arr = aValue.GetArrayValue();
NS_ABORT_IF_FALSE(arr->Count() == 2, "unexpected length");
typename CalcOps::result_type
lhs = ComputeCalc<CalcOps>(arr->Item(0), aClosure),
rhs = ComputeCalc<CalcOps>(arr->Item(1), aClosure);
return CalcOps::MergeAdditive(aValue.GetUnit(), lhs, rhs);
typename CalcOps::result_type lhs = ComputeCalc(arr->Item(0), aOps),
rhs = ComputeCalc(arr->Item(1), aOps);
return aOps.MergeAdditive(aValue.GetUnit(), lhs, rhs);
}
case eCSSUnit_Calc_Times_L: {
nsCSSValue::Array *arr = aValue.GetArrayValue();
NS_ABORT_IF_FALSE(arr->Count() == 2, "unexpected length");
float lhs = CalcOps::ComputeNumber(arr->Item(0));
typename CalcOps::result_type rhs =
ComputeCalc<CalcOps>(arr->Item(1), aClosure);
return CalcOps::MergeMultiplicativeL(aValue.GetUnit(), lhs, rhs);
float lhs = aOps.ComputeNumber(arr->Item(0));
typename CalcOps::result_type rhs = ComputeCalc(arr->Item(1), aOps);
return aOps.MergeMultiplicativeL(aValue.GetUnit(), lhs, rhs);
}
case eCSSUnit_Calc_Times_R:
case eCSSUnit_Calc_Divided: {
nsCSSValue::Array *arr = aValue.GetArrayValue();
NS_ABORT_IF_FALSE(arr->Count() == 2, "unexpected length");
typename CalcOps::result_type lhs =
ComputeCalc<CalcOps>(arr->Item(0), aClosure);
float rhs = CalcOps::ComputeNumber(arr->Item(1));
return CalcOps::MergeMultiplicativeR(aValue.GetUnit(), lhs, rhs);
typename CalcOps::result_type lhs = ComputeCalc(arr->Item(0), aOps);
float rhs = aOps.ComputeNumber(arr->Item(1));
return aOps.MergeMultiplicativeR(aValue.GetUnit(), lhs, rhs);
}
case eCSSUnit_Calc_Minimum:
case eCSSUnit_Calc_Maximum: {
nsCSSValue::Array *arr = aValue.GetArrayValue();
typename CalcOps::result_type result =
ComputeCalc<CalcOps>(arr->Item(0), aClosure);
typename CalcOps::result_type result = ComputeCalc(arr->Item(0), aOps);
for (PRUint32 i = 1, i_end = arr->Count(); i < i_end; ++i) {
typename CalcOps::result_type tmp =
ComputeCalc<CalcOps>(arr->Item(i), aClosure);
result = CalcOps::MergeAdditive(aValue.GetUnit(), result, tmp);
typename CalcOps::result_type tmp = ComputeCalc(arr->Item(i), aOps);
result = aOps.MergeAdditive(aValue.GetUnit(), result, tmp);
}
return result;
}
default: {
return CalcOps::ComputeLeafValue(aValue, aClosure);
return aOps.ComputeLeafValue(aValue);
}
}
}
@ -155,7 +148,7 @@ struct BasicCalcOpsAdditive
{
typedef T result_type;
static result_type
result_type
MergeAdditive(nsCSSUnit aCalcFunction,
result_type aValue1, result_type aValue2)
{
@ -176,7 +169,7 @@ struct BasicCalcOpsAdditive
struct BasicCoordCalcOps : public BasicCalcOpsAdditive<nscoord>
{
static result_type
result_type
MergeMultiplicativeL(nsCSSUnit aCalcFunction,
float aValue1, result_type aValue2)
{
@ -185,7 +178,7 @@ struct BasicCoordCalcOps : public BasicCalcOpsAdditive<nscoord>
return NSToCoordRound(aValue1 * aValue2);
}
static result_type
result_type
MergeMultiplicativeR(nsCSSUnit aCalcFunction,
result_type aValue1, float aValue2)
{
@ -200,7 +193,7 @@ struct BasicCoordCalcOps : public BasicCalcOpsAdditive<nscoord>
struct BasicFloatCalcOps : public BasicCalcOpsAdditive<float>
{
static result_type
result_type
MergeMultiplicativeL(nsCSSUnit aCalcFunction,
float aValue1, result_type aValue2)
{
@ -209,7 +202,7 @@ struct BasicFloatCalcOps : public BasicCalcOpsAdditive<float>
return aValue1 * aValue2;
}
static result_type
result_type
MergeMultiplicativeR(nsCSSUnit aCalcFunction,
result_type aValue1, float aValue2)
{
@ -228,7 +221,7 @@ struct BasicFloatCalcOps : public BasicCalcOpsAdditive<float>
*/
struct NumbersAlreadyNormalizedOps
{
static float ComputeNumber(const nsCSSValue& aValue)
float ComputeNumber(const nsCSSValue& aValue)
{
NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
return aValue.GetFloatValue();

View File

@ -7291,19 +7291,15 @@ CSSParserImpl::ParseCalcAdditiveExpression(nsCSSValue& aValue,
struct ReduceNumberCalcOps : public mozilla::css::BasicFloatCalcOps
{
struct ComputeData {};
static result_type ComputeLeafValue(const nsCSSValue& aValue,
const ComputeData& aClosure)
result_type ComputeLeafValue(const nsCSSValue& aValue)
{
NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
return aValue.GetFloatValue();
}
static float ComputeNumber(const nsCSSValue& aValue)
float ComputeNumber(const nsCSSValue& aValue)
{
return mozilla::css::ComputeCalc<ReduceNumberCalcOps>(
aValue, ReduceNumberCalcOps::ComputeData());
return mozilla::css::ComputeCalc(aValue, *this);
}
};
@ -7348,8 +7344,8 @@ CSSParserImpl::ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
if (variantMask & VARIANT_NUMBER) {
// Simplify the value immediately so we can check for division by
// zero.
float number = mozilla::css::ComputeCalc<ReduceNumberCalcOps>(
*storage, ReduceNumberCalcOps::ComputeData());
ReduceNumberCalcOps ops;
float number = mozilla::css::ComputeCalc(*storage, ops);
if (number == 0.0 && afterDivision)
return PR_FALSE;
storage->SetFloatValue(number, eCSSUnit_Number);
@ -7362,8 +7358,8 @@ CSSParserImpl::ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
NS_ABORT_IF_FALSE(storage == &aValue.GetArrayValue()->Item(1),
"unexpected relationship to current storage");
nsCSSValue &leftValue = aValue.GetArrayValue()->Item(0);
float number = mozilla::css::ComputeCalc<ReduceNumberCalcOps>(
leftValue, ReduceNumberCalcOps::ComputeData());
ReduceNumberCalcOps ops;
float number = mozilla::css::ComputeCalc(leftValue, ops);
leftValue.SetFloatValue(number, eCSSUnit_Number);
}
}

View File

@ -182,39 +182,34 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
struct CalcLengthCalcOps : public mozilla::css::BasicCoordCalcOps,
public mozilla::css::NumbersAlreadyNormalizedOps
{
struct ComputeData {
// All of the parameters to CalcLengthWith except aValue.
nscoord mFontSize;
const nsStyleFont* mStyleFont;
nsStyleContext* mStyleContext;
nsPresContext* mPresContext;
PRBool mUseProvidedRootEmSize;
PRBool mUseUserFontSet;
PRBool& mCanStoreInRuleTree;
// All of the parameters to CalcLengthWith except aValue.
const nscoord mFontSize;
const nsStyleFont* const mStyleFont;
nsStyleContext* const mStyleContext;
nsPresContext* const mPresContext;
const PRBool mUseProvidedRootEmSize;
const PRBool mUseUserFontSet;
PRBool& mCanStoreInRuleTree;
ComputeData(nscoord aFontSize, const nsStyleFont* aStyleFont,
nsStyleContext* aStyleContext, nsPresContext* aPresContext,
PRBool aUseProvidedRootEmSize, PRBool aUseUserFontSet,
PRBool& aCanStoreInRuleTree)
: mFontSize(aFontSize),
mStyleFont(aStyleFont),
mStyleContext(aStyleContext),
mPresContext(aPresContext),
mUseProvidedRootEmSize(aUseProvidedRootEmSize),
mUseUserFontSet(aUseUserFontSet),
mCanStoreInRuleTree(aCanStoreInRuleTree)
{
}
};
static result_type ComputeLeafValue(const nsCSSValue& aValue,
const ComputeData& aClosure)
CalcLengthCalcOps(nscoord aFontSize, const nsStyleFont* aStyleFont,
nsStyleContext* aStyleContext, nsPresContext* aPresContext,
PRBool aUseProvidedRootEmSize, PRBool aUseUserFontSet,
PRBool& aCanStoreInRuleTree)
: mFontSize(aFontSize),
mStyleFont(aStyleFont),
mStyleContext(aStyleContext),
mPresContext(aPresContext),
mUseProvidedRootEmSize(aUseProvidedRootEmSize),
mUseUserFontSet(aUseUserFontSet),
mCanStoreInRuleTree(aCanStoreInRuleTree)
{
return CalcLengthWith(aValue, aClosure.mFontSize, aClosure.mStyleFont,
aClosure.mStyleContext, aClosure.mPresContext,
aClosure.mUseProvidedRootEmSize,
aClosure.mUseUserFontSet,
aClosure.mCanStoreInRuleTree);
}
result_type ComputeLeafValue(const nsCSSValue& aValue)
{
return CalcLengthWith(aValue, mFontSize, mStyleFont, mStyleContext,
mPresContext, mUseProvidedRootEmSize,
mUseUserFontSet, mCanStoreInRuleTree);
}
};
@ -329,10 +324,10 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
case eCSSUnit_Calc_Divided:
case eCSSUnit_Calc_Minimum:
case eCSSUnit_Calc_Maximum: {
CalcLengthCalcOps::ComputeData
data(aFontSize, aStyleFont, aStyleContext, aPresContext,
aUseProvidedRootEmSize, aUseUserFontSet, aCanStoreInRuleTree);
return mozilla::css::ComputeCalc<CalcLengthCalcOps>(aValue, data);
CalcLengthCalcOps ops(aFontSize, aStyleFont, aStyleContext, aPresContext,
aUseProvidedRootEmSize, aUseUserFontSet,
aCanStoreInRuleTree);
return mozilla::css::ComputeCalc(aValue, ops);
}
default:
NS_NOTREACHED("unexpected unit");
@ -2662,50 +2657,47 @@ ComputeScriptLevelSize(const nsStyleFont* aFont, const nsStyleFont* aParentFont,
struct SetFontSizeCalcOps : public mozilla::css::BasicCoordCalcOps,
public mozilla::css::NumbersAlreadyNormalizedOps
{
struct ComputeData {
// The parameters beyond aValue that we need for CalcLengthWith.
nscoord mParentSize;
const nsStyleFont* mParentFont;
nsPresContext* mPresContext;
PRBool mAtRoot;
PRBool& mCanStoreInRuleTree;
// The parameters beyond aValue that we need for CalcLengthWith.
const nscoord mParentSize;
const nsStyleFont* const mParentFont;
nsPresContext* const mPresContext;
const PRBool mAtRoot;
PRBool& mCanStoreInRuleTree;
ComputeData(nscoord aParentSize, const nsStyleFont* aParentFont,
nsPresContext* aPresContext, PRBool aAtRoot,
PRBool& aCanStoreInRuleTree)
: mParentSize(aParentSize),
mParentFont(aParentFont),
mPresContext(aPresContext),
mAtRoot(aAtRoot),
mCanStoreInRuleTree(aCanStoreInRuleTree)
{
}
};
SetFontSizeCalcOps(nscoord aParentSize, const nsStyleFont* aParentFont,
nsPresContext* aPresContext, PRBool aAtRoot,
PRBool& aCanStoreInRuleTree)
: mParentSize(aParentSize),
mParentFont(aParentFont),
mPresContext(aPresContext),
mAtRoot(aAtRoot),
mCanStoreInRuleTree(aCanStoreInRuleTree)
{
}
static result_type ComputeLeafValue(const nsCSSValue& aValue,
const ComputeData& aClosure)
result_type ComputeLeafValue(const nsCSSValue& aValue)
{
nscoord size;
if (aValue.IsLengthUnit()) {
// Note that font-based length units use the parent's size
// unadjusted for scriptlevel changes. A scriptlevel change
// between us and the parent is simply ignored.
size = CalcLengthWith(aValue, aClosure.mParentSize, aClosure.mParentFont,
nsnull, aClosure.mPresContext, aClosure.mAtRoot,
PR_TRUE, aClosure.mCanStoreInRuleTree);
size = CalcLengthWith(aValue, mParentSize, mParentFont,
nsnull, mPresContext, mAtRoot,
PR_TRUE, mCanStoreInRuleTree);
if (aValue.IsFixedLengthUnit() || aValue.GetUnit() == eCSSUnit_Pixel) {
size = nsStyleFont::ZoomText(aClosure.mPresContext, size);
size = nsStyleFont::ZoomText(mPresContext, size);
}
}
else if (eCSSUnit_Percent == aValue.GetUnit()) {
aClosure.mCanStoreInRuleTree = PR_FALSE;
mCanStoreInRuleTree = PR_FALSE;
// Note that % units use the parent's size unadjusted for scriptlevel
// changes. A scriptlevel change between us and the parent is simply
// ignored.
size = NSToCoordRound(aClosure.mParentSize * aValue.GetPercentValue());
size = NSToCoordRound(mParentSize * aValue.GetPercentValue());
} else {
NS_ABORT_IF_FALSE(PR_FALSE, "unexpected value");
size = aClosure.mParentSize;
size = mParentSize;
}
return size;
@ -2776,11 +2768,9 @@ nsRuleNode::SetFontSize(nsPresContext* aPresContext,
else if (aFontData.mSize.IsLengthUnit() ||
aFontData.mSize.GetUnit() == eCSSUnit_Percent ||
aFontData.mSize.IsCalcUnit()) {
SetFontSizeCalcOps::ComputeData data(aParentSize, aParentFont,
aPresContext, aAtRoot,
aCanStoreInRuleTree);
*aSize =
mozilla::css::ComputeCalc<SetFontSizeCalcOps>(aFontData.mSize, data);
SetFontSizeCalcOps ops(aParentSize, aParentFont, aPresContext, aAtRoot,
aCanStoreInRuleTree);
*aSize = mozilla::css::ComputeCalc(aFontData.mSize, ops);
if (*aSize < 0) {
NS_ABORT_IF_FALSE(aFontData.mSize.IsCalcUnit(),
"negative lengths and percents should be rejected "