author | Milan Sreckovic <milan@mozilla.com> |
Tue, 07 Nov 2017 09:38:31 -0500 | |
changeset 444055 | 2a52e1d4c300aa71652652c4349d4e06c74c9dc7 |
parent 444054 | 0f9f5ef2c14122360e4bd3ea2ae171fad7ae2554 |
child 444056 | 1ede5a47bb9877a7bd01eb4303d65b8462f1d32c |
push id | 1618 |
push user | Callek@gmail.com |
push date | Thu, 11 Jan 2018 17:45:48 +0000 |
treeherder | mozilla-release@882ca853e05a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bas, jfkthame |
bugs | 1389152 |
milestone | 58.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
gfx/tests/gtest/TestRect.cpp | file | annotate | diff | comparison | revisions | |
layout/generic/WritingModes.h | file | annotate | diff | comparison | revisions |
--- a/gfx/tests/gtest/TestRect.cpp +++ b/gfx/tests/gtest/TestRect.cpp @@ -4,16 +4,17 @@ * 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 <limits> #include "gtest/gtest.h" #include "nsRect.h" #include "gfxRect.h" +#include "mozilla/WritingModes.h" #ifdef XP_WIN #include <windows.h> #endif template <class RectType> static bool TestConstructors() { @@ -440,17 +441,65 @@ TestSwap() { RectType rect(1, 2, 3, 4); EXPECT_TRUE(rect.X() == 1 && rect.Y() == 2 && rect.Width() == 3 && rect.Height() == 4); rect.Swap(); EXPECT_TRUE(rect.X() == 2 && rect.Y() == 1 && rect.Width() == 4 && rect.Height() == 3); return true; } +static void +TestIntersectionLogicalHelper(nscoord x1, nscoord y1, nscoord w1, nscoord h1, + nscoord x2, nscoord y2, nscoord w2, nscoord h2, + nscoord xR, nscoord yR, nscoord wR, nscoord hR, + bool isNonEmpty) +{ + nsRect rect1(x1, y1, w1, h1); + nsRect rect2(x2, y2, w2, h2); + nsRect rectDebug; + EXPECT_TRUE(isNonEmpty == rectDebug.IntersectRect(rect1, rect2)); + EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(xR, yR, wR, hR))); + mozilla::LogicalRect r1(mozilla::WritingMode(), rect1.X(), rect1.Y(), rect1.Width(), rect1.Height()); + mozilla::LogicalRect r2(mozilla::WritingMode(), rect2.X(), rect2.Y(), rect2.Width(), rect2.Height()); + EXPECT_TRUE(isNonEmpty == r1.IntersectRect(r1, r2)); + EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(r1.IStart(WritingMode()), r1.BStart(WritingMode()), + r1.ISize(WritingMode()), r1.BSize(WritingMode())))); + + mozilla::LogicalRect r3(mozilla::WritingMode(), rect1.X(), rect1.Y(), rect1.Width(), rect1.Height()); + mozilla::LogicalRect r4(mozilla::WritingMode(), rect2.X(), rect2.Y(), rect2.Width(), rect2.Height()); + EXPECT_TRUE(isNonEmpty == r4.IntersectRect(r3, r4)); + EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(r4.IStart(WritingMode()), r4.BStart(WritingMode()), + r4.ISize(WritingMode()), r4.BSize(WritingMode())))); + + mozilla::LogicalRect r5(mozilla::WritingMode(), rect1.X(), rect1.Y(), rect1.Width(), rect1.Height()); + mozilla::LogicalRect r6(mozilla::WritingMode(), rect2.X(), rect2.Y(), rect2.Width(), rect2.Height()); + mozilla::LogicalRect r7(mozilla::WritingMode(), 0, 0, 1, 1); + EXPECT_TRUE(isNonEmpty == r7.IntersectRect(r5, r6)); + EXPECT_TRUE(rectDebug.IsEqualEdges(nsRect(r7.IStart(WritingMode()), r7.BStart(WritingMode()), + r7.ISize(WritingMode()), r7.BSize(WritingMode())))); +} + +static void +TestIntersectionLogical(nscoord x1, nscoord y1, nscoord w1, nscoord h1, + nscoord x2, nscoord y2, nscoord w2, nscoord h2, + nscoord xR, nscoord yR, nscoord wR, nscoord hR, + bool isNonEmpty) +{ + TestIntersectionLogicalHelper(x1, y1, w1, h1, x2, y2, w2, h2, xR, yR, wR, hR, isNonEmpty); + TestIntersectionLogicalHelper(x2, y2, w2, h2, x1, y1, w1, h1, xR, yR, wR, hR, isNonEmpty); +} + +TEST(Gfx, Logical) +{ + TestIntersectionLogical(578, 0, 2650, 1152, 1036, 0, 2312, 1, 1036, 0, 2192, 1, true); + TestIntersectionLogical(0, 0, 1000, 1000, 500, 500, 1000, 1000, 500, 500, 500, 500, true); + TestIntersectionLogical(100, 200, 300, 400, 50, 250, 100, 100, 100, 250, 50, 100, true); + TestIntersectionLogical(0, 100, 200, 300, 300, 100, 100, 300, 300, 100, 0, 0, false); +} TEST(Gfx, nsRect) { TestConstructors<nsRect>(); TestEqualityOperator<nsRect>(); TestContainment<nsRect>(); TestIntersects<nsRect>(); TestIntersection<nsRect>(); TestUnion<nsRect>(); @@ -478,8 +527,9 @@ TEST(Gfx, gfxRect) { TestIntersects<gfxRect>(); TestIntersection<gfxRect>(); TestUnion<gfxRect>(); TestBug1135677<gfxRect>(); TestFiniteGfx(); TestSetWH<gfxRect>(); TestSwap<gfxRect>(); } +
--- a/layout/generic/WritingModes.h +++ b/layout/generic/WritingModes.h @@ -1484,123 +1484,132 @@ private: */ class LogicalRect { public: explicit LogicalRect(WritingMode aWritingMode) : #ifdef DEBUG mWritingMode(aWritingMode), #endif - mRect(0, 0, 0, 0) + mIStart(0), + mBStart(0), + mISize(0), + mBSize(0) { } LogicalRect(WritingMode aWritingMode, nscoord aIStart, nscoord aBStart, nscoord aISize, nscoord aBSize) : #ifdef DEBUG mWritingMode(aWritingMode), #endif - mRect(aIStart, aBStart, aISize, aBSize) + mIStart(aIStart), + mBStart(aBStart), + mISize(aISize), + mBSize(aBSize) { } LogicalRect(WritingMode aWritingMode, const LogicalPoint& aOrigin, const LogicalSize& aSize) : #ifdef DEBUG mWritingMode(aWritingMode), #endif - mRect(aOrigin.mPoint, aSize.mSize) + mIStart(aOrigin.mPoint.x), + mBStart(aOrigin.mPoint.y), + mISize(aSize.mSize.width), + mBSize(aSize.mSize.height) { CHECK_WRITING_MODE(aOrigin.GetWritingMode()); CHECK_WRITING_MODE(aSize.GetWritingMode()); } LogicalRect(WritingMode aWritingMode, const nsRect& aRect, const nsSize& aContainerSize) #ifdef DEBUG : mWritingMode(aWritingMode) #endif { if (aWritingMode.IsVertical()) { - mRect.y = aWritingMode.IsVerticalLR() - ? aRect.x : aContainerSize.width - aRect.XMost(); - mRect.x = aWritingMode.IsInlineReversed() - ? aContainerSize.height - aRect.YMost() : aRect.y; - mRect.height = aRect.width; - mRect.width = aRect.height; + mBStart = aWritingMode.IsVerticalLR() + ? aRect.X() : aContainerSize.width - aRect.XMost(); + mIStart = aWritingMode.IsInlineReversed() + ? aContainerSize.height - aRect.YMost() : aRect.Y(); + mBSize = aRect.Width(); + mISize = aRect.Height(); } else { - mRect.x = aWritingMode.IsInlineReversed() - ? aContainerSize.width - aRect.XMost() : aRect.x; - mRect.y = aRect.y; - mRect.width = aRect.width; - mRect.height = aRect.height; + mIStart = aWritingMode.IsInlineReversed() + ? aContainerSize.width - aRect.XMost() : aRect.X(); + mBStart = aRect.Y(); + mISize = aRect.Width(); + mBSize = aRect.Height(); } } /** * Inline- and block-dimension geometry. */ nscoord IStart(WritingMode aWritingMode) const // inline-start edge { CHECK_WRITING_MODE(aWritingMode); - return mRect.X(); + return mIStart; } nscoord IEnd(WritingMode aWritingMode) const // inline-end edge { CHECK_WRITING_MODE(aWritingMode); - return mRect.XMost(); + return mIStart + mISize; } nscoord ISize(WritingMode aWritingMode) const // inline-size { CHECK_WRITING_MODE(aWritingMode); - return mRect.Width(); + return mISize; } nscoord BStart(WritingMode aWritingMode) const // block-start edge { CHECK_WRITING_MODE(aWritingMode); - return mRect.Y(); + return mBStart; } nscoord BEnd(WritingMode aWritingMode) const // block-end edge { CHECK_WRITING_MODE(aWritingMode); - return mRect.YMost(); + return mBStart + mBSize; } nscoord BSize(WritingMode aWritingMode) const // block-size { CHECK_WRITING_MODE(aWritingMode); - return mRect.Height(); + return mBSize; } /** * Writable (reference) accessors are only available for the basic logical * fields (Start and Size), not derivatives like End. */ nscoord& IStart(WritingMode aWritingMode) // inline-start edge { CHECK_WRITING_MODE(aWritingMode); - return mRect.x; + return mIStart; } nscoord& ISize(WritingMode aWritingMode) // inline-size { CHECK_WRITING_MODE(aWritingMode); - return mRect.width; + return mISize; } nscoord& BStart(WritingMode aWritingMode) // block-start edge { CHECK_WRITING_MODE(aWritingMode); - return mRect.y; + return mBStart; } nscoord& BSize(WritingMode aWritingMode) // block-size { CHECK_WRITING_MODE(aWritingMode); - return mRect.height; + return mBSize; } /** * Accessors for line-relative coordinates */ nscoord LineLeft(WritingMode aWritingMode, const nsSize& aContainerSize) const { @@ -1627,91 +1636,98 @@ public: /** * Physical coordinates of the rect. */ nscoord X(WritingMode aWritingMode, nscoord aContainerWidth) const { CHECK_WRITING_MODE(aWritingMode); if (aWritingMode.IsVertical()) { return aWritingMode.IsVerticalLR() ? - mRect.Y() : aContainerWidth - mRect.YMost(); + mBStart : aContainerWidth - BEnd(); } else { return aWritingMode.IsInlineReversed() ? - aContainerWidth - mRect.XMost() : mRect.X(); + aContainerWidth - IEnd() : mIStart; } } nscoord Y(WritingMode aWritingMode, nscoord aContainerHeight) const { CHECK_WRITING_MODE(aWritingMode); if (aWritingMode.IsVertical()) { - return aWritingMode.IsInlineReversed() ? aContainerHeight - mRect.XMost() - : mRect.X(); + return aWritingMode.IsInlineReversed() ? aContainerHeight - IEnd() + : mIStart; } else { - return mRect.Y(); + return mBStart; } } nscoord Width(WritingMode aWritingMode) const { CHECK_WRITING_MODE(aWritingMode); - return aWritingMode.IsVertical() ? mRect.Height() : mRect.Width(); + return aWritingMode.IsVertical() ? mBSize : mISize; } nscoord Height(WritingMode aWritingMode) const { CHECK_WRITING_MODE(aWritingMode); - return aWritingMode.IsVertical() ? mRect.Width() : mRect.Height(); + return aWritingMode.IsVertical() ? mISize : mBSize; } nscoord XMost(WritingMode aWritingMode, nscoord aContainerWidth) const { CHECK_WRITING_MODE(aWritingMode); if (aWritingMode.IsVertical()) { return aWritingMode.IsVerticalLR() ? - mRect.YMost() : aContainerWidth - mRect.Y(); + BEnd() : aContainerWidth - mBStart; } else { return aWritingMode.IsInlineReversed() ? - aContainerWidth - mRect.X() : mRect.XMost(); + aContainerWidth - mIStart : IEnd(); } } nscoord YMost(WritingMode aWritingMode, nscoord aContainerHeight) const { CHECK_WRITING_MODE(aWritingMode); if (aWritingMode.IsVertical()) { - return aWritingMode.IsInlineReversed() ? aContainerHeight - mRect.x - : mRect.XMost(); + return aWritingMode.IsInlineReversed() ? aContainerHeight - mIStart + : IEnd(); } else { - return mRect.YMost(); + return mBStart; } } bool IsEmpty() const { - return mRect.IsEmpty(); + return mISize <= 0 || mBSize << 0; } bool IsAllZero() const { - return (mRect.x == 0 && mRect.y == 0 && - mRect.width == 0 && mRect.height == 0); + return (mIStart == 0 && mBStart == 0 && + mISize == 0 && mBSize == 0); } bool IsZeroSize() const { - return (mRect.width == 0 && mRect.height == 0); + return (mISize == 0 && mBSize == 0); } - void SetEmpty() { mRect.SetEmpty(); } + void SetEmpty() { mISize = mBSize = 0; } bool IsEqualEdges(const LogicalRect aOther) const { CHECK_WRITING_MODE(aOther.GetWritingMode()); - return mRect.IsEqualEdges(aOther.mRect); + bool result = mIStart == aOther.mIStart && mBStart == aOther.mBStart && + mISize == aOther.mISize && mBSize == aOther.mBSize; + + // We want the same result as nsRect, so assert we get it. + MOZ_ASSERT(result == nsRect(mIStart, mBStart, mISize, mBSize). + IsEqualEdges(nsRect(aOther.mIStart, aOther.mBStart, + aOther.mISize, aOther.mBSize))); + return result; } LogicalPoint Origin(WritingMode aWritingMode) const { CHECK_WRITING_MODE(aWritingMode); return LogicalPoint(aWritingMode, IStart(), BStart()); } void SetOrigin(WritingMode aWritingMode, const LogicalPoint& aPoint) @@ -1732,59 +1748,127 @@ public: return LogicalRect(GetWritingMode(), IStart() + aPoint.I(), BStart() + aPoint.B(), ISize(), BSize()); } LogicalRect& operator+=(const LogicalPoint& aPoint) { CHECK_WRITING_MODE(aPoint.GetWritingMode()); - mRect += aPoint.mPoint; + mIStart += aPoint.mPoint.x; + mBStart += aPoint.mPoint.y; return *this; } LogicalRect operator-(const LogicalPoint& aPoint) const { CHECK_WRITING_MODE(aPoint.GetWritingMode()); return LogicalRect(GetWritingMode(), IStart() - aPoint.I(), BStart() - aPoint.B(), ISize(), BSize()); } LogicalRect& operator-=(const LogicalPoint& aPoint) { CHECK_WRITING_MODE(aPoint.GetWritingMode()); - mRect -= aPoint.mPoint; + mIStart -= aPoint.mPoint.x; + mBStart -= aPoint.mPoint.y; return *this; } void MoveBy(WritingMode aWritingMode, const LogicalPoint& aDelta) { CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aDelta.GetWritingMode()); IStart() += aDelta.I(); BStart() += aDelta.B(); } - void Inflate(nscoord aD) { mRect.Inflate(aD); } - void Inflate(nscoord aDI, nscoord aDB) { mRect.Inflate(aDI, aDB); } + void Inflate(nscoord aD) + { +#ifdef DEBUG + // Compute using nsRect and assert the results match + nsRect rectDebug(mIStart, mBStart, mISize, mBSize); + rectDebug.Inflate(aD); +#endif + mIStart -= aD; + mBStart -= aD; + mISize += 2 * aD; + mBSize += 2 * aD; + MOZ_ASSERT(rectDebug.IsEqualEdges(nsRect(mIStart, mBStart, mISize, mBSize))); + } + void Inflate(nscoord aDI, nscoord aDB) + { +#ifdef DEBUG + // Compute using nsRect and assert the results match + nsRect rectDebug(mIStart, mBStart, mISize, mBSize); + rectDebug.Inflate(aDI, aDB); +#endif + mIStart -= aDI; + mBStart -= aDB; + mISize += 2 * aDI; + mBSize += 2 * aDB; + MOZ_ASSERT(rectDebug.IsEqualEdges(nsRect(mIStart, mBStart, mISize, mBSize))); + } void Inflate(WritingMode aWritingMode, const LogicalMargin& aMargin) { CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aMargin.GetWritingMode()); - mRect.Inflate(aMargin.mMargin); +#ifdef DEBUG + // Compute using nsRect and assert the results match + nsRect rectDebug(mIStart, mBStart, mISize, mBSize); + rectDebug.Inflate(aMargin.mMargin); +#endif + mIStart -= aMargin.mMargin.left; + mBStart -= aMargin.mMargin.top; + mISize += aMargin.mMargin.LeftRight(); + mBSize += aMargin.mMargin.TopBottom(); + MOZ_ASSERT(rectDebug.IsEqualEdges(nsRect(mIStart, mBStart, mISize, mBSize))); } - void Deflate(nscoord aD) { mRect.Deflate(aD); } - void Deflate(nscoord aDI, nscoord aDB) { mRect.Deflate(aDI, aDB); } + void Deflate(nscoord aD) + { +#ifdef DEBUG + // Compute using nsRect and assert the results match + nsRect rectDebug(mIStart, mBStart, mISize, mBSize); + rectDebug.Deflate(aD); +#endif + mIStart += aD; + mBStart += aD; + mISize = std::max(0, mISize - 2 * aD); + mBSize = std::max(0, mBSize - 2 * aD); + MOZ_ASSERT(rectDebug.IsEqualEdges(nsRect(mIStart, mBStart, mISize, mBSize))); + } + void Deflate(nscoord aDI, nscoord aDB) + { +#ifdef DEBUG + // Compute using nsRect and assert the results match + nsRect rectDebug(mIStart, mBStart, mISize, mBSize); + rectDebug.Deflate(aDI, aDB); +#endif + mIStart += aDI; + mBStart += aDB; + mISize = std::max(0, mISize - 2 * aDI); + mBSize = std::max(0, mBSize - 2 * aDB); + MOZ_ASSERT(rectDebug.IsEqualEdges(nsRect(mIStart, mBStart, mISize, mBSize))); + } void Deflate(WritingMode aWritingMode, const LogicalMargin& aMargin) { CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aMargin.GetWritingMode()); - mRect.Deflate(aMargin.mMargin); +#ifdef DEBUG + // Compute using nsRect and assert the results match + nsRect rectDebug(mIStart, mBStart, mISize, mBSize); + rectDebug.Deflate(aMargin.mMargin); +#endif + mIStart += aMargin.mMargin.left; + mBStart += aMargin.mMargin.top; + mISize = std::max(0, mISize - aMargin.mMargin.LeftRight()); + mBSize = std::max(0, mBSize - aMargin.mMargin.TopBottom()); + MOZ_ASSERT(rectDebug.IsEqualEdges(nsRect(mIStart, mBStart, mISize, mBSize))); } /** * Return an nsRect containing our physical coordinates within the given * container size. */ nsRect GetPhysicalRect(WritingMode aWritingMode, const nsSize& aContainerSize) const @@ -1818,75 +1902,102 @@ public: /** * Set *this to be the rectangle containing the intersection of aRect1 * and aRect2, return whether the intersection is non-empty. */ bool IntersectRect(const LogicalRect& aRect1, const LogicalRect& aRect2) { CHECK_WRITING_MODE(aRect1.mWritingMode); CHECK_WRITING_MODE(aRect2.mWritingMode); - return mRect.IntersectRect(aRect1.mRect, aRect2.mRect); +#ifdef DEBUG + // Compute using nsRect and assert the results match + nsRect rectDebug; + rectDebug.IntersectRect(nsRect(aRect1.mIStart, aRect1.mBStart, + aRect1.mISize, aRect1.mBSize), + nsRect(aRect2.mIStart, aRect2.mBStart, + aRect2.mISize, aRect2.mBSize)); +#endif + + nscoord iEnd = std::min(aRect1.IEnd(), aRect2.IEnd()); + mIStart = std::max(aRect1.mIStart, aRect2.mIStart); + mISize = iEnd - mIStart; + + nscoord bEnd = std::min(aRect1.BEnd(), aRect2.BEnd()); + mBStart = std::max(aRect1.mBStart, aRect2.mBStart); + mBSize = bEnd - mBStart; + + if (mISize < 0 || mBSize < 0) { + mISize = 0; + mBSize = 0; + } + + MOZ_ASSERT(rectDebug.IsEqualEdges(nsRect(mIStart, mBStart, mISize, mBSize))); + return mISize > 0 && mBSize > 0; } private: LogicalRect() = delete; #ifdef DEBUG WritingMode GetWritingMode() const { return mWritingMode; } #else WritingMode GetWritingMode() const { return WritingMode::Unknown(); } #endif nscoord IStart() const // inline-start edge { - return mRect.X(); + return mIStart; } nscoord IEnd() const // inline-end edge { - return mRect.XMost(); + return mIStart + mISize; } nscoord ISize() const // inline-size { - return mRect.Width(); + return mISize; } nscoord BStart() const // block-start edge { - return mRect.Y(); + return mBStart; } nscoord BEnd() const // block-end edge { - return mRect.YMost(); + return mBStart + mBSize; } nscoord BSize() const // block-size { - return mRect.Height(); + return mBSize; } nscoord& IStart() // inline-start edge { - return mRect.x; + return mIStart; } nscoord& ISize() // inline-size { - return mRect.width; + return mISize; } nscoord& BStart() // block-start edge { - return mRect.y; + return mBStart; } nscoord& BSize() // block-size { - return mRect.height; + return mBSize; } #ifdef DEBUG WritingMode mWritingMode; #endif - nsRect mRect; + // Inline- and block-geometry dimension + nscoord mIStart; // inline-start edge + nscoord mBStart; // block-start edge + nscoord mISize; // inline-size + nscoord mBSize; // block-size }; } // namespace mozilla // Definitions of inline methods for nsStyleSides, declared in nsStyleCoord.h // but not defined there because they need WritingMode. inline nsStyleUnit nsStyleSides::GetUnit(mozilla::WritingMode aWM, mozilla::LogicalSide aSide) const