diff options
Diffstat (limited to 'com/android/internal/widget/Magnifier.java')
-rw-r--r-- | com/android/internal/widget/Magnifier.java | 132 |
1 files changed, 24 insertions, 108 deletions
diff --git a/com/android/internal/widget/Magnifier.java b/com/android/internal/widget/Magnifier.java index 9bc0778d..86e7b38a 100644 --- a/com/android/internal/widget/Magnifier.java +++ b/com/android/internal/widget/Magnifier.java @@ -22,9 +22,7 @@ import android.annotation.UiThread; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Point; -import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Handler; import android.util.Log; import android.view.Gravity; @@ -43,8 +41,6 @@ import com.android.internal.util.Preconditions; */ public final class Magnifier { private static final String LOG_TAG = "magnifier"; - // Use this to specify that a previous configuration value does not exist. - private static final int INEXISTENT_PREVIOUS_CONFIG_VALUE = -1; // The view for which this magnifier is attached. private final View mView; // The window containing the magnifier. @@ -63,15 +59,6 @@ public final class Magnifier { // the copy is finished. private final Handler mPixelCopyHandler = Handler.getMain(); - private RectF mTmpRectF; - - // Variables holding previous states, used for detecting redundant calls and invalidation. - private Point mPrevStartCoordsOnScreen = new Point( - INEXISTENT_PREVIOUS_CONFIG_VALUE, INEXISTENT_PREVIOUS_CONFIG_VALUE); - private PointF mPrevCenterCoordsOnScreen = new PointF( - INEXISTENT_PREVIOUS_CONFIG_VALUE, INEXISTENT_PREVIOUS_CONFIG_VALUE); - private float mPrevScale = INEXISTENT_PREVIOUS_CONFIG_VALUE; - /** * Initializes a magnifier. * @@ -101,45 +88,16 @@ public final class Magnifier { /** * Shows the magnifier on the screen. * - * @param centerXOnScreen horizontal coordinate of the center point of the magnifier source. The - * lower end is clamped to 0 - * @param centerYOnScreen vertical coordinate of the center point of the magnifier source. The - * lower end is clamped to 0 - * @param scale the scale at which the magnifier zooms on the source content. The - * lower end is clamped to 1 and the higher end to 4 + * @param centerXOnScreen horizontal coordinate of the center point of the magnifier source + * @param centerYOnScreen vertical coordinate of the center point of the magnifier source + * @param scale the scale at which the magnifier zooms on the source content */ public void show(@FloatRange(from=0) float centerXOnScreen, @FloatRange(from=0) float centerYOnScreen, - @FloatRange(from=1, to=4) float scale) { - if (scale > 4) { - scale = 4; - } - - if (scale < 1) { - scale = 1; - } - - if (centerXOnScreen < 0) { - centerXOnScreen = 0; - } - - if (centerYOnScreen < 0) { - centerYOnScreen = 0; - } - - showInternal(centerXOnScreen, centerYOnScreen, scale, false); - } - - private void showInternal(@FloatRange(from=0) float centerXOnScreen, - @FloatRange(from=0) float centerYOnScreen, - @FloatRange(from=1, to=4) float scale, - boolean forceShow) { - if (mPrevScale != scale) { - resizeBitmap(scale); - mPrevScale = scale; - } + @FloatRange(from=1, to=10) float scale) { + maybeResizeBitmap(scale); configureCoordinates(centerXOnScreen, centerYOnScreen); - maybePerformPixelCopy(scale, forceShow); + performPixelCopy(); if (mWindow.isShowing()) { mWindow.update(mWindowCoords.x, mWindowCoords.y, mWindow.getWidth(), @@ -148,9 +106,6 @@ public final class Magnifier { mWindow.showAtLocation(mView.getRootView(), Gravity.NO_GRAVITY, mWindowCoords.x, mWindowCoords.y); } - - mPrevCenterCoordsOnScreen.x = centerXOnScreen; - mPrevCenterCoordsOnScreen.y = centerYOnScreen; } /** @@ -158,38 +113,6 @@ public final class Magnifier { */ public void dismiss() { mWindow.dismiss(); - - mPrevStartCoordsOnScreen.x = INEXISTENT_PREVIOUS_CONFIG_VALUE; - mPrevStartCoordsOnScreen.y = INEXISTENT_PREVIOUS_CONFIG_VALUE; - mPrevCenterCoordsOnScreen.x = INEXISTENT_PREVIOUS_CONFIG_VALUE; - mPrevCenterCoordsOnScreen.y = INEXISTENT_PREVIOUS_CONFIG_VALUE; - mPrevScale = INEXISTENT_PREVIOUS_CONFIG_VALUE; - } - - /** - * Forces the magnifier to update content by taking and showing a new snapshot using the - * previous coordinates. It does this only if the magnifier is showing and the dirty rectangle - * intersects the rectangle which holds the content to be magnified. - * - * @param dirtyRectOnScreen the rectangle representing the screen bounds of the dirty region - */ - public void invalidate(RectF dirtyRectOnScreen) { - if (mWindow.isShowing() && mPrevCenterCoordsOnScreen.x != INEXISTENT_PREVIOUS_CONFIG_VALUE - && mPrevCenterCoordsOnScreen.y != INEXISTENT_PREVIOUS_CONFIG_VALUE - && mPrevScale != INEXISTENT_PREVIOUS_CONFIG_VALUE) { - // Update the current showing RectF. - mTmpRectF = new RectF(mPrevStartCoordsOnScreen.x, - mPrevStartCoordsOnScreen.y, - mPrevStartCoordsOnScreen.x + mBitmap.getWidth(), - mPrevStartCoordsOnScreen.y + mBitmap.getHeight()); - - // Update only if we are currently showing content that has been declared as invalid. - if (RectF.intersects(dirtyRectOnScreen, mTmpRectF)) { - // Update the contents shown in the magnifier. - showInternal(mPrevCenterCoordsOnScreen.x, mPrevCenterCoordsOnScreen.y, mPrevScale, - true /* forceShow */); - } - } } /** @@ -206,11 +129,13 @@ public final class Magnifier { return mWindowWidth; } - private void resizeBitmap(float scale) { + private void maybeResizeBitmap(float scale) { final int bitmapWidth = (int) (mWindowWidth / scale); final int bitmapHeight = (int) (mWindowHeight / scale); - mBitmap.reconfigure(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); - getImageView().setImageBitmap(mBitmap); + if (mBitmap.getWidth() != bitmapWidth || mBitmap.getHeight() != bitmapHeight) { + mBitmap.reconfigure(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); + getImageView().setImageBitmap(mBitmap); + } } private void configureCoordinates(float posXOnScreen, float posYOnScreen) { @@ -219,29 +144,24 @@ public final class Magnifier { final int verticalMagnifierOffset = mView.getContext().getResources().getDimensionPixelSize( R.dimen.magnifier_offset); + final int availableTopSpace = (mCenterZoomCoords.y - mWindowHeight / 2) + - verticalMagnifierOffset - (mBitmap.getHeight() / 2); + mWindowCoords.x = mCenterZoomCoords.x - mWindowWidth / 2; - mWindowCoords.y = mCenterZoomCoords.y - mWindowHeight / 2 - verticalMagnifierOffset; + mWindowCoords.y = mCenterZoomCoords.y - mWindowHeight / 2 + + verticalMagnifierOffset * (availableTopSpace > 0 ? -1 : 1); } - private void maybePerformPixelCopy(final float scale, final boolean forceShow) { - final int startY = mCenterZoomCoords.y - mBitmap.getHeight() / 2; - int rawStartX = mCenterZoomCoords.x - mBitmap.getWidth() / 2; - + private void performPixelCopy() { + int startX = mCenterZoomCoords.x - mBitmap.getWidth() / 2; // Clamp startX value to avoid distorting the rendering of the magnifier content. - if (rawStartX < 0) { - rawStartX = 0; - } else if (rawStartX + mBitmap.getWidth() > mView.getWidth()) { - rawStartX = mView.getWidth() - mBitmap.getWidth(); + if (startX < 0) { + startX = 0; + } else if (startX + mBitmap.getWidth() > mView.getWidth()) { + startX = mView.getWidth() - mBitmap.getWidth(); } - if (!forceShow && rawStartX == mPrevStartCoordsOnScreen.x - && startY == mPrevStartCoordsOnScreen.y - && scale == mPrevScale) { - // Skip, we are already showing the desired content. - return; - } - - final int startX = rawStartX; + final int startY = mCenterZoomCoords.y - mBitmap.getHeight() / 2; final ViewRootImpl viewRootImpl = mView.getViewRootImpl(); if (viewRootImpl != null && viewRootImpl.mSurface != null @@ -251,11 +171,7 @@ public final class Magnifier { new Rect(startX, startY, startX + mBitmap.getWidth(), startY + mBitmap.getHeight()), mBitmap, - result -> { - getImageView().invalidate(); - mPrevStartCoordsOnScreen.x = startX; - mPrevStartCoordsOnScreen.y = startY; - }, + result -> getImageView().invalidate(), mPixelCopyHandler); } else { Log.d(LOG_TAG, "Could not perform PixelCopy request"); |