VectorDrawable.java revision 9c13ed366f205d94b2f3f4ddc96b55b1b9faadba
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; 45abb7d134c02ac60091108c491dafb00877093170John Hoford 46abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException; 47abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList; 484d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack; 494b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 50abb7d134c02ac60091108c491dafb00877093170John Hoford/** 516beeb75723cec42603b47664bce794a2b97d7bacChet Haase * This lets you create a drawable based on an XML vector graphic. It can be 52d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code><vector></code> element. 53abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 5446e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * The vector drawable has the following elements: 55abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 56177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code><vector></code></dt> 57a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 58a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined a vector drawable 59a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 60a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:width</code></dt> 61a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic width of the drawable. 62a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 63a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:height</code></dt> 64a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic height the drawable. 65a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 66a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportWidth</code></dt> 67a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the width of the viewport space. Viewport is basically 68a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 69a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportHeight</code></dt> 70a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the height of the viewport space. Viewport is basically 71a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 72a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tint</code></dt> 73a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd> 74a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tintMode</code></dt> 75a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd> 76a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:autoMirrored</code></dt> 77a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Indicates if the drawable needs to be mirrored when its layout direction is 78a95c8abb366d9c39450513335f550b56da13b30aztenghui * RTL (right-to-left).</dd> 79a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 80a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 81a95c8abb366d9c39450513335f550b56da13b30aztenghui * 82a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 836d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code><group></code></dt> 84452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information. 85452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport. 86a95c8abb366d9c39450513335f550b56da13b30aztenghui * And the transformations are applied in the order of scale, rotate then translate. 87a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 88a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:rotation</code></dt> 89a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The degrees of rotation of the group.</dd> 90a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotX</code></dt> 91a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group. 92a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 93a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotY</code></dt> 94a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group. 95a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 96a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleX</code></dt> 97a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the X Coordinate.</dd> 98a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleY</code></dt> 99a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the Y coordinate.</dd> 100a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateX</code></dt> 101a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the X coordinate. 102a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 103a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateY</code></dt> 104a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the Y coordinate. 105a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 106a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 107a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 108a95c8abb366d9c39450513335f550b56da13b30aztenghui * 109a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 110abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><path></code></dt> 1116d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn. 112abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 113a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 114a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the path.</dd> 115a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 11646e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute 117a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data. This is defined in the viewport space.</dd> 118a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:fillColor</code></dt> 119a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui * <dd>Defines the color to fill the path (none if not present).</dd> 120a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeColor</code></dt> 121d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd> 122a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeWidth</code></dt> 123a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The width a path stroke.</dd> 1242e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:strokeAlpha</code></dt> 1252e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity of a path stroke.</dd> 1262e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:fillAlpha</code></dt> 1272e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity to fill the path with.</dd> 128a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathStart</code></dt> 129a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd> 130a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathEnd</code></dt> 131a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd> 132a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathOffset</code></dt> 133a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Shift trim region (allows showed region to include the start and end), in the range 134a95c8abb366d9c39450513335f550b56da13b30aztenghui * from 0 to 1.</dd> 135a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineCap</code></dt> 136a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the linecap for a stroked path: butt, round, square.</dd> 137a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineJoin</code></dt> 138a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd> 139a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeMiterLimit</code></dt> 140a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the Miter limit for a stroked path.</dd> 141a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 142a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 143a95c8abb366d9c39450513335f550b56da13b30aztenghui * 144a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 145a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code><clip-path></code></dt> 146a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines path to be the current clip. 147a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 148a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 149a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the clip path.</dd> 150a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 151a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines clip path string. This is using exactly same format as "d" attribute 152a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data.</dd> 153a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 154abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl> 155a95c8abb366d9c39450513335f550b56da13b30aztenghui * <li>Here is a simple VectorDrawable in this vectordrawable.xml file. 156a95c8abb366d9c39450513335f550b56da13b30aztenghui * <pre> 157a95c8abb366d9c39450513335f550b56da13b30aztenghui * <vector xmlns:android="http://schemas.android.com/apk/res/android" 158a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:height="64dp" 159a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:width="64dp" 160a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportHeight="600" 161a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportWidth="600" > 162a95c8abb366d9c39450513335f550b56da13b30aztenghui * <group 163a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="rotationGroup" 164a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotX="300.0" 165a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotY="300.0" 166a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:rotation="45.0" > 167a95c8abb366d9c39450513335f550b56da13b30aztenghui * <path 168a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="v" 169a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:fillColor="#000000" 170a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 171a95c8abb366d9c39450513335f550b56da13b30aztenghui * </group> 172a95c8abb366d9c39450513335f550b56da13b30aztenghui * </vector> 173a95c8abb366d9c39450513335f550b56da13b30aztenghui * </pre></li> 174abb7d134c02ac60091108c491dafb00877093170John Hoford */ 175a95c8abb366d9c39450513335f550b56da13b30aztenghui 176abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable { 1779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private static final String LOGTAG = VectorDrawable.class.getSimpleName(); 1789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 179a95c8abb366d9c39450513335f550b56da13b30aztenghui private static final String SHAPE_CLIP_PATH = "clip-path"; 1806d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui private static final String SHAPE_GROUP = "group"; 181abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_PATH = "path"; 182abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VECTOR = "vector"; 183abb7d134c02ac60091108c491dafb00877093170John Hoford 184abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_BUTT = 0; 185abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_ROUND = 1; 186abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_SQUARE = 2; 1879453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 188abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_MITER = 0; 189abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_ROUND = 1; 190abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_BEVEL = 2; 1919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final boolean DBG_VECTOR_DRAWABLE = false; 1934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 19455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private VectorDrawableState mVectorState; 195e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 196b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette private PorterDuffColorFilter mTintFilter; 197b07b086bd42181f62718a6394b56be3917b12511Alan Viverette private ColorFilter mColorFilter; 198b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 19955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private boolean mMutated; 20055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 201482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise, 202482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // caching the bitmap by default is allowed. 203482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui private boolean mAllowCaching = true; 204482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 205abb7d134c02ac60091108c491dafb00877093170John Hoford public VectorDrawable() { 20655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(); 207abb7d134c02ac60091108c491dafb00877093170John Hoford } 208abb7d134c02ac60091108c491dafb00877093170John Hoford 2099453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) { 21016c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui if (theme != null && state.canApplyTheme()) { 21116c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui // If we need to apply a theme, implicitly mutate. 21216c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = new VectorDrawableState(state); 2139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette applyTheme(theme); 21416c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui } else { 21516c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = state; 2169453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 217b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 218b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 219abb7d134c02ac60091108c491dafb00877093170John Hoford } 220abb7d134c02ac60091108c491dafb00877093170John Hoford 22155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 22255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public Drawable mutate() { 22355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!mMutated && super.mutate() == this) { 22455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(mVectorState); 22555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mMutated = true; 22655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 22755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return this; 22855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 22955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 230e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Object getTargetByName(String name) { 23155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); 232e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 233e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 234abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 235abb7d134c02ac60091108c491dafb00877093170John Hoford public ConstantState getConstantState() { 23655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState.mChangingConfigurations = getChangingConfigurations(); 23755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState; 238abb7d134c02ac60091108c491dafb00877093170John Hoford } 239abb7d134c02ac60091108c491dafb00877093170John Hoford 2404554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette @Override 241abb7d134c02ac60091108c491dafb00877093170John Hoford public void draw(Canvas canvas) { 2424b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final Rect bounds = getBounds(); 2431968201b44567262e7b2e382eee3d88990748d89Dan Sandler if (bounds.width() == 0 || bounds.height() == 0) { 2441968201b44567262e7b2e382eee3d88990748d89Dan Sandler // too small to draw 2451968201b44567262e7b2e382eee3d88990748d89Dan Sandler return; 2461968201b44567262e7b2e382eee3d88990748d89Dan Sandler } 2471968201b44567262e7b2e382eee3d88990748d89Dan Sandler 2480670f029a4e59448aa53b46a98e60dff6404f360ztenghui final int saveCount = canvas.save(); 249738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui final boolean needMirroring = needMirroring(); 250738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2514b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.translate(bounds.left, bounds.top); 252738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (needMirroring) { 253738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.translate(bounds.width(), 0); 254738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.scale(-1.0f, 1.0f); 255738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 256482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 257b07b086bd42181f62718a6394b56be3917b12511Alan Viverette // Color filters always override tint filters. 258b07b086bd42181f62718a6394b56be3917b12511Alan Viverette final ColorFilter colorFilter = mColorFilter == null ? mTintFilter : mColorFilter; 259b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 260482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (!mAllowCaching) { 2618490354dc651dd8f25036ef0dda7917fb33013edztenghui // AnimatedVectorDrawable 2628490354dc651dd8f25036ef0dda7917fb33013edztenghui if (!mVectorState.hasTranslucentRoot()) { 263b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVectorState.mVPathRenderer.draw( 264b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas, bounds.width(), bounds.height(), colorFilter); 2658490354dc651dd8f25036ef0dda7917fb33013edztenghui } else { 2668490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.createCachedBitmapIfNeeded(bounds); 2678490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.updateCachedBitmap(bounds); 268b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter); 2698490354dc651dd8f25036ef0dda7917fb33013edztenghui } 270482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } else { 2718490354dc651dd8f25036ef0dda7917fb33013edztenghui // Static Vector Drawable case. 2728490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.createCachedBitmapIfNeeded(bounds); 2738490354dc651dd8f25036ef0dda7917fb33013edztenghui if (!mVectorState.canReuseCache()) { 2748490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.updateCachedBitmap(bounds); 275482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.updateCacheStates(); 276482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 277b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter); 278482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 279738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2804b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.restoreToCount(saveCount); 281abb7d134c02ac60091108c491dafb00877093170John Hoford } 282abb7d134c02ac60091108c491dafb00877093170John Hoford 283abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 284e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getAlpha() { 285e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mVectorState.mVPathRenderer.getRootAlpha(); 286e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 287e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 288e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 289abb7d134c02ac60091108c491dafb00877093170John Hoford public void setAlpha(int alpha) { 2902af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) { 2912af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mVectorState.mVPathRenderer.setRootAlpha(alpha); 292abb7d134c02ac60091108c491dafb00877093170John Hoford invalidateSelf(); 293abb7d134c02ac60091108c491dafb00877093170John Hoford } 294abb7d134c02ac60091108c491dafb00877093170John Hoford } 295abb7d134c02ac60091108c491dafb00877093170John Hoford 296abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 297abb7d134c02ac60091108c491dafb00877093170John Hoford public void setColorFilter(ColorFilter colorFilter) { 298b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mColorFilter = colorFilter; 299fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette invalidateSelf(); 300abb7d134c02ac60091108c491dafb00877093170John Hoford } 301abb7d134c02ac60091108c491dafb00877093170John Hoford 302abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 303a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintList(ColorStateList tint) { 304b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 305a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTint != tint) { 306b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTint = tint; 307a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode); 308a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette invalidateSelf(); 309a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 310a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 311b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 312a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette @Override 313a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintMode(Mode tintMode) { 314a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette final VectorDrawableState state = mVectorState; 315a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTintMode != tintMode) { 316a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette state.mTintMode = tintMode; 317a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode); 318b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette invalidateSelf(); 319b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 320b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 321b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 322b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 323607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean isStateful() { 324607bd848269fb802550e63aa61945790616f97a7Alan Viverette return super.isStateful() || (mVectorState != null && mVectorState.mTint != null 325607bd848269fb802550e63aa61945790616f97a7Alan Viverette && mVectorState.mTint.isStateful()); 326607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 327607bd848269fb802550e63aa61945790616f97a7Alan Viverette 328607bd848269fb802550e63aa61945790616f97a7Alan Viverette @Override 329b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette protected boolean onStateChange(int[] stateSet) { 330b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 331b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != null && state.mTintMode != null) { 332b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 333607bd848269fb802550e63aa61945790616f97a7Alan Viverette invalidateSelf(); 334b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return true; 335b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 336b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return false; 337b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 338b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 339b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 340abb7d134c02ac60091108c491dafb00877093170John Hoford public int getOpacity() { 341abb7d134c02ac60091108c491dafb00877093170John Hoford return PixelFormat.TRANSLUCENT; 342abb7d134c02ac60091108c491dafb00877093170John Hoford } 343abb7d134c02ac60091108c491dafb00877093170John Hoford 344abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 345abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicWidth() { 346ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseWidth; 347abb7d134c02ac60091108c491dafb00877093170John Hoford } 348abb7d134c02ac60091108c491dafb00877093170John Hoford 349abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 350abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicHeight() { 351ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseHeight; 352abb7d134c02ac60091108c491dafb00877093170John Hoford } 353abb7d134c02ac60091108c491dafb00877093170John Hoford 354abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 3559453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 3569453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme(); 3579453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette @Override 3609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 3619453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette super.applyTheme(t); 3629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VectorDrawableState state = mVectorState; 364607bd848269fb802550e63aa61945790616f97a7Alan Viverette if (state != null && state.mThemeAttrs != null) { 365607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(state.mThemeAttrs, R.styleable.VectorDrawable); 366607bd848269fb802550e63aa61945790616f97a7Alan Viverette try { 367607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.mCacheDirty = true; 368607bd848269fb802550e63aa61945790616f97a7Alan Viverette updateStateFromTypedArray(a); 369607bd848269fb802550e63aa61945790616f97a7Alan Viverette } catch (XmlPullParserException e) { 370607bd848269fb802550e63aa61945790616f97a7Alan Viverette throw new RuntimeException(e); 371607bd848269fb802550e63aa61945790616f97a7Alan Viverette } finally { 372607bd848269fb802550e63aa61945790616f97a7Alan Viverette a.recycle(); 373607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 374607bd848269fb802550e63aa61945790616f97a7Alan Viverette 375607bd848269fb802550e63aa61945790616f97a7Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 376607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 377607bd848269fb802550e63aa61945790616f97a7Alan Viverette 378ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer path = state.mVPathRenderer; 3799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (path != null && path.canApplyTheme()) { 3809453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.applyTheme(t); 3819453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3829453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3839453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 384fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount /** 385fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension. 386fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * This is used to calculate the path animation accuracy. 387fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * 388fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * @hide 389fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount */ 390fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount public float getPixelSize() { 391fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount if (mVectorState == null && mVectorState.mVPathRenderer == null || 392fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mBaseWidth == 0 || 393fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mBaseHeight == 0 || 394fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mViewportHeight == 0 || 395fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mViewportWidth == 0) { 396fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount return 1; // fall back to 1:1 pixel mapping. 397fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount } 398fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth; 399fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight; 400fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth; 401fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight; 402fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float scaleX = viewportWidth / intrinsicWidth; 403fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float scaleY = viewportHeight / intrinsicHeight; 404fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount return Math.min(scaleX, scaleY); 405fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount } 406fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount 4074b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette /** @hide */ 4084b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette public static VectorDrawable create(Resources resources, int rid) { 4094b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette try { 410874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final XmlPullParser parser = resources.getXml(rid); 411874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final AttributeSet attrs = Xml.asAttributeSet(parser); 412874bcd82c223ce58c9d76edcf619b3988c672307ztenghui int type; 413874bcd82c223ce58c9d76edcf619b3988c672307ztenghui while ((type=parser.next()) != XmlPullParser.START_TAG && 414874bcd82c223ce58c9d76edcf619b3988c672307ztenghui type != XmlPullParser.END_DOCUMENT) { 415874bcd82c223ce58c9d76edcf619b3988c672307ztenghui // Empty loop 416874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 417874bcd82c223ce58c9d76edcf619b3988c672307ztenghui if (type != XmlPullParser.START_TAG) { 418874bcd82c223ce58c9d76edcf619b3988c672307ztenghui throw new XmlPullParserException("No start tag found"); 419874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 4204b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4214b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final VectorDrawable drawable = new VectorDrawable(); 422874bcd82c223ce58c9d76edcf619b3988c672307ztenghui drawable.inflate(resources, parser, attrs); 4234b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4244b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return drawable; 4254b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (XmlPullParserException e) { 4264b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 4274b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (IOException e) { 4284b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 4294b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 4304b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return null; 4314b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 4324b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4332af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private static int applyAlpha(int color, float alpha) { 4342af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int alphaBytes = Color.alpha(color); 4352af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color &= 0x00FFFFFF; 4362af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color |= ((int) (alphaBytes * alpha)) << 24; 4372af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return color; 4382af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 4392af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 4409cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette @Override 4419cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 4429cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette throws XmlPullParserException, IOException { 443a95c8abb366d9c39450513335f550b56da13b30aztenghui final VectorDrawableState state = mVectorState; 444a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 445a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mVPathRenderer = pathRenderer; 446a95c8abb366d9c39450513335f550b56da13b30aztenghui 447607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable); 4489cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette updateStateFromTypedArray(a); 4499cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette a.recycle(); 4509cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 451a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mCacheDirty = true; 45255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui inflateInternal(res, parser, attrs, theme); 4539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4549cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 4559cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4569cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 457a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException { 4589cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 459a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 4609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4618e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 4628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 4638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 4649cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette // Extract the theme attributes, if any. 4659cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 4669cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4679cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1); 4689cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tintMode != -1) { 4699cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN); 4709cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4719cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4729cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint); 4739cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tint != null) { 4749cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTint = tint; 4759cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 476738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 477738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui state.mAutoMirrored = a.getBoolean( 478738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored); 479a95c8abb366d9c39450513335f550b56da13b30aztenghui 480a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportWidth = a.getFloat( 481a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportWidth, pathRenderer.mViewportWidth); 482a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportHeight = a.getFloat( 483a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportHeight, pathRenderer.mViewportHeight); 484a95c8abb366d9c39450513335f550b56da13b30aztenghui 485a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mViewportWidth <= 0) { 486a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 4871c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportWidth > 0"); 488a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mViewportHeight <= 0) { 489a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 4901c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportHeight > 0"); 491a95c8abb366d9c39450513335f550b56da13b30aztenghui } 492a95c8abb366d9c39450513335f550b56da13b30aztenghui 493a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseWidth = a.getDimension( 494a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_width, pathRenderer.mBaseWidth); 495a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseHeight = a.getDimension( 496a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_height, pathRenderer.mBaseHeight); 497a95c8abb366d9c39450513335f550b56da13b30aztenghui 498a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mBaseWidth <= 0) { 499a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5001c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires width > 0"); 501a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mBaseHeight <= 0) { 502a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5031c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires height > 0"); 504a95c8abb366d9c39450513335f550b56da13b30aztenghui } 5058490354dc651dd8f25036ef0dda7917fb33013edztenghui 5068490354dc651dd8f25036ef0dda7917fb33013edztenghui final float alphaInFloat = a.getFloat(R.styleable.VectorDrawable_alpha, 5078490354dc651dd8f25036ef0dda7917fb33013edztenghui pathRenderer.getAlpha()); 5088490354dc651dd8f25036ef0dda7917fb33013edztenghui pathRenderer.setAlpha(alphaInFloat); 5098490354dc651dd8f25036ef0dda7917fb33013edztenghui 5108490354dc651dd8f25036ef0dda7917fb33013edztenghui pathRenderer.mRootName = a.getString(R.styleable.VectorDrawable_name); 5118490354dc651dd8f25036ef0dda7917fb33013edztenghui if (pathRenderer.mRootName != null) { 5128490354dc651dd8f25036ef0dda7917fb33013edztenghui pathRenderer.mVGTargetsMap.put(pathRenderer.mRootName, pathRenderer); 5138490354dc651dd8f25036ef0dda7917fb33013edztenghui } 5149cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 5159cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 51655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 5178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette Theme theme) throws XmlPullParserException, IOException { 5188e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final VectorDrawableState state = mVectorState; 519a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 520abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noPathTag = true; 5219453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Use a stack to help to build the group tree. 5234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The top of the stack is always the current group. 5244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 5254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(pathRenderer.mRootGroup); 526abb7d134c02ac60091108c491dafb00877093170John Hoford 527abb7d134c02ac60091108c491dafb00877093170John Hoford int eventType = parser.getEventType(); 528abb7d134c02ac60091108c491dafb00877093170John Hoford while (eventType != XmlPullParser.END_DOCUMENT) { 529abb7d134c02ac60091108c491dafb00877093170John Hoford if (eventType == XmlPullParser.START_TAG) { 5309453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final String tagName = parser.getName(); 5314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final VGroup currentGroup = groupStack.peek(); 5324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 533abb7d134c02ac60091108c491dafb00877093170John Hoford if (SHAPE_PATH.equals(tagName)) { 534a95c8abb366d9c39450513335f550b56da13b30aztenghui final VFullPath path = new VFullPath(); 5359453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.inflate(res, attrs, theme); 5368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(path); 537e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (path.getPathName() != null) { 53855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 539e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 540abb7d134c02ac60091108c491dafb00877093170John Hoford noPathTag = false; 5418e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= path.mChangingConfigurations; 542a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (SHAPE_CLIP_PATH.equals(tagName)) { 543a95c8abb366d9c39450513335f550b56da13b30aztenghui final VClipPath path = new VClipPath(); 544a95c8abb366d9c39450513335f550b56da13b30aztenghui path.inflate(res, attrs, theme); 545a95c8abb366d9c39450513335f550b56da13b30aztenghui currentGroup.mChildren.add(path); 546a95c8abb366d9c39450513335f550b56da13b30aztenghui if (path.getPathName() != null) { 547a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 548a95c8abb366d9c39450513335f550b56da13b30aztenghui } 549a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mChangingConfigurations |= path.mChangingConfigurations; 5506d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 5514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui VGroup newChildGroup = new VGroup(); 5524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui newChildGroup.inflate(res, attrs, theme); 5538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(newChildGroup); 5544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(newChildGroup); 555e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (newChildGroup.getGroupName() != null) { 55655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 55755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui newChildGroup); 558e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 5598e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 560abb7d134c02ac60091108c491dafb00877093170John Hoford } 5614d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } else if (eventType == XmlPullParser.END_TAG) { 5624d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final String tagName = parser.getName(); 5634d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (SHAPE_GROUP.equals(tagName)) { 5644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.pop(); 5654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 566abb7d134c02ac60091108c491dafb00877093170John Hoford } 567abb7d134c02ac60091108c491dafb00877093170John Hoford eventType = parser.next(); 568abb7d134c02ac60091108c491dafb00877093170John Hoford } 5699453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the tree out for debug. 5714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (DBG_VECTOR_DRAWABLE) { 5724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 5736d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } 5746d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 575a95c8abb366d9c39450513335f550b56da13b30aztenghui if (noPathTag) { 5769453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final StringBuffer tag = new StringBuffer(); 5779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 578a95c8abb366d9c39450513335f550b56da13b30aztenghui if (tag.length() > 0) { 579a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(" or "); 580abb7d134c02ac60091108c491dafb00877093170John Hoford } 581a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(SHAPE_PATH); 5829453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5839453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette throw new XmlPullParserException("no " + tag + " defined"); 584abb7d134c02ac60091108c491dafb00877093170John Hoford } 585abb7d134c02ac60091108c491dafb00877093170John Hoford } 586abb7d134c02ac60091108c491dafb00877093170John Hoford 5874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void printGroupTree(VGroup currentGroup, int level) { 5884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui String indent = ""; 5898d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < level; i++) { 5904d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui indent += " "; 5914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the current node 5938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 5944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui + " rotation is " + currentGroup.mRotate); 5958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 5968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Then print all the children groups 5978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 5988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 5998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6008d0d24f7a2b1a59060aa18926984491691d3c667ztenghui printGroupTree((VGroup) child, level + 1); 6018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 60555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 60655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public int getChangingConfigurations() { 60755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return super.getChangingConfigurations() | mVectorState.mChangingConfigurations; 60855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 60955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 610482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui void setAllowCaching(boolean allowCaching) { 611482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mAllowCaching = allowCaching; 612482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 613482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 614738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui private boolean needMirroring() { 615738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 616738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 617738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 618738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 619738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public void setAutoMirrored(boolean mirrored) { 620738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (mVectorState.mAutoMirrored != mirrored) { 621738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mVectorState.mAutoMirrored = mirrored; 622738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui invalidateSelf(); 623738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 624738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 625738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 626738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 627738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public boolean isAutoMirrored() { 628738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return mVectorState.mAutoMirrored; 629738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 630738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 6315c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette private static class VectorDrawableState extends ConstantState { 6329cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette int[] mThemeAttrs; 6335c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette int mChangingConfigurations; 634ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui VPathRenderer mVPathRenderer; 635607bd848269fb802550e63aa61945790616f97a7Alan Viverette ColorStateList mTint = null; 636607bd848269fb802550e63aa61945790616f97a7Alan Viverette Mode mTintMode = DEFAULT_TINT_MODE; 637738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui boolean mAutoMirrored; 6385c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 639482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap mCachedBitmap; 640482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int[] mCachedThemeAttrs; 641482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui ColorStateList mCachedTint; 642482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Mode mCachedTintMode; 643482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int mCachedRootAlpha; 644670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCachedAutoMirrored; 645670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCacheDirty; 646482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 647b07b086bd42181f62718a6394b56be3917b12511Alan Viverette /** Temporary paint object used to draw cached bitmaps. */ 648b07b086bd42181f62718a6394b56be3917b12511Alan Viverette Paint mTempPaint; 649b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 65055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Deep copy for mutate() or implicitly mutate. 6515c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public VectorDrawableState(VectorDrawableState copy) { 6525c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette if (copy != null) { 6539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mThemeAttrs = copy.mThemeAttrs; 6545c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 655ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 6566f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVPathRenderer.mFillPaint != null) { 6576f6578e81c1df207da47e2e1337382341f271206Chet Haase mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint); 6586f6578e81c1df207da47e2e1337382341f271206Chet Haase } 6596f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVPathRenderer.mStrokePaint != null) { 6606f6578e81c1df207da47e2e1337382341f271206Chet Haase mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint); 6616f6578e81c1df207da47e2e1337382341f271206Chet Haase } 662b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = copy.mTint; 663b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = copy.mTintMode; 664738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mAutoMirrored = copy.mAutoMirrored; 6655c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6665c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6675c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 668b07b086bd42181f62718a6394b56be3917b12511Alan Viverette public void drawCachedBitmapWithRootAlpha(Canvas canvas, ColorFilter filter) { 6698490354dc651dd8f25036ef0dda7917fb33013edztenghui // The bitmap's size is the same as the bounds. 670b07b086bd42181f62718a6394b56be3917b12511Alan Viverette final Paint p = getPaint(filter); 671b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas.drawBitmap(mCachedBitmap, 0, 0, p); 6728490354dc651dd8f25036ef0dda7917fb33013edztenghui } 6738490354dc651dd8f25036ef0dda7917fb33013edztenghui 6748490354dc651dd8f25036ef0dda7917fb33013edztenghui public boolean hasTranslucentRoot() { 6758490354dc651dd8f25036ef0dda7917fb33013edztenghui return mVPathRenderer.getRootAlpha() < 255; 6768490354dc651dd8f25036ef0dda7917fb33013edztenghui } 6778490354dc651dd8f25036ef0dda7917fb33013edztenghui 6788490354dc651dd8f25036ef0dda7917fb33013edztenghui /** 6798490354dc651dd8f25036ef0dda7917fb33013edztenghui * @return null when there is no need for alpha paint. 6808490354dc651dd8f25036ef0dda7917fb33013edztenghui */ 681b07b086bd42181f62718a6394b56be3917b12511Alan Viverette public Paint getPaint(ColorFilter filter) { 682b07b086bd42181f62718a6394b56be3917b12511Alan Viverette if (!hasTranslucentRoot() && filter == null) { 683b07b086bd42181f62718a6394b56be3917b12511Alan Viverette return null; 6848490354dc651dd8f25036ef0dda7917fb33013edztenghui } 685b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 686b07b086bd42181f62718a6394b56be3917b12511Alan Viverette if (mTempPaint == null) { 687b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mTempPaint = new Paint(); 688b07b086bd42181f62718a6394b56be3917b12511Alan Viverette } 689b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mTempPaint.setAlpha(mVPathRenderer.getRootAlpha()); 690b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mTempPaint.setColorFilter(filter); 691b07b086bd42181f62718a6394b56be3917b12511Alan Viverette return mTempPaint; 6928490354dc651dd8f25036ef0dda7917fb33013edztenghui } 6938490354dc651dd8f25036ef0dda7917fb33013edztenghui 6948490354dc651dd8f25036ef0dda7917fb33013edztenghui public void updateCachedBitmap(Rect bounds) { 6958490354dc651dd8f25036ef0dda7917fb33013edztenghui mCachedBitmap.eraseColor(Color.TRANSPARENT); 6968490354dc651dd8f25036ef0dda7917fb33013edztenghui Canvas tmpCanvas = new Canvas(mCachedBitmap); 697b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height(), null); 6988490354dc651dd8f25036ef0dda7917fb33013edztenghui } 6998490354dc651dd8f25036ef0dda7917fb33013edztenghui 7008490354dc651dd8f25036ef0dda7917fb33013edztenghui public void createCachedBitmapIfNeeded(Rect bounds) { 7018490354dc651dd8f25036ef0dda7917fb33013edztenghui if (mCachedBitmap == null || !canReuseBitmap(bounds.width(), 7028490354dc651dd8f25036ef0dda7917fb33013edztenghui bounds.height())) { 7038490354dc651dd8f25036ef0dda7917fb33013edztenghui mCachedBitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), 7048490354dc651dd8f25036ef0dda7917fb33013edztenghui Bitmap.Config.ARGB_8888); 7059c13ed366f205d94b2f3f4ddc96b55b1b9faadbaztenghui mCacheDirty = true; 7068490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7078490354dc651dd8f25036ef0dda7917fb33013edztenghui 7088490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7098490354dc651dd8f25036ef0dda7917fb33013edztenghui 7108490354dc651dd8f25036ef0dda7917fb33013edztenghui public boolean canReuseBitmap(int width, int height) { 7118490354dc651dd8f25036ef0dda7917fb33013edztenghui if (width == mCachedBitmap.getWidth() 7128490354dc651dd8f25036ef0dda7917fb33013edztenghui && height == mCachedBitmap.getHeight()) { 7138490354dc651dd8f25036ef0dda7917fb33013edztenghui return true; 7148490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7158490354dc651dd8f25036ef0dda7917fb33013edztenghui return false; 7168490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7178490354dc651dd8f25036ef0dda7917fb33013edztenghui 7188490354dc651dd8f25036ef0dda7917fb33013edztenghui public boolean canReuseCache() { 719670689af43358568bf2b5916284f1cac5762f428ztenghui if (!mCacheDirty 720670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedThemeAttrs == mThemeAttrs 721482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTint == mTint 722482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTintMode == mTintMode 723670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedAutoMirrored == mAutoMirrored 7248490354dc651dd8f25036ef0dda7917fb33013edztenghui && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { 725482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return true; 726482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 727482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return false; 728482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 729482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 730482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public void updateCacheStates() { 731482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // Use shallow copy here and shallow comparison in canReuseCache(), 732482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // likely hit cache miss more, but practically not much difference. 733482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedThemeAttrs = mThemeAttrs; 734482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTint = mTint; 735482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTintMode = mTintMode; 736482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedRootAlpha = mVPathRenderer.getRootAlpha(); 737670689af43358568bf2b5916284f1cac5762f428ztenghui mCachedAutoMirrored = mAutoMirrored; 738670689af43358568bf2b5916284f1cac5762f428ztenghui mCacheDirty = false; 739482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 740482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 741607bd848269fb802550e63aa61945790616f97a7Alan Viverette @Override 742607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean canApplyTheme() { 743607bd848269fb802550e63aa61945790616f97a7Alan Viverette return super.canApplyTheme() || mThemeAttrs != null 744607bd848269fb802550e63aa61945790616f97a7Alan Viverette || (mVPathRenderer != null && mVPathRenderer.canApplyTheme()); 745607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 746607bd848269fb802550e63aa61945790616f97a7Alan Viverette 74755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VectorDrawableState() { 74855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVPathRenderer = new VPathRenderer(); 74955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 75055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 7515c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7525c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable() { 7535c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, null, null); 7545c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7555c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7565c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7575c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res) { 7585c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, null); 7595c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7605c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7615c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7625c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res, Theme theme) { 7635c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, theme); 7645c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7655c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7665c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7675c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public int getChangingConfigurations() { 7685c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return mChangingConfigurations; 7695c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7705c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7715c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 772ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui private static class VPathRenderer { 7734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui /* Right now the internal data structure is organized as a tree. 7744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Each node can be a group node, or a path. 7754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * A group node can have groups or paths as children, but a path node has 7764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * no children. 7774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * One example can be: 7784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Root Group 7794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / | \ 7804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Group Path Group 7814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / \ | 7824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Path Path Path 7834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * 7844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui */ 78555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables that only used temporarily inside the draw() call, so there 78655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // is no need for deep copying. 7876f6578e81c1df207da47e2e1337382341f271206Chet Haase private final Path mPath; 7886f6578e81c1df207da47e2e1337382341f271206Chet Haase private final Path mRenderPath; 7894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final Matrix IDENTITY_MATRIX = new Matrix(); 79055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mFinalPathMatrix = new Matrix(); 7914b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7924b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mStrokePaint; 7934b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mFillPaint; 794abb7d134c02ac60091108c491dafb00877093170John Hoford private PathMeasure mPathMeasure; 7954b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 79655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 79755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 7988e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 79955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final VGroup mRootGroup; 800a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseWidth = 0; 801a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseHeight = 0; 802a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportWidth = 0; 803a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportHeight = 0; 8048490354dc651dd8f25036ef0dda7917fb33013edztenghui int mRootAlpha = 0xFF; 8058490354dc651dd8f25036ef0dda7917fb33013edztenghui String mRootName = null; 8069453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 80755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 808abb7d134c02ac60091108c491dafb00877093170John Hoford 809ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer() { 8104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mRootGroup = new VGroup(); 8116f6578e81c1df207da47e2e1337382341f271206Chet Haase mPath = new Path(); 8126f6578e81c1df207da47e2e1337382341f271206Chet Haase mRenderPath = new Path(); 813abb7d134c02ac60091108c491dafb00877093170John Hoford } 8149453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 8152af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public void setRootAlpha(int alpha) { 8162af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mRootAlpha = alpha; 8172af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 8182af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 8192af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public int getRootAlpha() { 8202af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return mRootAlpha; 8212af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 8222af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 8238490354dc651dd8f25036ef0dda7917fb33013edztenghui // setAlpha() and getAlpha() are used mostly for animation purpose, since 8248490354dc651dd8f25036ef0dda7917fb33013edztenghui // Animator like to use alpha from 0 to 1. 8258490354dc651dd8f25036ef0dda7917fb33013edztenghui public void setAlpha(float alpha) { 8268490354dc651dd8f25036ef0dda7917fb33013edztenghui setRootAlpha((int) (alpha * 255)); 8278490354dc651dd8f25036ef0dda7917fb33013edztenghui } 8288490354dc651dd8f25036ef0dda7917fb33013edztenghui 8298490354dc651dd8f25036ef0dda7917fb33013edztenghui @SuppressWarnings("unused") 8308490354dc651dd8f25036ef0dda7917fb33013edztenghui public float getAlpha() { 8318490354dc651dd8f25036ef0dda7917fb33013edztenghui return getRootAlpha() / 255.0f; 8328490354dc651dd8f25036ef0dda7917fb33013edztenghui } 8338490354dc651dd8f25036ef0dda7917fb33013edztenghui 834ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer(VPathRenderer copy) { 83555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 8366f6578e81c1df207da47e2e1337382341f271206Chet Haase mPath = new Path(copy.mPath); 8376f6578e81c1df207da47e2e1337382341f271206Chet Haase mRenderPath = new Path(copy.mRenderPath); 838abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseWidth = copy.mBaseWidth; 839abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseHeight = copy.mBaseHeight; 8405eb5cde467081d1af628e5463ba55f110265a86fztenghui mViewportWidth = copy.mViewportWidth; 841abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportHeight = copy.mViewportHeight; 8428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 84355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootAlpha = copy.mRootAlpha; 8448490354dc651dd8f25036ef0dda7917fb33013edztenghui mRootName = copy.mRootName; 8458490354dc651dd8f25036ef0dda7917fb33013edztenghui if (copy.mRootName != null) { 8468490354dc651dd8f25036ef0dda7917fb33013edztenghui mVGTargetsMap.put(copy.mRootName, this); 8478490354dc651dd8f25036ef0dda7917fb33013edztenghui } 848abb7d134c02ac60091108c491dafb00877093170John Hoford } 849abb7d134c02ac60091108c491dafb00877093170John Hoford 8509453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 8514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // If one of the paths can apply theme, then return true; 8524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return recursiveCanApplyTheme(mRootGroup); 8534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private boolean recursiveCanApplyTheme(VGroup currentGroup) { 8564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, if there is one path return true, 8574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // then we return true for the whole tree. 8588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 8598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 8608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 8618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 8628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 8638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 8648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme() 8658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui || recursiveCanApplyTheme(childGroup)) { 8668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 8678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 8698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 8708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 8718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 8728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8759453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return false; 8769453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 8779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 8789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 8794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Apply theme to every path of the tree. 8804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui recursiveApplyTheme(mRootGroup, t); 8814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void recursiveApplyTheme(VGroup currentGroup, Theme t) { 8844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, apply theme to all paths which 8854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // can apply theme. 8868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 8878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 8888d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 8898d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 8908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 8918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme()) { 8928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childGroup.applyTheme(t); 8938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8948d0d24f7a2b1a59060aa18926984491691d3c667ztenghui recursiveApplyTheme(childGroup, t); 8958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 8968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 8978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 8988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childPath.applyTheme(t); 8998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 9004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 9014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 902abb7d134c02ac60091108c491dafb00877093170John Hoford } 903abb7d134c02ac60091108c491dafb00877093170John Hoford 9044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 905b07b086bd42181f62718a6394b56be3917b12511Alan Viverette Canvas canvas, int w, int h, ColorFilter filter) { 9064d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Calculate current group's matrix by preConcat the parent's and 9074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // and the current one on the top of the stack. 9084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 9094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Mi the local matrix at level i of the group tree. 9104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 9114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 9134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Draw the group tree in the same order as the XML file. 9158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 9168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 9178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 9188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 9198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 920b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas, w, h, filter); 9218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 9228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 923b07b086bd42181f62718a6394b56be3917b12511Alan Viverette drawPath(currentGroup, childPath, canvas, w, h, filter); 9248d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 925abb7d134c02ac60091108c491dafb00877093170John Hoford } 9264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 927abb7d134c02ac60091108c491dafb00877093170John Hoford 928b07b086bd42181f62718a6394b56be3917b12511Alan Viverette public void draw(Canvas canvas, int w, int h, ColorFilter filter) { 9294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Travese the tree in pre-order to draw. 930b07b086bd42181f62718a6394b56be3917b12511Alan Viverette drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h, filter); 931abb7d134c02ac60091108c491dafb00877093170John Hoford } 932abb7d134c02ac60091108c491dafb00877093170John Hoford 933b07b086bd42181f62718a6394b56be3917b12511Alan Viverette private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h, 934b07b086bd42181f62718a6394b56be3917b12511Alan Viverette ColorFilter filter) { 9358490354dc651dd8f25036ef0dda7917fb33013edztenghui final float scaleX = w / mViewportWidth; 9369d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleY = h / mViewportHeight; 9379d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float minScale = Math.min(scaleX, scaleY); 938abb7d134c02ac60091108c491dafb00877093170John Hoford 9394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.set(vGroup.mStackedMatrix); 9405a836f74df027bb568da17fbde4e641b6a56d2a9ztenghui mFinalPathMatrix.postScale(scaleX, scaleY); 941abb7d134c02ac60091108c491dafb00877093170John Hoford 9428d0d24f7a2b1a59060aa18926984491691d3c667ztenghui vPath.toPath(mPath); 9438d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Path path = mPath; 944abb7d134c02ac60091108c491dafb00877093170John Hoford 9458d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.reset(); 9469453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 947a95c8abb366d9c39450513335f550b56da13b30aztenghui if (vPath.isClipPath()) { 948a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 9498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.clipPath(mRenderPath, Region.Op.REPLACE); 9508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 951a95c8abb366d9c39450513335f550b56da13b30aztenghui VFullPath fullPath = (VFullPath) vPath; 952a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) { 953a95c8abb366d9c39450513335f550b56da13b30aztenghui float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f; 954a95c8abb366d9c39450513335f550b56da13b30aztenghui float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f; 955a95c8abb366d9c39450513335f550b56da13b30aztenghui 956a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mPathMeasure == null) { 957a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure = new PathMeasure(); 958a95c8abb366d9c39450513335f550b56da13b30aztenghui } 959a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.setPath(mPath, false); 960a95c8abb366d9c39450513335f550b56da13b30aztenghui 961a95c8abb366d9c39450513335f550b56da13b30aztenghui float len = mPathMeasure.getLength(); 962a95c8abb366d9c39450513335f550b56da13b30aztenghui start = start * len; 963a95c8abb366d9c39450513335f550b56da13b30aztenghui end = end * len; 964a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 965a95c8abb366d9c39450513335f550b56da13b30aztenghui if (start > end) { 966a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, len, path, true); 967a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(0f, end, path, true); 968a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 969a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, end, path, true); 970a95c8abb366d9c39450513335f550b56da13b30aztenghui } 971a95c8abb366d9c39450513335f550b56da13b30aztenghui path.rLineTo(0, 0); // fix bug in measure 972a95c8abb366d9c39450513335f550b56da13b30aztenghui } 973a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 974a95c8abb366d9c39450513335f550b56da13b30aztenghui 975a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui if (fullPath.mFillColor != Color.TRANSPARENT) { 9768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mFillPaint == null) { 9778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint = new Paint(); 9788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setStyle(Paint.Style.FILL); 9798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setAntiAlias(true); 98063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 981b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 982b07b086bd42181f62718a6394b56be3917b12511Alan Viverette final Paint fillPaint = mFillPaint; 983b07b086bd42181f62718a6394b56be3917b12511Alan Viverette fillPaint.setColor(applyAlpha(fullPath.mFillColor, fullPath.mFillAlpha)); 984b07b086bd42181f62718a6394b56be3917b12511Alan Viverette fillPaint.setColorFilter(filter); 985b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas.drawPath(mRenderPath, fillPaint); 9868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 98763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 988a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui if (fullPath.mStrokeColor != Color.TRANSPARENT) { 9898d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mStrokePaint == null) { 9908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint = new Paint(); 9918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 9928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setAntiAlias(true); 9938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 9944b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 9958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Paint strokePaint = mStrokePaint; 996a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineJoin != null) { 997a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin); 9988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 999abb7d134c02ac60091108c491dafb00877093170John Hoford 1000a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineCap != null) { 1001a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeCap(fullPath.mStrokeLineCap); 10028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 100363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1004c4d651ec8a8c190c5df173166357c2fdf47472ceztenghui strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit); 1005b07b086bd42181f62718a6394b56be3917b12511Alan Viverette strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, fullPath.mStrokeAlpha)); 1006b07b086bd42181f62718a6394b56be3917b12511Alan Viverette strokePaint.setColorFilter(filter); 1007a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale); 10088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, strokePaint); 100963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 1010abb7d134c02ac60091108c491dafb00877093170John Hoford } 1011abb7d134c02ac60091108c491dafb00877093170John Hoford } 1012abb7d134c02ac60091108c491dafb00877093170John Hoford } 1013abb7d134c02ac60091108c491dafb00877093170John Hoford 1014a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VGroup { 101555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 101655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // the parents' local matrices with the current one. 101755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mStackedMatrix = new Matrix(); 101855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 101955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 102055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 10218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 1022abb7d134c02ac60091108c491dafb00877093170John Hoford 102363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mRotate = 0; 102463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotX = 0; 102563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotY = 0; 1026452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleX = 1; 1027452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleY = 1; 1028452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateX = 0; 1029452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateY = 0; 10304d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 103155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mLocalMatrix is updated based on the update of transformation information, 103255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // either parsed from the XML or by animation. 10334d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private final Matrix mLocalMatrix = new Matrix(); 10348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 103563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private int[] mThemeAttrs; 1036e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private String mGroupName = null; 1037e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 103855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 103955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRotate = copy.mRotate; 104055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotX = copy.mPivotX; 104155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotY = copy.mPivotY; 104255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleX = copy.mScaleX; 104355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleY = copy.mScaleY; 104455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateX = copy.mTranslateX; 104555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateY = copy.mTranslateY; 104655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 104755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupName = copy.mGroupName; 104855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 104955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mGroupName != null) { 105055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui targetsMap.put(mGroupName, this); 105155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 105255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 105355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mLocalMatrix.set(copy.mLocalMatrix); 105455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 10558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = copy.mChildren; 10568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 10578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object copyChild = children.get(i); 10588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (copyChild instanceof VGroup) { 10598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup copyGroup = (VGroup) copyChild; 10608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 1061a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1062a95c8abb366d9c39450513335f550b56da13b30aztenghui VPath newPath = null; 1063a95c8abb366d9c39450513335f550b56da13b30aztenghui if (copyChild instanceof VFullPath) { 1064a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VFullPath((VFullPath) copyChild); 1065a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (copyChild instanceof VClipPath) { 1066a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VClipPath((VClipPath) copyChild); 1067a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1068a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new IllegalStateException("Unknown object in the tree!"); 1069a95c8abb366d9c39450513335f550b56da13b30aztenghui } 10708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(newPath); 10718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (newPath.mPathName != null) { 10728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui targetsMap.put(newPath.mPathName, newPath); 10738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 107455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 107555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 107655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 107755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 107855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup() { 107955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 108055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 1081a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getGroupName() { 1082a95c8abb366d9c39450513335f550b56da13b30aztenghui return mGroupName; 1083a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1084a95c8abb366d9c39450513335f550b56da13b30aztenghui 1085a95c8abb366d9c39450513335f550b56da13b30aztenghui public Matrix getLocalMatrix() { 1086a95c8abb366d9c39450513335f550b56da13b30aztenghui return mLocalMatrix; 1087a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1088a95c8abb366d9c39450513335f550b56da13b30aztenghui 1089a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources res, AttributeSet attrs, Theme theme) { 1090a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(res, theme, attrs, 1091a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableGroup); 1092a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1093a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1094a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1095a95c8abb366d9c39450513335f550b56da13b30aztenghui 1096a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1097a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1098a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1099a95c8abb366d9c39450513335f550b56da13b30aztenghui 1100a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 1101a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 1102a95c8abb366d9c39450513335f550b56da13b30aztenghui 1103a95c8abb366d9c39450513335f550b56da13b30aztenghui mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); 1104a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); 1105a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); 1106a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); 1107a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); 1108a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); 1109a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); 1110a95c8abb366d9c39450513335f550b56da13b30aztenghui 1111a95c8abb366d9c39450513335f550b56da13b30aztenghui final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); 1112a95c8abb366d9c39450513335f550b56da13b30aztenghui if (groupName != null) { 1113a95c8abb366d9c39450513335f550b56da13b30aztenghui mGroupName = groupName; 1114a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1115a95c8abb366d9c39450513335f550b56da13b30aztenghui 1116a95c8abb366d9c39450513335f550b56da13b30aztenghui updateLocalMatrix(); 1117a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1118a95c8abb366d9c39450513335f550b56da13b30aztenghui 1119607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean canApplyTheme() { 1120607bd848269fb802550e63aa61945790616f97a7Alan Viverette return mThemeAttrs != null; 1121607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 1122607bd848269fb802550e63aa61945790616f97a7Alan Viverette 1123a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1124a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1125a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1126a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1127a95c8abb366d9c39450513335f550b56da13b30aztenghui 1128607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawableGroup); 1129a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1130a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1131a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1132a95c8abb366d9c39450513335f550b56da13b30aztenghui 1133a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateLocalMatrix() { 1134a95c8abb366d9c39450513335f550b56da13b30aztenghui // The order we apply is the same as the 1135a95c8abb366d9c39450513335f550b56da13b30aztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 1136a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.reset(); 1137a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 1138a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 1139a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 1140a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 1141a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1142a95c8abb366d9c39450513335f550b56da13b30aztenghui 1143a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1144a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1145e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getRotation() { 1146e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mRotate; 1147e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1148e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1149a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1150e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setRotation(float rotation) { 1151e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (rotation != mRotate) { 1152e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mRotate = rotation; 1153e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1154e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1155e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1156e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1157a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1158e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotX() { 1159e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotX; 1160e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1161e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1162a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1163e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotX(float pivotX) { 1164e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotX != mPivotX) { 1165e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotX = pivotX; 1166e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1167e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1168e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1169e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1170a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1171e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotY() { 1172e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotY; 1173e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1174e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1175a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1176e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotY(float pivotY) { 1177e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotY != mPivotY) { 1178e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotY = pivotY; 1179e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1180e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1181e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1182e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1183a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1184e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleX() { 1185e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleX; 1186e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 11874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1188a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1189e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleX(float scaleX) { 1190e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleX != mScaleX) { 1191e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleX = scaleX; 1192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1193e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1194e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1195e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1196a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1197e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleY() { 1198e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleY; 1199e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1200e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1201a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1202e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleY(float scaleY) { 1203e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleY != mScaleY) { 1204e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleY = scaleY; 1205e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1206e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1207e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1208e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1209a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1210e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateX() { 1211e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateX; 1212e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1213e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1214a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1215e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateX(float translateX) { 1216e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateX != mTranslateX) { 1217e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateX = translateX; 1218e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1219e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1220e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1221e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1222a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1223e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateY() { 1224e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateY; 1225e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1226e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1227a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1228e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateY(float translateY) { 1229e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateY != mTranslateY) { 1230e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateY = translateY; 1231e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1232e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1233e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1234a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1235e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1236a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1237a95c8abb366d9c39450513335f550b56da13b30aztenghui * Common Path information for clip path and normal path. 1238a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1239a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VPath { 1240a95c8abb366d9c39450513335f550b56da13b30aztenghui protected PathParser.PathDataNode[] mNodes = null; 1241a95c8abb366d9c39450513335f550b56da13b30aztenghui String mPathName; 1242a95c8abb366d9c39450513335f550b56da13b30aztenghui int mChangingConfigurations; 1243a95c8abb366d9c39450513335f550b56da13b30aztenghui 1244a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath() { 1245a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 12464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1248a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath(VPath copy) { 1249a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = copy.mPathName; 1250a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations = copy.mChangingConfigurations; 1251a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 12524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1254a95c8abb366d9c39450513335f550b56da13b30aztenghui public void toPath(Path path) { 1255a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 1256a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mNodes != null) { 1257a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 1258a95c8abb366d9c39450513335f550b56da13b30aztenghui } 12594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1261a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getPathName() { 1262a95c8abb366d9c39450513335f550b56da13b30aztenghui return mPathName; 12638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12648e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 1265a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1266a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1267a95c8abb366d9c39450513335f550b56da13b30aztenghui } 126863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1269a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1270a95c8abb366d9c39450513335f550b56da13b30aztenghui } 127163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1272a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1273a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1274a95c8abb366d9c39450513335f550b56da13b30aztenghui } 127563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1276a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1277a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1278a95c8abb366d9c39450513335f550b56da13b30aztenghui public PathParser.PathDataNode[] getPathData() { 1279a95c8abb366d9c39450513335f550b56da13b30aztenghui return mNodes; 1280a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1281a95c8abb366d9c39450513335f550b56da13b30aztenghui 1282a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1283a95c8abb366d9c39450513335f550b56da13b30aztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 1284a95c8abb366d9c39450513335f550b56da13b30aztenghui if (!PathParser.canMorph(mNodes, nodes)) { 1285a95c8abb366d9c39450513335f550b56da13b30aztenghui // This should not happen in the middle of animation. 1286a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(nodes); 1287a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1288a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.updateNodes(mNodes, nodes); 128963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 1290a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1291a95c8abb366d9c39450513335f550b56da13b30aztenghui } 129263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1293a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1294a95c8abb366d9c39450513335f550b56da13b30aztenghui * Clip path, which only has name and pathData. 1295a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 12968490354dc651dd8f25036ef0dda7917fb33013edztenghui private static class VClipPath extends VPath { 1297a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath() { 1298a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 12998e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 13004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1301a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath(VClipPath copy) { 1302a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 1303a95c8abb366d9c39450513335f550b56da13b30aztenghui } 13044d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1305a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1306a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1307a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableClipPath); 13088e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 130963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 131063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 131163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1312a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1313a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1314a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1315a95c8abb366d9c39450513335f550b56da13b30aztenghui 1316a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = a.getString(R.styleable.VectorDrawableClipPath_name); 1317a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 1318a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableClipPath_pathData)); 1319a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1320a95c8abb366d9c39450513335f550b56da13b30aztenghui 1321a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1322a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1323a95c8abb366d9c39450513335f550b56da13b30aztenghui return true; 13244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 1325abb7d134c02ac60091108c491dafb00877093170John Hoford } 1326abb7d134c02ac60091108c491dafb00877093170John Hoford 1327a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1328a95c8abb366d9c39450513335f550b56da13b30aztenghui * Normal path, which contains all the fill / paint information. 1329a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1330a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VFullPath extends VPath { 133155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 133255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 13339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private int[] mThemeAttrs; 13349453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1335a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui int mStrokeColor = Color.TRANSPARENT; 1336abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeWidth = 0; 13372e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 1338a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui int mFillColor = Color.TRANSPARENT; 13392e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float mStrokeAlpha = 1.0f; 1340abb7d134c02ac60091108c491dafb00877093170John Hoford int mFillRule; 13412e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float mFillAlpha = 1.0f; 1342abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathStart = 0; 1343abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathEnd = 1; 1344abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathOffset = 0; 13459453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13464b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 13474b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Join mStrokeLineJoin = Paint.Join.MITER; 1348abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeMiterlimit = 4; 13499453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1350a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath() { 13519453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette // Empty constructor. 13529453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13539453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1354a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath(VFullPath copy) { 1355a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 135655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 135755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 135855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeColor = copy.mStrokeColor; 135955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeWidth = copy.mStrokeWidth; 13602e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = copy.mStrokeAlpha; 136155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillColor = copy.mFillColor; 136255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillRule = copy.mFillRule; 13632e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = copy.mFillAlpha; 136455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathStart = copy.mTrimPathStart; 136555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathEnd = copy.mTrimPathEnd; 136655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathOffset = copy.mTrimPathOffset; 136755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 136855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineCap = copy.mStrokeLineCap; 136955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 137055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 1371abb7d134c02ac60091108c491dafb00877093170John Hoford } 1372abb7d134c02ac60091108c491dafb00877093170John Hoford 13737f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 13747f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 13757f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_BUTT: 13767f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.BUTT; 13777f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_ROUND: 13787f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.ROUND; 13797f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_SQUARE: 13807f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.SQUARE; 13817f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 13827f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 13837f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13847f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13857f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 13867f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 13877f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 13887f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_MITER: 13897f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.MITER; 13907f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_ROUND: 13917f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.ROUND; 13927f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_BEVEL: 13937f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.BEVEL; 13947f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 13957f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 13967f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13977f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 13987f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 1399a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1400a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1401a95c8abb366d9c39450513335f550b56da13b30aztenghui return mThemeAttrs != null; 1402eb034fbca40006c55db143047eb628c4b657730aztenghui } 1403eb034fbca40006c55db143047eb628c4b657730aztenghui 1404a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1405a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1406a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath); 1407a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1408a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1409a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1410a95c8abb366d9c39450513335f550b56da13b30aztenghui 1411a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1412a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1413a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1414a95c8abb366d9c39450513335f550b56da13b30aztenghui 1415a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 1416a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 1417a95c8abb366d9c39450513335f550b56da13b30aztenghui 1418a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = a.getString(R.styleable.VectorDrawablePath_name); 1419a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 1420a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_pathData)); 1421a95c8abb366d9c39450513335f550b56da13b30aztenghui 1422a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor, 1423a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor); 14242e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha, 14252e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha); 1426a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineCap = getStrokeLineCap(a.getInt( 1427a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); 1428a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineJoin = getStrokeLineJoin(a.getInt( 1429a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); 1430a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeMiterlimit = a.getFloat( 1431a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); 1432a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor, 1433a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor); 14342e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha, 14352e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha); 1436a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, 1437a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth); 1438a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, 1439a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd); 1440a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathOffset = a.getFloat( 1441a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); 1442a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathStart = a.getFloat( 1443a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); 1444a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1445a95c8abb366d9c39450513335f550b56da13b30aztenghui 1446a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1447a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1448a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1449a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1450a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1451a95c8abb366d9c39450513335f550b56da13b30aztenghui 1452607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 1453a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1454a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1455a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1456a95c8abb366d9c39450513335f550b56da13b30aztenghui 1457a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1458eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1459e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getStroke() { 1460e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeColor; 1461e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1462e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1463eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1464e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStroke(int strokeColor) { 1465e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeColor = strokeColor; 1466e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1467e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1468eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1469e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeWidth() { 1470e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeWidth; 1471e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1472e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1473eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1474e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeWidth(float strokeWidth) { 1475e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeWidth = strokeWidth; 1476e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1477e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1478eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 14792e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float getstrokeAlpha() { 14802e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui return mStrokeAlpha; 14812e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 14822e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 14832e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 14842e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui void setstrokeAlpha(float strokeAlpha) { 14852e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = strokeAlpha; 14862e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 14872e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 14882e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1489e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getFill() { 1490e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillColor; 1491e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1492e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1493eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1494e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFill(int fillColor) { 1495e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillColor = fillColor; 1496e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1497e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1498eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 14992e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float getfillAlpha() { 15002e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui return mFillAlpha; 15012e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 15022e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 15032e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 15042e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui void setfillAlpha(float fillAlpha) { 15052e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = fillAlpha; 15062e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 15072e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 15082e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1509e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathStart() { 1510e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathStart; 1511e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1512e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1513eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1514e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathStart(float trimPathStart) { 1515e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathStart = trimPathStart; 1516e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1517e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1518eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1519e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathEnd() { 1520e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathEnd; 1521e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1522e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1523eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1524e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathEnd(float trimPathEnd) { 1525e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathEnd = trimPathEnd; 1526e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1527e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1528eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1529e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathOffset() { 1530e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathOffset; 1531e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1532e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1533eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1534e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathOffset(float trimPathOffset) { 1535e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathOffset = trimPathOffset; 1536e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1537abb7d134c02ac60091108c491dafb00877093170John Hoford } 1538abb7d134c02ac60091108c491dafb00877093170John Hoford} 1539