blob: f726d738dde9202d015ac1259241dbaaa383f718 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/paint/SVGMaskPainter.h"
#include "core/layout/svg/LayoutSVGResourceMasker.h"
#include "core/paint/CompositingRecorder.h"
#include "core/paint/LayoutObjectDrawingRecorder.h"
#include "core/paint/PaintInfo.h"
#include "core/paint/TransformRecorder.h"
#include "platform/graphics/paint/CompositingDisplayItem.h"
#include "platform/graphics/paint/DrawingDisplayItem.h"
#include "platform/graphics/paint/PaintController.h"
namespace blink {
bool SVGMaskPainter::prepareEffect(const LayoutObject& object, GraphicsContext& context)
{
ASSERT(m_mask.style());
ASSERT_WITH_SECURITY_IMPLICATION(!m_mask.needsLayout());
m_mask.clearInvalidationMask();
FloatRect paintInvalidationRect = object.paintInvalidationRectInLocalCoordinates();
if (paintInvalidationRect.isEmpty() || !m_mask.element()->hasChildren())
return false;
context.paintController().createAndAppend<BeginCompositingDisplayItem>(object, SkXfermode::kSrcOver_Mode, 1, &paintInvalidationRect);
return true;
}
void SVGMaskPainter::finishEffect(const LayoutObject& object, GraphicsContext& context)
{
ASSERT(m_mask.style());
ASSERT_WITH_SECURITY_IMPLICATION(!m_mask.needsLayout());
FloatRect paintInvalidationRect = object.paintInvalidationRectInLocalCoordinates();
{
ColorFilter maskLayerFilter = m_mask.style()->svgStyle().maskType() == MT_LUMINANCE
? ColorFilterLuminanceToAlpha : ColorFilterNone;
CompositingRecorder maskCompositing(context, object, SkXfermode::kDstIn_Mode, 1, &paintInvalidationRect, maskLayerFilter);
drawMaskForLayoutObject(context, object, object.objectBoundingBox(), paintInvalidationRect);
}
context.paintController().endItem<EndCompositingDisplayItem>(object);
}
void SVGMaskPainter::drawMaskForLayoutObject(GraphicsContext& context, const LayoutObject& layoutObject, const FloatRect& targetBoundingBox, const FloatRect& targetPaintInvalidationRect)
{
AffineTransform contentTransformation;
RefPtr<const SkPicture> maskContentPicture = m_mask.createContentPicture(contentTransformation, targetBoundingBox, context);
if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(context, layoutObject, DisplayItem::SVGMask, LayoutPoint()))
return;
LayoutObjectDrawingRecorder drawingRecorder(context, layoutObject, DisplayItem::SVGMask, targetPaintInvalidationRect, LayoutPoint());
context.save();
context.concatCTM(contentTransformation);
context.drawPicture(maskContentPicture.get());
context.restore();
}
}