Bug 1246762 - Add support for inset() in clip-path ; r?dholbert draft
authorManish Goregaokar <manishsmail@gmail.com>
Thu, 18 Aug 2016 19:59:01 +0530
changeset 404048 c0ed295e61d550cb288efbe148c0cab692a11cd3
parent 402150 97a52326b06a07930216ebefa5af333271578904
child 404049 8141e36fc3c3b500383baa1fcad8f1408a2104b1
child 404054 1288a28bc496d441e7298587b308134f2d9e6c6c
push id27086
push userbmo:manishearth@gmail.com
push dateMon, 22 Aug 2016 18:39:13 +0000
reviewersdholbert
bugs1246762
milestone51.0a1
Bug 1246762 - Add support for inset() in clip-path ; r?dholbert MozReview-Commit-ID: 9AhkTu9gVVm
layout/svg/nsCSSClipPathInstance.cpp
layout/svg/nsCSSClipPathInstance.h
--- 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