VectorDrawable.java revision 9cd14fc710cf81cc6d1c47d599abe349d3aa87dc
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;
21abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Canvas;
222af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghuiimport android.graphics.Color;
23abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.ColorFilter;
24abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Matrix;
25abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Paint;
26abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Path;
27abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PathMeasure;
28abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PixelFormat;
29b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuffColorFilter;
30abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Rect;
31abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Region;
32b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode;
33e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.ArrayMap;
34abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.AttributeSet;
35abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.Log;
36cf4832f69c8786b098ce18c24319021f8cd6733aztenghuiimport android.util.PathParser;
374b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport android.util.Xml;
38abb7d134c02ac60091108c491dafb00877093170John Hoford
39abb7d134c02ac60091108c491dafb00877093170John Hofordimport com.android.internal.R;
40abb7d134c02ac60091108c491dafb00877093170John Hoford
41abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParser;
42abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParserException;
434b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport org.xmlpull.v1.XmlPullParserFactory;
44abb7d134c02ac60091108c491dafb00877093170John Hoford
45abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException;
46abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList;
47abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.Arrays;
484d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack;
494b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
50abb7d134c02ac60091108c491dafb00877093170John Hoford/**
51d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * This lets you create a drawable based on an XML vector graphic It can be
52d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code>&lt;vector></code> element.
53abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/>
5446e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * The vector drawable has the following elements:
55abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/>
56abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl>
57177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code>&lt;vector></code></dt>
58e3c45e7a6b2a7d2176aa46ee482e299b54feeb9fztenghui * <dd>Used to defined a vector drawable</dd>
59abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>&lt;size></code></dt>
60abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the intrinsic Width Height size of the drawable using
61d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:width</code> and <code>android:height</code></dd>
62abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>&lt;viewport></code></dt>
63abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the size of the virtual canvas the paths are drawn on.
64d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * The size is defined using the attributes <code>android:viewportHeight</code>
65d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:viewportWidth</code></dd>
666d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code>&lt;group></code></dt>
67452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information.
68452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport.
69452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * And the transformations are applied in the order of scale, rotate then translate. </dd>
70452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:rotation</code>
71452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The degrees of rotation of the group.</dd></dt>
72452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotX</code>
73452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group</dd></dt>
74452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotY</code>
75452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group</dd></dt>
76452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleX</code>
77452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the X Coordinate</dd></dt>
78452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleY</code>
79452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the Y coordinate</dd></dt>
80452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateX</code>
81452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the X coordinate</dd></dt>
82452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateY</code>
83452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the Y coordinate</dd></dt>
84abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>&lt;path></code></dt>
856d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn.
86abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl>
87abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:name</code>
88abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the name of the path.</dd></dt>
89abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:pathData</code>
9046e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute
9146e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * in the SVG's path data</dd></dt>
92abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fill</code>
93abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the color to fill the path (none if not present).</dd></dt>
94abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:stroke</code>
95d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd>
96d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * </dt>
97abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeWidth</code>
98abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The width a path stroke</dd></dt>
99abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeOpacity</code>
100abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity of a path stroke</dd></dt>
101abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fillOpacity</code>
102abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity to fill the path with</dd></dt>
103abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathStart</code>
104abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the start from 0 to 1</dd></dt>
105abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathEnd</code>
106abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the end from 0 to 1</dd></dt>
107abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathOffset</code>
108d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Shift trim region (allows showed region to include the start and end)
109d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * from 0 to 1</dd></dt>
110abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:clipToPath</code>
111abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Path will set the clip path</dd></dt>
112abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineCap</code>
113abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the linecap for a stroked path: butt, round, square</dd></dt>
114abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineJoin</code>
115abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the lineJoin for a stroked path: miter,round,bevel</dd></dt>
116abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeMiterLimit</code>
117abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the Miter limit for a stroked path</dd></dt>
118abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl>
119abb7d134c02ac60091108c491dafb00877093170John Hoford * </dd>
120abb7d134c02ac60091108c491dafb00877093170John Hoford */
121abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable {
1229453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    private static final String LOGTAG = VectorDrawable.class.getSimpleName();
1239453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
124abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_SIZE = "size";
125abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_VIEWPORT = "viewport";
1266d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui    private static final String SHAPE_GROUP = "group";
127abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_PATH = "path";
128abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_VECTOR = "vector";
129abb7d134c02ac60091108c491dafb00877093170John Hoford
130abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_BUTT = 0;
131abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_ROUND = 1;
132abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_SQUARE = 2;
1339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
134abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_MITER = 0;
135abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_ROUND = 1;
136abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_BEVEL = 2;
1379453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1384d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    private static final boolean DBG_VECTOR_DRAWABLE = false;
1394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
1404b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette    private final VectorDrawableState mVectorState;
1414b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
142e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    private final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
143e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
144b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    private PorterDuffColorFilter mTintFilter;
145b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
146abb7d134c02ac60091108c491dafb00877093170John Hoford    public VectorDrawable() {
1479453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        mVectorState = new VectorDrawableState(null);
148abb7d134c02ac60091108c491dafb00877093170John Hoford    }
149abb7d134c02ac60091108c491dafb00877093170John Hoford
1509453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) {
15116c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui        if (theme != null && state.canApplyTheme()) {
15216c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            // If we need to apply a theme, implicitly mutate.
15316c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            mVectorState = new VectorDrawableState(state);
1549453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            applyTheme(theme);
15516c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui        } else {
15616c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            mVectorState = state;
1579453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
158b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
159b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
160b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
161abb7d134c02ac60091108c491dafb00877093170John Hoford    }
162abb7d134c02ac60091108c491dafb00877093170John Hoford
163e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    Object getTargetByName(String name) {
164e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        return mVGTargetsMap.get(name);
165e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    }
166e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
167abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
168abb7d134c02ac60091108c491dafb00877093170John Hoford    public ConstantState getConstantState() {
169abb7d134c02ac60091108c491dafb00877093170John Hoford        return mVectorState;
170abb7d134c02ac60091108c491dafb00877093170John Hoford    }
171abb7d134c02ac60091108c491dafb00877093170John Hoford
1724554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette    @Override
173abb7d134c02ac60091108c491dafb00877093170John Hoford    public void draw(Canvas canvas) {
1744b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        final int saveCount = canvas.save();
1754b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        final Rect bounds = getBounds();
1764b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        canvas.translate(bounds.left, bounds.top);
177ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height());
1784b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        canvas.restoreToCount(saveCount);
179abb7d134c02ac60091108c491dafb00877093170John Hoford    }
180abb7d134c02ac60091108c491dafb00877093170John Hoford
181abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
182e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    public int getAlpha() {
183e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        return mVectorState.mVPathRenderer.getRootAlpha();
184e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    }
185e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
186e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    @Override
187abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setAlpha(int alpha) {
1882af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) {
1892af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mVectorState.mVPathRenderer.setRootAlpha(alpha);
190abb7d134c02ac60091108c491dafb00877093170John Hoford            invalidateSelf();
191abb7d134c02ac60091108c491dafb00877093170John Hoford        }
192abb7d134c02ac60091108c491dafb00877093170John Hoford    }
193abb7d134c02ac60091108c491dafb00877093170John Hoford
194abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
195abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setColorFilter(ColorFilter colorFilter) {
196b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
197b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (colorFilter != null) {
198b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            // Color filter overrides tint.
199b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = null;
200b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        } else if (state.mTint != null && state.mTintMode != null) {
201b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            // Restore the tint filter, if we need one.
202b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT);
203b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
204b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            colorFilter = mTintFilter;
205b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
206b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
207b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        state.mVPathRenderer.setColorFilter(colorFilter);
208fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        invalidateSelf();
209abb7d134c02ac60091108c491dafb00877093170John Hoford    }
210abb7d134c02ac60091108c491dafb00877093170John Hoford
211abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
212b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    public void setTint(ColorStateList tint, Mode tintMode) {
213b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
214b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (state.mTint != tint || state.mTintMode != tintMode) {
215b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            state.mTint = tint;
216b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            state.mTintMode = tintMode;
217b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
218b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
219b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
220b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            invalidateSelf();
221b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
222b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
223b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
224b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
225b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    protected boolean onStateChange(int[] stateSet) {
226b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
227b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (state.mTint != null && state.mTintMode != null) {
228b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
229b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
230b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            return true;
231b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
232b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        return false;
233b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
234b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
235b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
236abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getOpacity() {
237abb7d134c02ac60091108c491dafb00877093170John Hoford        return PixelFormat.TRANSLUCENT;
238abb7d134c02ac60091108c491dafb00877093170John Hoford    }
239abb7d134c02ac60091108c491dafb00877093170John Hoford
240abb7d134c02ac60091108c491dafb00877093170John Hoford    /**
241d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette     * Sets padding for this shape, defined by a Rect object. Define the padding
242d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette     * in the Rect object as: left, top, right, bottom.
243abb7d134c02ac60091108c491dafb00877093170John Hoford     */
244abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setPadding(Rect padding) {
245abb7d134c02ac60091108c491dafb00877093170John Hoford        setPadding(padding.left, padding.top, padding.right, padding.bottom);
246abb7d134c02ac60091108c491dafb00877093170John Hoford    }
247abb7d134c02ac60091108c491dafb00877093170John Hoford
248abb7d134c02ac60091108c491dafb00877093170John Hoford    /**
249abb7d134c02ac60091108c491dafb00877093170John Hoford     * Sets padding for the shape.
250abb7d134c02ac60091108c491dafb00877093170John Hoford     *
251abb7d134c02ac60091108c491dafb00877093170John Hoford     * @param left padding for the left side (in pixels)
252abb7d134c02ac60091108c491dafb00877093170John Hoford     * @param top padding for the top (in pixels)
253abb7d134c02ac60091108c491dafb00877093170John Hoford     * @param right padding for the right side (in pixels)
254abb7d134c02ac60091108c491dafb00877093170John Hoford     * @param bottom padding for the bottom (in pixels)
255abb7d134c02ac60091108c491dafb00877093170John Hoford     */
256abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setPadding(int left, int top, int right, int bottom) {
257abb7d134c02ac60091108c491dafb00877093170John Hoford        if ((left | top | right | bottom) == 0) {
258abb7d134c02ac60091108c491dafb00877093170John Hoford            mVectorState.mPadding = null;
259abb7d134c02ac60091108c491dafb00877093170John Hoford        } else {
260abb7d134c02ac60091108c491dafb00877093170John Hoford            if (mVectorState.mPadding == null) {
261abb7d134c02ac60091108c491dafb00877093170John Hoford                mVectorState.mPadding = new Rect();
262abb7d134c02ac60091108c491dafb00877093170John Hoford            }
263abb7d134c02ac60091108c491dafb00877093170John Hoford            mVectorState.mPadding.set(left, top, right, bottom);
264abb7d134c02ac60091108c491dafb00877093170John Hoford        }
265abb7d134c02ac60091108c491dafb00877093170John Hoford        invalidateSelf();
266abb7d134c02ac60091108c491dafb00877093170John Hoford    }
267abb7d134c02ac60091108c491dafb00877093170John Hoford
268abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
269abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getIntrinsicWidth() {
270ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        return (int) mVectorState.mVPathRenderer.mBaseWidth;
271abb7d134c02ac60091108c491dafb00877093170John Hoford    }
272abb7d134c02ac60091108c491dafb00877093170John Hoford
273abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
274abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getIntrinsicHeight() {
275ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        return (int) mVectorState.mVPathRenderer.mBaseHeight;
276abb7d134c02ac60091108c491dafb00877093170John Hoford    }
277abb7d134c02ac60091108c491dafb00877093170John Hoford
278abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
279abb7d134c02ac60091108c491dafb00877093170John Hoford    public boolean getPadding(Rect padding) {
280abb7d134c02ac60091108c491dafb00877093170John Hoford        if (mVectorState.mPadding != null) {
281abb7d134c02ac60091108c491dafb00877093170John Hoford            padding.set(mVectorState.mPadding);
282abb7d134c02ac60091108c491dafb00877093170John Hoford            return true;
283abb7d134c02ac60091108c491dafb00877093170John Hoford        } else {
284abb7d134c02ac60091108c491dafb00877093170John Hoford            return super.getPadding(padding);
285abb7d134c02ac60091108c491dafb00877093170John Hoford        }
286abb7d134c02ac60091108c491dafb00877093170John Hoford    }
287abb7d134c02ac60091108c491dafb00877093170John Hoford
288abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
2899453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    public boolean canApplyTheme() {
2909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme();
2919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    }
2929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
2939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    @Override
2949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    public void applyTheme(Theme t) {
2959453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        super.applyTheme(t);
2969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
2979453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        final VectorDrawableState state = mVectorState;
298ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        final VPathRenderer path = state.mVPathRenderer;
2999453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        if (path != null && path.canApplyTheme()) {
3009453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            path.applyTheme(t);
3019453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
3029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    }
3039453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
3044b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette    /** @hide */
3054b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette    public static VectorDrawable create(Resources resources, int rid) {
3064b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        try {
3074b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            final XmlPullParser xpp = resources.getXml(rid);
3084b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            final AttributeSet attrs = Xml.asAttributeSet(xpp);
3094b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
3104b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            factory.setNamespaceAware(true);
3114b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette
3124b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            final VectorDrawable drawable = new VectorDrawable();
3134b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            drawable.inflate(resources, xpp, attrs);
3144b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette
3154b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            return drawable;
3164b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        } catch (XmlPullParserException e) {
3174b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            Log.e(LOGTAG, "parser error", e);
3184b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        } catch (IOException e) {
3194b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette            Log.e(LOGTAG, "parser error", e);
3204b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        }
3214b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette        return null;
3224b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette    }
3234b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette
3242af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui    private static int applyAlpha(int color, float alpha) {
3252af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        int alphaBytes = Color.alpha(color);
3262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        color &= 0x00FFFFFF;
3272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        color |= ((int) (alphaBytes * alpha)) << 24;
3282af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        return color;
3292af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui    }
3302af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
3319cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3329cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    @Override
3339cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
3349cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            throws XmlPullParserException, IOException {
3359cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final TypedArray a = obtainAttributes(res, theme,  attrs,R.styleable.VectorDrawable);
3369cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        updateStateFromTypedArray(a);
3379cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        a.recycle();
3389cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3399cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final VectorDrawableState state = mVectorState;
3409cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        state.mVPathRenderer = inflateInternal(res, parser, attrs, theme);
3419cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3429cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
3439cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        state.mVPathRenderer.setColorFilter(mTintFilter);
3449cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    }
3459cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3469cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    private void updateStateFromTypedArray(TypedArray a) {
3479cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final VectorDrawableState state = mVectorState;
3489cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3499cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        // Extract the theme attributes, if any.
3509cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        state.mThemeAttrs = a.extractThemeAttrs();
3519cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3529cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1);
3539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        if (tintMode != -1) {
3549cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
3559cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        }
3569cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3579cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint);
3589cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        if (tint != null) {
3599cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            state.mTint = tint;
3609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        }
3619cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    }
3629cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3639cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    private VPathRenderer inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
3649cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            throws XmlPullParserException, IOException {
365ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        final VPathRenderer pathRenderer = new VPathRenderer();
3669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
367abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean noSizeTag = true;
368abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean noViewportTag = true;
369abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean noPathTag = true;
3709453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
3714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Use a stack to help to build the group tree.
3724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // The top of the stack is always the current group.
3734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        final Stack<VGroup> groupStack = new Stack<VGroup>();
3744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        groupStack.push(pathRenderer.mRootGroup);
375abb7d134c02ac60091108c491dafb00877093170John Hoford
376abb7d134c02ac60091108c491dafb00877093170John Hoford        int eventType = parser.getEventType();
377abb7d134c02ac60091108c491dafb00877093170John Hoford        while (eventType != XmlPullParser.END_DOCUMENT) {
378abb7d134c02ac60091108c491dafb00877093170John Hoford            if (eventType == XmlPullParser.START_TAG) {
3799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                final String tagName = parser.getName();
3804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final VGroup currentGroup = groupStack.peek();
3814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
382abb7d134c02ac60091108c491dafb00877093170John Hoford                if (SHAPE_PATH.equals(tagName)) {
3839453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                    final VPath path = new VPath();
3849453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                    path.inflate(res, attrs, theme);
3859453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                    currentGroup.add(path);
386e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    if (path.getPathName() != null) {
387e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                        mVGTargetsMap.put(path.getPathName(), path);
388e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    }
389abb7d134c02ac60091108c491dafb00877093170John Hoford                    noPathTag = false;
390abb7d134c02ac60091108c491dafb00877093170John Hoford                } else if (SHAPE_SIZE.equals(tagName)) {
391ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui                    pathRenderer.parseSize(res, attrs);
392abb7d134c02ac60091108c491dafb00877093170John Hoford                    noSizeTag = false;
393abb7d134c02ac60091108c491dafb00877093170John Hoford                } else if (SHAPE_VIEWPORT.equals(tagName)) {
394ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui                    pathRenderer.parseViewport(res, attrs);
395abb7d134c02ac60091108c491dafb00877093170John Hoford                    noViewportTag = false;
3966d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui                } else if (SHAPE_GROUP.equals(tagName)) {
3974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    VGroup newChildGroup = new VGroup();
3984d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    newChildGroup.inflate(res, attrs, theme);
3994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    currentGroup.mChildGroupList.add(newChildGroup);
4004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    groupStack.push(newChildGroup);
401e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    if (newChildGroup.getGroupName() != null) {
402e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                        mVGTargetsMap.put(newChildGroup.getGroupName(), newChildGroup);
403e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    }
404abb7d134c02ac60091108c491dafb00877093170John Hoford                }
4054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            } else if (eventType == XmlPullParser.END_TAG) {
4064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final String tagName = parser.getName();
4074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                if (SHAPE_GROUP.equals(tagName)) {
4084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    groupStack.pop();
4094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
410abb7d134c02ac60091108c491dafb00877093170John Hoford            }
411abb7d134c02ac60091108c491dafb00877093170John Hoford            eventType = parser.next();
412abb7d134c02ac60091108c491dafb00877093170John Hoford        }
4139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
4144d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Print the tree out for debug.
4154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        if (DBG_VECTOR_DRAWABLE) {
4164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            printGroupTree(pathRenderer.mRootGroup, 0);
4176d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui        }
4186d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui
41946e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui        if (noSizeTag || noViewportTag || noPathTag) {
4209453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final StringBuffer tag = new StringBuffer();
4219453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
422abb7d134c02ac60091108c491dafb00877093170John Hoford            if (noSizeTag) {
4239453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                tag.append(SHAPE_SIZE);
424abb7d134c02ac60091108c491dafb00877093170John Hoford            }
4259453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
426d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette            if (noViewportTag) {
427d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette                if (tag.length() > 0) {
428abb7d134c02ac60091108c491dafb00877093170John Hoford                    tag.append(" & ");
429abb7d134c02ac60091108c491dafb00877093170John Hoford                }
4309453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                tag.append(SHAPE_SIZE);
431abb7d134c02ac60091108c491dafb00877093170John Hoford            }
4329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
433d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette            if (noPathTag) {
434d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette                if (tag.length() > 0) {
435abb7d134c02ac60091108c491dafb00877093170John Hoford                    tag.append(" or ");
436abb7d134c02ac60091108c491dafb00877093170John Hoford                }
4379453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                tag.append(SHAPE_PATH);
438abb7d134c02ac60091108c491dafb00877093170John Hoford            }
4399453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
4409453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            throw new XmlPullParserException("no " + tag + " defined");
441abb7d134c02ac60091108c491dafb00877093170John Hoford        }
4429453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
443ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        return pathRenderer;
444abb7d134c02ac60091108c491dafb00877093170John Hoford    }
445abb7d134c02ac60091108c491dafb00877093170John Hoford
4464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    private void printGroupTree(VGroup currentGroup, int level) {
4474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        String indent = "";
4484d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        for (int i = 0 ; i < level ; i++) {
4494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            indent += "    ";
4504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
4514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Print the current node
452e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        Log.v(LOGTAG, indent + "current group is :" +  currentGroup.getGroupName()
4534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                + " rotation is " + currentGroup.mRotate);
4544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        Log.v(LOGTAG, indent + "matrix is :" +  currentGroup.getLocalMatrix().toString());
4554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Then print all the children
4564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        for (int i = 0 ; i < currentGroup.mChildGroupList.size(); i++) {
4574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            printGroupTree(currentGroup.mChildGroupList.get(i), level + 1);
4584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
4594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    }
4604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
4615c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette    private static class VectorDrawableState extends ConstantState {
4629cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        int[] mThemeAttrs;
4635c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        int mChangingConfigurations;
464ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        VPathRenderer mVPathRenderer;
4655c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        Rect mPadding;
466b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        ColorStateList mTint;
467b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        Mode mTintMode;
4685c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
4695c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public VectorDrawableState(VectorDrawableState copy) {
4705c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            if (copy != null) {
4719cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette                mThemeAttrs = copy.mThemeAttrs;
4725c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette                mChangingConfigurations = copy.mChangingConfigurations;
4734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                // TODO: Make sure the constant state are handled correctly.
474ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui                mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
4755c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette                mPadding = new Rect(copy.mPadding);
476b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTint = copy.mTint;
477b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTintMode = copy.mTintMode;
4785c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            }
4795c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
4805c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
4815c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
4825c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable() {
4835c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, null, null);
4845c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
4855c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
4865c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
4875c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable(Resources res) {
4885c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, res, null);
4895c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
4905c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
4915c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
4925c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable(Resources res, Theme theme) {
4935c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, res, theme);
4945c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
4955c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
4965c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
4975c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public int getChangingConfigurations() {
4985c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return mChangingConfigurations;
4995c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
5005c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette    }
5015c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
502ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui    private static class VPathRenderer {
5034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        /* Right now the internal data structure is organized as a tree.
5044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * Each node can be a group node, or a path.
5054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * A group node can have groups or paths as children, but a path node has
5064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * no children.
5074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * One example can be:
5084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *                 Root Group
5094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *                /    |     \
5104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *           Group    Path    Group
5114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *          /     \             |
5124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *         Path   Path         Path
5134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *
5144d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         */
5154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final VGroup mRootGroup;
5164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
5174b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private final Path mPath = new Path();
5184b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private final Path mRenderPath = new Path();
5194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private static final Matrix IDENTITY_MATRIX = new Matrix();
5204b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
5214b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private Paint mStrokePaint;
5224b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private Paint mFillPaint;
523fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        private ColorFilter mColorFilter;
524abb7d134c02ac60091108c491dafb00877093170John Hoford        private PathMeasure mPathMeasure;
5254b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
5264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mBaseWidth = 0;
5274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mBaseHeight = 0;
5284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mViewportWidth = 0;
5294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mViewportHeight = 0;
5302af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        private int mRootAlpha = 0xFF;
5319453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
5324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final Matrix mFinalPathMatrix = new Matrix();
533abb7d134c02ac60091108c491dafb00877093170John Hoford
534ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        public VPathRenderer() {
5354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mRootGroup = new VGroup();
536abb7d134c02ac60091108c491dafb00877093170John Hoford        }
5379453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
5382af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        public void setRootAlpha(int alpha) {
5392af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mRootAlpha = alpha;
5402af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        }
5412af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
5422af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        public int getRootAlpha() {
5432af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            return mRootAlpha;
5442af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        }
5452af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
546ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        public VPathRenderer(VPathRenderer copy) {
5474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mRootGroup = copy.mRootGroup;
548abb7d134c02ac60091108c491dafb00877093170John Hoford            mBaseWidth = copy.mBaseWidth;
549abb7d134c02ac60091108c491dafb00877093170John Hoford            mBaseHeight = copy.mBaseHeight;
550abb7d134c02ac60091108c491dafb00877093170John Hoford            mViewportWidth = copy.mViewportHeight;
551abb7d134c02ac60091108c491dafb00877093170John Hoford            mViewportHeight = copy.mViewportHeight;
552abb7d134c02ac60091108c491dafb00877093170John Hoford        }
553abb7d134c02ac60091108c491dafb00877093170John Hoford
5549453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public boolean canApplyTheme() {
5554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // If one of the paths can apply theme, then return true;
5564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return recursiveCanApplyTheme(mRootGroup);
5574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
5584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
5594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private boolean recursiveCanApplyTheme(VGroup currentGroup) {
5604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // We can do a tree traverse here, if there is one path return true,
5614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // then we return true for the whole tree.
5624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            final ArrayList<VPath> paths = currentGroup.mPathList;
5634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            for (int j = paths.size() - 1; j >= 0; j--) {
5644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final VPath path = paths.get(j);
5654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                if (path.canApplyTheme()) {
5664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    return true;
5679453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                }
5689453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
5696d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui
5704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            final ArrayList<VGroup> childGroups = currentGroup.mChildGroupList;
5714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
5724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            for (int i = 0; i < childGroups.size(); i++) {
5734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                VGroup childGroup = childGroups.get(i);
5744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                if (childGroup.canApplyTheme()
5754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                        || recursiveCanApplyTheme(childGroup)) {
5764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    return true;
5774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
5784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
5799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            return false;
5809453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
5819453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
5829453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public void applyTheme(Theme t) {
5834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Apply theme to every path of the tree.
5844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            recursiveApplyTheme(mRootGroup, t);
5854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
5864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
5874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void recursiveApplyTheme(VGroup currentGroup, Theme t) {
5884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // We can do a tree traverse here, apply theme to all paths which
5894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // can apply theme.
5904d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            final ArrayList<VPath> paths = currentGroup.mPathList;
5914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            for (int j = paths.size() - 1; j >= 0; j--) {
5924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final VPath path = paths.get(j);
5934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                if (path.canApplyTheme()) {
5944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    path.applyTheme(t);
5959453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                }
5969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
5974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
5984d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            final ArrayList<VGroup> childGroups = currentGroup.mChildGroupList;
5994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
6004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            for (int i = 0; i < childGroups.size(); i++) {
6014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                VGroup childGroup = childGroups.get(i);
6024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                if (childGroup.canApplyTheme()) {
6034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    childGroup.applyTheme(t);
6044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
6054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                recursiveApplyTheme(childGroup, t);
6064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
6074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
608abb7d134c02ac60091108c491dafb00877093170John Hoford        }
609abb7d134c02ac60091108c491dafb00877093170John Hoford
610fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        public void setColorFilter(ColorFilter colorFilter) {
611fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mColorFilter = colorFilter;
612fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
613fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mFillPaint != null) {
614fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                mFillPaint.setColorFilter(colorFilter);
615fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            }
616fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
617fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mStrokePaint != null) {
618fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                mStrokePaint.setColorFilter(colorFilter);
619fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            }
6206d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui
621fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        }
622fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
6234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix,
6242af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                float currentAlpha, Canvas canvas, int w, int h) {
6254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Calculate current group's matrix by preConcat the parent's and
6264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // and the current one on the top of the stack.
6274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Basically the Mfinal = Mviewport * M0 * M1 * M2;
6284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Mi the local matrix at level i of the group tree.
6294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            currentGroup.mStackedMatrix.set(currentMatrix);
6304d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
6314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
6324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
6332af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha;
6342af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            drawPath(currentGroup, stackedAlpha, canvas, w, h);
6354d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Draw the group tree in post order.
6364d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            for (int i = 0 ; i < currentGroup.mChildGroupList.size(); i++) {
6374d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                drawGroupTree(currentGroup.mChildGroupList.get(i),
6382af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        currentGroup.mStackedMatrix, stackedAlpha, canvas, w, h);
639abb7d134c02ac60091108c491dafb00877093170John Hoford            }
6404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
641abb7d134c02ac60091108c491dafb00877093170John Hoford
6424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        public void draw(Canvas canvas, int w, int h) {
6434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Travese the tree in pre-order to draw.
6442af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF, canvas, w, h);
645abb7d134c02ac60091108c491dafb00877093170John Hoford        }
646abb7d134c02ac60091108c491dafb00877093170John Hoford
6472af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        private void drawPath(VGroup vGroup, float stackedAlpha, Canvas canvas, int w, int h) {
6489453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final float scale = Math.min(h / mViewportHeight, w / mViewportWidth);
649abb7d134c02ac60091108c491dafb00877093170John Hoford
6504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mFinalPathMatrix.set(vGroup.mStackedMatrix);
6514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mFinalPathMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f);
6524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mFinalPathMatrix.postTranslate(w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f);
653abb7d134c02ac60091108c491dafb00877093170John Hoford
65463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            ArrayList<VPath> paths = vGroup.getPaths();
65563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            for (int i = 0; i < paths.size(); i++) {
65663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                VPath vPath = paths.get(i);
65763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                vPath.toPath(mPath);
65863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                final Path path = mPath;
659abb7d134c02ac60091108c491dafb00877093170John Hoford
66063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) {
66163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f;
66263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f;
6639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
66463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    if (mPathMeasure == null) {
66563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                        mPathMeasure = new PathMeasure();
66663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    }
66763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    mPathMeasure.setPath(mPath, false);
66863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
66963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    float len = mPathMeasure.getLength();
67063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    start = start * len;
67163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    end = end * len;
67263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    path.reset();
67363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    if (start > end) {
67463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                        mPathMeasure.getSegment(start, len, path, true);
67563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                        mPathMeasure.getSegment(0f, end, path, true);
67663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    } else {
67763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                        mPathMeasure.getSegment(start, end, path, true);
67863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    }
67963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    path.rLineTo(0, 0); // fix bug in measure
6804b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette                }
6814b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
68263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                mRenderPath.reset();
6839453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
6844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                mRenderPath.addPath(path, mFinalPathMatrix);
6854b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
68663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                if (vPath.mClip) {
68763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    canvas.clipPath(mRenderPath, Region.Op.REPLACE);
6882af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                } else {
6892af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                   if (vPath.mFillColor != 0) {
6902af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        if (mFillPaint == null) {
6912af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mFillPaint = new Paint();
6922af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mFillPaint.setColorFilter(mColorFilter);
6932af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mFillPaint.setStyle(Paint.Style.FILL);
6942af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mFillPaint.setAntiAlias(true);
6952af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        }
6962af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        mFillPaint.setColor(applyAlpha(vPath.mFillColor, stackedAlpha));
6972af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        canvas.drawPath(mRenderPath, mFillPaint);
69863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    }
69963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
7002af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                    if (vPath.mStrokeColor != 0) {
7012af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        if (mStrokePaint == null) {
7022af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mStrokePaint = new Paint();
7032af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mStrokePaint.setColorFilter(mColorFilter);
7042af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mStrokePaint.setStyle(Paint.Style.STROKE);
7052af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            mStrokePaint.setAntiAlias(true);
7062af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        }
7074b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
7082af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        final Paint strokePaint = mStrokePaint;
7092af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        if (vPath.mStrokeLineJoin != null) {
7102af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            strokePaint.setStrokeJoin(vPath.mStrokeLineJoin);
7112af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        }
712abb7d134c02ac60091108c491dafb00877093170John Hoford
7132af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        if (vPath.mStrokeLineCap != null) {
7142af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                            strokePaint.setStrokeCap(vPath.mStrokeLineCap);
7152af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        }
71663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
7172af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale);
71863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
7192af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        strokePaint.setColor(applyAlpha(vPath.mStrokeColor, stackedAlpha));
7202af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale);
7212af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                        canvas.drawPath(mRenderPath, strokePaint);
7222af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                    }
72363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                }
724abb7d134c02ac60091108c491dafb00877093170John Hoford            }
725abb7d134c02ac60091108c491dafb00877093170John Hoford        }
726abb7d134c02ac60091108c491dafb00877093170John Hoford
727abb7d134c02ac60091108c491dafb00877093170John Hoford        private void parseViewport(Resources r, AttributeSet attrs)
728abb7d134c02ac60091108c491dafb00877093170John Hoford                throws XmlPullParserException {
7294b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette            final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport);
730fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mViewportWidth = a.getFloat(R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth);
731fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mViewportHeight = a.getFloat(R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight);
732fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
733fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mViewportWidth <= 0) {
734fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
735fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<viewport> tag requires viewportWidth > 0");
736fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            } else if (mViewportHeight <= 0) {
737fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
738fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<viewport> tag requires viewportHeight > 0");
739abb7d134c02ac60091108c491dafb00877093170John Hoford            }
740fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
741abb7d134c02ac60091108c491dafb00877093170John Hoford            a.recycle();
742abb7d134c02ac60091108c491dafb00877093170John Hoford        }
743abb7d134c02ac60091108c491dafb00877093170John Hoford
744abb7d134c02ac60091108c491dafb00877093170John Hoford        private void parseSize(Resources r, AttributeSet attrs)
745abb7d134c02ac60091108c491dafb00877093170John Hoford                throws XmlPullParserException  {
7464b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette            final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize);
747fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, mBaseWidth);
748fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, mBaseHeight);
749fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
750fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mBaseWidth <= 0) {
751fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
752fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<size> tag requires width > 0");
753fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            } else if (mBaseHeight <= 0) {
754fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
755fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<size> tag requires height > 0");
756abb7d134c02ac60091108c491dafb00877093170John Hoford            }
757fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
758abb7d134c02ac60091108c491dafb00877093170John Hoford            a.recycle();
759abb7d134c02ac60091108c491dafb00877093170John Hoford        }
7604b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
761abb7d134c02ac60091108c491dafb00877093170John Hoford    }
762abb7d134c02ac60091108c491dafb00877093170John Hoford
763e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    static class VGroup {
7644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final ArrayList<VPath> mPathList = new ArrayList<VPath>();
7654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final ArrayList<VGroup> mChildGroupList = new ArrayList<VGroup>();
766abb7d134c02ac60091108c491dafb00877093170John Hoford
76763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mRotate = 0;
76863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mPivotX = 0;
76963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mPivotY = 0;
770452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mScaleX = 1;
771452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mScaleY = 1;
772452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mTranslateX = 0;
773452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mTranslateY = 0;
7742af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        private float mGroupAlpha = 1;
7754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
7764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // mLocalMatrix is parsed from the XML.
7774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final Matrix mLocalMatrix = new Matrix();
7784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // mStackedMatrix is only used when drawing, it combines all the
7794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // parents' local matrices with the current one.
7804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final Matrix mStackedMatrix = new Matrix();
78163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
78263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private int[] mThemeAttrs;
78363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
784e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        private String mGroupName = null;
785e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
786e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        /* Getter and Setter */
787e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getRotation() {
788e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mRotate;
789e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
790e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
791e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setRotation(float rotation) {
792e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (rotation != mRotate) {
793e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mRotate = rotation;
794e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
795e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
796e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
797e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
798e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getPivotX() {
799e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPivotX;
800e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
801e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
802e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setPivotX(float pivotX) {
803e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (pivotX != mPivotX) {
804e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPivotX = pivotX;
805e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
806e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
807e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
808e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
809e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getPivotY() {
810e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPivotY;
811e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
812e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
813e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setPivotY(float pivotY) {
814e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (pivotY != mPivotY) {
815e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPivotY = pivotY;
816e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
817e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
818e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
819e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
820e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getScaleX() {
821e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mScaleX;
822e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
8234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
824e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setScaleX(float scaleX) {
825e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (scaleX != mScaleX) {
826e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mScaleX = scaleX;
827e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
828e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
829e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
830e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
831e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getScaleY() {
832e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mScaleY;
833e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
834e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
835e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setScaleY(float scaleY) {
836e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (scaleY != mScaleY) {
837e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mScaleY = scaleY;
838e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
839e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
840e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
841e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
842e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getTranslateX() {
843e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTranslateX;
844e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
845e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
846e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setTranslateX(float translateX) {
847e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (translateX != mTranslateX) {
848e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mTranslateX = translateX;
849e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
850e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
851e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
852e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
853e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getTranslateY() {
854e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTranslateY;
855e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
856e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
857e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setTranslateY(float translateY) {
858e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (translateY != mTranslateY) {
859e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mTranslateY = translateY;
860e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
861e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
862e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
863e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
864e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getAlpha() {
865e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mGroupAlpha;
866e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
867e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
868e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setAlpha(float groupAlpha) {
869e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (groupAlpha != mGroupAlpha) {
870e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mGroupAlpha = groupAlpha;
871e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
872e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
873e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
874e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public String getGroupName() {
875e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mGroupName;
8764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
8774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
8784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        public Matrix getLocalMatrix() {
8794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return mLocalMatrix;
8804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
8814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
882abb7d134c02ac60091108c491dafb00877093170John Hoford        public void add(VPath path) {
8834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mPathList.add(path);
884abb7d134c02ac60091108c491dafb00877093170John Hoford         }
885abb7d134c02ac60091108c491dafb00877093170John Hoford
8864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        public boolean canApplyTheme() {
8874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return mThemeAttrs != null;
8884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
8894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
89063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        public void applyTheme(Theme t) {
89163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            if (mThemeAttrs == null) {
89263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                return;
89363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            }
89463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
89563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            final TypedArray a = t.resolveAttributes(
89663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    mThemeAttrs, R.styleable.VectorDrawablePath);
89763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
89863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate);
89963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX);
90063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY);
901452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX);
902452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
903452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
904452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
9052af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha);
9064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            updateLocalMatrix();
9074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            if (a.hasValue(R.styleable.VectorDrawableGroup_name)) {
908e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mGroupName = a.getString(R.styleable.VectorDrawableGroup_name);
9094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
91063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            a.recycle();
91163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        }
91263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
91363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        public void inflate(Resources res, AttributeSet attrs, Theme theme) {
91463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawableGroup);
91563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            final int[] themeAttrs = a.extractThemeAttrs();
91663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
91763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            mThemeAttrs = themeAttrs;
91863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            // NOTE: The set of attributes loaded here MUST match the
91963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            // set of attributes loaded in applyTheme.
92063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
92163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_rotation] == 0) {
92263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate);
92363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            }
92463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
92563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_pivotX] == 0) {
92663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX);
92763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            }
92863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
92963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_pivotY] == 0) {
93063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY);
93163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            }
93263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
933452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_scaleX] == 0) {
934452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui                mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX);
935452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            }
936452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui
937452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_scaleY] == 0) {
938452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui                mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
939452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            }
940452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui
941452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_translateX] == 0) {
942452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui                mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
943452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            }
944452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui
945452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_translateY] == 0) {
946452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui                mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
947452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            }
948452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui
9494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_name] == 0) {
950e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mGroupName = a.getString(R.styleable.VectorDrawableGroup_name);
9514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
9524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
9534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawableGroup_alpha] == 0) {
9542af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha);
9554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
9564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
9574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            updateLocalMatrix();
95863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            a.recycle();
95963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        }
96063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
9614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void updateLocalMatrix() {
9624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // The order we apply is the same as the
9634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // RenderNode.cpp::applyViewPropertyTransforms().
9644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.reset();
9654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
9664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postScale(mScaleX, mScaleY);
9674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postRotate(mRotate, 0, 0);
9684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
9694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
9704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
971abb7d134c02ac60091108c491dafb00877093170John Hoford        /**
972abb7d134c02ac60091108c491dafb00877093170John Hoford         * Must return in order of adding
973abb7d134c02ac60091108c491dafb00877093170John Hoford         * @return ordered list of paths
974abb7d134c02ac60091108c491dafb00877093170John Hoford         */
97563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        public ArrayList<VPath> getPaths() {
9764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return mPathList;
977abb7d134c02ac60091108c491dafb00877093170John Hoford        }
978abb7d134c02ac60091108c491dafb00877093170John Hoford
979abb7d134c02ac60091108c491dafb00877093170John Hoford    }
980abb7d134c02ac60091108c491dafb00877093170John Hoford
981cf4832f69c8786b098ce18c24319021f8cd6733aztenghui    private static class VPath {
9829453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        private int[] mThemeAttrs;
9839453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
984abb7d134c02ac60091108c491dafb00877093170John Hoford        int mStrokeColor = 0;
985abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeWidth = 0;
986abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeOpacity = Float.NaN;
9872af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        int mFillColor = Color.BLACK;
988abb7d134c02ac60091108c491dafb00877093170John Hoford        int mFillRule;
989abb7d134c02ac60091108c491dafb00877093170John Hoford        float mFillOpacity = Float.NaN;
990abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathStart = 0;
991abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathEnd = 1;
992abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathOffset = 0;
9939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
994abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean mClip = false;
9954b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        Paint.Cap mStrokeLineCap = Paint.Cap.BUTT;
9964b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        Paint.Join mStrokeLineJoin = Paint.Join.MITER;
997abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeMiterlimit = 4;
9989453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
999cf4832f69c8786b098ce18c24319021f8cd6733aztenghui        private PathParser.PathDataNode[] mNode = null;
1000e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        private String mPathName;
1001abb7d134c02ac60091108c491dafb00877093170John Hoford
10029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public VPath() {
10039453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            // Empty constructor.
10049453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
10059453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1006abb7d134c02ac60091108c491dafb00877093170John Hoford        public void toPath(Path path) {
1007abb7d134c02ac60091108c491dafb00877093170John Hoford            path.reset();
1008abb7d134c02ac60091108c491dafb00877093170John Hoford            if (mNode != null) {
1009cf4832f69c8786b098ce18c24319021f8cd6733aztenghui                PathParser.PathDataNode.nodesToPath(mNode, path);
1010abb7d134c02ac60091108c491dafb00877093170John Hoford            }
1011abb7d134c02ac60091108c491dafb00877093170John Hoford        }
1012abb7d134c02ac60091108c491dafb00877093170John Hoford
1013e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public String getPathName() {
1014e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPathName;
1015abb7d134c02ac60091108c491dafb00877093170John Hoford        }
1016abb7d134c02ac60091108c491dafb00877093170John Hoford
10177f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) {
10187f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            switch (id) {
10197f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_BUTT:
10207f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.BUTT;
10217f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_ROUND:
10227f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.ROUND;
10237f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_SQUARE:
10247f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.SQUARE;
10257f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                default:
10267f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return defValue;
10277f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
10287f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        }
10297f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
10307f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) {
10317f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            switch (id) {
10327f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_MITER:
10337f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.MITER;
10347f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_ROUND:
10357f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.ROUND;
10367f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_BEVEL:
10377f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.BEVEL;
10387f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                default:
10397f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return defValue;
10407f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
10417f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        }
10427f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
1043e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        /* Setters and Getters */
1044e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        int getStroke() {
1045e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeColor;
1046e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1047e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1048e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStroke(int strokeColor) {
1049e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeColor = strokeColor;
1050e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1051e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1052e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getStrokeWidth() {
1053e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeWidth;
1054e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1055e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1056e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStrokeWidth(float strokeWidth) {
1057e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeWidth = strokeWidth;
1058e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1059e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1060e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getStrokeOpacity() {
1061e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeOpacity;
1062e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1063e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1064e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStrokeOpacity(float strokeOpacity) {
1065e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeOpacity = strokeOpacity;
1066e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1067e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1068e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        int getFill() {
1069e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mFillColor;
1070e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1071e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1072e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setFill(int fillColor) {
1073e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mFillColor = fillColor;
1074e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1075e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1076e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getFillOpacity() {
1077e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mFillOpacity;
1078e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1079e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1080e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setFillOpacity(float fillOpacity) {
1081e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mFillOpacity = fillOpacity;
1082e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1083e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1084e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathStart() {
1085e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathStart;
1086e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1087e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1088e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathStart(float trimPathStart) {
1089e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathStart = trimPathStart;
1090e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1091e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1092e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathEnd() {
1093e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathEnd;
1094e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1095e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1096e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathEnd(float trimPathEnd) {
1097e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathEnd = trimPathEnd;
1098e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1099e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1100e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathOffset() {
1101e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathOffset;
1102e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1103e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1104e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathOffset(float trimPathOffset) {
1105e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathOffset = trimPathOffset;
1106e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1107e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
11089453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public void inflate(Resources r, AttributeSet attrs, Theme theme) {
11099453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath);
11109453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final int[] themeAttrs = a.extractThemeAttrs();
11119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            mThemeAttrs = themeAttrs;
11129453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11137f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            // NOTE: The set of attributes loaded here MUST match the
11147f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            // set of attributes loaded in applyTheme.
11157f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_clipToPath] == 0) {
11167f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip);
11177f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11187f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
11197f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_name] == 0) {
1120e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPathName = a.getString(R.styleable.VectorDrawablePath_name);
11217f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11227f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
11237f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_pathData] == 0) {
1124cf4832f69c8786b098ce18c24319021f8cd6733aztenghui                mNode = PathParser.createNodesFromPathData(a.getString(
1125cf4832f69c8786b098ce18c24319021f8cd6733aztenghui                        R.styleable.VectorDrawablePath_pathData));
11267f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
1127abb7d134c02ac60091108c491dafb00877093170John Hoford
11289453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_fill] == 0) {
11297f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor);
11309453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
11319453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11327f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_fillOpacity] == 0) {
11337f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity);
1134abb7d134c02ac60091108c491dafb00877093170John Hoford            }
11359453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11367f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null
11377f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    || themeAttrs[R.styleable.VectorDrawablePath_strokeLineCap] == 0) {
11387f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mStrokeLineCap = getStrokeLineCap(
11397f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                        a.getInt(R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap);
11407f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11417f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
11427f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null
11437f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    || themeAttrs[R.styleable.VectorDrawablePath_strokeLineJoin] == 0) {
11447f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mStrokeLineJoin = getStrokeLineJoin(
11457f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                        a.getInt(R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin);
1146abb7d134c02ac60091108c491dafb00877093170John Hoford            }
11479453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11487f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null
11497f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    || themeAttrs[R.styleable.VectorDrawablePath_strokeMiterLimit] == 0) {
11507f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mStrokeMiterlimit = a.getFloat(
11517f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                        R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit);
11527f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11539453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11549453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_stroke] == 0) {
11559453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor);
1156abb7d134c02ac60091108c491dafb00877093170John Hoford            }
11579453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (themeAttrs == null
11599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                    || themeAttrs[R.styleable.VectorDrawablePath_strokeOpacity] == 0) {
11609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                mStrokeOpacity = a.getFloat(
11617f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                        R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity);
11629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
11639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11647f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_strokeWidth] == 0) {
11657f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth);
11667f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11677f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
11687f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null || themeAttrs[R.styleable.VectorDrawablePath_trimPathEnd] == 0) {
11697f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd);
11707f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11727f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null
11737f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    || themeAttrs[R.styleable.VectorDrawablePath_trimPathOffset] == 0) {
11747f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mTrimPathOffset = a.getFloat(
11757f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                        R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset);
11767f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11777f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
11787f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (themeAttrs == null
11797f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    || themeAttrs[R.styleable.VectorDrawablePath_trimPathStart] == 0) {
11807f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                mTrimPathStart = a.getFloat(
11817f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                        R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart);
11827f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11837f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
11849453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            updateColorAlphas();
11859453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1186abb7d134c02ac60091108c491dafb00877093170John Hoford            a.recycle();
1187abb7d134c02ac60091108c491dafb00877093170John Hoford        }
1188abb7d134c02ac60091108c491dafb00877093170John Hoford
11899453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public boolean canApplyTheme() {
11909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            return mThemeAttrs != null;
11919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
11929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public void applyTheme(Theme t) {
11949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (mThemeAttrs == null) {
11959453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                return;
11969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
11979453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
11989453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final TypedArray a = t.resolveAttributes(
11990cfb877f5a0a1bff82d9c3ee969195bf7812c0b5Alan Viverette                    mThemeAttrs, R.styleable.VectorDrawablePath);
12009453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12017f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip);
12029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12037f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (a.hasValue(R.styleable.VectorDrawablePath_name)) {
1204e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPathName = a.getString(R.styleable.VectorDrawablePath_name);
12059453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
12069453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12077f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            if (a.hasValue(R.styleable.VectorDrawablePath_pathData)) {
1208cf4832f69c8786b098ce18c24319021f8cd6733aztenghui                mNode = PathParser.createNodesFromPathData(a.getString(
1209cf4832f69c8786b098ce18c24319021f8cd6733aztenghui                        R.styleable.VectorDrawablePath_pathData));
12109453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
12119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12127f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor);
12137f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity);
12147f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
12157f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeLineCap = getStrokeLineCap(a.getInt(
12167f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap);
12177f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeLineJoin = getStrokeLineJoin(a.getInt(
12187f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin);
12197f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeMiterlimit = a.getFloat(
12207f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit);
12217f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor);
12227f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeOpacity = a.getFloat(
12237f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity);
12247f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth);
12257f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
12267f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd);
12277f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mTrimPathOffset = a.getFloat(
12287f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset);
12297f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mTrimPathStart = a.getFloat(
12307f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart);
12319453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            updateColorAlphas();
123363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            a.recycle();
12349453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
12359453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12369453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        private void updateColorAlphas() {
12379453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (!Float.isNaN(mFillOpacity)) {
12382af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                mFillColor = applyAlpha(mFillColor, mFillOpacity);
12399453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
12409453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12419453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (!Float.isNaN(mStrokeOpacity)) {
12422af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                mStrokeColor = applyAlpha(mStrokeColor, mStrokeOpacity);
12439453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
12449453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
1245abb7d134c02ac60091108c491dafb00877093170John Hoford    }
1246abb7d134c02ac60091108c491dafb00877093170John Hoford}
1247