diff options
author | Mitsuru Oshima <oshima@google.com> | 2009-07-22 20:39:14 -0700 |
---|---|---|
committer | Mitsuru Oshima <oshima@google.com> | 2009-07-23 13:31:00 -0700 |
commit | 240f8a7532a024e36998bdbe87cff2ef080d75de (patch) | |
tree | ffdc992eb95a2ccab062770fbf4ce320016e7435 /core | |
parent | de08cdc0a56ab8d48a226dadef02740520c274b7 (diff) | |
download | frameworks_base-240f8a7532a024e36998bdbe87cff2ef080d75de.zip frameworks_base-240f8a7532a024e36998bdbe87cff2ef080d75de.tar.gz frameworks_base-240f8a7532a024e36998bdbe87cff2ef080d75de.tar.bz2 |
* a best effort fix for apps that uses get/set Matrix API on canvas.
- scale the matrix
- but don't scale if the matrix *looks* like obtained from the canvas itself. (typically to set it back to original matrix)
This is best effort change and not perfect (not even close), but works for one game,
and hopes it can handle many other apps that uses set/get Matrix. If you have an alternative idea, please let me know.
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/Surface.java | 78 | ||||
-rw-r--r-- | core/java/android/view/SurfaceView.java | 2 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 3 |
3 files changed, 68 insertions, 15 deletions
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 83c30e1..4bc929b 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -16,6 +16,7 @@ package android.view; +import android.content.res.CompatibilityInfo.Translator; import android.graphics.*; import android.os.Parcelable; import android.os.Parcel; @@ -133,8 +134,12 @@ public class Surface implements Parcelable { private Canvas mCanvas; // The display metrics used to provide the pseudo canvas size for applications - // running in compatibility mode. This is set to null for regular mode. - private DisplayMetrics mDisplayMetrics; + // running in compatibility mode. This is set to null for non compatibility mode. + private DisplayMetrics mCompatibleDisplayMetrics; + + // A matrix to scale the matrix set by application. This is set to null for + // non compatibility mode. + private Matrix mCompatibleMatrix; /** * Exception thrown when a surface couldn't be created or resized @@ -172,23 +177,70 @@ public class Surface implements Parcelable { * {@hide} */ public Surface() { - mCanvas = new Canvas() { - @Override - public int getWidth() { - return mDisplayMetrics == null ? super.getWidth() : mDisplayMetrics.widthPixels; + mCanvas = new CompatibleCanvas(); + } + + /** + * A Canvas class that can handle the compatibility mode. This does two things differently. + * <ul> + * <li> Returns the width and height of the target metrics, rather than native. + * For example, the canvas returns 320x480 even if an app is running in WVGA high density. + * <li> Scales the matrix in setMatrix by the application scale, except if the matrix looks + * like obtained from getMatrix. This is a hack to handle the case that an application + * uses getMatrix to keep the original matrix, set matrix of its own, then set the original + * matrix back. There is no perfect solution that works for all cases, and there are a lot of + * cases that this model dose not work, but we hope this works for many apps. + * </ul> + */ + private class CompatibleCanvas extends Canvas { + // A temp matrix to remember what an application obtained via {@link getMatrix} + private Matrix mOrigMatrix = null; + + @Override + public int getWidth() { + return mCompatibleDisplayMetrics == null ? + super.getWidth() : mCompatibleDisplayMetrics.widthPixels; + } + + @Override + public int getHeight() { + return mCompatibleDisplayMetrics == null ? + super.getHeight() : mCompatibleDisplayMetrics.heightPixels; + } + + @Override + public void setMatrix(Matrix matrix) { + if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) { + // don't scale the matrix if it's not compatibility mode, or + // the matrix was obtained from getMatrix. + super.setMatrix(matrix); + } else { + Matrix m = new Matrix(mCompatibleMatrix); + m.preConcat(matrix); + super.setMatrix(m); } - @Override - public int getHeight() { - return mDisplayMetrics == null ? super.getHeight() : mDisplayMetrics.heightPixels; + } + + @Override + public void getMatrix(Matrix m) { + super.getMatrix(m); + if (mOrigMatrix == null) { + mOrigMatrix = new Matrix(); } - }; - } + mOrigMatrix.set(m); + } + }; /** * Sets the display metrics used to provide canva's width/height in comaptibility mode. */ - void setCompatibleDisplayMetrics(DisplayMetrics metrics) { - mDisplayMetrics = metrics; + void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) { + mCompatibleDisplayMetrics = metrics; + if (translator != null) { + float appScale = translator.applicationScale; + mCompatibleMatrix = new Matrix(); + mCompatibleMatrix.setScale(appScale, appScale); + } } /** diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index c73d29e..938104c 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -312,7 +312,7 @@ public class SurfaceView extends View { Resources res = getContext().getResources(); if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) { - mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics()); + mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator); } int myWidth = mRequestedWidth; diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 2f92b32..c6c3324 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -392,7 +392,8 @@ public final class ViewRoot extends Handler implements ViewParent, mTranslator = compatibilityInfo.getTranslator(attrs); if (mTranslator != null || !compatibilityInfo.supportsScreen()) { - mSurface.setCompatibleDisplayMetrics(resources.getDisplayMetrics()); + mSurface.setCompatibleDisplayMetrics(resources.getDisplayMetrics(), + mTranslator); } boolean restore = false; |