Chromium Code Reviews| Index: Source/core/paint/LayerPainter.cpp |
| diff --git a/Source/core/paint/LayerPainter.cpp b/Source/core/paint/LayerPainter.cpp |
| index 40083b4f2bc907007d571ea51ba840183f145729..990e96ed143c7c321cd0d2286a73ef4161da2830 100644 |
| --- a/Source/core/paint/LayerPainter.cpp |
| +++ b/Source/core/paint/LayerPainter.cpp |
| @@ -158,6 +158,72 @@ void LayerPainter::paintLayerContentsAndReflection(GraphicsContext* context, con |
| paintLayerContents(context, paintingInfo, localPaintFlags); |
| } |
| +class ClipPathPainter { |
|
mstensho (USE GERRIT)
2014/11/12 21:00:27
Does this class actually paint anything at all? Co
chrishtr
2014/11/12 21:41:45
Done.
|
| +public: |
| + ClipPathPainter(GraphicsContext* context, const RenderLayer& renderLayer, const LayerPaintingInfo& paintingInfo, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed, |
| + const LayoutPoint& offsetFromRoot, PaintLayerFlags paintFlags) |
| + : m_resourceClipper(0), m_clipStateSaver(*context, false), m_renderLayer(renderLayer), m_context(context) |
|
mstensho (USE GERRIT)
2014/11/12 21:00:27
Strange indentation.
chrishtr
2014/11/12 21:41:45
Done.
|
| + { |
| + RenderStyle* style = renderLayer.renderer()->style(); |
| + |
| + // 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 (!renderLayer.renderer()->hasClipPath() || !style || (renderLayer.needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))) |
| + return; |
| + |
| + m_clipperState = RenderSVGResourceClipper::ClipperNotApplied; |
| + |
| + ASSERT(style->clipPath()); |
| + if (style->clipPath()->type() == ClipPathOperation::SHAPE) { |
| + ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath()); |
| + if (clipPath->isValid()) { |
| + m_clipStateSaver.save(); |
| + |
| + if (!rootRelativeBoundsComputed) { |
|
mstensho (USE GERRIT)
2014/11/12 21:00:27
It's tempting to create a getter for this (LayoutR
chrishtr
2014/11/12 21:41:45
I almost pulled the trigger on this in earlier rev
|
| + rootRelativeBounds = renderLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); |
| + rootRelativeBoundsComputed = true; |
| + } |
| + |
| + context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule()); |
| + } |
| + } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) { |
| + ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath()); |
| + Document& document = renderLayer.renderer()->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->renderer()) { |
| + // FIXME: Saving at this point is not required in the 'mask'- |
| + // case, or if the clip ends up empty. |
| + m_clipStateSaver.save(); |
| + if (!rootRelativeBoundsComputed) { |
| + rootRelativeBounds = renderLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); |
| + rootRelativeBoundsComputed = true; |
| + } |
| + |
| + m_resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer())); |
| + if (!m_resourceClipper->applyClippingToContext(renderLayer.renderer(), rootRelativeBounds, |
| + paintingInfo.paintDirtyRect, context, m_clipperState)) { |
| + // No need to post-apply the clipper if this failed. |
| + m_resourceClipper = 0; |
| + } |
| + } |
| + } |
| + } |
| + |
| + ~ClipPathPainter() |
| + { |
| + if (m_resourceClipper) |
| + m_resourceClipper->postApplyStatefulResource(m_renderLayer.renderer(), m_context, m_clipperState); |
| + } |
| +private: |
| + RenderSVGResourceClipper* m_resourceClipper; |
| + GraphicsContextStateSaver m_clipStateSaver; |
| + RenderSVGResourceClipper::ClipperState m_clipperState; |
| + const RenderLayer& m_renderLayer; |
| + GraphicsContext* m_context; |
| +}; |
| + |
| void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) |
| { |
| ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingLayerDescendant()); |
| @@ -199,52 +265,7 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
| LayoutRect rootRelativeBounds; |
| bool rootRelativeBoundsComputed = false; |
| - // Apply clip-path to context. |
| - GraphicsContextStateSaver clipStateSaver(*context, false); |
| - RenderStyle* style = m_renderLayer.renderer()->style(); |
| - RenderSVGResourceClipper* resourceClipper = 0; |
| - RenderSVGResourceClipper::ClipperState clipperState = RenderSVGResourceClipper::ClipperNotApplied; |
| - |
| - // 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 (m_renderLayer.renderer()->hasClipPath() && style && (!m_renderLayer.needsCompositedScrolling() || paintFlags & PaintLayerPaintingChildClippingMaskPhase)) { |
| - ASSERT(style->clipPath()); |
| - if (style->clipPath()->type() == ClipPathOperation::SHAPE) { |
| - ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath()); |
| - if (clipPath->isValid()) { |
| - clipStateSaver.save(); |
| - |
| - if (!rootRelativeBoundsComputed) { |
| - rootRelativeBounds = m_renderLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); |
| - rootRelativeBoundsComputed = true; |
| - } |
| - |
| - context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule()); |
| - } |
| - } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) { |
| - ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath()); |
| - Document& document = m_renderLayer.renderer()->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->renderer()) { |
| - // FIXME: Saving at this point is not required in the 'mask'- |
| - // case, or if the clip ends up empty. |
| - clipStateSaver.save(); |
| - if (!rootRelativeBoundsComputed) { |
| - rootRelativeBounds = m_renderLayer.physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); |
| - rootRelativeBoundsComputed = true; |
| - } |
| - |
| - resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer())); |
| - if (!resourceClipper->applyClippingToContext(m_renderLayer.renderer(), rootRelativeBounds, |
| - paintingInfo.paintDirtyRect, context, clipperState)) { |
| - // No need to post-apply the clipper if this failed. |
| - resourceClipper = 0; |
| - } |
| - } |
| - } |
| - } |
| + ClipPathPainter clipPathPainter(context, m_renderLayer, paintingInfo, rootRelativeBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); |
| // Blending operations must be performed only with the nearest ancestor stacking context. |
| // Note that there is no need to create a transparency layer if we're painting the root. |
| @@ -354,9 +375,6 @@ void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint |
| context->restore(); |
| m_renderLayer.setUsedTransparency(false); |
| } |
| - |
| - if (resourceClipper) |
| - resourceClipper->postApplyStatefulResource(m_renderLayer.renderer(), context, clipperState); |
| } |
| static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer) |