JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionGetBBox(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<FloatRect>::create(imp->getBBox()).get(), imp); return result; }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionCreateSVGAngle(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); JSC::JSValue result = toJS(exec, WTF::getPtr(imp->createSVGAngle()), imp); return result; }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionSetCurrentTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); float seconds = args.at(0).toFloat(exec); imp->setCurrentTime(seconds); return jsUndefined(); }
bool SVGImage::usesContainerSize() const { if (!m_page) return false; Frame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); if (!rootElement) return false; if (RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer())) return !renderer->containerSize().isEmpty(); return false; }
TransformationMatrix RenderSVGViewportContainer::viewportTransform() const { if (element()->hasTagName(SVGNames::svgTag)) { SVGSVGElement* svg = static_cast<SVGSVGElement*>(element()); return svg->viewBoxToViewTransform(viewport().width(), viewport().height()); } else if (element()->hasTagName(SVGNames::markerTag)) { SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(element()); return marker->viewBoxToViewTransform(viewport().width(), viewport().height()); } return TransformationMatrix(); }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionGetCurrentTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); JSC::JSValue result = jsNumber(exec, imp->getCurrentTime()); return result; }
// RenderBox methods will expect coordinates w/o any transforms in coordinates // relative to our borderBox origin. This method gives us exactly that. void RenderSVGRoot::buildLocalToBorderBoxTransform() { SVGSVGElement* svg = toSVGSVGElement(node()); ASSERT(svg); float scale = style()->effectiveZoom(); SVGPoint translate = svg->currentTranslate(); LayoutSize borderAndPadding(borderLeft() + paddingLeft(), borderTop() + paddingTop()); m_localToBorderBoxTransform = svg->viewBoxToViewTransform(contentWidth() / scale, contentHeight() / scale); if (borderAndPadding.isEmpty() && scale == 1 && translate == SVGPoint::zero()) return; m_localToBorderBoxTransform = AffineTransform(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y()) * m_localToBorderBoxTransform; }
// LayoutBox methods will expect coordinates w/o any transforms in coordinates // relative to our borderBox origin. This method gives us exactly that. void LayoutSVGRoot::buildLocalToBorderBoxTransform() { SVGSVGElement* svg = toSVGSVGElement(node()); ASSERT(svg); float scale = style()->effectiveZoom(); FloatPoint translate = svg->currentTranslate(); LayoutSize borderAndPadding(borderLeft() + paddingLeft(), borderTop() + paddingTop()); m_localToBorderBoxTransform = svg->viewBoxToViewTransform(contentWidth() / scale, contentHeight() / scale); AffineTransform viewToBorderBoxTransform(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y()); m_localToBorderBoxTransform.preMultiply(viewToBorderBoxTransform); }
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // An empty viewport disables rendering. if (pixelSnappedBorderBoxRect().isEmpty()) return; // Don't paint, if the context explicitly disabled it. if (paintInfo.context->paintingDisabled()) return; // An empty viewBox also disables rendering. // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute) SVGSVGElement* svg = toSVGSVGElement(node()); ASSERT(svg); if (svg->hasEmptyViewBox()) return; // Don't paint if we don't have kids, except if we have filters we should paint those. if (!firstChild()) { SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this); if (!resources || !resources->filter()) return; } // Make a copy of the PaintInfo because applyTransform will modify the damage rect. PaintInfo childPaintInfo(paintInfo); childPaintInfo.context->save(); // Apply initial viewport clip if (shouldApplyViewportClip()) childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset))); // Convert from container offsets (html renderers) to a relative transform (svg renderers). // Transform from our paint container's coordinate system to our local coords. IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset); childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * localToBorderBoxTransform()); // SVGRenderingContext must be destroyed before we restore the childPaintInfo.context, because a filter may have // changed the context and it is only reverted when the SVGRenderingContext destructor finishes applying the filter. { SVGRenderingContext renderingContext; bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) { renderingContext.prepareToRenderSVGContent(this, childPaintInfo); continueRendering = renderingContext.isRenderingPrepared(); } if (continueRendering) RenderBox::paint(childPaintInfo, LayoutPoint()); } childPaintInfo.context->restore(); }
void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const IntSize& size, float zoom, ShouldClearBuffer shouldClear) { // FIXME: This doesn't work correctly with animations. If an image contains animations, that say run for 2 seconds, // and we currently have one <img> that displays us. If we open another document referencing the same SVGImage it // will display the document at a time where animations already ran - even though it has its own ImageBuffer. // We currently don't implement SVGSVGElement::setCurrentTime, and can NOT go back in time, once animations started. // There's no way to fix this besides avoiding style/attribute mutations from SVGAnimationElement. ASSERT(buffer); ASSERT(!size.isEmpty()); if (!m_page) return; Frame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); if (!rootElement) return; RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer()); if (!renderer) return; // Draw image at requested size. ImageObserver* observer = imageObserver(); ASSERT(observer); // Temporarily reset image observer, we don't want to receive any changeInRect() calls due this relayout. setImageObserver(0); renderer->setContainerSize(size); frame->view()->resize(this->size()); if (zoom != 1) frame->setPageZoomFactor(zoom); // Eventually clear image buffer. IntRect rect(IntPoint(), size); if (shouldClear == ClearImageBuffer) buffer->context()->clearRect(rect); // Draw SVG on top of ImageBuffer. draw(buffer->context(), rect, rect, ColorSpaceDeviceRGB, CompositeSourceOver); // Reset container size & zoom to initial state. Otherwhise the size() of this // image would return whatever last size was set by drawSVGToImageBuffer(). if (zoom != 1) frame->setPageZoomFactor(1); renderer->setContainerSize(IntSize()); frame->view()->resize(this->size()); if (frame->view()->needsLayout()) frame->view()->layout(); setImageObserver(observer); }
void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element* anchorNode) { RenderObject* renderer = this->renderer(); SVGViewSpec* view = m_viewSpec.get(); if (view) view->reset(); bool hadUseCurrentView = m_useCurrentView; m_useCurrentView = false; if (fragmentIdentifier.startsWith("xpointer(")) { // FIXME: XPointer references are ignored (https://bugs.webkit.org/show_bug.cgi?id=17491) if (renderer && hadUseCurrentView) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); return; } if (fragmentIdentifier.startsWith("svgView(")) { if (!view) view = currentView(); // Create the SVGViewSpec. if (view->parseViewSpec(fragmentIdentifier)) m_useCurrentView = true; else view->reset(); if (renderer && (hadUseCurrentView || m_useCurrentView)) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); return; } // Spec: If the SVG fragment identifier addresses a ‘view’ element within an SVG document (e.g., MyDrawing.svg#MyView // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor ‘svg’ element is displayed in the viewport. // Any view specification attributes included on the given ‘view’ element override the corresponding view specification // attributes on the closest ancestor ‘svg’ element. if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) { if (SVGViewElement* viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0) { SVGElement* element = SVGLocatable::nearestViewportElement(viewElement); if (element->hasTagName(SVGNames::svgTag)) { SVGSVGElement* svg = static_cast<SVGSVGElement*>(element); svg->inheritViewAttributes(viewElement); if (RenderObject* renderer = svg->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); } } return; } // FIXME: We need to decide which <svg> to focus on, and zoom to it. // FIXME: We need to actually "highlight" the viewTarget(s). }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionCreateSVGTransformFromMatrix(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); TransformationMatrix matrix = toSVGMatrix(args.at(0)); JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<SVGTransform>::create(imp->createSVGTransformFromMatrix(matrix)).get(), imp); return result; }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionSuspendRedraw(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); unsigned maxWaitMilliseconds = args.at(0).toInt32(exec); JSC::JSValue result = jsNumber(exec, imp->suspendRedraw(maxWaitMilliseconds)); return result; }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionHasExtension(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); const UString& extension = args.at(0).toString(exec); JSC::JSValue result = jsBoolean(imp->hasExtension(extension)); return result; }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionGetPresentationAttribute(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); const UString& name = args.at(0).toString(exec); JSC::JSValue result = toJS(exec, WTF::getPtr(imp->getPresentationAttribute(name))); return result; }
void SVGDocumentExtensions::dispatchSVGLoadEventToOutermostSVGElements() { Vector<RefPtr<SVGSVGElement> > timeContainers; timeContainers.appendRange(m_timeContainers.begin(), m_timeContainers.end()); Vector<RefPtr<SVGSVGElement> >::iterator end = timeContainers.end(); for (Vector<RefPtr<SVGSVGElement> >::iterator it = timeContainers.begin(); it != end; ++it) { SVGSVGElement* outerSVG = (*it).get(); if (!outerSVG->isOutermostSVGSVGElement()) continue; outerSVG->sendSVGLoadEventIfPossible(); } }
void SVGImage::setContainerSize(const IntSize& containerSize) { if (containerSize.width() <= 0 || containerSize.height() <= 0) return; if (!m_frame || !m_frame->document()) return; SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement(); if (!rootElement) return; rootElement->setContainerSize(containerSize); }
/* readonly attribute int32_t height; */ NS_IMETHODIMP VectorImage::GetHeight(int32_t* aHeight) { if (mError || !mIsFullyLoaded) { *aHeight = -1; } else { SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); MOZ_ASSERT(rootElem, "Should have a root SVG elem, since we finished " "loading without errors"); *aHeight = rootElem->GetIntrinsicHeight(); } return *aHeight >= 0 ? NS_OK : NS_ERROR_FAILURE; }
void SVGImage::setContainerSize(const IntSize& containerSize) { if (containerSize.isEmpty()) return; if (!m_page) return; Frame* frame = m_page->mainFrame(); SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement(); if (!rootElement) return; rootElement->setContainerSize(containerSize); }
bool nsSVGInnerSVGFrame::HasChildrenOnlyTransform(gfxMatrix *aTransform) const { SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent); if (content->HasViewBoxOrSyntheticViewBox()) { // XXX Maybe return false if the transform is the identity transform? if (aTransform) { *aTransform = content->GetViewBoxTransform(); } return true; } return false; }
void SVGDocumentWrapper::FlushImageTransformInvalidation() { NS_ABORT_IF_FALSE(!mIgnoreInvalidation, "shouldn't be reentrant"); SVGSVGElement* svgElem = GetRootSVGElem(); if (!svgElem) return; mIgnoreInvalidation = true; svgElem->FlushImageTransformInvalidation(); FlushLayout(); mIgnoreInvalidation = false; }
void SVGImage::setContainerSize(const IntSize& size) { SVGSVGElement* rootElement = svgRootElement(m_page.get()); if (!rootElement) return; FrameView* view = frameView(); view->resize(this->containerSize()); LayoutSVGRoot* layoutObject = toLayoutSVGRoot(rootElement->layoutObject()); if (!layoutObject) return; layoutObject->setContainerSize(size); }
void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const { // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing // SVG needs to specify how to calculate some intrinsic sizing properties to enable inclusion within other languages. // The intrinsic width and height of the viewport of SVG content must be determined from the ‘width’ and ‘height’ attributes. // If either of these are not specified, a value of '100%' must be assumed. Note: the ‘width’ and ‘height’ attributes are not // the same as the CSS width and height properties. Specifically, percentage values do not provide an intrinsic width or height, // and do not indicate a percentage of the containing block. Rather, once the viewport is established, they indicate the portion // of the viewport that is actually covered by image data. SVGSVGElement* svg = toSVGSVGElement(node()); ASSERT(svg); Length intrinsicWidthAttribute = svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties); Length intrinsicHeightAttribute = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties); // The intrinsic aspect ratio of the viewport of SVG content is necessary for example, when including SVG from an ‘object’ // element in HTML styled with CSS. It is possible (indeed, common) for an SVG graphic to have an intrinsic aspect ratio but // not to have an intrinsic width or height. The intrinsic aspect ratio must be calculated based upon the following rules: // - The aspect ratio is calculated by dividing a width by a height. // - If the ‘width’ and ‘height’ of the rootmost ‘svg’ element are both specified with unit identifiers (in, mm, cm, pt, pc, // px, em, ex) or in user units, then the aspect ratio is calculated from the ‘width’ and ‘height’ attributes after // resolving both values to user units. if (intrinsicWidthAttribute.isFixed() || intrinsicHeightAttribute.isFixed()) { if (intrinsicWidthAttribute.isFixed()) intrinsicSize.setWidth(floatValueForLength(intrinsicWidthAttribute, 0)); if (intrinsicHeightAttribute.isFixed()) intrinsicSize.setHeight(floatValueForLength(intrinsicHeightAttribute, 0)); if (!intrinsicSize.isEmpty()) intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height()); return; } // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ element are in percentage units (or omitted), the // aspect ratio is calculated from the width and height values of the ‘viewBox’ specified for the current SVG document // fragment. If the ‘viewBox’ is not correctly specified, or set to 'none', the intrinsic aspect ratio cannot be // calculated and is considered unspecified. intrinsicSize = svg->viewBox().size(); if (!intrinsicSize.isEmpty()) { // The viewBox can only yield an intrinsic ratio, not an intrinsic size. intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height()); intrinsicSize = FloatSize(); return; } // If our intrinsic size is in percentage units, return those to the caller through the intrinsicSize. Notify the caller // about the special situation, by setting isPercentageIntrinsicSize=true, so it knows how to interpret the return values. if (intrinsicWidthAttribute.isPercent() && intrinsicHeightAttribute.isPercent()) { isPercentageIntrinsicSize = true; intrinsicSize = FloatSize(intrinsicWidthAttribute.percent(), intrinsicHeightAttribute.percent()); } }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionUnsuspendRedraw(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); ExceptionCode ec = 0; unsigned suspendHandleId = args.at(0).toInt32(exec); imp->unsuspendRedraw(suspendHandleId, ec); setDOMException(exec, ec); return jsUndefined(); }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionGetEnclosureList(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); FloatRect rect = toSVGRect(args.at(0)); SVGElement* referenceElement = toSVGElement(args.at(1)); JSC::JSValue result = toJS(exec, WTF::getPtr(imp->getEnclosureList(rect, referenceElement))); return result; }
JSValue JSC_HOST_CALL jsSVGSVGElementPrototypeFunctionCheckEnclosure(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.isObject(&JSSVGSVGElement::s_info)) return throwError(exec, TypeError); JSSVGSVGElement* castedThisObj = static_cast<JSSVGSVGElement*>(asObject(thisValue)); SVGSVGElement* imp = static_cast<SVGSVGElement*>(castedThisObj->impl()); SVGElement* element = toSVGElement(args.at(0)); FloatRect rect = toSVGRect(args.at(1)); JSC::JSValue result = jsBoolean(imp->checkEnclosure(element, rect)); return result; }
void SVGDocumentExtensions::dispatchSVGLoadEventToOutermostSVGElements() { WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement>> timeContainers; copyToVector(m_timeContainers, timeContainers); for (const auto& container : timeContainers) { SVGSVGElement* outerSVG = container.get(); if (!outerSVG->isOutermostSVGSVGElement()) continue; // don't dispatch the load event document is not wellformed (for XML/standalone svg) if (outerSVG->document().wellFormed() || !outerSVG->document().isSVGDocument()) outerSVG->sendSVGLoadEventIfPossible(); } }
/* virtual */ nsSize nsSVGOuterSVGFrame::GetIntrinsicRatio() { // We only have an intrinsic size/ratio if our width and height attributes // are both specified and set to non-percentage values, or we have a viewBox // rect: http://www.w3.org/TR/SVGMobile12/coords.html#IntrinsicSizing SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent); nsSVGLength2 &width = content->mLengthAttributes[SVGSVGElement::ATTR_WIDTH]; nsSVGLength2 &height = content->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT]; if (!width.IsPercentage() && !height.IsPercentage()) { nsSize ratio(NSToCoordRoundWithClamp(width.GetAnimValue(content)), NSToCoordRoundWithClamp(height.GetAnimValue(content))); if (ratio.width < 0) { ratio.width = 0; } if (ratio.height < 0) { ratio.height = 0; } return ratio; } SVGViewElement* viewElement = content->GetCurrentViewElement(); const nsSVGViewBoxRect* viewbox = nullptr; // The logic here should match HasViewBox(). if (viewElement && viewElement->mViewBox.HasRect()) { viewbox = &viewElement->mViewBox.GetAnimValue(); } else if (content->mViewBox.HasRect()) { viewbox = &content->mViewBox.GetAnimValue(); } if (viewbox) { float viewBoxWidth = viewbox->width; float viewBoxHeight = viewbox->height; if (viewBoxWidth < 0.0f) { viewBoxWidth = 0.0f; } if (viewBoxHeight < 0.0f) { viewBoxHeight = 0.0f; } return nsSize(NSToCoordRoundWithClamp(viewBoxWidth), NSToCoordRoundWithClamp(viewBoxHeight)); } return nsSVGOuterSVGFrameBase::GetIntrinsicRatio(); }
void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) { SVGSVGElement* rootElement = this->rootElement(); if (!rootElement) return; intrinsicWidth = rootElement->intrinsicWidth(); intrinsicHeight = rootElement->intrinsicHeight(); if (rootElement->preserveAspectRatio().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) return; intrinsicRatio = rootElement->viewBox().size(); if (intrinsicRatio.isEmpty() && intrinsicWidth.isFixed() && intrinsicHeight.isFixed()) intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0)); }
gfxMatrix nsSVGInnerSVGFrame::GetCanvasTM() { if (!mCanvasTM) { NS_ASSERTION(GetParent(), "null parent"); nsSVGContainerFrame *parent = static_cast<nsSVGContainerFrame*>(GetParent()); SVGSVGElement *content = static_cast<SVGSVGElement*>(mContent); gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM()); mCanvasTM = new gfxMatrix(tm); } return *mCanvasTM; }