Bug 1326409 Part 4 - Extract a function to compute polygon vertices. r=dholbert
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 13 Mar 2017 12:03:40 +0800
changeset 497501 64d9398934264d9c034a857b482e0f558440cb8b
parent 497500 f9df20da54310660c413d402f1e87c84794574a1
child 497502 8f39505ab1ec7e273b1d034b190599fcaa76d20f
push id48933
push userbmo:james@hoppipolla.co.uk
push dateMon, 13 Mar 2017 13:53:04 +0000
reviewersdholbert
bugs1326409
milestone55.0a1
Bug 1326409 Part 4 - Extract a function to compute polygon vertices. r=dholbert MozReview-Commit-ID: B4BzBHjLHxW
layout/base/ShapeUtils.cpp
layout/base/ShapeUtils.h
layout/svg/nsCSSClipPathInstance.cpp
--- a/layout/base/ShapeUtils.cpp
+++ b/layout/base/ShapeUtils.cpp
@@ -144,9 +144,30 @@ ShapeUtils::ComputeInsetRadii(StyleBasic
                               nscoord aRadii[8])
 {
   const nsStyleCorners& radius = aBasicShape->GetRadius();
   return nsIFrame::ComputeBorderRadii(radius, aInsetRect.Size(), aRefBox.Size(),
                                       Sides(), aRadii);
 
 }
 
+/* static */ nsTArray<nsPoint>
+ShapeUtils::ComputePolygonVertices(const StyleBasicShape* aBasicShape,
+                                   const nsRect& aRefBox)
+{
+  MOZ_ASSERT(aBasicShape->GetShapeType() == StyleBasicShapeType::Polygon,
+             "The basic shape must be polygon()!");
+
+  const nsTArray<nsStyleCoord>& coords = aBasicShape->Coordinates();
+  MOZ_ASSERT(coords.Length() % 2 == 0 &&
+             coords.Length() >= 2, "Wrong number of arguments!");
+
+  nsTArray<nsPoint> vertices(coords.Length() / 2);
+  for (size_t i = 0; i + 1 < coords.Length(); i += 2) {
+    vertices.AppendElement(
+      nsPoint(nsRuleNode::ComputeCoordPercentCalc(coords[i], aRefBox.width),
+              nsRuleNode::ComputeCoordPercentCalc(coords[i + 1], aRefBox.height))
+      + aRefBox.TopLeft());
+  }
+  return vertices;
+}
+
 } // namespace mozilla
--- a/layout/base/ShapeUtils.h
+++ b/layout/base/ShapeUtils.h
@@ -68,13 +68,21 @@ struct ShapeUtils final
   // @param aInsetRect the inset rect computed by ComputeInsetRect().
   // @param aRadii the returned radii in app units.
   // @return true if any of the radii is nonzero; false otherwise.
   static bool ComputeInsetRadii(
     mozilla::StyleBasicShape* const aBasicShape,
     const nsRect& aInsetRect,
     const nsRect& aRefBox,
     nscoord aRadii[8]);
+
+  // Compute the vertices for a polygon.
+  // @param aRefBox the reference box of the polygon.
+  // @return The vertices in app units; the coordinate space is the same
+  //         as aRefBox.
+  static nsTArray<nsPoint> ComputePolygonVertices(
+    const StyleBasicShape* aBasicShape,
+    const nsRect& aRefBox);
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ShapeUtils_h
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -9,16 +9,17 @@
 #include "gfx2DGlue.h"
 #include "gfxPlatform.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/ShapeUtils.h"
 #include "nsCSSRendering.h"
 #include "nsIFrame.h"
+#include "nsLayoutUtils.h"
 #include "nsRenderingContext.h"
 #include "nsRuleNode.h"
 #include "nsSVGElement.h"
 #include "nsSVGUtils.h"
 #include "nsSVGViewBox.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -145,33 +146,32 @@ nsCSSClipPathInstance::CreateClipPathEll
   return builder->Finish();
 }
 
 already_AddRefed<Path>
 nsCSSClipPathInstance::CreateClipPathPolygon(DrawTarget* aDrawTarget,
                                              const nsRect& aRefBox)
 {
   StyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
-  const nsTArray<nsStyleCoord>& coords = basicShape->Coordinates();
-  MOZ_ASSERT(coords.Length() % 2 == 0 &&
-             coords.Length() >= 2, "wrong number of arguments");
-
   FillRule fillRule = basicShape->GetFillRule() == StyleFillRule::Nonzero ?
                         FillRule::FILL_WINDING : FillRule::FILL_EVEN_ODD;
   RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(fillRule);
 
-  nscoord x = nsRuleNode::ComputeCoordPercentCalc(coords[0], aRefBox.width);
-  nscoord y = nsRuleNode::ComputeCoordPercentCalc(coords[1], aRefBox.height);
-  nscoord appUnitsPerDevPixel =
-    mTargetFrame->PresContext()->AppUnitsPerDevPixel();
-  builder->MoveTo(Point(aRefBox.x + x, aRefBox.y + y) / appUnitsPerDevPixel);
-  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);
+  nsTArray<nsPoint> vertices =
+    ShapeUtils::ComputePolygonVertices(basicShape, aRefBox);
+  if (vertices.IsEmpty()) {
+    MOZ_ASSERT_UNREACHABLE(
+      "ComputePolygonVertices() should've given us some vertices!");
+  } else {
+    nscoord appUnitsPerDevPixel =
+      mTargetFrame->PresContext()->AppUnitsPerDevPixel();
+    builder->MoveTo(NSPointToPoint(vertices[0], appUnitsPerDevPixel));
+    for (size_t i = 1; i < vertices.Length(); ++i) {
+      builder->LineTo(NSPointToPoint(vertices[i], appUnitsPerDevPixel));
+    }
   }
   builder->Close();
   return builder->Finish();
 }
 
 already_AddRefed<Path>
 nsCSSClipPathInstance::CreateClipPathInset(DrawTarget* aDrawTarget,
                                            const nsRect& aRefBox)