Bug 1289011 - Part 2. Implement ComputeSVGReferenceRect.
MozReview-Commit-ID: G98lmo59AuB
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -57,44 +57,92 @@ nsCSSClipPathInstance::HitTestBasicShape
RefPtr<DrawTarget> drawTarget =
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
RefPtr<Path> path = instance.CreateClipPath(drawTarget);
float pixelRatio = float(nsPresContext::AppUnitsPerCSSPixel()) /
aFrame->PresContext()->AppUnitsPerDevPixel();
return path->ContainsPoint(ToPoint(aPoint) * pixelRatio, Matrix());
}
+nsRect
+nsCSSClipPathInstance::ComputeSVGReferenceRect()
+{
+ nsRect r;
+
+ // For SVG elements without associated CSS layout box, the used value for
+ // content-box, padding-box, border-box and margin-box is fill-box.
+ switch (mClipPathStyle.GetReferenceBox()) {
+
+ case StyleClipPathGeometryBox::NoBox:
+ case StyleClipPathGeometryBox::Border:
+ case StyleClipPathGeometryBox::Content:
+ case StyleClipPathGeometryBox::Padding:
+ case StyleClipPathGeometryBox::Margin:
+ case StyleClipPathGeometryBox::Fill: {
+ gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
+ nsSVGUtils::eBBoxIncludeFill);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ default:{
+ MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
+ gfxRect bbox = nsSVGUtils::GetBBox(mTargetFrame,
+ nsSVGUtils::eBBoxIncludeFill);
+ r = nsLayoutUtils::RoundGfxRectToAppRect(bbox,
+ nsPresContext::AppUnitsPerCSSPixel());
+ break;
+ }
+ }
+
+ return r;
+}
nsRect
nsCSSClipPathInstance::ComputeHTMLReferenceRect()
{
nsRect r;
- // XXXkrit SVG needs to use different boxes.
+
+ // For elements with associated CSS layout box, the used value for fill-box,
+ // stroke-box and view-box is border-box.
switch (mClipPathStyle.GetReferenceBox()) {
case StyleClipPathGeometryBox::Content:
r = mTargetFrame->GetContentRectRelativeToSelf();
break;
case StyleClipPathGeometryBox::Padding:
r = mTargetFrame->GetPaddingRectRelativeToSelf();
break;
case StyleClipPathGeometryBox::Margin:
r = mTargetFrame->GetMarginRectRelativeToSelf();
break;
- default: // Use the border box
+ case StyleClipPathGeometryBox::NoBox:
+ case StyleClipPathGeometryBox::Border:
+ case StyleClipPathGeometryBox::Fill:
+ case StyleClipPathGeometryBox::Stroke:
+ case StyleClipPathGeometryBox::View:
+ r = mTargetFrame->GetRectRelativeToSelf();
+ break;
+ default:
+ MOZ_ASSERT_UNREACHABLE("unknown StyleClipPathGeometryBox type");
r = mTargetFrame->GetRectRelativeToSelf();
break;
}
return r;
}
already_AddRefed<Path>
nsCSSClipPathInstance::CreateClipPath(DrawTarget* aDrawTarget)
{
- nsRect r = ComputeHTMLReferenceRect();
+ // We use ComputeSVGReferenceRect for all SVG elements, except <svg>
+ // element, which does have an associated CSS layout box. In this case we
+ // should still use ComputeHTMLReferenceRect for region computing.
+ nsRect r = mTargetFrame->IsFrameOfType(nsIFrame::eSVG) &&
+ (mTargetFrame->GetType() != nsGkAtoms::svgOuterSVGFrame)
+ ? ComputeSVGReferenceRect() : ComputeHTMLReferenceRect();
if (mClipPathStyle.GetType() != StyleShapeSourceType::Shape) {
// TODO Clip to border-radius/reference box if no shape
// was specified.
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
return builder->Finish();
}
--- a/layout/svg/nsCSSClipPathInstance.h
+++ b/layout/svg/nsCSSClipPathInstance.h
@@ -45,16 +45,17 @@ private:
already_AddRefed<Path> CreateClipPathPolygon(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
already_AddRefed<Path> CreateClipPathInset(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
nsRect ComputeHTMLReferenceRect();
+ nsRect ComputeSVGReferenceRect();
/**
* The frame for the element that is currently being clipped.
*/
nsIFrame* mTargetFrame;
StyleClipPath mClipPathStyle;
};