void RenderPath::layout() { LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout()); SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); bool needsPathUpdate = m_needsPathUpdate; if (needsPathUpdate) { m_path = element->toPathData(); m_needsPathUpdate = false; } if (m_needsTransformUpdate) { m_localTransform = element->animatedLocalTransform(); m_needsTransformUpdate = false; } // Invalidate all resources of this client if our layout changed. if (m_everHadLayout && selfNeedsLayout()) SVGResourcesCache::clientLayoutChanged(this); // At this point LayoutRepainter already grabbed the old bounds, // recalculate them now so repaintAfterLayout() uses the new bounds if (needsPathUpdate || m_needsBoundariesUpdate) { updateCachedBoundaries(); m_needsBoundariesUpdate = false; } repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderSVGShape::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) && selfNeedsLayout()); SVGStyledTransformableElement* element = toSVGStyledTransformableElement(node()); bool updateCachedBoundariesInParents = false; if (m_needsShapeUpdate || m_needsBoundariesUpdate) { updateShapeFromElement(); m_needsShapeUpdate = false; updateRepaintBoundingBox(); m_needsBoundariesUpdate = false; updateCachedBoundariesInParents = true; } if (m_needsTransformUpdate) { m_localTransform = element->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(); setNeedsLayout(false); }
SVGResource* SVGClipPathElement::canvasResource() { if (!m_clipper) m_clipper = SVGResourceClipper::create(); else m_clipper->resetClipData(); bool bbox = clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; RenderStyle* clipPathStyle = styleForRenderer(parent()->renderer()); // FIXME: Manual style resolution is a hack for (Node* n = firstChild(); n; n = n->nextSibling()) { if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) { SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(n); RenderStyle* pathStyle = document()->styleSelector()->styleForElement(styled, clipPathStyle); if (pathStyle->display() != NONE) { Path pathData = styled->toClipPath(); // FIXME: How do we know the element has done a layout? pathData.transform(styled->animatedLocalTransform()); if (!pathData.isEmpty()) m_clipper->addClipData(pathData, pathStyle->svgStyle()->clipRule(), bbox); } pathStyle->deref(document()->renderArena()); } } if (m_clipper->clipData().isEmpty()) { Path pathData; pathData.addRect(FloatRect()); m_clipper->addClipData(pathData, RULE_EVENODD, bbox); } clipPathStyle->deref(document()->renderArena()); return m_clipper.get(); }
bool RenderSVGTransformableContainer::calculateLocalTransform() { SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); // 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 = 0; if (element->hasTagName(SVGNames::useTag)) useElement = static_cast<SVGUseElement*>(element); else if (element->isInShadowTree() && element->hasTagName(SVGNames::gTag)) { SVGElement* correspondingElement = element->correspondingElement(); if (correspondingElement && correspondingElement->hasTagName(SVGNames::useTag)) useElement = static_cast<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 RenderPath::layout() { LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout()); SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); m_localTransform = element->animatedLocalTransform(); setPath(element->toPathData()); repainter.repaintAfterLayout(); setNeedsLayout(false); }
bool RenderSVGTransformableContainer::calculateLocalTransform() { SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); bool needsUpdate = m_needsTransformUpdate; if (needsUpdate) { m_localTransform = element->animatedLocalTransform(); m_needsTransformUpdate = false; } if (!element->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(element)->isShadowTreeContainerElement()) return needsUpdate; FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(element)->containerTranslation(); if (translation.width() == 0 && translation.height() == 0) return needsUpdate; // FIXME: Could optimize this case for use to avoid refetching the animatedLocalTransform() here, if only the containerTranslation() changed. if (!needsUpdate) m_localTransform = element->animatedLocalTransform(); m_localTransform.translate(translation.width(), translation.height()); return true; }
void RenderSVGPath::layout() { LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout()); SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); bool updateCachedBoundariesInParents = false; bool needsPathUpdate = m_needsPathUpdate; if (needsPathUpdate) { m_path.clear(); element->toPathData(m_path); m_needsPathUpdate = false; updateCachedBoundariesInParents = true; } if (m_needsTransformUpdate) { m_localTransform = element->animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } if (m_needsBoundariesUpdate) updateCachedBoundariesInParents = true; // Invalidate all resources of this client if our layout changed. if (m_everHadLayout && selfNeedsLayout()) { SVGResourcesCache::clientLayoutChanged(this); m_markerLayoutInfo.clear(); } // At this point LayoutRepainter already grabbed the old bounds, // recalculate them now so repaintAfterLayout() uses the new bounds. if (needsPathUpdate || m_needsBoundariesUpdate) { updateCachedBoundaries(); m_needsBoundariesUpdate = false; } // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGModelObject::setNeedsBoundariesUpdate(); repainter.repaintAfterLayout(); setNeedsLayout(false); }