Bug 665597. Add nsRect::SaturatingUnion(Rect)(Edges). r=mats
authorRobert O'Callahan <robert@ocallahan.org>
Tue, 03 Jan 2012 11:55:30 +1300
changeset 84612 961442fdd15945f7d1fbe3b4098e87f633de97c5
parent 84605 7ea3311b5e6c2465baf167d3e6dc55998c0ae1fb
child 84613 e176daacecfca8baadaada589d8f85d32ffaff34
push id21868
push usermak77@bonardo.net
push dateTue, 17 Jan 2012 15:23:07 +0000
treeherdermozilla-central@ff1bedd7d463 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs665597
milestone12.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 665597. Add nsRect::SaturatingUnion(Rect)(Edges). r=mats
gfx/src/nsRect.h
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -76,16 +76,64 @@ struct NS_GFX nsRect :
   }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
   ~nsRect() {
     MOZ_COUNT_DTOR(nsRect);
   }
 #endif
 
+  // We have saturating versions of all the Union methods. These avoid
+  // overflowing nscoord values in the 'width' and 'height' fields by
+  // clamping the width and height values to nscoord_MAX if necessary.
+
+  nsRect SaturatingUnion(const nsRect& aRect) const
+  {
+    if (IsEmpty()) {
+      return aRect;
+    } else if (aRect.IsEmpty()) {
+      return *static_cast<const nsRect*>(this);
+    } else {
+      return SaturatingUnionEdges(aRect);
+    }
+  }
+
+  nsRect SaturatingUnionEdges(const nsRect& aRect) const
+  {
+#ifdef NS_COORD_IS_FLOAT
+    return UnionEdges(aRect);
+#else
+    nsRect result;
+    result.x = NS_MIN(aRect.x, x);
+    result.y = NS_MIN(aRect.y, y);
+    PRInt64 w = NS_MAX(PRInt64(aRect.x) + aRect.width, PRInt64(x) + width) - result.x;
+    PRInt64 h = NS_MAX(PRInt64(aRect.y) + aRect.height, PRInt64(y) + height) - result.y;
+    if (w > nscoord_MAX) {
+      NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord width");
+      w = nscoord_MAX;
+    }
+    if (h > nscoord_MAX) {
+      NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord height");
+      h = nscoord_MAX;
+    }
+    result.width = nscoord(w);
+    result.height = nscoord(h);
+    return result;
+#endif
+  }
+
+  void SaturatingUnionRect(const nsRect& aRect1, const nsRect& aRect2)
+  {
+    *this = aRect1.SaturatingUnion(aRect2);
+  }
+  void SaturatingUnionRectEdges(const nsRect& aRect1, const nsRect& aRect2)
+  {
+    *this = aRect1.SaturatingUnionEdges(aRect2);
+  }
+
   // Converts this rect from aFromAPP, an appunits per pixel ratio, to aToAPP.
   // In the RoundOut version we make the rect the smallest rect containing the
   // unrounded result. In the RoundIn version we make the rect the largest rect
   // contained in the unrounded result.
   // Note: this can turn an empty rectangle into a non-empty rectangle
   inline nsRect ConvertAppUnitsRoundOut(PRInt32 aFromAPP, PRInt32 aToAPP) const;
   inline nsRect ConvertAppUnitsRoundIn(PRInt32 aFromAPP, PRInt32 aToAPP) const;