FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x, const SVGLength& y) { ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN); if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { SVGLengthContext lengthContext(context); return FloatPoint(x.value(lengthContext), y.value(lengthContext)); } // FIXME: valueAsPercentage() won't be correct for eg. cm units. They need to be resolved in user space and then be considered in objectBoundingBox space. return FloatPoint(x.valueAsPercentage(), y.valueAsPercentage()); }
FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x, const SVGLength& y) { DCHECK_NE(SVGUnitTypes::kSvgUnitTypeUnknown, type); if (type == SVGUnitTypes::kSvgUnitTypeUserspaceonuse) { SVGLengthContext lengthContext(context); return FloatPoint(x.value(lengthContext), y.value(lengthContext)); } // FIXME: valueAsPercentage() won't be correct for eg. cm units. They need to // be resolved in user space and then be considered in objectBoundingBox // space. return FloatPoint(x.valueAsPercentage(), y.valueAsPercentage()); }
float SVGTextLayoutEngineSpacing::calculateCSSKerningAndSpacing(const SVGRenderStyle* style, SVGElement* contextElement, const UChar* currentCharacter) { float kerning = 0; SVGLength kerningLength = style->kerning(); if (kerningLength.unitType() == LengthTypePercentage) kerning = kerningLength.valueAsPercentage() * m_font.pixelSize(); else { SVGLengthContext lengthContext(contextElement); kerning = kerningLength.value(lengthContext); } const UChar* lastCharacter = m_lastCharacter; m_lastCharacter = currentCharacter; if (!kerning && !m_font.letterSpacing() && !m_font.wordSpacing()) return 0; float spacing = m_font.letterSpacing() + kerning; if (currentCharacter && lastCharacter && m_font.wordSpacing()) { if (Font::treatAsSpace(*currentCharacter) && !Font::treatAsSpace(*lastCharacter)) spacing += m_font.wordSpacing(); } return spacing; }
int SVGSVGElement::relativeHeightValue() const { SVGLength h = height(); if (h.unitType() != LengthTypePercentage) return 0; return static_cast<int>(h.valueAsPercentage() * m_containerSize.height()); }
int SVGSVGElement::relativeWidthValue() const { SVGLength w = width(); if (w.unitType() != LengthTypePercentage) return 0; return static_cast<int>(w.valueAsPercentage() * m_containerSize.width()); }
float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle* style, SVGElement* lengthContext) const { if (style->baselineShift() == BS_LENGTH) { SVGLength baselineShiftValueLength = style->baselineShiftValue(); if (baselineShiftValueLength.unitType() == LengthTypePercentage) return baselineShiftValueLength.valueAsPercentage() * m_font.pixelSize(); return baselineShiftValueLength.value(lengthContext); } switch (style->baselineShift()) { case BS_BASELINE: return 0; case BS_SUB: return -m_font.height() / 2; case BS_SUPER: return m_font.height() / 2; default: ASSERT_NOT_REACHED(); return 0; } }
// Helper function static float calculateBaselineShift(RenderObject* item) { ASSERT(item); ASSERT(item->style()); ASSERT(item->node()); ASSERT(item->node()->isSVGElement()); const Font& font = item->style()->font(); const SVGRenderStyle* svgStyle = item->style()->svgStyle(); float baselineShift = 0.0f; if (svgStyle->baselineShift() == BS_LENGTH) { SVGLength baselineShiftValueLength = svgStyle->baselineShiftValue(); if (baselineShiftValueLength.unitType() == LengthTypePercentage) baselineShift = baselineShiftValueLength.valueAsPercentage() * font.pixelSize(); else baselineShift = baselineShiftValueLength.value(static_cast<SVGElement*>(item->node())); } else { float baselineAscent = font.ascent() + font.descent(); switch (svgStyle->baselineShift()) { case BS_BASELINE: break; case BS_SUB: baselineShift = -baselineAscent / 2.0f; break; case BS_SUPER: baselineShift = baselineAscent / 2.0f; break; default: ASSERT_NOT_REACHED(); } } return baselineShift; }