Gesture.java revision 9ffe1ae56bf495b1ada1e9c1da523db0677d98b7
16e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato/* 26e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * Copyright (C) 2008-2009 The Android Open Source Project 36e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * 46e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 56e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * you may not use this file except in compliance with the License. 66e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * You may obtain a copy of the License at 76e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * 86e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 96e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * 106e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * Unless required by applicable law or agreed to in writing, software 116e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 126e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * See the License for the specific language governing permissions and 146e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * limitations under the License. 156e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato */ 166e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 17db567c390bd56c05614eaa83c02dbb99f97ad9ccRomain Guypackage android.gesture; 186e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 196e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport android.graphics.Bitmap; 206e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport android.graphics.Canvas; 216e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport android.graphics.Paint; 226e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport android.graphics.Path; 236e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport android.graphics.RectF; 246e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport android.os.Parcel; 256e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport android.os.Parcelable; 26b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guyimport android.util.Log; 276e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 286e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport java.io.IOException; 29b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guyimport java.io.DataOutputStream; 30b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guyimport java.io.DataInputStream; 31b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guyimport java.io.ByteArrayOutputStream; 32b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guyimport java.io.ByteArrayInputStream; 336e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratoimport java.util.ArrayList; 346e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 356e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato/** 3635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * A gesture can have a single or multiple strokes 376e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato */ 386e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 396e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onoratopublic class Gesture implements Parcelable { 4035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li private static final long GESTURE_ID_BASE = System.currentTimeMillis(); 4135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 4235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li private static final int BITMAP_RENDERING_WIDTH = 2; 4335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 4435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li private static final boolean BITMAP_RENDERING_ANTIALIAS = true; 4535aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li private static final boolean BITMAP_RENDERING_DITHER = true; 4635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 4735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li private static int sGestureCount = 0; 4835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 499ffe1ae56bf495b1ada1e9c1da523db0677d98b7Romain Guy private final RectF mBoundingBox = new RectF(); 5035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 5135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li // the same as its instance ID 5235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li private long mGestureID; 5335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 54c534727972c3835ed997e84a349f259915ef2cddRomain Guy private final ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>(); 556e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 566e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato public Gesture() { 5735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li mGestureID = GESTURE_ID_BASE + sGestureCount++; 586e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 596e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 6082f3495b146b267f3786997752cef25310176349Romain Guy void recycle() { 6182f3495b146b267f3786997752cef25310176349Romain Guy mStrokes.clear(); 6282f3495b146b267f3786997752cef25310176349Romain Guy mBoundingBox.setEmpty(); 6382f3495b146b267f3786997752cef25310176349Romain Guy } 6482f3495b146b267f3786997752cef25310176349Romain Guy 6535aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li /** 6635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @return all the strokes of the gesture 6735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li */ 6835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li public ArrayList<GestureStroke> getStrokes() { 6935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li return mStrokes; 70935fd37d27804539b141fa074c060d2c15524424Yang Li } 7135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 7235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li /** 7335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @return the number of strokes included by this gesture 7435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li */ 7535aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li public int getStrokesCount() { 7635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li return mStrokes.size(); 776e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 786e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 7935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li /** 8035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * Add a stroke to the gesture 8135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * 8235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param stroke 8335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li */ 8435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li public void addStroke(GestureStroke stroke) { 8535aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li mStrokes.add(stroke); 869ffe1ae56bf495b1ada1e9c1da523db0677d98b7Romain Guy mBoundingBox.union(stroke.boundingBox); 876e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 886e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato 896e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato /** 9035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * Get the total length of the gesture. When there are multiple strokes in 9135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * the gesture, this returns the sum of the lengths of all the strokes 9235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * 936e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * @return the length of the gesture 946e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato */ 956e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato public float getLength() { 9635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li int len = 0; 97c534727972c3835ed997e84a349f259915ef2cddRomain Guy final ArrayList<GestureStroke> strokes = mStrokes; 98c534727972c3835ed997e84a349f259915ef2cddRomain Guy final int count = strokes.size(); 99c534727972c3835ed997e84a349f259915ef2cddRomain Guy 10035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li for (int i = 0; i < count; i++) { 101c534727972c3835ed997e84a349f259915ef2cddRomain Guy len += strokes.get(i).length; 10235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li } 103c534727972c3835ed997e84a349f259915ef2cddRomain Guy 10435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li return len; 1056e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 10635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 10735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li /** 10835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @return the bounding box of the gesture 10935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li */ 11035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li public RectF getBoundingBox() { 11135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li return mBoundingBox; 1126e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 11335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 11482f3495b146b267f3786997752cef25310176349Romain Guy public Path toPath() { 11582f3495b146b267f3786997752cef25310176349Romain Guy return toPath(null); 11682f3495b146b267f3786997752cef25310176349Romain Guy } 11782f3495b146b267f3786997752cef25310176349Romain Guy 11882f3495b146b267f3786997752cef25310176349Romain Guy public Path toPath(Path path) { 11982f3495b146b267f3786997752cef25310176349Romain Guy if (path == null) path = new Path(); 12082f3495b146b267f3786997752cef25310176349Romain Guy 12182f3495b146b267f3786997752cef25310176349Romain Guy final ArrayList<GestureStroke> strokes = mStrokes; 12282f3495b146b267f3786997752cef25310176349Romain Guy final int count = strokes.size(); 12382f3495b146b267f3786997752cef25310176349Romain Guy 12482f3495b146b267f3786997752cef25310176349Romain Guy for (int i = 0; i < count; i++) { 12582f3495b146b267f3786997752cef25310176349Romain Guy path.addPath(strokes.get(i).getPath()); 12682f3495b146b267f3786997752cef25310176349Romain Guy } 12782f3495b146b267f3786997752cef25310176349Romain Guy 12882f3495b146b267f3786997752cef25310176349Romain Guy return path; 12982f3495b146b267f3786997752cef25310176349Romain Guy } 13082f3495b146b267f3786997752cef25310176349Romain Guy 13182f3495b146b267f3786997752cef25310176349Romain Guy public Path toPath(int width, int height, int edge, int numSample) { 13282f3495b146b267f3786997752cef25310176349Romain Guy return toPath(null, width, height, edge, numSample); 13382f3495b146b267f3786997752cef25310176349Romain Guy } 13482f3495b146b267f3786997752cef25310176349Romain Guy 13582f3495b146b267f3786997752cef25310176349Romain Guy public Path toPath(Path path, int width, int height, int edge, int numSample) { 13682f3495b146b267f3786997752cef25310176349Romain Guy if (path == null) path = new Path(); 13782f3495b146b267f3786997752cef25310176349Romain Guy 13882f3495b146b267f3786997752cef25310176349Romain Guy final ArrayList<GestureStroke> strokes = mStrokes; 13982f3495b146b267f3786997752cef25310176349Romain Guy final int count = strokes.size(); 14082f3495b146b267f3786997752cef25310176349Romain Guy 14182f3495b146b267f3786997752cef25310176349Romain Guy for (int i = 0; i < count; i++) { 14282f3495b146b267f3786997752cef25310176349Romain Guy path.addPath(strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample)); 14382f3495b146b267f3786997752cef25310176349Romain Guy } 14482f3495b146b267f3786997752cef25310176349Romain Guy 14582f3495b146b267f3786997752cef25310176349Romain Guy return path; 14682f3495b146b267f3786997752cef25310176349Romain Guy } 14782f3495b146b267f3786997752cef25310176349Romain Guy 14835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li /** 14935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * Set the id of the gesture 15035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * 15135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param id 15235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li */ 15335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li void setID(long id) { 15435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li mGestureID = id; 1556e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 15635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 15735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li /** 15835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @return the id of the gesture 15935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li */ 1606e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato public long getID() { 16135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li return mGestureID; 1626e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 16335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 1646e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato /** 1656e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * draw the gesture 16635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * 1676e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * @param canvas 1686e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato */ 16935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li void draw(Canvas canvas, Paint paint) { 170c534727972c3835ed997e84a349f259915ef2cddRomain Guy final ArrayList<GestureStroke> strokes = mStrokes; 171c534727972c3835ed997e84a349f259915ef2cddRomain Guy final int count = strokes.size(); 172c534727972c3835ed997e84a349f259915ef2cddRomain Guy 17335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li for (int i = 0; i < count; i++) { 174c534727972c3835ed997e84a349f259915ef2cddRomain Guy strokes.get(i).draw(canvas, paint); 1756e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 1766e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 17735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 1786e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato /** 17935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * Create a bitmap of the gesture with a transparent background 18035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * 18135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param width width of the target bitmap 18235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param height height of the target bitmap 18335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param edge the edge 18435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param numSample 18535aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param color 18635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @return the bitmap 187935fd37d27804539b141fa074c060d2c15524424Yang Li */ 18835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li public Bitmap toBitmap(int width, int height, int edge, int numSample, int color) { 189b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 190b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final Canvas canvas = new Canvas(bitmap); 191b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 19235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li canvas.translate(edge, edge); 193b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 194b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final Paint paint = new Paint(); 19535aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS); 19635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setDither(BITMAP_RENDERING_DITHER); 19735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setColor(color); 19835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setStyle(Paint.Style.STROKE); 19935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setStrokeJoin(Paint.Join.ROUND); 20035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setStrokeCap(Paint.Cap.ROUND); 20135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setStrokeWidth(BITMAP_RENDERING_WIDTH); 202c534727972c3835ed997e84a349f259915ef2cddRomain Guy 203c534727972c3835ed997e84a349f259915ef2cddRomain Guy final ArrayList<GestureStroke> strokes = mStrokes; 204c534727972c3835ed997e84a349f259915ef2cddRomain Guy final int count = strokes.size(); 205c534727972c3835ed997e84a349f259915ef2cddRomain Guy 20635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li for (int i = 0; i < count; i++) { 207c534727972c3835ed997e84a349f259915ef2cddRomain Guy Path path = strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample); 20835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li canvas.drawPath(path, paint); 209935fd37d27804539b141fa074c060d2c15524424Yang Li } 21035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 21135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li return bitmap; 212935fd37d27804539b141fa074c060d2c15524424Yang Li } 21335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 214935fd37d27804539b141fa074c060d2c15524424Yang Li /** 21535aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * Create a bitmap of the gesture with a transparent background 21635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * 21735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param width 21835aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param height 2196e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato * @param edge 22035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @param color 22135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li * @return the bitmap 2226e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato */ 22335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li public Bitmap toBitmap(int width, int height, int edge, int color) { 224b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 225b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final Canvas canvas = new Canvas(bitmap); 226b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 22735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li canvas.translate(edge, edge); 228b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 229b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final Paint paint = new Paint(); 23035aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS); 23135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setDither(BITMAP_RENDERING_DITHER); 23235aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setColor(color); 2336e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato paint.setStyle(Paint.Style.STROKE); 2346e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato paint.setStrokeJoin(Paint.Join.ROUND); 2356e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato paint.setStrokeCap(Paint.Cap.ROUND); 23635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li paint.setStrokeWidth(BITMAP_RENDERING_WIDTH); 237b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 238b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final ArrayList<GestureStroke> strokes = mStrokes; 239b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final int count = strokes.size(); 240b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 24135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li for (int i = 0; i < count; i++) { 242b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy strokes.get(i).draw(canvas, paint); 24335aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li } 24435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 2456e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato return bitmap; 2466e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 24735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 248b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy void serialize(DataOutputStream out) throws IOException { 249b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final ArrayList<GestureStroke> strokes = mStrokes; 250b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final int count = strokes.size(); 251b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 252b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy // Write gesture ID 253b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy out.writeLong(mGestureID); 254b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy // Write number of strokes 255b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy out.writeInt(count); 256b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 25735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li for (int i = 0; i < count; i++) { 258b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy strokes.get(i).serialize(out); 2596e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 2606e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 26135aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 262b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy static Gesture deserialize(DataInputStream in) throws IOException { 263b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final Gesture gesture = new Gesture(); 264b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 265b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy // Gesture ID 266b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy gesture.mGestureID = in.readLong(); 267b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy // Number of strokes 268b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final int count = in.readInt(); 269b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 270b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy for (int i = 0; i < count; i++) { 271b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy gesture.addStroke(GestureStroke.deserialize(in)); 2726e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 273b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 274b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy return gesture; 2756e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 27635aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 27735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li public static final Parcelable.Creator<Gesture> CREATOR = new Parcelable.Creator<Gesture>() { 2786e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato public Gesture createFromParcel(Parcel in) { 279b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy Gesture gesture = null; 280b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final long gestureID = in.readLong(); 281b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 282b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final DataInputStream inStream = new DataInputStream( 283b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy new ByteArrayInputStream(in.createByteArray())); 284b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 285b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy try { 286b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy gesture = deserialize(inStream); 287b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } catch (IOException e) { 288db567c390bd56c05614eaa83c02dbb99f97ad9ccRomain Guy Log.e(GestureConstants.LOG_TAG, "Error reading Gesture from parcel:", e); 289b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } finally { 290b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy GestureUtilities.closeStream(inStream); 291b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } 292b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 293b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy if (gesture != null) { 294b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy gesture.mGestureID = gestureID; 295b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } 296b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 29735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li return gesture; 2986e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 29935aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 3006e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato public Gesture[] newArray(int size) { 3016e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato return new Gesture[size]; 3026e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 3036e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato }; 30435aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 3056e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato public void writeToParcel(Parcel out, int flags) { 306b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy out.writeLong(mGestureID); 307b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 308b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy boolean result = false; 309b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final ByteArrayOutputStream byteStream = 310b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy new ByteArrayOutputStream(GestureConstants.IO_BUFFER_SIZE); 311b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy final DataOutputStream outStream = new DataOutputStream(byteStream); 312b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 313b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy try { 314b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy serialize(outStream); 315b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy result = true; 316b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } catch (IOException e) { 317db567c390bd56c05614eaa83c02dbb99f97ad9ccRomain Guy Log.e(GestureConstants.LOG_TAG, "Error writing Gesture to parcel:", e); 318b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } finally { 319b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy GestureUtilities.closeStream(outStream); 320b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy GestureUtilities.closeStream(byteStream); 321b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } 322b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 323b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy if (result) { 324b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy out.writeByteArray(byteStream.toByteArray()); 325b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy } 3266e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 32735aa84b1f9f5e42dd00cb66df993ed1628c8963bYang Li 3286e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato public int describeContents() { 329b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy return 0; 3306e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato } 3316e93a3db56d6add29b43077718a4cad9ccfc047fJoe Onorato} 332b6d99b7d17fd1bb1326a70744bd01be5d1586487Romain Guy 333