From 84ce64f2c0255c25d8e697473b3c026d62cbe74d Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Wed, 16 Jan 2013 17:47:54 +0900 Subject: [PATCH] Fix bounding rectangle of gesture preview trail Bug: 7917443 Bug: 7987585 Change-Id: I99e6db1fe43d3a9b497e92330a6857e0454c428c --- .../internal/GesturePreviewTrail.java | 22 +++++------ .../keyboard/internal/PreviewPlacerView.java | 38 +++++++------------ .../keyboard/internal/RoundedLine.java | 7 ++++ 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java index a8407254f..4a8407cb5 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java @@ -138,6 +138,7 @@ final class GesturePreviewTrail { } private final RoundedLine mRoundedLine = new RoundedLine(); + private final Rect mRoundedLineBounds = new Rect(); /** * Draw gesture preview trail @@ -149,6 +150,8 @@ final class GesturePreviewTrail { */ public boolean drawGestureTrail(final Canvas canvas, final Paint paint, final Rect outBoundsRect, final Params params) { + // Initialize bounds rectangle. + outBoundsRect.setEmpty(); final int trailSize = mEventTimes.getLength(); if (trailSize == 0) { return false; @@ -171,39 +174,32 @@ final class GesturePreviewTrail { if (startIndex < trailSize) { paint.setColor(params.mTrailColor); paint.setStyle(Paint.Style.FILL); - final RoundedLine line = mRoundedLine; + final RoundedLine roundedLine = mRoundedLine; int p1x = getXCoordValue(xCoords[startIndex]); int p1y = yCoords[startIndex]; final int lastTime = sinceDown - eventTimes[startIndex]; - float maxWidth = getWidth(lastTime, params); - float r1 = maxWidth / 2.0f; - // Initialize bounds rectangle. - outBoundsRect.set(p1x, p1y, p1x, p1y); + float r1 = getWidth(lastTime, params) / 2.0f; for (int i = startIndex + 1; i < trailSize; i++) { final int elapsedTime = sinceDown - eventTimes[i]; final int p2x = getXCoordValue(xCoords[i]); final int p2y = yCoords[i]; - final float width = getWidth(elapsedTime, params); - final float r2 = width / 2.0f; + final float r2 = getWidth(elapsedTime, params) / 2.0f; // Draw trail line only when the current point isn't a down point. if (!isDownEventXCoord(xCoords[i])) { - final Path path = line.makePath(p1x, p1y, r1, p2x, p2y, r2); + final Path path = roundedLine.makePath(p1x, p1y, r1, p2x, p2y, r2); if (path != null) { final int alpha = getAlpha(elapsedTime, params); paint.setAlpha(alpha); canvas.drawPath(path, paint); // Take union for the bounds. - outBoundsRect.union(p2x, p2y); - maxWidth = Math.max(maxWidth, width); + roundedLine.getBounds(mRoundedLineBounds); + outBoundsRect.union(mRoundedLineBounds); } } p1x = p2x; p1y = p2y; r1 = r2; } - // Take care of trail line width. - final int inset = -((int)maxWidth + 1); - outBoundsRect.inset(inset, inset); } final int newSize = trailSize - startIndex; diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java index bfb7b1fe0..7c87467bb 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java @@ -52,7 +52,8 @@ public final class PreviewPlacerView extends RelativeLayout { private int mOffscreenOffsetY; private Bitmap mOffscreenBuffer; private final Canvas mOffscreenCanvas = new Canvas(); - private final Rect mOffscreenDirtyRect = new Rect(); + private final Rect mOffscreenSrcRect = new Rect(); + private final Rect mDirtyRect = new Rect(); private final Rect mGesturePreviewTrailBoundsRect = new Rect(); // per trail private final GestureFloatingPreviewText mGestureFloatingPreviewText; private boolean mShowSlidingKeyInputPreview; @@ -193,6 +194,7 @@ public final class PreviewPlacerView extends RelativeLayout { mOffscreenBuffer = Bitmap.createBitmap( mOffscreenWidth, mOffscreenHeight, Bitmap.Config.ARGB_8888); mOffscreenCanvas.setBitmap(mOffscreenBuffer); + mOffscreenCanvas.translate(0, mOffscreenOffsetY); } @Override @@ -205,19 +207,18 @@ public final class PreviewPlacerView extends RelativeLayout { mayAllocateOffscreenBuffer(); // Draw gesture trails to offscreen buffer. final boolean needsUpdatingGesturePreviewTrail = drawGestureTrails( - mOffscreenCanvas, mGesturePaint, mOffscreenDirtyRect); - // Transfer offscreen buffer to screen. - if (!mOffscreenDirtyRect.isEmpty()) { - canvas.translate(0, - mOffscreenOffsetY); - canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect, - mGesturePaint); - canvas.translate(0, mOffscreenOffsetY); - // Note: Defer clearing the dirty rectangle here because we will get cleared - // rectangle on the canvas. - } + mOffscreenCanvas, mGesturePaint, mDirtyRect); if (needsUpdatingGesturePreviewTrail) { mDrawingHandler.postUpdateGestureTrailPreview(); } + // Transfer offscreen buffer to screen. + if (!mDirtyRect.isEmpty()) { + mOffscreenSrcRect.set(mDirtyRect); + mOffscreenSrcRect.offset(0, mOffscreenOffsetY); + canvas.drawBitmap(mOffscreenBuffer, mOffscreenSrcRect, mDirtyRect, null); + // Note: Defer clearing the dirty rectangle here because we will get cleared + // rectangle on the canvas. + } } mGestureFloatingPreviewText.onDraw(canvas); if (mShowSlidingKeyInputPreview) { @@ -235,10 +236,8 @@ public final class PreviewPlacerView extends RelativeLayout { offscreenCanvas.drawRect(dirtyRect, paint); } dirtyRect.setEmpty(); - - // Draw gesture trails to offscreen buffer. - offscreenCanvas.translate(0, mOffscreenOffsetY); boolean needsUpdatingGesturePreviewTrail = false; + // Draw gesture trails to offscreen buffer. synchronized (mGesturePreviewTrails) { // Trails count == fingers count that have ever been active. final int trailsCount = mGesturePreviewTrails.size(); @@ -251,20 +250,9 @@ public final class PreviewPlacerView extends RelativeLayout { dirtyRect.union(mGesturePreviewTrailBoundsRect); } } - offscreenCanvas.translate(0, -mOffscreenOffsetY); - - // Clip dirty rectangle with offscreen buffer width/height. - dirtyRect.offset(0, mOffscreenOffsetY); - clipRect(dirtyRect, 0, 0, mOffscreenWidth, mOffscreenHeight); return needsUpdatingGesturePreviewTrail; } - private static void clipRect(final Rect out, final int left, final int top, final int right, - final int bottom) { - out.set(Math.max(out.left, left), Math.max(out.top, top), Math.min(out.right, right), - Math.min(out.bottom, bottom)); - } - public void setGestureFloatingPreviewText(final SuggestedWords suggestedWords) { if (!mGestureFloatingPreviewText.isPreviewEnabled()) return; mGestureFloatingPreviewText.setSuggetedWords(suggestedWords); diff --git a/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java b/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java index 1f5252077..cd6efc4b7 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java +++ b/java/src/com/android/inputmethod/keyboard/internal/RoundedLine.java @@ -15,6 +15,7 @@ package com.android.inputmethod.keyboard.internal; import android.graphics.Path; +import android.graphics.Rect; import android.graphics.RectF; public final class RoundedLine { @@ -100,4 +101,10 @@ public final class RoundedLine { mPath.close(); return mPath; } + + public void getBounds(final Rect outBounds) { + // Reuse mArc1 as working variable + mPath.computeBounds(mArc1, true /* unused */); + mArc1.roundOut(outBounds); + } }