diff options
10 files changed, 288 insertions, 278 deletions
diff --git a/tests/sketch/AndroidManifest.xml b/tests/sketch/AndroidManifest.xml index 1f4333c..78df234 100755 --- a/tests/sketch/AndroidManifest.xml +++ b/tests/sketch/AndroidManifest.xml @@ -14,25 +14,34 @@ limitations under the License. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.gesture.example" - android:versionCode="1" - android:versionName="1.0.0"> - <uses-permission android:name="android.permission.READ_CONTACTS" /> - <application android:icon="@drawable/icon" android:label="@string/app_name"> - <activity android:name="com.android.gesture.example.GestureEntry" - android:label="@string/app_name"> + package="com.android.gesture.example" + android:versionCode="1" + android:versionName="1.0.0"> + + <uses-permission android:name="android.permission.READ_CONTACTS" /> + <uses-permission android:name="android.permission.WRITE_SDCARD" /> + + <application android:icon="@drawable/icon" android:label="@string/app_name"> + + <activity + android:name="com.android.gesture.example.GestureEntry" + android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + <activity android:name="com.android.gesture.example.GestureLibViewer"/> - <activity android:name="com.android.gesture.example.ContactListGestureOverlay" - android:label="@string/overlay_name"> + + <activity + android:name="com.android.gesture.example.ContactListGestureOverlay" + android:label="@string/overlay_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + </application> </manifest> diff --git a/tests/sketch/src/com/android/gesture/Gesture.java b/tests/sketch/src/com/android/gesture/Gesture.java index 44711ca..d5dcc65 100755 --- a/tests/sketch/src/com/android/gesture/Gesture.java +++ b/tests/sketch/src/com/android/gesture/Gesture.java @@ -23,12 +23,17 @@ import android.graphics.Path; import android.graphics.RectF; import android.os.Parcel; import android.os.Parcelable; - -import org.xmlpull.v1.XmlSerializer; +import android.util.Log; import java.io.IOException; +import java.io.DataOutputStream; +import java.io.DataInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; import java.util.ArrayList; +import static com.android.gesture.GestureConstants.LOG_TAG; + /** * A gesture can have a single or multiple strokes */ @@ -149,10 +154,12 @@ public class Gesture implements Parcelable { * @return the bitmap */ public Bitmap toBitmap(int width, int height, int edge, int numSample, int color) { - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); + final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(bitmap); + canvas.translate(edge, edge); - Paint paint = new Paint(); + + final Paint paint = new Paint(); paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS); paint.setDither(BITMAP_RENDERING_DITHER); paint.setColor(color); @@ -182,10 +189,12 @@ public class Gesture implements Parcelable { * @return the bitmap */ public Bitmap toBitmap(int width, int height, int edge, int color) { - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); + final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(bitmap); + canvas.translate(edge, edge); - Paint paint = new Paint(); + + final Paint paint = new Paint(); paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS); paint.setDither(BITMAP_RENDERING_DITHER); paint.setColor(color); @@ -193,53 +202,44 @@ public class Gesture implements Parcelable { paint.setStrokeJoin(Paint.Join.ROUND); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeWidth(BITMAP_RENDERING_WIDTH); - ArrayList<GestureStroke> strokes = mStrokes; - int count = strokes.size(); + + final ArrayList<GestureStroke> strokes = mStrokes; + final int count = strokes.size(); + for (int i = 0; i < count; i++) { - GestureStroke stroke = strokes.get(i); - stroke.draw(canvas, paint); + strokes.get(i).draw(canvas, paint); } return bitmap; } - /** - * Save the gesture as XML - * - * @param namespace - * @param serializer - * @throws IOException - */ - void toXML(String namespace, XmlSerializer serializer) throws IOException { - serializer.startTag(namespace, GestureConstants.XML_TAG_GESTURE); - serializer.attribute(namespace, GestureConstants.XML_TAG_ID, Long.toString(mGestureID)); - ArrayList<GestureStroke> strokes = mStrokes; - int count = strokes.size(); + void serialize(DataOutputStream out) throws IOException { + final ArrayList<GestureStroke> strokes = mStrokes; + final int count = strokes.size(); + + // Write gesture ID + out.writeLong(mGestureID); + // Write number of strokes + out.writeInt(count); + for (int i = 0; i < count; i++) { - GestureStroke stroke = strokes.get(i); - stroke.toXML(namespace, serializer); + strokes.get(i).serialize(out); } - serializer.endTag(namespace, GestureConstants.XML_TAG_GESTURE); } - /** - * Create the gesture from a string - * - * @param str - */ - public void createFromString(String str) { - int startIndex = 0; - int endIndex; - while ((endIndex = - str.indexOf(GestureConstants.STRING_GESTURE_DELIIMITER, startIndex + 1)) != -1) { - String token = str.substring(startIndex, endIndex); - if (startIndex > 0) { // stroke tokens - addStroke(GestureStroke.createFromString(token)); - } else { // id token - mGestureID = Long.parseLong(token); - } - startIndex = endIndex + 1; + static Gesture deserialize(DataInputStream in) throws IOException { + final Gesture gesture = new Gesture(); + + // Gesture ID + gesture.mGestureID = in.readLong(); + // Number of strokes + final int count = in.readInt(); + + for (int i = 0; i < count; i++) { + gesture.addStroke(GestureStroke.deserialize(in)); } + + return gesture; } /** @@ -247,12 +247,14 @@ public class Gesture implements Parcelable { */ @Override public String toString() { - StringBuilder str = new StringBuilder(); + final StringBuilder str = new StringBuilder(); str.append(mGestureID); - ArrayList<GestureStroke> strokes = mStrokes; - int count = strokes.size(); + + final ArrayList<GestureStroke> strokes = mStrokes; + final int count = strokes.size(); + for (int i = 0; i < count; i++) { - GestureStroke stroke = strokes.get(i); + final GestureStroke stroke = strokes.get(i); str.append(GestureConstants.STRING_GESTURE_DELIIMITER); str.append(stroke.toString()); } @@ -262,9 +264,24 @@ public class Gesture implements Parcelable { public static final Parcelable.Creator<Gesture> CREATOR = new Parcelable.Creator<Gesture>() { public Gesture createFromParcel(Parcel in) { - String str = in.readString(); - Gesture gesture = new Gesture(); - gesture.createFromString(str); + Gesture gesture = null; + final long gestureID = in.readLong(); + + final DataInputStream inStream = new DataInputStream( + new ByteArrayInputStream(in.createByteArray())); + + try { + gesture = deserialize(inStream); + } catch (IOException e) { + Log.e(LOG_TAG, "Error reading Gesture from parcel:", e); + } finally { + GestureUtilities.closeStream(inStream); + } + + if (gesture != null) { + gesture.mGestureID = gestureID; + } + return gesture; } @@ -273,35 +290,31 @@ public class Gesture implements Parcelable { } }; - /** - * Build a gesture from a byte array - * - * @param bytes - * @return the gesture - */ - static Gesture buildFromArray(byte[] bytes) { - String str = new String(bytes); - Gesture gesture = new Gesture(); - gesture.createFromString(str); - return gesture; - } - - /** - * Save a gesture to a byte array - * - * @param stroke - * @return the byte array - */ - static byte[] saveToArray(Gesture stroke) { - String str = stroke.toString(); - return str.getBytes(); - } - public void writeToParcel(Parcel out, int flags) { - out.writeString(toString()); + out.writeLong(mGestureID); + + boolean result = false; + final ByteArrayOutputStream byteStream = + new ByteArrayOutputStream(GestureConstants.IO_BUFFER_SIZE); + final DataOutputStream outStream = new DataOutputStream(byteStream); + + try { + serialize(outStream); + result = true; + } catch (IOException e) { + Log.e(LOG_TAG, "Error writing Gesture to parcel:", e); + } finally { + GestureUtilities.closeStream(outStream); + GestureUtilities.closeStream(byteStream); + } + + if (result) { + out.writeByteArray(byteStream.toByteArray()); + } } public int describeContents() { - return CONTENTS_FILE_DESCRIPTOR; + return 0; } } + diff --git a/tests/sketch/src/com/android/gesture/GestureConstants.java b/tests/sketch/src/com/android/gesture/GestureConstants.java index cb64791..c0f2f3d 100644 --- a/tests/sketch/src/com/android/gesture/GestureConstants.java +++ b/tests/sketch/src/com/android/gesture/GestureConstants.java @@ -17,16 +17,13 @@ package com.android.gesture; interface GestureConstants { - static final String XML_TAG_LIBRARY = "library"; - static final String XML_TAG_ENTRY = "entry"; - static final String XML_TAG_GESTURE = "gesture"; - static final String XML_TAG_STROKE = "stroke"; - static final String XML_TAG_ID = "id"; - static final String XML_TAG_NAME = "name"; static final String STRING_GESTURE_DELIIMITER = "#"; static final String STRING_STROKE_DELIIMITER = ","; + static final int STROKE_STRING_BUFFER_SIZE = 1024; static final int STROKE_POINT_BUFFER_SIZE = 100; // number of points - static final int IO_BUFFER_SIZE = 8 * 1024; // 8K - String LOG_TAG = "GestureLibrary"; + + static final int IO_BUFFER_SIZE = 32 * 1024; // 32K + + static final String LOG_TAG = "Gestures"; } diff --git a/tests/sketch/src/com/android/gesture/GestureLibrary.java b/tests/sketch/src/com/android/gesture/GestureLibrary.java index 915b840..eba6069 100644 --- a/tests/sketch/src/com/android/gesture/GestureLibrary.java +++ b/tests/sketch/src/com/android/gesture/GestureLibrary.java @@ -16,16 +16,8 @@ package com.android.gesture; -import android.util.Config; import android.util.Log; -import android.util.Xml; -import android.util.Xml.Encoding; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; -import org.xmlpull.v1.XmlSerializer; +import android.os.SystemClock; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -33,10 +25,12 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.io.PrintWriter; +import java.io.DataOutputStream; +import java.io.DataInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; +import java.util.Map; import static com.android.gesture.GestureConstants.LOG_TAG; @@ -44,10 +38,28 @@ import static com.android.gesture.GestureConstants.LOG_TAG; * GestureLibrary maintains gesture examples and makes predictions on a new * gesture */ +// +// File format for GestureLibrary: +// +// Nb. bytes Java type Description +// ----------------------------------- +// Header +// 2 bytes short File format version number +// 4 bytes int Number of entries +// Entry +// X bytes UTF String Entry name +// 4 bytes int Number of gestures +// Gesture +// 8 bytes long Gesture ID +// 4 bytes int Number of strokes +// Stroke +// 4 bytes int Number of points +// Point +// 4 bytes float X coordinate of the point +// 4 bytes float Y coordinate of the point +// 8 bytes long Time stamp +// public class GestureLibrary { - - private static final String NAMESPACE = ""; - public static final int SEQUENCE_INVARIANT = 1; // when SEQUENCE_SENSITIVE is used, only single stroke gestures are currently allowed public static final int SEQUENCE_SENSITIVE = 2; @@ -56,12 +68,16 @@ public class GestureLibrary { public static final int ORIENTATION_INVARIANT = 1; public static final int ORIENTATION_SENSITIVE = 2; + private static final short FILE_FORMAT_VERSION = 1; + + private static final boolean PROFILE_LOADING_SAVING = false; + private int mSequenceType = SEQUENCE_SENSITIVE; private int mOrientationStyle = ORIENTATION_SENSITIVE; private final String mGestureFileName; - private final HashMap<String, ArrayList<Gesture>> mEntryName2gestures = + private final HashMap<String, ArrayList<Gesture>> mNamedGestures = new HashMap<String, ArrayList<Gesture>>(); private Learner mClassifier; @@ -104,7 +120,7 @@ public class GestureLibrary { * @return a set of strings */ public Set<String> getGestureEntries() { - return mEntryName2gestures.keySet(); + return mNamedGestures.keySet(); } /** @@ -128,10 +144,10 @@ public class GestureLibrary { if (entryName == null || entryName.length() == 0) { return; } - ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName); + ArrayList<Gesture> gestures = mNamedGestures.get(entryName); if (gestures == null) { gestures = new ArrayList<Gesture>(); - mEntryName2gestures.put(entryName, gestures); + mNamedGestures.put(entryName, gestures); } gestures.add(gesture); mClassifier.addInstance(Instance.createInstance(mSequenceType, gesture, entryName)); @@ -146,7 +162,7 @@ public class GestureLibrary { * @param gesture */ public void removeGesture(String entryName, Gesture gesture) { - ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName); + ArrayList<Gesture> gestures = mNamedGestures.get(entryName); if (gestures == null) { return; } @@ -155,7 +171,7 @@ public class GestureLibrary { // if there are no more samples, remove the entry automatically if (gestures.isEmpty()) { - mEntryName2gestures.remove(entryName); + mNamedGestures.remove(entryName); } mClassifier.removeInstance(gesture.getID()); @@ -169,7 +185,7 @@ public class GestureLibrary { * @param entryName the entry name */ public void removeEntireEntry(String entryName) { - mEntryName2gestures.remove(entryName); + mNamedGestures.remove(entryName); mClassifier.removeInstances(entryName); mChanged = true; } @@ -181,7 +197,7 @@ public class GestureLibrary { * @return the list of gestures that is under this name */ public ArrayList<Gesture> getGestures(String entryName) { - ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName); + ArrayList<Gesture> gestures = mNamedGestures.get(entryName); if (gestures != null) { return new ArrayList<Gesture>(gestures); } else { @@ -197,8 +213,8 @@ public class GestureLibrary { return true; } - boolean result= false; - PrintWriter writer = null; + boolean result = false; + DataOutputStream out = null; try { File file = new File(mGestureFileName); @@ -208,40 +224,48 @@ public class GestureLibrary { } } - writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream( - mGestureFileName), GestureConstants.IO_BUFFER_SIZE)); + long start; + if (PROFILE_LOADING_SAVING) { + start = SystemClock.elapsedRealtime(); + } + + final HashMap<String, ArrayList<Gesture>> maps = mNamedGestures; + + out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file), + GestureConstants.IO_BUFFER_SIZE)); + // Write version number + out.writeShort(FILE_FORMAT_VERSION); + // Write number of entries + out.writeInt(maps.size()); - final XmlSerializer serializer = Xml.newSerializer(); - serializer.setOutput(writer); - serializer.startDocument(Encoding.ISO_8859_1.name(), null); - serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY); + for (Map.Entry<String, ArrayList<Gesture>> entry : maps.entrySet()) { + final String key = entry.getKey(); + final ArrayList<Gesture> examples = entry.getValue(); + final int count = examples.size(); - final HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures; + // Write entry name + out.writeUTF(key); + // Write number of examples for this entry + out.writeInt(count); - for (String key : maps.keySet()) { - ArrayList<Gesture> examples = maps.get(key); - // save an entry - serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY); - serializer.attribute(NAMESPACE, GestureConstants.XML_TAG_NAME, key); - int count = examples.size(); for (int i = 0; i < count; i++) { - Gesture gesture = examples.get(i); - // save each gesture in the entry - gesture.toXML(NAMESPACE, serializer); + examples.get(i).serialize(out); } - serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY); } - serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY); - serializer.endDocument(); - serializer.flush(); + out.flush(); + + if (PROFILE_LOADING_SAVING) { + long end = SystemClock.elapsedRealtime(); + Log.d(LOG_TAG, "Saving gestures library = " + (end - start) + " ms"); + } mChanged = false; result = true; } catch (IOException ex) { Log.d(LOG_TAG, "Failed to save gestures:", ex); } finally { - GestureUtilities.closeStream(writer); + GestureUtilities.closeStream(out); } return result; @@ -255,17 +279,30 @@ public class GestureLibrary { final File file = new File(mGestureFileName); if (file.exists()) { - BufferedInputStream in = null; + DataInputStream in = null; try { - if (Config.DEBUG) { - Log.v(LOG_TAG, "Load from " + mGestureFileName); + in = new DataInputStream(new BufferedInputStream( + new FileInputStream(mGestureFileName), GestureConstants.IO_BUFFER_SIZE)); + + long start; + if (PROFILE_LOADING_SAVING) { + start = SystemClock.elapsedRealtime(); + } + + // Read file format version number + final short versionNumber = in.readShort(); + switch (versionNumber) { + case 1: + readFormatV1(in); + break; } - in = new BufferedInputStream(new FileInputStream( - mGestureFileName), GestureConstants.IO_BUFFER_SIZE); - Xml.parse(in, Encoding.ISO_8859_1, new CompactInkHandler()); + + if (PROFILE_LOADING_SAVING) { + long end = SystemClock.elapsedRealtime(); + Log.d(LOG_TAG, "Loading gestures library = " + (end - start) + " ms"); + } + result = true; - } catch (SAXException ex) { - Log.d(LOG_TAG, "Failed to load gestures:", ex); } catch (IOException ex) { Log.d(LOG_TAG, "Failed to load gestures:", ex); } finally { @@ -276,69 +313,28 @@ public class GestureLibrary { return result; } - private class CompactInkHandler implements ContentHandler { - final StringBuilder mBuffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE); - - String mEntryName; - - Gesture mCurrentGesture = null; - ArrayList<Gesture> mGestures; - - CompactInkHandler() { - } - - public void characters(char[] ch, int start, int length) { - mBuffer.append(ch, start, length); - } - - public void endDocument() { - } - - public void endElement(String uri, String localName, String qName) { - if (localName.equals(GestureConstants.XML_TAG_ENTRY)) { - mEntryName2gestures.put(mEntryName, mGestures); - mGestures = null; - } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) { - mGestures.add(mCurrentGesture); - mClassifier.addInstance(Instance.createInstance(mSequenceType, - mCurrentGesture, mEntryName)); - mCurrentGesture = null; - } else if (localName.equals(GestureConstants.XML_TAG_STROKE)) { - mCurrentGesture.addStroke(GestureStroke.createFromString(mBuffer.toString())); - mBuffer.setLength(0); + private void readFormatV1(DataInputStream in) throws IOException { + final Learner classifier = mClassifier; + final HashMap<String, ArrayList<Gesture>> namedGestures = mNamedGestures; + namedGestures.clear(); + + // Number of entries in the library + final int entriesCount = in.readInt(); + + for (int i = 0; i < entriesCount; i++) { + // Entry name + final String name = in.readUTF(); + // Number of gestures + final int gestureCount = in.readInt(); + + final ArrayList<Gesture> gestures = new ArrayList<Gesture>(gestureCount); + for (int j = 0; j < gestureCount; j++) { + final Gesture gesture = Gesture.deserialize(in); + gestures.add(gesture); + classifier.addInstance(Instance.createInstance(mSequenceType, gesture, name)); } - } - - public void endPrefixMapping(String prefix) { - } - - public void ignorableWhitespace(char[] ch, int start, int length) { - } - - public void processingInstruction(String target, String data) { - } - - public void setDocumentLocator(Locator locator) { - } - - public void skippedEntity(String name) { - } - - public void startDocument() { - } - - public void startElement(String uri, String localName, String qName, Attributes attributes) { - if (localName.equals(GestureConstants.XML_TAG_ENTRY)) { - mGestures = new ArrayList<Gesture>(); - mEntryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME); - } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) { - mCurrentGesture = new Gesture(); - mCurrentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE, - GestureConstants.XML_TAG_ID))); - } - } - public void startPrefixMapping(String prefix, String uri) { + namedGestures.put(name, gestures); } } } diff --git a/tests/sketch/src/com/android/gesture/GesturePoint.java b/tests/sketch/src/com/android/gesture/GesturePoint.java index 81e59a4..560f893 100644 --- a/tests/sketch/src/com/android/gesture/GesturePoint.java +++ b/tests/sketch/src/com/android/gesture/GesturePoint.java @@ -16,6 +16,9 @@ package com.android.gesture; +import java.io.DataInputStream; +import java.io.IOException; + /** * A timed point of a gesture stroke */ @@ -31,4 +34,13 @@ public class GesturePoint { this.y = y; timestamp = t; } + + static GesturePoint deserialize(DataInputStream in) throws IOException { + // Read X and Y + final float x = in.readFloat(); + final float y = in.readFloat(); + // Read timestamp + final long timeStamp = in.readLong(); + return new GesturePoint(x, y, timeStamp); + } } diff --git a/tests/sketch/src/com/android/gesture/GestureStroke.java b/tests/sketch/src/com/android/gesture/GestureStroke.java index c2ebc17..79b42fe 100644 --- a/tests/sketch/src/com/android/gesture/GestureStroke.java +++ b/tests/sketch/src/com/android/gesture/GestureStroke.java @@ -22,9 +22,9 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; -import org.xmlpull.v1.XmlSerializer; - import java.io.IOException; +import java.io.DataOutputStream; +import java.io.DataInputStream; import java.util.ArrayList; /** @@ -167,57 +167,35 @@ public class GestureStroke { return path; } - /** - * Save the gesture stroke as XML - * - * @param namespace - * @param serializer - * @throws IOException - */ - void toXML(String namespace, XmlSerializer serializer) throws IOException { - serializer.startTag(namespace, GestureConstants.XML_TAG_STROKE); - serializer.text(toString()); - serializer.endTag(namespace, GestureConstants.XML_TAG_STROKE); + void serialize(DataOutputStream out) throws IOException { + final float[] pts = points; + final long[] times = timestamps; + final int count = points.length; + + // Write number of points + out.writeInt(count / 2); + + for (int i = 0; i < count; i += 2) { + // Write X + out.writeFloat(pts[i]); + // Write Y + out.writeFloat(pts[i + 1]); + // Write timestamp + out.writeLong(times[i / 2]); + } } - /** - * Create a gesture stroke from a string - * - * @param str - * @return the gesture stroke - */ - public static GestureStroke createFromString(String str) { - final ArrayList<GesturePoint> points = new ArrayList<GesturePoint>( - GestureConstants.STROKE_POINT_BUFFER_SIZE); - - int endIndex; - int startIndex = 0; - - while ((endIndex = - str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1)) != -1) { - - // parse x - String token = str.substring(startIndex, endIndex); - float x = Float.parseFloat(token); - startIndex = endIndex + 1; - - // parse y - endIndex = str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1); - token = str.substring(startIndex, endIndex); - float y = Float.parseFloat(token); - startIndex = endIndex + 1; - - // parse t - endIndex = str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1); - token = str.substring(startIndex, endIndex); - long time = Long.parseLong(token); - startIndex = endIndex + 1; - - points.add(new GesturePoint(x, y, time)); + static GestureStroke deserialize(DataInputStream in) throws IOException { + // Number of points + final int count = in.readInt(); + + final ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(count); + for (int i = 0; i < count; i++) { + points.add(GesturePoint.deserialize(in)); } return new GestureStroke(points); - } + } /** * Convert the stroke to string diff --git a/tests/sketch/src/com/android/gesture/GestureUtilities.java b/tests/sketch/src/com/android/gesture/GestureUtilities.java index 92de987..6d73c2d 100755 --- a/tests/sketch/src/com/android/gesture/GestureUtilities.java +++ b/tests/sketch/src/com/android/gesture/GestureUtilities.java @@ -18,6 +18,7 @@ package com.android.gesture; import android.graphics.RectF; import android.graphics.Matrix; +import android.util.Log; import java.util.ArrayList; import java.util.Arrays; @@ -42,7 +43,7 @@ final class GestureUtilities { try { stream.close(); } catch (IOException e) { - android.util.Log.e(LOG_TAG, "Could not close stream", e); + Log.e(LOG_TAG, "Could not close stream", e); } } } @@ -56,24 +57,25 @@ final class GestureUtilities { float sx = targetPatchSize / rect.width(); float sy = targetPatchSize / rect.height(); float scale = sx < sy ? sx : sy; - android.graphics.Matrix trans = new android.graphics.Matrix(); + + Matrix trans = new Matrix(); trans.setScale(scale, scale); - android.graphics.Matrix translate1 = new android.graphics.Matrix(); - translate1.setTranslate(-rect.centerX(), -rect.centerY()); - trans.preConcat(translate1); - android.graphics.Matrix translate2 = new android.graphics.Matrix(); - translate2.setTranslate(targetPatchSize / 2, targetPatchSize / 2); - trans.postConcat(translate2); - - ArrayList<GestureStroke> strokes = gesture.getStrokes(); - int count = strokes.size(); + trans.preTranslate(-rect.centerX(), -rect.centerY()); + trans.postTranslate(targetPatchSize / 2, targetPatchSize / 2); + + final ArrayList<GestureStroke> strokes = gesture.getStrokes(); + final int count = strokes.size(); + int size; float xpos; float ypos; + for (int index = 0; index < count; index++) { - GestureStroke stroke = strokes.get(index); + final GestureStroke stroke = strokes.get(index); size = stroke.points.length; - float[] pts = new float[size]; + + final float[] pts = new float[size]; + trans.mapPoints(pts, 0, stroke.points, 0, size / 2); float segmentEndX = -1; float segmentEndY = -1; diff --git a/tests/sketch/src/com/android/gesture/Instance.java b/tests/sketch/src/com/android/gesture/Instance.java index b2e030e..502a0fa 100755 --- a/tests/sketch/src/com/android/gesture/Instance.java +++ b/tests/sketch/src/com/android/gesture/Instance.java @@ -16,6 +16,8 @@ package com.android.gesture; +import android.graphics.Matrix; + /** * An instance represents a sample if the label is available or a query if the * label is null. @@ -47,10 +49,12 @@ class Instance { private void normalize() { float[] sample = vector; float sum = 0; + int size = sample.length; for (int i = 0; i < size; i++) { sum += sample[i] * sample[i]; } + float magnitude = (float) Math.sqrt(sum); for (int i = 0; i < size; i++) { sample[i] /= magnitude; @@ -100,12 +104,11 @@ class Instance { } } - android.graphics.Matrix m = new android.graphics.Matrix(); + Matrix m = new Matrix(); m.setTranslate(-center[0], -center[1]); - android.graphics.Matrix rotation = new android.graphics.Matrix(); - rotation.setRotate(adjustment); - m.postConcat(rotation); + m.postRotate(adjustment); m.mapPoints(pts); + return pts; } diff --git a/tests/sketch/src/com/android/gesture/LetterRecognizer.java b/tests/sketch/src/com/android/gesture/LetterRecognizer.java index 086aedf..981c416 100644 --- a/tests/sketch/src/com/android/gesture/LetterRecognizer.java +++ b/tests/sketch/src/com/android/gesture/LetterRecognizer.java @@ -21,7 +21,6 @@ import android.content.res.Resources; import android.util.Log; import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; @@ -29,9 +28,9 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -public class LetterRecognizer { - private static final String LOG_TAG = "LetterRecognizer"; +import static com.android.gesture.GestureConstants.LOG_TAG; +public class LetterRecognizer { public final static int LATIN_LOWERCASE = 0; private SigmoidUnit[] mHiddenLayer; @@ -41,7 +40,7 @@ public class LetterRecognizer { private final int mPatchSize; - static final String GESTURE_FILE_NAME = "letters.xml"; + static final String GESTURE_FILE_NAME = "letters.gestures"; private GestureLibrary mGestureLibrary; private final static int ADJUST_RANGE = 3; @@ -151,7 +150,8 @@ public class LetterRecognizer { LetterRecognizer classifier = null; try { - in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID))); + in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID), + GestureConstants.IO_BUFFER_SIZE)); final int iCount = in.readInt(); final int hCount = in.readInt(); diff --git a/tests/sketch/src/com/android/gesture/example/GestureEntry.java b/tests/sketch/src/com/android/gesture/example/GestureEntry.java index 03a26da..53ba481 100644 --- a/tests/sketch/src/com/android/gesture/example/GestureEntry.java +++ b/tests/sketch/src/com/android/gesture/example/GestureEntry.java @@ -49,7 +49,7 @@ public class GestureEntry extends Activity { private static final String PARCEL_KEY = "gesture"; static final String GESTURE_FILE_NAME = Environment.getExternalStorageDirectory().getAbsolutePath() - + File.separator + "gestureEntry.xml"; + + File.separator + "demo_library.gestures"; private static final int DIALOG_NEW_ENTRY = 1; |