ClipPathHelper(GraphicsContext* context, const PaintLayer& paintLayer, PaintLayerPaintingInfo& paintingInfo, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed, const LayoutPoint& offsetFromRoot, PaintLayerFlags paintFlags) : m_resourceClipper(0), m_paintLayer(paintLayer), m_context(context) { const ComputedStyle& style = paintLayer.layoutObject()->styleRef(); // Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container. // It must, however, still be applied to the mask layer, so that the compositor can properly mask the // scrolling contents and scrollbars. if (!paintLayer.layoutObject()->hasClipPath() || (paintLayer.needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))) return; m_clipperState = SVGClipPainter::ClipperNotApplied; paintingInfo.ancestorHasClipPathClipping = true; ASSERT(style.clipPath()); if (style.clipPath()->type() == ClipPathOperation::SHAPE) { ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style.clipPath()); if (clipPath->isValid()) { if (!rootRelativeBoundsComputed) { rootRelativeBounds = paintLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(offsetFromRoot); rootRelativeBoundsComputed = true; } m_clipPathRecorder.emplace(*context, *paintLayer.layoutObject(), clipPath->path(FloatRect(rootRelativeBounds))); } } else if (style.clipPath()->type() == ClipPathOperation::REFERENCE) { ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style.clipPath()); Document& document = paintLayer.layoutObject()->document(); // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405) Element* element = document.getElementById(referenceClipPathOperation->fragment()); if (isSVGClipPathElement(element) && element->layoutObject()) { if (!rootRelativeBoundsComputed) { rootRelativeBounds = paintLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(offsetFromRoot); rootRelativeBoundsComputed = true; } m_resourceClipper = toLayoutSVGResourceClipper(toLayoutSVGResourceContainer(element->layoutObject())); if (!SVGClipPainter(*m_resourceClipper).prepareEffect(*paintLayer.layoutObject(), FloatRect(rootRelativeBounds), FloatRect(rootRelativeBounds), context, m_clipperState)) { // No need to post-apply the clipper if this failed. m_resourceClipper = 0; } } } }
bool ReferenceClipPathOperation::operator==(const ClipPathOperation& o) const { if (!isSameType(o)) return false; const ReferenceClipPathOperation& other = toReferenceClipPathOperation(o); return m_elementProxy == other.m_elementProxy && m_url == other.m_url; }