Bug 1389152: Change LogicalRect from having nsRect as a member variable, and exposing its member variable addresses, to storing four nscoord values separately and doing some operations by creating temporary rectangles to ensure consistency. Add a method to BaseRect to get OriginAndSize at once. r=bas,jfkthame.schouten

MozReview-Commit-ID: FhmSXK7p5c6

--HG--
extra : rebase_source : eb542fac9017852fa812b54aa3b12f0522a1e4be
This commit is contained in:
Milan Sreckovic 2017-11-07 09:38:31 -05:00
Родитель b4927e95b5
Коммит 1c4ab9e9c2
2 изменённых файлов: 223 добавлений и 62 удалений

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsRect.h" #include "nsRect.h"
#include "gfxRect.h" #include "gfxRect.h"
#include "mozilla/WritingModes.h"
#ifdef XP_WIN #ifdef XP_WIN
#include <windows.h> #include <windows.h>
#endif #endif
@ -445,7 +446,55 @@ TestSwap()
return true; 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) { TEST(Gfx, nsRect) {
TestConstructors<nsRect>(); TestConstructors<nsRect>();
@ -483,3 +532,4 @@ TEST(Gfx, gfxRect) {
TestSetWH<gfxRect>(); TestSetWH<gfxRect>();
TestSwap<gfxRect>(); TestSwap<gfxRect>();
} }

Просмотреть файл

@ -1489,7 +1489,10 @@ public:
#ifdef DEBUG #ifdef DEBUG
mWritingMode(aWritingMode), mWritingMode(aWritingMode),
#endif #endif
mRect(0, 0, 0, 0) mIStart(0),
mBStart(0),
mISize(0),
mBSize(0)
{ } { }
LogicalRect(WritingMode aWritingMode, LogicalRect(WritingMode aWritingMode,
@ -1499,7 +1502,10 @@ public:
#ifdef DEBUG #ifdef DEBUG
mWritingMode(aWritingMode), mWritingMode(aWritingMode),
#endif #endif
mRect(aIStart, aBStart, aISize, aBSize) mIStart(aIStart),
mBStart(aBStart),
mISize(aISize),
mBSize(aBSize)
{ } { }
LogicalRect(WritingMode aWritingMode, LogicalRect(WritingMode aWritingMode,
@ -1509,7 +1515,10 @@ public:
#ifdef DEBUG #ifdef DEBUG
mWritingMode(aWritingMode), mWritingMode(aWritingMode),
#endif #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(aOrigin.GetWritingMode());
CHECK_WRITING_MODE(aSize.GetWritingMode()); CHECK_WRITING_MODE(aSize.GetWritingMode());
@ -1523,18 +1532,18 @@ public:
#endif #endif
{ {
if (aWritingMode.IsVertical()) { if (aWritingMode.IsVertical()) {
mRect.y = aWritingMode.IsVerticalLR() mBStart = aWritingMode.IsVerticalLR()
? aRect.x : aContainerSize.width - aRect.XMost(); ? aRect.X() : aContainerSize.width - aRect.XMost();
mRect.x = aWritingMode.IsInlineReversed() mIStart = aWritingMode.IsInlineReversed()
? aContainerSize.height - aRect.YMost() : aRect.y; ? aContainerSize.height - aRect.YMost() : aRect.Y();
mRect.height = aRect.width; mBSize = aRect.Width();
mRect.width = aRect.height; mISize = aRect.Height();
} else { } else {
mRect.x = aWritingMode.IsInlineReversed() mIStart = aWritingMode.IsInlineReversed()
? aContainerSize.width - aRect.XMost() : aRect.x; ? aContainerSize.width - aRect.XMost() : aRect.X();
mRect.y = aRect.y; mBStart = aRect.Y();
mRect.width = aRect.width; mISize = aRect.Width();
mRect.height = aRect.height; mBSize = aRect.Height();
} }
} }
@ -1544,33 +1553,33 @@ public:
nscoord IStart(WritingMode aWritingMode) const // inline-start edge nscoord IStart(WritingMode aWritingMode) const // inline-start edge
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.X(); return mIStart;
} }
nscoord IEnd(WritingMode aWritingMode) const // inline-end edge nscoord IEnd(WritingMode aWritingMode) const // inline-end edge
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.XMost(); return mIStart + mISize;
} }
nscoord ISize(WritingMode aWritingMode) const // inline-size nscoord ISize(WritingMode aWritingMode) const // inline-size
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.Width(); return mISize;
} }
nscoord BStart(WritingMode aWritingMode) const // block-start edge nscoord BStart(WritingMode aWritingMode) const // block-start edge
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.Y(); return mBStart;
} }
nscoord BEnd(WritingMode aWritingMode) const // block-end edge nscoord BEnd(WritingMode aWritingMode) const // block-end edge
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.YMost(); return mBStart + mBSize;
} }
nscoord BSize(WritingMode aWritingMode) const // block-size nscoord BSize(WritingMode aWritingMode) const // block-size
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.Height(); return mBSize;
} }
/** /**
@ -1580,22 +1589,22 @@ public:
nscoord& IStart(WritingMode aWritingMode) // inline-start edge nscoord& IStart(WritingMode aWritingMode) // inline-start edge
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.x; return mIStart;
} }
nscoord& ISize(WritingMode aWritingMode) // inline-size nscoord& ISize(WritingMode aWritingMode) // inline-size
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.width; return mISize;
} }
nscoord& BStart(WritingMode aWritingMode) // block-start edge nscoord& BStart(WritingMode aWritingMode) // block-start edge
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.y; return mBStart;
} }
nscoord& BSize(WritingMode aWritingMode) // block-size nscoord& BSize(WritingMode aWritingMode) // block-size
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return mRect.height; return mBSize;
} }
/** /**
@ -1632,10 +1641,10 @@ public:
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
if (aWritingMode.IsVertical()) { if (aWritingMode.IsVertical()) {
return aWritingMode.IsVerticalLR() ? return aWritingMode.IsVerticalLR() ?
mRect.Y() : aContainerWidth - mRect.YMost(); mBStart : aContainerWidth - BEnd();
} else { } else {
return aWritingMode.IsInlineReversed() ? return aWritingMode.IsInlineReversed() ?
aContainerWidth - mRect.XMost() : mRect.X(); aContainerWidth - IEnd() : mIStart;
} }
} }
@ -1643,23 +1652,23 @@ public:
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
if (aWritingMode.IsVertical()) { if (aWritingMode.IsVertical()) {
return aWritingMode.IsInlineReversed() ? aContainerHeight - mRect.XMost() return aWritingMode.IsInlineReversed() ? aContainerHeight - IEnd()
: mRect.X(); : mIStart;
} else { } else {
return mRect.Y(); return mBStart;
} }
} }
nscoord Width(WritingMode aWritingMode) const nscoord Width(WritingMode aWritingMode) const
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return aWritingMode.IsVertical() ? mRect.Height() : mRect.Width(); return aWritingMode.IsVertical() ? mBSize : mISize;
} }
nscoord Height(WritingMode aWritingMode) const nscoord Height(WritingMode aWritingMode) const
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
return aWritingMode.IsVertical() ? mRect.Width() : mRect.Height(); return aWritingMode.IsVertical() ? mISize : mBSize;
} }
nscoord XMost(WritingMode aWritingMode, nscoord aContainerWidth) const nscoord XMost(WritingMode aWritingMode, nscoord aContainerWidth) const
@ -1667,10 +1676,10 @@ public:
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
if (aWritingMode.IsVertical()) { if (aWritingMode.IsVertical()) {
return aWritingMode.IsVerticalLR() ? return aWritingMode.IsVerticalLR() ?
mRect.YMost() : aContainerWidth - mRect.Y(); BEnd() : aContainerWidth - mBStart;
} else { } else {
return aWritingMode.IsInlineReversed() ? return aWritingMode.IsInlineReversed() ?
aContainerWidth - mRect.X() : mRect.XMost(); aContainerWidth - mIStart : IEnd();
} }
} }
@ -1678,35 +1687,42 @@ public:
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
if (aWritingMode.IsVertical()) { if (aWritingMode.IsVertical()) {
return aWritingMode.IsInlineReversed() ? aContainerHeight - mRect.x return aWritingMode.IsInlineReversed() ? aContainerHeight - mIStart
: mRect.XMost(); : IEnd();
} else { } else {
return mRect.YMost(); return mBStart;
} }
} }
bool IsEmpty() const bool IsEmpty() const
{ {
return mRect.IsEmpty(); return mISize <= 0 || mBSize << 0;
} }
bool IsAllZero() const bool IsAllZero() const
{ {
return (mRect.x == 0 && mRect.y == 0 && return (mIStart == 0 && mBStart == 0 &&
mRect.width == 0 && mRect.height == 0); mISize == 0 && mBSize == 0);
} }
bool IsZeroSize() const 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 bool IsEqualEdges(const LogicalRect aOther) const
{ {
CHECK_WRITING_MODE(aOther.GetWritingMode()); 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 LogicalPoint Origin(WritingMode aWritingMode) const
@ -1737,7 +1753,8 @@ public:
LogicalRect& operator+=(const LogicalPoint& aPoint) LogicalRect& operator+=(const LogicalPoint& aPoint)
{ {
CHECK_WRITING_MODE(aPoint.GetWritingMode()); CHECK_WRITING_MODE(aPoint.GetWritingMode());
mRect += aPoint.mPoint; mIStart += aPoint.mPoint.x;
mBStart += aPoint.mPoint.y;
return *this; return *this;
} }
@ -1752,7 +1769,8 @@ public:
LogicalRect& operator-=(const LogicalPoint& aPoint) LogicalRect& operator-=(const LogicalPoint& aPoint)
{ {
CHECK_WRITING_MODE(aPoint.GetWritingMode()); CHECK_WRITING_MODE(aPoint.GetWritingMode());
mRect -= aPoint.mPoint; mIStart -= aPoint.mPoint.x;
mBStart -= aPoint.mPoint.y;
return *this; return *this;
} }
@ -1764,22 +1782,88 @@ public:
BStart() += aDelta.B(); BStart() += aDelta.B();
} }
void Inflate(nscoord aD) { mRect.Inflate(aD); } void Inflate(nscoord aD)
void Inflate(nscoord aDI, nscoord aDB) { mRect.Inflate(aDI, aDB); } {
#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) void Inflate(WritingMode aWritingMode, const LogicalMargin& aMargin)
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
CHECK_WRITING_MODE(aMargin.GetWritingMode()); 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 aD)
void Deflate(nscoord aDI, nscoord aDB) { mRect.Deflate(aDI, aDB); } {
#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) void Deflate(WritingMode aWritingMode, const LogicalMargin& aMargin)
{ {
CHECK_WRITING_MODE(aWritingMode); CHECK_WRITING_MODE(aWritingMode);
CHECK_WRITING_MODE(aMargin.GetWritingMode()); 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)));
} }
/** /**
@ -1823,7 +1907,30 @@ public:
{ {
CHECK_WRITING_MODE(aRect1.mWritingMode); CHECK_WRITING_MODE(aRect1.mWritingMode);
CHECK_WRITING_MODE(aRect2.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: private:
@ -1837,51 +1944,55 @@ private:
nscoord IStart() const // inline-start edge nscoord IStart() const // inline-start edge
{ {
return mRect.X(); return mIStart;
} }
nscoord IEnd() const // inline-end edge nscoord IEnd() const // inline-end edge
{ {
return mRect.XMost(); return mIStart + mISize;
} }
nscoord ISize() const // inline-size nscoord ISize() const // inline-size
{ {
return mRect.Width(); return mISize;
} }
nscoord BStart() const // block-start edge nscoord BStart() const // block-start edge
{ {
return mRect.Y(); return mBStart;
} }
nscoord BEnd() const // block-end edge nscoord BEnd() const // block-end edge
{ {
return mRect.YMost(); return mBStart + mBSize;
} }
nscoord BSize() const // block-size nscoord BSize() const // block-size
{ {
return mRect.Height(); return mBSize;
} }
nscoord& IStart() // inline-start edge nscoord& IStart() // inline-start edge
{ {
return mRect.x; return mIStart;
} }
nscoord& ISize() // inline-size nscoord& ISize() // inline-size
{ {
return mRect.width; return mISize;
} }
nscoord& BStart() // block-start edge nscoord& BStart() // block-start edge
{ {
return mRect.y; return mBStart;
} }
nscoord& BSize() // block-size nscoord& BSize() // block-size
{ {
return mRect.height; return mBSize;
} }
#ifdef DEBUG #ifdef DEBUG
WritingMode mWritingMode; WritingMode mWritingMode;
#endif #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 } // namespace mozilla