Bug 1311244 Part 4 - Extract the computation of circle radius as ComputeCircleRadius(). draft
authorTing-Yu Lin <tlin@mozilla.com>
Fri, 06 Jan 2017 16:36:05 +0800
changeset 459616 7589ebedab47e9a5fe6d5992433cd6f491e93104
parent 459615 8d32baeb5b482ab073a78ecc70ecb52c1ec8577c
child 459617 031efd094115fea28bfd4ae20004067aff339380
push id41270
push userbmo:tlin@mozilla.com
push dateThu, 12 Jan 2017 09:51:31 +0000
bugs1311244
milestone53.0a1
Bug 1311244 Part 4 - Extract the computation of circle radius as ComputeCircleRadius(). MozReview-Commit-ID: LJNvNOoc7FI
layout/base/ShapeUtils.cpp
layout/base/ShapeUtils.h
layout/svg/nsCSSClipPathInstance.cpp
--- a/layout/base/ShapeUtils.cpp
+++ b/layout/base/ShapeUtils.cpp
@@ -4,17 +4,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ShapeUtils.h"
 
 #include <cstdlib>
 
 #include "nsCSSRendering.h"
+#include "nsRuleNode.h"
+#include "nsStyleCoord.h"
 #include "nsStyleStruct.h"
+#include "SVGContentUtils.h"
 
 namespace mozilla {
 
 nscoord
 ShapeUtils::ComputeShapeRadius(const StyleShapeRadius aType,
                                const nscoord aCenter,
                                const nscoord aPosMin,
                                const nscoord aPosMax)
@@ -40,9 +43,38 @@ ShapeUtils::ComputeCircleOrEllipseCenter
   nsPoint topLeft, anchor;
   nsSize size(aRefBox.Size());
   nsImageRenderer::ComputeObjectAnchorPoint(aBasicShape->GetPosition(),
                                             size, size,
                                             &topLeft, &anchor);
   return nsPoint(anchor.x + aRefBox.x, anchor.y + aRefBox.y);
 }
 
+nscoord
+ShapeUtils::ComputeCircleRadius(StyleBasicShape* const aBasicShape,
+                                const nsPoint& aCenter,
+                                const nsRect& aRefBox)
+{
+  const nsTArray<nsStyleCoord>& coords = aBasicShape->Coordinates();
+  MOZ_ASSERT(coords.Length() == 1, "wrong number of arguments");
+  nscoord r = 0;
+  if (coords[0].GetUnit() == eStyleUnit_Enumerated) {
+    const auto styleShapeRadius = coords[0].GetEnumValue<StyleShapeRadius>();
+    nscoord horizontal =
+      ComputeShapeRadius(styleShapeRadius, aCenter.x, aRefBox.x, aRefBox.XMost());
+    nscoord vertical =
+      ComputeShapeRadius(styleShapeRadius, aCenter.y, aRefBox.y, aRefBox.YMost());
+    r = styleShapeRadius == StyleShapeRadius::FarthestSide
+          ? std::max(horizontal, vertical)
+          : std::min(horizontal, vertical);
+  } else {
+    // We resolve percent <shape-radius> value for circle() as defined here:
+    // https://drafts.csswg.org/css-shapes/#funcdef-circle
+    double referenceLength =
+      SVGContentUtils::ComputeNormalizedHypotenuse(aRefBox.width,
+                                                   aRefBox.height);
+    r = nsRuleNode::ComputeCoordPercentCalc(coords[0],
+                                            NSToCoordRound(referenceLength));
+  }
+  return r;
+}
+
 } // namespace mozilla
--- a/layout/base/ShapeUtils.h
+++ b/layout/base/ShapeUtils.h
@@ -35,13 +35,21 @@ struct ShapeUtils final
 
   // Compute the center of a circle or an ellipse.
   //
   // @param aRefBox The reference box of the basic shape.
   // @return The point of the center.
   static nsPoint ComputeCircleOrEllipseCenter(
     StyleBasicShape* const aBasicShape,
     const nsRect& aRefBox);
+
+  // Compute the radius for a circle.
+  // @param aCenter the center of the circle.
+  // @param aRefBox the reference box of the circle.
+  // @return The length of the radius in app units.
+  static nscoord ComputeCircleRadius(
+    mozilla::StyleBasicShape* const aBasicShape,
+    const nsPoint& aCenter, const nsRect& aRefBox);
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ShapeUtils_h
--- a/layout/svg/nsCSSClipPathInstance.cpp
+++ b/layout/svg/nsCSSClipPathInstance.cpp
@@ -110,43 +110,17 @@ nsCSSClipPathInstance::CreateClipPathCir
                                             const nsRect& aRefBox)
 {
   StyleBasicShape* basicShape = mClipPathStyle.GetBasicShape();
 
   RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder();
 
   nsPoint center =
     ShapeUtils::ComputeCircleOrEllipseCenter(basicShape, aRefBox);
-
-  const nsTArray<nsStyleCoord>& coords = basicShape->Coordinates();
-  MOZ_ASSERT(coords.Length() == 1, "wrong number of arguments");
-  nscoord r = 0;
-  if (coords[0].GetUnit() == eStyleUnit_Enumerated) {
-    const auto styleShapeRadius = coords[0].GetEnumValue<StyleShapeRadius>();
-    nscoord horizontal =
-      ShapeUtils::ComputeShapeRadius(styleShapeRadius, center.x, aRefBox.x,
-                                     aRefBox.x + aRefBox.width);
-    nscoord vertical =
-      ShapeUtils::ComputeShapeRadius(styleShapeRadius, center.y, aRefBox.y,
-                                     aRefBox.y + aRefBox.height);
-    if (styleShapeRadius == StyleShapeRadius::FarthestSide) {
-      r = horizontal > vertical ? horizontal : vertical;
-    } else {
-      r = horizontal < vertical ? horizontal : vertical;
-    }
-  } else {
-    // We resolve percent <shape-radius> value for circle() as defined here:
-    // https://drafts.csswg.org/css-shapes/#funcdef-circle
-    double referenceLength =
-      SVGContentUtils::ComputeNormalizedHypotenuse(aRefBox.width,
-                                                   aRefBox.height);
-    r = nsRuleNode::ComputeCoordPercentCalc(coords[0],
-                                            NSToCoordRound(referenceLength));
-  }
-
+  nscoord r = ShapeUtils::ComputeCircleRadius(basicShape, center, aRefBox);
   nscoord appUnitsPerDevPixel =
     mTargetFrame->PresContext()->AppUnitsPerDevPixel();
   builder->Arc(Point(center.x, center.y) / appUnitsPerDevPixel,
                r / appUnitsPerDevPixel,
                0, Float(2 * M_PI));
   builder->Close();
   return builder->Finish();
 }