Bug 1476506: Move RoundedRect into Moz2D and convert all callers. r=mattwoodrow
MozReview-Commit-ID: JHeWD3k42QE
--- 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();
}
}