void RenderReplaced::adjustOverflowForBoxShadowAndReflect() { IntRect overflow; for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { if (boxShadow->style == Inset) continue; IntRect shadow = borderBoxRect(); shadow.move(boxShadow->x, boxShadow->y); shadow.inflate(boxShadow->blur + boxShadow->spread); overflow.unite(shadow); } // Now that we have an overflow rect including shadow, let's make sure that // the reflection (which can also include the shadow) is also included. if (hasReflection()) { if (overflow.isEmpty()) overflow = borderBoxRect(); overflow.unite(reflectedRect(overflow)); } if (!overflow.isEmpty()) { if (!gOverflowRectMap) gOverflowRectMap = new OverflowRectMap(); overflow.unite(borderBoxRect()); gOverflowRectMap->set(this, overflow); setReplacedHasOverflow(true); } else if (replacedHasOverflow()) { gOverflowRectMap->remove(this); setReplacedHasOverflow(false); } }
IntRect RenderReplaced::overflowRect(bool) const { if (replacedHasOverflow()) return gOverflowRectMap->find(this)->second; return borderBoxRect(); }
LayoutRect RenderSVGBlock::visualOverflowRect() const { LayoutRect borderRect = borderBoxRect(); if (const ShadowList* textShadow = style()->textShadow()) textShadow->adjustRectForShadow(borderRect); return borderRect; }
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& adjustedPaintOffset) { // An empty viewport disables rendering. if (borderBoxRect().isEmpty()) return; // Don't paint, if the context explicitely disabled it. if (paintInfo.context->paintingDisabled()) return; Page* page = 0; if (Frame* frame = this->frame()) page = frame->page(); // 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()) { if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantUnpaintedObject(this, visualOverflowRect()); return; } } if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantRepaintedObject(this, visualOverflowRect()); // 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(adjustedPaintOffset, paintInfo.renderRegion)); // 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(AffineTransform::translation(adjustedPaintOffset.x() - x(), adjustedPaintOffset.y() - y()) * localToParentTransform()); 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(); }
LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const { if (style().visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) return LayoutRect(); FloatRect contentRepaintRect = m_localToBorderBoxTransform.mapRect(repaintRectInLocalCoordinates()); contentRepaintRect.intersect(snappedIntRect(borderBoxRect())); LayoutRect repaintRect = enclosingLayoutRect(contentRepaintRect); if (m_hasBoxDecorations || hasRenderOverflow()) repaintRect.unite(unionRect(localSelectionRect(false), visualOverflowRect())); return RenderReplaced::computeRectForRepaint(enclosingIntRect(repaintRect), repaintContainer); }
void RenderSVGRoot::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { if (paintInfo.context->paintingDisabled()) return; bool isVisible = style()->visibility() == VISIBLE; LayoutPoint borderBoxOriginInContainer = paintOffset + parentOriginToBorderBox(); if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground) && isVisible) paintBoxDecorations(paintInfo, borderBoxOriginInContainer); if (paintInfo.phase == PaintPhaseBlockBackground) return; // An empty viewport disables rendering. if (borderBoxRect().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, paintInfo.renderRegion)); // 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(paintOffset)); bool continueRendering = true; if (childPaintInfo.phase == PaintPhaseForeground) continueRendering = SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo); if (continueRendering) RenderBox::paint(childPaintInfo, LayoutPoint()); 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, LayoutRect(borderBoxOriginInContainer, size())); }
void RenderSVGRoot::computeFloatRectForRepaint(RenderBoxModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const { // Apply our local transforms (except for x/y translation), then our shadow, // and then call RenderBox's method to handle all the normal CSS Box model bits repaintRect = m_localToBorderBoxTransform.mapRect(repaintRect); // Apply initial viewport clip - not affected by overflow settings repaintRect.intersect(borderBoxRect()); const SVGRenderStyle* svgStyle = style()->svgStyle(); if (const ShadowData* shadow = svgStyle->shadow()) shadow->adjustRectForShadow(repaintRect); LayoutRect rect = enclosingIntRect(repaintRect); RenderReplaced::computeRectForRepaint(repaintContainer, rect, fixed); repaintRect = rect; }
FloatRect RenderSVGRoot::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const { // Apply our local transforms (except for x/y translation), then our shadow, // and then call RenderBox's method to handle all the normal CSS Box model bits FloatRect adjustedRect = m_localToBorderBoxTransform.mapRect(repaintRect); const SVGRenderStyle& svgStyle = style().svgStyle(); if (const ShadowData* shadow = svgStyle.shadow()) shadow->adjustRectForShadow(adjustedRect); // Apply initial viewport clip if (shouldApplyViewportClip()) adjustedRect.intersect(snappedIntRect(borderBoxRect())); if (m_hasBoxDecorations || hasRenderOverflow()) { // The selectionRect can project outside of the overflowRect, so take their union // for repainting to avoid selection painting glitches. LayoutRect decoratedRepaintRect = unionRect(localSelectionRect(false), visualOverflowRect()); adjustedRect.unite(decoratedRepaintRect); } return RenderReplaced::computeRectForRepaint(enclosingIntRect(adjustedRect), repaintContainer, {fixed, false}); }
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset) { // An empty viewport disables rendering. if (borderBoxRect().isEmpty()) return; // Don't paint, if the context explicitly disabled it. if (paintInfo.context().paintingDisabled()) return; // SVG outlines are painted during PaintPhaseForeground. if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) return; // An empty viewBox also disables rendering. // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute) if (svgSVGElement().hasEmptyViewBox()) return; Page* page = frame().page(); // Don't paint if we don't have kids, except if we have filters we should paint those. if (!firstChild()) { auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this); if (!resources || !resources->filter()) { if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantUnpaintedObject(this, visualOverflowRect()); return; } } if (page && paintInfo.phase == PaintPhaseForeground) page->addRelevantRepaintedObject(this, visualOverflowRect()); // 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(snappedIntRect(overflowClipRect(paintOffset, currentRenderNamedFlowFragment()))); // 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) { childPaintInfo.updateSubtreePaintRootForChildren(this); for (auto& child : childrenOfType<RenderElement>(*this)) child.paint(childPaintInfo, location()); } } childPaintInfo.context().restore(); }