Bug 1246762 - Add support for inset() in clip-path ; r?dholbert
MozReview-Commit-ID: 9AhkTu9gVVm
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -96,17 +96,17 @@ nsCSSClipPathInstance::CreateClipPath(Dr
switch (basicShape->GetShapeType()) {
case StyleBasicShapeType::Circle:
return CreateClipPathCircle(aDrawTarget, r);
case StyleBasicShapeType::Ellipse:
return CreateClipPathEllipse(aDrawTarget, r);
case StyleBasicShapeType::Polygon:
return CreateClipPathPolygon(aDrawTarget, r);
case StyleBasicShapeType::Inset:
- // XXXkrit support all basic shapes
+ return CreateClipPathInset(aDrawTarget, r);
break;
default:
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected shape type");
}
// Return an empty Path:
RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
return builder->Finish();
}
@@ -234,8 +234,46 @@ nsCSSClipPathInstance::CreateClipPathPol
for (size_t i = 2; i < coords.Length(); i += 2) {
x = nsRuleNode::ComputeCoordPercentCalc(coords[i], aRefBox.width);
y = nsRuleNode::ComputeCoordPercentCalc(coords[i + 1], aRefBox.height);
builder->LineTo(Point(aRefBox.x + x, aRefBox.y + y) / appUnitsPerDevPixel);
}
builder->Close();
return builder->Finish();
}
+
+already_AddRefed<Path>
+nsCSSClipPathInstance::CreateClipPathInset(DrawTarget* aDrawTarget,
+ const nsRect& aRefBox)
+{
+ StyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
+ const nsTArray<nsStyleCoord>& coords = basicShape->Coordinates();
+ MOZ_ASSERT(coords.Length() == 4, "wrong number of arguments");
+
+ RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
+
+ nscoord appUnitsPerDevPixel =
+ mTargetFrame->PresContext()->AppUnitsPerDevPixel();
+
+ nsMargin inset(nsRuleNode::ComputeCoordPercentCalc(coords[0], aRefBox.height),
+ nsRuleNode::ComputeCoordPercentCalc(coords[1], aRefBox.width),
+ nsRuleNode::ComputeCoordPercentCalc(coords[2], aRefBox.height),
+ nsRuleNode::ComputeCoordPercentCalc(coords[3], aRefBox.width));
+
+ nsRect insetRect(aRefBox);
+ insetRect.Deflate(inset);
+ const Rect insetRectPixels = NSRectToRect(insetRect, appUnitsPerDevPixel);
+ const nsStyleCorners& radius = basicShape->GetRadius();
+
+ nscoord appUnitsRadii[8];
+
+ if (nsIFrame::ComputeBorderRadii(radius, insetRect.Size(), aRefBox.Size(),
+ Sides(), appUnitsRadii)) {
+ RectCornerRadii corners;
+ nsCSSRendering::ComputePixelRadii(appUnitsRadii,
+ appUnitsPerDevPixel, &corners);
+
+ AppendRoundedRectToPath(builder, insetRectPixels, corners, true);
+ } else {
+ AppendRectToPath(builder, insetRectPixels, true);
+ }
+ return builder->Finish();
+}
--- a/layout/svg/nsCSSClipPathInstance.h
+++ b/layout/svg/nsCSSClipPathInstance.h
@@ -40,16 +40,18 @@ private:
const nsRect& aRefBox);
already_AddRefed<Path> CreateClipPathEllipse(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
already_AddRefed<Path> CreateClipPathPolygon(DrawTarget* aDrawTarget,
const nsRect& aRefBox);
+ already_AddRefed<Path> CreateClipPathInset(DrawTarget* aDrawTarget,
+ const nsRect& aRefBox);
/**
* The frame for the element that is currently being clipped.
*/
nsIFrame* mTargetFrame;
StyleClipPath mClipPathStyle;
};
} // namespace mozilla