diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-05-20 15:37:45 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-05-20 15:37:45 -0700 |
commit | b204d4f12773ec67c7f0ded41cb111018f154476 (patch) | |
tree | bd4688f235830a84f7ed584df0b88b17fec4f57e /tests | |
parent | aa9833885d89d42a0cd0b4202485e67b63d51412 (diff) | |
parent | c534727972c3835ed997e84a349f259915ef2cdd (diff) | |
download | frameworks_base-b204d4f12773ec67c7f0ded41cb111018f154476.zip frameworks_base-b204d4f12773ec67c7f0ded41cb111018f154476.tar.gz frameworks_base-b204d4f12773ec67c7f0ded41cb111018f154476.tar.bz2 |
Merge change 2136 into donut
* changes:
First pass at cleaning up the gestures code.
Diffstat (limited to 'tests')
16 files changed, 539 insertions, 296 deletions
diff --git a/tests/sketch/src/com/android/gesture/Gesture.java b/tests/sketch/src/com/android/gesture/Gesture.java index a5e7a25..44711ca 100755 --- a/tests/sketch/src/com/android/gesture/Gesture.java +++ b/tests/sketch/src/com/android/gesture/Gesture.java @@ -34,13 +34,11 @@ import java.util.ArrayList; */ public class Gesture implements Parcelable { - private static final long GESTURE_ID_BASE = System.currentTimeMillis(); private static final int BITMAP_RENDERING_WIDTH = 2; private static final boolean BITMAP_RENDERING_ANTIALIAS = true; - private static final boolean BITMAP_RENDERING_DITHER = true; private static int sGestureCount = 0; @@ -50,7 +48,7 @@ public class Gesture implements Parcelable { // the same as its instance ID private long mGestureID; - private ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>(); + private final ArrayList<GestureStroke> mStrokes = new ArrayList<GestureStroke>(); public Gesture() { mGestureID = GESTURE_ID_BASE + sGestureCount++; @@ -93,12 +91,13 @@ public class Gesture implements Parcelable { */ public float getLength() { int len = 0; - 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); - len += stroke.length; + len += strokes.get(i).length; } + return len; } @@ -131,11 +130,11 @@ public class Gesture implements Parcelable { * @param canvas */ void draw(Canvas canvas, Paint paint) { - 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); } } @@ -150,7 +149,6 @@ public class Gesture implements Parcelable { * @return the bitmap */ public Bitmap toBitmap(int width, int height, int edge, int numSample, int color) { - RectF bbx = getBoundingBox(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.translate(edge, edge); @@ -162,11 +160,12 @@ 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); - Path path = stroke.toPath(width - 2 * edge, height - 2 * edge, numSample); + Path path = strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample); canvas.drawPath(path, paint); } @@ -183,7 +182,6 @@ public class Gesture implements Parcelable { * @return the bitmap */ public Bitmap toBitmap(int width, int height, int edge, int color) { - RectF bbx = getBoundingBox(); Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.translate(edge, edge); @@ -232,7 +230,8 @@ public class Gesture implements Parcelable { public void createFromString(String str) { int startIndex = 0; int endIndex; - while ((endIndex = str.indexOf(GestureConstants.STRING_GESTURE_DELIIMITER, startIndex + 1)) != -1) { + 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)); diff --git a/tests/sketch/src/com/android/gesture/GestureActionListener.java b/tests/sketch/src/com/android/gesture/GestureActionListener.java index 130ac19..c9c5232 100644 --- a/tests/sketch/src/com/android/gesture/GestureActionListener.java +++ b/tests/sketch/src/com/android/gesture/GestureActionListener.java @@ -16,7 +16,6 @@ package com.android.gesture; - public interface GestureActionListener { public void onGesturePerformed(GestureOverlay overlay, Gesture gesture); } diff --git a/tests/sketch/src/com/android/gesture/GestureConstants.java b/tests/sketch/src/com/android/gesture/GestureConstants.java index 0e17c8a..cb64791 100644 --- a/tests/sketch/src/com/android/gesture/GestureConstants.java +++ b/tests/sketch/src/com/android/gesture/GestureConstants.java @@ -28,4 +28,5 @@ interface GestureConstants { 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"; } diff --git a/tests/sketch/src/com/android/gesture/GestureLibrary.java b/tests/sketch/src/com/android/gesture/GestureLibrary.java index c89aa16..3e753e7 100644 --- a/tests/sketch/src/com/android/gesture/GestureLibrary.java +++ b/tests/sketch/src/com/android/gesture/GestureLibrary.java @@ -36,36 +36,33 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.Set; +import static com.android.gesture.GestureConstants.LOG_TAG; + /** * GestureLibrary maintains gesture examples and makes predictions on a new * gesture */ public class GestureLibrary { - public static final int SEQUENCE_INVARIANT = 1; + private static final String NAMESPACE = ""; + public static final int SEQUENCE_INVARIANT = 1; // when SEQUENCE_SENSITIVE is used, only single stroke gestures are allowed public static final int SEQUENCE_SENSITIVE = 2; - private int mSequenceType = SEQUENCE_SENSITIVE; - public static final int ORIENTATION_INVARIANT = 1; - // ORIENTATION_SENSITIVE is only available for single stroke gestures public static final int ORIENTATION_SENSITIVE = 2; + private int mSequenceType = SEQUENCE_SENSITIVE; private int mOrientationStyle = ORIENTATION_SENSITIVE; - private static final String LOGTAG = "GestureLibrary"; - - private static final String NAMESPACE = ""; - private final String mGestureFileName; - private HashMap<String, ArrayList<Gesture>> mEntryName2gestures = new HashMap<String, ArrayList<Gesture>>(); + private final HashMap<String, ArrayList<Gesture>> mEntryName2gestures = + new HashMap<String, ArrayList<Gesture>>(); private Learner mClassifier; @@ -128,9 +125,6 @@ public class GestureLibrary { * @param gesture */ public void addGesture(String entryName, Gesture gesture) { - if (Config.DEBUG) { - Log.v(LOGTAG, "Add an example for gesture: " + entryName); - } if (entryName == null || entryName.length() == 0) { return; } @@ -186,11 +180,10 @@ public class GestureLibrary { * @param entryName * @return the list of gestures that is under this name */ - @SuppressWarnings("unchecked") public ArrayList<Gesture> getGestures(String entryName) { ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName); if (gestures != null) { - return (ArrayList<Gesture>)gestures.clone(); + return new ArrayList<Gesture>(gestures); } else { return null; } @@ -199,30 +192,33 @@ public class GestureLibrary { /** * Save the gesture library */ - public void save() { - if (!mChanged) - return; + public boolean save() { + if (!mChanged) { + return true; + } + + boolean result= false; + PrintWriter writer = null; try { File file = new File(mGestureFileName); if (!file.getParentFile().exists()) { - file.getParentFile().mkdirs(); - } - if (Config.DEBUG) { - Log.v(LOGTAG, "Save to " + mGestureFileName); + if (!file.getParentFile().mkdirs()) { + return false; + } } - BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream( - mGestureFileName), GestureConstants.IO_BUFFER_SIZE); - PrintWriter writer = new PrintWriter(outputStream); - XmlSerializer serializer = Xml.newSerializer(); + writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream( + mGestureFileName), GestureConstants.IO_BUFFER_SIZE)); + + final XmlSerializer serializer = Xml.newSerializer(); serializer.setOutput(writer); serializer.startDocument(Encoding.ISO_8859_1.name(), null); serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY); - HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures; - Iterator<String> it = maps.keySet().iterator(); - while (it.hasNext()) { - String key = it.next(); + + final HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures; + + for (String key : maps.keySet()) { ArrayList<Gesture> examples = maps.get(key); // save an entry serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY); @@ -235,53 +231,64 @@ public class GestureLibrary { } serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY); } + serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY); serializer.endDocument(); serializer.flush(); - writer.close(); - outputStream.close(); + mChanged = false; + result = true; } catch (IOException ex) { - Log.d(LOGTAG, "Failed to save gestures:", ex); + Log.d(LOG_TAG, "Failed to save gestures:", ex); + } finally { + GestureUtilities.closeStream(writer); } + + return result; } /** * Load the gesture library */ - public void load() { - File file = new File(mGestureFileName); + public boolean load() { + boolean result = false; + + final File file = new File(mGestureFileName); if (file.exists()) { + BufferedInputStream in = null; try { if (Config.DEBUG) { - Log.v(LOGTAG, "Load from " + mGestureFileName); + Log.v(LOG_TAG, "Load from " + mGestureFileName); } - BufferedInputStream in = new BufferedInputStream(new FileInputStream( + in = new BufferedInputStream(new FileInputStream( mGestureFileName), GestureConstants.IO_BUFFER_SIZE); Xml.parse(in, Encoding.ISO_8859_1, new CompactInkHandler()); - in.close(); + result = true; } catch (SAXException ex) { - Log.d(LOGTAG, "Failed to load gestures:", ex); + Log.d(LOG_TAG, "Failed to load gestures:", ex); } catch (IOException ex) { - Log.d(LOGTAG, "Failed to load gestures:", ex); + Log.d(LOG_TAG, "Failed to load gestures:", ex); + } finally { + GestureUtilities.closeStream(in); } } + + return result; } private class CompactInkHandler implements ContentHandler { - Gesture currentGesture = null; - - StringBuilder buffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE); + final StringBuilder mBuffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE); - String entryName; + String mEntryName; - ArrayList<Gesture> gestures; + Gesture mCurrentGesture = null; + ArrayList<Gesture> mGestures; CompactInkHandler() { } public void characters(char[] ch, int start, int length) { - buffer.append(ch, start, length); + mBuffer.append(ch, start, length); } public void endDocument() { @@ -289,16 +296,16 @@ public class GestureLibrary { public void endElement(String uri, String localName, String qName) { if (localName.equals(GestureConstants.XML_TAG_ENTRY)) { - mEntryName2gestures.put(entryName, gestures); - gestures = null; + mEntryName2gestures.put(mEntryName, mGestures); + mGestures = null; } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) { - gestures.add(currentGesture); + mGestures.add(mCurrentGesture); mClassifier.addInstance(Instance.createInstance(GestureLibrary.this, - currentGesture, entryName)); - currentGesture = null; + mCurrentGesture, mEntryName)); + mCurrentGesture = null; } else if (localName.equals(GestureConstants.XML_TAG_STROKE)) { - currentGesture.addStroke(GestureStroke.createFromString(buffer.toString())); - buffer.setLength(0); + mCurrentGesture.addStroke(GestureStroke.createFromString(mBuffer.toString())); + mBuffer.setLength(0); } } @@ -322,11 +329,11 @@ public class GestureLibrary { public void startElement(String uri, String localName, String qName, Attributes attributes) { if (localName.equals(GestureConstants.XML_TAG_ENTRY)) { - gestures = new ArrayList<Gesture>(); - entryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME); + mGestures = new ArrayList<Gesture>(); + mEntryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME); } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) { - currentGesture = new Gesture(); - currentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE, + mCurrentGesture = new Gesture(); + mCurrentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_ID))); } } diff --git a/tests/sketch/src/com/android/gesture/GestureOverlay.java b/tests/sketch/src/com/android/gesture/GestureOverlay.java index 9907831..72ab787 100755 --- a/tests/sketch/src/com/android/gesture/GestureOverlay.java +++ b/tests/sketch/src/com/android/gesture/GestureOverlay.java @@ -20,7 +20,6 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BlurMaskFilter; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; @@ -37,32 +36,32 @@ import java.util.ArrayList; */ public class GestureOverlay extends View { - static final float TOUCH_TOLERANCE = 3; - private static final int TRANSPARENT_BACKGROUND = Color.argb(0, 0, 0, 0); + // TODO: Move all these values into XML attributes + private static final int TRANSPARENT_BACKGROUND = 0x00000000; private static final float FADING_ALPHA_CHANGE = 0.03f; - private static final long FADING_REFRESHING_RATE = 100; private static final int GESTURE_STROKE_WIDTH = 12; - private static final boolean GESTURE_RENDERING_ANTIALIAS = true; - private static final BlurMaskFilter BLUR_MASK_FILTER = new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL); - private static final boolean DITHER_FLAG = true; + public static final int DEFAULT_GESTURE_COLOR = 0xFFFFFF00; + private static final int REFRESH_RANGE = 10; - public static final int DEFAULT_GESTURE_COLOR = Color.argb(255, 255, 255, 0); + private static final BlurMaskFilter BLUR_MASK_FILTER = + new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL); + // double buffering private Paint mGesturePaint; + private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG); private Bitmap mBitmap; // with transparent background - private Canvas mBitmapCanvas; // for rendering immediate ink feedback @@ -71,31 +70,25 @@ public class GestureOverlay extends View { private Path mPath; private float mX; - private float mY; private float mCurveEndX; - private float mCurveEndY; // current gesture private Gesture mCurrentGesture = null; - // gesture event handlers - ArrayList<GestureListener> mGestureListeners = new ArrayList<GestureListener>(); - + // TODO: Make this a list of WeakReferences + private final ArrayList<GestureListener> mGestureListeners = new ArrayList<GestureListener>(); private ArrayList<GesturePoint> mPointBuffer = null; // fading out effect private boolean mIsFadingOut = false; - private float mFadingAlpha = 1; private Handler mHandler = new Handler(); - private Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG); - - private Runnable mFadingOut = new Runnable() { + private final Runnable mFadingOut = new Runnable() { public void run() { if (mIsFadingOut) { mFadingAlpha -= FADING_ALPHA_CHANGE; @@ -165,13 +158,15 @@ public class GestureOverlay extends View { private void init() { mGesturePaint = new Paint(); - mGesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS); - mGesturePaint.setColor(DEFAULT_GESTURE_COLOR); - mGesturePaint.setStyle(Paint.Style.STROKE); - mGesturePaint.setStrokeJoin(Paint.Join.ROUND); - mGesturePaint.setStrokeCap(Paint.Cap.ROUND); - mGesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH); - mGesturePaint.setDither(DITHER_FLAG); + + final Paint gesturePaint = mGesturePaint; + gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS); + gesturePaint.setColor(DEFAULT_GESTURE_COLOR); + gesturePaint.setStyle(Paint.Style.STROKE); + gesturePaint.setStrokeJoin(Paint.Join.ROUND); + gesturePaint.setStrokeCap(Paint.Cap.ROUND); + gesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH); + gesturePaint.setDither(DITHER_FLAG); mPath = null; } @@ -179,14 +174,24 @@ public class GestureOverlay extends View { @Override protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { super.onSizeChanged(width, height, oldWidth, oldHeight); + if (width <= 0 || height <= 0) { return; } + int targetWidth = width > oldWidth ? width : oldWidth; int targetHeight = height > oldHeight ? height : oldHeight; + + if (mBitmap != null) mBitmap.recycle(); + mBitmap = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888); - mBitmapCanvas = new Canvas(mBitmap); + if (mBitmapCanvas != null) { + mBitmapCanvas.setBitmap(mBitmap); + } else { + mBitmapCanvas = new Canvas(mBitmap); + } mBitmapCanvas.drawColor(TRANSPARENT_BACKGROUND); + if (mCurrentGesture != null) { mCurrentGesture.draw(mBitmapCanvas, mGesturePaint); } @@ -248,7 +253,6 @@ public class GestureOverlay extends View { @Override public boolean onTouchEvent(MotionEvent event) { - if (!isEnabled()) { return true; } @@ -275,8 +279,8 @@ public class GestureOverlay extends View { private Rect touchStart(MotionEvent event) { // pass the event to handlers - ArrayList<GestureListener> listeners = mGestureListeners; - int count = listeners.size(); + final ArrayList<GestureListener> listeners = mGestureListeners; + final int count = listeners.size(); for (int i = 0; i < count; i++) { GestureListener listener = listeners.get(i); listener.onStartGesture(this, event); @@ -306,8 +310,8 @@ public class GestureOverlay extends View { mPath = new Path(); mPath.moveTo(x, y); - mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE, (int) x + REFRESH_RANGE, - (int) y + REFRESH_RANGE); + mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE, + (int) x + REFRESH_RANGE, (int) y + REFRESH_RANGE); mCurveEndX = x; mCurveEndY = y; @@ -352,11 +356,10 @@ public class GestureOverlay extends View { mPointBuffer.add(new GesturePoint(x, y, event.getEventTime())); // pass the event to handlers - ArrayList<GestureListener> listeners = mGestureListeners; - int count = listeners.size(); + final ArrayList<GestureListener> listeners = mGestureListeners; + final int count = listeners.size(); for (int i = 0; i < count; i++) { - GestureListener listener = listeners.get(i); - listener.onGesture(this, event); + listeners.get(i).onGesture(this, event); } return areaToRefresh; @@ -372,11 +375,10 @@ public class GestureOverlay extends View { mGesturePaint.setMaskFilter(null); // pass the event to handlers - ArrayList<GestureListener> listeners = mGestureListeners; - int count = listeners.size(); + final ArrayList<GestureListener> listeners = mGestureListeners; + final int count = listeners.size(); for (int i = 0; i < count; i++) { - GestureListener listener = listeners.get(i); - listener.onFinishGesture(this, event); + listeners.get(i).onFinishGesture(this, event); } mPath = null; diff --git a/tests/sketch/src/com/android/gesture/GesturePoint.java b/tests/sketch/src/com/android/gesture/GesturePoint.java index d06eff47..81e59a4 100644 --- a/tests/sketch/src/com/android/gesture/GesturePoint.java +++ b/tests/sketch/src/com/android/gesture/GesturePoint.java @@ -21,15 +21,14 @@ package com.android.gesture; */ public class GesturePoint { - public final float xpos; - - public final float ypos; + public final float x; + public final float y; public final long timestamp; public GesturePoint(float x, float y, long t) { - xpos = x; - ypos = y; + this.x = x; + this.y = y; timestamp = t; } } diff --git a/tests/sketch/src/com/android/gesture/GestureStroke.java b/tests/sketch/src/com/android/gesture/GestureStroke.java index b5e38b7..3555010 100644 --- a/tests/sketch/src/com/android/gesture/GestureStroke.java +++ b/tests/sketch/src/com/android/gesture/GestureStroke.java @@ -34,50 +34,48 @@ public class GestureStroke { public final RectF boundingBox; public final float length; - public final float[] points; private final long[] timestamps; - private Path mCachedPath; /** * Construct a gesture stroke from a list of gesture points * - * @param pts + * @param points */ - public GestureStroke(ArrayList<GesturePoint> pts) { - float[] tmpPoints = new float[pts.size() * 2]; - long[] times = new long[pts.size()]; + public GestureStroke(ArrayList<GesturePoint> points) { + final int count = points.size(); + final float[] tmpPoints = new float[count * 2]; + final long[] times = new long[count]; RectF bx = null; float len = 0; int index = 0; - int count = pts.size(); for (int i = 0; i < count; i++) { - GesturePoint p = pts.get(i); - tmpPoints[i * 2] = p.xpos; - tmpPoints[i * 2 + 1] = p.ypos; + final GesturePoint p = points.get(i); + tmpPoints[i * 2] = p.x; + tmpPoints[i * 2 + 1] = p.y; times[index] = p.timestamp; if (bx == null) { bx = new RectF(); - bx.top = p.ypos; - bx.left = p.xpos; - bx.right = p.xpos; - bx.bottom = p.ypos; + bx.top = p.y; + bx.left = p.x; + bx.right = p.x; + bx.bottom = p.y; len = 0; } else { - len += Math.sqrt(Math.pow(p.xpos - tmpPoints[(i - 1) * 2], 2) - + Math.pow(p.ypos - tmpPoints[(i -1 ) * 2 + 1], 2)); - bx.union(p.xpos, p.ypos); + len += Math.sqrt(Math.pow(p.x - tmpPoints[(i - 1) * 2], 2) + + Math.pow(p.y - tmpPoints[(i -1 ) * 2 + 1], 2)); + bx.union(p.x, p.y); } index++; } timestamps = times; - points = tmpPoints; + this.points = tmpPoints; boundingBox = bx; length = len; } @@ -89,13 +87,17 @@ public class GestureStroke { */ void draw(Canvas canvas, Paint paint) { if (mCachedPath == null) { - float[] pts = points; - int count = pts.length; + final float[] localPoints = points; + final int count = localPoints.length; + Path path = null; - float mX = 0, mY = 0; + + float mX = 0; + float mY = 0; + for (int i = 0; i < count; i += 2) { - float x = pts[i]; - float y = pts[i + 1]; + float x = localPoints[i]; + float y = localPoints[i + 1]; if (path == null) { path = new Path(); path.moveTo(x, y); @@ -127,22 +129,22 @@ public class GestureStroke { * @return the path */ public Path toPath(float width, float height, int numSample) { - float[] pts = GestureUtils.temporalSampling(this, numSample); - RectF rect = boundingBox; - float scale = height / rect.height(); - Matrix matrix = new Matrix(); + final float[] pts = GestureUtilities.temporalSampling(this, numSample); + final RectF rect = boundingBox; + final float scale = height / rect.height(); + + final Matrix matrix = new Matrix(); matrix.setTranslate(-rect.left, -rect.top); - Matrix scaleMatrix = new Matrix(); - scaleMatrix.setScale(scale, scale); - matrix.postConcat(scaleMatrix); - Matrix translate = new Matrix(); - matrix.postConcat(translate); + matrix.postScale(scale, scale); matrix.mapPoints(pts); - Path path = null; float mX = 0; float mY = 0; - int count = pts.length; + + Path path = null; + + final int count = pts.length; + for (int i = 0; i < count; i += 2) { float x = pts[i]; float y = pts[i + 1]; @@ -161,6 +163,7 @@ public class GestureStroke { } } } + return path; } @@ -184,11 +187,14 @@ public class GestureStroke { * @return the gesture stroke */ public static GestureStroke createFromString(String str) { - ArrayList<GesturePoint> points = new ArrayList<GesturePoint>( + 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) { + + while ((endIndex = + str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1)) != -1) { // parse x String token = str.substring(startIndex, endIndex); @@ -209,6 +215,7 @@ public class GestureStroke { points.add(new GesturePoint(x, y, time)); } + return new GestureStroke(points); } @@ -217,15 +224,17 @@ public class GestureStroke { */ @Override public String toString() { - StringBuilder str = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE); - float[] pts = points; - long[] times = timestamps; - int count = points.length; + final StringBuilder str = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE); + final float[] pts = points; + final long[] times = timestamps; + final int count = points.length; + for (int i = 0; i < count; i += 2) { - str.append(points[i] + GestureConstants.STRING_STROKE_DELIIMITER + points[i + 1] - + GestureConstants.STRING_STROKE_DELIIMITER + times[i / 2] - + GestureConstants.STRING_STROKE_DELIIMITER); + str.append(pts[i]).append(GestureConstants.STRING_STROKE_DELIIMITER); + str.append(pts[i + 1]).append(GestureConstants.STRING_STROKE_DELIIMITER); + str.append(times[i / 2]).append(GestureConstants.STRING_STROKE_DELIIMITER); } + return str.toString(); } diff --git a/tests/sketch/src/com/android/gesture/GestureUtils.java b/tests/sketch/src/com/android/gesture/GestureUtilities.java index 09d2625..2798616 100755 --- a/tests/sketch/src/com/android/gesture/GestureUtils.java +++ b/tests/sketch/src/com/android/gesture/GestureUtilities.java @@ -17,15 +17,37 @@ package com.android.gesture; import android.graphics.RectF; +import android.graphics.Matrix; import java.util.ArrayList; import java.util.Arrays; +import java.io.Closeable; +import java.io.IOException; -public class GestureUtils { +import static com.android.gesture.GestureConstants.*; +public final class GestureUtilities { private static final int TEMPORAL_SAMPLING_RATE = 16; - - protected static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) { + + private GestureUtilities() { + } + + /** + * Closes the specified stream. + * + * @param stream The stream to close. + */ + static void closeStream(Closeable stream) { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + android.util.Log.e(LOG_TAG, "Could not close stream", e); + } + } + } + + static float[] spatialSampling(Gesture gesture, int sampleMatrixDimension) { final float targetPatchSize = sampleMatrixDimension - 1; // edge inclusive float[] sample = new float[sampleMatrixDimension * sampleMatrixDimension]; Arrays.fill(sample, 0); @@ -120,7 +142,6 @@ public class GestureUtils { return sample; } - private static void plot(float x, float y, float[] sample, int sampleSize) { x = x < 0 ? 0 : x; y = y < 0 ? 0 : y; @@ -175,7 +196,7 @@ public class GestureUtils { * @param sampleSize * @return a float array */ - protected static float[] temporalSampling(GestureStroke stroke, int sampleSize) { + static float[] temporalSampling(GestureStroke stroke, int sampleSize) { final float increment = stroke.length / (sampleSize - 1); int vectorLength = sampleSize * 2; float[] vector = new float[vectorLength]; @@ -237,7 +258,7 @@ public class GestureUtils { * @param points * @return the centroid */ - public static float[] computeCentroid(float[] points) { + static float[] computeCentroid(float[] points) { float centerX = 0; float centerY = 0; int count = points.length; @@ -283,7 +304,7 @@ public class GestureUtils { return array; } - public static float computeTotalLength(float[] points) { + static float computeTotalLength(float[] points) { float sum = 0; int count = points.length - 4; for (int i = 0; i < count; i += 2) { @@ -294,14 +315,14 @@ public class GestureUtils { return sum; } - public static double computeStraightness(float[] points) { + static double computeStraightness(float[] points) { float totalLen = computeTotalLength(points); float dx = points[2] - points[0]; float dy = points[3] - points[1]; return Math.sqrt(dx * dx + dy * dy) / totalLen; } - public static double computeStraightness(float[] points, float totalLen) { + static double computeStraightness(float[] points, float totalLen) { float dx = points[2] - points[0]; float dy = points[3] - points[1]; return Math.sqrt(dx * dx + dy * dy) / totalLen; @@ -314,7 +335,7 @@ public class GestureUtils { * @param vector2 * @return the distance */ - protected static double squaredEuclideanDistance(float[] vector1, float[] vector2) { + static double squaredEuclideanDistance(float[] vector1, float[] vector2) { double squaredDistance = 0; int size = vector1.length; for (int i = 0; i < size; i++) { @@ -331,7 +352,7 @@ public class GestureUtils { * @param in2 * @return the distance between 0 and Math.PI */ - protected static double cosineDistance(Instance in1, Instance in2) { + static double cosineDistance(Instance in1, Instance in2) { float sum = 0; float[] vector1 = in1.vector; float[] vector2 = in2.vector; @@ -342,20 +363,19 @@ public class GestureUtils { return Math.acos(sum / (in1.magnitude * in2.magnitude)); } - public static OrientedBoundingBox computeOrientedBBX(ArrayList<GesturePoint> pts) { + public static OrientedBoundingBox computeOrientedBoundingBox(ArrayList<GesturePoint> pts) { GestureStroke stroke = new GestureStroke(pts); float[] points = temporalSampling(stroke, TEMPORAL_SAMPLING_RATE); - return computeOrientedBBX(points); + return computeOrientedBoundingBox(points); } - public static OrientedBoundingBox computeOrientedBBX(float[] points) { + public static OrientedBoundingBox computeOrientedBoundingBox(float[] points) { float[] meanVector = computeCentroid(points); - return computeOrientedBBX(points, meanVector); + return computeOrientedBoundingBox(points, meanVector); } - public static OrientedBoundingBox computeOrientedBBX(float[] points, float[] centroid) { - - android.graphics.Matrix tr = new android.graphics.Matrix(); + public static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) { + Matrix tr = new Matrix(); tr.setTranslate(-centroid[0], -centroid[1]); tr.mapPoints(points); @@ -394,9 +414,7 @@ public class GestureUtils { } } - OrientedBoundingBox bbx = new OrientedBoundingBox(angle, centroid[0], centroid[1], maxx - - minx, maxy - miny); - return bbx; + return new OrientedBoundingBox(angle, centroid[0], centroid[1], maxx - minx, maxy - miny); } private static double[] computeOrientation(double[][] covarianceMatrix) { diff --git a/tests/sketch/src/com/android/gesture/Instance.java b/tests/sketch/src/com/android/gesture/Instance.java index 4fbebf9..011d1fc 100755 --- a/tests/sketch/src/com/android/gesture/Instance.java +++ b/tests/sketch/src/com/android/gesture/Instance.java @@ -21,7 +21,6 @@ package com.android.gesture; * label is null. */ class Instance { - private static final int SEQUENCE_SAMPLE_SIZE = 16; private static final int PATCH_SAMPLE_SIZE = 8; @@ -40,10 +39,10 @@ class Instance { final float magnitude; // the id of the instance - final long instanceID; + final long id; private Instance(long id, float[] sample, String sampleName) { - instanceID = id; + this.id = id; vector = sample; label = sampleName; float sum = 0; @@ -72,14 +71,13 @@ class Instance { } private static float[] spatialSampler(Gesture gesture) { - float[] pts = GestureUtils.spatialSampling(gesture, PATCH_SAMPLE_SIZE); - return pts; + return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE); } private static float[] temporalSampler(GestureLibrary gesturelib, Gesture gesture) { - float[] pts = GestureUtils.temporalSampling(gesture.getStrokes().get(0), + float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0), SEQUENCE_SAMPLE_SIZE); - float[] center = GestureUtils.computeCentroid(pts); + float[] center = GestureUtilities.computeCentroid(pts); float orientation = (float) Math.atan2(pts[1] - center[1], pts[0] - center[0]); orientation *= 180 / Math.PI; diff --git a/tests/sketch/src/com/android/gesture/InstanceLearner.java b/tests/sketch/src/com/android/gesture/InstanceLearner.java index 95241d4..335719a 100644 --- a/tests/sketch/src/com/android/gesture/InstanceLearner.java +++ b/tests/sketch/src/com/android/gesture/InstanceLearner.java @@ -46,9 +46,9 @@ class InstanceLearner extends Learner { } double distance; if (lib.getGestureType() == GestureLibrary.SEQUENCE_SENSITIVE) { - distance = GestureUtils.cosineDistance(sample, instance); + distance = GestureUtilities.cosineDistance(sample, instance); } else { - distance = GestureUtils.squaredEuclideanDistance(sample.vector, instance.vector); + distance = GestureUtilities.squaredEuclideanDistance(sample.vector, instance.vector); } double weight; if (distance == 0) { diff --git a/tests/sketch/src/com/android/gesture/Learner.java b/tests/sketch/src/com/android/gesture/Learner.java index 63f3156..b4183d2 100755 --- a/tests/sketch/src/com/android/gesture/Learner.java +++ b/tests/sketch/src/com/android/gesture/Learner.java @@ -22,7 +22,6 @@ import java.util.ArrayList; * The abstract class of a gesture learner */ abstract class Learner { - private final ArrayList<Instance> mInstances = new ArrayList<Instance>(); /** @@ -53,7 +52,7 @@ abstract class Learner { int count = instances.size(); for (int i = 0; i < count; i++) { Instance instance = instances.get(i); - if (id == instance.instanceID) { + if (id == instance.id) { instances.remove(instance); return; } @@ -66,16 +65,18 @@ abstract class Learner { * @param name the category name */ void removeInstances(String name) { - ArrayList<Instance> toDelete = new ArrayList<Instance>(); - ArrayList<Instance> instances = mInstances; - int count = instances.size(); + final ArrayList<Instance> toDelete = new ArrayList<Instance>(); + final ArrayList<Instance> instances = mInstances; + final int count = instances.size(); + for (int i = 0; i < count; i++) { - Instance instance = instances.get(i); - if (instance.label.equals(name)) { + final Instance instance = instances.get(i); + // the label can be null, as specified in Instance + if ((instance.label == null && name == null) || instance.label.equals(name)) { toDelete.add(instance); } } - mInstances.removeAll(toDelete); + instances.removeAll(toDelete); } abstract ArrayList<Prediction> classify(GestureLibrary library, Instance instance); diff --git a/tests/sketch/src/com/android/gesture/LetterRecognizer.java b/tests/sketch/src/com/android/gesture/LetterRecognizer.java index 1c15c7d..73151de 100644 --- a/tests/sketch/src/com/android/gesture/LetterRecognizer.java +++ b/tests/sketch/src/com/android/gesture/LetterRecognizer.java @@ -20,45 +20,44 @@ import android.content.Context; import android.content.res.Resources; import android.util.Log; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.IOException; +import java.io.DataInputStream; +import java.io.BufferedInputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class LetterRecognizer { + private static final String LOG_TAG = "LetterRecognizer"; - private static final String LOGTAG = "LetterRecognizer"; - - public final static int LATTIN_LOWERCASE = 0; + public final static int LATIN_LOWERCASE = 0; private SigmoidUnit[] mHiddenLayer; - private SigmoidUnit[] mOutputLayer; private final String[] mClasses; private final int mInputCount; - private class SigmoidUnit { - - private float[] mWeights; + private static class SigmoidUnit { + final float[] mWeights; - private SigmoidUnit(float[] weights) { + SigmoidUnit(float[] weights) { mWeights = weights; } private float compute(float[] inputs) { float sum = 0; - int count = inputs.length; - float[] weights = mWeights; + + final int count = inputs.length; + final float[] weights = mWeights; + for (int i = 0; i < count; i++) { sum += inputs[i] * weights[i]; } sum += weights[weights.length - 1]; - return 1 / (float)(1 + Math.exp(-sum)); + + return 1.0f / (float) (1 + Math.exp(-sum)); } } @@ -71,33 +70,35 @@ public class LetterRecognizer { public static LetterRecognizer getLetterRecognizer(Context context, int type) { switch (type) { - case LATTIN_LOWERCASE: { - return createFromResource(context, com.android.internal.R.raw.lattin_lowercase); + case LATIN_LOWERCASE: { + return createFromResource(context, com.android.internal.R.raw.latin_lowercase); } } return null; } public ArrayList<Prediction> recognize(Gesture gesture) { - return this.classify(GestureUtils.spatialSampling(gesture, mInputCount)); + return classify(GestureUtilities.spatialSampling(gesture, mInputCount)); } private ArrayList<Prediction> classify(float[] vector) { - float[] intermediateOutput = compute(mHiddenLayer, vector); - float[] output = compute(mOutputLayer, intermediateOutput); - ArrayList<Prediction> predictions = new ArrayList<Prediction>(); + final float[] intermediateOutput = compute(mHiddenLayer, vector); + final float[] output = compute(mOutputLayer, intermediateOutput); + final ArrayList<Prediction> predictions = new ArrayList<Prediction>(); + double sum = 0; - int count = mClasses.length; + + final String[] classes = mClasses; + final int count = classes.length; + for (int i = 0; i < count; i++) { - String name = mClasses[i]; double score = output[i]; sum += score; - predictions.add(new Prediction(name, score)); + predictions.add(new Prediction(classes[i], score)); } for (int i = 0; i < count; i++) { - Prediction name = predictions.get(i); - name.score /= sum; + predictions.get(i).score /= sum; } Collections.sort(predictions, new Comparator<Prediction>() { @@ -117,82 +118,63 @@ public class LetterRecognizer { } private float[] compute(SigmoidUnit[] layer, float[] input) { - float[] output = new float[layer.length]; - int count = layer.length; + final float[] output = new float[layer.length]; + final int count = layer.length; + for (int i = 0; i < count; i++) { output[i] = layer[i].compute(input); } + return output; } private static LetterRecognizer createFromResource(Context context, int resourceID) { - Resources resources = context.getResources(); - InputStream stream = resources.openRawResource(resourceID); + final Resources resources = context.getResources(); + + DataInputStream in = null; + LetterRecognizer classifier = null; + try { - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - - String line = reader.readLine(); - int startIndex = 0; - int endIndex = -1; - endIndex = line.indexOf(" ", startIndex); - int iCount = Integer.parseInt(line.substring(startIndex, endIndex)); - - startIndex = endIndex + 1; - endIndex = line.indexOf(" ", startIndex); - int hCount = Integer.parseInt(line.substring(startIndex, endIndex)); - - startIndex = endIndex + 1; - endIndex = line.length(); - int oCount = Integer.parseInt(line.substring(startIndex, endIndex)); - - String[] classes = new String[oCount]; - line = reader.readLine(); - startIndex = 0; - endIndex = -1; - for (int i = 0; i < oCount; i++) { - endIndex = line.indexOf(" ", startIndex); - classes[i] = line.substring(startIndex, endIndex); - startIndex = endIndex + 1; + in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID))); + + final int iCount = in.readInt(); + final int hCount = in.readInt(); + final int oCount = in.readInt(); + + final String[] classes = new String[oCount]; + for (int i = 0; i < classes.length; i++) { + classes[i] = in.readUTF(); } - LetterRecognizer classifier = new LetterRecognizer(iCount, hCount, classes); + classifier = new LetterRecognizer(iCount, hCount, classes); SigmoidUnit[] hiddenLayer = new SigmoidUnit[hCount]; SigmoidUnit[] outputLayer = new SigmoidUnit[oCount]; for (int i = 0; i < hCount; i++) { float[] weights = new float[iCount]; - line = reader.readLine(); - startIndex = 0; for (int j = 0; j < iCount; j++) { - endIndex = line.indexOf(" ", startIndex); - weights[j] = Float.parseFloat(line.substring(startIndex, endIndex)); - startIndex = endIndex + 1; + weights[j] = in.readFloat(); } - hiddenLayer[i] = classifier.new SigmoidUnit(weights); + hiddenLayer[i] = new SigmoidUnit(weights); } for (int i = 0; i < oCount; i++) { float[] weights = new float[hCount]; - line = reader.readLine(); - startIndex = 0; for (int j = 0; j < hCount; j++) { - endIndex = line.indexOf(" ", startIndex); - weights[j] = Float.parseFloat(line.substring(startIndex, endIndex)); - startIndex = endIndex + 1; + weights[j] = in.readFloat(); } - outputLayer[i] = classifier.new SigmoidUnit(weights); + outputLayer[i] = new SigmoidUnit(weights); } - reader.close(); - classifier.mHiddenLayer = hiddenLayer; classifier.mOutputLayer = outputLayer; - return classifier; - - } catch (IOException ex) { - Log.d(LOGTAG, "Failed to save gestures:", ex); + } catch (IOException e) { + Log.d(LOG_TAG, "Failed to load gestures:", e); + } finally { + GestureUtilities.closeStream(in); } - return null; + + return classifier; } } diff --git a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java b/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java index 90c3969..a07d125 100644 --- a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java +++ b/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java @@ -23,7 +23,6 @@ import android.graphics.Path; * An oriented bounding box */ public class OrientedBoundingBox { - public final float squareness; public final float width; diff --git a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java index 0ffc370..7fc7e28 100644 --- a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java +++ b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java @@ -30,15 +30,11 @@ import java.util.ArrayList; */ public class TouchThroughGesturing implements GestureListener { - public static final int SINGLE_STROKE = 0; - public static final int MULTIPLE_STROKE = 1; private static final float STROKE_LENGTH_THRESHOLD = 30; - private static final float SQUARENESS_THRESHOLD = 0.275f; - private static final float ANGLE_THRESHOLD = 40; public static final int DEFAULT_UNCERTAIN_GESTURE_COLOR = Color.argb(60, 255, 255, 0); @@ -47,15 +43,18 @@ public class TouchThroughGesturing implements GestureListener { private float mTotalLength; - private float mX, mY; + private float mX; + private float mY; + // TODO: Use WeakReference? private View mModel; private int mGestureType = SINGLE_STROKE; - private int mUncertainGestureColor = DEFAULT_UNCERTAIN_GESTURE_COLOR; - private ArrayList<GestureActionListener> mActionListeners = new ArrayList<GestureActionListener>(); + // TODO: Use WeakReferences + private final ArrayList<GestureActionListener> mActionListeners = + new ArrayList<GestureActionListener>(); public TouchThroughGesturing(View model) { mModel = model; @@ -77,14 +76,17 @@ public class TouchThroughGesturing implements GestureListener { if (mGestureType == MULTIPLE_STROKE) { overlay.cancelFadingOut(); } + mX = event.getX(); mY = event.getY(); mTotalLength = 0; mIsGesturing = false; + if (mGestureType == SINGLE_STROKE || overlay.getCurrentGesture() == null || overlay.getCurrentGesture().getStrokesCount() == 0) { overlay.setGestureColor(mUncertainGestureColor); } + mModel.dispatchTouchEvent(event); } @@ -92,40 +94,45 @@ public class TouchThroughGesturing implements GestureListener { if (mIsGesturing) { return; } - float x = event.getX(); - float y = event.getY(); - float dx = x - mX; - float dy = y - mY; + + final float x = event.getX(); + final float y = event.getY(); + final float dx = x - mX; + final float dy = y - mY; + mTotalLength += (float)Math.sqrt(dx * dx + dy * dy); mX = x; mY = y; if (mTotalLength > STROKE_LENGTH_THRESHOLD) { - OrientedBoundingBox bbx = GestureUtils.computeOrientedBBX(overlay.getCurrentStroke()); - float angle = Math.abs(bbx.orientation); + final OrientedBoundingBox box = + GestureUtilities.computeOrientedBoundingBox(overlay.getCurrentStroke()); + float angle = Math.abs(box.orientation); if (angle > 90) { angle = 180 - angle; } - if (bbx.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) { + if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) { mIsGesturing = true; overlay.setGestureColor(GestureOverlay.DEFAULT_GESTURE_COLOR); event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(), - MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(), event - .getMetaState(), event.getXPrecision(), event.getYPrecision(), + MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(), + event.getMetaState(), event.getXPrecision(), event.getYPrecision(), event.getDeviceId(), event.getEdgeFlags()); } } + mModel.dispatchTouchEvent(event); } public void onFinishGesture(GestureOverlay overlay, MotionEvent event) { if (mIsGesturing) { overlay.clear(true); - ArrayList<GestureActionListener> listeners = mActionListeners; - int count = listeners.size(); + + final ArrayList<GestureActionListener> listeners = mActionListeners; + final int count = listeners.size(); + for (int i = 0; i < count; i++) { - GestureActionListener listener = listeners.get(i); - listener.onGesturePerformed(overlay, overlay.getCurrentGesture()); + listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture()); } } else { mModel.dispatchTouchEvent(event); diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java index 1d3fdf3..fc26757 100644 --- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java +++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java @@ -69,7 +69,7 @@ public class ContactListGestureOverlay extends Activity { setProgressBarIndeterminateVisibility(true); // create a letter recognizer - mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATTIN_LOWERCASE); + mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATIN_LOWERCASE); // load the contact list mContactList = (ListView) findViewById(R.id.list); diff --git a/tests/sketch/tools/Converter.java b/tests/sketch/tools/Converter.java new file mode 100644 index 0000000..b4654f8 --- /dev/null +++ b/tests/sketch/tools/Converter.java @@ -0,0 +1,222 @@ +import java.io.File; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Closeable; +import java.io.DataOutputStream; +import java.io.FileOutputStream; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.BufferedInputStream; + +/** + * Converts text-based letter stores to binary-based stores. + */ +public class Converter { + private final File mFile; + + Converter(File file) { + mFile = file; + } + + private void convert() { + boolean read = false; + + String[] classes = null; + int iCount = 0; + int hCount = 0; + int oCount = 0; + float[][] iWeights = null; + float[][] oWeights = null; + + BufferedReader reader = null; + + try { + reader = new BufferedReader(new FileReader(mFile)); + + long start = System.nanoTime(); + + String line = reader.readLine(); + int startIndex = 0; + int endIndex; + endIndex = line.indexOf(" ", startIndex); + iCount = Integer.parseInt(line.substring(startIndex, endIndex)); + + startIndex = endIndex + 1; + endIndex = line.indexOf(" ", startIndex); + hCount = Integer.parseInt(line.substring(startIndex, endIndex)); + + startIndex = endIndex + 1; + endIndex = line.length(); + oCount = Integer.parseInt(line.substring(startIndex, endIndex)); + + classes = new String[oCount]; + line = reader.readLine(); + startIndex = 0; + + for (int i = 0; i < oCount; i++) { + endIndex = line.indexOf(" ", startIndex); + classes[i] = line.substring(startIndex, endIndex); + startIndex = endIndex + 1; + } + + iWeights = new float[hCount][]; + for (int i = 0; i < hCount; i++) { + iWeights[i] = new float[iCount]; + line = reader.readLine(); + startIndex = 0; + for (int j = 0; j < iCount; j++) { + endIndex = line.indexOf(" ", startIndex); + iWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex)); + startIndex = endIndex + 1; + } + } + + oWeights = new float[oCount][]; + for (int i = 0; i < oCount; i++) { + oWeights[i] = new float[hCount]; + line = reader.readLine(); + startIndex = 0; + for (int j = 0; j < hCount; j++) { + endIndex = line.indexOf(" ", startIndex); + oWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex)); + startIndex = endIndex + 1; + } + } + + long end = System.nanoTime(); + System.out.println("time to read text file = " + + ((end - start) / 1000.0f / 1000.0f) + " ms"); + + read = true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + close(reader); + } + + if (read) { + boolean wrote = false; + DataOutputStream out = null; + + try { + out = new DataOutputStream(new FileOutputStream(mFile)); + + out.writeInt(iCount); + out.writeInt(hCount); + out.writeInt(oCount); + + for (String aClass : classes) { + out.writeUTF(aClass); + } + + for (float[] weights : iWeights) { + for (float weight : weights) { + out.writeFloat(weight); + } + } + + for (float[] weights : oWeights) { + for (float weight : weights) { + out.writeFloat(weight); + } + } + + out.flush(); + + wrote = true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + close(out); + } + + if (wrote) { + DataInputStream in = null; + + try { + in = new DataInputStream(new BufferedInputStream(new FileInputStream(mFile))); + + long start = System.nanoTime(); + + iCount = in.readInt(); + hCount = in.readInt(); + oCount = in.readInt(); + + classes = new String[oCount]; + for (int i = 0; i < classes.length; i++) { + classes[i] = in.readUTF(); + } + + iWeights = new float[hCount][]; + for (int i = 0; i < iWeights.length; i++) { + iWeights[i] = new float[iCount]; + for (int j = 0; j < iCount; j++) { + iWeights[i][j] = in.readFloat(); + } + } + + oWeights = new float[oCount][]; + for (int i = 0; i < oWeights.length; i++) { + oWeights[i] = new float[hCount]; + for (int j = 0; j < hCount; j++) { + oWeights[i][j] = in.readFloat(); + } + } + + long end = System.nanoTime(); + System.out.println("time to read binary file = " + + ((end - start) / 1000.0f / 1000.0f) + " ms"); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + close(in); + } + } + } + } + + private static void close(Closeable reader) { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + String fileName = args[0]; + if (fileName != null) { + File file = new File(fileName); + if (!file.exists()) { + printHelp(fileName); + } else { + new Converter(file).convert(); + } + } else { + printHelp(null); + } + } + + private static void printHelp(String name) { + if (name == null) { + System.out.println("You must specify the name of the file to convert:"); + } else { + System.out.println("The specified file does not exist: " + name); + } + System.out.println("java Converter [filename]"); + System.out.println(""); + System.out.println("\t[filename]\tPath to the file to convert. The file is replaced by " + + "the conversion result."); + } +}
\ No newline at end of file |