Bug 1476506: Move RoundedRect into Moz2D and convert all callers. r=mattwoodrow draft
authorBas Schouten <bschouten@mozilla.com>
Wed, 18 Jul 2018 08:00:15 +0200
changeset 819569 6098e66ef2398cd311113ede01579f019a5e205c
parent 819435 1f4c59246bff1c98b0052d4edfa4c49d05c52b1a
push id116587
push userbschouten@mozilla.com
push dateWed, 18 Jul 2018 06:00:57 +0000
reviewersmattwoodrow
bugs1476506
milestone63.0a1
Bug 1476506: Move RoundedRect into Moz2D and convert all callers. r=mattwoodrow MozReview-Commit-ID: JHeWD3k42QE
gfx/2d/PathHelpers.h
gfx/2d/Rect.h
gfx/thebes/RoundedRect.h
gfx/thebes/moz.build
gfx/webrender_bindings/WebRenderTypes.h
layout/generic/nsBulletFrame.cpp
layout/painting/nsCSSRenderingBorders.cpp
widget/windows/nsWindow.cpp
--- a/gfx/2d/PathHelpers.h
+++ b/gfx/2d/PathHelpers.h
@@ -173,93 +173,16 @@ inline already_AddRefed<Path> MakePathFo
                                           const Rect& aRect,
                                           bool aDrawClockwise = true)
 {
   RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder();
   AppendRectToPath(builder, aRect, aDrawClockwise);
   return builder->Finish();
 }
 
-struct RectCornerRadii {
-  Size radii[eCornerCount];
-
-  RectCornerRadii() {}
-
-  explicit RectCornerRadii(Float radius) {
-    NS_FOR_CSS_FULL_CORNERS(i) {
-      radii[i].SizeTo(radius, radius);
-    }
-  }
-
-  explicit RectCornerRadii(Float radiusX, Float radiusY) {
-    NS_FOR_CSS_FULL_CORNERS(i) {
-      radii[i].SizeTo(radiusX, radiusY);
-    }
-  }
-
-  RectCornerRadii(Float tl, Float tr, Float br, Float bl) {
-    radii[eCornerTopLeft].SizeTo(tl, tl);
-    radii[eCornerTopRight].SizeTo(tr, tr);
-    radii[eCornerBottomRight].SizeTo(br, br);
-    radii[eCornerBottomLeft].SizeTo(bl, bl);
-  }
-
-  RectCornerRadii(const Size& tl, const Size& tr,
-                  const Size& br, const Size& bl) {
-    radii[eCornerTopLeft] = tl;
-    radii[eCornerTopRight] = tr;
-    radii[eCornerBottomRight] = br;
-    radii[eCornerBottomLeft] = bl;
-  }
-
-  const Size& operator[](size_t aCorner) const {
-    return radii[aCorner];
-  }
-
-  Size& operator[](size_t aCorner) {
-    return radii[aCorner];
-  }
-
-  bool operator==(const RectCornerRadii& aOther) const {
-    return TopLeft() == aOther.TopLeft() &&
-           TopRight() == aOther.TopRight() &&
-           BottomRight() == aOther.BottomRight() &&
-           BottomLeft() == aOther.BottomLeft();
-  }
-
-  bool AreRadiiSame() const {
-    return TopLeft() == TopRight() &&
-           TopLeft() == BottomRight() &&
-           TopLeft() == BottomLeft();
-  }
-
-  void Scale(Float aXScale, Float aYScale) {
-    NS_FOR_CSS_FULL_CORNERS(i) {
-      radii[i].Scale(aXScale, aYScale);
-    }
-  }
-
-  const Size TopLeft() const { return radii[eCornerTopLeft]; }
-  Size& TopLeft() { return radii[eCornerTopLeft]; }
-
-  const Size TopRight() const { return radii[eCornerTopRight]; }
-  Size& TopRight() { return radii[eCornerTopRight]; }
-
-  const Size BottomRight() const { return radii[eCornerBottomRight]; }
-  Size& BottomRight() { return radii[eCornerBottomRight]; }
-
-  const Size BottomLeft() const { return radii[eCornerBottomLeft]; }
-  Size& BottomLeft() { return radii[eCornerBottomLeft]; }
-
-  bool IsEmpty() const {
-    return TopLeft().IsEmpty() && TopRight().IsEmpty() &&
-           BottomRight().IsEmpty() && BottomLeft().IsEmpty();
-  }
-};
-
 /**
  * Appends a path represending a rounded rectangle to the path being built by
  * aPathBuilder.
  *
  * aRect           The rectangle to append.
  * aCornerRadii    Contains the radii of the top-left, top-right, bottom-right
  *                 and bottom-left corners, in that order.
  * aDrawClockwise  If set to true, the path will start at the left of the top
--- a/gfx/2d/Rect.h
+++ b/gfx/2d/Rect.h
@@ -336,12 +336,135 @@ UnionMaybeRects(const Maybe<Rect>& a, co
     return b;
   } else if (!b) {
     return a;
   } else {
     return Some(a->Union(*b));
   }
 }
 
+struct RectCornerRadii {
+  Size radii[eCornerCount];
+
+  RectCornerRadii() {}
+
+  explicit RectCornerRadii(Float radius) {
+    NS_FOR_CSS_FULL_CORNERS(i) {
+      radii[i].SizeTo(radius, radius);
+    }
+  }
+
+  explicit RectCornerRadii(Float radiusX, Float radiusY) {
+    NS_FOR_CSS_FULL_CORNERS(i) {
+      radii[i].SizeTo(radiusX, radiusY);
+    }
+  }
+
+  RectCornerRadii(Float tl, Float tr, Float br, Float bl) {
+    radii[eCornerTopLeft].SizeTo(tl, tl);
+    radii[eCornerTopRight].SizeTo(tr, tr);
+    radii[eCornerBottomRight].SizeTo(br, br);
+    radii[eCornerBottomLeft].SizeTo(bl, bl);
+  }
+
+  RectCornerRadii(const Size& tl, const Size& tr,
+                  const Size& br, const Size& bl) {
+    radii[eCornerTopLeft] = tl;
+    radii[eCornerTopRight] = tr;
+    radii[eCornerBottomRight] = br;
+    radii[eCornerBottomLeft] = bl;
+  }
+
+  const Size& operator[](size_t aCorner) const {
+    return radii[aCorner];
+  }
+
+  Size& operator[](size_t aCorner) {
+    return radii[aCorner];
+  }
+
+  bool operator==(const RectCornerRadii& aOther) const {
+    return TopLeft() == aOther.TopLeft() &&
+           TopRight() == aOther.TopRight() &&
+           BottomRight() == aOther.BottomRight() &&
+           BottomLeft() == aOther.BottomLeft();
+  }
+
+  bool AreRadiiSame() const {
+    return TopLeft() == TopRight() &&
+           TopLeft() == BottomRight() &&
+           TopLeft() == BottomLeft();
+  }
+
+  void Scale(Float aXScale, Float aYScale) {
+    NS_FOR_CSS_FULL_CORNERS(i) {
+      radii[i].Scale(aXScale, aYScale);
+    }
+  }
+
+  const Size TopLeft() const { return radii[eCornerTopLeft]; }
+  Size& TopLeft() { return radii[eCornerTopLeft]; }
+
+  const Size TopRight() const { return radii[eCornerTopRight]; }
+  Size& TopRight() { return radii[eCornerTopRight]; }
+
+  const Size BottomRight() const { return radii[eCornerBottomRight]; }
+  Size& BottomRight() { return radii[eCornerBottomRight]; }
+
+  const Size BottomLeft() const { return radii[eCornerBottomLeft]; }
+  Size& BottomLeft() { return radii[eCornerBottomLeft]; }
+
+  bool IsEmpty() const {
+    return TopLeft().IsEmpty() && TopRight().IsEmpty() &&
+           BottomRight().IsEmpty() && BottomLeft().IsEmpty();
+  }
+};
+
+/* A rounded rectangle abstraction.
+ *
+ * This can represent a rectangle with a different pair of radii on each corner.
+ *
+ * Note: CoreGraphics and Direct2D only support rounded rectangle with the same
+ * radii on all corners. However, supporting CSS's border-radius requires the extra flexibility. */
+struct RoundedRect {
+    typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
+
+    RoundedRect(const Rect& aRect, const RectCornerRadii& aCorners)
+      : rect(aRect)
+      , corners(aCorners)
+    {
+    }
+
+    void Deflate(Float aTopWidth, Float aBottomWidth, Float aLeftWidth, Float aRightWidth) {
+        // deflate the internal rect
+        rect.SetRect(rect.X() + aLeftWidth,
+                     rect.Y() + aTopWidth,
+                     std::max(0.f, rect.Width() - aLeftWidth - aRightWidth),
+                     std::max(0.f, rect.Height() - aTopWidth - aBottomWidth));
+
+        corners.radii[mozilla::eCornerTopLeft].width =
+            std::max(0.f, corners.radii[mozilla::eCornerTopLeft].width - aLeftWidth);
+        corners.radii[mozilla::eCornerTopLeft].height =
+            std::max(0.f, corners.radii[mozilla::eCornerTopLeft].height - aTopWidth);
+
+        corners.radii[mozilla::eCornerTopRight].width =
+            std::max(0.f, corners.radii[mozilla::eCornerTopRight].width - aRightWidth);
+        corners.radii[mozilla::eCornerTopRight].height =
+            std::max(0.f, corners.radii[mozilla::eCornerTopRight].height - aTopWidth);
+
+        corners.radii[mozilla::eCornerBottomLeft].width =
+            std::max(0.f, corners.radii[mozilla::eCornerBottomLeft].width - aLeftWidth);
+        corners.radii[mozilla::eCornerBottomLeft].height =
+            std::max(0.f, corners.radii[mozilla::eCornerBottomLeft].height - aBottomWidth);
+
+        corners.radii[mozilla::eCornerBottomRight].width =
+            std::max(0.f, corners.radii[mozilla::eCornerBottomRight].width - aRightWidth);
+        corners.radii[mozilla::eCornerBottomRight].height =
+            std::max(0.f, corners.radii[mozilla::eCornerBottomRight].height - aBottomWidth);
+    }
+    Rect rect;
+    RectCornerRadii corners;
+};
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_RECT_H_ */
deleted file mode 100644
--- a/gfx/thebes/RoundedRect.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifndef ROUNDED_RECT_H
-#define ROUNDED_RECT_H
-
-#include "gfxRect.h"
-#include "gfxTypes.h"
-#include "mozilla/gfx/PathHelpers.h"
-
-namespace mozilla {
-/* A rounded rectangle abstraction.
- *
- * This can represent a rectangle with a different pair of radii on each corner.
- *
- * Note: CoreGraphics and Direct2D only support rounded rectangle with the same
- * radii on all corners. However, supporting CSS's border-radius requires the extra flexibility. */
-struct RoundedRect {
-    typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
-
-    RoundedRect(const gfxRect& aRect, const RectCornerRadii& aCorners)
-      : rect(aRect)
-      , corners(aCorners)
-    {
-    }
-
-    void Deflate(gfxFloat aTopWidth, gfxFloat aBottomWidth, gfxFloat aLeftWidth, gfxFloat aRightWidth) {
-        // deflate the internal rect
-        rect.SetRect(rect.X() + aLeftWidth,
-                     rect.Y() + aTopWidth,
-                     std::max(0., rect.Width() - aLeftWidth - aRightWidth),
-                     std::max(0., rect.Height() - aTopWidth - aBottomWidth));
-
-        corners.radii[mozilla::eCornerTopLeft].width =
-            std::max(0., corners.radii[mozilla::eCornerTopLeft].width - aLeftWidth);
-        corners.radii[mozilla::eCornerTopLeft].height =
-            std::max(0., corners.radii[mozilla::eCornerTopLeft].height - aTopWidth);
-
-        corners.radii[mozilla::eCornerTopRight].width =
-            std::max(0., corners.radii[mozilla::eCornerTopRight].width - aRightWidth);
-        corners.radii[mozilla::eCornerTopRight].height =
-            std::max(0., corners.radii[mozilla::eCornerTopRight].height - aTopWidth);
-
-        corners.radii[mozilla::eCornerBottomLeft].width =
-            std::max(0., corners.radii[mozilla::eCornerBottomLeft].width - aLeftWidth);
-        corners.radii[mozilla::eCornerBottomLeft].height =
-            std::max(0., corners.radii[mozilla::eCornerBottomLeft].height - aBottomWidth);
-
-        corners.radii[mozilla::eCornerBottomRight].width =
-            std::max(0., corners.radii[mozilla::eCornerBottomRight].width - aRightWidth);
-        corners.radii[mozilla::eCornerBottomRight].height =
-            std::max(0., corners.radii[mozilla::eCornerBottomRight].height - aBottomWidth);
-    }
-    gfxRect rect;
-    RectCornerRadii corners;
-};
-
-} // namespace mozilla
-
-#endif
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -48,17 +48,16 @@ EXPORTS += [
     'gfxRect.h',
     'gfxSharedImageSurface.h',
     'gfxSkipChars.h',
     'gfxSVGGlyphs.h',
     'gfxTextRun.h',
     'gfxTypes.h',
     'gfxUserFontSet.h',
     'gfxUtils.h',
-    'RoundedRect.h',
     'SoftwareVsyncSource.h',
     'VsyncSource.h',
 ]
 
 EXPORTS.mozilla.gfx += [
     'D3D11Checks.h',
     'DeviceManagerDx.h',
     'PrintTarget.h',
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -9,21 +9,21 @@
 
 #include "FrameMetrics.h"
 #include "ImageTypes.h"
 #include "mozilla/webrender/webrender_ffi.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/gfx/Matrix.h"
 #include "mozilla/gfx/Types.h"
 #include "mozilla/gfx/Tools.h"
+#include "mozilla/gfx/Rect.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Range.h"
 #include "mozilla/Variant.h"
 #include "Units.h"
-#include "RoundedRect.h"
 #include "nsStyleConsts.h"
 
 namespace mozilla {
 
 namespace ipc {
 class ByteBuf;
 } // namespace ipc
 
@@ -310,17 +310,17 @@ static inline wr::LayoutRect ToLayoutRec
   wr::LayoutRect r;
   r.origin.x = rect.X();
   r.origin.y = rect.Y();
   r.size.width = rect.Width();
   r.size.height = rect.Height();
   return r;
 }
 
-static inline wr::LayoutRect ToLayoutRect(const gfxRect& rect)
+static inline wr::LayoutRect ToLayoutRect(const gfx::Rect& rect)
 {
   wr::LayoutRect r;
   r.origin.x = rect.X();
   r.origin.y = rect.Y();
   r.size.width = rect.Width();
   r.size.height = rect.Height();
   return r;
 }
@@ -349,17 +349,17 @@ static inline wr::LayoutRect ToRoundedLa
 static inline wr::LayoutSize ToLayoutSize(const mozilla::LayoutDeviceSize& size)
 {
   wr::LayoutSize ls;
   ls.width = size.width;
   ls.height = size.height;
   return ls;
 }
 
-static inline wr::ComplexClipRegion ToComplexClipRegion(const RoundedRect& rect)
+static inline wr::ComplexClipRegion ToComplexClipRegion(const gfx::RoundedRect& rect)
 {
   wr::ComplexClipRegion ret;
   ret.rect               = ToLayoutRect(rect.rect);
   ret.radii.top_left     = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(rect.corners.radii[mozilla::eCornerTopLeft]));
   ret.radii.top_right    = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(rect.corners.radii[mozilla::eCornerTopRight]));
   ret.radii.bottom_left  = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(rect.corners.radii[mozilla::eCornerBottomLeft]));
   ret.radii.bottom_right = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(rect.corners.radii[mozilla::eCornerBottomRight]));
   ret.mode = wr::ClipMode::Clip;
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -525,17 +525,17 @@ BulletRenderer::CreateWebRenderCommandsF
       aBuilder.PushBorder(dest, dest, isBackfaceVisible, borderWidths,
                           sidesRange,
                           wr::ToBorderRadius(radii, radii, radii, radii));
       return true;
     }
     case NS_STYLE_LIST_STYLE_DISC: {
       nsTArray<wr::ComplexClipRegion> clips;
       clips.AppendElement(wr::ToComplexClipRegion(
-        RoundedRect(ThebesRect(mPathRect.ToUnknownRect()),
+        RoundedRect(mPathRect.ToUnknownRect(),
                     RectCornerRadii(dest.size.width / 2.0))
       ));
       auto clipId = aBuilder.DefineClip(Nothing(), dest, &clips, nullptr);
       aBuilder.PushClip(clipId);
       aBuilder.PushRect(dest, dest, isBackfaceVisible, color);
       aBuilder.PopClip();
       return true;
     }
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -18,17 +18,16 @@
 #include "nsStyleConsts.h"
 #include "nsContentUtils.h"
 #include "nsCSSColorUtils.h"
 #include "nsCSSRendering.h"
 #include "nsCSSRenderingGradients.h"
 #include "nsDisplayList.h"
 #include "GeckoProfiler.h"
 #include "nsExpirationTracker.h"
-#include "RoundedRect.h"
 #include "nsIScriptError.h"
 #include "nsClassHashtable.h"
 #include "nsPresContext.h"
 #include "nsStyleStruct.h"
 #include "mozilla/gfx/2D.h"
 #include "gfx2DGlue.h"
 #include "gfxGradientCache.h"
 #include "mozilla/layers/StackingContextHelper.h"
@@ -3123,35 +3122,34 @@ nsCSSBorderRenderer::DrawBorders()
   }
 
   if (mAllBordersSameStyle &&
       mBorderStyles[0] == NS_STYLE_BORDER_STYLE_SOLID &&
       !mAvoidStroke &&
       !mNoBorderRadius)
   {
     // Relatively simple case.
-    gfxRect outerRect = ThebesRect(mOuterRect);
-    RoundedRect borderInnerRect(outerRect, mBorderRadii);
+    RoundedRect borderInnerRect(mOuterRect, mBorderRadii);
     borderInnerRect.Deflate(mBorderWidths[eSideTop],
                             mBorderWidths[eSideBottom],
                             mBorderWidths[eSideLeft],
                             mBorderWidths[eSideRight]);
 
     // Instead of stroking we just use two paths: an inner and an outer.
     // This allows us to draw borders that we couldn't when stroking. For example,
     // borders with a border width >= the border radius. (i.e. when there are
     // square corners on the inside)
     //
     // Further, this approach can be more efficient because the backend
     // doesn't need to compute an offset curve to stroke the path. We know that
     // the rounded parts are elipses we can offset exactly and can just compute
     // a new cubic approximation.
     RefPtr<PathBuilder> builder = mDrawTarget->CreatePathBuilder();
     AppendRoundedRectToPath(builder, mOuterRect, mBorderRadii, true);
-    AppendRoundedRectToPath(builder, ToRect(borderInnerRect.rect), borderInnerRect.corners, false);
+    AppendRoundedRectToPath(builder, borderInnerRect.rect, borderInnerRect.corners, false);
     RefPtr<Path> path = builder->Finish();
     mDrawTarget->Fill(path, color);
     return;
   }
 
   const bool allBordersSolid = AllBordersSolid();
 
   // This leaves the border corners non-interpolated for single width borders.
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -4088,17 +4088,17 @@ void
 nsWindow::AddWindowOverlayWebRenderCommands(layers::WebRenderBridgeChild* aWrBridge,
                                             wr::DisplayListBuilder& aBuilder,
                                             wr::IpcResourceUpdateQueue& aResources)
 {
   if (mWindowButtonsRect) {
     wr::LayoutRect rect = wr::ToLayoutRect(*mWindowButtonsRect);
     nsTArray<wr::ComplexClipRegion> roundedClip;
     roundedClip.AppendElement(wr::ToComplexClipRegion(
-      RoundedRect(ThebesRect(mWindowButtonsRect->ToUnknownRect()),
+      RoundedRect(IntRectToRect(mWindowButtonsRect->ToUnknownRect()),
                   RectCornerRadii(0, 0, 3, 3))));
     wr::WrClipId clipId =
       aBuilder.DefineClip(Nothing(), rect, &roundedClip);
     aBuilder.PushClip(clipId);
     aBuilder.PushClearRect(rect);
     aBuilder.PopClip();
   }
 }