float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, CSSPrimitiveValue::UnitType fromUnit) const { float userUnits = value; switch (fromUnit) { case CSSPrimitiveValue::UnitType::Pixels: case CSSPrimitiveValue::UnitType::Number: case CSSPrimitiveValue::UnitType::UserUnits: userUnits = value; break; case CSSPrimitiveValue::UnitType::Percentage: { FloatSize viewportSize; if (!determineViewport(viewportSize)) return 0; userUnits = value * dimensionForLengthMode(mode, viewportSize) / 100; break; } case CSSPrimitiveValue::UnitType::Ems: userUnits = convertValueFromEMSToUserUnits(computedStyleForLengthResolving(m_context), value); break; case CSSPrimitiveValue::UnitType::Exs: userUnits = convertValueFromEXSToUserUnits(value); break; case CSSPrimitiveValue::UnitType::Centimeters: userUnits = value * cssPixelsPerCentimeter; break; case CSSPrimitiveValue::UnitType::Millimeters: userUnits = value * cssPixelsPerMillimeter; break; case CSSPrimitiveValue::UnitType::Inches: userUnits = value * cssPixelsPerInch; break; case CSSPrimitiveValue::UnitType::Points: userUnits = value * cssPixelsPerPoint; break; case CSSPrimitiveValue::UnitType::Picas: userUnits = value * cssPixelsPerPica; break; case CSSPrimitiveValue::UnitType::Rems: userUnits = convertValueFromEMSToUserUnits(rootElementStyle(m_context), value); break; case CSSPrimitiveValue::UnitType::Chs: userUnits = convertValueFromCHSToUserUnits(value); break; case CSSPrimitiveValue::UnitType::ViewportWidth: case CSSPrimitiveValue::UnitType::ViewportHeight: case CSSPrimitiveValue::UnitType::ViewportMin: case CSSPrimitiveValue::UnitType::ViewportMax: userUnits = value * dimensionForViewportUnit(m_context, fromUnit); break; default: ASSERT_NOT_REACHED(); break; } // Since we mix css <length> values with svg's length values we need to // clamp values to the narrowest range, otherwise it can result in // rendering issues. return CSSPrimitiveValue::clampToCSSLengthRange(userUnits); }
float SVGLengthContext::convertValueFromUserUnits( float value, SVGLengthMode mode, CSSPrimitiveValue::UnitType toUnit) const { switch (toUnit) { case CSSPrimitiveValue::UnitType::Pixels: case CSSPrimitiveValue::UnitType::Number: case CSSPrimitiveValue::UnitType::Integer: case CSSPrimitiveValue::UnitType::UserUnits: return value; case CSSPrimitiveValue::UnitType::Percentage: { FloatSize viewportSize; if (!determineViewport(viewportSize)) return 0; float dimension = dimensionForLengthMode(mode, viewportSize); if (!dimension) return 0; // LengthTypePercentage is represented with 100% = 100.0. // Good for accuracy but could eventually be changed. return value * 100 / dimension; } case CSSPrimitiveValue::UnitType::Ems: return convertValueFromUserUnitsToEMS( computedStyleForLengthResolving(m_context), value); case CSSPrimitiveValue::UnitType::Exs: return convertValueFromUserUnitsToEXS(value); case CSSPrimitiveValue::UnitType::Rems: return convertValueFromUserUnitsToEMS(rootElementStyle(m_context), value); case CSSPrimitiveValue::UnitType::Chs: return convertValueFromUserUnitsToCHS(value); case CSSPrimitiveValue::UnitType::Centimeters: return value / cssPixelsPerCentimeter; case CSSPrimitiveValue::UnitType::Millimeters: return value / cssPixelsPerMillimeter; case CSSPrimitiveValue::UnitType::Inches: return value / cssPixelsPerInch; case CSSPrimitiveValue::UnitType::Points: return value / cssPixelsPerPoint; case CSSPrimitiveValue::UnitType::Picas: return value / cssPixelsPerPica; case CSSPrimitiveValue::UnitType::ViewportWidth: case CSSPrimitiveValue::UnitType::ViewportHeight: case CSSPrimitiveValue::UnitType::ViewportMin: case CSSPrimitiveValue::UnitType::ViewportMax: return value / dimensionForViewportUnit(m_context, toUnit); default: break; } ASSERT_NOT_REACHED(); return 0; }