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 id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjoe, blocking2.0
bugs586683
milestone2.0b12pre
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;
   }
 
   /**