VectorDrawable.java revision 5a836f74df027bb568da17fbde4e641b6a56d2a9
1abb7d134c02ac60091108c491dafb00877093170John Hoford/*
2abb7d134c02ac60091108c491dafb00877093170John Hoford * Copyright (C) 2014 The Android Open Source Project
3abb7d134c02ac60091108c491dafb00877093170John Hoford *
4abb7d134c02ac60091108c491dafb00877093170John Hoford * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5abb7d134c02ac60091108c491dafb00877093170John Hoford * in compliance with the License. You may obtain a copy of the License at
6abb7d134c02ac60091108c491dafb00877093170John Hoford *
7abb7d134c02ac60091108c491dafb00877093170John Hoford * http://www.apache.org/licenses/LICENSE-2.0
8abb7d134c02ac60091108c491dafb00877093170John Hoford *
9abb7d134c02ac60091108c491dafb00877093170John Hoford * Unless required by applicable law or agreed to in writing, software distributed under the License
10abb7d134c02ac60091108c491dafb00877093170John Hoford * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11abb7d134c02ac60091108c491dafb00877093170John Hoford * or implied. See the License for the specific language governing permissions and limitations under
12abb7d134c02ac60091108c491dafb00877093170John Hoford * the License.
13abb7d134c02ac60091108c491dafb00877093170John Hoford */
14abb7d134c02ac60091108c491dafb00877093170John Hoford
15abb7d134c02ac60091108c491dafb00877093170John Hofordpackage android.graphics.drawable;
16abb7d134c02ac60091108c491dafb00877093170John Hoford
17b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList;
18abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources;
19abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources.Theme;
204b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viveretteimport android.content.res.TypedArray;
21482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghuiimport android.graphics.Bitmap;
22abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Canvas;
232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghuiimport android.graphics.Color;
24abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.ColorFilter;
25abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Matrix;
26abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Paint;
27abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Path;
28abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PathMeasure;
29abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PixelFormat;
30b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuffColorFilter;
31abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Rect;
32abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Region;
33b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode;
34e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.ArrayMap;
35abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.AttributeSet;
36738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghuiimport android.util.LayoutDirection;
37abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.Log;
38cf4832f69c8786b098ce18c24319021f8cd6733aztenghuiimport android.util.PathParser;
394b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport android.util.Xml;
40abb7d134c02ac60091108c491dafb00877093170John Hoford
41abb7d134c02ac60091108c491dafb00877093170John Hofordimport com.android.internal.R;
42abb7d134c02ac60091108c491dafb00877093170John Hoford
43abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParser;
44abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParserException;
454b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport org.xmlpull.v1.XmlPullParserFactory;
46abb7d134c02ac60091108c491dafb00877093170John Hoford
47abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException;
48abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList;
494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack;
504b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
51abb7d134c02ac60091108c491dafb00877093170John Hoford/**
52d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * This lets you create a drawable based on an XML vector graphic It can be
53d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code>&lt;vector></code> element.
54abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/>
5546e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * The vector drawable has the following elements:
56abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/>
57abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl>
58177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code>&lt;vector></code></dt>
59e3c45e7a6b2a7d2176aa46ee482e299b54feeb9fztenghui * <dd>Used to defined a vector drawable</dd>
60abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>&lt;size></code></dt>
61abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the intrinsic Width Height size of the drawable using
62d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:width</code> and <code>android:height</code></dd>
63abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>&lt;viewport></code></dt>
64abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the size of the virtual canvas the paths are drawn on.
65d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * The size is defined using the attributes <code>android:viewportHeight</code>
66d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:viewportWidth</code></dd>
676d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code>&lt;group></code></dt>
68452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information.
69452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport.
70452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * And the transformations are applied in the order of scale, rotate then translate. </dd>
71452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:rotation</code>
72452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The degrees of rotation of the group.</dd></dt>
73452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotX</code>
74452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group</dd></dt>
75452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotY</code>
76452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group</dd></dt>
77452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleX</code>
78452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the X Coordinate</dd></dt>
79452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleY</code>
80452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the Y coordinate</dd></dt>
81452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateX</code>
82452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the X coordinate</dd></dt>
83452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateY</code>
84452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the Y coordinate</dd></dt>
85abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>&lt;path></code></dt>
866d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn.
87abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl>
88abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:name</code>
89abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the name of the path.</dd></dt>
90abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:pathData</code>
9146e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute
9246e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * in the SVG's path data</dd></dt>
93abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fill</code>
94abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the color to fill the path (none if not present).</dd></dt>
95abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:stroke</code>
96d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd>
97d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * </dt>
98abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeWidth</code>
99abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The width a path stroke</dd></dt>
100abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeOpacity</code>
101abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity of a path stroke</dd></dt>
102abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fillOpacity</code>
103abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity to fill the path with</dd></dt>
104abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathStart</code>
105abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the start from 0 to 1</dd></dt>
106abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathEnd</code>
107abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the end from 0 to 1</dd></dt>
108abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathOffset</code>
109d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Shift trim region (allows showed region to include the start and end)
110d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * from 0 to 1</dd></dt>
111abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:clipToPath</code>
112abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Path will set the clip path</dd></dt>
113abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineCap</code>
114abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the linecap for a stroked path: butt, round, square</dd></dt>
115abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineJoin</code>
116abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the lineJoin for a stroked path: miter,round,bevel</dd></dt>
117abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeMiterLimit</code>
118abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the Miter limit for a stroked path</dd></dt>
119abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl>
120abb7d134c02ac60091108c491dafb00877093170John Hoford * </dd>
121abb7d134c02ac60091108c491dafb00877093170John Hoford */
122abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable {
1239453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    private static final String LOGTAG = VectorDrawable.class.getSimpleName();
1249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
125abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_SIZE = "size";
126abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_VIEWPORT = "viewport";
1276d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui    private static final String SHAPE_GROUP = "group";
128abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_PATH = "path";
129abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final String SHAPE_VECTOR = "vector";
130abb7d134c02ac60091108c491dafb00877093170John Hoford
131abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_BUTT = 0;
132abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_ROUND = 1;
133abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINECAP_SQUARE = 2;
1349453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
135abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_MITER = 0;
136abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_ROUND = 1;
137abb7d134c02ac60091108c491dafb00877093170John Hoford    private static final int LINEJOIN_BEVEL = 2;
1389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    private static final boolean DBG_VECTOR_DRAWABLE = false;
1404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
14155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    private VectorDrawableState mVectorState;
142e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
143b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    private PorterDuffColorFilter mTintFilter;
144b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
14555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    private boolean mMutated;
14655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
147482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise,
148482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    // caching the bitmap by default is allowed.
149482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    private boolean mAllowCaching = true;
150482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
151abb7d134c02ac60091108c491dafb00877093170John Hoford    public VectorDrawable() {
15255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        mVectorState = new VectorDrawableState();
153abb7d134c02ac60091108c491dafb00877093170John Hoford    }
154abb7d134c02ac60091108c491dafb00877093170John Hoford
1559453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette    private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) {
15616c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui        if (theme != null && state.canApplyTheme()) {
15716c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            // If we need to apply a theme, implicitly mutate.
15816c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            mVectorState = new VectorDrawableState(state);
1599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            applyTheme(theme);
16016c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui        } else {
16116c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui            mVectorState = state;
1629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
163b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
164b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
165b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
166abb7d134c02ac60091108c491dafb00877093170John Hoford    }
167abb7d134c02ac60091108c491dafb00877093170John Hoford
16855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    @Override
16955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    public Drawable mutate() {
17055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        if (!mMutated && super.mutate() == this) {
17155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mVectorState = new VectorDrawableState(mVectorState);
17255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mMutated = true;
17355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
17455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return this;
17555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    }
17655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
177e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    Object getTargetByName(String name) {
17855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return mVectorState.mVPathRenderer.mVGTargetsMap.get(name);
179e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    }
180e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
181abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
182abb7d134c02ac60091108c491dafb00877093170John Hoford    public ConstantState getConstantState() {
18355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        mVectorState.mChangingConfigurations = getChangingConfigurations();
18455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return mVectorState;
185abb7d134c02ac60091108c491dafb00877093170John Hoford    }
186abb7d134c02ac60091108c491dafb00877093170John Hoford
1874554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette    @Override
188abb7d134c02ac60091108c491dafb00877093170John Hoford    public void draw(Canvas canvas) {
1894b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        final int saveCount = canvas.save();
1904b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        final Rect bounds = getBounds();
191738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        final boolean needMirroring = needMirroring();
192738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
1934b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        canvas.translate(bounds.left, bounds.top);
194738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        if (needMirroring) {
195738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            canvas.translate(bounds.width(), 0);
196738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            canvas.scale(-1.0f, 1.0f);
197738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        }
198482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
199482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        if (!mAllowCaching) {
200482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height());
201482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        } else {
202482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            Bitmap bitmap = mVectorState.mCachedBitmap;
203482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            if (bitmap == null || !mVectorState.canReuseCache(bounds.width(),
204482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    bounds.height())) {
205482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(),
206482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                        Bitmap.Config.ARGB_8888);
207482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                Canvas tmpCanvas = new Canvas(bitmap);
208482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                mVectorState.mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height());
209482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                mVectorState.mCachedBitmap = bitmap;
210482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
211482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                mVectorState.updateCacheStates();
212482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            }
213482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            canvas.drawBitmap(bitmap, null, bounds, null);
214482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        }
215738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
2164b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        canvas.restoreToCount(saveCount);
217abb7d134c02ac60091108c491dafb00877093170John Hoford    }
218abb7d134c02ac60091108c491dafb00877093170John Hoford
219abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
220e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    public int getAlpha() {
221e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        return mVectorState.mVPathRenderer.getRootAlpha();
222e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    }
223e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
224e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    @Override
225abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setAlpha(int alpha) {
2262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) {
2272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mVectorState.mVPathRenderer.setRootAlpha(alpha);
228abb7d134c02ac60091108c491dafb00877093170John Hoford            invalidateSelf();
229abb7d134c02ac60091108c491dafb00877093170John Hoford        }
230abb7d134c02ac60091108c491dafb00877093170John Hoford    }
231abb7d134c02ac60091108c491dafb00877093170John Hoford
232abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
233abb7d134c02ac60091108c491dafb00877093170John Hoford    public void setColorFilter(ColorFilter colorFilter) {
234b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
235b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (colorFilter != null) {
236b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            // Color filter overrides tint.
237b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = null;
238b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        } else if (state.mTint != null && state.mTintMode != null) {
239b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            // Restore the tint filter, if we need one.
240b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT);
241b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
242b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            colorFilter = mTintFilter;
243b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
244b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
245b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        state.mVPathRenderer.setColorFilter(colorFilter);
246fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        invalidateSelf();
247abb7d134c02ac60091108c491dafb00877093170John Hoford    }
248abb7d134c02ac60091108c491dafb00877093170John Hoford
249abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
250b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    public void setTint(ColorStateList tint, Mode tintMode) {
251b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
252b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (state.mTint != tint || state.mTintMode != tintMode) {
253b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            state.mTint = tint;
254b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            state.mTintMode = tintMode;
255b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
256b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, tint, tintMode);
257b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
258b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            invalidateSelf();
259b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
260b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
261b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
262b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
263b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    protected boolean onStateChange(int[] stateSet) {
264b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        final VectorDrawableState state = mVectorState;
265b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        if (state.mTint != null && state.mTintMode != null) {
266b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
267b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            mVectorState.mVPathRenderer.setColorFilter(mTintFilter);
268b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette            return true;
269b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        }
270b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        return false;
271b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    }
272b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette
273b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette    @Override
274abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getOpacity() {
275abb7d134c02ac60091108c491dafb00877093170John Hoford        return PixelFormat.TRANSLUCENT;
276abb7d134c02ac60091108c491dafb00877093170John Hoford    }
277abb7d134c02ac60091108c491dafb00877093170John Hoford
278abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
279abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getIntrinsicWidth() {
280ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        return (int) mVectorState.mVPathRenderer.mBaseWidth;
281abb7d134c02ac60091108c491dafb00877093170John Hoford    }
282abb7d134c02ac60091108c491dafb00877093170John Hoford
283abb7d134c02ac60091108c491dafb00877093170John Hoford    @Override
284abb7d134c02ac60091108c491dafb00877093170John Hoford    public int getIntrinsicHeight() {
285ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        return (int) mVectorState.mVPathRenderer.mBaseHeight;
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    @Override
3329cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme)
3339cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            throws XmlPullParserException, IOException {
3348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable);
3359cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        updateStateFromTypedArray(a);
3369cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        a.recycle();
3379cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3389cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final VectorDrawableState state = mVectorState;
339670689af43358568bf2b5916284f1cac5762f428ztenghui        mVectorState.mCacheDirty = true;
34055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        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
3498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        // Account for any configuration changes.
3508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        state.mChangingConfigurations |= a.getChangingConfigurations();
3518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
3529cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        // Extract the theme attributes, if any.
3539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        state.mThemeAttrs = a.extractThemeAttrs();
3549cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3559cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1);
3569cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        if (tintMode != -1) {
3579cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
3589cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        }
3599cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
3609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint);
3619cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        if (tint != null) {
3629cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette            state.mTint = tint;
3639cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        }
364738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
365738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        state.mAutoMirrored = a.getBoolean(
366738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui                R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored);
3679cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette    }
3689cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette
36955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs,
3708e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            Theme theme) throws XmlPullParserException, IOException {
3718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        final VectorDrawableState state = mVectorState;
372ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        final VPathRenderer pathRenderer = new VPathRenderer();
37355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        state.mVPathRenderer = pathRenderer;
3749453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
375abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean noSizeTag = true;
376abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean noViewportTag = true;
377abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean noPathTag = true;
3789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
3794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Use a stack to help to build the group tree.
3804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // The top of the stack is always the current group.
3814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        final Stack<VGroup> groupStack = new Stack<VGroup>();
3824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        groupStack.push(pathRenderer.mRootGroup);
383abb7d134c02ac60091108c491dafb00877093170John Hoford
384abb7d134c02ac60091108c491dafb00877093170John Hoford        int eventType = parser.getEventType();
385abb7d134c02ac60091108c491dafb00877093170John Hoford        while (eventType != XmlPullParser.END_DOCUMENT) {
386abb7d134c02ac60091108c491dafb00877093170John Hoford            if (eventType == XmlPullParser.START_TAG) {
3879453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                final String tagName = parser.getName();
3884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final VGroup currentGroup = groupStack.peek();
3894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
390abb7d134c02ac60091108c491dafb00877093170John Hoford                if (SHAPE_PATH.equals(tagName)) {
3919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                    final VPath path = new VPath();
3929453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                    path.inflate(res, attrs, theme);
3938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    currentGroup.mChildren.add(path);
394e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    if (path.getPathName() != null) {
39555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                        pathRenderer.mVGTargetsMap.put(path.getPathName(), path);
396e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    }
397abb7d134c02ac60091108c491dafb00877093170John Hoford                    noPathTag = false;
3988e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    state.mChangingConfigurations |= path.mChangingConfigurations;
399abb7d134c02ac60091108c491dafb00877093170John Hoford                } else if (SHAPE_SIZE.equals(tagName)) {
400ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui                    pathRenderer.parseSize(res, attrs);
401abb7d134c02ac60091108c491dafb00877093170John Hoford                    noSizeTag = false;
4028e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    state.mChangingConfigurations |= pathRenderer.mChangingConfigurations;
403abb7d134c02ac60091108c491dafb00877093170John Hoford                } else if (SHAPE_VIEWPORT.equals(tagName)) {
404ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui                    pathRenderer.parseViewport(res, attrs);
405abb7d134c02ac60091108c491dafb00877093170John Hoford                    noViewportTag = false;
4068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    state.mChangingConfigurations |= pathRenderer.mChangingConfigurations;
4076d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui                } else if (SHAPE_GROUP.equals(tagName)) {
4084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    VGroup newChildGroup = new VGroup();
4094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    newChildGroup.inflate(res, attrs, theme);
4108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    currentGroup.mChildren.add(newChildGroup);
4114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    groupStack.push(newChildGroup);
412e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    if (newChildGroup.getGroupName() != null) {
41355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                        pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(),
41455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                                newChildGroup);
415e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                    }
4168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    state.mChangingConfigurations |= newChildGroup.mChangingConfigurations;
417abb7d134c02ac60091108c491dafb00877093170John Hoford                }
4184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            } else if (eventType == XmlPullParser.END_TAG) {
4194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                final String tagName = parser.getName();
4204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                if (SHAPE_GROUP.equals(tagName)) {
4214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                    groupStack.pop();
4224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
423abb7d134c02ac60091108c491dafb00877093170John Hoford            }
424abb7d134c02ac60091108c491dafb00877093170John Hoford            eventType = parser.next();
425abb7d134c02ac60091108c491dafb00877093170John Hoford        }
4269453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
4274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Print the tree out for debug.
4284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        if (DBG_VECTOR_DRAWABLE) {
4294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            printGroupTree(pathRenderer.mRootGroup, 0);
4306d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui        }
4316d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui
43246e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui        if (noSizeTag || noViewportTag || noPathTag) {
4339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final StringBuffer tag = new StringBuffer();
4349453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
435abb7d134c02ac60091108c491dafb00877093170John Hoford            if (noSizeTag) {
4369453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                tag.append(SHAPE_SIZE);
437abb7d134c02ac60091108c491dafb00877093170John Hoford            }
4389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
439d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette            if (noViewportTag) {
440d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette                if (tag.length() > 0) {
441abb7d134c02ac60091108c491dafb00877093170John Hoford                    tag.append(" & ");
442abb7d134c02ac60091108c491dafb00877093170John Hoford                }
4439453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                tag.append(SHAPE_SIZE);
444abb7d134c02ac60091108c491dafb00877093170John Hoford            }
4459453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
446d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette            if (noPathTag) {
447d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette                if (tag.length() > 0) {
448abb7d134c02ac60091108c491dafb00877093170John Hoford                    tag.append(" or ");
449abb7d134c02ac60091108c491dafb00877093170John Hoford                }
4509453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette                tag.append(SHAPE_PATH);
451abb7d134c02ac60091108c491dafb00877093170John Hoford            }
4529453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
4539453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            throw new XmlPullParserException("no " + tag + " defined");
454abb7d134c02ac60091108c491dafb00877093170John Hoford        }
455abb7d134c02ac60091108c491dafb00877093170John Hoford    }
456abb7d134c02ac60091108c491dafb00877093170John Hoford
4574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    private void printGroupTree(VGroup currentGroup, int level) {
4584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        String indent = "";
4598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        for (int i = 0; i < level; i++) {
4604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            indent += "    ";
4614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
4624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        // Print the current node
4638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName()
4644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                + " rotation is " + currentGroup.mRotate);
4658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString());
4668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        // Then print all the children groups
4678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        for (int i = 0; i < currentGroup.mChildren.size(); i++) {
4688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            Object child = currentGroup.mChildren.get(i);
4698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            if (child instanceof VGroup) {
4708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                printGroupTree((VGroup) child, level + 1);
4718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            }
4724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
4734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui    }
4744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
47555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    @Override
47655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    public int getChangingConfigurations() {
47755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        return super.getChangingConfigurations() | mVectorState.mChangingConfigurations;
47855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui    }
47955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
480482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    void setAllowCaching(boolean allowCaching) {
481482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        mAllowCaching = allowCaching;
482482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui    }
483482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
484738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    private boolean needMirroring() {
485738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL;
486738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    }
487738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
488738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    @Override
489738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    public void setAutoMirrored(boolean mirrored) {
490738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        if (mVectorState.mAutoMirrored != mirrored) {
491738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            mVectorState.mAutoMirrored = mirrored;
492738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui            invalidateSelf();
493738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        }
494738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    }
495738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
496738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    @Override
497738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    public boolean isAutoMirrored() {
498738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        return mVectorState.mAutoMirrored;
499738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui    }
500738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui
5015c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette    private static class VectorDrawableState extends ConstantState {
5029cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette        int[] mThemeAttrs;
5035c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        int mChangingConfigurations;
504ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        VPathRenderer mVPathRenderer;
505b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        ColorStateList mTint;
506b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette        Mode mTintMode;
507738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui        boolean mAutoMirrored;
5085c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
509482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        Bitmap mCachedBitmap;
510482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        int[] mCachedThemeAttrs;
511482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        ColorStateList mCachedTint;
512482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        Mode mCachedTintMode;
513482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        int mCachedRootAlpha;
514670689af43358568bf2b5916284f1cac5762f428ztenghui        boolean mCachedAutoMirrored;
515670689af43358568bf2b5916284f1cac5762f428ztenghui        boolean mCacheDirty;
516482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
51755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Deep copy for mutate() or implicitly mutate.
5185c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public VectorDrawableState(VectorDrawableState copy) {
5195c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            if (copy != null) {
5209cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette                mThemeAttrs = copy.mThemeAttrs;
5215c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette                mChangingConfigurations = copy.mChangingConfigurations;
522ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui                mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
523b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTint = copy.mTint;
524b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette                mTintMode = copy.mTintMode;
525738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui                mAutoMirrored = copy.mAutoMirrored;
5265c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            }
5275c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
5285c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
529482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        public boolean canReuseCache(int width, int height) {
530670689af43358568bf2b5916284f1cac5762f428ztenghui            if (!mCacheDirty
531670689af43358568bf2b5916284f1cac5762f428ztenghui                    && mCachedThemeAttrs == mThemeAttrs
532482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && mCachedTint == mTint
533482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && mCachedTintMode == mTintMode
534670689af43358568bf2b5916284f1cac5762f428ztenghui                    && mCachedAutoMirrored == mAutoMirrored
535482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && width == mCachedBitmap.getWidth()
536482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && height == mCachedBitmap.getHeight()
537482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                    && mCachedRootAlpha == mVPathRenderer.getRootAlpha())  {
538482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui                return true;
539482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            }
540482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            return false;
541482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        }
542482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
543482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        public void updateCacheStates() {
544482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            // Use shallow copy here and shallow comparison in canReuseCache(),
545482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            // likely hit cache miss more, but practically not much difference.
546482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedThemeAttrs = mThemeAttrs;
547482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedTint = mTint;
548482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedTintMode = mTintMode;
549482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui            mCachedRootAlpha = mVPathRenderer.getRootAlpha();
550670689af43358568bf2b5916284f1cac5762f428ztenghui            mCachedAutoMirrored = mAutoMirrored;
551670689af43358568bf2b5916284f1cac5762f428ztenghui            mCacheDirty = false;
552482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui        }
553482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui
55455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public VectorDrawableState() {
55555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mVPathRenderer = new VPathRenderer();
55655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
55755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
5585c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
5595c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable() {
5605c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, null, null);
5615c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
5625c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
5635c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
5645c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable(Resources res) {
5655c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, res, null);
5665c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
5675c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
5685c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
5695c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public Drawable newDrawable(Resources res, Theme theme) {
5705c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return new VectorDrawable(this, res, theme);
5715c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
5725c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
5735c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        @Override
5745c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        public int getChangingConfigurations() {
5755c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette            return mChangingConfigurations;
5765c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette        }
5775c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette    }
5785c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette
579ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui    private static class VPathRenderer {
5804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        /* Right now the internal data structure is organized as a tree.
5814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * Each node can be a group node, or a path.
5824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * A group node can have groups or paths as children, but a path node has
5834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * no children.
5844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         * One example can be:
5854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *                 Root Group
5864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *                /    |     \
5874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *           Group    Path    Group
5884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *          /     \             |
5894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *         Path   Path         Path
5904d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         *
5914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui         */
59255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables that only used temporarily inside the draw() call, so there
59355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // is no need for deep copying.
5944b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private final Path mPath = new Path();
5954b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private final Path mRenderPath = new Path();
5964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private static final Matrix IDENTITY_MATRIX = new Matrix();
59755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private final Matrix mFinalPathMatrix = new Matrix();
5984b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
5994b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private Paint mStrokePaint;
6004b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        private Paint mFillPaint;
601fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        private ColorFilter mColorFilter;
602abb7d134c02ac60091108c491dafb00877093170John Hoford        private PathMeasure mPathMeasure;
6034b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
60455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        /////////////////////////////////////////////////////
60555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables below need to be copied (deep copy if applicable) for mutation.
6068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        private int mChangingConfigurations;
60755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private final VGroup mRootGroup;
6084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mBaseWidth = 0;
6094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mBaseHeight = 0;
6104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mViewportWidth = 0;
6114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private float mViewportHeight = 0;
6122af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        private int mRootAlpha = 0xFF;
6139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
61455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>();
615abb7d134c02ac60091108c491dafb00877093170John Hoford
616ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        public VPathRenderer() {
6174d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mRootGroup = new VGroup();
618abb7d134c02ac60091108c491dafb00877093170John Hoford        }
6199453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
6202af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        public void setRootAlpha(int alpha) {
6212af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mRootAlpha = alpha;
6222af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        }
6232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
6242af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        public int getRootAlpha() {
6252af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            return mRootAlpha;
6262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        }
6272af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui
628ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui        public VPathRenderer(VPathRenderer copy) {
62955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
630abb7d134c02ac60091108c491dafb00877093170John Hoford            mBaseWidth = copy.mBaseWidth;
631abb7d134c02ac60091108c491dafb00877093170John Hoford            mBaseHeight = copy.mBaseHeight;
632abb7d134c02ac60091108c491dafb00877093170John Hoford            mViewportWidth = copy.mViewportHeight;
633abb7d134c02ac60091108c491dafb00877093170John Hoford            mViewportHeight = copy.mViewportHeight;
6348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mChangingConfigurations = copy.mChangingConfigurations;
63555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mRootAlpha = copy.mRootAlpha;
636abb7d134c02ac60091108c491dafb00877093170John Hoford        }
637abb7d134c02ac60091108c491dafb00877093170John Hoford
6389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public boolean canApplyTheme() {
6394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // If one of the paths can apply theme, then return true;
6404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return recursiveCanApplyTheme(mRootGroup);
6414d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
6424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
6434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private boolean recursiveCanApplyTheme(VGroup currentGroup) {
6444d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // We can do a tree traverse here, if there is one path return true,
6454d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // then we return true for the whole tree.
6468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final ArrayList<Object> children = currentGroup.mChildren;
6478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui
6488d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < children.size(); i++) {
6498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object child = children.get(i);
6508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (child instanceof VGroup) {
6518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup childGroup = (VGroup) child;
6528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childGroup.canApplyTheme()
6538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                            || recursiveCanApplyTheme(childGroup)) {
6548d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        return true;
6558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
6568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else if (child instanceof VPath) {
6578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath childPath = (VPath) child;
6588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childPath.canApplyTheme()) {
6598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        return true;
6608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
6614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
6624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
6639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            return false;
6649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
6659453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
6669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public void applyTheme(Theme t) {
6674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Apply theme to every path of the tree.
6684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            recursiveApplyTheme(mRootGroup, t);
6694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
6704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
6714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void recursiveApplyTheme(VGroup currentGroup, Theme t) {
6724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // We can do a tree traverse here, apply theme to all paths which
6734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // can apply theme.
6748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final ArrayList<Object> children = currentGroup.mChildren;
6758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < children.size(); i++) {
6768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object child = children.get(i);
6778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (child instanceof VGroup) {
6788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup childGroup = (VGroup) child;
6798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childGroup.canApplyTheme()) {
6808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        childGroup.applyTheme(t);
6818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
6828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    recursiveApplyTheme(childGroup, t);
6838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else if (child instanceof VPath) {
6848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath childPath = (VPath) child;
6858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (childPath.canApplyTheme()) {
6868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        childPath.applyTheme(t);
6878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
6884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui                }
6894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
690abb7d134c02ac60091108c491dafb00877093170John Hoford        }
691abb7d134c02ac60091108c491dafb00877093170John Hoford
692fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        public void setColorFilter(ColorFilter colorFilter) {
693fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mColorFilter = colorFilter;
694fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
695fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mFillPaint != null) {
696fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                mFillPaint.setColorFilter(colorFilter);
697fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            }
698fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
699fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mStrokePaint != null) {
700fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                mStrokePaint.setColorFilter(colorFilter);
701fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            }
7026d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui
703fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette        }
704fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
7054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix,
7062af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                float currentAlpha, Canvas canvas, int w, int h) {
7074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Calculate current group's matrix by preConcat the parent's and
7084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // and the current one on the top of the stack.
7094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Basically the Mfinal = Mviewport * M0 * M1 * M2;
7104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Mi the local matrix at level i of the group tree.
7114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            currentGroup.mStackedMatrix.set(currentMatrix);
7124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
7134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
7144d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
7152af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha;
7168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui
7178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            // Draw the group tree in the same order as the XML file.
7188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < currentGroup.mChildren.size(); i++) {
7198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object child = currentGroup.mChildren.get(i);
7208d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (child instanceof VGroup) {
7218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup childGroup = (VGroup) child;
7228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    drawGroupTree(childGroup, currentGroup.mStackedMatrix,
7238d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                            stackedAlpha, canvas, w, h);
7248d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else if (child instanceof VPath) {
7258d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath childPath = (VPath) child;
7268d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    drawPath(currentGroup, childPath, stackedAlpha, canvas, w, h);
7278d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                }
728abb7d134c02ac60091108c491dafb00877093170John Hoford            }
7294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
730abb7d134c02ac60091108c491dafb00877093170John Hoford
7314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        public void draw(Canvas canvas, int w, int h) {
7324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // Travese the tree in pre-order to draw.
7332af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF, canvas, w, h);
734abb7d134c02ac60091108c491dafb00877093170John Hoford        }
735abb7d134c02ac60091108c491dafb00877093170John Hoford
7368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        private void drawPath(VGroup vGroup, VPath vPath, float stackedAlpha,
7378d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Canvas canvas, int w, int h) {
7389d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui            final float scaleX =  w / mViewportWidth;
7399d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui            final float scaleY = h / mViewportHeight;
7409d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui            final float minScale = Math.min(scaleX, scaleY);
741abb7d134c02ac60091108c491dafb00877093170John Hoford
7424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mFinalPathMatrix.set(vGroup.mStackedMatrix);
7435a836f74df027bb568da17fbde4e641b6a56d2a9ztenghui            mFinalPathMatrix.postScale(scaleX, scaleY);
744abb7d134c02ac60091108c491dafb00877093170John Hoford
7458d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            vPath.toPath(mPath);
7468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final Path path = mPath;
747abb7d134c02ac60091108c491dafb00877093170John Hoford
7488d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) {
7498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f;
7508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f;
7519453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
7528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (mPathMeasure == null) {
7538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mPathMeasure = new PathMeasure();
7544b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette                }
7558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                mPathMeasure.setPath(mPath, false);
7568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui
7578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                float len = mPathMeasure.getLength();
7588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                start = start * len;
7598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                end = end * len;
7608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                path.reset();
7618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (start > end) {
7628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mPathMeasure.getSegment(start, len, path, true);
7638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mPathMeasure.getSegment(0f, end, path, true);
7648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else {
7658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mPathMeasure.getSegment(start, end, path, true);
7668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                }
7678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                path.rLineTo(0, 0); // fix bug in measure
7688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            }
7694b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
7708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            mRenderPath.reset();
7719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
7728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            mRenderPath.addPath(path, mFinalPathMatrix);
7734b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
7748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            if (vPath.mClip) {
7758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                canvas.clipPath(mRenderPath, Region.Op.REPLACE);
7768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            } else {
7778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (vPath.mFillColor != 0) {
7788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (mFillPaint == null) {
7798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint = new Paint();
7808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint.setColorFilter(mColorFilter);
7818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint.setStyle(Paint.Style.FILL);
7828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mFillPaint.setAntiAlias(true);
78363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                    }
7848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mFillPaint.setColor(applyAlpha(vPath.mFillColor, stackedAlpha));
7858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    canvas.drawPath(mRenderPath, mFillPaint);
7868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                }
78763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
7888d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (vPath.mStrokeColor != 0) {
7898d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (mStrokePaint == null) {
7908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint = new Paint();
7918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint.setColorFilter(mColorFilter);
7928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint.setStyle(Paint.Style.STROKE);
7938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        mStrokePaint.setAntiAlias(true);
7948d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
7954b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
7968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    final Paint strokePaint = mStrokePaint;
7978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (vPath.mStrokeLineJoin != null) {
7988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        strokePaint.setStrokeJoin(vPath.mStrokeLineJoin);
7998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
800abb7d134c02ac60091108c491dafb00877093170John Hoford
8018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (vPath.mStrokeLineCap != null) {
8028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        strokePaint.setStrokeCap(vPath.mStrokeLineCap);
8038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
80463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
8059d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui                    strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * minScale);
80663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
8078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    strokePaint.setColor(applyAlpha(vPath.mStrokeColor, stackedAlpha));
8089d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui                    strokePaint.setStrokeWidth(vPath.mStrokeWidth * minScale);
8098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    canvas.drawPath(mRenderPath, strokePaint);
81063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui                }
811abb7d134c02ac60091108c491dafb00877093170John Hoford            }
812abb7d134c02ac60091108c491dafb00877093170John Hoford        }
813abb7d134c02ac60091108c491dafb00877093170John Hoford
814abb7d134c02ac60091108c491dafb00877093170John Hoford        private void parseViewport(Resources r, AttributeSet attrs)
815abb7d134c02ac60091108c491dafb00877093170John Hoford                throws XmlPullParserException {
8164b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette            final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport);
8178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
8188e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            // Account for any configuration changes.
8198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mChangingConfigurations |= a.getChangingConfigurations();
8208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
8218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mViewportWidth = a.getFloat(
8228e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth);
8238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mViewportHeight = a.getFloat(
8248e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight);
825fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
826fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mViewportWidth <= 0) {
827fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
828fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<viewport> tag requires viewportWidth > 0");
829fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            } else if (mViewportHeight <= 0) {
830fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
831fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<viewport> tag requires viewportHeight > 0");
832abb7d134c02ac60091108c491dafb00877093170John Hoford            }
833fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
834abb7d134c02ac60091108c491dafb00877093170John Hoford            a.recycle();
835abb7d134c02ac60091108c491dafb00877093170John Hoford        }
836abb7d134c02ac60091108c491dafb00877093170John Hoford
837abb7d134c02ac60091108c491dafb00877093170John Hoford        private void parseSize(Resources r, AttributeSet attrs)
8388d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                throws XmlPullParserException {
8394b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette            final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize);
8408e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
8418e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            // Account for any configuration changes.
8428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mChangingConfigurations |= a.getChangingConfigurations();
8438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
844fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, mBaseWidth);
845fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, mBaseHeight);
846fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
847fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            if (mBaseWidth <= 0) {
848fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
849fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<size> tag requires width > 0");
850fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette            } else if (mBaseHeight <= 0) {
851fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                throw new XmlPullParserException(a.getPositionDescription() +
852fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette                        "<size> tag requires height > 0");
853abb7d134c02ac60091108c491dafb00877093170John Hoford            }
854fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette
855abb7d134c02ac60091108c491dafb00877093170John Hoford            a.recycle();
856abb7d134c02ac60091108c491dafb00877093170John Hoford        }
8574b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette
858abb7d134c02ac60091108c491dafb00877093170John Hoford    }
859abb7d134c02ac60091108c491dafb00877093170John Hoford
860e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui    static class VGroup {
86155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // mStackedMatrix is only used temporarily when drawing, it combines all
86255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // the parents' local matrices with the current one.
86355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private final Matrix mStackedMatrix = new Matrix();
86455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
86555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        /////////////////////////////////////////////////////
86655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables below need to be copied (deep copy if applicable) for mutation.
8678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        final ArrayList<Object> mChildren = new ArrayList<Object>();
868abb7d134c02ac60091108c491dafb00877093170John Hoford
86963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mRotate = 0;
87063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mPivotX = 0;
87163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private float mPivotY = 0;
872452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mScaleX = 1;
873452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mScaleY = 1;
874452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mTranslateX = 0;
875452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui        private float mTranslateY = 0;
8762af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        private float mGroupAlpha = 1;
8774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
87855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // mLocalMatrix is updated based on the update of transformation information,
87955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // either parsed from the XML or by animation.
8804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private final Matrix mLocalMatrix = new Matrix();
8818e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        private int mChangingConfigurations;
88263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        private int[] mThemeAttrs;
883e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        private String mGroupName = null;
884e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
88555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) {
88655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mRotate = copy.mRotate;
88755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mPivotX = copy.mPivotX;
88855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mPivotY = copy.mPivotY;
88955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mScaleX = copy.mScaleX;
89055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mScaleY = copy.mScaleY;
89155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTranslateX = copy.mTranslateX;
89255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTranslateY = copy.mTranslateY;
89355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mGroupAlpha = copy.mGroupAlpha;
89455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mThemeAttrs = copy.mThemeAttrs;
89555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mGroupName = copy.mGroupName;
89655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mChangingConfigurations = copy.mChangingConfigurations;
89755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            if (mGroupName != null) {
89855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                targetsMap.put(mGroupName, this);
89955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            }
90055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
90155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mLocalMatrix.set(copy.mLocalMatrix);
90255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
9038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            final ArrayList<Object> children = copy.mChildren;
9048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui            for (int i = 0; i < children.size(); i++) {
9058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                Object copyChild = children.get(i);
9068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                if (copyChild instanceof VGroup) {
9078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VGroup copyGroup = (VGroup) copyChild;
9088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mChildren.add(new VGroup(copyGroup, targetsMap));
9098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                } else if (copyChild instanceof VPath) {
9108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath copyPath = (VPath) copyChild;
9118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    VPath newPath = new VPath(copyPath);
9128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    mChildren.add(newPath);
9138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    if (newPath.mPathName != null) {
9148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                        targetsMap.put(newPath.mPathName, newPath);
9158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui                    }
91655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                }
91755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            }
91855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
91955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
92055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public VGroup() {
92155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
92255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
923e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        /* Getter and Setter */
924e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getRotation() {
925e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mRotate;
926e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
927e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
928e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setRotation(float rotation) {
929e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (rotation != mRotate) {
930e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mRotate = rotation;
931e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
932e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
933e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
934e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
935e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getPivotX() {
936e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPivotX;
937e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
938e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
939e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setPivotX(float pivotX) {
940e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (pivotX != mPivotX) {
941e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPivotX = pivotX;
942e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
943e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
944e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
945e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
946e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getPivotY() {
947e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPivotY;
948e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
949e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
950e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setPivotY(float pivotY) {
951e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (pivotY != mPivotY) {
952e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mPivotY = pivotY;
953e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
954e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
955e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
956e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
957e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getScaleX() {
958e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mScaleX;
959e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
9604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
961e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setScaleX(float scaleX) {
962e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (scaleX != mScaleX) {
963e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mScaleX = scaleX;
964e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
965e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
966e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
967e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
968e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getScaleY() {
969e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mScaleY;
970e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
971e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
972e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setScaleY(float scaleY) {
973e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (scaleY != mScaleY) {
974e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mScaleY = scaleY;
975e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
976e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
977e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
978e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
979e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getTranslateX() {
980e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTranslateX;
981e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
982e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
983e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setTranslateX(float translateX) {
984e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (translateX != mTranslateX) {
985e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mTranslateX = translateX;
986e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
987e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
988e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
989e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
990e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getTranslateY() {
991e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTranslateY;
992e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
993e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
994e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setTranslateY(float translateY) {
995e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (translateY != mTranslateY) {
996e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mTranslateY = translateY;
997e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                updateLocalMatrix();
998e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
999e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1000e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1001e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public float getAlpha() {
1002e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mGroupAlpha;
1003e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1004e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1005e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public void setAlpha(float groupAlpha) {
1006e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            if (groupAlpha != mGroupAlpha) {
1007e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui                mGroupAlpha = groupAlpha;
1008e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            }
1009e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1010e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1011e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public String getGroupName() {
1012e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mGroupName;
10134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
10144d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
10154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        public Matrix getLocalMatrix() {
10164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return mLocalMatrix;
10174d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
10184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
10194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        public boolean canApplyTheme() {
10204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            return mThemeAttrs != null;
10214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
10224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
10238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        public void inflate(Resources res, AttributeSet attrs, Theme theme) {
10248e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            final TypedArray a = obtainAttributes(res, theme, attrs,
10258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    R.styleable.VectorDrawableGroup);
10268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            updateStateFromTypedArray(a);
10278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            a.recycle();
10288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        }
10298e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
10308e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        private void updateStateFromTypedArray(TypedArray a) {
10318e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            // Account for any configuration changes.
10328e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mChangingConfigurations |= a.getChangingConfigurations();
103363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
10348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            // Extract the theme attributes, if any.
10358e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mThemeAttrs = a.extractThemeAttrs();
103663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
103763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate);
103863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX);
103963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY);
1040452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX);
1041452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
1042452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
1043452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui            mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
10442af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui            mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha);
104563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
10468e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            final String groupName = a.getString(R.styleable.VectorDrawableGroup_name);
10478e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            if (groupName != null) {
10488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                mGroupName = groupName;
104963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            }
105063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
10518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            updateLocalMatrix();
10528e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        }
10534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
10548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        public void applyTheme(Theme t) {
10558e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            if (mThemeAttrs == null) {
10568e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                return;
10574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            }
10584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui
10598e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath);
10608e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            updateStateFromTypedArray(a);
106163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            a.recycle();
106263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui        }
106363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui
10644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        private void updateLocalMatrix() {
10654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // The order we apply is the same as the
10664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            // RenderNode.cpp::applyViewPropertyTransforms().
10674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.reset();
10684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
10694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postScale(mScaleX, mScaleY);
10704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postRotate(mRotate, 0, 0);
10714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui            mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
10724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui        }
1073abb7d134c02ac60091108c491dafb00877093170John Hoford    }
1074abb7d134c02ac60091108c491dafb00877093170John Hoford
1075cf4832f69c8786b098ce18c24319021f8cd6733aztenghui    private static class VPath {
107655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        /////////////////////////////////////////////////////
107755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        // Variables below need to be copied (deep copy if applicable) for mutation.
10789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        private int[] mThemeAttrs;
10799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1080abb7d134c02ac60091108c491dafb00877093170John Hoford        int mStrokeColor = 0;
1081abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeWidth = 0;
1082abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeOpacity = Float.NaN;
10832af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui        int mFillColor = Color.BLACK;
1084abb7d134c02ac60091108c491dafb00877093170John Hoford        int mFillRule;
1085abb7d134c02ac60091108c491dafb00877093170John Hoford        float mFillOpacity = Float.NaN;
1086abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathStart = 0;
1087abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathEnd = 1;
1088abb7d134c02ac60091108c491dafb00877093170John Hoford        float mTrimPathOffset = 0;
10899453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
1090abb7d134c02ac60091108c491dafb00877093170John Hoford        boolean mClip = false;
10914b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        Paint.Cap mStrokeLineCap = Paint.Cap.BUTT;
10924b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette        Paint.Join mStrokeLineJoin = Paint.Join.MITER;
1093abb7d134c02ac60091108c491dafb00877093170John Hoford        float mStrokeMiterlimit = 4;
10949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
109555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private PathParser.PathDataNode[] mNodes = null;
10968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui        String mPathName;
109755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        private int mChangingConfigurations;
1098abb7d134c02ac60091108c491dafb00877093170John Hoford
10999453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public VPath() {
11009453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            // Empty constructor.
11019453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
11029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
110355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public VPath(VPath copy) {
110455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mThemeAttrs = copy.mThemeAttrs;
110555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
110655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeColor = copy.mStrokeColor;
110755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeWidth = copy.mStrokeWidth;
110855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeOpacity = copy.mStrokeOpacity;
110955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mFillColor = copy.mFillColor;
111055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mFillRule = copy.mFillRule;
111155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mFillOpacity = copy.mFillOpacity;
111255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTrimPathStart = copy.mTrimPathStart;
111355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTrimPathEnd = copy.mTrimPathEnd;
111455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mTrimPathOffset = copy.mTrimPathOffset;
111555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
111655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mClip = copy.mClip;
111755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeLineCap = copy.mStrokeLineCap;
111855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeLineJoin = copy.mStrokeLineJoin;
111955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mStrokeMiterlimit = copy.mStrokeMiterlimit;
112055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
112155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mNodes = PathParser.deepCopyNodes(copy.mNodes);
112255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mPathName = copy.mPathName;
112355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mChangingConfigurations = copy.mChangingConfigurations;
112455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        }
112555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
1126abb7d134c02ac60091108c491dafb00877093170John Hoford        public void toPath(Path path) {
1127abb7d134c02ac60091108c491dafb00877093170John Hoford            path.reset();
112855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            if (mNodes != null) {
112955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                PathParser.PathDataNode.nodesToPath(mNodes, path);
1130abb7d134c02ac60091108c491dafb00877093170John Hoford            }
1131abb7d134c02ac60091108c491dafb00877093170John Hoford        }
1132abb7d134c02ac60091108c491dafb00877093170John Hoford
1133e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        public String getPathName() {
1134e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mPathName;
1135abb7d134c02ac60091108c491dafb00877093170John Hoford        }
1136abb7d134c02ac60091108c491dafb00877093170John Hoford
11377f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) {
11387f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            switch (id) {
11397f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_BUTT:
11407f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.BUTT;
11417f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_ROUND:
11427f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.ROUND;
11437f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINECAP_SQUARE:
11447f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Cap.SQUARE;
11457f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                default:
11467f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return defValue;
11477f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11487f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        }
11497f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
11507f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) {
11517f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            switch (id) {
11527f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_MITER:
11537f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.MITER;
11547f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_ROUND:
11557f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.ROUND;
11567f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                case LINEJOIN_BEVEL:
11577f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return Paint.Join.BEVEL;
11587f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                default:
11597f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    return defValue;
11607f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            }
11617f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette        }
11627f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette
1163eb034fbca40006c55db143047eb628c4b657730aztenghui        /* Setters and Getters, mostly used by animator from AnimatedVectorDrawable. */
1164eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1165eb034fbca40006c55db143047eb628c4b657730aztenghui        public PathParser.PathDataNode[] getPathData() {
116655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            return mNodes;
1167eb034fbca40006c55db143047eb628c4b657730aztenghui        }
1168eb034fbca40006c55db143047eb628c4b657730aztenghui
1169eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
117055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui        public void setPathData(PathParser.PathDataNode[] nodes) {
117155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            if (!PathParser.canMorph(mNodes, nodes)) {
1172eb034fbca40006c55db143047eb628c4b657730aztenghui                // This should not happen in the middle of animation.
117355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                mNodes = PathParser.deepCopyNodes(nodes);
1174eb034fbca40006c55db143047eb628c4b657730aztenghui            } else {
117555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui                PathParser.updateNodes(mNodes, nodes);
1176eb034fbca40006c55db143047eb628c4b657730aztenghui            }
1177eb034fbca40006c55db143047eb628c4b657730aztenghui        }
1178eb034fbca40006c55db143047eb628c4b657730aztenghui
1179eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1180e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        int getStroke() {
1181e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeColor;
1182e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1183e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1184eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1185e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStroke(int strokeColor) {
1186e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeColor = strokeColor;
1187e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1188e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1189eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1190e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getStrokeWidth() {
1191e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeWidth;
1192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1193e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1194eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1195e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStrokeWidth(float strokeWidth) {
1196e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeWidth = strokeWidth;
1197e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1198e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1199eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1200e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getStrokeOpacity() {
1201e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mStrokeOpacity;
1202e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1203e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1204eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1205e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setStrokeOpacity(float strokeOpacity) {
1206e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mStrokeOpacity = strokeOpacity;
1207e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1208e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1209eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1210e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        int getFill() {
1211e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mFillColor;
1212e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1213e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1214eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1215e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setFill(int fillColor) {
1216e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mFillColor = fillColor;
1217e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1218e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1219eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1220e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getFillOpacity() {
1221e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mFillOpacity;
1222e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1223e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1224eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1225e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setFillOpacity(float fillOpacity) {
1226e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mFillOpacity = fillOpacity;
1227e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1228e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1229eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1230e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathStart() {
1231e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathStart;
1232e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1233e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1234eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1235e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathStart(float trimPathStart) {
1236e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathStart = trimPathStart;
1237e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1238e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1239eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1240e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathEnd() {
1241e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathEnd;
1242e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1243e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1244eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1245e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathEnd(float trimPathEnd) {
1246e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathEnd = trimPathEnd;
1247e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1248e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1249eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1250e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        float getTrimPathOffset() {
1251e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            return mTrimPathOffset;
1252e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1253e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
1254eb034fbca40006c55db143047eb628c4b657730aztenghui        @SuppressWarnings("unused")
1255e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        void setTrimPathOffset(float trimPathOffset) {
1256e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui            mTrimPathOffset = trimPathOffset;
1257e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui        }
1258e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui
12598e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        public boolean canApplyTheme() {
12608e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            return mThemeAttrs != null;
12618e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        }
12628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
12639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        public void inflate(Resources r, AttributeSet attrs, Theme theme) {
12649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath);
12658e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            updateStateFromTypedArray(a);
1266abb7d134c02ac60091108c491dafb00877093170John Hoford            a.recycle();
1267abb7d134c02ac60091108c491dafb00877093170John Hoford        }
1268abb7d134c02ac60091108c491dafb00877093170John Hoford
12698e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        private void updateStateFromTypedArray(TypedArray a) {
12708e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            // Account for any configuration changes.
12718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mChangingConfigurations |= a.getChangingConfigurations();
12729453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12738e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            // Extract the theme attributes, if any.
12748e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mThemeAttrs = a.extractThemeAttrs();
12759453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
12767f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip);
127755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
12788e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            mPathName = a.getString(R.styleable.VectorDrawablePath_name);
127955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui            mNodes = PathParser.createNodesFromPathData(a.getString(
12808e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                    R.styleable.VectorDrawablePath_pathData));
128155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui
12827f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor);
12837f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity);
12847f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeLineCap = getStrokeLineCap(a.getInt(
12857f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap);
12867f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeLineJoin = getStrokeLineJoin(a.getInt(
12877f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin);
12887f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeMiterlimit = a.getFloat(
12897f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit);
12907f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor);
12917f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeOpacity = a.getFloat(
12927f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity);
12937f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth);
12947f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd);
12957f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mTrimPathOffset = a.getFloat(
12967f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset);
12977f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette            mTrimPathStart = a.getFloat(
12987f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette                    R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart);
12999453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
13009453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            updateColorAlphas();
13018e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        }
13028e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
13038e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette        public void applyTheme(Theme t) {
13048e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            if (mThemeAttrs == null) {
13058e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette                return;
13068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            }
13078e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette
13088e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath);
13098e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette            updateStateFromTypedArray(a);
131063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui            a.recycle();
13119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
13129453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
13139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        private void updateColorAlphas() {
13149453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (!Float.isNaN(mFillOpacity)) {
13152af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                mFillColor = applyAlpha(mFillColor, mFillOpacity);
13169453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
13179453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette
13189453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            if (!Float.isNaN(mStrokeOpacity)) {
13192af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui                mStrokeColor = applyAlpha(mStrokeColor, mStrokeOpacity);
13209453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette            }
13219453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette        }
1322abb7d134c02ac60091108c491dafb00877093170John Hoford    }
1323abb7d134c02ac60091108c491dafb00877093170John Hoford}
1324