зеркало из https://github.com/mozilla/gecko-dev.git
Simplify storage of computed calc() as a result of removing min() and max(). (Bug 363249) r=bzbarsky a2.0=blocking2.0:beta6
This commit is contained in:
Родитель
e031591955
Коммит
3d7d18c200
|
@ -3216,75 +3216,6 @@ nsIFrame::InlinePrefWidthData::ForceBreak(nsIRenderingContext *aRenderingContext
|
|||
skipWhitespace = PR_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class does calc() computation of lengths and percents separately.
|
||||
*
|
||||
* FIXME: remove this in the next patch
|
||||
*
|
||||
* It is used only for intrinsic width computation, where being an
|
||||
* approximation is sometimes ok (although it would be good to fix at
|
||||
* some point in the future).
|
||||
*/
|
||||
struct LengthPercentPairWithMinMaxCalcOps : public css::StyleCoordInputCalcOps
|
||||
{
|
||||
struct result_type {
|
||||
nscoord mLength;
|
||||
float mPercent;
|
||||
|
||||
result_type(nscoord aLength, float aPercent)
|
||||
: mLength(aLength), mPercent(aPercent) {}
|
||||
};
|
||||
|
||||
result_type ComputeLeafValue(const nsStyleCoord& aValue)
|
||||
{
|
||||
if (aValue.GetUnit() == eStyleUnit_Percent) {
|
||||
return result_type(0, aValue.GetPercentValue());
|
||||
}
|
||||
return result_type(aValue.GetCoordValue(), 0.0f);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeAdditive(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
if (aCalcFunction == eCSSUnit_Calc_Plus) {
|
||||
return result_type(NSCoordSaturatingAdd(aValue1.mLength,
|
||||
aValue2.mLength),
|
||||
aValue1.mPercent + aValue2.mPercent);
|
||||
}
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Minus,
|
||||
"unexpected unit");
|
||||
return result_type(NSCoordSaturatingSubtract(aValue1.mLength,
|
||||
aValue2.mLength, 0),
|
||||
aValue1.mPercent - aValue2.mPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeL(nsCSSUnit aCalcFunction,
|
||||
float aValue1, result_type aValue2)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Times_L,
|
||||
"unexpected unit");
|
||||
return result_type(NSCoordSaturatingMultiply(aValue2.mLength, aValue1),
|
||||
aValue1 * aValue2.mPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeR(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, float aValue2)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Times_R ||
|
||||
aCalcFunction == eCSSUnit_Calc_Divided,
|
||||
"unexpected unit");
|
||||
if (aCalcFunction == eCSSUnit_Calc_Divided) {
|
||||
aValue2 = 1.0f / aValue2;
|
||||
}
|
||||
return result_type(NSCoordSaturatingMultiply(aValue1.mLength, aValue2),
|
||||
aValue1.mPercent * aValue2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static void
|
||||
AddCoord(const nsStyleCoord& aStyle,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
|
@ -3292,20 +3223,35 @@ AddCoord(const nsStyleCoord& aStyle,
|
|||
nscoord* aCoord, float* aPercent,
|
||||
PRBool aClampNegativeToZero)
|
||||
{
|
||||
if (!aStyle.IsCoordPercentCalcUnit()) {
|
||||
return;
|
||||
switch (aStyle.GetUnit()) {
|
||||
case eStyleUnit_Coord: {
|
||||
NS_ASSERTION(!aClampNegativeToZero || aStyle.GetCoordValue() >= 0,
|
||||
"unexpected negative value");
|
||||
*aCoord += aStyle.GetCoordValue();
|
||||
return;
|
||||
}
|
||||
case eStyleUnit_Percent: {
|
||||
NS_ASSERTION(!aClampNegativeToZero || aStyle.GetPercentValue() >= 0.0f,
|
||||
"unexpected negative value");
|
||||
*aPercent += aStyle.GetPercentValue();
|
||||
return;
|
||||
}
|
||||
case eStyleUnit_Calc: {
|
||||
const nsStyleCoord::Calc *calc = aStyle.GetCalcValue();
|
||||
if (aClampNegativeToZero) {
|
||||
// This is far from ideal when one is negative and one is positive.
|
||||
*aCoord += NS_MAX(calc->mLength, 0);
|
||||
*aPercent += NS_MAX(calc->mPercent, 0.0f);
|
||||
} else {
|
||||
*aCoord += calc->mLength;
|
||||
*aPercent += calc->mPercent;
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LengthPercentPairWithMinMaxCalcOps ops;
|
||||
LengthPercentPairWithMinMaxCalcOps::result_type pair =
|
||||
css::ComputeCalc(aStyle, ops);
|
||||
if (aClampNegativeToZero) {
|
||||
// This is far from ideal when one is negative and one is positive.
|
||||
pair.mLength = NS_MAX(pair.mLength, 0);
|
||||
pair.mPercent = NS_MAX(pair.mPercent, 0.0f);
|
||||
}
|
||||
*aCoord += pair.mLength;
|
||||
*aPercent += pair.mPercent;
|
||||
}
|
||||
|
||||
/* virtual */ nsIFrame::IntrinsicWidthOffsetData
|
||||
|
@ -3313,10 +3259,6 @@ nsFrame::IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext)
|
|||
{
|
||||
IntrinsicWidthOffsetData result;
|
||||
|
||||
// FIXME: The handling of calc() with min() and max() by AddCoord
|
||||
// is a rough approximation. It could be improved, but only by
|
||||
// changing the IntrinsicWidthOffsets API substantially. See the
|
||||
// comment above LengthPercentPairWithMinMaxCalcOps.
|
||||
const nsStyleMargin *styleMargin = GetStyleMargin();
|
||||
AddCoord(styleMargin->mMargin.GetLeft(), aRenderingContext, this,
|
||||
&result.hMargin, &result.hPctMargin, PR_FALSE);
|
||||
|
|
|
@ -143,36 +143,6 @@ ComputeCalc(const typename CalcOps::input_type& aValue, CalcOps &aOps)
|
|||
}
|
||||
}
|
||||
|
||||
#define CHECK_UNIT(u_) \
|
||||
PR_STATIC_ASSERT(int(eCSSUnit_##u_) + 14 == int(eStyleUnit_##u_)); \
|
||||
PR_STATIC_ASSERT(eCSSUnit_##u_ >= eCSSUnit_Calc); \
|
||||
PR_STATIC_ASSERT(eCSSUnit_##u_ <= eCSSUnit_Calc_Divided);
|
||||
|
||||
CHECK_UNIT(Calc)
|
||||
CHECK_UNIT(Calc_Plus)
|
||||
CHECK_UNIT(Calc_Minus)
|
||||
CHECK_UNIT(Calc_Times_L)
|
||||
CHECK_UNIT(Calc_Times_R)
|
||||
CHECK_UNIT(Calc_Divided)
|
||||
|
||||
#undef CHECK_UNIT
|
||||
|
||||
inline nsStyleUnit
|
||||
ConvertCalcUnit(nsCSSUnit aUnit)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(eCSSUnit_Calc <= aUnit &&
|
||||
aUnit <= eCSSUnit_Calc_Divided, "out of range");
|
||||
return nsStyleUnit(aUnit + 14);
|
||||
}
|
||||
|
||||
inline nsCSSUnit
|
||||
ConvertCalcUnit(nsStyleUnit aUnit)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(eStyleUnit_Calc <= aUnit &&
|
||||
aUnit <= eStyleUnit_Calc_Divided, "out of range");
|
||||
return nsCSSUnit(aUnit - 14);
|
||||
}
|
||||
|
||||
/**
|
||||
* The input unit operation for input_type being nsCSSValue.
|
||||
*/
|
||||
|
@ -188,30 +158,6 @@ struct CSSValueInputCalcOps
|
|||
|
||||
};
|
||||
|
||||
/**
|
||||
* The input unit operation for input_type being nsStyleCoord
|
||||
*/
|
||||
struct StyleCoordInputCalcOps
|
||||
{
|
||||
typedef nsStyleCoord input_type;
|
||||
typedef nsStyleCoord::Array input_array_type;
|
||||
|
||||
static nsCSSUnit GetUnit(const nsStyleCoord& aValue)
|
||||
{
|
||||
if (aValue.IsCalcUnit()) {
|
||||
return css::ConvertCalcUnit(aValue.GetUnit());
|
||||
}
|
||||
return eCSSUnit_Null;
|
||||
}
|
||||
|
||||
float ComputeNumber(const nsStyleCoord& aValue)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "SpecifiedToComputedCalcOps should not "
|
||||
"leave numbers in structure");
|
||||
return 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Basic*CalcOps provide a partial implementation of the CalcOps
|
||||
* template parameter to ComputeCalc, for those callers whose merging
|
||||
|
|
|
@ -3802,54 +3802,6 @@ nsComputedDOMStyle::GetBorderStyleFor(mozilla::css::Side aSide, nsIDOMCSSValue**
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
struct StyleCoordSerializeCalcOps {
|
||||
StyleCoordSerializeCalcOps(nsAString& aResult)
|
||||
: mResult(aResult)
|
||||
{
|
||||
}
|
||||
|
||||
typedef nsStyleCoord input_type;
|
||||
typedef nsStyleCoord::Array input_array_type;
|
||||
|
||||
static nsCSSUnit GetUnit(const input_type& aValue) {
|
||||
if (aValue.IsCalcUnit()) {
|
||||
return css::ConvertCalcUnit(aValue.GetUnit());
|
||||
}
|
||||
return eCSSUnit_Null;
|
||||
}
|
||||
|
||||
void Append(const char* aString)
|
||||
{
|
||||
mResult.AppendASCII(aString);
|
||||
}
|
||||
|
||||
void AppendLeafValue(const input_type& aValue)
|
||||
{
|
||||
nsRefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue();
|
||||
if (aValue.GetUnit() == eStyleUnit_Percent) {
|
||||
val->SetPercent(aValue.GetPercentValue());
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(aValue.GetUnit() == eStyleUnit_Coord,
|
||||
"unexpected unit");
|
||||
val->SetAppUnits(aValue.GetCoordValue());
|
||||
}
|
||||
|
||||
nsAutoString tmp;
|
||||
val->GetCssText(tmp);
|
||||
mResult.Append(tmp);
|
||||
}
|
||||
|
||||
void AppendNumber(const input_type& aValue)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(PR_FALSE,
|
||||
"should not have numbers in nsStyleCoord calc()");
|
||||
}
|
||||
|
||||
private:
|
||||
nsAString &mResult;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue,
|
||||
const nsStyleCoord& aCoord,
|
||||
|
@ -3909,37 +3861,51 @@ nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue,
|
|||
aValue->SetIdent(eCSSKeyword_none);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (aCoord.IsCalcUnit()) {
|
||||
nscoord percentageBase;
|
||||
if (!aCoord.CalcHasPercent()) {
|
||||
nscoord val = nsRuleNode::ComputeCoordPercentCalc(aCoord, 0);
|
||||
if (aClampNegativeCalc && val < 0) {
|
||||
NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(),
|
||||
"parser should have rejected value");
|
||||
val = 0;
|
||||
}
|
||||
aValue->SetAppUnits(NS_MAX(aMinAppUnits, NS_MIN(val, aMaxAppUnits)));
|
||||
} else if (aPercentageBaseGetter &&
|
||||
(this->*aPercentageBaseGetter)(percentageBase)) {
|
||||
nscoord val =
|
||||
nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase);
|
||||
if (aClampNegativeCalc && val < 0) {
|
||||
NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(),
|
||||
"parser should have rejected value");
|
||||
val = 0;
|
||||
}
|
||||
aValue->SetAppUnits(NS_MAX(aMinAppUnits, NS_MIN(val, aMaxAppUnits)));
|
||||
} else {
|
||||
nsAutoString tmp;
|
||||
StyleCoordSerializeCalcOps ops(tmp);
|
||||
css::SerializeCalc(aCoord, ops);
|
||||
aValue->SetString(tmp); // not really SetString
|
||||
case eStyleUnit_Calc:
|
||||
nscoord percentageBase;
|
||||
if (!aCoord.CalcHasPercent()) {
|
||||
nscoord val = nsRuleNode::ComputeCoordPercentCalc(aCoord, 0);
|
||||
if (aClampNegativeCalc && val < 0) {
|
||||
NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(),
|
||||
"parser should have rejected value");
|
||||
val = 0;
|
||||
}
|
||||
aValue->SetAppUnits(NS_MAX(aMinAppUnits, NS_MIN(val, aMaxAppUnits)));
|
||||
} else if (aPercentageBaseGetter &&
|
||||
(this->*aPercentageBaseGetter)(percentageBase)) {
|
||||
nscoord val =
|
||||
nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase);
|
||||
if (aClampNegativeCalc && val < 0) {
|
||||
NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(),
|
||||
"parser should have rejected value");
|
||||
val = 0;
|
||||
}
|
||||
aValue->SetAppUnits(NS_MAX(aMinAppUnits, NS_MIN(val, aMaxAppUnits)));
|
||||
} else {
|
||||
NS_ERROR("Can't handle this unit");
|
||||
nsStyleCoord::Calc *calc = aCoord.GetCalcValue();
|
||||
nsRefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue();
|
||||
nsAutoString tmp, result;
|
||||
|
||||
result.AppendLiteral("-moz-calc(");
|
||||
|
||||
val->SetAppUnits(calc->mLength);
|
||||
val->GetCssText(tmp);
|
||||
result.Append(tmp);
|
||||
|
||||
result.AppendLiteral(" + ");
|
||||
|
||||
val->SetPercent(calc->mPercent);
|
||||
val->GetCssText(tmp);
|
||||
result.Append(tmp);
|
||||
|
||||
result.AppendLiteral(")");
|
||||
|
||||
aValue->SetString(result); // not really SetString
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Can't handle this unit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -371,134 +371,75 @@ nsRuleNode::CalcLengthWithInitialFont(nsPresContext* aPresContext,
|
|||
PR_TRUE, PR_FALSE, canStoreInRuleTree);
|
||||
}
|
||||
|
||||
struct SpecifiedToComputedCalcOps : public css::NumbersAlreadyNormalizedOps
|
||||
struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps
|
||||
{
|
||||
// FIXME (perf): Is there too much copying as a result of returning
|
||||
// nsStyleCoord objects?
|
||||
typedef nsStyleCoord result_type;
|
||||
typedef nsRuleNode::ComputedCalc result_type;
|
||||
|
||||
nsStyleContext* const mStyleContext;
|
||||
nsPresContext* const mPresContext;
|
||||
PRBool& mCanStoreInRuleTree;
|
||||
|
||||
SpecifiedToComputedCalcOps(nsStyleContext* aStyleContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree)
|
||||
: mStyleContext(aStyleContext),
|
||||
LengthPercentPairCalcOps(nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree)
|
||||
: mContext(aContext),
|
||||
mPresContext(aPresContext),
|
||||
mCanStoreInRuleTree(aCanStoreInRuleTree)
|
||||
mCanStoreInRuleTree(aCanStoreInRuleTree),
|
||||
mHasPercent(PR_FALSE) {}
|
||||
|
||||
nsStyleContext* mContext;
|
||||
nsPresContext* mPresContext;
|
||||
PRBool& mCanStoreInRuleTree;
|
||||
PRBool mHasPercent;
|
||||
|
||||
result_type ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
if (aValue.GetUnit() == eCSSUnit_Percent) {
|
||||
mHasPercent = PR_TRUE;
|
||||
return result_type(0, aValue.GetPercentValue());
|
||||
}
|
||||
return result_type(CalcLength(aValue, mContext, mPresContext,
|
||||
mCanStoreInRuleTree),
|
||||
0.0f);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeAdditive(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
nsStyleUnit unit1 = aValue1.GetUnit();
|
||||
nsStyleUnit unit2 = aValue2.GetUnit();
|
||||
NS_ABORT_IF_FALSE(unit1 == eStyleUnit_Coord ||
|
||||
unit1 == eStyleUnit_Percent ||
|
||||
aValue1.IsCalcUnit(),
|
||||
"unexpected unit");
|
||||
NS_ABORT_IF_FALSE(unit2 == eStyleUnit_Coord ||
|
||||
unit2 == eStyleUnit_Percent ||
|
||||
aValue2.IsCalcUnit(),
|
||||
"unexpected unit");
|
||||
nsStyleCoord result;
|
||||
if (unit1 == unit2 && !aValue1.IsCalcUnit()) {
|
||||
// Merge nodes that we don't need to keep separate.
|
||||
if (unit1 == eStyleUnit_Percent) {
|
||||
css::BasicFloatCalcOps ops;
|
||||
result.SetPercentValue(ops.MergeAdditive(aCalcFunction,
|
||||
aValue1.GetPercentValue(),
|
||||
aValue2.GetPercentValue()));
|
||||
} else {
|
||||
css::BasicCoordCalcOps ops;
|
||||
result.SetCoordValue(ops.MergeAdditive(aCalcFunction,
|
||||
aValue1.GetCoordValue(),
|
||||
aValue2.GetCoordValue()));
|
||||
}
|
||||
} else {
|
||||
nsStyleCoord::Array *array =
|
||||
nsStyleCoord::Array::Create(mStyleContext, mCanStoreInRuleTree, 2);
|
||||
array->Item(0) = aValue1;
|
||||
array->Item(1) = aValue2;
|
||||
result.SetArrayValue(array, css::ConvertCalcUnit(aCalcFunction));
|
||||
if (aCalcFunction == eCSSUnit_Calc_Plus) {
|
||||
return result_type(NSCoordSaturatingAdd(aValue1.mLength,
|
||||
aValue2.mLength),
|
||||
aValue1.mPercent + aValue2.mPercent);
|
||||
}
|
||||
return result;
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Minus,
|
||||
"min() and max() are not allowed in calc() on "
|
||||
"transform");
|
||||
return result_type(NSCoordSaturatingSubtract(aValue1.mLength,
|
||||
aValue2.mLength, 0),
|
||||
aValue1.mPercent - aValue2.mPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeL(nsCSSUnit aCalcFunction,
|
||||
float aValue1, result_type aValue2)
|
||||
{
|
||||
nsStyleCoord result;
|
||||
switch (aValue2.GetUnit()) {
|
||||
case eStyleUnit_Percent: {
|
||||
css::BasicFloatCalcOps ops;
|
||||
result.SetPercentValue(ops.MergeMultiplicativeL(
|
||||
aCalcFunction, aValue1, aValue2.GetPercentValue()));
|
||||
break;
|
||||
}
|
||||
case eStyleUnit_Coord: {
|
||||
css::BasicCoordCalcOps ops;
|
||||
result.SetCoordValue(ops.MergeMultiplicativeL(
|
||||
aCalcFunction, aValue1, aValue2.GetCoordValue()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(aValue2.IsCalcUnit(), "unexpected unit");
|
||||
nsStyleCoord::Array *array =
|
||||
nsStyleCoord::Array::Create(mStyleContext, mCanStoreInRuleTree, 2);
|
||||
array->Item(0).SetFactorValue(aValue1);
|
||||
array->Item(1) = aValue2;
|
||||
result.SetArrayValue(array, css::ConvertCalcUnit(aCalcFunction));
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Times_L,
|
||||
"unexpected unit");
|
||||
return result_type(NSCoordSaturatingMultiply(aValue2.mLength, aValue1),
|
||||
aValue1 * aValue2.mPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeR(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, float aValue2)
|
||||
{
|
||||
nsStyleCoord result;
|
||||
switch (aValue1.GetUnit()) {
|
||||
case eStyleUnit_Percent: {
|
||||
css::BasicFloatCalcOps ops;
|
||||
result.SetPercentValue(ops.MergeMultiplicativeR(
|
||||
aCalcFunction, aValue1.GetPercentValue(), aValue2));
|
||||
break;
|
||||
}
|
||||
case eStyleUnit_Coord: {
|
||||
css::BasicCoordCalcOps ops;
|
||||
result.SetCoordValue(ops.MergeMultiplicativeR(
|
||||
aCalcFunction, aValue1.GetCoordValue(), aValue2));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(aValue1.IsCalcUnit(), "unexpected unit");
|
||||
nsStyleCoord::Array *array =
|
||||
nsStyleCoord::Array::Create(mStyleContext, mCanStoreInRuleTree, 2);
|
||||
array->Item(0) = aValue1;
|
||||
array->Item(1).SetFactorValue(aValue2);
|
||||
result.SetArrayValue(array, css::ConvertCalcUnit(aCalcFunction));
|
||||
break;
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Times_R ||
|
||||
aCalcFunction == eCSSUnit_Calc_Divided,
|
||||
"unexpected unit");
|
||||
if (aCalcFunction == eCSSUnit_Calc_Divided) {
|
||||
aValue2 = 1.0f / aValue2;
|
||||
}
|
||||
return result;
|
||||
return result_type(NSCoordSaturatingMultiply(aValue1.mLength, aValue2),
|
||||
aValue1.mPercent * aValue2);
|
||||
}
|
||||
|
||||
result_type ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
nsStyleCoord result;
|
||||
if (aValue.GetUnit() == eCSSUnit_Percent) {
|
||||
result.SetPercentValue(aValue.GetPercentValue());
|
||||
} else {
|
||||
result.SetCoordValue(CalcLength(aValue, mStyleContext, mPresContext,
|
||||
mCanStoreInRuleTree));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -506,41 +447,33 @@ SpecifiedCalcToComputedCalc(const nsCSSValue& aValue, nsStyleCoord& aCoord,
|
|||
nsStyleContext* aStyleContext,
|
||||
PRBool& aCanStoreInRuleTree)
|
||||
{
|
||||
SpecifiedToComputedCalcOps ops(aStyleContext, aStyleContext->PresContext(),
|
||||
aCanStoreInRuleTree);
|
||||
aCoord = ComputeCalc(aValue, ops);
|
||||
if (!aCoord.IsCalcUnit()) {
|
||||
// Some callers distinguish between calc(50%) and 50%, or calc(50px)
|
||||
// and 50px.
|
||||
nsStyleCoord::Array *array =
|
||||
nsStyleCoord::Array::Create(aStyleContext, aCanStoreInRuleTree, 1);
|
||||
array->Item(0) = aCoord;
|
||||
aCoord.SetArrayValue(array, eStyleUnit_Calc);
|
||||
}
|
||||
LengthPercentPairCalcOps ops(aStyleContext, aStyleContext->PresContext(),
|
||||
aCanStoreInRuleTree);
|
||||
nsRuleNode::ComputedCalc vals = ComputeCalc(aValue, ops);
|
||||
|
||||
nsStyleCoord::Calc *calcObj =
|
||||
new (aStyleContext->Alloc(sizeof(nsStyleCoord::Calc))) nsStyleCoord::Calc;
|
||||
// Because we use aStyleContext->Alloc(), we have to store the result
|
||||
// on the style context and not in the rule tree.
|
||||
aCanStoreInRuleTree = PR_FALSE;
|
||||
|
||||
calcObj->mLength = vals.mLength;
|
||||
calcObj->mPercent = vals.mPercent;
|
||||
calcObj->mHasPercent = ops.mHasPercent;
|
||||
|
||||
aCoord.SetCalcValue(calcObj);
|
||||
}
|
||||
|
||||
struct ComputeComputedCalcCalcOps : public css::StyleCoordInputCalcOps,
|
||||
public css::BasicCoordCalcOps
|
||||
/* static */ nsRuleNode::ComputedCalc
|
||||
nsRuleNode::SpecifiedCalcToComputedCalc(const nsCSSValue& aValue,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree)
|
||||
{
|
||||
const nscoord mPercentageBasis;
|
||||
|
||||
ComputeComputedCalcCalcOps(nscoord aPercentageBasis)
|
||||
: mPercentageBasis(aPercentageBasis)
|
||||
{
|
||||
}
|
||||
|
||||
result_type ComputeLeafValue(const nsStyleCoord& aValue)
|
||||
{
|
||||
nscoord result;
|
||||
if (aValue.GetUnit() == eStyleUnit_Percent) {
|
||||
result =
|
||||
NSToCoordFloorClamped(mPercentageBasis * aValue.GetPercentValue());
|
||||
} else {
|
||||
result = aValue.GetCoordValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
LengthPercentPairCalcOps ops(aStyleContext, aPresContext,
|
||||
aCanStoreInRuleTree);
|
||||
return ComputeCalc(aValue, ops);
|
||||
}
|
||||
|
||||
// This is our public API for handling calc() expressions that involve
|
||||
// percentages.
|
||||
|
@ -548,8 +481,26 @@ struct ComputeComputedCalcCalcOps : public css::StyleCoordInputCalcOps,
|
|||
nsRuleNode::ComputeComputedCalc(const nsStyleCoord& aValue,
|
||||
nscoord aPercentageBasis)
|
||||
{
|
||||
ComputeComputedCalcCalcOps ops(aPercentageBasis);
|
||||
return css::ComputeCalc(aValue, ops);
|
||||
nsStyleCoord::Calc *calc = aValue.GetCalcValue();
|
||||
return calc->mLength +
|
||||
NSToCoordFloorClamped(aPercentageBasis * calc->mPercent);
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
nsRuleNode::ComputeCoordPercentCalc(const nsStyleCoord& aCoord,
|
||||
nscoord aPercentageBasis)
|
||||
{
|
||||
switch (aCoord.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
return aCoord.GetCoordValue();
|
||||
case eStyleUnit_Percent:
|
||||
return NSToCoordFloorClamped(aPercentageBasis * aCoord.GetPercentValue());
|
||||
case eStyleUnit_Calc:
|
||||
return ComputeComputedCalc(aCoord, aPercentageBasis);
|
||||
default:
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "unexpected unit");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given an enumerated value that represents a box position, converts it to
|
||||
|
|
|
@ -758,6 +758,19 @@ public:
|
|||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree);
|
||||
|
||||
struct ComputedCalc {
|
||||
nscoord mLength;
|
||||
float mPercent;
|
||||
|
||||
ComputedCalc(nscoord aLength, float aPercent)
|
||||
: mLength(aLength), mPercent(aPercent) {}
|
||||
};
|
||||
static ComputedCalc
|
||||
SpecifiedCalcToComputedCalc(const nsCSSValue& aValue,
|
||||
nsStyleContext* aStyleContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree);
|
||||
|
||||
// Compute the value of an nsStyleCoord that IsCalcUnit().
|
||||
// (Values that don't require aPercentageBasis should be handled
|
||||
// inside nsRuleNode rather than through this API.)
|
||||
|
@ -767,11 +780,7 @@ public:
|
|||
// Compute the value of an nsStyleCoord that is either a coord, a
|
||||
// percent, or a calc expression.
|
||||
static nscoord ComputeCoordPercentCalc(const nsStyleCoord& aCoord,
|
||||
nscoord aPercentageBasis)
|
||||
{
|
||||
// ComputeComputedCalc will handle coords and percents correctly
|
||||
return ComputeComputedCalc(aCoord, aPercentageBasis);
|
||||
}
|
||||
nscoord aPercentageBasis);
|
||||
|
||||
// Return whether the rule tree for which this node is the root has
|
||||
// cached data such that we need to do dynamic change handling for
|
||||
|
|
|
@ -91,7 +91,7 @@ nsStyleCoord& nsStyleCoord::operator=(const nsStyleCoord& aCopy)
|
|||
if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) {
|
||||
mValue.mFloat = aCopy.mValue.mFloat;
|
||||
}
|
||||
else if (IsArrayValue()) {
|
||||
else if (IsPointerValue()) {
|
||||
mValue.mPointer = aCopy.mValue.mPointer;
|
||||
}
|
||||
else {
|
||||
|
@ -122,12 +122,7 @@ PRBool nsStyleCoord::operator==(const nsStyleCoord& aOther) const
|
|||
case eStyleUnit_Enumerated:
|
||||
return mValue.mInt == aOther.mValue.mInt;
|
||||
case eStyleUnit_Calc:
|
||||
case eStyleUnit_Calc_Plus:
|
||||
case eStyleUnit_Calc_Minus:
|
||||
case eStyleUnit_Calc_Times_L:
|
||||
case eStyleUnit_Calc_Times_R:
|
||||
case eStyleUnit_Calc_Divided:
|
||||
return *this->GetArrayValue() == *aOther.GetArrayValue();
|
||||
return *this->GetCalcValue() == *aOther.GetCalcValue();
|
||||
}
|
||||
NS_ABORT_IF_FALSE(PR_FALSE, "unexpected unit");
|
||||
return PR_FALSE;
|
||||
|
@ -184,15 +179,10 @@ void nsStyleCoord::SetAngleValue(float aValue, nsStyleUnit aUnit)
|
|||
}
|
||||
}
|
||||
|
||||
void nsStyleCoord::SetArrayValue(Array* aValue, nsStyleUnit aUnit)
|
||||
void nsStyleCoord::SetCalcValue(Calc* aValue)
|
||||
{
|
||||
mUnit = aUnit;
|
||||
if (IsArrayValue()) {
|
||||
mValue.mPointer = aValue;
|
||||
} else {
|
||||
NS_NOTREACHED("not a pointer value");
|
||||
Reset();
|
||||
}
|
||||
mUnit = eStyleUnit_Calc;
|
||||
mValue.mPointer = aValue;
|
||||
}
|
||||
|
||||
void nsStyleCoord::SetNormalValue()
|
||||
|
@ -231,63 +221,6 @@ nsStyleCoord::GetAngleValueInRadians() const
|
|||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsStyleCoord::CalcHasPercent() const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(IsCalcUnit(), "caller should check IsCalcUnit()");
|
||||
nsStyleCoord::Array *a = GetArrayValue();
|
||||
for (size_t i = 0, i_end = a->Count(); i < i_end; ++i) {
|
||||
const nsStyleCoord &v = a->Item(i);
|
||||
if (v.GetUnit() == eStyleUnit_Percent) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (v.IsCalcUnit() && v.CalcHasPercent()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
inline void*
|
||||
nsStyleCoord::Array::operator new(size_t aSelfSize,
|
||||
nsStyleContext *aAllocationContext,
|
||||
size_t aItemCount) CPP_THROW_NEW
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aItemCount > 0, "cannot have 0 item count");
|
||||
return aAllocationContext->Alloc(
|
||||
aSelfSize + sizeof(nsStyleCoord) * (aItemCount - 1));
|
||||
}
|
||||
|
||||
/* static */ nsStyleCoord::Array*
|
||||
nsStyleCoord::Array::Create(nsStyleContext *aAllocationContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
size_t aCount)
|
||||
{
|
||||
// While it's not ideal that every time we use an array, we force it
|
||||
// not to be stored in the rule tree, it's the easiest option for now.
|
||||
// (This is done only because of the style-context-scoped allocation.)
|
||||
aCanStoreInRuleTree = PR_FALSE;
|
||||
|
||||
return new(aAllocationContext, aCount) Array(aCount);
|
||||
}
|
||||
|
||||
bool
|
||||
nsStyleCoord::Array::operator==(const Array& aOther) const
|
||||
{
|
||||
if (Count() != aOther.Count()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mCount; ++i) {
|
||||
if ((*this)[i] != aOther[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// used by nsStyleSides and nsStyleCorners
|
||||
#define COMPARE_INDEXED_COORD(i) \
|
||||
PR_BEGIN_MACRO \
|
||||
|
|
|
@ -60,24 +60,18 @@ enum nsStyleUnit {
|
|||
eStyleUnit_Coord = 20, // (nscoord) value is twips
|
||||
eStyleUnit_Integer = 30, // (int) value is simple integer
|
||||
eStyleUnit_Enumerated = 32, // (int) value has enumerated meaning
|
||||
// The following are all of the eCSSUnit_Calc_* types. They are weak
|
||||
// pointers to a calc tree allocated by nsStyleContext::Alloc.
|
||||
// NOTE: They are in the same order as the eCSSUnit_Calc_* values so
|
||||
// that converting between the two sets is just addition/subtraction.
|
||||
eStyleUnit_Calc = 39, // (Array*) calc() toplevel, to
|
||||
// distinguish 50% from calc(50%), etc.
|
||||
eStyleUnit_Calc_Plus = 40, // (Array*) + node within calc()
|
||||
eStyleUnit_Calc_Minus = 41, // (Array*) - within calc
|
||||
eStyleUnit_Calc_Times_L = 42, // (Array*) num * val within calc
|
||||
eStyleUnit_Calc_Times_R = 43, // (Array*) val * num within calc
|
||||
eStyleUnit_Calc_Divided = 44 // (Array*) / within calc
|
||||
|
||||
// The following are allocated types. They are weak pointers to
|
||||
// values allocated by nsStyleContext::Alloc.
|
||||
eStyleUnit_Calc = 40 // (Calc*) calc() toplevel; always present
|
||||
// to distinguish 50% from calc(50%), etc.
|
||||
};
|
||||
|
||||
typedef union {
|
||||
PRInt32 mInt; // nscoord is a PRInt32 for now
|
||||
float mFloat;
|
||||
// An mPointer is a weak pointer to a value that is guaranteed to
|
||||
// outlive the nsStyleCoord. In the case of nsStyleCoord::Array*, it
|
||||
// outlive the nsStyleCoord. In the case of nsStyleCoord::Calc*, it
|
||||
// is a pointer owned by the style context, allocated through
|
||||
// nsStyleContext::Alloc (and, therefore, is never stored in the rule
|
||||
// tree).
|
||||
|
@ -94,8 +88,19 @@ typedef union {
|
|||
*/
|
||||
class nsStyleCoord {
|
||||
public:
|
||||
struct Array;
|
||||
friend struct Array;
|
||||
struct Calc {
|
||||
// Every calc() expression evaluates to a length plus a percentage.
|
||||
nscoord mLength;
|
||||
float mPercent;
|
||||
PRPackedBool mHasPercent; // whether there was any % syntax, even if 0
|
||||
|
||||
bool operator==(const Calc& aOther) const {
|
||||
return mLength == aOther.mLength &&
|
||||
mPercent == aOther.mPercent &&
|
||||
mHasPercent == aOther.mHasPercent;
|
||||
}
|
||||
bool operator!=(const Calc& aOther) const { return !(*this == aOther); }
|
||||
};
|
||||
|
||||
nsStyleCoord(nsStyleUnit aUnit = eStyleUnit_Null);
|
||||
enum CoordConstructorType { CoordConstructor };
|
||||
|
@ -119,7 +124,11 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsCalcUnit() const {
|
||||
return eStyleUnit_Calc <= mUnit && mUnit <= eStyleUnit_Calc_Divided;
|
||||
return eStyleUnit_Calc == mUnit;
|
||||
}
|
||||
|
||||
PRBool IsPointerValue() const {
|
||||
return IsCalcUnit();
|
||||
}
|
||||
|
||||
PRBool IsCoordPercentCalcUnit() const {
|
||||
|
@ -130,10 +139,8 @@ public:
|
|||
|
||||
// Does this calc() expression have any percentages inside it? Can be
|
||||
// called only when IsCalcUnit() is true.
|
||||
PRBool CalcHasPercent() const;
|
||||
|
||||
PRBool IsArrayValue() const {
|
||||
return IsCalcUnit();
|
||||
PRBool CalcHasPercent() const {
|
||||
return GetCalcValue()->mHasPercent;
|
||||
}
|
||||
|
||||
PRBool HasPercent() const {
|
||||
|
@ -152,7 +159,7 @@ public:
|
|||
float GetFactorValue() const;
|
||||
float GetAngleValue() const;
|
||||
double GetAngleValueInRadians() const;
|
||||
Array* GetArrayValue() const;
|
||||
Calc* GetCalcValue() const;
|
||||
void GetUnionValue(nsStyleUnion& aValue) const;
|
||||
|
||||
void Reset(); // sets to null
|
||||
|
@ -164,65 +171,13 @@ public:
|
|||
void SetNormalValue();
|
||||
void SetAutoValue();
|
||||
void SetNoneValue();
|
||||
void SetArrayValue(Array* aValue, nsStyleUnit aUnit);
|
||||
void SetCalcValue(Calc* aValue);
|
||||
|
||||
public: // FIXME: private!
|
||||
nsStyleUnit mUnit;
|
||||
nsStyleUnion mValue;
|
||||
};
|
||||
|
||||
// A fixed-size array, that, like everything else in nsStyleCoord,
|
||||
// doesn't require that its destructors be called.
|
||||
struct nsStyleCoord::Array {
|
||||
static Array* Create(nsStyleContext *aAllocationContext,
|
||||
PRBool& aCanStoreInRuleTree,
|
||||
size_t aCount);
|
||||
|
||||
size_t Count() const { return mCount; }
|
||||
|
||||
nsStyleCoord& operator[](size_t aIndex) {
|
||||
NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
|
||||
return mArray[aIndex];
|
||||
}
|
||||
|
||||
const nsStyleCoord& operator[](size_t aIndex) const {
|
||||
NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
|
||||
return mArray[aIndex];
|
||||
}
|
||||
|
||||
// Easier to use with an Array*:
|
||||
nsStyleCoord& Item(size_t aIndex) { return (*this)[aIndex]; }
|
||||
const nsStyleCoord& Item(size_t aIndex) const { return (*this)[aIndex]; }
|
||||
|
||||
bool operator==(const Array& aOther) const;
|
||||
|
||||
bool operator!=(const Array& aOther) const {
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
private:
|
||||
inline void* operator new(size_t aSelfSize,
|
||||
nsStyleContext *aAllocationContext,
|
||||
size_t aItemCount) CPP_THROW_NEW;
|
||||
|
||||
Array(size_t aCount)
|
||||
: mCount(aCount)
|
||||
{
|
||||
// Initialize all entries not in the class.
|
||||
for (size_t i = 1; i < aCount; ++i) {
|
||||
new (mArray + i) nsStyleCoord();
|
||||
}
|
||||
}
|
||||
|
||||
size_t mCount;
|
||||
nsStyleCoord mArray[1]; // for alignment, have the first element in the class
|
||||
|
||||
// not to be implemented
|
||||
Array(const Array& aOther);
|
||||
Array& operator=(const Array& aOther);
|
||||
~Array();
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that represents a set of top/right/bottom/left nsStyleCoords.
|
||||
* This is commonly used to hold the widths of the borders, margins,
|
||||
|
@ -308,7 +263,7 @@ inline nsStyleCoord::nsStyleCoord(const nsStyleCoord& aCopy)
|
|||
if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) {
|
||||
mValue.mFloat = aCopy.mValue.mFloat;
|
||||
}
|
||||
else if (IsArrayValue()) {
|
||||
else if (IsPointerValue()) {
|
||||
mValue.mPointer = aCopy.mValue.mPointer;
|
||||
}
|
||||
else {
|
||||
|
@ -375,11 +330,11 @@ inline float nsStyleCoord::GetAngleValue() const
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
inline nsStyleCoord::Array* nsStyleCoord::GetArrayValue() const
|
||||
inline nsStyleCoord::Calc* nsStyleCoord::GetCalcValue() const
|
||||
{
|
||||
NS_ASSERTION(IsArrayValue(), "not a pointer value");
|
||||
if (IsArrayValue()) {
|
||||
return static_cast<Array*>(mValue.mPointer);
|
||||
NS_ASSERTION(IsCalcUnit(), "not a pointer value");
|
||||
if (IsCalcUnit()) {
|
||||
return static_cast<Calc*>(mValue.mPointer);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
|
|
@ -229,81 +229,6 @@ static nscoord CalcLength(const nsCSSValue &aValue,
|
|||
aCanStoreInRuleTree);
|
||||
}
|
||||
|
||||
struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps
|
||||
{
|
||||
struct result_type {
|
||||
nscoord mLength;
|
||||
float mPercent;
|
||||
|
||||
result_type(nscoord aLength, float aPercent)
|
||||
: mLength(aLength), mPercent(aPercent) {}
|
||||
};
|
||||
|
||||
LengthPercentPairCalcOps(nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
PRBool& aCanStoreInRuleTree)
|
||||
: mContext(aContext),
|
||||
mPresContext(aPresContext),
|
||||
mCanStoreInRuleTree(aCanStoreInRuleTree) {}
|
||||
|
||||
nsStyleContext* mContext;
|
||||
nsPresContext* mPresContext;
|
||||
PRBool& mCanStoreInRuleTree;
|
||||
|
||||
result_type ComputeLeafValue(const nsCSSValue& aValue)
|
||||
{
|
||||
if (aValue.GetUnit() == eCSSUnit_Percent) {
|
||||
return result_type(0, aValue.GetPercentValue());
|
||||
} else {
|
||||
return result_type(CalcLength(aValue, mContext, mPresContext,
|
||||
mCanStoreInRuleTree),
|
||||
0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeAdditive(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, result_type aValue2)
|
||||
{
|
||||
if (aCalcFunction == eCSSUnit_Calc_Plus) {
|
||||
return result_type(NSCoordSaturatingAdd(aValue1.mLength,
|
||||
aValue2.mLength),
|
||||
aValue1.mPercent + aValue2.mPercent);
|
||||
}
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Minus,
|
||||
"min() and max() are not allowed in calc() on "
|
||||
"transform");
|
||||
return result_type(NSCoordSaturatingSubtract(aValue1.mLength,
|
||||
aValue2.mLength, 0),
|
||||
aValue1.mPercent - aValue2.mPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeL(nsCSSUnit aCalcFunction,
|
||||
float aValue1, result_type aValue2)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Times_L,
|
||||
"unexpected unit");
|
||||
return result_type(NSCoordSaturatingMultiply(aValue2.mLength, aValue1),
|
||||
aValue1 * aValue2.mPercent);
|
||||
}
|
||||
|
||||
result_type
|
||||
MergeMultiplicativeR(nsCSSUnit aCalcFunction,
|
||||
result_type aValue1, float aValue2)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aCalcFunction == eCSSUnit_Calc_Times_R ||
|
||||
aCalcFunction == eCSSUnit_Calc_Divided,
|
||||
"unexpected unit");
|
||||
if (aCalcFunction == eCSSUnit_Calc_Divided) {
|
||||
aValue2 = 1.0f / aValue2;
|
||||
}
|
||||
return result_type(NSCoordSaturatingMultiply(aValue1.mLength, aValue2),
|
||||
aValue1.mPercent * aValue2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static void ProcessTranslatePart(nscoord& aOffset, float& aPercent,
|
||||
const nsCSSValue& aValue,
|
||||
nsStyleContext* aContext,
|
||||
|
@ -313,9 +238,9 @@ static void ProcessTranslatePart(nscoord& aOffset, float& aPercent,
|
|||
if (aValue.GetUnit() == eCSSUnit_Percent) {
|
||||
aPercent = aValue.GetPercentValue();
|
||||
} else if (aValue.IsCalcUnit()) {
|
||||
LengthPercentPairCalcOps ops(aContext, aPresContext, aCanStoreInRuleTree);
|
||||
LengthPercentPairCalcOps::result_type result =
|
||||
css::ComputeCalc(aValue, ops);
|
||||
nsRuleNode::ComputedCalc result =
|
||||
nsRuleNode::SpecifiedCalcToComputedCalc(aValue, aContext, aPresContext,
|
||||
aCanStoreInRuleTree);
|
||||
aPercent = result.mPercent;
|
||||
aOffset = result.mLength;
|
||||
} else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче