Exemple #1
0
void RenderSVGShape::layout()
{
    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());

    bool updateCachedBoundariesInParents = false;

    bool needsShapeUpdate = m_needsShapeUpdate;
    if (needsShapeUpdate || m_needsBoundariesUpdate) {
        setIsPaintingFallback(false);
        m_path.clear();
        createShape();
        m_needsShapeUpdate = 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);
        m_markerLayoutInfo.clear();
    }

    // At this point LayoutRepainter already grabbed the old bounds,
    // recalculate them now so repaintAfterLayout() uses the new bounds.
    if (needsShapeUpdate || m_needsBoundariesUpdate) {
        updateCachedBoundaries();
        m_needsBoundariesUpdate = false;
    }

    // If our bounds changed, notify the parents.
    if (updateCachedBoundariesInParents)
        RenderSVGModelObject::setNeedsBoundariesUpdate();

    repainter.repaintAfterLayout();
    setNeedsLayout(false);
}
void RenderSVGRect::createShape()
{
    // Before creating a new object we need to clear the cached bounding box
    // to avoid using garbage.
    m_boundingBox = FloatRect();
    m_innerStrokeRect = FloatRect();
    m_outerStrokeRect = FloatRect();
    SVGRectElement* rect = static_cast<SVGRectElement*>(node());
    ASSERT(rect);

    bool nonScalingStroke = style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE;
    // Fallback to RenderSVGShape if rect has rounded corners.
    if (rect->hasAttribute(SVGNames::rxAttr) || rect->hasAttribute(SVGNames::ryAttr) || nonScalingStroke) {
       RenderSVGShape::createShape();
       setIsPaintingFallback(true);
       return;
    }

    SVGLengthContext lengthContext(rect);
    FloatSize boundingBoxSize(rect->width().value(lengthContext), rect->height().value(lengthContext));
    if (boundingBoxSize.isEmpty())
        return;

    m_boundingBox = FloatRect(FloatPoint(rect->x().value(lengthContext), rect->y().value(lengthContext)), boundingBoxSize);

    // To decide if the stroke contains a point we create two rects which represent the inner and
    // the outer stroke borders. A stroke contains the point, if the point is between them.
    m_innerStrokeRect = m_boundingBox;
    m_outerStrokeRect = m_boundingBox;

    if (style()->svgStyle()->hasStroke()) {
        float strokeWidth = this->strokeWidth();
        m_innerStrokeRect.inflate(-strokeWidth / 2);
        m_outerStrokeRect.inflate(strokeWidth / 2);
    }
}