Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57e95111 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Use offscreen bitmap buffer to draw gesture preview trail" into jb-mr1-dev

parents 8d031a63 9ad4b2a8
Loading
Loading
Loading
Loading
+3 −11
Original line number Diff line number Diff line
@@ -182,7 +182,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
    private final Region mClipRegion = new Region();
    private Bitmap mOffscreenBuffer;
    /** The canvas for the above mutable keyboard bitmap */
    private Canvas mOffscreenCanvas;
    private final Canvas mOffscreenCanvas = new Canvas();
    private final Paint mPaint = new Paint();
    private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
    // This sparse array caches key label text height in pixel indexed by key label text size.
@@ -365,7 +365,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
        if (bufferNeedsUpdates || mOffscreenBuffer == null) {
            if (maybeAllocateOffscreenBuffer()) {
                mInvalidateAllKeys = true;
                maybeCreateOffscreenCanvas();
                // TODO: Stop using the offscreen canvas even when in software rendering
                mOffscreenCanvas.setBitmap(mOffscreenBuffer);
            }
            onDrawKeyboard(mOffscreenCanvas);
        }
@@ -394,15 +395,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
        }
    }

    private void maybeCreateOffscreenCanvas() {
        // TODO: Stop using the offscreen canvas even when in software rendering
        if (mOffscreenCanvas != null) {
            mOffscreenCanvas.setBitmap(mOffscreenBuffer);
        } else {
            mOffscreenCanvas = new Canvas(mOffscreenBuffer);
        }
    }

    private void onDrawKeyboard(final Canvas canvas) {
        if (mKeyboard == null) return;

+15 −10
Original line number Diff line number Diff line
@@ -17,9 +17,7 @@ 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.graphics.Rect;
import android.os.SystemClock;

import com.android.inputmethod.latin.Constants;
@@ -118,17 +116,16 @@ final class GesturePreviewTrail {
                / params.mTrailLingerDuration, 0.0f);
    }

    private final static Xfermode PORTER_DUFF_MODE_SRC =
            new PorterDuffXfermode(PorterDuff.Mode.SRC);

    /**
     * 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 outBoundsRect the bounding box of this gesture trail drawing
     * @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, final Params params) {
    public boolean drawGestureTrail(final Canvas canvas, final Paint paint,
            final Rect outBoundsRect, final Params params) {
        final int trailSize = mEventTimes.getLength();
        if (trailSize == 0) {
            return false;
@@ -149,12 +146,14 @@ final class GesturePreviewTrail {
        mTrailStartIndex = startIndex;

        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);
            int lastX = getXCoordValue(xCoords[startIndex]);
            int lastY = yCoords[startIndex];
            float maxWidth = getWidth(sinceDown - eventTimes[startIndex], params);
            // Initialize bounds rectangle.
            outBoundsRect.set(lastX, lastY, lastX, lastY);
            for (int i = startIndex + 1; i < trailSize - 1; i++) {
                final int x = xCoords[i];
                final int y = yCoords[i];
@@ -166,10 +165,16 @@ final class GesturePreviewTrail {
                    final float width = getWidth(elapsedTime, params);
                    paint.setStrokeWidth(width);
                    canvas.drawLine(lastX, lastY, x, y, paint);
                    // Take union for the bounds.
                    outBoundsRect.union(x, y);
                    maxWidth = Math.max(maxWidth, width);
                }
                lastX = getXCoordValue(x);
                lastY = y;
            }
            // Take care of trail line width.
            final int inset = -((int)maxWidth + 1);
            outBoundsRect.inset(inset, inset);
        }

        final int newSize = trailSize - startIndex;
+37 −3
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ package com.android.inputmethod.keyboard.internal;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.PorterDuff;
@@ -54,6 +56,10 @@ public class PreviewPlacerView extends RelativeLayout {
    private final Params mGesturePreviewTrailParams;
    private final Paint mGesturePaint;
    private boolean mDrawsGesturePreviewTrail;
    private Bitmap mOffscreenBuffer;
    private final Canvas mOffscreenCanvas = new Canvas();
    private final Rect mOffscreenDirtyRect = new Rect();
    private final Rect mGesturePreviewTrailBoundsRect = new Rect(); // per trail

    private final Paint mTextPaint;
    private String mGestureFloatingPreviewText;
@@ -154,6 +160,7 @@ public class PreviewPlacerView extends RelativeLayout {

        final Paint gesturePaint = new Paint();
        gesturePaint.setAntiAlias(true);
        gesturePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
        mGesturePaint = gesturePaint;

        final Paint textPaint = new Paint();
@@ -198,11 +205,31 @@ public class PreviewPlacerView extends RelativeLayout {
        invalidate();
    }

    @Override
    protected void onDetachedFromWindow() {
        if (mOffscreenBuffer != null) {
            mOffscreenBuffer.recycle();
            mOffscreenBuffer = null;
        }
    }

    @Override
    public void onDraw(final Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(mXOrigin, mYOrigin);
        if (mDrawsGesturePreviewTrail) {
            if (mOffscreenBuffer == null) {
                mOffscreenBuffer = Bitmap.createBitmap(
                        getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
                mOffscreenCanvas.setBitmap(mOffscreenBuffer);
            }
            if (!mOffscreenDirtyRect.isEmpty()) {
                // Clear previous dirty rectangle.
                mGesturePaint.setColor(Color.TRANSPARENT);
                mGesturePaint.setStyle(Paint.Style.FILL);
                mOffscreenCanvas.drawRect(mOffscreenDirtyRect, mGesturePaint);
                mOffscreenDirtyRect.setEmpty();
            }
            boolean needsUpdatingGesturePreviewTrail = false;
            synchronized (mGesturePreviewTrails) {
                // Trails count == fingers count that have ever been active.
@@ -210,10 +237,18 @@ public class PreviewPlacerView extends RelativeLayout {
                for (int index = 0; index < trailsCount; index++) {
                    final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index);
                    needsUpdatingGesturePreviewTrail |=
                            trail.drawGestureTrail(canvas, mGesturePaint,
                                    mGesturePreviewTrailParams);
                            trail.drawGestureTrail(mOffscreenCanvas, mGesturePaint,
                                    mGesturePreviewTrailBoundsRect, mGesturePreviewTrailParams);
                    // {@link #mGesturePreviewTrailBoundsRect} has bounding box of the trail.
                    mOffscreenDirtyRect.union(mGesturePreviewTrailBoundsRect);
                }
            }
            if (!mOffscreenDirtyRect.isEmpty()) {
                canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect,
                        mGesturePaint);
                // Note: Defer clearing the dirty rectangle here because we will get cleared
                // rectangle on the canvas.
            }
            if (needsUpdatingGesturePreviewTrail) {
                mDrawingHandler.postUpdateGestureTrailPreview();
            }
@@ -263,7 +298,6 @@ public class PreviewPlacerView extends RelativeLayout {
        final float round = mGestureFloatingPreviewRoundRadius;
        paint.setColor(mGestureFloatingPreviewColor);
        canvas.drawRoundRect(rectangle, round, round, paint);

        // Paint the text preview
        paint.setColor(mGestureFloatingPreviewTextColor);
        final float textX = rectX + hPad + textWidth / 2.0f;