Bug 1234485 - Part 3. Implement nsSVGIntegrationUtils::PaintMask.
Unlike nsSVGIntegrationUtils::PaintMaskAndClipPath, which paints masked content
onto aParam.ctx, nsSVGIntegrationUtils::PaintMask paints only mask, no content,
onto aParams.ctx.
MozReview-Commit-ID: BaRbtHpoHzj
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -745,16 +745,70 @@ nsSVGIntegrationUtils::IsMaskResourceRea
}
}
// Either all mask resources are ready, or no mask resource is needed.
return true;
}
DrawResult
+nsSVGIntegrationUtils::PaintMask(const PaintFramesParams& aParams)
+{
+ MaskUsage maskUsage;
+ DetermineMaskUsage(aParams.frame, aParams.handleOpacity, maskUsage);
+ MOZ_ASSERT(maskUsage.shouldGenerateMaskLayer);
+
+ nsIFrame* frame = aParams.frame;
+ DrawResult result = DrawResult::SUCCESS;
+ if (!ValidateSVGFrame(frame)) {
+ return result;
+ }
+
+ if (maskUsage.opacity == 0.0f) {
+ return DrawResult::SUCCESS;
+ }
+
+ gfxContext& ctx = aParams.ctx;
+
+ Matrix maskTransform;
+ RefPtr<SourceSurface> maskSurface;
+
+ gfxContextMatrixAutoSaveRestore matSR(&ctx);
+
+ nsIFrame* firstFrame =
+ nsLayoutUtils::FirstContinuationOrIBSplitSibling(frame);
+ nsSVGEffects::EffectProperties effectProperties =
+ nsSVGEffects::GetEffectProperties(firstFrame);
+ nsTArray<nsSVGMaskFrame *> maskFrames = effectProperties.GetMaskFrames();
+ bool opacityApplied = false;
+
+ nsPoint offsetToBoundingBox;
+ nsPoint offsetToUserSpace;
+ SetupContextMatrix(frame, aParams, offsetToBoundingBox,
+ offsetToUserSpace, false);
+ result = GenerateMaskSurface(aParams, maskUsage.opacity,
+ firstFrame->StyleContext(),
+ maskFrames, offsetToUserSpace,
+ maskTransform, maskSurface, opacityApplied);
+ if (!maskSurface) {
+ // Entire surface is clipped out.
+ return result;
+ }
+
+ ctx.Multiply(ThebesMatrix(maskTransform));
+
+ DrawTarget* target = ctx.GetDrawTarget();
+ MOZ_ASSERT(target->GetFormat() == SurfaceFormat::A8);
+ Rect drawingRect(Point(0, 0), Size(target->GetSize()));
+ target->DrawSurface(maskSurface, drawingRect, drawingRect);
+
+ return result;
+}
+
+DrawResult
nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
{
MOZ_ASSERT(UsingMaskOrClipPathForFrame(aParams.frame),
"Should not use this method when no mask or clipPath effect"
"on this frame");
/* SVG defines the following rendering model:
*
--- a/layout/svg/nsSVGIntegrationUtils.h
+++ b/layout/svg/nsSVGIntegrationUtils.h
@@ -155,16 +155,23 @@ public:
};
/**
* Paint non-SVG frame with mask, clipPath and opacity effect.
*/
static DrawResult
PaintMaskAndClipPath(const PaintFramesParams& aParams);
+ /**
+ * Paint mask of non-SVG frame onto a given context, aParams.ctx.
+ * aParams.ctx must contain an A8 surface.
+ */
+ static DrawResult
+ PaintMask(const PaintFramesParams& aParams);
+
struct MaskUsage {
bool shouldGenerateMaskLayer;
bool shouldGenerateClipMaskLayer;
bool shouldApplyClipPath;
bool shouldApplyBasicShape;
float opacity;
MaskUsage()