void RenderSVGShape::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) && selfNeedsLayout()); bool updateCachedBoundariesInParents = false; if (m_needsShapeUpdate || m_needsBoundariesUpdate) { updateShapeFromElement(); m_needsShapeUpdate = false; updateRepaintBoundingBox(); m_needsBoundariesUpdate = false; updateCachedBoundariesInParents = true; } if (m_needsTransformUpdate) { m_localTransform = graphicsElement().animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } // Invalidate all resources of this client if our layout changed. if (everHadLayout() && selfNeedsLayout()) SVGResourcesCache::clientLayoutChanged(*this); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGModelObject::setNeedsBoundariesUpdate(); repainter.repaintAfterLayout(); clearNeedsLayout(); }
bool RenderSVGTransformableContainer::calculateLocalTransform() { SVGGraphicsElement& element = graphicsElement(); // If we're either the renderer for a <use> element, or for any <g> element inside the shadow // tree, that was created during the use/symbol/svg expansion in SVGUseElement. These containers // need to respect the translations induced by their corresponding use elements x/y attributes. SVGUseElement* useElement = nullptr; if (is<SVGUseElement>(element)) useElement = &downcast<SVGUseElement>(element); else if (element.isInShadowTree() && is<SVGGElement>(element)) { SVGElement* correspondingElement = element.correspondingElement(); if (is<SVGUseElement>(correspondingElement)) useElement = downcast<SVGUseElement>(correspondingElement); } if (useElement) { SVGLengthContext lengthContext(useElement); FloatSize translation(useElement->x().value(lengthContext), useElement->y().value(lengthContext)); if (translation != m_lastTranslation) m_needsTransformUpdate = true; m_lastTranslation = translation; } m_didTransformToRootUpdate = m_needsTransformUpdate || SVGRenderSupport::transformToRootChanged(parent()); if (!m_needsTransformUpdate) return false; m_localTransform = element.animatedLocalTransform(); m_localTransform.translate(m_lastTranslation.width(), m_lastTranslation.height()); m_needsTransformUpdate = false; return true; }
void RenderSVGEllipse::calculateRadiiAndCenter() { SVGLengthContext lengthContext(&graphicsElement()); m_center = FloatPoint( lengthContext.valueForLength(style().svgStyle().cx(), LengthModeWidth), lengthContext.valueForLength(style().svgStyle().cy(), LengthModeHeight)); if (is<SVGCircleElement>(graphicsElement())) { float radius = lengthContext.valueForLength(style().svgStyle().r()); m_radii = FloatSize(radius, radius); return; } ASSERT(is<SVGEllipseElement>(graphicsElement())); m_radii = FloatSize( lengthContext.valueForLength(style().svgStyle().rx(), LengthModeWidth), lengthContext.valueForLength(style().svgStyle().ry(), LengthModeHeight)); }
void RenderSVGEllipse::calculateRadiiAndCenter() { if (isSVGCircleElement(graphicsElement())) { SVGCircleElement& circle = toSVGCircleElement(graphicsElement()); SVGLengthContext lengthContext(&circle); float radius = circle.r().value(lengthContext); m_radii = FloatSize(radius, radius); m_center = FloatPoint(circle.cx().value(lengthContext), circle.cy().value(lengthContext)); return; } ASSERT(isSVGEllipseElement(graphicsElement())); SVGEllipseElement& ellipse = toSVGEllipseElement(graphicsElement()); SVGLengthContext lengthContext(&ellipse); m_radii = FloatSize(ellipse.rx().value(lengthContext), ellipse.ry().value(lengthContext)); m_center = FloatPoint(ellipse.cx().value(lengthContext), ellipse.cy().value(lengthContext)); }
void RenderSVGShape::updateShapeFromElement() { m_path = std::make_unique<Path>(); ASSERT(RenderSVGShape::isEmpty()); updatePathFromGraphicsElement(&graphicsElement(), path()); processMarkerPositions(); m_fillBoundingBox = calculateObjectBoundingBox(); m_strokeBoundingBox = calculateStrokeBoundingBox(); }
void RenderSVGShape::updateShapeFromElement() { m_path.clear(); m_path = adoptPtr(new Path); ASSERT(RenderSVGShape::isEmpty()); updatePathFromGraphicsElement(&graphicsElement(), path()); processMarkerPositions(); m_fillBoundingBox = calculateObjectBoundingBox(); m_strokeBoundingBox = calculateStrokeBoundingBox(); }
bool RenderSVGShape::shouldGenerateMarkerPositions() const { if (!style().svgStyle().hasMarkers()) return false; if (!graphicsElement().supportsMarkers()) return false; auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this); if (!resources) return false; return resources->markerStart() || resources->markerMid() || resources->markerEnd(); }
float RenderSVGShape::strokeWidth() const { SVGLengthContext lengthContext(&graphicsElement()); return lengthContext.valueForLength(style().svgStyle().strokeWidth()); }
AffineTransform RenderSVGShape::nonScalingStrokeTransform() const { return graphicsElement().getScreenCTM(SVGLocatable::DisallowStyleUpdate); }