Merge change 1057 into donut

* changes:
  * Add regoin scaling for transparent support
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 819bc31..576d432 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -960,11 +960,10 @@
                         mTmpLocation[1] + host.mBottom - host.mTop);
 
                 host.gatherTransparentRegion(mTransparentRegion);
+                if (mAppScale != 1.0f) {
+                    mTransparentRegion.scale(mAppScale);
+                }
 
-                // TODO: scale the region, like:
-                // Region uses native methods. We probabl should have ScalableRegion class.
-
-                // Region does not have equals method ?
                 if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
                     mPreviousTransparentRegion.set(mTransparentRegion);
                     // reconfigure window manager
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index 00d6cd9..1dc0314 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -102,6 +102,36 @@
         rgn->translate(x, y);
 }
 
+// Scale the rectangle by given scale and set the reuslt to the dst.
+static void scale_rect(SkIRect* dst, const SkIRect& src, float scale) {
+   dst->fLeft = (int)::roundf(src.fLeft * scale);
+   dst->fTop = (int)::roundf(src.fTop * scale);
+   dst->fRight = (int)::roundf(src.fRight * scale);
+   dst->fBottom = (int)::roundf(src.fBottom * scale);
+}
+
+// Scale the region by given scale and set the reuslt to the dst.
+// dest and src can be the same region instance.
+static void scale_rgn(SkRegion* dst, const SkRegion& src, float scale) {
+   SkRegion tmp;
+   SkRegion::Iterator iter(src);
+
+   for (; !iter.done(); iter.next()) {
+       SkIRect r;
+       scale_rect(&r, iter.rect(), scale);
+       tmp.op(r, SkRegion::kUnion_Op);
+   }
+   dst->swap(tmp);
+}
+
+static void Region_scale(JNIEnv* env, jobject region, jfloat scale, jobject dst) {
+    SkRegion* rgn = GetSkRegion(env, region);
+    if (dst)
+        scale_rgn(GetSkRegion(env, dst), *rgn, scale);
+    else
+        scale_rgn(rgn, *rgn, scale);
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 #include "Parcel.h"
@@ -139,6 +169,13 @@
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+static jboolean Region_equals(JNIEnv* env, jobject clazz, const SkRegion *r1, const SkRegion* r2)
+{
+  return (jboolean) (*r1 == *r2);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 struct RgnIterPair {
     SkRegion            fRgn;   // a copy of the caller's region
     SkRegion::Iterator  fIter;  // an iterator acting upon the copy (fRgn)
@@ -206,10 +243,12 @@
     { "quickContains",          "(IIII)Z",                          (void*)Region_quickContains     },
     { "quickReject",            "(IIII)Z",                          (void*)Region_quickRejectIIII   },
     { "quickReject",            "(Landroid/graphics/Region;)Z",     (void*)Region_quickRejectRgn    },
+    { "scale",                  "(FLandroid/graphics/Region;)V",    (void*)Region_scale             },
     { "translate",              "(IILandroid/graphics/Region;)V",   (void*)Region_translate         },
     // parceling methods
     { "nativeCreateFromParcel", "(Landroid/os/Parcel;)I",           (void*)Region_createFromParcel  },
-    { "nativeWriteToParcel",    "(ILandroid/os/Parcel;)Z",          (void*)Region_writeToParcel     }
+    { "nativeWriteToParcel",    "(ILandroid/os/Parcel;)Z",          (void*)Region_writeToParcel     },
+    { "nativeEquals",           "(II)Z",                            (void*)Region_equals            },
 };
 
 int register_android_graphics_Region(JNIEnv* env);
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index 544ff4f..2b080aa 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -211,6 +211,26 @@
      */
     public native void translate(int dx, int dy, Region dst);
 
+    /**
+     * Scale the region by the given scale amount. This re-constructs new region by
+     * scaling the rects that this region consists of. New rectis are computed by scaling 
+     * coordinates by float, then rounded by roundf() function to integers. This may results
+     * in less internal rects if 0 < scale < 1. Zero and Negative scale result in
+     * an empty region. If this region is empty, do nothing.
+     *
+     * @hide
+     */
+    public void scale(float scale) {
+        scale(scale, null);
+    }
+
+    /**
+     * Set the dst region to the result of scaling this region by the given scale amount.
+     * If this region is empty, then dst will be set to empty.
+     * @hide
+     */
+    public native void scale(float scale, Region dst);
+
     public final boolean union(Rect r) {
         return op(r, Op.UNION);
     }
@@ -294,7 +314,16 @@
             throw new RuntimeException();
         }
     }
-    
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof Region)) {
+            return false;
+        }
+        Region peer = (Region) obj;
+        return nativeEquals(mNativeRegion, peer.mNativeRegion);
+    }
+
     protected void finalize() throws Throwable {
         nativeDestructor(mNativeRegion);
     }
@@ -340,5 +369,7 @@
     private static native boolean nativeWriteToParcel(int native_region,
                                                       Parcel p);
 
+    private static native boolean nativeEquals(int native_r1, int native_r2);
+
     private final int mNativeRegion;
 }