float SVGLength::GetValueInSpecifiedUnit(PRUint8 aUnit, const nsSVGElement *aElement, PRUint8 aAxis) const { if (aUnit == mUnit) { return mValue; } if ((aUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER && mUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_PX) || (aUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_PX && mUnit == nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER)) { return mValue; } if (IsAbsoluteUnit(aUnit) && IsAbsoluteUnit(mUnit)) { return mValue * GetAbsUnitsPerAbsUnit(aUnit, mUnit); } // Otherwise we do a two step convertion via user units. This can only // succeed if aElement is non-null (although that's not sufficent to // guarantee success). float userUnitsPerCurrentUnit = GetUserUnitsPerUnit(aElement, aAxis); float userUnitsPerNewUnit = SVGLength(0.0f, aUnit).GetUserUnitsPerUnit(aElement, aAxis); NS_ASSERTION(userUnitsPerCurrentUnit >= 0 || !NS_finite(userUnitsPerCurrentUnit), "bad userUnitsPerCurrentUnit"); NS_ASSERTION(userUnitsPerNewUnit >= 0 || !NS_finite(userUnitsPerNewUnit), "bad userUnitsPerNewUnit"); float value = mValue * userUnitsPerCurrentUnit / userUnitsPerNewUnit; // userUnitsPerCurrentUnit could be infinity, or userUnitsPerNewUnit could // be zero. if (NS_finite(value)) { return value; } return std::numeric_limits<float>::quiet_NaN(); }
/** * Helper to convert between different CSS absolute units without the need for * an element, which provides more flexibility at the DOM level (and without * the need for an intermediary conversion to user units, which avoids * unnecessary overhead and rounding error). * * Example usage: to find out how many centimeters there are per inch: * * GetAbsUnitsPerAbsUnit(nsIDOMSVGLength::SVG_LENGTHTYPE_CM, * nsIDOMSVGLength::SVG_LENGTHTYPE_IN) */ inline static float GetAbsUnitsPerAbsUnit(PRUint8 aUnits, PRUint8 aPerUnit) { NS_ABORT_IF_FALSE(IsAbsoluteUnit(aUnits), "Not a CSS absolute unit"); NS_ABORT_IF_FALSE(IsAbsoluteUnit(aPerUnit), "Not a CSS absolute unit"); float CSSAbsoluteUnitConversionFactors[5][5] = { // columns: cm, mm, in, pt, pc // cm per...: { 1.0, 0.1, 2.54, 0.035277777777777778, 0.42333333333333333 }, // mm per...: { 10.0, 1.0, 25.4, 0.35277777777777778, 4.2333333333333333 }, // in per...: { 0.39370078740157481, 0.039370078740157481, 1.0, 0.013888888888888889, 0.16666666666666667 }, // pt per...: { 28.346456692913386, 2.8346456692913386, 72.0, 1.0, 12.0 }, // pc per...: { 2.3622047244094489, 0.23622047244094489, 6.0, 0.083333333333333333, 1.0 } }; // First absolute unit is SVG_LENGTHTYPE_CM = 6 return CSSAbsoluteUnitConversionFactors[aUnits - 6][aPerUnit - 6]; }
/** * Helper to convert between different CSS absolute units without the need for * an element, which provides more flexibility at the DOM level (and without * the need for an intermediary conversion to user units, which avoids * unnecessary overhead and rounding error). * * Example usage: to find out how many centimeters there are per inch: * * GetAbsUnitsPerAbsUnit(nsIDOMSVGLength::SVG_LENGTHTYPE_CM, * nsIDOMSVGLength::SVG_LENGTHTYPE_IN) */ inline static float GetAbsUnitsPerAbsUnit(uint8_t aUnits, uint8_t aPerUnit) { MOZ_ASSERT(IsAbsoluteUnit(aUnits), "Not a CSS absolute unit"); MOZ_ASSERT(IsAbsoluteUnit(aPerUnit), "Not a CSS absolute unit"); float CSSAbsoluteUnitConversionFactors[5][5] = { // columns: cm, mm, in, pt, pc // cm per...: { 1.0f, 0.1f, 2.54f, 0.035277777777777778f, 0.42333333333333333f }, // mm per...: { 10.0f, 1.0f, 25.4f, 0.35277777777777778f, 4.2333333333333333f }, // in per...: { 0.39370078740157481f, 0.039370078740157481f, 1.0f, 0.013888888888888889f, 0.16666666666666667f }, // pt per...: { 28.346456692913386f, 2.8346456692913386f, 72.0f, 1.0f, 12.0f }, // pc per...: { 2.3622047244094489f, 0.23622047244094489f, 6.0f, 0.083333333333333333f, 1.0f } }; // First absolute unit is SVG_LENGTHTYPE_CM = 6 return CSSAbsoluteUnitConversionFactors[aUnits - 6][aPerUnit - 6]; }