From 8c5331160efa157bac380e6e60259b47018080d6 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 5 Apr 2018 18:27:33 +1000 Subject: [PATCH] Bug 1448763 part 8 - Remove CSSCalc.h. r=emilio MozReview-Commit-ID: eecZRhdxH8 --HG-- extra : rebase_source : a25a8d4de1916a92ff736303848daf259a9b265c --- layout/style/CSSCalc.h | 436 ------------------------------------ layout/style/nsCSSValue.cpp | 1 - 2 files changed, 437 deletions(-) delete mode 100644 layout/style/CSSCalc.h diff --git a/layout/style/CSSCalc.h b/layout/style/CSSCalc.h deleted file mode 100644 index 73f9287d2b7c..000000000000 --- a/layout/style/CSSCalc.h +++ /dev/null @@ -1,436 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef CSSCalc_h_ -#define CSSCalc_h_ - -#include "nsCSSValue.h" -#include "nsStyleCoord.h" -#include -#include - -namespace mozilla { - -namespace css { - -/** - * ComputeCalc computes the result of a calc() expression tree. - * - * It is templatized over a CalcOps class that is expected to provide: - * - * // input_type and input_array_type have a bunch of very specific - * // expectations (which happen to be met by two classes (nsCSSValue - * // and nsStyleCoord). There must be methods (roughly): - * // input_array_type* input_type::GetArrayValue(); - * // uint32_t input_array_type::Count() const; - * // input_type& input_array_type::Item(uint32_t); - * typedef ... input_type; - * typedef ... input_array_type; - * - * typedef ... coeff_type; - * - * typedef ... result_type; - * - * // GetUnit(avalue) must return the correct nsCSSUnit for any - * // value that represents a calc tree node (eCSSUnit_Calc*). For - * // other nodes, it may return any non eCSSUnit_Calc* unit. - * static nsCSSUnit GetUnit(const input_type& aValue); - * - * result_type - * MergeAdditive(nsCSSUnit aCalcFunction, - * result_type aValue1, result_type aValue2); - * - * result_type - * MergeMultiplicativeL(nsCSSUnit aCalcFunction, - * coeff_type aValue1, result_type aValue2); - * - * result_type - * MergeMultiplicativeR(nsCSSUnit aCalcFunction, - * result_type aValue1, coeff_type aValue2); - * - * bool - * ComputeLeafValue(result_type& aResult, const input_type& aValue); - * - * coeff_type - * ComputeCoefficient(const coeff_type& aValue); - * - * The CalcOps methods might compute the calc() expression down to a - * number, reduce some parts of it to a number but replicate other - * parts, or produce a tree with a different data structure (for - * example, nsCSS* for specified values vs nsStyle* for computed - * values). - * - * For each leaf in the calc() expression, ComputeCalc will call either - * ComputeCoefficient (when the leaf is the left side of a Times_L or the - * right side of a Times_R or Divided) or ComputeLeafValue (otherwise). - * (The CalcOps in the CSS parser that reduces purely numeric - * expressions in turn calls ComputeCalc on numbers; other ops can - * presume that expressions in the coefficient positions have already been - * normalized to a single numeric value and derive from, if their coefficient - * types are floats, FloatCoeffsAlreadyNormalizedCalcOps.) - * - * ComputeCalc will fail and return false if ComputeLeafValue returns false at - * any point during the computation. ComputeLeafValue shall return false if and - * only if an unexpected (i.e., inconsistent) unit is encountered. - * - * coeff_type will be float most of the time, but it's templatized so that - * ParseCalc can be used with s too. - * - * For non-leaves, one of the Merge functions will be called: - * MergeAdditive for Plus and Minus - * MergeMultiplicativeL for Times_L (coeff * value) - * MergeMultiplicativeR for Times_R (value * coeff) and Divided - */ -template -static bool -ComputeCalc(typename CalcOps::result_type& aResult, - const typename CalcOps::input_type& aValue, CalcOps &aOps) -{ - switch (CalcOps::GetUnit(aValue)) { - case eCSSUnit_Calc: { - typename CalcOps::input_array_type *arr = aValue.GetArrayValue(); - MOZ_ASSERT(arr->Count() == 1, "unexpected length"); - return ComputeCalc(aResult, arr->Item(0), aOps); - } - case eCSSUnit_Calc_Plus: - case eCSSUnit_Calc_Minus: { - typename CalcOps::input_array_type *arr = aValue.GetArrayValue(); - MOZ_ASSERT(arr->Count() == 2, "unexpected length"); - typename CalcOps::result_type lhs, rhs; - if (!ComputeCalc(lhs, arr->Item(0), aOps) || - !ComputeCalc(rhs, arr->Item(1), aOps)) { - return false; - } - aResult = aOps.MergeAdditive(CalcOps::GetUnit(aValue), lhs, rhs); - return true; - } - case eCSSUnit_Calc_Times_L: { - typename CalcOps::input_array_type *arr = aValue.GetArrayValue(); - MOZ_ASSERT(arr->Count() == 2, "unexpected length"); - typename CalcOps::coeff_type lhs = aOps.ComputeCoefficient(arr->Item(0)); - typename CalcOps::result_type rhs; - if (!ComputeCalc(rhs, arr->Item(1), aOps)) { - return false; - } - aResult = aOps.MergeMultiplicativeL(CalcOps::GetUnit(aValue), lhs, rhs); - return true; - } - case eCSSUnit_Calc_Times_R: - case eCSSUnit_Calc_Divided: { - typename CalcOps::input_array_type *arr = aValue.GetArrayValue(); - MOZ_ASSERT(arr->Count() == 2, "unexpected length"); - typename CalcOps::result_type lhs; - if (!ComputeCalc(lhs, arr->Item(0), aOps)) { - return false; - } - typename CalcOps::coeff_type rhs = aOps.ComputeCoefficient(arr->Item(1)); - aResult = aOps.MergeMultiplicativeR(CalcOps::GetUnit(aValue), lhs, rhs); - return true; - } - default: { - return aOps.ComputeLeafValue(aResult, aValue); - } - } -} - -/** - * The input unit operation for input_type being nsCSSValue. - */ -struct CSSValueInputCalcOps -{ - typedef nsCSSValue input_type; - typedef nsCSSValue::Array input_array_type; - - static nsCSSUnit GetUnit(const nsCSSValue& aValue) - { - return aValue.GetUnit(); - } - -}; - -/** - * Basic*CalcOps provide a partial implementation of the CalcOps - * template parameter to ComputeCalc, for those callers whose merging - * just consists of mathematics (rather than tree construction). - */ - -struct BasicCoordCalcOps -{ - typedef nscoord result_type; - typedef float coeff_type; - - result_type - MergeAdditive(nsCSSUnit aCalcFunction, - result_type aValue1, result_type aValue2) - { - if (aCalcFunction == eCSSUnit_Calc_Plus) { - return NSCoordSaturatingAdd(aValue1, aValue2); - } - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Minus, - "unexpected unit"); - return NSCoordSaturatingSubtract(aValue1, aValue2, 0); - } - - result_type - MergeMultiplicativeL(nsCSSUnit aCalcFunction, - coeff_type aValue1, result_type aValue2) - { - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_L, - "unexpected unit"); - return NSCoordSaturatingMultiply(aValue2, aValue1); - } - - result_type - MergeMultiplicativeR(nsCSSUnit aCalcFunction, - result_type aValue1, coeff_type aValue2) - { - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_R || - aCalcFunction == eCSSUnit_Calc_Divided, - "unexpected unit"); - if (aCalcFunction == eCSSUnit_Calc_Divided) { - aValue2 = 1.0f / aValue2; - } - return NSCoordSaturatingMultiply(aValue1, aValue2); - } -}; - -/** - * A ComputeCoefficient implementation for callers that can assume coefficients - * are floats and are already normalized (i.e., anything past the parser except - * pure-integer calcs, whose coefficients are integers). - */ -struct FloatCoeffsAlreadyNormalizedOps : public CSSValueInputCalcOps -{ - typedef float coeff_type; - - coeff_type ComputeCoefficient(const nsCSSValue& aValue) - { - MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit"); - return aValue.GetFloatValue(); - } -}; - -/** - * SerializeCalc appends the serialization of aValue to a string. - * - * It is templatized over a CalcOps class that is expected to provide: - * - * // input_type and input_array_type have a bunch of very specific - * // expectations (which happen to be met by two classes (nsCSSValue - * // and nsStyleCoord). There must be methods (roughly): - * // input_array_type* input_type::GetArrayValue(); - * // uint32_t input_array_type::Count() const; - * // input_type& input_array_type::Item(uint32_t); - * typedef ... input_type; - * typedef ... input_array_type; - * - * static nsCSSUnit GetUnit(const input_type& aValue); - * - * void Append(const char* aString); - * void AppendLeafValue(const input_type& aValue); - * - * // AppendCoefficient accepts an input_type value, which represents a - * // value in the coefficient position, not a value of coeff_type, - * // because we're serializing the calc() expression itself. - * void AppendCoefficient(const input_type& aValue); - * - * Data structures given may or may not have a toplevel eCSSUnit_Calc - * node representing a calc whose toplevel is not min() or max(). - */ - -template -static void -SerializeCalcInternal(const typename CalcOps::input_type& aValue, CalcOps &aOps); - -// Serialize the toplevel value in a calc() tree. See big comment -// above. -template -static void -SerializeCalc(const typename CalcOps::input_type& aValue, CalcOps &aOps) -{ - 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"); - SerializeCalcInternal(array->Item(0), aOps); - } else { - SerializeCalcInternal(aValue, aOps); - } - aOps.Append(")"); -} - -static inline bool -IsCalcAdditiveUnit(nsCSSUnit aUnit) -{ - return aUnit == eCSSUnit_Calc_Plus || - aUnit == eCSSUnit_Calc_Minus; -} - -static inline bool -IsCalcMultiplicativeUnit(nsCSSUnit aUnit) -{ - return aUnit == eCSSUnit_Calc_Times_L || - aUnit == eCSSUnit_Calc_Times_R || - aUnit == eCSSUnit_Calc_Divided; -} - -// Serialize a non-toplevel value in a calc() tree. See big comment -// above. -template -/* static */ void -SerializeCalcInternal(const typename CalcOps::input_type& aValue, CalcOps &aOps) -{ - nsCSSUnit unit = CalcOps::GetUnit(aValue); - if (IsCalcAdditiveUnit(unit)) { - const typename CalcOps::input_array_type *array = aValue.GetArrayValue(); - MOZ_ASSERT(array->Count() == 2, "unexpected length"); - - SerializeCalcInternal(array->Item(0), aOps); - - if (eCSSUnit_Calc_Plus == unit) { - aOps.Append(" + "); - } else { - MOZ_ASSERT(eCSSUnit_Calc_Minus == unit, "unexpected unit"); - aOps.Append(" - "); - } - - bool needParens = IsCalcAdditiveUnit(CalcOps::GetUnit(array->Item(1))); - if (needParens) { - aOps.Append("("); - } - SerializeCalcInternal(array->Item(1), aOps); - if (needParens) { - aOps.Append(")"); - } - } else if (IsCalcMultiplicativeUnit(unit)) { - const typename CalcOps::input_array_type *array = aValue.GetArrayValue(); - MOZ_ASSERT(array->Count() == 2, "unexpected length"); - - bool needParens = IsCalcAdditiveUnit(CalcOps::GetUnit(array->Item(0))); - if (needParens) { - aOps.Append("("); - } - if (unit == eCSSUnit_Calc_Times_L) { - aOps.AppendCoefficient(array->Item(0)); - } else { - SerializeCalcInternal(array->Item(0), aOps); - } - if (needParens) { - aOps.Append(")"); - } - - if (eCSSUnit_Calc_Times_L == unit || eCSSUnit_Calc_Times_R == unit) { - aOps.Append(" * "); - } else { - MOZ_ASSERT(eCSSUnit_Calc_Divided == unit, "unexpected unit"); - aOps.Append(" / "); - } - - nsCSSUnit subUnit = CalcOps::GetUnit(array->Item(1)); - needParens = IsCalcAdditiveUnit(subUnit) || - IsCalcMultiplicativeUnit(subUnit); - if (needParens) { - aOps.Append("("); - } - if (unit == eCSSUnit_Calc_Times_L) { - SerializeCalcInternal(array->Item(1), aOps); - } else { - aOps.AppendCoefficient(array->Item(1)); - } - if (needParens) { - aOps.Append(")"); - } - } else { - aOps.AppendLeafValue(aValue); - } -} - -/** - * ReduceCalcOps is a CalcOps implementation for pure-number, pure-percent, and - * pure-integer calc() (sub-)expressions, input as nsCSSValues. - * - * Instantiate with the appropriate coeff/result type and unit, for example: - * ReduceCalcOps - * ReduceCalcOps - * ReduceCalcOps - * - * For example, nsCSSParser::ParseCalcMultiplicativeExpression uses it to - * simplify numeric sub-expressions in order to check for division-by-zero. - */ -template -struct ReduceCalcOps : public mozilla::css::CSSValueInputCalcOps -{ - static_assert((std::is_same::value && unit == eCSSUnit_Integer) || - (std::is_same::value && - (unit == eCSSUnit_Number || unit == eCSSUnit_Percent)), - "ReduceCalcOps: Invalid template arguments: must use " - "int coefficient with eCSSUnit_Integer, or " - "float coefficient with (eCSSUnit_Number or eCSSUnit_Percent)"); - - typedef type result_type; - typedef type coeff_type; - - result_type - MergeAdditive(nsCSSUnit aCalcFunction, - result_type aValue1, result_type aValue2) - { - if (aCalcFunction == eCSSUnit_Calc_Plus) { - return aValue1 + aValue2; - } - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Minus, "unexpected unit"); - return aValue1 - aValue2; - } - - result_type - MergeMultiplicativeL(nsCSSUnit aCalcFunction, - coeff_type aValue1, result_type aValue2) - { - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_L, "unexpected unit"); - return aValue1 * aValue2; - } - - result_type - MergeMultiplicativeR(nsCSSUnit aCalcFunction, - result_type aValue1, coeff_type aValue2) - { - if (aCalcFunction == eCSSUnit_Calc_Times_R) { - return aValue1 * aValue2; - } - MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Divided, "unexpected unit"); - MOZ_ASSERT(unit != eCSSUnit_Integer, - "We should catch and prevent divisions in integer " - "calc()s in the parser"); - return aValue1 / aValue2; - } - - bool ComputeLeafValue(result_type& aResult, const nsCSSValue& aValue) - { - if (aValue.GetUnit() != unit) { - return false; - } - aResult = unit == eCSSUnit_Percent ? aValue.GetPercentValue() : - unit == eCSSUnit_Integer ? aValue.GetIntValue() : - aValue.GetFloatValue(); - return true; - } - - coeff_type ComputeCoefficient(const nsCSSValue& aValue) - { - coeff_type coeff; - if (!mozilla::css::ComputeCalc(coeff, aValue, *this)) { - // Something's wrong; parser should enforce that calc() coefficients are - // unitless, but failure in ComputeCalc means there was a unit mismatch. - MOZ_ASSERT_UNREACHABLE("unexpected unit"); - } - return coeff; - } -}; - -} // namespace css - -} // namespace mozilla - -#endif /* !defined(CSSCalc_h_) */ diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index f8f631e1b474..6da9c21c87cf 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -16,7 +16,6 @@ #include "mozilla/Likely.h" #include "mozilla/MemoryReporting.h" #include "mozilla/css/ImageLoader.h" -#include "CSSCalc.h" #include "gfxFontConstants.h" #include "imgIRequest.h" #include "imgRequestProxy.h"