diff options
-rw-r--r-- | core/java/android/view/ViewRoot.java | 7 | ||||
-rw-r--r-- | core/jni/android/graphics/Region.cpp | 41 | ||||
-rw-r--r-- | graphics/java/android/graphics/Region.java | 33 |
3 files changed, 75 insertions, 6 deletions
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 @@ public final class ViewRoot extends Handler implements ViewParent, 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 @@ static void Region_translate(JNIEnv* env, jobject region, int x, int y, jobject 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_writeToParcel(JNIEnv* env, jobject clazz, const SkRegion* //////////////////////////////////////////////////////////////////////////////////////////////////////////// +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 @@ static JNINativeMethod gRegionMethods[] = { { "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 class Region implements Parcelable { */ 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 @@ public class Region implements Parcelable { 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 @@ public class Region implements Parcelable { 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; } |