diff --git a/layout/style/CSSCalc.h b/layout/style/CSSCalc.h index b5499768aa..06a570c731 100644 --- a/layout/style/CSSCalc.h +++ b/layout/style/CSSCalc.h @@ -6,7 +6,6 @@ #include "nsCSSValue.h" #include "nsStyleCoord.h" -#include #include namespace mozilla { @@ -47,13 +46,6 @@ namespace css { * result_type aValue1, float aValue2); * * result_type - * MergeMinMax(nsCSSUnit aCalcFunction, - * result_type aValue1, result_type aValue2); - * - * result_type - * MergeClamp(result_type aMin, result_type aCenter, result_type aMax); - * - * result_type * ComputeLeafValue(const input_type& aValue); * * float @@ -78,8 +70,6 @@ namespace css { * MergeAdditive for Plus and Minus * MergeMultiplicativeL for Times_L (number * value) * MergeMultiplicativeR for Times_R (value * number) and Divided - * MergeMinMax for Min and Max - * MergeClamp for Clamp */ template static typename CalcOps::result_type @@ -114,25 +104,6 @@ ComputeCalc(const typename CalcOps::input_type& aValue, CalcOps &aOps) float rhs = aOps.ComputeNumber(arr->Item(1)); return aOps.MergeMultiplicativeR(CalcOps::GetUnit(aValue), lhs, rhs); } - case eCSSUnit_Calc_Min: - case eCSSUnit_Calc_Max: { - typename CalcOps::input_array_type *arr = aValue.GetArrayValue(); - MOZ_ASSERT(arr->Count() >= 1, "unexpected length"); - typename CalcOps::result_type result = ComputeCalc(arr->Item(0), aOps); - for (uint32_t i = 1; i < arr->Count(); ++i) { - typename CalcOps::result_type next = ComputeCalc(arr->Item(i), aOps); - result = aOps.MergeMinMax(CalcOps::GetUnit(aValue), result, next); - } - return result; - } - case eCSSUnit_Calc_Clamp: { - typename CalcOps::input_array_type *arr = aValue.GetArrayValue(); - MOZ_ASSERT(arr->Count() == 3, "unexpected length"); - typename CalcOps::result_type min = ComputeCalc(arr->Item(0), aOps); - typename CalcOps::result_type center = ComputeCalc(arr->Item(1), aOps); - typename CalcOps::result_type max = ComputeCalc(arr->Item(2), aOps); - return aOps.MergeClamp(min, center, max); - } default: { return aOps.ComputeLeafValue(aValue); } @@ -197,23 +168,6 @@ struct BasicCoordCalcOps } return NSCoordSaturatingMultiply(aValue1, aValue2); } - - result_type - MergeMinMax(nsCSSUnit aCalcFunction, - result_type aValue1, result_type aValue2) - { - if (aCalcFunction == eCSSUnit_Calc_Min) { - return std::min(aValue1, aValue2); - } - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit"); - return std::max(aValue1, aValue2); - } - - result_type - MergeClamp(result_type aMin, result_type aCenter, result_type aMax) - { - return std::max(aMin, std::min(aCenter, aMax)); - } }; struct BasicFloatCalcOps @@ -252,23 +206,6 @@ struct BasicFloatCalcOps "unexpected unit"); return aValue1 / aValue2; } - - result_type - MergeMinMax(nsCSSUnit aCalcFunction, - result_type aValue1, result_type aValue2) - { - if (aCalcFunction == eCSSUnit_Calc_Min) { - return std::min(aValue1, aValue2); - } - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit"); - return std::max(aValue1, aValue2); - } - - result_type - MergeClamp(result_type aMin, result_type aCenter, result_type aMax) - { - return std::max(aMin, std::min(aCenter, aMax)); - } }; /** @@ -318,20 +255,8 @@ template static void SerializeCalc(const typename CalcOps::input_type& aValue, CalcOps &aOps) { - nsCSSUnit unit = CalcOps::GetUnit(aValue); - if (unit == eCSSUnit_Calc) { - const typename CalcOps::input_array_type *array = aValue.GetArrayValue(); - MOZ_ASSERT(array->Count() == 1, "unexpected length"); - nsCSSUnit childUnit = CalcOps::GetUnit(array->Item(0)); - if (childUnit == eCSSUnit_Calc_Min || - childUnit == eCSSUnit_Calc_Max || - childUnit == eCSSUnit_Calc_Clamp) { - SerializeCalcInternal(array->Item(0), aOps); - return; - } - } - aOps.Append("calc("); + nsCSSUnit unit = CalcOps::GetUnit(aValue); if (unit == eCSSUnit_Calc) { const typename CalcOps::input_array_type *array = aValue.GetArrayValue(); MOZ_ASSERT(array->Count() == 1, "unexpected length"); @@ -357,14 +282,6 @@ IsCalcMultiplicativeUnit(nsCSSUnit aUnit) aUnit == eCSSUnit_Calc_Divided; } -static inline bool -IsCalcMinMaxClampUnit(nsCSSUnit aUnit) -{ - return aUnit == eCSSUnit_Calc_Min || - aUnit == eCSSUnit_Calc_Max || - aUnit == eCSSUnit_Calc_Clamp; -} - // Serialize a non-toplevel value in a calc() tree. See big comment // above. template @@ -431,29 +348,6 @@ SerializeCalcInternal(const typename CalcOps::input_type& aValue, CalcOps &aOps) if (needParens) { aOps.Append(")"); } - } else if (IsCalcMinMaxClampUnit(unit)) { - const typename CalcOps::input_array_type *array = aValue.GetArrayValue(); - MOZ_ASSERT(unit != eCSSUnit_Calc_Clamp || array->Count() == 3, - "unexpected length"); - MOZ_ASSERT(unit == eCSSUnit_Calc_Clamp || array->Count() >= 1, - "unexpected length"); - - if (unit == eCSSUnit_Calc_Min) { - aOps.Append("min("); - } else if (unit == eCSSUnit_Calc_Max) { - aOps.Append("max("); - } else { - MOZ_ASSERT(unit == eCSSUnit_Calc_Clamp, "unexpected unit"); - aOps.Append("clamp("); - } - - for (uint32_t i = 0; i < array->Count(); ++i) { - if (i != 0) { - aOps.Append(", "); - } - SerializeCalcInternal(array->Item(i), aOps); - } - aOps.Append(")"); } else { aOps.AppendLeafValue(aValue); } diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 8faddd1871..59872b0f67 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -197,213 +197,11 @@ OKLabToSRGBColor(float aL, float aA, float aB, float aAlpha) float g = mozilla::clamped(LinearSRGBToEncoded(linearG), 0.0f, 1.0f); float b = mozilla::clamped(LinearSRGBToEncoded(linearB), 0.0f, 1.0f); - if (aIdent.LowerCaseEqualsLiteral("-infinity")) { - aValue = -std::numeric_limits::infinity(); - return true; - } - - return false; -} - -static bool -IsCalcNumberFunctionName(const nsAString& aIdent) -{ - return aIdent.LowerCaseEqualsLiteral("min") || - aIdent.LowerCaseEqualsLiteral("max") || - aIdent.LowerCaseEqualsLiteral("clamp"); -} - -static void -WrapCalcNumberValue(nsCSSValue& aValue, float aNumber) -{ - RefPtr arr = nsCSSValue::Array::Create(1); - arr->Item(0).SetFloatValue(aNumber, eCSSUnit_Number); - aValue.SetArrayValue(arr, eCSSUnit_Calc); -} - -static bool -IsFiniteCalcNumber(float aValue) -{ - return !std::isnan(aValue) && !std::isinf(aValue); -} - -static bool -GetCalcLengthTypedArithmeticExponent(const nsCSSValue& aValue, - int32_t& aExponent) -{ - switch (aValue.GetUnit()) { - case eCSSUnit_Calc: { - nsCSSValue::Array* array = aValue.GetArrayValue(); - MOZ_ASSERT(array->Count() == 1, "unexpected length"); - return GetCalcLengthTypedArithmeticExponent(array->Item(0), aExponent); - } - - case eCSSUnit_Calc_Plus: - case eCSSUnit_Calc_Minus: { - nsCSSValue::Array* array = aValue.GetArrayValue(); - MOZ_ASSERT(array->Count() == 2, "unexpected length"); - int32_t lhsExponent; - int32_t rhsExponent; - if (!GetCalcLengthTypedArithmeticExponent(array->Item(0), lhsExponent) || - !GetCalcLengthTypedArithmeticExponent(array->Item(1), rhsExponent) || - lhsExponent != rhsExponent) { - return false; - } - aExponent = lhsExponent; - return true; - } - - case eCSSUnit_Calc_Times_L: - case eCSSUnit_Calc_Times_R: - case eCSSUnit_Calc_Divided: { - nsCSSValue::Array* array = aValue.GetArrayValue(); - MOZ_ASSERT(array->Count() == 2, "unexpected length"); - int32_t lhsExponent; - int32_t rhsExponent; - if (!GetCalcLengthTypedArithmeticExponent(array->Item(0), lhsExponent) || - !GetCalcLengthTypedArithmeticExponent(array->Item(1), rhsExponent)) { - return false; - } - aExponent = aValue.GetUnit() == eCSSUnit_Calc_Divided - ? lhsExponent - rhsExponent - : lhsExponent + rhsExponent; - return true; - } - - case eCSSUnit_Calc_Min: - case eCSSUnit_Calc_Max: - case eCSSUnit_Calc_Clamp: { - nsCSSValue::Array* array = aValue.GetArrayValue(); - MOZ_ASSERT(aValue.GetUnit() != eCSSUnit_Calc_Clamp || - array->Count() == 3, "unexpected length"); - MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Calc_Clamp || - array->Count() >= 1, "unexpected length"); - - int32_t exponent; - if (!GetCalcLengthTypedArithmeticExponent(array->Item(0), exponent)) { - return false; - } - for (uint32_t i = 1; i < array->Count(); ++i) { - int32_t itemExponent; - if (!GetCalcLengthTypedArithmeticExponent(array->Item(i), - itemExponent) || - itemExponent != exponent) { - return false; - } - } - aExponent = exponent; - return true; - } - - case eCSSUnit_Number: - aExponent = 0; - return true; - - default: - break; - } - - if (aValue.IsLengthUnit()) { - aExponent = 1; - return true; - } - - return false; -} - -static bool -NormalizeCalcForVariant(nsCSSValue& aValue, - uint32_t aPropertyVariantMask, - uint32_t aResultVariantMask, - bool aSawSpecialNumericValues = false) -{ - if (ShouldPreserveCalcValue(aPropertyVariantMask)) { - return true; - } - - if (aResultVariantMask == VARIANT_NUMBER) { - ReduceNumberCalcOps ops; - float value = mozilla::css::ComputeCalc(aValue, ops); - - if (aPropertyVariantMask & VARIANT_INTEGER) { - if (!IsFiniteCalcNumber(value)) { - return false; - } - aValue.SetIntValue(RoundFloatToCSSInteger(value), eCSSUnit_Integer); - } else if ((aPropertyVariantMask & VARIANT_OPACITY) && - aSawSpecialNumericValues) { - WrapCalcNumberValue(aValue, value); - } else { - aValue.SetFloatValue(value, eCSSUnit_Number); - } - return true; - } - - if (aResultVariantMask & VARIANT_PERCENT) { - ReducePercentageCalcOps ops; - float value = mozilla::css::ComputeCalc(aValue, ops); - - if (aPropertyVariantMask & VARIANT_OPACITY) { - if (aSawSpecialNumericValues) { - WrapCalcNumberValue(aValue, value); - } else { - aValue.SetFloatValue(value, eCSSUnit_Number); - } - } else { - aValue.SetPercentValue(value); - } - return true; - } - - if (aResultVariantMask & VARIANT_ANGLE) { - ReduceDimensionCalcOps ops(ReduceDimensionCalcOps::DimensionType::Angle); - aValue.SetFloatValue(mozilla::css::ComputeCalc(aValue, ops), eCSSUnit_Degree); - return true; - } - - if (aResultVariantMask & VARIANT_TIME) { - ReduceDimensionCalcOps ops(ReduceDimensionCalcOps::DimensionType::Time); - aValue.SetFloatValue(mozilla::css::ComputeCalc(aValue, ops), eCSSUnit_Seconds); - return true; - } - - if (aResultVariantMask & VARIANT_FREQUENCY) { - ReduceDimensionCalcOps ops(ReduceDimensionCalcOps::DimensionType::Frequency); - aValue.SetFloatValue(mozilla::css::ComputeCalc(aValue, ops), eCSSUnit_Hertz); - return true; - } - - MOZ_ASSERT_UNREACHABLE("unsupported calc result type"); - return false; -} - -static bool -MergeCalcFunctionVariantMask(uint32_t& aMergedMask, uint32_t aItemMask) -{ - MOZ_ASSERT(aItemMask != 0, "unexpected empty item mask"); - if (aMergedMask == 0) { - aMergedMask = aItemMask; - return true; - } - - const bool mergedIsNumber = (aMergedMask & VARIANT_NUMBER) != 0; - const bool itemIsNumber = (aItemMask & VARIANT_NUMBER) != 0; - if (mergedIsNumber || itemIsNumber) { - return mergedIsNumber == itemIsNumber; - } - - const uint32_t lengthPercentMask = VARIANT_LENGTH | VARIANT_PERCENT; - if ((aMergedMask & lengthPercentMask) && (aItemMask & lengthPercentMask)) { - aMergedMask = (aMergedMask | aItemMask) & lengthPercentMask; - return true; - } - - if ((aMergedMask & aItemMask) != 0) { - aMergedMask &= aItemMask; - return true; - } - - return false; + return NS_RGBA( + NSToIntRound(r * 255.0f), + NSToIntRound(g * 255.0f), + NSToIntRound(b * 255.0f), + nsStyleUtil::FloatToColorComponent(mozilla::clamped(aAlpha, 0.0f, 1.0f))); } static_assert(css::eAuthorSheetFeatures == 0 && @@ -1146,8 +944,6 @@ protected: // Property specific parsing routines bool ParseImageLayers(const nsCSSPropertyID aTable[]); - bool ParseAspectRatio(nsCSSValue& aValue); - bool ParseAspectRatioRatio(nsCSSValue& aValue); struct ImageLayersShorthandParseState { nsCSSValue& mColor; @@ -1225,10 +1021,6 @@ protected: uint32_t& aVariantMask, bool *aHadFinalWS); bool ParseCalcTerm(nsCSSValue& aValue, uint32_t& aVariantMask); - bool ParseCalcMinMaxClampFunction(nsCSSValue& aValue, - uint32_t& aVariantMask); - bool ParseCalcNumberExpressionValue(float& aValue); - bool ParseCalcNumberFunction(nsCSSValue& aValue, uint32_t& aVariantMask); bool RequireWhitespace(); // For "flex" shorthand property, defined in CSS Flexbox spec @@ -4053,7 +3845,9 @@ CSSParserImpl::ParseMediaQueryExpression(nsMediaQuery* aQuery) break; } } - if (!feature->mName) { + if (!feature->mName || + (expr->mRange != nsMediaExpression::eEqual && + feature->mRangeType != nsMediaFeature::eMinMaxAllowed)) { REPORT_UNEXPECTED_TOKEN(PEMQExpectedFeatureName); SkipUntil(')'); return false; @@ -4071,52 +3865,13 @@ CSSParserImpl::ParseMediaQueryExpression(nsMediaQuery* aQuery) return true; } - bool usesRangeSyntax = false; - if (mToken.IsSymbol('<') || mToken.IsSymbol('>') || mToken.IsSymbol('=')) { - if (expr->mRange != nsMediaExpression::eEqual) { - REPORT_UNEXPECTED_TOKEN(PEMQExpectedFeatureNameEnd); - UngetToken(); - SkipUntil(')'); - return false; - } - - usesRangeSyntax = true; - char16_t rangeSymbol = mToken.mSymbol; - bool inclusive = rangeSymbol == '='; - - if (rangeSymbol != '=') { - if (!GetToken(true)) { - REPORT_UNEXPECTED_EOF(PEMQExpressionEOF); - return false; - } - if (mToken.IsSymbol('=')) { - inclusive = true; - } else { - UngetToken(); - } - } - - if (rangeSymbol == '>') { - expr->mRange = inclusive ? nsMediaExpression::eMin - : nsMediaExpression::eMinExclusive; - } else if (rangeSymbol == '<') { - expr->mRange = inclusive ? nsMediaExpression::eMax - : nsMediaExpression::eMaxExclusive; - } - } else if (!mToken.IsSymbol(':')) { + if (!mToken.IsSymbol(':')) { REPORT_UNEXPECTED_TOKEN(PEMQExpectedFeatureNameEnd); UngetToken(); SkipUntil(')'); return false; } - if ((expr->mRange != nsMediaExpression::eEqual || usesRangeSyntax) && - feature->mRangeType != nsMediaFeature::eMinMaxAllowed) { - REPORT_UNEXPECTED_TOKEN(PEMQExpectedFeatureName); - SkipUntil(')'); - return false; - } - bool rv = false; switch (feature->mValueType) { case nsMediaFeature::eLength: @@ -13201,59 +12956,6 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSPropertyID aPropID) #define BG_CLR (BG_CENTER | BG_LEFT | BG_RIGHT) #define BG_LR (BG_LEFT | BG_RIGHT) -bool -CSSParserImpl::ParseAspectRatioRatio(nsCSSValue& aValue) -{ - nsCSSValue width; - if (!ParseNonNegativeNumber(width)) { - return false; - } - - float w = width.GetFloatValue(); - float h = 1.0f; - if (ExpectSymbol('/', true)) { - nsCSSValue height; - if (!ParseNonNegativeNumber(height)) { - return false; - } - h = height.GetFloatValue(); - } - - // Degenerate ratios behave as auto in layout. - aValue.SetFloatValue(w == 0.0f || h == 0.0f ? 0.0f : w / h, - eCSSUnit_Number); - return true; -} - -bool -CSSParserImpl::ParseAspectRatio(nsCSSValue& aValue) -{ - if (ParseSingleTokenVariant(aValue, VARIANT_INHERIT, nullptr)) { - return true; - } - - nsCSSValue autoValue; - bool hasAuto = ParseSingleTokenVariant(autoValue, VARIANT_AUTO, nullptr); - - nsCSSValue ratioValue; - bool hasRatio = ParseAspectRatioRatio(ratioValue); - if (!hasAuto && !hasRatio) { - return false; - } - - if (hasRatio) { - if (!hasAuto) { - // The grammar is "auto || ", so auto may appear after the ratio. - ParseSingleTokenVariant(autoValue, VARIANT_AUTO, nullptr); - } - aValue = ratioValue; - return true; - } - - aValue.SetAutoValue(); - return true; -} - CSSParseResult CSSParserImpl::ParseBoxProperty(nsCSSValue& aValue, nsCSSPropertyID aPropID) @@ -13292,8 +12994,6 @@ CSSParserImpl::ParseSingleValuePropertyByFunction(nsCSSValue& aValue, switch (aPropID) { case eCSSProperty_clip_path: return ParseClipPath(aValue); - case eCSSProperty_aspect_ratio: - return ParseAspectRatio(aValue); case eCSSProperty_contain: return ParseContain(aValue); case eCSSProperty_font_family: @@ -13637,8 +13337,7 @@ CSSParserImpl::IsCalcFunctionToken(const nsCSSToken& aToken) const { return aToken.mType == eCSSToken_Function && (aToken.mIdent.LowerCaseEqualsLiteral("calc") || - aToken.mIdent.LowerCaseEqualsLiteral("-moz-calc") || - IsCalcNumberFunctionName(aToken.mIdent)); + aToken.mIdent.LowerCaseEqualsLiteral("-moz-calc")); } // Parse one item of the background shorthand property. @@ -14977,39 +14676,11 @@ CSSParserImpl::ParseCalc(nsCSSValue &aValue, uint32_t aVariantMask) // The toplevel of a calc() is always an nsCSSValue::Array of length 1. RefPtr arr = nsCSSValue::Array::Create(1); - const bool isMinMaxClamp = - mToken.mType == eCSSToken_Function && - IsCalcNumberFunctionName(mToken.mIdent); - if (isMinMaxClamp) { - if (!ParseCalcMinMaxClampFunction(arr->Item(0), resultVariantMask)) { - break; - } - } else if (!ParseCalcAdditiveExpression(arr->Item(0), resultVariantMask)) { + if (!ParseCalcAdditiveExpression(arr->Item(0), aVariantMask)) break; - } - if (mCalcAllowsTypedArithmetic) { - int32_t exponent; - if (!GetCalcLengthTypedArithmeticExponent(arr->Item(0), exponent)) { - break; - } - - if (aVariantMask & VARIANT_NUMBER) { - if (exponent == 0) { - resultVariantMask = VARIANT_NUMBER; - } else if (exponent == 1) { - resultVariantMask &= ~int32_t(VARIANT_NUMBER); - } else { - break; - } - } else if (exponent != 1) { - break; - } - } - - if (!isMinMaxClamp && !ExpectSymbol(')', true)) { + if (!ExpectSymbol(')', true)) break; - } aValue.SetArrayValue(arr, eCSSUnit_Calc); mUnitlessLengthQuirk = oldUnitlessLengthQuirk; @@ -15183,14 +14854,6 @@ CSSParserImpl::ParseCalcTerm(nsCSSValue& aValue, uint32_t& aVariantMask) MOZ_ASSERT(aVariantMask != 0, "unexpected variant mask"); if (!GetToken(true)) return false; - if (mToken.mType == eCSSToken_Function && - IsCalcNumberFunctionName(mToken.mIdent)) { - if (!ParseCalcMinMaxClampFunction(aValue, aVariantMask)) { - SkipUntil(')'); - return false; - } - return true; - } // Either an additive expression in parentheses... if (mToken.IsSymbol('(') || // Treat nested calc() as plain parenthesis. @@ -15202,16 +14865,6 @@ CSSParserImpl::ParseCalcTerm(nsCSSValue& aValue, uint32_t& aVariantMask) } return true; } - if ((aVariantMask & VARIANT_NUMBER) != 0 && - mToken.mType == eCSSToken_Ident) { - float specialValue; - if (IsCalcSpecialNumberIdent(mToken.mIdent, specialValue)) { - mCalcHasSpecialNumericValues = true; - aValue.SetFloatValue(specialValue, eCSSUnit_Number); - aVariantMask = VARIANT_NUMBER; - return true; - } - } // ... or just a value UngetToken(); // Always pass VARIANT_NUMBER to ParseVariant so that unitless zero @@ -15236,139 +14889,6 @@ CSSParserImpl::ParseCalcTerm(nsCSSValue& aValue, uint32_t& aVariantMask) return true; } -bool -CSSParserImpl::ParseCalcMinMaxClampFunction(nsCSSValue& aValue, - uint32_t& aVariantMask) -{ - MOZ_ASSERT(mToken.mType == eCSSToken_Function, "expected function token"); - MOZ_ASSERT(IsCalcNumberFunctionName(mToken.mIdent), - "unexpected calc() math function"); - - nsCSSUnit unit; - if (mToken.mIdent.LowerCaseEqualsLiteral("min")) { - unit = eCSSUnit_Calc_Min; - } else if (mToken.mIdent.LowerCaseEqualsLiteral("max")) { - unit = eCSSUnit_Calc_Max; - } else { - MOZ_ASSERT(mToken.mIdent.LowerCaseEqualsLiteral("clamp"), - "unexpected calc() math function"); - unit = eCSSUnit_Calc_Clamp; - } - - AutoTArray arguments; - uint32_t mergedVariantMask = 0; - - for (;;) { - nsCSSValue* argument = arguments.AppendElement(); - uint32_t argumentVariantMask = aVariantMask; - if (!ParseCalcAdditiveExpression(*argument, argumentVariantMask) || - !MergeCalcFunctionVariantMask(mergedVariantMask, - argumentVariantMask)) { - return false; - } - - if (!ExpectSymbol(',', true)) { - break; - } - } - - const uint32_t argumentCount = arguments.Length(); - if ((unit == eCSSUnit_Calc_Clamp && argumentCount != 3) || - (unit != eCSSUnit_Calc_Clamp && argumentCount == 0) || - !ExpectSymbol(')', true)) { - return false; - } - - if (unit != eCSSUnit_Calc_Clamp && argumentCount == 1) { - aValue = arguments[0]; - } else { - RefPtr array = nsCSSValue::Array::Create(argumentCount); - for (uint32_t i = 0; i < argumentCount; ++i) { - array->Item(i) = arguments[i]; - } - aValue.SetArrayValue(array, unit); - } - - aVariantMask = mergedVariantMask; - return true; -} - -bool -CSSParserImpl::ParseCalcNumberExpressionValue(float& aValue) -{ - nsCSSValue expression; - uint32_t variantMask = VARIANT_NUMBER; - if (!ParseCalcAdditiveExpression(expression, variantMask) || - variantMask != VARIANT_NUMBER) { - return false; - } - - ReduceNumberCalcOps ops; - aValue = mozilla::css::ComputeCalc(expression, ops); - return true; -} - -bool -CSSParserImpl::ParseCalcNumberFunction(nsCSSValue& aValue, - uint32_t& aVariantMask) -{ - MOZ_ASSERT(mToken.mType == eCSSToken_Function, "expected function token"); - MOZ_ASSERT(IsCalcNumberFunctionName(mToken.mIdent), - "unexpected calc() number function"); - - float result; - - if (mToken.mIdent.LowerCaseEqualsLiteral("clamp")) { - float minValue; - float centerValue; - float maxValue; - if (!ParseCalcNumberExpressionValue(minValue) || - !ExpectSymbol(',', true) || - !ParseCalcNumberExpressionValue(centerValue) || - !ExpectSymbol(',', true) || - !ParseCalcNumberExpressionValue(maxValue) || - !ExpectSymbol(')', true)) { - return false; - } - - if (std::isnan(minValue) || std::isnan(centerValue) || - std::isnan(maxValue)) { - result = std::numeric_limits::quiet_NaN(); - } else { - result = std::max(minValue, std::min(centerValue, maxValue)); - } - } else { - const bool isMax = mToken.mIdent.LowerCaseEqualsLiteral("max"); - bool sawComma = false; - - if (!ParseCalcNumberExpressionValue(result)) { - return false; - } - - while (ExpectSymbol(',', true)) { - sawComma = true; - float candidate; - if (!ParseCalcNumberExpressionValue(candidate)) { - return false; - } - if (std::isnan(result) || std::isnan(candidate)) { - result = std::numeric_limits::quiet_NaN(); - } else { - result = isMax ? std::max(result, candidate) - : std::min(result, candidate); - } - } - - if (!sawComma || !ExpectSymbol(')', true)) { - return false; - } - } - - aValue.SetFloatValue(result, eCSSUnit_Number); - aVariantMask = VARIANT_NUMBER; - return true; -} - // This function consumes all consecutive whitespace and returns whether // there was any. bool diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index c5fa6ccd19..1e43377460 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -1473,11 +1473,9 @@ nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult, aResult.Append(')'); } else if (IsCalcUnit()) { - if (!AppendNormalizedLengthPercentCalcToString(*this, aProperty, aResult, - aSerialization)) { - CSSValueSerializeCalcOps ops(aProperty, aResult, aSerialization); - css::SerializeCalc(*this, ops); - } + MOZ_ASSERT(GetUnit() == eCSSUnit_Calc, "unexpected unit"); + CSSValueSerializeCalcOps ops(aProperty, aResult, aSerialization); + css::SerializeCalc(*this, ops); } else if (eCSSUnit_Integer == unit) { aResult.AppendInt(GetIntValue(), 10); @@ -2039,9 +2037,6 @@ nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult, case eCSSUnit_Calc_Times_L: break; case eCSSUnit_Calc_Times_R: break; case eCSSUnit_Calc_Divided: break; - case eCSSUnit_Calc_Min: break; - case eCSSUnit_Calc_Max: break; - case eCSSUnit_Calc_Clamp: break; case eCSSUnit_Integer: break; case eCSSUnit_Enumerated: break; case eCSSUnit_EnumColor: break; @@ -2172,9 +2167,6 @@ nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const case eCSSUnit_Calc_Times_L: case eCSSUnit_Calc_Times_R: case eCSSUnit_Calc_Divided: - case eCSSUnit_Calc_Min: - case eCSSUnit_Calc_Max: - case eCSSUnit_Calc_Clamp: break; // URL diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 7665b1eb58..780f62c1e9 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -701,30 +701,6 @@ static inline nscoord CalcLength(const nsCSSValue& aValue, aPresContext, aConditions); } -static inline nscoord -CalcLengthTowardZero(const nsCSSValue& aValue, - nsStyleContext* aStyleContext, - nsPresContext* aPresContext, - RuleNodeCacheConditions& aConditions) -{ - NS_ASSERTION(aStyleContext, "Must have style data"); - - return CalcLengthWith(aValue, -1, nullptr, - aStyleContext, aPresContext, - false, true, aConditions, - AppUnitRounding::TowardZero); -} - -already_AddRefed -nsRuleNode::ComputedCalc::ToCalcNode() const -{ - if (mNode) { - RefPtr node = mNode; - return node.forget(); - } - return nsStyleCoord::CalcNode::CreateLeaf(mLength, mPercent, mHasPercent); -} - /* static */ nscoord nsRuleNode::CalcLengthWithInitialFont(nsPresContext* aPresContext, const nsCSSValue& aValue) @@ -757,42 +733,27 @@ struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps { if (aValue.GetUnit() == eCSSUnit_Percent) { mHasPercent = true; - return result_type(0, aValue.GetPercentValue(), true); + return result_type(0, aValue.GetPercentValue()); } return result_type(CalcLength(aValue, mContext, mPresContext, mConditions), - 0.0f, false); + 0.0f); } result_type MergeAdditive(nsCSSUnit aCalcFunction, result_type aValue1, result_type aValue2) { - if (aValue1.HasNode() || aValue2.HasNode()) { - RefPtr node = - nsStyleCoord::CalcNode::Create( - aCalcFunction == eCSSUnit_Calc_Plus - ? nsStyleCoord::CalcNode::Type::Add - : nsStyleCoord::CalcNode::Type::Subtract); - node->mChildren.AppendElement(aValue1.ToCalcNode()); - node->mChildren.AppendElement(aValue2.ToCalcNode()); - node->mHasPercent = node->HasPercent(); - mHasPercent = mHasPercent || node->mHasPercent; - return result_type(node.forget()); - } - if (aCalcFunction == eCSSUnit_Calc_Plus) { return result_type(NSCoordSaturatingAdd(aValue1.mLength, aValue2.mLength), - aValue1.mPercent + aValue2.mPercent, - aValue1.mHasPercent || aValue2.mHasPercent); + aValue1.mPercent + aValue2.mPercent); } MOZ_ASSERT(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, - aValue1.mHasPercent || aValue2.mHasPercent); + aValue1.mPercent - aValue2.mPercent); } result_type @@ -801,19 +762,8 @@ struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps { MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_L, "unexpected unit"); - if (aValue2.HasNode()) { - RefPtr node = - nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Multiply); - node->mChildren.AppendElement(aValue2.ToCalcNode()); - node->mNumber = aValue1; - node->mHasPercent = node->HasPercent(); - mHasPercent = mHasPercent || node->mHasPercent; - return result_type(node.forget()); - } - return result_type(NSCoordSaturatingMultiply(aValue2.mLength, aValue1), - aValue1 * aValue2.mPercent, - aValue2.mHasPercent); + aValue1 * aValue2.mPercent); } result_type @@ -824,89 +774,10 @@ struct LengthPercentPairCalcOps : public css::NumbersAlreadyNormalizedOps aCalcFunction == eCSSUnit_Calc_Divided, "unexpected unit"); if (aCalcFunction == eCSSUnit_Calc_Divided) { - if (aValue1.HasNode()) { - RefPtr node = - nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Divide); - node->mChildren.AppendElement(aValue1.ToCalcNode()); - node->mNumber = aValue2; - node->mHasPercent = node->HasPercent(); - mHasPercent = mHasPercent || node->mHasPercent; - return result_type(node.forget()); - } aValue2 = 1.0f / aValue2; - } else if (aValue1.HasNode()) { - RefPtr node = - nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Multiply); - node->mChildren.AppendElement(aValue1.ToCalcNode()); - node->mNumber = aValue2; - node->mHasPercent = node->HasPercent(); - mHasPercent = mHasPercent || node->mHasPercent; - return result_type(node.forget()); } return result_type(NSCoordSaturatingMultiply(aValue1.mLength, aValue2), - aValue1.mPercent * aValue2, - aValue1.mHasPercent); - } - - result_type - MergeMinMax(nsCSSUnit aCalcFunction, - result_type aValue1, result_type aValue2) - { - const bool hasNode = aValue1.HasNode() || aValue2.HasNode(); - const bool hasPercent = aValue1.mHasPercent || aValue2.mHasPercent; - if (!hasNode && !hasPercent) { - if (aCalcFunction == eCSSUnit_Calc_Min) { - return result_type(std::min(aValue1.mLength, aValue2.mLength), - 0.0f, false); - } - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit"); - return result_type(std::max(aValue1.mLength, aValue2.mLength), - 0.0f, false); - } - - RefPtr node = - nsStyleCoord::CalcNode::Create( - aCalcFunction == eCSSUnit_Calc_Min - ? nsStyleCoord::CalcNode::Type::Min - : nsStyleCoord::CalcNode::Type::Max); - if (aValue1.HasNode() && - aValue1.mNode->mType == node->mType) { - node->mChildren.AppendElements(aValue1.mNode->mChildren); - } else { - node->mChildren.AppendElement(aValue1.ToCalcNode()); - } - if (aValue2.HasNode() && - aValue2.mNode->mType == node->mType) { - node->mChildren.AppendElements(aValue2.mNode->mChildren); - } else { - node->mChildren.AppendElement(aValue2.ToCalcNode()); - } - node->mHasPercent = node->HasPercent(); - mHasPercent = mHasPercent || node->mHasPercent; - return result_type(node.forget()); - } - - result_type - MergeClamp(result_type aMin, result_type aCenter, result_type aMax) - { - const bool hasNode = aMin.HasNode() || aCenter.HasNode() || aMax.HasNode(); - const bool hasPercent = aMin.mHasPercent || - aCenter.mHasPercent || - aMax.mHasPercent; - if (!hasNode && !hasPercent) { - return result_type(std::max(aMin.mLength, - std::min(aCenter.mLength, aMax.mLength)), - 0.0f, false); - } - - RefPtr node = - nsStyleCoord::CalcNode::Create(nsStyleCoord::CalcNode::Type::Clamp); - node->mChildren.AppendElement(aMin.ToCalcNode()); - node->mChildren.AppendElement(aCenter.ToCalcNode()); - node->mChildren.AppendElement(aMax.ToCalcNode()); - node->mHasPercent = node->HasPercent(); - mHasPercent = mHasPercent || node->mHasPercent; - return result_type(node.forget()); + aValue1.mPercent * aValue2); } }; @@ -924,8 +795,7 @@ SpecifiedCalcToComputedCalc(const nsCSSValue& aValue, nsStyleCoord& aCoord, calcObj->mLength = vals.mLength; calcObj->mPercent = vals.mPercent; - calcObj->mHasPercent = vals.mHasPercent || ops.mHasPercent; - calcObj->mNode = vals.mNode; + calcObj->mHasPercent = ops.mHasPercent; aCoord.SetCalcValue(calcObj); } @@ -948,7 +818,8 @@ nsRuleNode::ComputeComputedCalc(const nsStyleCoord& aValue, nscoord aPercentageBasis) { nsStyleCoord::Calc* calc = aValue.GetCalcValue(); - return calc->Resolve(aPercentageBasis); + return calc->mLength + + NSToCoordFloorClamped(aPercentageBasis * calc->mPercent); } /* static */ nscoord @@ -4926,34 +4797,6 @@ struct LengthNumberCalcOps : public css::NumbersAlreadyNormalizedOps return result; } - result_type - MergeMinMax(nsCSSUnit aCalcFunction, - result_type aValue1, result_type aValue2) - { - MOZ_ASSERT(aValue1.mIsNumber == aValue2.mIsNumber); - LengthNumberCalcObj result; - result.mIsNumber = aValue1.mIsNumber; - if (aCalcFunction == eCSSUnit_Calc_Min) { - result.mValue = std::min(aValue1.mValue, aValue2.mValue); - return result; - } - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit"); - result.mValue = std::max(aValue1.mValue, aValue2.mValue); - return result; - } - - result_type - MergeClamp(result_type aMin, result_type aCenter, result_type aMax) - { - MOZ_ASSERT(aMin.mIsNumber == aCenter.mIsNumber && - aCenter.mIsNumber == aMax.mIsNumber); - LengthNumberCalcObj result; - result.mIsNumber = aCenter.mIsNumber; - result.mValue = std::max(aMin.mValue, - std::min(aCenter.mValue, aMax.mValue)); - return result; - } - result_type ComputeLeafValue(const nsCSSValue& aValue) { LengthNumberCalcObj result; @@ -5044,38 +4887,6 @@ struct LengthPercentNumberCalcOps : public css::NumbersAlreadyNormalizedOps return result; } - result_type - MergeMinMax(nsCSSUnit aCalcFunction, - result_type aValue1, result_type aValue2) - { - MOZ_ASSERT(aValue1.mIsNumber == aValue2.mIsNumber); - result_type result; - result.mIsNumber = aValue1.mIsNumber; - if (aCalcFunction == eCSSUnit_Calc_Min) { - result.mLength = std::min(aValue1.mLength, aValue2.mLength); - result.mPercent = std::min(aValue1.mPercent, aValue2.mPercent); - } else { - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Max, "unexpected unit"); - result.mLength = std::max(aValue1.mLength, aValue2.mLength); - result.mPercent = std::max(aValue1.mPercent, aValue2.mPercent); - } - return result; - } - - result_type - MergeClamp(result_type aMin, result_type aCenter, result_type aMax) - { - MOZ_ASSERT(aMin.mIsNumber == aCenter.mIsNumber && - aCenter.mIsNumber == aMax.mIsNumber); - result_type result; - result.mIsNumber = aCenter.mIsNumber; - result.mLength = std::max(aMin.mLength, - std::min(aCenter.mLength, aMax.mLength)); - result.mPercent = std::max(aMin.mPercent, - std::min(aCenter.mPercent, aMax.mPercent)); - return result; - } - result_type ComputeLeafValue(const nsCSSValue& aValue) { @@ -9171,16 +8982,11 @@ nsRuleNode::ComputePositionData(void* aStartStruct, SETCOORD_UNSET_INITIAL, aContext, mPresContext, conditions); - // aspect-ratio: auto | - const nsCSSValue* aspectRatio = aRuleData->ValueForAspectRatio(); - if (aspectRatio->GetUnit() == eCSSUnit_Auto) { - pos->mAspectRatio = 0.0f; - } else { - SetFactor(*aspectRatio, - pos->mAspectRatio, conditions, - parentPos->mAspectRatio, 0.0f, - SETFCT_UNSET_INITIAL | SETFCT_POSITIVE | SETFCT_NONE); - } + // aspect-ratio: float, initial + SetFactor(*aRuleData->ValueForAspectRatio(), + pos->mAspectRatio, conditions, + parentPos->mAspectRatio, 0.0f, + SETFCT_UNSET_INITIAL | SETFCT_POSITIVE | SETFCT_NONE); // box-sizing: enum, inherit, initial SetValue(*aRuleData->ValueForBoxSizing(),