From 5a836f74df027bb568da17fbde4e641b6a56d2a9 Mon Sep 17 00:00:00 2001
From: ztenghui <ztenghui@google.com>
Date: Mon, 21 Jul 2014 15:59:06 -0700
Subject: Add negative sign separation support in the pathData

bug:14585171

Change-Id: I61dec27856be09c44bb1d32ff61b3c3cd458cc34
---
 core/java/android/util/PathParser.java             | 93 +++++++++++++++-------
 .../android/graphics/drawable/VectorDrawable.java  |  4 +-
 tests/VectorDrawableTest/AndroidManifest.xml       |  2 +-
 .../res/drawable/vector_drawable01.xml             |  2 +-
 .../res/drawable/vector_drawable03.xml             | 28 +++----
 .../res/drawable/vector_drawable04.xml             | 32 ++++----
 .../res/drawable/vector_drawable05.xml             | 24 +++---
 .../res/drawable/vector_drawable07.xml             |  6 +-
 .../res/drawable/vector_drawable09.xml             |  2 +-
 .../res/drawable/vector_drawable10.xml             |  8 +-
 .../res/drawable/vector_drawable_favorite.xml      |  4 +-
 11 files changed, 121 insertions(+), 84 deletions(-)

diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java
index f4a0448..c36421d 100644
--- a/core/java/android/util/PathParser.java
+++ b/core/java/android/util/PathParser.java
@@ -54,9 +54,11 @@ public class PathParser {
         ArrayList<PathDataNode> list = new ArrayList<PathDataNode>();
         while (end < pathData.length()) {
             end = nextStart(pathData, end);
-            String s = pathData.substring(start, end);
-            float[] val = getFloats(s);
-            addNode(list, s.charAt(0), val);
+            String s = pathData.substring(start, end).trim();
+            if (s.length() > 0) {
+                float[] val = getFloats(s);
+                addNode(list, s.charAt(0), val);
+            }
 
             start = end;
             end++;
@@ -135,6 +137,12 @@ public class PathParser {
         list.add(new PathDataNode(cmd, val));
     }
 
+    private static class ExtractFloatResult {
+        // We need to return the position of the next separator and whether the
+        // next float starts with a '-'.
+        int mEndPosition;
+        boolean mEndWithNegSign;
+    }
 
     /**
      * Parse the floats in the string.
@@ -148,42 +156,73 @@ public class PathParser {
             return new float[0];
         }
         try {
-            float[] tmp = new float[s.length()];
+            float[] results = new float[s.length()];
             int count = 0;
-            int pos = 1, end;
-            while ((end = extract(s, pos)) >= 0) {
-                if (pos < end) {
-                    tmp[count++] = Float.parseFloat(s.substring(pos, end));
+            int startPosition = 1;
+            int endPosition = 0;
+
+            ExtractFloatResult result = new ExtractFloatResult();
+            int totalLength = s.length();
+
+            // The startPosition should always be the first character of the
+            // current number, and endPosition is the character after the current
+            // number.
+            while (startPosition < totalLength) {
+                extract(s, startPosition, result);
+                endPosition = result.mEndPosition;
+
+                if (startPosition < endPosition) {
+                    results[count++] = Float.parseFloat(
+                            s.substring(startPosition, endPosition));
+                }
+
+                if (result.mEndWithNegSign) {
+                    // Keep the '-' sign with next number.
+                    startPosition = endPosition;
+                } else {
+                    startPosition = endPosition + 1;
                 }
-                pos = end + 1;
-            }
-            // handle the final float if there is one
-            if (pos < s.length()) {
-                tmp[count++] = Float.parseFloat(s.substring(pos, s.length()));
             }
-            return Arrays.copyOf(tmp, count);
-        } catch (NumberFormatException e){
-            Log.e(LOGTAG,"error in parsing \""+s+"\"");
+            return Arrays.copyOf(results, count);
+        } catch (NumberFormatException e) {
+            Log.e(LOGTAG, "error in parsing \"" + s + "\"");
             throw e;
         }
     }
 
     /**
-     * Calculate the position of the next comma or space
+     * Calculate the position of the next comma or space or negative sign
      * @param s the string to search
      * @param start the position to start searching
-     * @return the position of the next comma or space or -1 if none found
+     * @param result the result of the extraction, including the position of the
+     * the starting position of next number, whether it is ending with a '-'.
      */
-    private static int extract(String s, int start) {
-        int space = s.indexOf(' ', start);
-        int comma = s.indexOf(',', start);
-        if (space == -1) {
-            return comma;
-        }
-        if (comma == -1) {
-            return space;
+    private static void extract(String s, int start, ExtractFloatResult result) {
+        // Now looking for ' ', ',' or '-' from the start.
+        int currentIndex = start;
+        boolean foundSeparator = false;
+        result.mEndWithNegSign = false;
+        for (; currentIndex < s.length(); currentIndex++) {
+            char currentChar = s.charAt(currentIndex);
+            switch (currentChar) {
+                case ' ':
+                case ',':
+                    foundSeparator = true;
+                    break;
+                case '-':
+                    if (currentIndex != start) {
+                        foundSeparator = true;
+                        result.mEndWithNegSign = true;
+                    }
+                    break;
+            }
+            if (foundSeparator) {
+                break;
+            }
         }
-        return (comma > space) ? space : comma;
+        // When there is nothing found, then we put the end position to the end
+        // of the string.
+        result.mEndPosition = currentIndex;
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 13ef89b..8ed6776d 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -740,9 +740,7 @@ public class VectorDrawable extends Drawable {
             final float minScale = Math.min(scaleX, scaleY);
 
             mFinalPathMatrix.set(vGroup.mStackedMatrix);
-            mFinalPathMatrix.postScale(scaleX, scaleY, mViewportWidth / 2f, mViewportHeight / 2f);
-            mFinalPathMatrix.postTranslate(
-                    w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f);
+            mFinalPathMatrix.postScale(scaleX, scaleY);
 
             vPath.toPath(mPath);
             final Path path = mPath;
diff --git a/tests/VectorDrawableTest/AndroidManifest.xml b/tests/VectorDrawableTest/AndroidManifest.xml
index a16b749..ee62e5e 100644
--- a/tests/VectorDrawableTest/AndroidManifest.xml
+++ b/tests/VectorDrawableTest/AndroidManifest.xml
@@ -100,7 +100,7 @@
         </activity>
         <activity
             android:name="VectorDrawableStaticPerf"
-            android:label="Performance of vector images" >
+            android:label="System icons" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml
index 66a9452..3b01e02 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable01.xml
@@ -26,7 +26,7 @@
     <group>
         <path
             android:name="box1"
-            android:pathData="m20,200l100,90l180,-180l-35,-35l-145,145l-60,-60l-40,40z"
+            android:pathData="m20,200l100,90l180-180l-35-35l-145,145l-60-60l-40,40z"
             android:fill="?android:attr/colorControlActivated"
             android:stroke="?android:attr/colorControlActivated"
             android:strokeLineCap="round"
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml
index 2fdb676..cd2fd47 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable03.xml
@@ -35,16 +35,16 @@
                 M 0, 6.125
                 l 7.3, 0
                 l 0, 12.25
-                l -7.3, 0
+                l-7.3, 0
                 z" />
     </group>
     <group>
         <path
             android:name="one"
             android:fill="#ff88ff"
-            android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
-                l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
-                l -5.046875,0.0 0.0,-1.0Z" />
+            android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125
+                l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+                l-5.046875,0.0 0.0-1.0Z" />
     </group>
     <group
         android:pivotX="3.65"
@@ -57,22 +57,22 @@
                 M 0, 0
                 l 7.3, 0
                 l 0, 6.125
-                l -7.3, 0
+                l-7.3, 0
                 z" />
     </group>
     <group>
         <path
             android:name="two"
             android:fill="#ff88ff"
-            android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
-                        q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
-                        q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
-                        q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
-                        q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
-                        q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
-                        q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
-                        q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
-                        q -0.78125024,0.8125 -2.2187502,2.265625Z" />
+            android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
+                        q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
+                        q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625
+                        q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875
+                        q-0.609375,0.1875-1.3125,0.59375l 0.0-1.203125q 0.71875-0.28125 1.328125-0.421875
+                        q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875
+                        q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625
+                        q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375
+                        q-0.78125024,0.8125-2.2187502,2.265625Z" />
     </group>
 
 </vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml
index 296e026..d57ae8b 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml
@@ -28,41 +28,41 @@
                 android:name="clip1"
                 android:pathData="
                 M 3.65, 6.125
-                m -.001, 0
+                m-.001, 0
                 a .001,.001 0 1,0 .002,0
-                a .001,.001 0 1,0 -.002,0z"
+                a .001,.001 0 1,0-.002,0z"
                 android:clipToPath="true"
                 android:fill="#112233"
                 />
 
         <path
                 android:name="one"
-                android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
-                l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
-                l -5.046875,0.0 0.0,-1.0Z"
+                android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125
+                l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+                l-5.046875,0.0 0.0-1.0Z"
                 android:fill="#ff88ff"
                 />
         <path
                 android:name="clip2"
                 android:pathData="
                 M 3.65, 6.125
-                m -6, 0
+                m-6, 0
                 a 6,6 0 1,0 12,0
-                a 6,6 0 1,0 -12,0z"
+                a 6,6 0 1,0-12,0z"
                 android:clipToPath="true"
                 android:fill="#112233"
                 />
         <path
                 android:name="two"
-                android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
-                        q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
-                        q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
-                        q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
-                        q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
-                        q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
-                        q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
-                        q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
-                        q -0.78125024,0.8125 -2.2187502,2.265625Z"
+                android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
+                        q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
+                        q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625
+                        q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875
+                        q-0.609375,0.1875-1.3125,0.59375l 0.0-1.203125q 0.71875-0.28125 1.328125-0.421875
+                        q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875
+                        q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625
+                        q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375
+                        q-0.78125024,0.8125-2.2187502,2.265625Z"
                 android:fill="#ff88ff"
                 />
     </group>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml
index 1633326..673c465 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml
@@ -28,21 +28,21 @@
         <path
             android:name="one"
             android:fill="#ffff00"
-            android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0,-6.671875 -2.109375,0.421875 0.0,-1.078125
-                l 2.09375,-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
-                l -5.046875,0.0 0.0,-1.0Z" />
+            android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125
+                l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
+                l-5.046875,0.0 0.0-1.0Z" />
         <path
             android:name="two"
             android:fill="#ffff00"
             android:fillOpacity="0"
-            android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0,-1.0q 0.671875,-0.6875 1.828125,-1.859375
-                        q 1.1718752,-1.1875 1.4687502,-1.53125 0.578125,-0.625 0.796875,-1.0625
-                        q 0.234375,-0.453125 0.234375,-0.875 0.0,-0.703125 -0.5,-1.140625
-                        q -0.484375,-0.4375 -1.2656252,-0.4375 -0.5625,0.0 -1.1875,0.1875
-                        q -0.609375,0.1875 -1.3125,0.59375l 0.0,-1.203125q 0.71875,-0.28125 1.328125,-0.421875
-                        q 0.625,-0.15625 1.140625,-0.15625 1.3593752,0.0 2.1718752,0.6875
-                        q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
-                        q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
-                        q -0.78125024,0.8125 -2.2187502,2.265625Z" />
+            android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
+                        q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
+                        q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625
+                        q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875
+                        q-0.609375,0.1875-1.3125,0.59375l 0.0-1.203125q 0.71875-0.28125 1.328125-0.421875
+                        q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875
+                        q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625
+                        q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375
+                        q-0.78125024,0.8125-2.2187502,2.265625Z" />
     </group>
 </vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable07.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable07.xml
index 7c7e679..ccb0df0 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable07.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable07.xml
@@ -23,9 +23,9 @@
     <group>
         <path
                 android:name="back"
-                android:pathData="M 20,55 l 35.3,-35.3 7.07,7.07 -35.3,35.3 z
-              M 27,50 l 97,0 0,10 -97,0 z
-              M 20,55 l 7.07,-7.07 35.3,35.3 -7.07,7.07 z"
+                android:pathData="M 20,55 l 35.3-35.3 7.07,7.07-35.3,35.3 z
+              M 27,50 l 97,0 0,10-97,0 z
+              M 20,55 l 7.07-7.07 35.3,35.3-7.07,7.07 z"
                 android:fill="#ffffffff"
                 />
     </group>
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml
index c93c85f..77434fc 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable09.xml
@@ -30,7 +30,7 @@
         <path
             android:name="house"
             android:fill="#ffffffff"
-            android:pathData="M 100,20 l 0,0 0,140 -80,0 z M 100,20 l 0,0 80,140 -80,0 z"/>
+            android:pathData="M 100,20 l 0,0 0,140-80,0 z M 100,20 l 0,0 80,140-80,0 z"/>
     </group>
 
 </vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable10.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable10.xml
index 8484e9e..df24713 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable10.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable10.xml
@@ -28,19 +28,19 @@
         <path
             android:name="bar3"
             android:fill="#FFFFFFFF"
-            android:pathData="M49.001,60c-5.466,0 -9.899,4.478 -9.899,10s4.434,10,9.899,10c5.468,0,9.899 -4.478,9.899 -10S54.469,60,49.001,60z" />
+            android:pathData="M49.001,60c-5.466,0-9.899,4.478-9.899,10s4.434,10,9.899,10c5.468,0,9.899-4.478,9.899-10S54.469,60,49.001,60z" />
         <path
             android:name="bar2"
             android:fill="#FFFFFFFF"
-            android:pathData="M28.001,48.787l7,7.07c7.731 -7.811,20.269 -7.81,28.001,0l6.999 -7.07C58.403,37.071,39.599,37.071,28.001,48.787z" />
+            android:pathData="M28.001,48.787l7,7.07c7.731-7.811,20.269-7.81,28.001,0l6.999-7.07C58.403,37.071,39.599,37.071,28.001,48.787z" />
         <path
             android:name="bar1"
             android:fill="#FF555555"
-            android:pathData="M14.001,34.645   L21,41.716c15.464 -15.621,40.536 -15.621,56,0l7.001 -7.071C64.672,15.119,33.33,15.119,14.001,34.645z" />
+            android:pathData="M14.001,34.645   L21,41.716c15.464-15.621,40.536-15.621,56,0l7.001-7.071C64.672,15.119,33.33,15.119,14.001,34.645z" />
         <path
             android:name="bar0"
             android:fill="#FF555555"
-            android:pathData="M0,20.502l6.999,7.071   c23.196 -23.431,60.806 -23.431,84.002,0L98,20.503C70.938 -6.834,27.063 -6.834,0,20.502z" />
+            android:pathData="M0,20.502l6.999,7.071   c23.196-23.431,60.806-23.431,84.002,0L98,20.503C70.938-6.834,27.063-6.834,0,20.502z" />
     </group>
 
 </vector>
\ No newline at end of file
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
index c8840f5..5a66e2d 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable_favorite.xml
@@ -32,11 +32,11 @@
             android:fill="#ff000000"
             android:pathData="M2.100006104,-6
                 C0.1449127197,-6,1.600006104,-5.975006104,0,-5.975006104
-                C-1.574996948,-5.975006104,0.00309753418,-6,-1.949996948,-6
+                C-1.574996948,-5.975006104,0.00309753418,-6-1.949996948-6
                 C-4.492996216,-6,-5.949996948,-3.718399048,-5.949996948,-1.149993896
                 C-5.949996948,2.379302979,-5.699996948,5.100006104,0,5.100006104
                 C5.699996948,5.100006104,6,2.379302979,6,-1.149993896
-                C6,-3.718399048,4.643005371,-6,2.100006104,-6" />
+                C6,-3.718399048,4.643005371-6,2.100006104-6" />
     </group>
 
 </vector>
\ No newline at end of file
-- 
cgit v1.1