From 240f8a7532a024e36998bdbe87cff2ef080d75de Mon Sep 17 00:00:00 2001 From: Mitsuru Oshima Date: Wed, 22 Jul 2009 20:39:14 -0700 Subject: * 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. --- core/java/android/view/Surface.java | 78 +++++++++++++++++++++++++++------ core/java/android/view/SurfaceView.java | 2 +- core/java/android/view/ViewRoot.java | 3 +- 3 files changed, 68 insertions(+), 15 deletions(-) (limited to 'core') 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. + * + */ + 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; -- cgit v1.1