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
authorMilan Sreckovic <milan@mozilla.com>
Tue, 07 Nov 2017 09:38:31 -0500
changeset 444055 2a52e1d4c300aa71652652c4349d4e06c74c9dc7
parent 444054 0f9f5ef2c14122360e4bd3ea2ae171fad7ae2554
child 444056 1ede5a47bb9877a7bd01eb4303d65b8462f1d32c
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas, jfkthame
bugs1389152
milestone58.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
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
gfx/tests/gtest/TestRect.cpp
layout/generic/WritingModes.h
--- 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