VectorDrawable.java revision 2e17d2b232e11b3ec246c704d8c4707c8fd863fa
1abb7d134c02ac60091108c491dafb00877093170John Hoford/*
2abb7d134c02ac60091108c491dafb00877093170John Hoford * Copyright (C) 2014 The Android Open Source Project
3abb7d134c02ac60091108c491dafb00877093170John Hoford *
4abb7d134c02ac60091108c491dafb00877093170John Hoford * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5abb7d134c02ac60091108c491dafb00877093170John Hoford * in compliance with the License. You may obtain a copy of the License at
6abb7d134c02ac60091108c491dafb00877093170John Hoford *
7abb7d134c02ac60091108c491dafb00877093170John Hoford * http://www.apache.org/licenses/LICENSE-2.0
8abb7d134c02ac60091108c491dafb00877093170John Hoford *
9abb7d134c02ac60091108c491dafb00877093170John Hoford * Unless required by applicable law or agreed to in writing, software distributed under the License
10abb7d134c02ac60091108c491dafb00877093170John Hoford * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11abb7d134c02ac60091108c491dafb00877093170John Hoford * or implied. See the License for the specific language governing permissions and limitations under
12abb7d134c02ac60091108c491dafb00877093170John Hoford * the License.
13abb7d134c02ac60091108c491dafb00877093170John Hoford */
14abb7d134c02ac60091108c491dafb00877093170John Hoford
15abb7d134c02ac60091108c491dafb00877093170John Hofordpackage android.graphics.drawable;
16abb7d134c02ac60091108c491dafb00877093170John Hoford
17b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList;
18abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources;
19abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources.Theme;
204b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viveretteimport android.content.res.TypedArray;
21482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghuiimport android.graphics.Bitmap;
22abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Canvas;
232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghuiimport android.graphics.Color;
24abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.ColorFilter;
25abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Matrix;
26abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Paint;
27abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Path;
28abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PathMeasure;
29abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PixelFormat;
30b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuffColorFilter;
31abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Rect;
32abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Region;
33b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode;
34e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.ArrayMap;
35abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.AttributeSet;
36738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghuiimport android.util.LayoutDirection;
37abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.Log;
38cf4832f69c8786b098ce18c24319021f8cd6733aztenghuiimport android.util.PathParser;
394b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport android.util.Xml;
40abb7d134c02ac60091108c491dafb00877093170John Hoford
41abb7d134c02ac60091108c491dafb00877093170John Hofordimport com.android.internal.R;
42abb7d134c02ac60091108c491dafb00877093170John Hoford
43abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParser;
44abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParserException;
454b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport org.xmlpull.v1.XmlPullParserFactory;
46abb7d134c02ac60091108c491dafb00877093170John Hoford
47abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException;
48abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList;
494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack;
504b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
51abb7d134c02ac60091108c491dafb00877093170John Hoford/**
526beeb75723cec42603b47664bce794a2b97d7bacChet Haase * This lets you create a drawable based on an XML vector graphic. It can be
53d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code>&lt;vector></code> element.
54abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/>
5546e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * The vector drawable has the following elements:
56abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/>
57177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code>&lt;vector></code></dt>
58a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl>
59a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined a vector drawable
60a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl>
61a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:width</code></dt>
62a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic width of the drawable.
63a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd>
64a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:height</code></dt>
65a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic height the drawable.
66a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd>
67a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportWidth</code></dt>
68a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the width of the viewport space. Viewport is basically
69a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd>
70a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportHeight</code></dt>
71a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the height of the viewport space. Viewport is basically
72a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd>
73a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tint</code></dt>
74a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd>
75a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tintMode</code></dt>
76a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd>
77a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:autoMirrored</code></dt>
78a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Indicates if the drawable needs to be mirrored when its layout direction is
79a95c8abb366d9c39450513335f550b56da13b30aztenghui * RTL (right-to-left).</dd>
80a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd>
81a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl>
82a95c8abb366d9c39450513335f550b56da13b30aztenghui *
83a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl>
846d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code>&lt;group></code></dt>
85452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information.
86452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport.
87a95c8abb366d9c39450513335f550b56da13b30aztenghui * And the transformations are applied in the order of scale, rotate then translate.
88a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl>
89a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:rotation</code></dt>
90a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The degrees of rotation of the group.</dd>
91a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotX</code></dt>
92a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group.
93a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd>
94a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotY</code></dt>
95a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group.
96a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd>
97a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleX</code></dt>
98a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the X Coordinate.</dd>
99a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleY</code></dt>
100a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the Y coordinate.</dd>
101a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateX</code></dt>
102a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the X coordinate.
103a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd>
104a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateY</code></dt>
105a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the Y coordinate.
106a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd>
107a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd>
108a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl>
109a95c8abb366d9c39450513335f550b56da13b30aztenghui *
110a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl>
111abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>&lt;path></code></dt>
1126d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn.
113abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl>
114a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt>
115a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the path.</dd>
116a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt>
11746e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute
118a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data. This is defined in the viewport space.</dd>
119a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:fillColor</code></dt>
120a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui * <dd>Defines the color to fill the path (none if not present).</dd>
121a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeColor</code></dt>
122d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd>
123a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeWidth</code></dt>
124a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The width a path stroke.</dd>
1252e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:strokeAlpha</code></dt>
1262e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity of a path stroke.</dd>
1272e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:fillAlpha</code></dt>
1282e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity to fill the path with.</dd>
129a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathStart</code></dt>
130a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd>
131a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathEnd</code></dt>
132a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd>
133a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathOffset</code></dt>
134a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Shift trim region (allows showed region to include the start and end), in the range
135a95c8abb366d9c39450513335f550b56da13b30aztenghui * from 0 to 1.</dd>
136a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineCap</code></dt>
137a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the linecap for a stroked path: butt, round, square.</dd>
138a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineJoin</code></dt>
139a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd>
140a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeMiterLimit</code></dt>
141a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the Miter limit for a stroked path.</dd>
142a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd>
143a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl>
144a95c8abb366d9c39450513335f550b56da13b30aztenghui *
145a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl>
146a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>&lt;clip-path></code></dt>
147a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines path to be the current clip.
148a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl>
149a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt>
150a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the clip path.</dd>
151a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt>
152a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines clip path string. This is using exactly same format as "d" attribute
153a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data.</dd>
154a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd>
155abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl>
156a95c8abb366d9c39450513335f550b56da13b30aztenghui * <li>Here is a simple VectorDrawable in this vectordrawable.xml file.
157a95c8abb366d9c39450513335f550b56da13b30aztenghui * <pre>
158a95c8abb366d9c39450513335f550b56da13b30aztenghui * &lt;vector xmlns:android=&quot;http://schemas.android.com/apk/res/android";
159a95c8abb366d9c39450513335f550b56da13b30aztenghui *     android:height=&quot;64dp&quot;
160a95c8abb366d9c39450513335f550b56da13b30aztenghui *     android:width=&quot;64dp&quot;
161a95c8abb366d9c39450513335f550b56da13b30aztenghui *     android:viewportHeight=&quot;600&quot;
162a95c8abb366d9c39450513335f550b56da13b30aztenghui *     android:viewportWidth=&quot;600&quot; &gt;
163a95c8abb366d9c39450513335f550b56da13b30aztenghui *     &lt;group
164a95c8abb366d9c39450513335f550b56da13b30aztenghui *         android:name=&quot;rotationGroup&quot;
165a95c8abb366d9c39450513335f550b56da13b30aztenghui *         android:pivotX=&quot;300.0&quot;
166a95c8abb366d9c39450513335f550b56da13b30aztenghui *         android:pivotY=&quot;300.0&quot;
167a95c8abb366d9c39450513335f550b56da13b30aztenghui *         android:rotation=&quot;45.0&quot; &gt;
168a95c8abb366d9c39450513335f550b56da13b30aztenghui *         &lt;path
169a95c8abb366d9c39450513335f550b56da13b30aztenghui *             android:name=&quot;v&quot;
170a95c8abb366d9c39450513335f550b56da13b30aztenghui *             android:fillColor=&quot;#000000&quot;
171a95c8abb366d9c39450513335f550b56da13b30aztenghui *             android:pathData=&quot;M300,70 l 0,-70 70,70 0,0 -70,70z&quot; /&gt;
172a95c8abb366d9c39450513335f550b56da13b30aztenghui *     &lt;/group&gt;
173a95c8abb366d9c39450513335f550b56da13b30aztenghui * &lt;/vector&gt;
174a95c8abb366d9c39450513335f550b56da13b30aztenghui * </pre></li>
175abb7d134c02ac60091108c491dafb00877093170John Hoford */
176a95c8abb366d9c39450513335f550b56da13b30aztenghui
177abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable {
1789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    private static final String LOGTAG = VectorDrawable.class.getSimpleName();
1799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
180a95c8abb366d9c39450513335f550b56da13b30aztenghui    private static final String SHAPE_CLIP_PATH = "clip-path";
1816d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui    private static final String SHAPE_GROUP = "group";
182abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_PATH = "path";
183abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_VECTOR = "vector";
184abb7d134c02ac60091108c491dafb00877093170John Hoford
185abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_BUTT = 0;
186abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_ROUND = 1;
187abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_SQUARE = 2;
1889453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
189abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_MITER = 0;
190abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_ROUND = 1;
191abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_BEVEL = 2;
1929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    private static final boolean DBG_VECTOR_DRAWABLE = false;
1944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
19555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    private VectorDrawableState mVectorState;
196e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
197b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    private PorterDuffColorFilter mTintFilter;
198b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
19955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    private boolean mMutated;
20055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
201482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise,
202482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    // caching the bitmap by default is allowed.
203482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    private boolean mAllowCaching = true;
204482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
205abb7d134c02ac60091108c491dafb00877093170John Hoford    public VectorDrawable() {
20655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        mVectorState = new VectorDrawableState();
207abb7d134c02ac60091108c491dafb00877093170John Hoford    }
208abb7d134c02ac60091108c491dafb00877093170John Hoford
2099453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) {
21016c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui        if (theme != null && state.canApplyTheme()) {
21116c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            // If we need to apply a theme, implicitly mutate.
21216c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            mVectorState = new VectorDrawableState(state);
2139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            applyTheme(theme);
21416c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui        } else {
21516c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            mVectorState = state;
2169453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
217b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
218b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
219b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
220abb7d134c02ac60091108c491dafb00877093170John Hoford    }
221abb7d134c02ac60091108c491dafb00877093170John Hoford
22255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    @Override
22355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    public Drawable mutate() {
22455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        if (!mMutated && super.mutate() == this) {
22555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mVectorState = new VectorDrawableState(mVectorState);
22655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mMutated = true;
22755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
22855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return this;
22955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    }
23055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
231e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    Object getTargetByName(String name) {
23255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return mVectorState.mVPathRenderer.mVGTargetsMap.get(name);
233e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    }
234e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
235abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
236abb7d134c02ac60091108c491dafb00877093170John Hoford    public ConstantState getConstantState() {
23755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        mVectorState.mChangingConfigurations = getChangingConfigurations();
23855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return mVectorState;
239abb7d134c02ac60091108c491dafb00877093170John Hoford    }
240abb7d134c02ac60091108c491dafb00877093170John Hoford
2414554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette    @Override
242abb7d134c02ac60091108c491dafb00877093170John Hoford    public void draw(Canvas canvas) {
2434b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        final Rect bounds = getBounds();
2441968201b44567262e7b2e382eee3d88990748d89Dan Sandler        if (bounds.width() == 0 || bounds.height() == 0) {
2451968201b44567262e7b2e382eee3d88990748d89Dan Sandler            // too small to draw
2461968201b44567262e7b2e382eee3d88990748d89Dan Sandler            return;
2471968201b44567262e7b2e382eee3d88990748d89Dan Sandler        }
2481968201b44567262e7b2e382eee3d88990748d89Dan Sandler
2490670f029a4e59448aa53b46a98e60dff6404f360ztenghui        final int saveCount = canvas.save();
250738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        final boolean needMirroring = needMirroring();
251738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
2524b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        canvas.translate(bounds.left, bounds.top);
253738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        if (needMirroring) {
254738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            canvas.translate(bounds.width(), 0);
255738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            canvas.scale(-1.0f, 1.0f);
256738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        }
257482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
258482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        if (!mAllowCaching) {
259482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height());
260482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        } else {
261482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            Bitmap bitmap = mVectorState.mCachedBitmap;
262482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            if (bitmap == null || !mVectorState.canReuseCache(bounds.width(),
263482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    bounds.height())) {
264482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(),
265482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                        Bitmap.Config.ARGB_8888);
266482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                Canvas tmpCanvas = new Canvas(bitmap);
267482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                mVectorState.mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height());
268482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                mVectorState.mCachedBitmap = bitmap;
269482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
270482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                mVectorState.updateCacheStates();
271482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            }
27266613415966f2f1a43cdaa76560eb6d53a05f15dztenghui            // The bitmap's size is the same as the bounds.
27366613415966f2f1a43cdaa76560eb6d53a05f15dztenghui            canvas.drawBitmap(bitmap, 0, 0, null);
274482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        }
275738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
2764b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        canvas.restoreToCount(saveCount);
277abb7d134c02ac60091108c491dafb00877093170John Hoford    }
278abb7d134c02ac60091108c491dafb00877093170John Hoford
279abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
280e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    public int getAlpha() {
281e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        return mVectorState.mVPathRenderer.getRootAlpha();
282e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    }
283e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
284e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    @Override
285abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setAlpha(int alpha) {
2862af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) {
2872af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mVectorState.mVPathRenderer.setRootAlpha(alpha);
288abb7d134c02ac60091108c491dafb00877093170John Hoford            invalidateSelf();
289abb7d134c02ac60091108c491dafb00877093170John Hoford        }
290abb7d134c02ac60091108c491dafb00877093170John Hoford    }
291abb7d134c02ac60091108c491dafb00877093170John Hoford
292abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
293abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setColorFilter(ColorFilter colorFilter) {
294b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
295b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (colorFilter != null) {
296b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            // Color filter overrides tint.
297b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = null;
298b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        } else if (state.mTint != null && state.mTintMode != null) {
299b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            // Restore the tint filter, if we need one.
300b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT);
301b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
302b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            colorFilter = mTintFilter;
303b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
304b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
305b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        state.mVPathRenderer.setColorFilter(colorFilter);
306fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        invalidateSelf();
307abb7d134c02ac60091108c491dafb00877093170John Hoford    }
308abb7d134c02ac60091108c491dafb00877093170John Hoford
309abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
310a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    public void setTintList(ColorStateList tint) {
311b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
312a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        if (state.mTint != tint) {
313b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            state.mTint = tint;
314a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode);
315a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            state.mVPathRenderer.setColorFilter(mTintFilter);
316a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            invalidateSelf();
317a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        }
318a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    }
319b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
320a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    @Override
321a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette    public void setTintMode(Mode tintMode) {
322a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        final VectorDrawableState state = mVectorState;
323a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette        if (state.mTintMode != tintMode) {
324a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            state.mTintMode = tintMode;
325a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode);
326a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette            state.mVPathRenderer.setColorFilter(mTintFilter);
327b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            invalidateSelf();
328b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
329b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
330b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
331b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
332b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    protected boolean onStateChange(int[] stateSet) {
333b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
334b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (state.mTint != null && state.mTintMode != null) {
335b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
336b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
337b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            return true;
338b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
339b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        return false;
340b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
341b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
342b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
343abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getOpacity() {
344abb7d134c02ac60091108c491dafb00877093170John Hoford        return PixelFormat.TRANSLUCENT;
345abb7d134c02ac60091108c491dafb00877093170John Hoford    }
346abb7d134c02ac60091108c491dafb00877093170John Hoford
347abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
348abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getIntrinsicWidth() {
349ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        return (int) mVectorState.mVPathRenderer.mBaseWidth;
350abb7d134c02ac60091108c491dafb00877093170John Hoford    }
351abb7d134c02ac60091108c491dafb00877093170John Hoford
352abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
353abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getIntrinsicHeight() {
354ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        return (int) mVectorState.mVPathRenderer.mBaseHeight;
355abb7d134c02ac60091108c491dafb00877093170John Hoford    }
356abb7d134c02ac60091108c491dafb00877093170John Hoford
357abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
3589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    public boolean canApplyTheme() {
3599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme();
3609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    }
3619453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
3629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    @Override
3639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    public void applyTheme(Theme t) {
3649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        super.applyTheme(t);
3659453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
3669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        final VectorDrawableState state = mVectorState;
367ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        final VPathRenderer path = state.mVPathRenderer;
3689453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        if (path != null && path.canApplyTheme()) {
3699453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            path.applyTheme(t);
3709453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
3719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    }
3729453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
373fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount    /**
374fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount     * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension.
375fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount     * This is used to calculate the path animation accuracy.
376fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount     *
377fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount     * @hide
378fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount     */
379fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount    public float getPixelSize() {
380fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        if (mVectorState == null && mVectorState.mVPathRenderer == null ||
381fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount                mVectorState.mVPathRenderer.mBaseWidth == 0 ||
382fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount                mVectorState.mVPathRenderer.mBaseHeight == 0 ||
383fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount                mVectorState.mVPathRenderer.mViewportHeight == 0 ||
384fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount                mVectorState.mVPathRenderer.mViewportWidth == 0) {
385fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount            return 1; // fall back to 1:1 pixel mapping.
386fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        }
387fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth;
388fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight;
389fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth;
390fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight;
391fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        float scaleX = viewportWidth / intrinsicWidth;
392fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        float scaleY = viewportHeight / intrinsicHeight;
393fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount        return Math.min(scaleX, scaleY);
394fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount    }
395fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount
3964b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette    /** @hide */
3974b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette    public static VectorDrawable create(Resources resources, int rid) {
3984b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        try {
399874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            final XmlPullParser parser = resources.getXml(rid);
400874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            final AttributeSet attrs = Xml.asAttributeSet(parser);
401874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            int type;
402874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            while ((type=parser.next()) != XmlPullParser.START_TAG &&
403874bcd82c223ce58c9d76edcf619b3988c672307ztenghui                    type != XmlPullParser.END_DOCUMENT) {
404874bcd82c223ce58c9d76edcf619b3988c672307ztenghui                // Empty loop
405874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            }
406874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            if (type != XmlPullParser.START_TAG) {
407874bcd82c223ce58c9d76edcf619b3988c672307ztenghui                throw new XmlPullParserException("No start tag found");
408874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            }
4094b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette
4104b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            final VectorDrawable drawable = new VectorDrawable();
411874bcd82c223ce58c9d76edcf619b3988c672307ztenghui            drawable.inflate(resources, parser, attrs);
4124b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette
4134b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            return drawable;
4144b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        } catch (XmlPullParserException e) {
4154b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            Log.e(LOGTAG, "parser error", e);
4164b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        } catch (IOException e) {
4174b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            Log.e(LOGTAG, "parser error", e);
4184b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        }
4194b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        return null;
4204b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette    }
4214b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette
4222af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui    private static int applyAlpha(int color, float alpha) {
4232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        int alphaBytes = Color.alpha(color);
4242af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        color &= 0x00FFFFFF;
4252af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        color |= ((int) (alphaBytes * alpha)) << 24;
4262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        return color;
4272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui    }
4282af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
4299cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    @Override
4309cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
4319cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            throws XmlPullParserException, IOException {
432a95c8abb366d9c39450513335f550b56da13b30aztenghui        final VectorDrawableState state = mVectorState;
433a95c8abb366d9c39450513335f550b56da13b30aztenghui        final VPathRenderer pathRenderer = new VPathRenderer();
434a95c8abb366d9c39450513335f550b56da13b30aztenghui        state.mVPathRenderer = pathRenderer;
435a95c8abb366d9c39450513335f550b56da13b30aztenghui
436a95c8abb366d9c39450513335f550b56da13b30aztenghui        TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable);
4379cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        updateStateFromTypedArray(a);
4389cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        a.recycle();
4399cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
440a95c8abb366d9c39450513335f550b56da13b30aztenghui        state.mCacheDirty = true;
44155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        inflateInternal(res, parser, attrs, theme);
4429cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
4439cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
4449cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        state.mVPathRenderer.setColorFilter(mTintFilter);
4459cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    }
4469cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
447a95c8abb366d9c39450513335f550b56da13b30aztenghui    private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException {
4489cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final VectorDrawableState state = mVectorState;
449a95c8abb366d9c39450513335f550b56da13b30aztenghui        final VPathRenderer pathRenderer = state.mVPathRenderer;
4509cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
4518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
4528e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mChangingConfigurations |= a.getChangingConfigurations();
4538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
4549cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        // Extract the theme attributes, if any.
4559cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        state.mThemeAttrs = a.extractThemeAttrs();
4569cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
4579cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1);
4589cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        if (tintMode != -1) {
4599cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
4609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        }
4619cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
4629cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint);
4639cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        if (tint != null) {
4649cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            state.mTint = tint;
4659cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        }
466738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
467738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        state.mAutoMirrored = a.getBoolean(
468738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui                R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored);
469a95c8abb366d9c39450513335f550b56da13b30aztenghui
470a95c8abb366d9c39450513335f550b56da13b30aztenghui        pathRenderer.mViewportWidth = a.getFloat(
471a95c8abb366d9c39450513335f550b56da13b30aztenghui                R.styleable.VectorDrawable_viewportWidth, pathRenderer.mViewportWidth);
472a95c8abb366d9c39450513335f550b56da13b30aztenghui        pathRenderer.mViewportHeight = a.getFloat(
473a95c8abb366d9c39450513335f550b56da13b30aztenghui                R.styleable.VectorDrawable_viewportHeight, pathRenderer.mViewportHeight);
474a95c8abb366d9c39450513335f550b56da13b30aztenghui
475a95c8abb366d9c39450513335f550b56da13b30aztenghui        if (pathRenderer.mViewportWidth <= 0) {
476a95c8abb366d9c39450513335f550b56da13b30aztenghui            throw new XmlPullParserException(a.getPositionDescription() +
4771c4d8b2173bf4b5bbac94748959752599775628dztenghui                    "<vector> tag requires viewportWidth > 0");
478a95c8abb366d9c39450513335f550b56da13b30aztenghui        } else if (pathRenderer.mViewportHeight <= 0) {
479a95c8abb366d9c39450513335f550b56da13b30aztenghui            throw new XmlPullParserException(a.getPositionDescription() +
4801c4d8b2173bf4b5bbac94748959752599775628dztenghui                    "<vector> tag requires viewportHeight > 0");
481a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
482a95c8abb366d9c39450513335f550b56da13b30aztenghui
483a95c8abb366d9c39450513335f550b56da13b30aztenghui        pathRenderer.mBaseWidth = a.getDimension(
484a95c8abb366d9c39450513335f550b56da13b30aztenghui                R.styleable.VectorDrawable_width, pathRenderer.mBaseWidth);
485a95c8abb366d9c39450513335f550b56da13b30aztenghui        pathRenderer.mBaseHeight = a.getDimension(
486a95c8abb366d9c39450513335f550b56da13b30aztenghui                R.styleable.VectorDrawable_height, pathRenderer.mBaseHeight);
487a95c8abb366d9c39450513335f550b56da13b30aztenghui
488a95c8abb366d9c39450513335f550b56da13b30aztenghui        if (pathRenderer.mBaseWidth <= 0) {
489a95c8abb366d9c39450513335f550b56da13b30aztenghui            throw new XmlPullParserException(a.getPositionDescription() +
4901c4d8b2173bf4b5bbac94748959752599775628dztenghui                    "<vector> tag requires width > 0");
491a95c8abb366d9c39450513335f550b56da13b30aztenghui        } else if (pathRenderer.mBaseHeight <= 0) {
492a95c8abb366d9c39450513335f550b56da13b30aztenghui            throw new XmlPullParserException(a.getPositionDescription() +
4931c4d8b2173bf4b5bbac94748959752599775628dztenghui                    "<vector> tag requires height > 0");
494a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
4959cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    }
4969cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
49755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs,
4988e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            Theme theme) throws XmlPullParserException, IOException {
4998e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        final VectorDrawableState state = mVectorState;
500a95c8abb366d9c39450513335f550b56da13b30aztenghui        final VPathRenderer pathRenderer = state.mVPathRenderer;
501abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean noPathTag = true;
5029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
5034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Use a stack to help to build the group tree.
5044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // The top of the stack is always the current group.
5054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        final Stack<VGroup> groupStack = new Stack<VGroup>();
5064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        groupStack.push(pathRenderer.mRootGroup);
507abb7d134c02ac60091108c491dafb00877093170John Hoford
508abb7d134c02ac60091108c491dafb00877093170John Hoford        int eventType = parser.getEventType();
509abb7d134c02ac60091108c491dafb00877093170John Hoford        while (eventType != XmlPullParser.END_DOCUMENT) {
510abb7d134c02ac60091108c491dafb00877093170John Hoford            if (eventType == XmlPullParser.START_TAG) {
5119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                final String tagName = parser.getName();
5124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final VGroup currentGroup = groupStack.peek();
5134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
514abb7d134c02ac60091108c491dafb00877093170John Hoford                if (SHAPE_PATH.equals(tagName)) {
515a95c8abb366d9c39450513335f550b56da13b30aztenghui                    final VFullPath path = new VFullPath();
5169453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                    path.inflate(res, attrs, theme);
5178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    currentGroup.mChildren.add(path);
518e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    if (path.getPathName() != null) {
51955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                        pathRenderer.mVGTargetsMap.put(path.getPathName(), path);
520e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    }
521abb7d134c02ac60091108c491dafb00877093170John Hoford                    noPathTag = false;
5228e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    state.mChangingConfigurations |= path.mChangingConfigurations;
523a95c8abb366d9c39450513335f550b56da13b30aztenghui                } else if (SHAPE_CLIP_PATH.equals(tagName)) {
524a95c8abb366d9c39450513335f550b56da13b30aztenghui                    final VClipPath path = new VClipPath();
525a95c8abb366d9c39450513335f550b56da13b30aztenghui                    path.inflate(res, attrs, theme);
526a95c8abb366d9c39450513335f550b56da13b30aztenghui                    currentGroup.mChildren.add(path);
527a95c8abb366d9c39450513335f550b56da13b30aztenghui                    if (path.getPathName() != null) {
528a95c8abb366d9c39450513335f550b56da13b30aztenghui                        pathRenderer.mVGTargetsMap.put(path.getPathName(), path);
529a95c8abb366d9c39450513335f550b56da13b30aztenghui                    }
530a95c8abb366d9c39450513335f550b56da13b30aztenghui                    state.mChangingConfigurations |= path.mChangingConfigurations;
5316d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui                } else if (SHAPE_GROUP.equals(tagName)) {
5324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    VGroup newChildGroup = new VGroup();
5334d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    newChildGroup.inflate(res, attrs, theme);
5348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    currentGroup.mChildren.add(newChildGroup);
5354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    groupStack.push(newChildGroup);
536e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    if (newChildGroup.getGroupName() != null) {
53755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                        pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(),
53855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                                newChildGroup);
539e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    }
5408e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    state.mChangingConfigurations |= newChildGroup.mChangingConfigurations;
541abb7d134c02ac60091108c491dafb00877093170John Hoford                }
5424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            } else if (eventType == XmlPullParser.END_TAG) {
5434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final String tagName = parser.getName();
5444d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                if (SHAPE_GROUP.equals(tagName)) {
5454d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    groupStack.pop();
5464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
547abb7d134c02ac60091108c491dafb00877093170John Hoford            }
548abb7d134c02ac60091108c491dafb00877093170John Hoford            eventType = parser.next();
549abb7d134c02ac60091108c491dafb00877093170John Hoford        }
5509453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
5514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Print the tree out for debug.
5524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        if (DBG_VECTOR_DRAWABLE) {
5534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            printGroupTree(pathRenderer.mRootGroup, 0);
5546d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui        }
5556d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui
556a95c8abb366d9c39450513335f550b56da13b30aztenghui        if (noPathTag) {
5579453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final StringBuffer tag = new StringBuffer();
5589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
559a95c8abb366d9c39450513335f550b56da13b30aztenghui            if (tag.length() > 0) {
560a95c8abb366d9c39450513335f550b56da13b30aztenghui                tag.append(" or ");
561abb7d134c02ac60091108c491dafb00877093170John Hoford            }
562a95c8abb366d9c39450513335f550b56da13b30aztenghui            tag.append(SHAPE_PATH);
5639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
5649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            throw new XmlPullParserException("no " + tag + " defined");
565abb7d134c02ac60091108c491dafb00877093170John Hoford        }
566abb7d134c02ac60091108c491dafb00877093170John Hoford    }
567abb7d134c02ac60091108c491dafb00877093170John Hoford
5684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    private void printGroupTree(VGroup currentGroup, int level) {
5694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        String indent = "";
5708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        for (int i = 0; i < level; i++) {
5714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            indent += "    ";
5724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
5734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Print the current node
5748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName()
5754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                + " rotation is " + currentGroup.mRotate);
5768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString());
5778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        // Then print all the children groups
5788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        for (int i = 0; i < currentGroup.mChildren.size(); i++) {
5798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            Object child = currentGroup.mChildren.get(i);
5808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            if (child instanceof VGroup) {
5818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                printGroupTree((VGroup) child, level + 1);
5828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            }
5834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
5844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    }
5854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
58655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    @Override
58755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    public int getChangingConfigurations() {
58855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return super.getChangingConfigurations() | mVectorState.mChangingConfigurations;
58955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    }
59055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
591482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    void setAllowCaching(boolean allowCaching) {
592482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        mAllowCaching = allowCaching;
593482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    }
594482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
595738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    private boolean needMirroring() {
596738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL;
597738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    }
598738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
599738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    @Override
600738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    public void setAutoMirrored(boolean mirrored) {
601738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        if (mVectorState.mAutoMirrored != mirrored) {
602738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            mVectorState.mAutoMirrored = mirrored;
603738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            invalidateSelf();
604738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        }
605738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    }
606738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
607738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    @Override
608738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    public boolean isAutoMirrored() {
609738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        return mVectorState.mAutoMirrored;
610738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    }
611738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
6125c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette    private static class VectorDrawableState extends ConstantState {
6139cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        int[] mThemeAttrs;
6145c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        int mChangingConfigurations;
615ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        VPathRenderer mVPathRenderer;
616b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        ColorStateList mTint;
617b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        Mode mTintMode;
618738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        boolean mAutoMirrored;
6195c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
620482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        Bitmap mCachedBitmap;
621482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        int[] mCachedThemeAttrs;
622482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        ColorStateList mCachedTint;
623482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        Mode mCachedTintMode;
624482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        int mCachedRootAlpha;
625670689af43358568bf2b5916284f1cac5762f428ztenghui        boolean mCachedAutoMirrored;
626670689af43358568bf2b5916284f1cac5762f428ztenghui        boolean mCacheDirty;
627482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
62855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Deep copy for mutate() or implicitly mutate.
6295c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public VectorDrawableState(VectorDrawableState copy) {
6305c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            if (copy != null) {
6319cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette                mThemeAttrs = copy.mThemeAttrs;
6325c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette                mChangingConfigurations = copy.mChangingConfigurations;
633ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui                mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
6346f6578e81c1df207da47e2e1337382341f271206Chet Haase                if (copy.mVPathRenderer.mFillPaint != null) {
6356f6578e81c1df207da47e2e1337382341f271206Chet Haase                    mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint);
6366f6578e81c1df207da47e2e1337382341f271206Chet Haase                }
6376f6578e81c1df207da47e2e1337382341f271206Chet Haase                if (copy.mVPathRenderer.mStrokePaint != null) {
6386f6578e81c1df207da47e2e1337382341f271206Chet Haase                    mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint);
6396f6578e81c1df207da47e2e1337382341f271206Chet Haase                }
6406f6578e81c1df207da47e2e1337382341f271206Chet Haase                if (copy.mVPathRenderer.mColorFilter != null) {
6416f6578e81c1df207da47e2e1337382341f271206Chet Haase                    mVPathRenderer.mColorFilter = copy.mVPathRenderer.mColorFilter;
6426f6578e81c1df207da47e2e1337382341f271206Chet Haase                }
643b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTint = copy.mTint;
644b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTintMode = copy.mTintMode;
645738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui                mAutoMirrored = copy.mAutoMirrored;
6465c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            }
6475c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
6485c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
649482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        public boolean canReuseCache(int width, int height) {
650670689af43358568bf2b5916284f1cac5762f428ztenghui            if (!mCacheDirty
651670689af43358568bf2b5916284f1cac5762f428ztenghui                    && mCachedThemeAttrs == mThemeAttrs
652482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && mCachedTint == mTint
653482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && mCachedTintMode == mTintMode
654670689af43358568bf2b5916284f1cac5762f428ztenghui                    && mCachedAutoMirrored == mAutoMirrored
655482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && width == mCachedBitmap.getWidth()
656482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && height == mCachedBitmap.getHeight()
657482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && mCachedRootAlpha == mVPathRenderer.getRootAlpha())  {
658482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                return true;
659482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            }
660482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            return false;
661482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        }
662482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
663482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        public void updateCacheStates() {
664482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            // Use shallow copy here and shallow comparison in canReuseCache(),
665482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            // likely hit cache miss more, but practically not much difference.
666482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedThemeAttrs = mThemeAttrs;
667482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedTint = mTint;
668482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedTintMode = mTintMode;
669482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedRootAlpha = mVPathRenderer.getRootAlpha();
670670689af43358568bf2b5916284f1cac5762f428ztenghui            mCachedAutoMirrored = mAutoMirrored;
671670689af43358568bf2b5916284f1cac5762f428ztenghui            mCacheDirty = false;
672482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        }
673482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
67455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public VectorDrawableState() {
67555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mVPathRenderer = new VPathRenderer();
67655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
67755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
6785c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
6795c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable() {
6805c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, null, null);
6815c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
6825c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
6835c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
6845c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable(Resources res) {
6855c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, res, null);
6865c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
6875c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
6885c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
6895c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable(Resources res, Theme theme) {
6905c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, res, theme);
6915c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
6925c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
6935c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
6945c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public int getChangingConfigurations() {
6955c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return mChangingConfigurations;
6965c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
6975c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette    }
6985c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
699ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui    private static class VPathRenderer {
7004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        /* Right now the internal data structure is organized as a tree.
7014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * Each node can be a group node, or a path.
7024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * A group node can have groups or paths as children, but a path node has
7034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * no children.
7044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * One example can be:
7054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *                 Root Group
7064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *                /    |     \
7074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *           Group    Path    Group
7084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *          /     \             |
7094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *         Path   Path         Path
7104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *
7114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         */
71255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables that only used temporarily inside the draw() call, so there
71355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // is no need for deep copying.
7146f6578e81c1df207da47e2e1337382341f271206Chet Haase        private final Path mPath;
7156f6578e81c1df207da47e2e1337382341f271206Chet Haase        private final Path mRenderPath;
7164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private static final Matrix IDENTITY_MATRIX = new Matrix();
71755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private final Matrix mFinalPathMatrix = new Matrix();
7184b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
7194b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private Paint mStrokePaint;
7204b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private Paint mFillPaint;
721fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        private ColorFilter mColorFilter;
722abb7d134c02ac60091108c491dafb00877093170John Hoford        private PathMeasure mPathMeasure;
7234b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
72455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        /////////////////////////////////////////////////////
72555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables below need to be copied (deep copy if applicable) for mutation.
7268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        private int mChangingConfigurations;
72755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private final VGroup mRootGroup;
728a95c8abb366d9c39450513335f550b56da13b30aztenghui        float mBaseWidth = 0;
729a95c8abb366d9c39450513335f550b56da13b30aztenghui        float mBaseHeight = 0;
730a95c8abb366d9c39450513335f550b56da13b30aztenghui        float mViewportWidth = 0;
731a95c8abb366d9c39450513335f550b56da13b30aztenghui        float mViewportHeight = 0;
7322af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        private int mRootAlpha = 0xFF;
7339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
73455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
735abb7d134c02ac60091108c491dafb00877093170John Hoford
736ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        public VPathRenderer() {
7374d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mRootGroup = new VGroup();
7386f6578e81c1df207da47e2e1337382341f271206Chet Haase            mPath = new Path();
7396f6578e81c1df207da47e2e1337382341f271206Chet Haase            mRenderPath = new Path();
740abb7d134c02ac60091108c491dafb00877093170John Hoford        }
7419453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
7422af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        public void setRootAlpha(int alpha) {
7432af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mRootAlpha = alpha;
7442af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        }
7452af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
7462af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        public int getRootAlpha() {
7472af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            return mRootAlpha;
7482af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        }
7492af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
750ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        public VPathRenderer(VPathRenderer copy) {
75155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
7526f6578e81c1df207da47e2e1337382341f271206Chet Haase            mPath = new Path(copy.mPath);
7536f6578e81c1df207da47e2e1337382341f271206Chet Haase            mRenderPath = new Path(copy.mRenderPath);
754abb7d134c02ac60091108c491dafb00877093170John Hoford            mBaseWidth = copy.mBaseWidth;
755abb7d134c02ac60091108c491dafb00877093170John Hoford            mBaseHeight = copy.mBaseHeight;
7565eb5cde467081d1af628e5463ba55f110265a86fztenghui            mViewportWidth = copy.mViewportWidth;
757abb7d134c02ac60091108c491dafb00877093170John Hoford            mViewportHeight = copy.mViewportHeight;
7588e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mChangingConfigurations = copy.mChangingConfigurations;
75955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mRootAlpha = copy.mRootAlpha;
760abb7d134c02ac60091108c491dafb00877093170John Hoford        }
761abb7d134c02ac60091108c491dafb00877093170John Hoford
7629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public boolean canApplyTheme() {
7634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // If one of the paths can apply theme, then return true;
7644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return recursiveCanApplyTheme(mRootGroup);
7654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
7664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
7674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private boolean recursiveCanApplyTheme(VGroup currentGroup) {
7684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // We can do a tree traverse here, if there is one path return true,
7694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // then we return true for the whole tree.
7708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final ArrayList<Object> children = currentGroup.mChildren;
7718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui
7728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < children.size(); i++) {
7738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object child = children.get(i);
7748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (child instanceof VGroup) {
7758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup childGroup = (VGroup) child;
7768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childGroup.canApplyTheme()
7778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                            || recursiveCanApplyTheme(childGroup)) {
7788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        return true;
7798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
7808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else if (child instanceof VPath) {
7818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath childPath = (VPath) child;
7828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childPath.canApplyTheme()) {
7838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        return true;
7848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
7854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
7864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
7879453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            return false;
7889453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
7899453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
7909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public void applyTheme(Theme t) {
7914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Apply theme to every path of the tree.
7924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            recursiveApplyTheme(mRootGroup, t);
7934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
7944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
7954d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void recursiveApplyTheme(VGroup currentGroup, Theme t) {
7964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // We can do a tree traverse here, apply theme to all paths which
7974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // can apply theme.
7988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final ArrayList<Object> children = currentGroup.mChildren;
7998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < children.size(); i++) {
8008d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object child = children.get(i);
8018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (child instanceof VGroup) {
8028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup childGroup = (VGroup) child;
8038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childGroup.canApplyTheme()) {
8048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        childGroup.applyTheme(t);
8058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
8068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    recursiveApplyTheme(childGroup, t);
8078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else if (child instanceof VPath) {
8088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath childPath = (VPath) child;
8098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childPath.canApplyTheme()) {
8108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        childPath.applyTheme(t);
8118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
8124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
8134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
814abb7d134c02ac60091108c491dafb00877093170John Hoford        }
815abb7d134c02ac60091108c491dafb00877093170John Hoford
816fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        public void setColorFilter(ColorFilter colorFilter) {
817fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mColorFilter = colorFilter;
818fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
819fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mFillPaint != null) {
820fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                mFillPaint.setColorFilter(colorFilter);
821fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            }
822fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
823fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mStrokePaint != null) {
824fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                mStrokePaint.setColorFilter(colorFilter);
825fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            }
8266d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui
827fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        }
828fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
8294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix,
8302e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                Canvas canvas, int w, int h) {
8314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Calculate current group's matrix by preConcat the parent's and
8324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // and the current one on the top of the stack.
8334d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Basically the Mfinal = Mviewport * M0 * M1 * M2;
8344d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Mi the local matrix at level i of the group tree.
8354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            currentGroup.mStackedMatrix.set(currentMatrix);
8364d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
8374d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
8384d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
8398d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            // Draw the group tree in the same order as the XML file.
8408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < currentGroup.mChildren.size(); i++) {
8418d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object child = currentGroup.mChildren.get(i);
8428d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (child instanceof VGroup) {
8438d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup childGroup = (VGroup) child;
8448d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    drawGroupTree(childGroup, currentGroup.mStackedMatrix,
8452e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                            canvas, w, h);
8468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else if (child instanceof VPath) {
8478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath childPath = (VPath) child;
8482e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                    drawPath(currentGroup, childPath, canvas, w, h);
8498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                }
850abb7d134c02ac60091108c491dafb00877093170John Hoford            }
8514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
852abb7d134c02ac60091108c491dafb00877093170John Hoford
8534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        public void draw(Canvas canvas, int w, int h) {
8544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Travese the tree in pre-order to draw.
8552e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h);
856abb7d134c02ac60091108c491dafb00877093170John Hoford        }
857abb7d134c02ac60091108c491dafb00877093170John Hoford
8582e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h) {
8599d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui            final float scaleX =  w / mViewportWidth;
8609d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui            final float scaleY = h / mViewportHeight;
8619d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui            final float minScale = Math.min(scaleX, scaleY);
862abb7d134c02ac60091108c491dafb00877093170John Hoford
8634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mFinalPathMatrix.set(vGroup.mStackedMatrix);
8645a836f74df027bb568da17fbde4e641b6a56d2a9ztenghui            mFinalPathMatrix.postScale(scaleX, scaleY);
865abb7d134c02ac60091108c491dafb00877093170John Hoford
8668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            vPath.toPath(mPath);
8678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final Path path = mPath;
868abb7d134c02ac60091108c491dafb00877093170John Hoford
8698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            mRenderPath.reset();
8709453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
871a95c8abb366d9c39450513335f550b56da13b30aztenghui            if (vPath.isClipPath()) {
872a95c8abb366d9c39450513335f550b56da13b30aztenghui                mRenderPath.addPath(path, mFinalPathMatrix);
8738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                canvas.clipPath(mRenderPath, Region.Op.REPLACE);
8748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            } else {
875a95c8abb366d9c39450513335f550b56da13b30aztenghui                VFullPath fullPath = (VFullPath) vPath;
876a95c8abb366d9c39450513335f550b56da13b30aztenghui                if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
877a95c8abb366d9c39450513335f550b56da13b30aztenghui                    float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f;
878a95c8abb366d9c39450513335f550b56da13b30aztenghui                    float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f;
879a95c8abb366d9c39450513335f550b56da13b30aztenghui
880a95c8abb366d9c39450513335f550b56da13b30aztenghui                    if (mPathMeasure == null) {
881a95c8abb366d9c39450513335f550b56da13b30aztenghui                        mPathMeasure = new PathMeasure();
882a95c8abb366d9c39450513335f550b56da13b30aztenghui                    }
883a95c8abb366d9c39450513335f550b56da13b30aztenghui                    mPathMeasure.setPath(mPath, false);
884a95c8abb366d9c39450513335f550b56da13b30aztenghui
885a95c8abb366d9c39450513335f550b56da13b30aztenghui                    float len = mPathMeasure.getLength();
886a95c8abb366d9c39450513335f550b56da13b30aztenghui                    start = start * len;
887a95c8abb366d9c39450513335f550b56da13b30aztenghui                    end = end * len;
888a95c8abb366d9c39450513335f550b56da13b30aztenghui                    path.reset();
889a95c8abb366d9c39450513335f550b56da13b30aztenghui                    if (start > end) {
890a95c8abb366d9c39450513335f550b56da13b30aztenghui                        mPathMeasure.getSegment(start, len, path, true);
891a95c8abb366d9c39450513335f550b56da13b30aztenghui                        mPathMeasure.getSegment(0f, end, path, true);
892a95c8abb366d9c39450513335f550b56da13b30aztenghui                    } else {
893a95c8abb366d9c39450513335f550b56da13b30aztenghui                        mPathMeasure.getSegment(start, end, path, true);
894a95c8abb366d9c39450513335f550b56da13b30aztenghui                    }
895a95c8abb366d9c39450513335f550b56da13b30aztenghui                    path.rLineTo(0, 0); // fix bug in measure
896a95c8abb366d9c39450513335f550b56da13b30aztenghui                }
897a95c8abb366d9c39450513335f550b56da13b30aztenghui                mRenderPath.addPath(path, mFinalPathMatrix);
898a95c8abb366d9c39450513335f550b56da13b30aztenghui
899a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui                if (fullPath.mFillColor != Color.TRANSPARENT) {
9008d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (mFillPaint == null) {
9018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint = new Paint();
9028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint.setColorFilter(mColorFilter);
9038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint.setStyle(Paint.Style.FILL);
9048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint.setAntiAlias(true);
90563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    }
9062e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                    mFillPaint.setColor(applyAlpha(fullPath.mFillColor,
9072e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                            fullPath.mFillAlpha));
9088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    canvas.drawPath(mRenderPath, mFillPaint);
9098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                }
91063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
911a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui                if (fullPath.mStrokeColor != Color.TRANSPARENT) {
9128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (mStrokePaint == null) {
9138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint = new Paint();
9148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint.setColorFilter(mColorFilter);
9158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint.setStyle(Paint.Style.STROKE);
9168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint.setAntiAlias(true);
9178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
9184b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
9198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    final Paint strokePaint = mStrokePaint;
920a95c8abb366d9c39450513335f550b56da13b30aztenghui                    if (fullPath.mStrokeLineJoin != null) {
921a95c8abb366d9c39450513335f550b56da13b30aztenghui                        strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin);
9228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
923abb7d134c02ac60091108c491dafb00877093170John Hoford
924a95c8abb366d9c39450513335f550b56da13b30aztenghui                    if (fullPath.mStrokeLineCap != null) {
925a95c8abb366d9c39450513335f550b56da13b30aztenghui                        strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
9268d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
92763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
928c4d651ec8a8c190c5df173166357c2fdf47472ceztenghui                    strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
92963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
9302e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                    strokePaint.setColor(applyAlpha(fullPath.mStrokeColor,
9312e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                            fullPath.mStrokeAlpha));
932a95c8abb366d9c39450513335f550b56da13b30aztenghui                    strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale);
9338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    canvas.drawPath(mRenderPath, strokePaint);
93463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                }
935abb7d134c02ac60091108c491dafb00877093170John Hoford            }
936abb7d134c02ac60091108c491dafb00877093170John Hoford        }
937abb7d134c02ac60091108c491dafb00877093170John Hoford    }
938abb7d134c02ac60091108c491dafb00877093170John Hoford
939a95c8abb366d9c39450513335f550b56da13b30aztenghui    private static class VGroup {
94055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // mStackedMatrix is only used temporarily when drawing, it combines all
94155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // the parents' local matrices with the current one.
94255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private final Matrix mStackedMatrix = new Matrix();
94355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
94455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        /////////////////////////////////////////////////////
94555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables below need to be copied (deep copy if applicable) for mutation.
9468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        final ArrayList<Object> mChildren = new ArrayList<Object>();
947abb7d134c02ac60091108c491dafb00877093170John Hoford
94863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mRotate = 0;
94963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mPivotX = 0;
95063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mPivotY = 0;
951452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mScaleX = 1;
952452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mScaleY = 1;
953452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mTranslateX = 0;
954452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mTranslateY = 0;
9554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
95655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // mLocalMatrix is updated based on the update of transformation information,
95755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // either parsed from the XML or by animation.
9584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final Matrix mLocalMatrix = new Matrix();
9598e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        private int mChangingConfigurations;
96063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private int[] mThemeAttrs;
961e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        private String mGroupName = null;
962e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
96355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) {
96455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mRotate = copy.mRotate;
96555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mPivotX = copy.mPivotX;
96655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mPivotY = copy.mPivotY;
96755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mScaleX = copy.mScaleX;
96855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mScaleY = copy.mScaleY;
96955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTranslateX = copy.mTranslateX;
97055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTranslateY = copy.mTranslateY;
97155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mThemeAttrs = copy.mThemeAttrs;
97255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mGroupName = copy.mGroupName;
97355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mChangingConfigurations = copy.mChangingConfigurations;
97455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            if (mGroupName != null) {
97555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                targetsMap.put(mGroupName, this);
97655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            }
97755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
97855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mLocalMatrix.set(copy.mLocalMatrix);
97955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
9808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final ArrayList<Object> children = copy.mChildren;
9818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < children.size(); i++) {
9828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object copyChild = children.get(i);
9838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (copyChild instanceof VGroup) {
9848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup copyGroup = (VGroup) copyChild;
9858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mChildren.add(new VGroup(copyGroup, targetsMap));
986a95c8abb366d9c39450513335f550b56da13b30aztenghui                } else {
987a95c8abb366d9c39450513335f550b56da13b30aztenghui                    VPath newPath = null;
988a95c8abb366d9c39450513335f550b56da13b30aztenghui                    if (copyChild instanceof VFullPath) {
989a95c8abb366d9c39450513335f550b56da13b30aztenghui                        newPath = new VFullPath((VFullPath) copyChild);
990a95c8abb366d9c39450513335f550b56da13b30aztenghui                    } else if (copyChild instanceof VClipPath) {
991a95c8abb366d9c39450513335f550b56da13b30aztenghui                        newPath = new VClipPath((VClipPath) copyChild);
992a95c8abb366d9c39450513335f550b56da13b30aztenghui                    } else {
993a95c8abb366d9c39450513335f550b56da13b30aztenghui                        throw new IllegalStateException("Unknown object in the tree!");
994a95c8abb366d9c39450513335f550b56da13b30aztenghui                    }
9958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mChildren.add(newPath);
9968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (newPath.mPathName != null) {
9978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        targetsMap.put(newPath.mPathName, newPath);
9988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
99955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                }
100055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            }
100155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
100255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
100355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public VGroup() {
100455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
100555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
1006a95c8abb366d9c39450513335f550b56da13b30aztenghui        public String getGroupName() {
1007a95c8abb366d9c39450513335f550b56da13b30aztenghui            return mGroupName;
1008a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1009a95c8abb366d9c39450513335f550b56da13b30aztenghui
1010a95c8abb366d9c39450513335f550b56da13b30aztenghui        public Matrix getLocalMatrix() {
1011a95c8abb366d9c39450513335f550b56da13b30aztenghui            return mLocalMatrix;
1012a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1013a95c8abb366d9c39450513335f550b56da13b30aztenghui
1014a95c8abb366d9c39450513335f550b56da13b30aztenghui        public boolean canApplyTheme() {
1015a95c8abb366d9c39450513335f550b56da13b30aztenghui            return mThemeAttrs != null;
1016a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1017a95c8abb366d9c39450513335f550b56da13b30aztenghui
1018a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void inflate(Resources res, AttributeSet attrs, Theme theme) {
1019a95c8abb366d9c39450513335f550b56da13b30aztenghui            final TypedArray a = obtainAttributes(res, theme, attrs,
1020a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawableGroup);
1021a95c8abb366d9c39450513335f550b56da13b30aztenghui            updateStateFromTypedArray(a);
1022a95c8abb366d9c39450513335f550b56da13b30aztenghui            a.recycle();
1023a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1024a95c8abb366d9c39450513335f550b56da13b30aztenghui
1025a95c8abb366d9c39450513335f550b56da13b30aztenghui        private void updateStateFromTypedArray(TypedArray a) {
1026a95c8abb366d9c39450513335f550b56da13b30aztenghui            // Account for any configuration changes.
1027a95c8abb366d9c39450513335f550b56da13b30aztenghui            mChangingConfigurations |= a.getChangingConfigurations();
1028a95c8abb366d9c39450513335f550b56da13b30aztenghui
1029a95c8abb366d9c39450513335f550b56da13b30aztenghui            // Extract the theme attributes, if any.
1030a95c8abb366d9c39450513335f550b56da13b30aztenghui            mThemeAttrs = a.extractThemeAttrs();
1031a95c8abb366d9c39450513335f550b56da13b30aztenghui
1032a95c8abb366d9c39450513335f550b56da13b30aztenghui            mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate);
1033a95c8abb366d9c39450513335f550b56da13b30aztenghui            mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX);
1034a95c8abb366d9c39450513335f550b56da13b30aztenghui            mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY);
1035a95c8abb366d9c39450513335f550b56da13b30aztenghui            mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX);
1036a95c8abb366d9c39450513335f550b56da13b30aztenghui            mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
1037a95c8abb366d9c39450513335f550b56da13b30aztenghui            mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
1038a95c8abb366d9c39450513335f550b56da13b30aztenghui            mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
1039a95c8abb366d9c39450513335f550b56da13b30aztenghui
1040a95c8abb366d9c39450513335f550b56da13b30aztenghui            final String groupName = a.getString(R.styleable.VectorDrawableGroup_name);
1041a95c8abb366d9c39450513335f550b56da13b30aztenghui            if (groupName != null) {
1042a95c8abb366d9c39450513335f550b56da13b30aztenghui                mGroupName = groupName;
1043a95c8abb366d9c39450513335f550b56da13b30aztenghui            }
1044a95c8abb366d9c39450513335f550b56da13b30aztenghui
1045a95c8abb366d9c39450513335f550b56da13b30aztenghui            updateLocalMatrix();
1046a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1047a95c8abb366d9c39450513335f550b56da13b30aztenghui
1048a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void applyTheme(Theme t) {
1049a95c8abb366d9c39450513335f550b56da13b30aztenghui            if (mThemeAttrs == null) {
1050a95c8abb366d9c39450513335f550b56da13b30aztenghui                return;
1051a95c8abb366d9c39450513335f550b56da13b30aztenghui            }
1052a95c8abb366d9c39450513335f550b56da13b30aztenghui
1053a95c8abb366d9c39450513335f550b56da13b30aztenghui            final TypedArray a = t.resolveAttributes(mThemeAttrs,
1054a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawableGroup);
1055a95c8abb366d9c39450513335f550b56da13b30aztenghui            updateStateFromTypedArray(a);
1056a95c8abb366d9c39450513335f550b56da13b30aztenghui            a.recycle();
1057a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1058a95c8abb366d9c39450513335f550b56da13b30aztenghui
1059a95c8abb366d9c39450513335f550b56da13b30aztenghui        private void updateLocalMatrix() {
1060a95c8abb366d9c39450513335f550b56da13b30aztenghui            // The order we apply is the same as the
1061a95c8abb366d9c39450513335f550b56da13b30aztenghui            // RenderNode.cpp::applyViewPropertyTransforms().
1062a95c8abb366d9c39450513335f550b56da13b30aztenghui            mLocalMatrix.reset();
1063a95c8abb366d9c39450513335f550b56da13b30aztenghui            mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
1064a95c8abb366d9c39450513335f550b56da13b30aztenghui            mLocalMatrix.postScale(mScaleX, mScaleY);
1065a95c8abb366d9c39450513335f550b56da13b30aztenghui            mLocalMatrix.postRotate(mRotate, 0, 0);
1066a95c8abb366d9c39450513335f550b56da13b30aztenghui            mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
1067a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1068a95c8abb366d9c39450513335f550b56da13b30aztenghui
1069a95c8abb366d9c39450513335f550b56da13b30aztenghui        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
1070a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1071e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getRotation() {
1072e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mRotate;
1073e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1074e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1075a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1076e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setRotation(float rotation) {
1077e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (rotation != mRotate) {
1078e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mRotate = rotation;
1079e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
1080e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1081e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1082e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1083a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1084e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getPivotX() {
1085e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPivotX;
1086e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1087e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1088a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1089e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setPivotX(float pivotX) {
1090e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (pivotX != mPivotX) {
1091e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPivotX = pivotX;
1092e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
1093e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1094e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1095e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1096a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1097e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getPivotY() {
1098e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPivotY;
1099e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1100e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1101a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1102e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setPivotY(float pivotY) {
1103e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (pivotY != mPivotY) {
1104e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPivotY = pivotY;
1105e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
1106e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1107e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1108e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1109a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1110e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getScaleX() {
1111e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mScaleX;
1112e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
11134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
1114a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1115e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setScaleX(float scaleX) {
1116e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (scaleX != mScaleX) {
1117e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mScaleX = scaleX;
1118e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
1119e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1120e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1121e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1122a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1123e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getScaleY() {
1124e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mScaleY;
1125e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1126e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1127a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1128e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setScaleY(float scaleY) {
1129e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (scaleY != mScaleY) {
1130e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mScaleY = scaleY;
1131e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
1132e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1133e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1134e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1135a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1136e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getTranslateX() {
1137e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTranslateX;
1138e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1139e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1140a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1141e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setTranslateX(float translateX) {
1142e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (translateX != mTranslateX) {
1143e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mTranslateX = translateX;
1144e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
1145e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1146e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1147e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1148a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1149e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getTranslateY() {
1150e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTranslateY;
1151e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1152e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1153a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1154e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setTranslateY(float translateY) {
1155e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (translateY != mTranslateY) {
1156e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mTranslateY = translateY;
1157e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
1158e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1159e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1160a95c8abb366d9c39450513335f550b56da13b30aztenghui    }
1161e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1162a95c8abb366d9c39450513335f550b56da13b30aztenghui    /**
1163a95c8abb366d9c39450513335f550b56da13b30aztenghui     * Common Path information for clip path and normal path.
1164a95c8abb366d9c39450513335f550b56da13b30aztenghui     */
1165a95c8abb366d9c39450513335f550b56da13b30aztenghui    private static class VPath {
1166a95c8abb366d9c39450513335f550b56da13b30aztenghui        protected PathParser.PathDataNode[] mNodes = null;
1167a95c8abb366d9c39450513335f550b56da13b30aztenghui        String mPathName;
1168a95c8abb366d9c39450513335f550b56da13b30aztenghui        int mChangingConfigurations;
1169a95c8abb366d9c39450513335f550b56da13b30aztenghui
1170a95c8abb366d9c39450513335f550b56da13b30aztenghui        public VPath() {
1171a95c8abb366d9c39450513335f550b56da13b30aztenghui            // Empty constructor.
11724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
11734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
1174a95c8abb366d9c39450513335f550b56da13b30aztenghui        public VPath(VPath copy) {
1175a95c8abb366d9c39450513335f550b56da13b30aztenghui            mPathName = copy.mPathName;
1176a95c8abb366d9c39450513335f550b56da13b30aztenghui            mChangingConfigurations = copy.mChangingConfigurations;
1177a95c8abb366d9c39450513335f550b56da13b30aztenghui            mNodes = PathParser.deepCopyNodes(copy.mNodes);
11784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
11794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
1180a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void toPath(Path path) {
1181a95c8abb366d9c39450513335f550b56da13b30aztenghui            path.reset();
1182a95c8abb366d9c39450513335f550b56da13b30aztenghui            if (mNodes != null) {
1183a95c8abb366d9c39450513335f550b56da13b30aztenghui                PathParser.PathDataNode.nodesToPath(mNodes, path);
1184a95c8abb366d9c39450513335f550b56da13b30aztenghui            }
11854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
11864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
1187a95c8abb366d9c39450513335f550b56da13b30aztenghui        public String getPathName() {
1188a95c8abb366d9c39450513335f550b56da13b30aztenghui            return mPathName;
11898e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        }
11908e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
1191a95c8abb366d9c39450513335f550b56da13b30aztenghui        public boolean canApplyTheme() {
1192a95c8abb366d9c39450513335f550b56da13b30aztenghui            return false;
1193a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
119463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
1195a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void applyTheme(Theme t) {
1196a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
119763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
1198a95c8abb366d9c39450513335f550b56da13b30aztenghui        public boolean isClipPath() {
1199a95c8abb366d9c39450513335f550b56da13b30aztenghui            return false;
1200a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
120163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
1202a95c8abb366d9c39450513335f550b56da13b30aztenghui        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
1203a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1204a95c8abb366d9c39450513335f550b56da13b30aztenghui        public PathParser.PathDataNode[] getPathData() {
1205a95c8abb366d9c39450513335f550b56da13b30aztenghui            return mNodes;
1206a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1207a95c8abb366d9c39450513335f550b56da13b30aztenghui
1208a95c8abb366d9c39450513335f550b56da13b30aztenghui        @SuppressWarnings("unused")
1209a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void setPathData(PathParser.PathDataNode[] nodes) {
1210a95c8abb366d9c39450513335f550b56da13b30aztenghui            if (!PathParser.canMorph(mNodes, nodes)) {
1211a95c8abb366d9c39450513335f550b56da13b30aztenghui                // This should not happen in the middle of animation.
1212a95c8abb366d9c39450513335f550b56da13b30aztenghui                mNodes = PathParser.deepCopyNodes(nodes);
1213a95c8abb366d9c39450513335f550b56da13b30aztenghui            } else {
1214a95c8abb366d9c39450513335f550b56da13b30aztenghui                PathParser.updateNodes(mNodes, nodes);
121563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            }
1216a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1217a95c8abb366d9c39450513335f550b56da13b30aztenghui    }
121863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
1219a95c8abb366d9c39450513335f550b56da13b30aztenghui    /**
1220a95c8abb366d9c39450513335f550b56da13b30aztenghui     * Clip path, which only has name and pathData.
1221a95c8abb366d9c39450513335f550b56da13b30aztenghui     */
1222a95c8abb366d9c39450513335f550b56da13b30aztenghui    private static class VClipPath extends VPath{
1223a95c8abb366d9c39450513335f550b56da13b30aztenghui        public VClipPath() {
1224a95c8abb366d9c39450513335f550b56da13b30aztenghui            // Empty constructor.
12258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        }
12264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
1227a95c8abb366d9c39450513335f550b56da13b30aztenghui        public VClipPath(VClipPath copy) {
1228a95c8abb366d9c39450513335f550b56da13b30aztenghui            super(copy);
1229a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
12304d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
1231a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void inflate(Resources r, AttributeSet attrs, Theme theme) {
1232a95c8abb366d9c39450513335f550b56da13b30aztenghui            final TypedArray a = obtainAttributes(r, theme, attrs,
1233a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawableClipPath);
12348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            updateStateFromTypedArray(a);
123563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            a.recycle();
123663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        }
123763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
1238a95c8abb366d9c39450513335f550b56da13b30aztenghui        private void updateStateFromTypedArray(TypedArray a) {
1239a95c8abb366d9c39450513335f550b56da13b30aztenghui            // Account for any configuration changes.
1240a95c8abb366d9c39450513335f550b56da13b30aztenghui            mChangingConfigurations |= a.getChangingConfigurations();
1241a95c8abb366d9c39450513335f550b56da13b30aztenghui
1242a95c8abb366d9c39450513335f550b56da13b30aztenghui            mPathName = a.getString(R.styleable.VectorDrawableClipPath_name);
1243a95c8abb366d9c39450513335f550b56da13b30aztenghui            mNodes = PathParser.createNodesFromPathData(a.getString(
1244a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawableClipPath_pathData));
1245a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1246a95c8abb366d9c39450513335f550b56da13b30aztenghui
1247a95c8abb366d9c39450513335f550b56da13b30aztenghui        @Override
1248a95c8abb366d9c39450513335f550b56da13b30aztenghui        public boolean isClipPath() {
1249a95c8abb366d9c39450513335f550b56da13b30aztenghui            return true;
12504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
1251abb7d134c02ac60091108c491dafb00877093170John Hoford    }
1252abb7d134c02ac60091108c491dafb00877093170John Hoford
1253a95c8abb366d9c39450513335f550b56da13b30aztenghui    /**
1254a95c8abb366d9c39450513335f550b56da13b30aztenghui     * Normal path, which contains all the fill / paint information.
1255a95c8abb366d9c39450513335f550b56da13b30aztenghui     */
1256a95c8abb366d9c39450513335f550b56da13b30aztenghui    private static class VFullPath extends VPath {
125755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        /////////////////////////////////////////////////////
125855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables below need to be copied (deep copy if applicable) for mutation.
12599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        private int[] mThemeAttrs;
12609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1261a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui        int mStrokeColor = Color.TRANSPARENT;
1262abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeWidth = 0;
12632e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui
1264a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui        int mFillColor = Color.TRANSPARENT;
12652e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        float mStrokeAlpha = 1.0f;
1266abb7d134c02ac60091108c491dafb00877093170John Hoford        int mFillRule;
12672e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        float mFillAlpha = 1.0f;
1268abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathStart = 0;
1269abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathEnd = 1;
1270abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathOffset = 0;
12719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12724b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        Paint.Cap mStrokeLineCap = Paint.Cap.BUTT;
12734b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        Paint.Join mStrokeLineJoin = Paint.Join.MITER;
1274abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeMiterlimit = 4;
12759453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1276a95c8abb366d9c39450513335f550b56da13b30aztenghui        public VFullPath() {
12779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            // Empty constructor.
12789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
12799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1280a95c8abb366d9c39450513335f550b56da13b30aztenghui        public VFullPath(VFullPath copy) {
1281a95c8abb366d9c39450513335f550b56da13b30aztenghui            super(copy);
128255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mThemeAttrs = copy.mThemeAttrs;
128355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
128455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeColor = copy.mStrokeColor;
128555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeWidth = copy.mStrokeWidth;
12862e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            mStrokeAlpha = copy.mStrokeAlpha;
128755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mFillColor = copy.mFillColor;
128855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mFillRule = copy.mFillRule;
12892e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            mFillAlpha = copy.mFillAlpha;
129055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTrimPathStart = copy.mTrimPathStart;
129155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTrimPathEnd = copy.mTrimPathEnd;
129255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTrimPathOffset = copy.mTrimPathOffset;
129355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
129455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeLineCap = copy.mStrokeLineCap;
129555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeLineJoin = copy.mStrokeLineJoin;
129655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeMiterlimit = copy.mStrokeMiterlimit;
1297abb7d134c02ac60091108c491dafb00877093170John Hoford        }
1298abb7d134c02ac60091108c491dafb00877093170John Hoford
12997f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) {
13007f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            switch (id) {
13017f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_BUTT:
13027f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.BUTT;
13037f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_ROUND:
13047f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.ROUND;
13057f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_SQUARE:
13067f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.SQUARE;
13077f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                default:
13087f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return defValue;
13097f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
13107f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        }
13117f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
13127f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) {
13137f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            switch (id) {
13147f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_MITER:
13157f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.MITER;
13167f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_ROUND:
13177f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.ROUND;
13187f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_BEVEL:
13197f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.BEVEL;
13207f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                default:
13217f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return defValue;
13227f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
13237f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        }
13247f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
1325a95c8abb366d9c39450513335f550b56da13b30aztenghui        @Override
1326a95c8abb366d9c39450513335f550b56da13b30aztenghui        public boolean canApplyTheme() {
1327a95c8abb366d9c39450513335f550b56da13b30aztenghui            return mThemeAttrs != null;
1328eb034fbca40006c55db143047eb628c4b657730aztenghui        }
1329eb034fbca40006c55db143047eb628c4b657730aztenghui
1330a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void inflate(Resources r, AttributeSet attrs, Theme theme) {
1331a95c8abb366d9c39450513335f550b56da13b30aztenghui            final TypedArray a = obtainAttributes(r, theme, attrs,
1332a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath);
1333a95c8abb366d9c39450513335f550b56da13b30aztenghui            updateStateFromTypedArray(a);
1334a95c8abb366d9c39450513335f550b56da13b30aztenghui            a.recycle();
1335a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1336a95c8abb366d9c39450513335f550b56da13b30aztenghui
1337a95c8abb366d9c39450513335f550b56da13b30aztenghui        private void updateStateFromTypedArray(TypedArray a) {
1338a95c8abb366d9c39450513335f550b56da13b30aztenghui            // Account for any configuration changes.
1339a95c8abb366d9c39450513335f550b56da13b30aztenghui            mChangingConfigurations |= a.getChangingConfigurations();
1340a95c8abb366d9c39450513335f550b56da13b30aztenghui
1341a95c8abb366d9c39450513335f550b56da13b30aztenghui            // Extract the theme attributes, if any.
1342a95c8abb366d9c39450513335f550b56da13b30aztenghui            mThemeAttrs = a.extractThemeAttrs();
1343a95c8abb366d9c39450513335f550b56da13b30aztenghui
1344a95c8abb366d9c39450513335f550b56da13b30aztenghui            mPathName = a.getString(R.styleable.VectorDrawablePath_name);
1345a95c8abb366d9c39450513335f550b56da13b30aztenghui            mNodes = PathParser.createNodesFromPathData(a.getString(
1346a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath_pathData));
1347a95c8abb366d9c39450513335f550b56da13b30aztenghui
1348a95c8abb366d9c39450513335f550b56da13b30aztenghui            mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor,
1349a95c8abb366d9c39450513335f550b56da13b30aztenghui                    mFillColor);
13502e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha,
13512e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                    mFillAlpha);
1352a95c8abb366d9c39450513335f550b56da13b30aztenghui            mStrokeLineCap = getStrokeLineCap(a.getInt(
1353a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap);
1354a95c8abb366d9c39450513335f550b56da13b30aztenghui            mStrokeLineJoin = getStrokeLineJoin(a.getInt(
1355a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin);
1356a95c8abb366d9c39450513335f550b56da13b30aztenghui            mStrokeMiterlimit = a.getFloat(
1357a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit);
1358a95c8abb366d9c39450513335f550b56da13b30aztenghui            mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor,
1359a95c8abb366d9c39450513335f550b56da13b30aztenghui                    mStrokeColor);
13602e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha,
13612e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui                    mStrokeAlpha);
1362a95c8abb366d9c39450513335f550b56da13b30aztenghui            mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth,
1363a95c8abb366d9c39450513335f550b56da13b30aztenghui                    mStrokeWidth);
1364a95c8abb366d9c39450513335f550b56da13b30aztenghui            mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd,
1365a95c8abb366d9c39450513335f550b56da13b30aztenghui                    mTrimPathEnd);
1366a95c8abb366d9c39450513335f550b56da13b30aztenghui            mTrimPathOffset = a.getFloat(
1367a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset);
1368a95c8abb366d9c39450513335f550b56da13b30aztenghui            mTrimPathStart = a.getFloat(
1369a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart);
1370a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1371a95c8abb366d9c39450513335f550b56da13b30aztenghui
1372a95c8abb366d9c39450513335f550b56da13b30aztenghui        @Override
1373a95c8abb366d9c39450513335f550b56da13b30aztenghui        public void applyTheme(Theme t) {
1374a95c8abb366d9c39450513335f550b56da13b30aztenghui            if (mThemeAttrs == null) {
1375a95c8abb366d9c39450513335f550b56da13b30aztenghui                return;
1376a95c8abb366d9c39450513335f550b56da13b30aztenghui            }
1377a95c8abb366d9c39450513335f550b56da13b30aztenghui
1378a95c8abb366d9c39450513335f550b56da13b30aztenghui            final TypedArray a = t.resolveAttributes(mThemeAttrs,
1379a95c8abb366d9c39450513335f550b56da13b30aztenghui                    R.styleable.VectorDrawablePath);
1380a95c8abb366d9c39450513335f550b56da13b30aztenghui            updateStateFromTypedArray(a);
1381a95c8abb366d9c39450513335f550b56da13b30aztenghui            a.recycle();
1382a95c8abb366d9c39450513335f550b56da13b30aztenghui        }
1383a95c8abb366d9c39450513335f550b56da13b30aztenghui
1384a95c8abb366d9c39450513335f550b56da13b30aztenghui        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
1385eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1386e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        int getStroke() {
1387e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeColor;
1388e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1389e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1390eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1391e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStroke(int strokeColor) {
1392e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeColor = strokeColor;
1393e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1394e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1395eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1396e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getStrokeWidth() {
1397e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeWidth;
1398e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1399e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1400eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1401e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStrokeWidth(float strokeWidth) {
1402e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeWidth = strokeWidth;
1403e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1404e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1405eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
14062e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        float getstrokeAlpha() {
14072e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            return mStrokeAlpha;
14082e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        }
14092e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui
14102e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        @SuppressWarnings("unused")
14112e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        void setstrokeAlpha(float strokeAlpha) {
14122e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            mStrokeAlpha = strokeAlpha;
14132e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        }
14142e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui
14152e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        @SuppressWarnings("unused")
1416e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        int getFill() {
1417e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mFillColor;
1418e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1419e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1420eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1421e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setFill(int fillColor) {
1422e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mFillColor = fillColor;
1423e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1424e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1425eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
14262e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        float getfillAlpha() {
14272e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            return mFillAlpha;
14282e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        }
14292e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui
14302e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        @SuppressWarnings("unused")
14312e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        void setfillAlpha(float fillAlpha) {
14322e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui            mFillAlpha = fillAlpha;
14332e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        }
14342e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui
14352e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui        @SuppressWarnings("unused")
1436e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathStart() {
1437e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathStart;
1438e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1439e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1440eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1441e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathStart(float trimPathStart) {
1442e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathStart = trimPathStart;
1443e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1444e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1445eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1446e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathEnd() {
1447e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathEnd;
1448e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1449e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1450eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1451e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathEnd(float trimPathEnd) {
1452e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathEnd = trimPathEnd;
1453e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1454e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1455eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1456e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathOffset() {
1457e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathOffset;
1458e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1459e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1460eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1461e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathOffset(float trimPathOffset) {
1462e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathOffset = trimPathOffset;
1463e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1464abb7d134c02ac60091108c491dafb00877093170John Hoford    }
1465abb7d134c02ac60091108c491dafb00877093170John Hoford}
1466