void RenderSVGContainer::paint(PaintInfo& paintInfo, int parentX, int parentY) { if (paintInfo.context->paintingDisabled() || !drawsContents()) return; // Spec: groups w/o children still may render filter content. if (!firstChild() && !selfWillPaint()) return; paintInfo.context->save(); applyContentTransforms(paintInfo); SVGResourceFilter* filter = 0; PaintInfo savedInfo(paintInfo); FloatRect boundingBox = relativeBBox(true); if (paintInfo.phase == PaintPhaseForeground) prepareToRenderSVGContent(this, paintInfo, boundingBox, filter); applyAdditionalTransforms(paintInfo); // default implementation. Just pass paint through to the children PaintInfo childInfo(paintInfo); childInfo.paintingRoot = paintingRootForChildren(paintInfo); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) child->paint(childInfo, 0, 0); if (paintInfo.phase == PaintPhaseForeground) finishRenderSVGContent(this, paintInfo, boundingBox, filter, savedInfo.context); paintInfo.context->restore(); if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE) paintOutline(paintInfo.context, m_absoluteBounds.x(), m_absoluteBounds.y(), m_absoluteBounds.width(), m_absoluteBounds.height(), style()); }
void RenderSVGContainer::layout() { ASSERT(needsLayout()); // RenderSVGRoot disables layoutState for the SVG rendering tree. ASSERT(!view()->layoutStateEnabled()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout() || selfWillPaint()); // Allow RenderSVGViewportContainer to update its viewport. calcViewport(); // Allow RenderSVGTransformableContainer to update its transform. bool updatedTransform = calculateLocalTransform(); SVGRenderSupport::layoutChildren(this, selfNeedsLayout() || SVGRenderSupport::filtersForceContainerLayout(this)); // Invalidate all resources of this client if our layout changed. if (everHadLayout() && needsLayout()) SVGResourcesCache::clientLayoutChanged(this); // At this point LayoutRepainter already grabbed the old bounds, // recalculate them now so repaintAfterLayout() uses the new bounds. if (m_needsBoundariesUpdate || updatedTransform) { updateCachedBoundaries(); m_needsBoundariesUpdate = false; // If our bounds changed, notify the parents. RenderSVGModelObject::setNeedsBoundariesUpdate(); } repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderSVGContainer::layout() { ASSERT(needsLayout()); ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree. calcViewport(); // Allow RenderSVGViewportContainer to update its viewport LayoutRepainter repainter(*this, checkForRepaintDuringLayout() || selfWillPaint()); calculateLocalTransform(); // Allow RenderSVGTransformableContainer to update its transform for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { // Only force our kids to layout if we're being asked to relayout as a result of a parent changing // FIXME: We should be able to skip relayout of non-relative kids when only bounds size has changed // that's a possible future optimization using LayoutState // http://bugs.webkit.org/show_bug.cgi?id=15391 if (selfNeedsLayout()) child->setNeedsLayout(true); child->layoutIfNeeded(); ASSERT(!child->needsLayout()); } repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&) { ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this); if (paintInfo.context->paintingDisabled()) return; // Spec: groups w/o children still may render filter content. if (!firstChild() && !selfWillPaint()) return; FloatRect repaintRect = repaintRectInLocalCoordinates(); if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(repaintRect, localToParentTransform(), paintInfo)) return; PaintInfo childPaintInfo(paintInfo); { GraphicsContextStateSaver stateSaver(*childPaintInfo.context); // Let the RenderSVGViewportContainer subclass clip if necessary applyViewportClip(childPaintInfo); childPaintInfo.applyTransform(localToParentTransform()); SVGRenderingContext renderingContext; GraphicsContextCullSaver cullSaver(*childPaintInfo.context); bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) { renderingContext.prepareToRenderSVGContent(this, childPaintInfo); continueRendering = renderingContext.isRenderingPrepared(); if (continueRendering && document().settings()->containerCullingEnabled()) cullSaver.cull(repaintRectInLocalCoordinates()); } if (continueRendering) { childPaintInfo.updatePaintingRootForChildren(this); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) child->paint(childPaintInfo, IntPoint()); } } // FIXME: This really should be drawn from local coordinates, but currently we hack it // to avoid our clip killing our outline rect. Thus we translate our // outline rect into parent coords before drawing. // FIXME: This means our focus ring won't share our rotation like it should. // We should instead disable our clip during PaintPhaseOutline if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE) { IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRect)); paintOutline(paintInfo, paintRectInParent); } }
void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY) { if (paintInfo.context->paintingDisabled()) return; bool isVisible = style()->visibility() == VISIBLE; IntPoint parentOriginInContainer(parentX, parentY); IntPoint borderBoxOriginInContainer = parentOriginInContainer + parentOriginToBorderBox(); if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground) && isVisible) paintBoxDecorations(paintInfo, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y()); if (paintInfo.phase == PaintPhaseBlockBackground) return; // An empty viewport disables rendering. FIXME: Should we still render filters? if (m_viewportSize.isEmpty()) return; // Don't paint if we don't have kids, except if we have filters we should paint those. if (!firstChild() && !selfWillPaint()) return; // Make a copy of the PaintInfo because applyTransform will modify the damage rect. PaintInfo childPaintInfo(paintInfo); childPaintInfo.context->save(); // Apply initial viewport clip - not affected by overflow handling childPaintInfo.context->clip(overflowClipRect(borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y())); // Convert from container offsets (html renderers) to a relative transform (svg renderers). // Transform from our paint container's coordinate system to our local coords. childPaintInfo.applyTransform(localToRepaintContainerTransform(parentOriginInContainer)); bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) continueRendering = SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo); if (continueRendering) RenderBox::paint(childPaintInfo, 0, 0); if (childPaintInfo.phase == PaintPhaseForeground) SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, paintInfo.context); childPaintInfo.context->restore(); if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && isVisible) paintOutline(paintInfo.context, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y(), width(), height()); }
void RenderSVGContainer::layout() { ASSERT(needsLayout()); ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree. calcViewport(); // Allow RenderSVGViewportContainer to update its viewport LayoutRepainter repainter(*this, checkForRepaintDuringLayout() || selfWillPaint()); calculateLocalTransform(); // Allow RenderSVGTransformableContainer to update its transform layoutChildren(this, selfNeedsLayout()); repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int) { if (paintInfo.context->paintingDisabled() || !drawsContents()) return; // Spec: groups w/o children still may render filter content. if (!firstChild() && !selfWillPaint()) return; FloatRect repaintRect = repaintRectInLocalCoordinates(); if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(repaintRect, localToParentTransform(), paintInfo)) return; PaintInfo childPaintInfo(paintInfo); childPaintInfo.context->save(); // Let the RenderSVGViewportContainer subclass clip if necessary applyViewportClip(childPaintInfo); childPaintInfo.applyTransform(localToParentTransform()); bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) continueRendering = SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo); if (continueRendering) { childPaintInfo.updatePaintingRootForChildren(this); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) child->paint(childPaintInfo, 0, 0); } if (paintInfo.phase == PaintPhaseForeground) SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, paintInfo.context); childPaintInfo.context->restore(); // FIXME: This really should be drawn from local coordinates, but currently we hack it // to avoid our clip killing our outline rect. Thus we translate our // outline rect into parent coords before drawing. // FIXME: This means our focus ring won't share our rotation like it should. // We should instead disable our clip during PaintPhaseOutline if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE) { IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRect)); paintOutline(paintInfo.context, paintRectInParent.x(), paintRectInParent.y(), paintRectInParent.width(), paintRectInParent.height()); } }
void RenderSVGContainer::layout() { ASSERT(needsLayout()); // Arbitrary affine transforms are incompatible with LayoutState. view()->disableLayoutState(); IntRect oldBounds; IntRect oldOutlineBox; bool checkForRepaint = checkForRepaintDuringLayout() && selfWillPaint(); if (checkForRepaint) { oldBounds = m_absoluteBounds; oldOutlineBox = absoluteOutlineBounds(); } calculateLocalTransform(); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { // Only force our kids to layout if we're being asked to relayout as a result of a parent changing // FIXME: We should be able to skip relayout of non-relative kids when only bounds size has changed // that's a possible future optimization using LayoutState // http://bugs.webkit.org/show_bug.cgi?id=15391 if (selfNeedsLayout()) child->setNeedsLayout(true); child->layoutIfNeeded(); ASSERT(!child->needsLayout()); } calcBounds(); if (checkForRepaint) repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox); view()->enableLayoutState(); setNeedsLayout(false); }