Bug 586683 - Part 2a - Add ScaleRoundOut to nsIntRect/Region. r=joe a=blocking2.0
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 09 Feb 2011 09:37:44 +1300
changeset 62162 b0512b9a8c11ae974391a714753aca994857a391
parent 62161 5ed6c4935486d1aee52f9edcd96043b0fab86fb8
child 62163 acec86b21f5ee4b38145d92cc182a206be0e3299
push id18625
push usermwoodrow@mozilla.com
push dateTue, 08 Feb 2011 20:45:21 +0000
treeherdermozilla-central@0b4c13e87e5a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe, blocking2
bugs586683
milestone2.0b12pre
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 586683 - Part 2a - Add ScaleRoundOut to nsIntRect/Region. r=joe a=blocking2.0
gfx/src/nsRect.cpp
gfx/src/nsRect.h
gfx/src/nsRegion.cpp
gfx/src/nsRegion.h
--- a/gfx/src/nsRect.cpp
+++ b/gfx/src/nsRect.cpp
@@ -323,8 +323,20 @@ PRBool nsIntRect::UnionRect(const nsIntR
     // Compute the size
     width = PR_MAX(xmost1, xmost2) - x;
     height = PR_MAX(ymost1, ymost2) - y;
   }
 
   return result;
 }
 
+// scale the rect but round to smallest containing rect
+nsIntRect& nsIntRect::ScaleRoundOut(float aXScale, float aYScale)
+{
+  nscoord right = NSToCoordCeil(float(XMost()) * aXScale);
+  nscoord bottom = NSToCoordCeil(float(YMost()) * aYScale);
+  x = NSToCoordFloor(float(x) * aXScale);
+  y = NSToCoordFloor(float(y) * aYScale);
+  width = (right - x);
+  height = (bottom - y);
+  return *this;
+}
+
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -337,16 +337,18 @@ struct NS_GFX nsIntRect {
 
   nsIntSize Size() const { return nsIntSize(width, height); }
 
   // Helper methods for computing the extents
   PRInt32 XMost() const {return x + width;}
   PRInt32 YMost() const {return y + height;}
 
   inline nsRect ToAppUnits(nscoord aAppUnitsPerPixel) const;
+
+  nsIntRect& ScaleRoundOut(float aXScale, float aYScale);
 
   // Returns a special nsIntRect that's used in some places to signify
   // "all available space".
   static const nsIntRect& GetMaxSizedIntRect() { return kMaxSizedIntRect; }
 
 protected:
   static const nsIntRect kMaxSizedIntRect;
 };
--- a/gfx/src/nsRegion.cpp
+++ b/gfx/src/nsRegion.cpp
@@ -1311,16 +1311,32 @@ nsRegion& nsRegion::ExtendForScaling (fl
       break;
     nsRect rect = *r;
     rect.ExtendForScaling(aXMult, aYMult);
     region.Or(region, rect);
   }
   *this = region;
   return *this;
 }
+
+nsRegion& nsRegion::ScaleRoundOut (float aXScale, float aYScale)
+{
+  nsRegion region;
+  nsRegionRectIterator iter(*this);
+  for (;;) {
+    const nsRect* r = iter.Next();
+    if (!r)
+      break;
+    nsRect rect = *r;
+    rect.ScaleRoundOut(aXScale, aYScale);
+    region.Or(region, rect);
+  }
+  *this = region;
+  return *this;
+}
 
 nsRegion nsRegion::ConvertAppUnitsRoundOut (PRInt32 aFromAPP, PRInt32 aToAPP) const
 {
   if (aFromAPP == aToAPP) {
     return *this;
   }
   // Do it in a simplistic and slow way to avoid any weird behaviour with
   // rounding causing rects to overlap. Should be fast enough for what we need.
--- a/gfx/src/nsRegion.h
+++ b/gfx/src/nsRegion.h
@@ -179,16 +179,17 @@ public:
   PRBool IsEqual (const nsRegion& aRegion) const;
   PRUint32 GetNumRects () const { return mRectCount; }
   const nsRect& GetBounds () const { return mBoundRect; }
   // Converts this region from aFromAPP, an appunits per pixel ratio, to
   // aToAPP. This applies nsRect::ConvertAppUnitsRoundOut/In to each rect of
   // the region.
   nsRegion ConvertAppUnitsRoundOut (PRInt32 aFromAPP, PRInt32 aToAPP) const;
   nsRegion ConvertAppUnitsRoundIn (PRInt32 aFromAPP, PRInt32 aToAPP) const;
+  nsRegion& ScaleRoundOut(float aXScale, float aYScale);
   nsIntRegion ToOutsidePixels (nscoord aAppUnitsPerPixel) const;
   nsRegion& ExtendForScaling (float aXMult, float aYMult);
 
   /**
    * Gets the largest rectangle contained in the region.
    * @param aContainingRect if non-empty, we choose a rectangle that
    * maximizes the area intersecting with aContainingRect (and break ties by
    * then choosing the largest rectangle overall)
@@ -433,16 +434,22 @@ public:
   }
   PRUint32 GetNumRects () const { return mImpl.GetNumRects (); }
   nsIntRect GetBounds () const { return FromRect (mImpl.GetBounds ()); }
   nsRegion ToAppUnits (nscoord aAppUnitsPerPixel) const;
   nsIntRect GetLargestRectangle (const nsIntRect& aContainingRect = nsIntRect()) const
   {
     return FromRect (mImpl.GetLargestRectangle( ToRect(aContainingRect) ));
   }
+
+  nsIntRegion& ScaleRoundOut (float aXScale, float aYScale)
+  {
+    mImpl.ScaleRoundOut(aXScale, aYScale);
+    return *this;
+  }
 
   nsIntRegion& ExtendForScaling (float aXMult, float aYMult)
   {
     mImpl.ExtendForScaling(aXMult, aYMult);
     return *this;
   }
 
   /**