float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode mode) { ASSERT(context); float width = 0.0f, height = 0.0f; SVGElement* viewportElement = context->viewportElement(); // PercentageOfViewport() is used to resolve all relative-positioned values within a SVG document (fragment) Document* doc = context->document(); if (doc->documentElement() == context) { // Resolve value against outermost <svg> element if (RenderView* view = toRenderView(doc->renderer())) { width = view->viewWidth(); height = view->viewHeight(); } } else if (viewportElement && viewportElement->isSVG()) { // Resolve value against nearest viewport element (common case: inner <svg> elements) const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement); if (svg->hasAttribute(SVGNames::viewBoxAttr)) { width = svg->viewBox().width(); height = svg->viewBox().height(); } else { width = svg->width().value(svg); height = svg->height().value(svg); } } else if (context->parent() && !context->parent()->isSVGElement()) { // Resolve value against enclosing non-SVG RenderBox if (RenderObject* renderer = context->renderer()) { if (renderer->isBox()) { RenderBox* box = toRenderBox(renderer); width = box->width(); height = box->height(); } } } if (mode == LengthModeWidth) return value * width; else if (mode == LengthModeHeight) return value * height; else if (mode == LengthModeOther) return value * sqrtf(powf(width, 2) + powf(height, 2)) / sqrtf(2.0f); return 0.0f; }
bool SVGLength::determineViewport(const SVGElement* context, float& width, float& height) const { if (!context) return false; // Take size from outermost <svg> element. Document* document = context->document(); if (document->documentElement() == context) { if (RenderView* view = toRenderView(document->renderer())) { width = view->viewWidth(); height = view->viewHeight(); return true; } return false; } // Resolve value against nearest viewport element (common case: inner <svg> elements) SVGElement* viewportElement = context->viewportElement(); if (viewportElement && viewportElement->isSVG()) { const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement); if (svg->hasAttribute(SVGNames::viewBoxAttr)) { width = svg->viewBox().width(); height = svg->viewBox().height(); } else { width = svg->width().value(svg); height = svg->height().value(svg); } return true; } // Resolve value against enclosing non-SVG RenderBox if (!context->parentNode() || context->parentNode()->isSVGElement()) return false; RenderObject* renderer = context->renderer(); if (!renderer || !renderer->isBox()) return false; RenderBox* box = toRenderBox(renderer); width = box->width(); height = box->height(); return true; }
float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode mode) { ASSERT(context); float width = 0.0f, height = 0.0f; SVGElement* viewportElement = context->viewportElement(); Document* doc = context->document(); if (doc->documentElement() == context) { // We have to ask the canvas for the full "canvas size"... RenderView* view = toRenderView(doc->renderer()); if (view && view->frameView()) { width = view->frameView()->visibleWidth(); // TODO: recheck! height = view->frameView()->visibleHeight(); // TODO: recheck! } } else if (viewportElement && viewportElement->isSVG()) { const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement); if (svg->hasAttribute(SVGNames::viewBoxAttr)) { width = svg->viewBox().width(); height = svg->viewBox().height(); } else { width = svg->width().value(svg); height = svg->height().value(svg); } } else if (context->parent() && !context->parent()->isSVGElement()) { if (RenderObject* renderer = context->renderer()) { if (renderer->isBox()) { RenderBox* box = toRenderBox(renderer); width = box->width(); height = box->height(); } } } if (mode == LengthModeWidth) return value * width; else if (mode == LengthModeHeight) return value * height; else if (mode == LengthModeOther) return value * sqrtf(powf(width, 2) + powf(height, 2)) / sqrtf(2.0f); return 0.0f; }