summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/Surface.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/view/Surface.java')
-rw-r--r--core/java/android/view/Surface.java78
1 files changed, 65 insertions, 13 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);
+ }
}
/**