static inline float dimensionForViewportUnit(const SVGElement* context, CSSPrimitiveValue::UnitType unit)
{
    if (!context)
        return 0;

    const Document& document = context->document();
    FrameView* view = document.view();
    if (!view)
        return 0;

    const ComputedStyle* style = computedStyleForLengthResolving(context);
    if (!style)
        return 0;

    FloatSize viewportSize(view->width(), view->height());

    switch (unit) {
    case CSSPrimitiveValue::UnitType::ViewportWidth:
        return viewportLengthPercent(viewportSize.width()) / style->effectiveZoom();

    case CSSPrimitiveValue::UnitType::ViewportHeight:
        return viewportLengthPercent(viewportSize.height()) / style->effectiveZoom();

    case CSSPrimitiveValue::UnitType::ViewportMin:
        return viewportMinPercent(viewportSize) / style->effectiveZoom();

    case CSSPrimitiveValue::UnitType::ViewportMax:
        return viewportMaxPercent(viewportSize) / style->effectiveZoom();
    default:
        break;
    }

    ASSERT_NOT_REACHED();
    return 0;
}
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::convertValueFromCHSToUserUnits(float value) const
{
    const ComputedStyle* style = computedStyleForLengthResolving(m_context);
    if (!style)
        return 0;

    return value * style->fontMetrics().zeroWidth() / style->effectiveZoom();
}
float SVGLengthContext::convertValueFromEXSToUserUnits(float value) const
{
    const ComputedStyle* style = computedStyleForLengthResolving(m_context);
    if (!style)
        return 0;

    // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg
    // if this causes problems in real world cases maybe it would be best to remove this
    return value * ceilf(style->fontMetrics().xHeight() / style->effectiveZoom());
}
float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit) const
{
    float userUnits = value;
    switch (fromUnit) {
    case LengthTypeUnknown:
        return 0;
    case LengthTypePX:
    case LengthTypeNumber:
        userUnits = value;
        break;
    case LengthTypePercentage: {
        FloatSize viewportSize;
        if (!determineViewport(viewportSize))
            return 0;
        userUnits = value * dimensionForLengthMode(mode, viewportSize) / 100;
        break;
    }
    case LengthTypeEMS:
        userUnits = convertValueFromEMSToUserUnits(computedStyleForLengthResolving(m_context), value);
        break;
    case LengthTypeEXS:
        userUnits = convertValueFromEXSToUserUnits(value);
        break;
    case LengthTypeCM:
        userUnits = value * cssPixelsPerCentimeter;
        break;
    case LengthTypeMM:
        userUnits = value * cssPixelsPerMillimeter;
        break;
    case LengthTypeIN:
        userUnits = value * cssPixelsPerInch;
        break;
    case LengthTypePT:
        userUnits = value * cssPixelsPerPoint;
        break;
    case LengthTypePC:
        userUnits = value * cssPixelsPerPica;
        break;
    case LengthTypeREMS:
        userUnits = convertValueFromEMSToUserUnits(rootElementStyle(m_context), value);
        break;
    case LengthTypeCHS:
        userUnits = convertValueFromCHSToUserUnits(value);
        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::convertValueFromUserUnitsToCHS(float value) const
{
    const ComputedStyle* style = computedStyleForLengthResolving(m_context);
    if (!style)
        return 0;

    float zeroWidth = style->fontMetrics().zeroWidth();
    if (!zeroWidth)
        return 0;

    return value / zeroWidth;
}
Example #7
0
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;
}
Example #8
0
float SVGLengthContext::convertValueFromUserUnitsToCHS(float value) const {
  const ComputedStyle* style = computedStyleForLengthResolving(m_context);
  const SimpleFontData* fontData = style->font().primaryFont();
  if (!style || !fontData)
    return 0;

  float zeroWidth =
      fontData->getFontMetrics().zeroWidth() / style->effectiveZoom();
  if (!zeroWidth)
    return 0;

  return value / zeroWidth;
}
Example #9
0
float SVGLengthContext::resolveValue(const CSSPrimitiveValue& primitiveValue,
                                     SVGLengthMode mode) const {
  const ComputedStyle* style = computedStyleForLengthResolving(m_context);
  if (!style)
    return 0;

  const ComputedStyle* rootStyle = rootElementStyle(m_context);
  if (!rootStyle)
    return 0;

  CSSToLengthConversionData conversionData = CSSToLengthConversionData(
      style, rootStyle, m_context->document().layoutViewItem(), 1.0f);
  Length length = primitiveValue.convertToLength(conversionData);
  return valueForLength(length, 1.0f, mode);
}
Example #10
0
float SVGLengthContext::convertValueFromUserUnitsToEXS(float value) const {
  const ComputedStyle* style = computedStyleForLengthResolving(m_context);
  const SimpleFontData* fontData = style->font().primaryFont();
  if (!style || !fontData)
    return 0;

  // Use of ceil allows a pixel match to the W3Cs expected output of
  // coords-units-03-b.svg, if this causes problems in real world cases maybe it
  // would be best to remove this.
  float xHeight =
      ceilf(fontData->getFontMetrics().xHeight() / style->effectiveZoom());
  if (!xHeight)
    return 0;

  return value / xHeight;
}
float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mode, SVGLengthType toUnit) const
{
    switch (toUnit) {
    case LengthTypeUnknown:
        return 0;
    case LengthTypeNumber:
        return value;
    case LengthTypePercentage: {
        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 LengthTypeEMS:
        return convertValueFromUserUnitsToEMS(computedStyleForLengthResolving(m_context), value);
    case LengthTypeEXS:
        return convertValueFromUserUnitsToEXS(value);
    case LengthTypeREMS:
        return convertValueFromUserUnitsToEMS(rootElementStyle(m_context), value);
    case LengthTypeCHS:
        return convertValueFromUserUnitsToCHS(value);
    case LengthTypePX:
        return value;
    case LengthTypeCM:
        return value / cssPixelsPerCentimeter;
    case LengthTypeMM:
        return value / cssPixelsPerMillimeter;
    case LengthTypeIN:
        return value / cssPixelsPerInch;
    case LengthTypePT:
        return value / cssPixelsPerPoint;
    case LengthTypePC:
        return value / cssPixelsPerPica;
    }

    ASSERT_NOT_REACHED();
    return 0;
}