IntSize SVGImage::size() const { IntSize defaultSize(300, 150); // FIXME: Eventually we'll be passed in the dest size and can scale against that IntSize destSize = defaultSize; if (!m_frame || !m_frame->document()) return IntSize(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement(); if (!rootElement) return defaultSize; SVGLength width = rootElement->width(); SVGLength height = rootElement->height(); IntSize svgSize; if (width.unitType() == LengthTypePercentage) svgSize.setWidth(static_cast<int>(width.valueInSpecifiedUnits() * destSize.width())); else svgSize.setWidth(static_cast<int>(width.value())); if (height.unitType() == LengthTypePercentage) svgSize.setHeight(static_cast<int>(height.valueInSpecifiedUnits() * destSize.height())); else svgSize.setHeight(static_cast<int>(height.value())); return svgSize; }
IntSize SVGImage::size() const { if (!m_page) return IntSize(); Frame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); if (!rootElement) return IntSize(); SVGLength width = rootElement->width(); SVGLength height = rootElement->height(); IntSize svgSize; if (width.unitType() == LengthTypePercentage) svgSize.setWidth(rootElement->relativeWidthValue()); else svgSize.setWidth(static_cast<int>(width.value(rootElement))); if (height.unitType() == LengthTypePercentage) svgSize.setHeight(rootElement->relativeHeightValue()); else svgSize.setHeight(static_cast<int>(height.value(rootElement))); return svgSize; }
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()); }
static v8::Handle<v8::Value> unitTypeAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.SVGLength.unitType._get"); V8SVGPODTypeWrapper<SVGLength>* impWrapper = V8SVGPODTypeWrapper<SVGLength>::toNative(info.Holder()); SVGLength impInstance = *impWrapper; SVGLength* imp = &impInstance; return v8::Integer::New(imp->unitType()); }
void RenderSVGRoot::calcViewport() { SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); if (!svg->hasSetContainerSize()) { // In the normal case of <svg> being stand-alone or in a CSSBoxModel object we use // RenderBox::width()/height() (which pulls data from RenderStyle) m_viewportSize = FloatSize(width(), height()); return; } // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use // the special relativeWidthValue accessors which respect the specified containerSize // FIXME: Check how SVGImage + zooming is supposed to be handled? SVGLength width = svg->width(); SVGLength height = svg->height(); m_viewportSize = FloatSize(width.unitType() == LengthTypePercentage ? svg->relativeWidthValue() : width.value(svg), height.unitType() == LengthTypePercentage ? svg->relativeHeightValue() : height.value(svg)); }
void RenderSVGRoot::calcViewport() { SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); if (!selfNeedsLayout() && !svg->hasRelativeValues()) return; if (!svg->hasSetContainerSize()) { // In the normal case of <svg> being stand-alone or in a CSSBoxModel object we use // RenderBox::width()/height() (which pulls data from RenderStyle) m_viewportSize = FloatSize(width(), height()); } else { // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use // the special relativeWidthValue accessors which respect the specified containerSize SVGLength width = svg->width(); SVGLength height = svg->height(); float viewportWidth = (width.unitType() == LengthTypePercentage) ? svg->relativeWidthValue() : width.value(svg); float viewportHeight = (height.unitType() == LengthTypePercentage) ? svg->relativeHeightValue() : height.value(svg); m_viewportSize = FloatSize(viewportWidth, viewportHeight); } }
PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& length) { CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN; switch (length.unitType()) { case LengthTypeUnknown: break; case LengthTypeNumber: cssType = CSSPrimitiveValue::CSS_NUMBER; break; case LengthTypePercentage: cssType = CSSPrimitiveValue::CSS_PERCENTAGE; break; case LengthTypeEMS: cssType = CSSPrimitiveValue::CSS_EMS; break; case LengthTypeEXS: cssType = CSSPrimitiveValue::CSS_EXS; break; case LengthTypePX: cssType = CSSPrimitiveValue::CSS_PX; break; case LengthTypeCM: cssType = CSSPrimitiveValue::CSS_CM; break; case LengthTypeMM: cssType = CSSPrimitiveValue::CSS_MM; break; case LengthTypeIN: cssType = CSSPrimitiveValue::CSS_IN; break; case LengthTypePT: cssType = CSSPrimitiveValue::CSS_PT; break; case LengthTypePC: cssType = CSSPrimitiveValue::CSS_PC; break; default: ASSERT_NOT_REACHED(); }; return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType); }
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; }