OSDN Git Service

[Magnifier-48] Allow on-the-fly zoom update
authorMihai Popa <popam@google.com>
Thu, 19 Jul 2018 14:50:43 +0000 (15:50 +0100)
committerMihai Popa <popam@google.com>
Wed, 29 Aug 2018 10:16:26 +0000 (11:16 +0100)
The CL adds Magnifier#setZoom(float), which allows dynamically changing
the initial zoom applied to the content that will be magnified and
displayed in the magnifier.

Bug: 72211470
Test: manual testing
Test: atest CtsWidgetTestCases:android.widget.cts.MagnifierTest
Change-Id: I1dd01085ef5a1589a3602aefd03223d1451564f5

api/current.txt
api/test-current.txt
core/java/android/widget/Magnifier.java

index cc4e36f..c07ea98 100644 (file)
@@ -52977,6 +52977,7 @@ package android.widget {
     method public int getSourceWidth();
     method public int getWidth();
     method public float getZoom();
+    method public void setZoom(float);
     method public void show(float, float);
     method public void show(float, float, float, float);
     method public void update();
index bb3cb1f..b8cee4b 100644 (file)
@@ -1545,6 +1545,7 @@ package android.widget {
   public final class Magnifier {
     method public android.graphics.Bitmap getContent();
     method public static android.graphics.PointF getMagnifierDefaultSize();
+    method public android.graphics.Bitmap getOriginalContent();
     method public void setOnOperationCompleteCallback(android.widget.Magnifier.Callback);
   }
 
index f82b17f..3280d47 100644 (file)
@@ -77,11 +77,13 @@ public final class Magnifier {
     // The height of the window containing the magnifier.
     private final int mWindowHeight;
     // The zoom applied to the view region copied to the magnifier view.
-    private final float mZoom;
+    private float mZoom;
     // The width of the content that will be copied to the magnifier.
-    private final int mSourceWidth;
+    private int mSourceWidth;
     // The height of the content that will be copied to the magnifier.
-    private final int mSourceHeight;
+    private int mSourceHeight;
+    // Whether the zoom of the magnifier has changed since last content copy.
+    private boolean mDirtyZoom;
     // The elevation of the window containing the magnifier.
     private final float mWindowElevation;
     // The corner radius of the window containing the magnifier.
@@ -196,7 +198,8 @@ public final class Magnifier {
 
         final int startX = mClampedCenterZoomCoords.x - mSourceWidth / 2;
         final int startY = mClampedCenterZoomCoords.y - mSourceHeight / 2;
-        if (sourceCenterX != mPrevShowSourceCoords.x || sourceCenterY != mPrevShowSourceCoords.y) {
+        if (sourceCenterX != mPrevShowSourceCoords.x || sourceCenterY != mPrevShowSourceCoords.y
+                || mDirtyZoom) {
             if (mWindow == null) {
                 synchronized (mLock) {
                     mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
@@ -253,9 +256,16 @@ public final class Magnifier {
     public void update() {
         if (mWindow != null) {
             obtainSurfaces();
-            // Update the content shown in the magnifier.
-            performPixelCopy(mPrevStartCoordsInSurface.x, mPrevStartCoordsInSurface.y,
-                    false /* update window position */);
+            if (!mDirtyZoom) {
+                // Update the content shown in the magnifier.
+                performPixelCopy(mPrevStartCoordsInSurface.x, mPrevStartCoordsInSurface.y,
+                        false /* update window position */);
+            } else {
+                // If the zoom has changed, we cannot use the same top left coordinates
+                // as before, so just #show again to have them recomputed.
+                show(mPrevShowSourceCoords.x, mPrevShowSourceCoords.y,
+                        mPrevShowWindowCoords.x, mPrevShowWindowCoords.y);
+            }
         }
     }
 
@@ -298,6 +308,18 @@ public final class Magnifier {
     }
 
     /**
+     * Sets the zoom to be applied to the chosen content before being copied to the magnifier popup.
+     * @param zoom the zoom to be set
+     */
+    public void setZoom(@FloatRange(from = 0f) float zoom) {
+        Preconditions.checkArgumentPositive(zoom, "Zoom should be positive");
+        mZoom = zoom;
+        mSourceWidth = Math.round(mWindowWidth / mZoom);
+        mSourceHeight = Math.round(mWindowHeight / mZoom);
+        mDirtyZoom = true;
+    }
+
+    /**
      * Returns the zoom to be applied to the magnified view region copied to the magnifier.
      * If the zoom is x and the magnifier window size is (width, height), the original size
      * of the content being magnified will be (width / x, height / x).
@@ -534,6 +556,7 @@ public final class Magnifier {
                 sPixelCopyHandlerThread.getThreadHandler());
         mPrevStartCoordsInSurface.x = startXInSurface;
         mPrevStartCoordsInSurface.y = startYInSurface;
+        mDirtyZoom = false;
     }
 
     /**
@@ -1020,6 +1043,21 @@ public final class Magnifier {
     }
 
     /**
+     * @return the content to be magnified, as bitmap
+     *
+     * @hide
+     */
+    @TestApi
+    public @Nullable Bitmap getOriginalContent() {
+        if (mWindow == null) {
+            return null;
+        }
+        synchronized (mWindow.mLock) {
+            return Bitmap.createBitmap(mWindow.mBitmap);
+        }
+    }
+
+    /**
      * @return the size of the magnifier window in dp
      *
      * @hide