diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index e60139704..7e8c77e13 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -90,7 +90,8 @@
-
+
+
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 9ccaaaf4e..d92a71560 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -100,7 +100,8 @@
36%
- 2.5dp
+ 18.0dp
+ 2.5dp
24dp
73dp
diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml
index 94fdbeb53..ed92440ef 100644
--- a/java/res/values/styles.xml
+++ b/java/res/values/styles.xml
@@ -77,7 +77,8 @@
- @integer/config_gesture_preview_trail_fadeout_duration
- @integer/config_gesture_preview_trail_update_interval
- @android:color/holo_blue_light
- - @dimen/gesture_preview_trail_width
+ - @dimen/gesture_preview_trail_start_width
+ - @dimen/gesture_preview_trail_end_width
- @dimen/config_key_hysteresis_distance
- @integer/config_touch_noise_threshold_time
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
index e814d8009..7442b7fad 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
@@ -17,16 +17,18 @@ package com.android.inputmethod.keyboard.internal;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Xfermode;
import android.os.SystemClock;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.ResizableIntArray;
-class GesturePreviewTrail {
+final class GesturePreviewTrail {
private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewTrail.PREVIEW_CAPACITY;
- private final GesturePreviewTrailParams mPreviewParams;
private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY);
@@ -34,28 +36,39 @@ class GesturePreviewTrail {
private long mCurrentDownTime;
private int mTrailStartIndex;
+ private final static Xfermode PORTER_DUFF_MODE_SRC =
+ new PorterDuffXfermode(PorterDuff.Mode.SRC);
+
// Use this value as imaginary zero because x-coordinates may be zero.
private static final int DOWN_EVENT_MARKER = -128;
- static class GesturePreviewTrailParams {
+ static final class Params {
+ public final int mTrailColor;
+ public final float mTrailStartWidth;
+ public final float mTrailEndWidth;
public final int mFadeoutStartDelay;
public final int mFadeoutDuration;
public final int mUpdateInterval;
- public GesturePreviewTrailParams(final TypedArray keyboardViewAttr) {
+ public final int mTrailLingerDuration;
+
+ public Params(final TypedArray keyboardViewAttr) {
+ mTrailColor = keyboardViewAttr.getColor(
+ R.styleable.KeyboardView_gesturePreviewTrailColor, 0);
+ mTrailStartWidth = keyboardViewAttr.getDimension(
+ R.styleable.KeyboardView_gesturePreviewTrailStartWidth, 0.0f);
+ mTrailEndWidth = keyboardViewAttr.getDimension(
+ R.styleable.KeyboardView_gesturePreviewTrailEndWidth, 0.0f);
mFadeoutStartDelay = keyboardViewAttr.getInt(
R.styleable.KeyboardView_gesturePreviewTrailFadeoutStartDelay, 0);
mFadeoutDuration = keyboardViewAttr.getInt(
R.styleable.KeyboardView_gesturePreviewTrailFadeoutDuration, 0);
+ mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration;
mUpdateInterval = keyboardViewAttr.getInt(
R.styleable.KeyboardView_gesturePreviewTrailUpdateInterval, 0);
}
}
- public GesturePreviewTrail(final GesturePreviewTrailParams params) {
- mPreviewParams = params;
- }
-
private static int markAsDownEvent(final int xCoord) {
return DOWN_EVENT_MARKER - xCoord;
}
@@ -94,23 +107,30 @@ class GesturePreviewTrail {
}
}
- private int getAlpha(final int elapsedTime) {
- if (elapsedTime < mPreviewParams.mFadeoutStartDelay) {
+ private static int getAlpha(final int elapsedTime, final Params params) {
+ if (elapsedTime < params.mFadeoutStartDelay) {
return Constants.Color.ALPHA_OPAQUE;
}
final int decreasingAlpha = Constants.Color.ALPHA_OPAQUE
- * (elapsedTime - mPreviewParams.mFadeoutStartDelay)
- / mPreviewParams.mFadeoutDuration;
+ * (elapsedTime - params.mFadeoutStartDelay)
+ / params.mFadeoutDuration;
return Constants.Color.ALPHA_OPAQUE - decreasingAlpha;
}
+ private static float getWidth(final int elapsedTime, final Params params) {
+ return Math.max((params.mTrailLingerDuration - elapsedTime)
+ * (params.mTrailStartWidth - params.mTrailEndWidth)
+ / params.mTrailLingerDuration, 0.0f);
+ }
+
/**
* Draw gesture preview trail
* @param canvas The canvas to draw the gesture preview trail
* @param paint The paint object to be used to draw the gesture preview trail
+ * @param params The drawing parameters of gesture preview trail
* @return true if some gesture preview trails remain to be drawn
*/
- public boolean drawGestureTrail(final Canvas canvas, final Paint paint) {
+ public boolean drawGestureTrail(final Canvas canvas, final Paint paint, final Params params) {
final int trailSize = mEventTimes.getLength();
if (trailSize == 0) {
return false;
@@ -120,13 +140,11 @@ class GesturePreviewTrail {
final int[] xCoords = mXCoordinates.getPrimitiveArray();
final int[] yCoords = mYCoordinates.getPrimitiveArray();
final int sinceDown = (int)(SystemClock.uptimeMillis() - mCurrentDownTime);
- final int lingeringDuration = mPreviewParams.mFadeoutStartDelay
- + mPreviewParams.mFadeoutDuration;
int startIndex;
for (startIndex = mTrailStartIndex; startIndex < trailSize; startIndex++) {
final int elapsedTime = sinceDown - eventTimes[startIndex];
// Skip too old trail points.
- if (elapsedTime < lingeringDuration) {
+ if (elapsedTime < params.mTrailLingerDuration) {
break;
}
}
@@ -135,13 +153,20 @@ class GesturePreviewTrail {
if (startIndex < trailSize) {
int lastX = getXCoordValue(xCoords[startIndex]);
int lastY = yCoords[startIndex];
+ paint.setColor(params.mTrailColor);
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeCap(Paint.Cap.ROUND);
+ paint.setXfermode(PORTER_DUFF_MODE_SRC);
for (int i = startIndex + 1; i < trailSize - 1; i++) {
final int x = xCoords[i];
final int y = yCoords[i];
final int elapsedTime = sinceDown - eventTimes[i];
// Draw trail line only when the current point isn't a down point.
if (!isDownEventXCoord(x)) {
- paint.setAlpha(getAlpha(elapsedTime));
+ final int alpha = getAlpha(elapsedTime, params);
+ paint.setAlpha(alpha);
+ final float width = getWidth(elapsedTime, params);
+ paint.setStrokeWidth(width);
canvas.drawLine(lastX, lastY, x, y, paint);
}
lastX = getXCoordValue(x);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
index 641fadf6d..8dde4d671 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
@@ -21,6 +21,8 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Message;
@@ -30,14 +32,12 @@ import android.util.SparseArray;
import android.widget.RelativeLayout;
import com.android.inputmethod.keyboard.PointerTracker;
-import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.GesturePreviewTrailParams;
+import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
public class PreviewPlacerView extends RelativeLayout {
- private final Paint mGesturePaint;
- private final Paint mTextPaint;
private final int mGestureFloatingPreviewTextColor;
private final int mGestureFloatingPreviewTextOffset;
private final int mGestureFloatingPreviewColor;
@@ -51,8 +51,11 @@ public class PreviewPlacerView extends RelativeLayout {
private final SparseArray mGesturePreviewTrails =
CollectionUtils.newSparseArray();
- private final GesturePreviewTrailParams mGesturePreviewTrailParams;
+ private final Params mGesturePreviewTrailParams;
+ private final Paint mGesturePaint;
+ private boolean mDrawsGesturePreviewTrail;
+ private final Paint mTextPaint;
private String mGestureFloatingPreviewText;
private final int mGestureFloatingPreviewTextHeight;
// {@link RectF} is needed for {@link Canvas#drawRoundRect(RectF, float, float, Paint)}.
@@ -60,8 +63,6 @@ public class PreviewPlacerView extends RelativeLayout {
private int mLastPointerX;
private int mLastPointerY;
private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' };
-
- private boolean mDrawsGesturePreviewTrail;
private boolean mDrawsGestureFloatingPreviewText;
private final DrawingHandler mDrawingHandler;
@@ -70,10 +71,10 @@ public class PreviewPlacerView extends RelativeLayout {
private static final int MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 0;
private static final int MSG_UPDATE_GESTURE_PREVIEW_TRAIL = 1;
- private final GesturePreviewTrailParams mGesturePreviewTrailParams;
+ private final Params mGesturePreviewTrailParams;
public DrawingHandler(final PreviewPlacerView outerInstance,
- final GesturePreviewTrailParams gesturePreviewTrailParams) {
+ final Params gesturePreviewTrailParams) {
super(outerInstance);
mGesturePreviewTrailParams = gesturePreviewTrailParams;
}
@@ -146,21 +147,13 @@ public class PreviewPlacerView extends RelativeLayout {
R.styleable.KeyboardView_gestureFloatingPreviewRoundRadius, 0.0f);
mGestureFloatingPreviewTextLingerTimeout = keyboardViewAttr.getInt(
R.styleable.KeyboardView_gestureFloatingPreviewTextLingerTimeout, 0);
- final int gesturePreviewTrailColor = keyboardViewAttr.getColor(
- R.styleable.KeyboardView_gesturePreviewTrailColor, 0);
- final int gesturePreviewTrailWidth = keyboardViewAttr.getDimensionPixelSize(
- R.styleable.KeyboardView_gesturePreviewTrailWidth, 0);
- mGesturePreviewTrailParams = new GesturePreviewTrailParams(keyboardViewAttr);
+ mGesturePreviewTrailParams = new Params(keyboardViewAttr);
keyboardViewAttr.recycle();
mDrawingHandler = new DrawingHandler(this, mGesturePreviewTrailParams);
final Paint gesturePaint = new Paint();
gesturePaint.setAntiAlias(true);
- gesturePaint.setStyle(Paint.Style.STROKE);
- gesturePaint.setStrokeJoin(Paint.Join.ROUND);
- gesturePaint.setColor(gesturePreviewTrailColor);
- gesturePaint.setStrokeWidth(gesturePreviewTrailWidth);
mGesturePaint = gesturePaint;
final Paint textPaint = new Paint();
@@ -172,6 +165,10 @@ public class PreviewPlacerView extends RelativeLayout {
final Rect textRect = new Rect();
textPaint.getTextBounds(TEXT_HEIGHT_REFERENCE_CHAR, 0, 1, textRect);
mGestureFloatingPreviewTextHeight = textRect.height();
+
+ final Paint layerPaint = new Paint();
+ layerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
+ setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
}
public void setOrigin(final int x, final int y) {
@@ -190,7 +187,7 @@ public class PreviewPlacerView extends RelativeLayout {
synchronized (mGesturePreviewTrails) {
trail = mGesturePreviewTrails.get(tracker.mPointerId);
if (trail == null) {
- trail = new GesturePreviewTrail(mGesturePreviewTrailParams);
+ trail = new GesturePreviewTrail();
mGesturePreviewTrails.put(tracker.mPointerId, trail);
}
}
@@ -214,7 +211,8 @@ public class PreviewPlacerView extends RelativeLayout {
for (int index = 0; index < trailsCount; index++) {
final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index);
needsUpdatingGesturePreviewTrail |=
- trail.drawGestureTrail(canvas, mGesturePaint);
+ trail.drawGestureTrail(canvas, mGesturePaint,
+ mGesturePreviewTrailParams);
}
}
if (needsUpdatingGesturePreviewTrail) {