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

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

@ -1489,7 +1489,10 @@ public:
#ifdef DEBUG
mWritingMode(aWritingMode),
#endif
mRect(0, 0, 0, 0)
mIStart(0),
mBStart(0),
mISize(0),
mBSize(0)
{ }
LogicalRect(WritingMode aWritingMode,
@ -1499,7 +1502,10 @@ public:
#ifdef DEBUG
mWritingMode(aWritingMode),
#endif
mRect(aIStart, aBStart, aISize, aBSize)
mIStart(aIStart),
mBStart(aBStart),
mISize(aISize),
mBSize(aBSize)
{ }
LogicalRect(WritingMode aWritingMode,
@ -1509,7 +1515,10 @@ public:
#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());
@ -1523,18 +1532,18 @@ public:
#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();
}
}
@ -1544,33 +1553,33 @@ public:
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;
}
/**
@ -1580,22 +1589,22 @@ public:
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;
}
/**
@ -1632,10 +1641,10 @@ public:
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;
}
}
@ -1643,23 +1652,23 @@ public:
{
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
@ -1667,10 +1676,10 @@ public:
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();
}
}
@ -1678,35 +1687,42 @@ public:
{
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
@ -1737,7 +1753,8 @@ public:
LogicalRect& operator+=(const LogicalPoint& aPoint)
{
CHECK_WRITING_MODE(aPoint.GetWritingMode());
mRect += aPoint.mPoint;
mIStart += aPoint.mPoint.x;
mBStart += aPoint.mPoint.y;
return *this;
}
@ -1752,7 +1769,8 @@ public:
LogicalRect& operator-=(const LogicalPoint& aPoint)
{
CHECK_WRITING_MODE(aPoint.GetWritingMode());
mRect -= aPoint.mPoint;
mIStart -= aPoint.mPoint.x;
mBStart -= aPoint.mPoint.y;
return *this;
}
@ -1764,22 +1782,88 @@ public:
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)));
}
/**
@ -1823,7 +1907,30 @@ public:
{
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:
@ -1837,51 +1944,55 @@ private:
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