VectorDrawable.java revision 34c623cbf3677820c4170f24c5211f663dda91f7
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 1717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viveretteimport android.annotation.NonNull; 18b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList; 19abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources; 20abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources.Theme; 214b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viveretteimport android.content.res.TypedArray; 22482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghuiimport android.graphics.Bitmap; 23abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Canvas; 242af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghuiimport android.graphics.Color; 25abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.ColorFilter; 26abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Matrix; 27abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Paint; 28abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Path; 29abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PathMeasure; 30abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PixelFormat; 31b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuffColorFilter; 32abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Rect; 33abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Region; 34b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode; 35e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.ArrayMap; 36abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.AttributeSet; 37738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghuiimport android.util.LayoutDirection; 38abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.Log; 39cf4832f69c8786b098ce18c24319021f8cd6733aztenghuiimport android.util.PathParser; 404b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport android.util.Xml; 41abb7d134c02ac60091108c491dafb00877093170John Hoford 42abb7d134c02ac60091108c491dafb00877093170John Hofordimport com.android.internal.R; 43abb7d134c02ac60091108c491dafb00877093170John Hoford 44abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParser; 45abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParserException; 46abb7d134c02ac60091108c491dafb00877093170John Hoford 47abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException; 48abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList; 494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack; 504b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 51abb7d134c02ac60091108c491dafb00877093170John Hoford/** 526beeb75723cec42603b47664bce794a2b97d7bacChet Haase * This lets you create a drawable based on an XML vector graphic. It can be 53d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code><vector></code> element. 54abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 5546e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * The vector drawable has the following elements: 56abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 57177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code><vector></code></dt> 58a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 59a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined a vector drawable 60a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 61c3fdffa98136bdad1fee9c77598d541d792920e1ztenghui * <dt><code>android:name</code></dt> 62c3fdffa98136bdad1fee9c77598d541d792920e1ztenghui * <dd>Defines the name of this vector drawable.</dd> 63a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:width</code></dt> 64a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic width of the drawable. 65a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 66a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:height</code></dt> 67a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic height the drawable. 68a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 69a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportWidth</code></dt> 70a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the width of the viewport space. Viewport is basically 71a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 72a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportHeight</code></dt> 73a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the height of the viewport space. Viewport is basically 74a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 75a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tint</code></dt> 76a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd> 77a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tintMode</code></dt> 78a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd> 79a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:autoMirrored</code></dt> 80a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Indicates if the drawable needs to be mirrored when its layout direction is 81a95c8abb366d9c39450513335f550b56da13b30aztenghui * RTL (right-to-left).</dd> 82c3fdffa98136bdad1fee9c77598d541d792920e1ztenghui * <dt><code>android:alpha</code></dt> 83c3fdffa98136bdad1fee9c77598d541d792920e1ztenghui * <dd>The opacity of this drawable.</dd> 84a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 85a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 86a95c8abb366d9c39450513335f550b56da13b30aztenghui * 87a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 886d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code><group></code></dt> 89452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information. 90452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport. 91a95c8abb366d9c39450513335f550b56da13b30aztenghui * And the transformations are applied in the order of scale, rotate then translate. 92a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 93c3fdffa98136bdad1fee9c77598d541d792920e1ztenghui * <dt><code>android:name</code></dt> 94c3fdffa98136bdad1fee9c77598d541d792920e1ztenghui * <dd>Defines the name of the group.</dd> 95a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:rotation</code></dt> 96a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The degrees of rotation of the group.</dd> 97a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotX</code></dt> 98a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group. 99a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 100a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotY</code></dt> 101a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group. 102a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 103a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleX</code></dt> 104a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the X Coordinate.</dd> 105a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleY</code></dt> 106a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the Y coordinate.</dd> 107a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateX</code></dt> 108a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the X coordinate. 109a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 110a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateY</code></dt> 111a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the Y coordinate. 112a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 113a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 114a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 115a95c8abb366d9c39450513335f550b56da13b30aztenghui * 116a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 117abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><path></code></dt> 1186d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn. 119abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 120a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 121a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the path.</dd> 122a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 12346e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute 124a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data. This is defined in the viewport space.</dd> 125a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:fillColor</code></dt> 126a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui * <dd>Defines the color to fill the path (none if not present).</dd> 127a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeColor</code></dt> 128d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd> 129a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeWidth</code></dt> 130a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The width a path stroke.</dd> 1312e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:strokeAlpha</code></dt> 1322e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity of a path stroke.</dd> 1332e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dt><code>android:fillAlpha</code></dt> 1342e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui * <dd>The opacity to fill the path with.</dd> 135a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathStart</code></dt> 136a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd> 137a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathEnd</code></dt> 138a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd> 139a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathOffset</code></dt> 140a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Shift trim region (allows showed region to include the start and end), in the range 141a95c8abb366d9c39450513335f550b56da13b30aztenghui * from 0 to 1.</dd> 142a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineCap</code></dt> 143a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the linecap for a stroked path: butt, round, square.</dd> 144a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineJoin</code></dt> 145a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd> 146a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeMiterLimit</code></dt> 147a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the Miter limit for a stroked path.</dd> 148a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 149a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 150a95c8abb366d9c39450513335f550b56da13b30aztenghui * 151a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 152a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code><clip-path></code></dt> 1536fbcefe4d7248912cd797de376eb25c5ace1544dztenghui * <dd>Defines path to be the current clip. Note that the clip path only apply to 1546fbcefe4d7248912cd797de376eb25c5ace1544dztenghui * the current group and its children. 155a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 156a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 157a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the clip path.</dd> 158a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 159a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines clip path string. This is using exactly same format as "d" attribute 160a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data.</dd> 161a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 162abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl> 163a95c8abb366d9c39450513335f550b56da13b30aztenghui * <li>Here is a simple VectorDrawable in this vectordrawable.xml file. 164a95c8abb366d9c39450513335f550b56da13b30aztenghui * <pre> 165a95c8abb366d9c39450513335f550b56da13b30aztenghui * <vector xmlns:android="http://schemas.android.com/apk/res/android" 166a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:height="64dp" 167a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:width="64dp" 168a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportHeight="600" 169a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportWidth="600" > 170a95c8abb366d9c39450513335f550b56da13b30aztenghui * <group 171a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="rotationGroup" 172a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotX="300.0" 173a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotY="300.0" 174a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:rotation="45.0" > 175a95c8abb366d9c39450513335f550b56da13b30aztenghui * <path 176a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="v" 177a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:fillColor="#000000" 178a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 179a95c8abb366d9c39450513335f550b56da13b30aztenghui * </group> 180a95c8abb366d9c39450513335f550b56da13b30aztenghui * </vector> 181a95c8abb366d9c39450513335f550b56da13b30aztenghui * </pre></li> 182abb7d134c02ac60091108c491dafb00877093170John Hoford */ 183a95c8abb366d9c39450513335f550b56da13b30aztenghui 184abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable { 1859453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private static final String LOGTAG = VectorDrawable.class.getSimpleName(); 1869453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 187a95c8abb366d9c39450513335f550b56da13b30aztenghui private static final String SHAPE_CLIP_PATH = "clip-path"; 1886d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui private static final String SHAPE_GROUP = "group"; 189abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_PATH = "path"; 190abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VECTOR = "vector"; 191abb7d134c02ac60091108c491dafb00877093170John Hoford 192abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_BUTT = 0; 193abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_ROUND = 1; 194abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_SQUARE = 2; 1959453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 196abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_MITER = 0; 197abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_ROUND = 1; 198abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_BEVEL = 2; 1999453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 2004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final boolean DBG_VECTOR_DRAWABLE = false; 2014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 20255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private VectorDrawableState mVectorState; 203e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 204b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette private PorterDuffColorFilter mTintFilter; 205b07b086bd42181f62718a6394b56be3917b12511Alan Viverette private ColorFilter mColorFilter; 206b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 20755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private boolean mMutated; 20855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 209482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise, 210482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // caching the bitmap by default is allowed. 211482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui private boolean mAllowCaching = true; 212482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 213abb7d134c02ac60091108c491dafb00877093170John Hoford public VectorDrawable() { 21455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(); 215abb7d134c02ac60091108c491dafb00877093170John Hoford } 216abb7d134c02ac60091108c491dafb00877093170John Hoford 21717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette private VectorDrawable(@NonNull VectorDrawableState state) { 21817cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette mVectorState = state; 219b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 220abb7d134c02ac60091108c491dafb00877093170John Hoford } 221abb7d134c02ac60091108c491dafb00877093170John Hoford 22255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 22355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public Drawable mutate() { 22455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!mMutated && super.mutate() == this) { 22555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(mVectorState); 22655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mMutated = true; 22755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 22855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return this; 22955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 23055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 231727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 232727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 233727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 234727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 235727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 236727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 237727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 238727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 239e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Object getTargetByName(String name) { 24055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); 241e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 242e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 243abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 244abb7d134c02ac60091108c491dafb00877093170John Hoford public ConstantState getConstantState() { 24555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState.mChangingConfigurations = getChangingConfigurations(); 24655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState; 247abb7d134c02ac60091108c491dafb00877093170John Hoford } 248abb7d134c02ac60091108c491dafb00877093170John Hoford 2494554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette @Override 250abb7d134c02ac60091108c491dafb00877093170John Hoford public void draw(Canvas canvas) { 2514b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final Rect bounds = getBounds(); 25234c623cbf3677820c4170f24c5211f663dda91f7ztenghui if (bounds.width() <= 0 || bounds.height() <= 0) { 25334c623cbf3677820c4170f24c5211f663dda91f7ztenghui // Nothing to draw 2541968201b44567262e7b2e382eee3d88990748d89Dan Sandler return; 2551968201b44567262e7b2e382eee3d88990748d89Dan Sandler } 2561968201b44567262e7b2e382eee3d88990748d89Dan Sandler 2570670f029a4e59448aa53b46a98e60dff6404f360ztenghui final int saveCount = canvas.save(); 258738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui final boolean needMirroring = needMirroring(); 259738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2604b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.translate(bounds.left, bounds.top); 261738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (needMirroring) { 262738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.translate(bounds.width(), 0); 263738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.scale(-1.0f, 1.0f); 264738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 265482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 266b07b086bd42181f62718a6394b56be3917b12511Alan Viverette // Color filters always override tint filters. 267b07b086bd42181f62718a6394b56be3917b12511Alan Viverette final ColorFilter colorFilter = mColorFilter == null ? mTintFilter : mColorFilter; 268b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 269482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (!mAllowCaching) { 2708490354dc651dd8f25036ef0dda7917fb33013edztenghui // AnimatedVectorDrawable 2718490354dc651dd8f25036ef0dda7917fb33013edztenghui if (!mVectorState.hasTranslucentRoot()) { 272b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVectorState.mVPathRenderer.draw( 273b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas, bounds.width(), bounds.height(), colorFilter); 2748490354dc651dd8f25036ef0dda7917fb33013edztenghui } else { 2758490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.createCachedBitmapIfNeeded(bounds); 2768490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.updateCachedBitmap(bounds); 277b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter); 2788490354dc651dd8f25036ef0dda7917fb33013edztenghui } 279482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } else { 2808490354dc651dd8f25036ef0dda7917fb33013edztenghui // Static Vector Drawable case. 2818490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.createCachedBitmapIfNeeded(bounds); 2828490354dc651dd8f25036ef0dda7917fb33013edztenghui if (!mVectorState.canReuseCache()) { 2838490354dc651dd8f25036ef0dda7917fb33013edztenghui mVectorState.updateCachedBitmap(bounds); 284482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.updateCacheStates(); 285482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 286b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter); 287482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 288738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2894b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.restoreToCount(saveCount); 290abb7d134c02ac60091108c491dafb00877093170John Hoford } 291abb7d134c02ac60091108c491dafb00877093170John Hoford 292abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 293e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getAlpha() { 294e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mVectorState.mVPathRenderer.getRootAlpha(); 295e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 296e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 297e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 298abb7d134c02ac60091108c491dafb00877093170John Hoford public void setAlpha(int alpha) { 2992af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) { 3002af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mVectorState.mVPathRenderer.setRootAlpha(alpha); 301abb7d134c02ac60091108c491dafb00877093170John Hoford invalidateSelf(); 302abb7d134c02ac60091108c491dafb00877093170John Hoford } 303abb7d134c02ac60091108c491dafb00877093170John Hoford } 304abb7d134c02ac60091108c491dafb00877093170John Hoford 305abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 306abb7d134c02ac60091108c491dafb00877093170John Hoford public void setColorFilter(ColorFilter colorFilter) { 307b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mColorFilter = colorFilter; 308fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette invalidateSelf(); 309abb7d134c02ac60091108c491dafb00877093170John Hoford } 310abb7d134c02ac60091108c491dafb00877093170John Hoford 311abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 312a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintList(ColorStateList tint) { 313b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 314a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTint != tint) { 315b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTint = tint; 316a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode); 317a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette invalidateSelf(); 318a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 319a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 320b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 321a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette @Override 322a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintMode(Mode tintMode) { 323a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette final VectorDrawableState state = mVectorState; 324a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTintMode != tintMode) { 325a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette state.mTintMode = tintMode; 326a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode); 327b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette invalidateSelf(); 328b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 329b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 330b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 331b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 332607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean isStateful() { 333607bd848269fb802550e63aa61945790616f97a7Alan Viverette return super.isStateful() || (mVectorState != null && mVectorState.mTint != null 334607bd848269fb802550e63aa61945790616f97a7Alan Viverette && mVectorState.mTint.isStateful()); 335607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 336607bd848269fb802550e63aa61945790616f97a7Alan Viverette 337607bd848269fb802550e63aa61945790616f97a7Alan Viverette @Override 338b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette protected boolean onStateChange(int[] stateSet) { 339b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 340b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != null && state.mTintMode != null) { 341b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 342607bd848269fb802550e63aa61945790616f97a7Alan Viverette invalidateSelf(); 343b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return true; 344b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 345b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return false; 346b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 347b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 348b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 349abb7d134c02ac60091108c491dafb00877093170John Hoford public int getOpacity() { 350abb7d134c02ac60091108c491dafb00877093170John Hoford return PixelFormat.TRANSLUCENT; 351abb7d134c02ac60091108c491dafb00877093170John Hoford } 352abb7d134c02ac60091108c491dafb00877093170John Hoford 353abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 354abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicWidth() { 355ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseWidth; 356abb7d134c02ac60091108c491dafb00877093170John Hoford } 357abb7d134c02ac60091108c491dafb00877093170John Hoford 358abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 359abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicHeight() { 360ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseHeight; 361abb7d134c02ac60091108c491dafb00877093170John Hoford } 362abb7d134c02ac60091108c491dafb00877093170John Hoford 363abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 3649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 365d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette return (mVectorState != null && mVectorState.canApplyTheme()) || super.canApplyTheme(); 3669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3679453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3689453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette @Override 3699453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 3709453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette super.applyTheme(t); 3719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3729453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VectorDrawableState state = mVectorState; 37345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state == null) { 37445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return; 37545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 37645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 37745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state.mThemeAttrs != null) { 37845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final TypedArray a = t.resolveAttributes( 37945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette state.mThemeAttrs, R.styleable.VectorDrawable); 380607bd848269fb802550e63aa61945790616f97a7Alan Viverette try { 381607bd848269fb802550e63aa61945790616f97a7Alan Viverette state.mCacheDirty = true; 382607bd848269fb802550e63aa61945790616f97a7Alan Viverette updateStateFromTypedArray(a); 383607bd848269fb802550e63aa61945790616f97a7Alan Viverette } catch (XmlPullParserException e) { 384607bd848269fb802550e63aa61945790616f97a7Alan Viverette throw new RuntimeException(e); 385607bd848269fb802550e63aa61945790616f97a7Alan Viverette } finally { 386607bd848269fb802550e63aa61945790616f97a7Alan Viverette a.recycle(); 387607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 38845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 389607bd848269fb802550e63aa61945790616f97a7Alan Viverette 39045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Apply theme to contained color state list. 39145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state.mTint != null && state.mTint.canApplyTheme()) { 39245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette state.mTint.applyTheme(t); 393607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 394607bd848269fb802550e63aa61945790616f97a7Alan Viverette 395ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer path = state.mVPathRenderer; 3969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (path != null && path.canApplyTheme()) { 3979453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.applyTheme(t); 3989453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 39945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 40045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Update local state. 40145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 4029453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 4039453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 404fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount /** 405fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension. 406fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * This is used to calculate the path animation accuracy. 407fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * 408fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount * @hide 409fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount */ 410fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount public float getPixelSize() { 411f2b1cff4e2b152a7c776a7a79e8225a591f97d3eAndreas Gampe if (mVectorState == null || mVectorState.mVPathRenderer == null || 412fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mBaseWidth == 0 || 413fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mBaseHeight == 0 || 414fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mViewportHeight == 0 || 415fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount mVectorState.mVPathRenderer.mViewportWidth == 0) { 416fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount return 1; // fall back to 1:1 pixel mapping. 417fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount } 418fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth; 419fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight; 420fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth; 421fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight; 422fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float scaleX = viewportWidth / intrinsicWidth; 423fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount float scaleY = viewportHeight / intrinsicHeight; 424fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount return Math.min(scaleX, scaleY); 425fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount } 426fd3c4744f265c5277e6e2641a18d5ec3dff19f6bGeorge Mount 4274b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette /** @hide */ 4284b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette public static VectorDrawable create(Resources resources, int rid) { 4294b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette try { 430874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final XmlPullParser parser = resources.getXml(rid); 431874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final AttributeSet attrs = Xml.asAttributeSet(parser); 432874bcd82c223ce58c9d76edcf619b3988c672307ztenghui int type; 433874bcd82c223ce58c9d76edcf619b3988c672307ztenghui while ((type=parser.next()) != XmlPullParser.START_TAG && 434874bcd82c223ce58c9d76edcf619b3988c672307ztenghui type != XmlPullParser.END_DOCUMENT) { 435874bcd82c223ce58c9d76edcf619b3988c672307ztenghui // Empty loop 436874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 437874bcd82c223ce58c9d76edcf619b3988c672307ztenghui if (type != XmlPullParser.START_TAG) { 438874bcd82c223ce58c9d76edcf619b3988c672307ztenghui throw new XmlPullParserException("No start tag found"); 439874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 4404b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4414b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final VectorDrawable drawable = new VectorDrawable(); 442874bcd82c223ce58c9d76edcf619b3988c672307ztenghui drawable.inflate(resources, parser, attrs); 4434b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4444b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return drawable; 4454b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (XmlPullParserException e) { 4464b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 4474b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (IOException e) { 4484b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 4494b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 4504b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return null; 4514b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 4524b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 4532af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private static int applyAlpha(int color, float alpha) { 4542af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int alphaBytes = Color.alpha(color); 4552af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color &= 0x00FFFFFF; 4562af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color |= ((int) (alphaBytes * alpha)) << 24; 4572af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return color; 4582af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 4592af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 4609cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette @Override 4619cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 4629cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette throws XmlPullParserException, IOException { 463a95c8abb366d9c39450513335f550b56da13b30aztenghui final VectorDrawableState state = mVectorState; 464a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 465a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mVPathRenderer = pathRenderer; 466a95c8abb366d9c39450513335f550b56da13b30aztenghui 467607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable); 4689cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette updateStateFromTypedArray(a); 4699cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette a.recycle(); 4709cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 471a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mCacheDirty = true; 47255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui inflateInternal(res, parser, attrs, theme); 4739cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4749cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 4759cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4769cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 477a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException { 4789cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 479a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 4809cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4818e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 4828e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 4838e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 4849cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette // Extract the theme attributes, if any. 4859cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 4869cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4879cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1); 4889cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tintMode != -1) { 4899cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN); 4909cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4919cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4929cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint); 4939cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tint != null) { 4949cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTint = tint; 4959cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 496738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 497738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui state.mAutoMirrored = a.getBoolean( 498738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored); 499a95c8abb366d9c39450513335f550b56da13b30aztenghui 500a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportWidth = a.getFloat( 501a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportWidth, pathRenderer.mViewportWidth); 502a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportHeight = a.getFloat( 503a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportHeight, pathRenderer.mViewportHeight); 504a95c8abb366d9c39450513335f550b56da13b30aztenghui 505a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mViewportWidth <= 0) { 506a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5071c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportWidth > 0"); 508a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mViewportHeight <= 0) { 509a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5101c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportHeight > 0"); 511a95c8abb366d9c39450513335f550b56da13b30aztenghui } 512a95c8abb366d9c39450513335f550b56da13b30aztenghui 513a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseWidth = a.getDimension( 514a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_width, pathRenderer.mBaseWidth); 515a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseHeight = a.getDimension( 516a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_height, pathRenderer.mBaseHeight); 517a95c8abb366d9c39450513335f550b56da13b30aztenghui 518a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mBaseWidth <= 0) { 519a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5201c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires width > 0"); 521a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mBaseHeight <= 0) { 522a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 5231c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires height > 0"); 524a95c8abb366d9c39450513335f550b56da13b30aztenghui } 5258490354dc651dd8f25036ef0dda7917fb33013edztenghui 5268490354dc651dd8f25036ef0dda7917fb33013edztenghui final float alphaInFloat = a.getFloat(R.styleable.VectorDrawable_alpha, 5278490354dc651dd8f25036ef0dda7917fb33013edztenghui pathRenderer.getAlpha()); 5288490354dc651dd8f25036ef0dda7917fb33013edztenghui pathRenderer.setAlpha(alphaInFloat); 5298490354dc651dd8f25036ef0dda7917fb33013edztenghui 5305004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette final String name = a.getString(R.styleable.VectorDrawable_name); 5315004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette if (name != null) { 5325004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette pathRenderer.mRootName = name; 5335004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette pathRenderer.mVGTargetsMap.put(name, pathRenderer); 5348490354dc651dd8f25036ef0dda7917fb33013edztenghui } 5359cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 5369cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 53755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 5388e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette Theme theme) throws XmlPullParserException, IOException { 5398e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final VectorDrawableState state = mVectorState; 540a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 541abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noPathTag = true; 5429453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Use a stack to help to build the group tree. 5444d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The top of the stack is always the current group. 5454d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 5464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(pathRenderer.mRootGroup); 547abb7d134c02ac60091108c491dafb00877093170John Hoford 548abb7d134c02ac60091108c491dafb00877093170John Hoford int eventType = parser.getEventType(); 549abb7d134c02ac60091108c491dafb00877093170John Hoford while (eventType != XmlPullParser.END_DOCUMENT) { 550abb7d134c02ac60091108c491dafb00877093170John Hoford if (eventType == XmlPullParser.START_TAG) { 5519453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final String tagName = parser.getName(); 5524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final VGroup currentGroup = groupStack.peek(); 5534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 554abb7d134c02ac60091108c491dafb00877093170John Hoford if (SHAPE_PATH.equals(tagName)) { 555a95c8abb366d9c39450513335f550b56da13b30aztenghui final VFullPath path = new VFullPath(); 5569453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.inflate(res, attrs, theme); 5578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(path); 558e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (path.getPathName() != null) { 55955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 560e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 561abb7d134c02ac60091108c491dafb00877093170John Hoford noPathTag = false; 5628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= path.mChangingConfigurations; 563a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (SHAPE_CLIP_PATH.equals(tagName)) { 564a95c8abb366d9c39450513335f550b56da13b30aztenghui final VClipPath path = new VClipPath(); 565a95c8abb366d9c39450513335f550b56da13b30aztenghui path.inflate(res, attrs, theme); 566a95c8abb366d9c39450513335f550b56da13b30aztenghui currentGroup.mChildren.add(path); 567a95c8abb366d9c39450513335f550b56da13b30aztenghui if (path.getPathName() != null) { 568a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 569a95c8abb366d9c39450513335f550b56da13b30aztenghui } 570a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mChangingConfigurations |= path.mChangingConfigurations; 5716d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 5724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui VGroup newChildGroup = new VGroup(); 5734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui newChildGroup.inflate(res, attrs, theme); 5748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(newChildGroup); 5754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(newChildGroup); 576e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (newChildGroup.getGroupName() != null) { 57755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 57855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui newChildGroup); 579e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 5808e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 581abb7d134c02ac60091108c491dafb00877093170John Hoford } 5824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } else if (eventType == XmlPullParser.END_TAG) { 5834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final String tagName = parser.getName(); 5844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (SHAPE_GROUP.equals(tagName)) { 5854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.pop(); 5864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 587abb7d134c02ac60091108c491dafb00877093170John Hoford } 588abb7d134c02ac60091108c491dafb00877093170John Hoford eventType = parser.next(); 589abb7d134c02ac60091108c491dafb00877093170John Hoford } 5909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the tree out for debug. 5924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (DBG_VECTOR_DRAWABLE) { 5934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 5946d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } 5956d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 596a95c8abb366d9c39450513335f550b56da13b30aztenghui if (noPathTag) { 5979453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final StringBuffer tag = new StringBuffer(); 5989453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 599a95c8abb366d9c39450513335f550b56da13b30aztenghui if (tag.length() > 0) { 600a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(" or "); 601abb7d134c02ac60091108c491dafb00877093170John Hoford } 602a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(SHAPE_PATH); 6039453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 6049453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette throw new XmlPullParserException("no " + tag + " defined"); 605abb7d134c02ac60091108c491dafb00877093170John Hoford } 606abb7d134c02ac60091108c491dafb00877093170John Hoford } 607abb7d134c02ac60091108c491dafb00877093170John Hoford 6084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void printGroupTree(VGroup currentGroup, int level) { 6094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui String indent = ""; 6108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < level; i++) { 6114d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui indent += " "; 6124d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6134d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the current node 6148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 6154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui + " rotation is " + currentGroup.mRotate); 6168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 6178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Then print all the children groups 6188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 6198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 6208d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui printGroupTree((VGroup) child, level + 1); 6228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 62655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 62755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public int getChangingConfigurations() { 62855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return super.getChangingConfigurations() | mVectorState.mChangingConfigurations; 62955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 63055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 631482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui void setAllowCaching(boolean allowCaching) { 632482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mAllowCaching = allowCaching; 633482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 634482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 635738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui private boolean needMirroring() { 636738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 637738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 638738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 639738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 640738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public void setAutoMirrored(boolean mirrored) { 641738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (mVectorState.mAutoMirrored != mirrored) { 642738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mVectorState.mAutoMirrored = mirrored; 643738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui invalidateSelf(); 644738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 645738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 646738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 647738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 648738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public boolean isAutoMirrored() { 649738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return mVectorState.mAutoMirrored; 650738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 651738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 6525c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette private static class VectorDrawableState extends ConstantState { 6539cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette int[] mThemeAttrs; 6545c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette int mChangingConfigurations; 655ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui VPathRenderer mVPathRenderer; 656607bd848269fb802550e63aa61945790616f97a7Alan Viverette ColorStateList mTint = null; 657607bd848269fb802550e63aa61945790616f97a7Alan Viverette Mode mTintMode = DEFAULT_TINT_MODE; 658738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui boolean mAutoMirrored; 6595c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 660482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap mCachedBitmap; 661482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int[] mCachedThemeAttrs; 662482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui ColorStateList mCachedTint; 663482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Mode mCachedTintMode; 664482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int mCachedRootAlpha; 665670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCachedAutoMirrored; 666670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCacheDirty; 667482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 668b07b086bd42181f62718a6394b56be3917b12511Alan Viverette /** Temporary paint object used to draw cached bitmaps. */ 669b07b086bd42181f62718a6394b56be3917b12511Alan Viverette Paint mTempPaint; 670b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 67155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Deep copy for mutate() or implicitly mutate. 6725c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public VectorDrawableState(VectorDrawableState copy) { 6735c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette if (copy != null) { 6749cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mThemeAttrs = copy.mThemeAttrs; 6755c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 676ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 6776f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVPathRenderer.mFillPaint != null) { 6786f6578e81c1df207da47e2e1337382341f271206Chet Haase mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint); 6796f6578e81c1df207da47e2e1337382341f271206Chet Haase } 6806f6578e81c1df207da47e2e1337382341f271206Chet Haase if (copy.mVPathRenderer.mStrokePaint != null) { 6816f6578e81c1df207da47e2e1337382341f271206Chet Haase mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint); 6826f6578e81c1df207da47e2e1337382341f271206Chet Haase } 683b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = copy.mTint; 684b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = copy.mTintMode; 685738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mAutoMirrored = copy.mAutoMirrored; 6865c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6875c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6885c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 689b07b086bd42181f62718a6394b56be3917b12511Alan Viverette public void drawCachedBitmapWithRootAlpha(Canvas canvas, ColorFilter filter) { 6908490354dc651dd8f25036ef0dda7917fb33013edztenghui // The bitmap's size is the same as the bounds. 691b07b086bd42181f62718a6394b56be3917b12511Alan Viverette final Paint p = getPaint(filter); 692b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas.drawBitmap(mCachedBitmap, 0, 0, p); 6938490354dc651dd8f25036ef0dda7917fb33013edztenghui } 6948490354dc651dd8f25036ef0dda7917fb33013edztenghui 6958490354dc651dd8f25036ef0dda7917fb33013edztenghui public boolean hasTranslucentRoot() { 6968490354dc651dd8f25036ef0dda7917fb33013edztenghui return mVPathRenderer.getRootAlpha() < 255; 6978490354dc651dd8f25036ef0dda7917fb33013edztenghui } 6988490354dc651dd8f25036ef0dda7917fb33013edztenghui 6998490354dc651dd8f25036ef0dda7917fb33013edztenghui /** 7008490354dc651dd8f25036ef0dda7917fb33013edztenghui * @return null when there is no need for alpha paint. 7018490354dc651dd8f25036ef0dda7917fb33013edztenghui */ 702b07b086bd42181f62718a6394b56be3917b12511Alan Viverette public Paint getPaint(ColorFilter filter) { 703b07b086bd42181f62718a6394b56be3917b12511Alan Viverette if (!hasTranslucentRoot() && filter == null) { 704b07b086bd42181f62718a6394b56be3917b12511Alan Viverette return null; 7058490354dc651dd8f25036ef0dda7917fb33013edztenghui } 706b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 707b07b086bd42181f62718a6394b56be3917b12511Alan Viverette if (mTempPaint == null) { 708b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mTempPaint = new Paint(); 709eec6164e6f6178343219bdedcb1e26779fae7f89ztenghui mTempPaint.setFilterBitmap(true); 710b07b086bd42181f62718a6394b56be3917b12511Alan Viverette } 711b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mTempPaint.setAlpha(mVPathRenderer.getRootAlpha()); 712b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mTempPaint.setColorFilter(filter); 713b07b086bd42181f62718a6394b56be3917b12511Alan Viverette return mTempPaint; 7148490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7158490354dc651dd8f25036ef0dda7917fb33013edztenghui 7168490354dc651dd8f25036ef0dda7917fb33013edztenghui public void updateCachedBitmap(Rect bounds) { 7178490354dc651dd8f25036ef0dda7917fb33013edztenghui mCachedBitmap.eraseColor(Color.TRANSPARENT); 7188490354dc651dd8f25036ef0dda7917fb33013edztenghui Canvas tmpCanvas = new Canvas(mCachedBitmap); 719b07b086bd42181f62718a6394b56be3917b12511Alan Viverette mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height(), null); 7208490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7218490354dc651dd8f25036ef0dda7917fb33013edztenghui 7228490354dc651dd8f25036ef0dda7917fb33013edztenghui public void createCachedBitmapIfNeeded(Rect bounds) { 7238490354dc651dd8f25036ef0dda7917fb33013edztenghui if (mCachedBitmap == null || !canReuseBitmap(bounds.width(), 7248490354dc651dd8f25036ef0dda7917fb33013edztenghui bounds.height())) { 7258490354dc651dd8f25036ef0dda7917fb33013edztenghui mCachedBitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), 7268490354dc651dd8f25036ef0dda7917fb33013edztenghui Bitmap.Config.ARGB_8888); 7279c13ed366f205d94b2f3f4ddc96b55b1b9faadbaztenghui mCacheDirty = true; 7288490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7298490354dc651dd8f25036ef0dda7917fb33013edztenghui 7308490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7318490354dc651dd8f25036ef0dda7917fb33013edztenghui 7328490354dc651dd8f25036ef0dda7917fb33013edztenghui public boolean canReuseBitmap(int width, int height) { 7338490354dc651dd8f25036ef0dda7917fb33013edztenghui if (width == mCachedBitmap.getWidth() 7348490354dc651dd8f25036ef0dda7917fb33013edztenghui && height == mCachedBitmap.getHeight()) { 7358490354dc651dd8f25036ef0dda7917fb33013edztenghui return true; 7368490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7378490354dc651dd8f25036ef0dda7917fb33013edztenghui return false; 7388490354dc651dd8f25036ef0dda7917fb33013edztenghui } 7398490354dc651dd8f25036ef0dda7917fb33013edztenghui 7408490354dc651dd8f25036ef0dda7917fb33013edztenghui public boolean canReuseCache() { 741670689af43358568bf2b5916284f1cac5762f428ztenghui if (!mCacheDirty 742670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedThemeAttrs == mThemeAttrs 743482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTint == mTint 744482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTintMode == mTintMode 745670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedAutoMirrored == mAutoMirrored 7468490354dc651dd8f25036ef0dda7917fb33013edztenghui && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { 747482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return true; 748482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 749482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return false; 750482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 751482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 752482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public void updateCacheStates() { 753482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // Use shallow copy here and shallow comparison in canReuseCache(), 754482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // likely hit cache miss more, but practically not much difference. 755482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedThemeAttrs = mThemeAttrs; 756482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTint = mTint; 757482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTintMode = mTintMode; 758482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedRootAlpha = mVPathRenderer.getRootAlpha(); 759670689af43358568bf2b5916284f1cac5762f428ztenghui mCachedAutoMirrored = mAutoMirrored; 760670689af43358568bf2b5916284f1cac5762f428ztenghui mCacheDirty = false; 761482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 762482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 763607bd848269fb802550e63aa61945790616f97a7Alan Viverette @Override 764607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean canApplyTheme() { 76545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mThemeAttrs != null 76645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || (mVPathRenderer != null && mVPathRenderer.canApplyTheme()) 76745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || (mTint != null && mTint.canApplyTheme()) 768d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette || super.canApplyTheme(); 769607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 770607bd848269fb802550e63aa61945790616f97a7Alan Viverette 77155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VectorDrawableState() { 77255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVPathRenderer = new VPathRenderer(); 77355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 77455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 7755c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7765c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable() { 77717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette return new VectorDrawable(this); 7785c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7795c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7805c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7815c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res) { 78217cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette return new VectorDrawable(this); 7835c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7845c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 7855c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 7865c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public int getChangingConfigurations() { 7875c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return mChangingConfigurations; 7885c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7895c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 7905c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 791ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui private static class VPathRenderer { 7924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui /* Right now the internal data structure is organized as a tree. 7934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Each node can be a group node, or a path. 7944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * A group node can have groups or paths as children, but a path node has 7954d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * no children. 7964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * One example can be: 7974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Root Group 7984d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / | \ 7994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Group Path Group 8004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / \ | 8014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Path Path Path 8024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * 8034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui */ 80455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables that only used temporarily inside the draw() call, so there 80555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // is no need for deep copying. 8066f6578e81c1df207da47e2e1337382341f271206Chet Haase private final Path mPath; 8076f6578e81c1df207da47e2e1337382341f271206Chet Haase private final Path mRenderPath; 80855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mFinalPathMatrix = new Matrix(); 8094b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 8104b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mStrokePaint; 8114b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mFillPaint; 812abb7d134c02ac60091108c491dafb00877093170John Hoford private PathMeasure mPathMeasure; 8134b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 81455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 81555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 8168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 81755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final VGroup mRootGroup; 818a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseWidth = 0; 819a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseHeight = 0; 820a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportWidth = 0; 821a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportHeight = 0; 8228490354dc651dd8f25036ef0dda7917fb33013edztenghui int mRootAlpha = 0xFF; 8238490354dc651dd8f25036ef0dda7917fb33013edztenghui String mRootName = null; 8249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 82555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 826abb7d134c02ac60091108c491dafb00877093170John Hoford 827ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer() { 8284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mRootGroup = new VGroup(); 8296f6578e81c1df207da47e2e1337382341f271206Chet Haase mPath = new Path(); 8306f6578e81c1df207da47e2e1337382341f271206Chet Haase mRenderPath = new Path(); 831abb7d134c02ac60091108c491dafb00877093170John Hoford } 8329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 8332af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public void setRootAlpha(int alpha) { 8342af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mRootAlpha = alpha; 8352af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 8362af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 8372af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public int getRootAlpha() { 8382af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return mRootAlpha; 8392af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 8402af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 8418490354dc651dd8f25036ef0dda7917fb33013edztenghui // setAlpha() and getAlpha() are used mostly for animation purpose, since 8428490354dc651dd8f25036ef0dda7917fb33013edztenghui // Animator like to use alpha from 0 to 1. 8438490354dc651dd8f25036ef0dda7917fb33013edztenghui public void setAlpha(float alpha) { 8448490354dc651dd8f25036ef0dda7917fb33013edztenghui setRootAlpha((int) (alpha * 255)); 8458490354dc651dd8f25036ef0dda7917fb33013edztenghui } 8468490354dc651dd8f25036ef0dda7917fb33013edztenghui 8478490354dc651dd8f25036ef0dda7917fb33013edztenghui @SuppressWarnings("unused") 8488490354dc651dd8f25036ef0dda7917fb33013edztenghui public float getAlpha() { 8498490354dc651dd8f25036ef0dda7917fb33013edztenghui return getRootAlpha() / 255.0f; 8508490354dc651dd8f25036ef0dda7917fb33013edztenghui } 8518490354dc651dd8f25036ef0dda7917fb33013edztenghui 852ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer(VPathRenderer copy) { 85355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 8546f6578e81c1df207da47e2e1337382341f271206Chet Haase mPath = new Path(copy.mPath); 8556f6578e81c1df207da47e2e1337382341f271206Chet Haase mRenderPath = new Path(copy.mRenderPath); 856abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseWidth = copy.mBaseWidth; 857abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseHeight = copy.mBaseHeight; 8585eb5cde467081d1af628e5463ba55f110265a86fztenghui mViewportWidth = copy.mViewportWidth; 859abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportHeight = copy.mViewportHeight; 8608e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 86155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootAlpha = copy.mRootAlpha; 8628490354dc651dd8f25036ef0dda7917fb33013edztenghui mRootName = copy.mRootName; 8638490354dc651dd8f25036ef0dda7917fb33013edztenghui if (copy.mRootName != null) { 8648490354dc651dd8f25036ef0dda7917fb33013edztenghui mVGTargetsMap.put(copy.mRootName, this); 8658490354dc651dd8f25036ef0dda7917fb33013edztenghui } 866abb7d134c02ac60091108c491dafb00877093170John Hoford } 867abb7d134c02ac60091108c491dafb00877093170John Hoford 8689453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 8694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // If one of the paths can apply theme, then return true; 8704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return recursiveCanApplyTheme(mRootGroup); 8714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private boolean recursiveCanApplyTheme(VGroup currentGroup) { 8744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, if there is one path return true, 8754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // then we return true for the whole tree. 8768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 8778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 8788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 8798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 8808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 8818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 8828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme() 8838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui || recursiveCanApplyTheme(childGroup)) { 8848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 8858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 8878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 8888d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 8898d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 8908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 8939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return false; 8949453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 8959453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 8969453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 8974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Apply theme to every path of the tree. 8984d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui recursiveApplyTheme(mRootGroup, t); 8994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 9004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void recursiveApplyTheme(VGroup currentGroup, Theme t) { 9024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, apply theme to all paths which 9034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // can apply theme. 9048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 9058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 9068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 9078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 9088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 9098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme()) { 9108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childGroup.applyTheme(t); 9118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 9128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui recursiveApplyTheme(childGroup, t); 9138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 9148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 9158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 9168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childPath.applyTheme(t); 9178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 9184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 9194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 920abb7d134c02ac60091108c491dafb00877093170John Hoford } 921abb7d134c02ac60091108c491dafb00877093170John Hoford 9224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 923b07b086bd42181f62718a6394b56be3917b12511Alan Viverette Canvas canvas, int w, int h, ColorFilter filter) { 9244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Calculate current group's matrix by preConcat the parent's and 9254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // and the current one on the top of the stack. 9264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 9274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Mi the local matrix at level i of the group tree. 9284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 9294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 9304d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 931054a17caaa7cd36f4f4ba644088c4ccf5b9c06fbztenghui // Save the current clip information, which is local to this group. 932054a17caaa7cd36f4f4ba644088c4ccf5b9c06fbztenghui canvas.save(); 9338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Draw the group tree in the same order as the XML file. 9348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 9358d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 9368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 9378d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 9388d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 939b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas, w, h, filter); 9408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 9418d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 942b07b086bd42181f62718a6394b56be3917b12511Alan Viverette drawPath(currentGroup, childPath, canvas, w, h, filter); 9438d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 944abb7d134c02ac60091108c491dafb00877093170John Hoford } 945054a17caaa7cd36f4f4ba644088c4ccf5b9c06fbztenghui canvas.restore(); 9464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 947abb7d134c02ac60091108c491dafb00877093170John Hoford 948b07b086bd42181f62718a6394b56be3917b12511Alan Viverette public void draw(Canvas canvas, int w, int h, ColorFilter filter) { 9494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Travese the tree in pre-order to draw. 950d538fa0fb21171d8256b7d800ae757757f4e3a44Andreas Gampe drawGroupTree(mRootGroup, Matrix.IDENTITY_MATRIX, canvas, w, h, filter); 951abb7d134c02ac60091108c491dafb00877093170John Hoford } 952abb7d134c02ac60091108c491dafb00877093170John Hoford 953b07b086bd42181f62718a6394b56be3917b12511Alan Viverette private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h, 954b07b086bd42181f62718a6394b56be3917b12511Alan Viverette ColorFilter filter) { 9558490354dc651dd8f25036ef0dda7917fb33013edztenghui final float scaleX = w / mViewportWidth; 9569d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleY = h / mViewportHeight; 9579d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float minScale = Math.min(scaleX, scaleY); 958abb7d134c02ac60091108c491dafb00877093170John Hoford 9594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.set(vGroup.mStackedMatrix); 9605a836f74df027bb568da17fbde4e641b6a56d2a9ztenghui mFinalPathMatrix.postScale(scaleX, scaleY); 961abb7d134c02ac60091108c491dafb00877093170John Hoford 9628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui vPath.toPath(mPath); 9638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Path path = mPath; 964abb7d134c02ac60091108c491dafb00877093170John Hoford 9658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.reset(); 9669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 967a95c8abb366d9c39450513335f550b56da13b30aztenghui if (vPath.isClipPath()) { 968a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 9698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.clipPath(mRenderPath, Region.Op.REPLACE); 9708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 971a95c8abb366d9c39450513335f550b56da13b30aztenghui VFullPath fullPath = (VFullPath) vPath; 972a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) { 973a95c8abb366d9c39450513335f550b56da13b30aztenghui float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f; 974a95c8abb366d9c39450513335f550b56da13b30aztenghui float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f; 975a95c8abb366d9c39450513335f550b56da13b30aztenghui 976a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mPathMeasure == null) { 977a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure = new PathMeasure(); 978a95c8abb366d9c39450513335f550b56da13b30aztenghui } 979a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.setPath(mPath, false); 980a95c8abb366d9c39450513335f550b56da13b30aztenghui 981a95c8abb366d9c39450513335f550b56da13b30aztenghui float len = mPathMeasure.getLength(); 982a95c8abb366d9c39450513335f550b56da13b30aztenghui start = start * len; 983a95c8abb366d9c39450513335f550b56da13b30aztenghui end = end * len; 984a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 985a95c8abb366d9c39450513335f550b56da13b30aztenghui if (start > end) { 986a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, len, path, true); 987a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(0f, end, path, true); 988a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 989a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, end, path, true); 990a95c8abb366d9c39450513335f550b56da13b30aztenghui } 991a95c8abb366d9c39450513335f550b56da13b30aztenghui path.rLineTo(0, 0); // fix bug in measure 992a95c8abb366d9c39450513335f550b56da13b30aztenghui } 993a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 994a95c8abb366d9c39450513335f550b56da13b30aztenghui 995a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui if (fullPath.mFillColor != Color.TRANSPARENT) { 9968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mFillPaint == null) { 9978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint = new Paint(); 9988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setStyle(Paint.Style.FILL); 9998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setAntiAlias(true); 100063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 1001b07b086bd42181f62718a6394b56be3917b12511Alan Viverette 1002b07b086bd42181f62718a6394b56be3917b12511Alan Viverette final Paint fillPaint = mFillPaint; 1003b07b086bd42181f62718a6394b56be3917b12511Alan Viverette fillPaint.setColor(applyAlpha(fullPath.mFillColor, fullPath.mFillAlpha)); 1004b07b086bd42181f62718a6394b56be3917b12511Alan Viverette fillPaint.setColorFilter(filter); 1005b07b086bd42181f62718a6394b56be3917b12511Alan Viverette canvas.drawPath(mRenderPath, fillPaint); 10068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 100763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1008a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui if (fullPath.mStrokeColor != Color.TRANSPARENT) { 10098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mStrokePaint == null) { 10108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint = new Paint(); 10118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 10128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setAntiAlias(true); 10138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 10144b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 10158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Paint strokePaint = mStrokePaint; 1016a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineJoin != null) { 1017a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin); 10188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 1019abb7d134c02ac60091108c491dafb00877093170John Hoford 1020a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineCap != null) { 1021a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeCap(fullPath.mStrokeLineCap); 10228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 102363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1024c4d651ec8a8c190c5df173166357c2fdf47472ceztenghui strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit); 1025b07b086bd42181f62718a6394b56be3917b12511Alan Viverette strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, fullPath.mStrokeAlpha)); 1026b07b086bd42181f62718a6394b56be3917b12511Alan Viverette strokePaint.setColorFilter(filter); 1027a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale); 10288d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, strokePaint); 102963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 1030abb7d134c02ac60091108c491dafb00877093170John Hoford } 1031abb7d134c02ac60091108c491dafb00877093170John Hoford } 1032abb7d134c02ac60091108c491dafb00877093170John Hoford } 1033abb7d134c02ac60091108c491dafb00877093170John Hoford 1034a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VGroup { 103555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 103655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // the parents' local matrices with the current one. 103755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mStackedMatrix = new Matrix(); 103855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 103955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 104055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 10418d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 1042abb7d134c02ac60091108c491dafb00877093170John Hoford 104363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mRotate = 0; 104463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotX = 0; 104563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotY = 0; 1046452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleX = 1; 1047452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleY = 1; 1048452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateX = 0; 1049452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateY = 0; 10504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 105155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mLocalMatrix is updated based on the update of transformation information, 105255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // either parsed from the XML or by animation. 10534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private final Matrix mLocalMatrix = new Matrix(); 10548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 105563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private int[] mThemeAttrs; 1056e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private String mGroupName = null; 1057e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 105855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 105955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRotate = copy.mRotate; 106055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotX = copy.mPivotX; 106155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotY = copy.mPivotY; 106255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleX = copy.mScaleX; 106355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleY = copy.mScaleY; 106455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateX = copy.mTranslateX; 106555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateY = copy.mTranslateY; 106655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 106755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupName = copy.mGroupName; 106855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 106955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mGroupName != null) { 107055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui targetsMap.put(mGroupName, this); 107155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 107255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 107355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mLocalMatrix.set(copy.mLocalMatrix); 107455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 10758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = copy.mChildren; 10768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 10778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object copyChild = children.get(i); 10788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (copyChild instanceof VGroup) { 10798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup copyGroup = (VGroup) copyChild; 10808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 1081a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1082a95c8abb366d9c39450513335f550b56da13b30aztenghui VPath newPath = null; 1083a95c8abb366d9c39450513335f550b56da13b30aztenghui if (copyChild instanceof VFullPath) { 1084a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VFullPath((VFullPath) copyChild); 1085a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (copyChild instanceof VClipPath) { 1086a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VClipPath((VClipPath) copyChild); 1087a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1088a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new IllegalStateException("Unknown object in the tree!"); 1089a95c8abb366d9c39450513335f550b56da13b30aztenghui } 10908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(newPath); 10918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (newPath.mPathName != null) { 10928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui targetsMap.put(newPath.mPathName, newPath); 10938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 109455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 109555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 109655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 109755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 109855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup() { 109955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 110055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 1101a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getGroupName() { 1102a95c8abb366d9c39450513335f550b56da13b30aztenghui return mGroupName; 1103a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1104a95c8abb366d9c39450513335f550b56da13b30aztenghui 1105a95c8abb366d9c39450513335f550b56da13b30aztenghui public Matrix getLocalMatrix() { 1106a95c8abb366d9c39450513335f550b56da13b30aztenghui return mLocalMatrix; 1107a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1108a95c8abb366d9c39450513335f550b56da13b30aztenghui 1109a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources res, AttributeSet attrs, Theme theme) { 1110a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(res, theme, attrs, 1111a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableGroup); 1112a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1113a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1114a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1115a95c8abb366d9c39450513335f550b56da13b30aztenghui 1116a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1117a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1118a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1119a95c8abb366d9c39450513335f550b56da13b30aztenghui 1120a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 1121a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 1122a95c8abb366d9c39450513335f550b56da13b30aztenghui 1123a95c8abb366d9c39450513335f550b56da13b30aztenghui mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); 1124a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); 1125a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); 1126a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); 1127a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); 1128a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); 1129a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); 1130a95c8abb366d9c39450513335f550b56da13b30aztenghui 1131a95c8abb366d9c39450513335f550b56da13b30aztenghui final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); 1132a95c8abb366d9c39450513335f550b56da13b30aztenghui if (groupName != null) { 1133a95c8abb366d9c39450513335f550b56da13b30aztenghui mGroupName = groupName; 1134a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1135a95c8abb366d9c39450513335f550b56da13b30aztenghui 1136a95c8abb366d9c39450513335f550b56da13b30aztenghui updateLocalMatrix(); 1137a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1138a95c8abb366d9c39450513335f550b56da13b30aztenghui 1139607bd848269fb802550e63aa61945790616f97a7Alan Viverette public boolean canApplyTheme() { 1140607bd848269fb802550e63aa61945790616f97a7Alan Viverette return mThemeAttrs != null; 1141607bd848269fb802550e63aa61945790616f97a7Alan Viverette } 1142607bd848269fb802550e63aa61945790616f97a7Alan Viverette 1143a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1144a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1145a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1146a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1147a95c8abb366d9c39450513335f550b56da13b30aztenghui 1148607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawableGroup); 1149a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1150a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1151a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1152a95c8abb366d9c39450513335f550b56da13b30aztenghui 1153a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateLocalMatrix() { 1154a95c8abb366d9c39450513335f550b56da13b30aztenghui // The order we apply is the same as the 1155a95c8abb366d9c39450513335f550b56da13b30aztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 1156a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.reset(); 1157a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 1158a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 1159a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 1160a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 1161a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1162a95c8abb366d9c39450513335f550b56da13b30aztenghui 1163a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1164a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1165e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getRotation() { 1166e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mRotate; 1167e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1168e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1169a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1170e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setRotation(float rotation) { 1171e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (rotation != mRotate) { 1172e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mRotate = rotation; 1173e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1174e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1175e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1176e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1177a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1178e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotX() { 1179e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotX; 1180e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1181e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1182a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1183e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotX(float pivotX) { 1184e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotX != mPivotX) { 1185e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotX = pivotX; 1186e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1187e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1188e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1189e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1190a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1191e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotY() { 1192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotY; 1193e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1194e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1195a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1196e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotY(float pivotY) { 1197e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotY != mPivotY) { 1198e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotY = pivotY; 1199e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1200e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1201e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1202e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1203a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1204e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleX() { 1205e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleX; 1206e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 12074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1208a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1209e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleX(float scaleX) { 1210e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleX != mScaleX) { 1211e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleX = scaleX; 1212e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1213e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1214e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1215e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1216a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1217e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleY() { 1218e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleY; 1219e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1220e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1221a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1222e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleY(float scaleY) { 1223e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleY != mScaleY) { 1224e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleY = scaleY; 1225e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1226e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1227e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1228e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1229a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1230e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateX() { 1231e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateX; 1232e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1233e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1234a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1235e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateX(float translateX) { 1236e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateX != mTranslateX) { 1237e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateX = translateX; 1238e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1239e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1240e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1241e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1242a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1243e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateY() { 1244e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateY; 1245e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1246e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1247a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1248e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateY(float translateY) { 1249e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateY != mTranslateY) { 1250e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateY = translateY; 1251e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1252e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1253e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1254a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1255e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1256a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1257a95c8abb366d9c39450513335f550b56da13b30aztenghui * Common Path information for clip path and normal path. 1258a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1259a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VPath { 1260a95c8abb366d9c39450513335f550b56da13b30aztenghui protected PathParser.PathDataNode[] mNodes = null; 1261a95c8abb366d9c39450513335f550b56da13b30aztenghui String mPathName; 1262a95c8abb366d9c39450513335f550b56da13b30aztenghui int mChangingConfigurations; 1263a95c8abb366d9c39450513335f550b56da13b30aztenghui 1264a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath() { 1265a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 12664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1268a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath(VPath copy) { 1269a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = copy.mPathName; 1270a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations = copy.mChangingConfigurations; 1271a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 12724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1274a95c8abb366d9c39450513335f550b56da13b30aztenghui public void toPath(Path path) { 1275a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 1276a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mNodes != null) { 1277a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 1278a95c8abb366d9c39450513335f550b56da13b30aztenghui } 12794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 12804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1281a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getPathName() { 1282a95c8abb366d9c39450513335f550b56da13b30aztenghui return mPathName; 12838e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12848e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 1285a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1286a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1287a95c8abb366d9c39450513335f550b56da13b30aztenghui } 128863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1289a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1290a95c8abb366d9c39450513335f550b56da13b30aztenghui } 129163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1292a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1293a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1294a95c8abb366d9c39450513335f550b56da13b30aztenghui } 129563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1296a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1297a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1298a95c8abb366d9c39450513335f550b56da13b30aztenghui public PathParser.PathDataNode[] getPathData() { 1299a95c8abb366d9c39450513335f550b56da13b30aztenghui return mNodes; 1300a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1301a95c8abb366d9c39450513335f550b56da13b30aztenghui 1302a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1303a95c8abb366d9c39450513335f550b56da13b30aztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 1304a95c8abb366d9c39450513335f550b56da13b30aztenghui if (!PathParser.canMorph(mNodes, nodes)) { 1305a95c8abb366d9c39450513335f550b56da13b30aztenghui // This should not happen in the middle of animation. 1306a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(nodes); 1307a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1308a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.updateNodes(mNodes, nodes); 130963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 1310a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1311a95c8abb366d9c39450513335f550b56da13b30aztenghui } 131263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1313a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1314a95c8abb366d9c39450513335f550b56da13b30aztenghui * Clip path, which only has name and pathData. 1315a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 13168490354dc651dd8f25036ef0dda7917fb33013edztenghui private static class VClipPath extends VPath { 1317a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath() { 1318a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 13198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 13204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1321a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath(VClipPath copy) { 1322a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 1323a95c8abb366d9c39450513335f550b56da13b30aztenghui } 13244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1325a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1326a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1327a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableClipPath); 13288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 132963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 133063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 133163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1332a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1333a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1334a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1335a95c8abb366d9c39450513335f550b56da13b30aztenghui 13365004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette final String pathName = a.getString(R.styleable.VectorDrawableClipPath_name); 13375004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette if (pathName != null) { 13385004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette mPathName = pathName; 13395004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette } 13405004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette 13415004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette final String pathData = a.getString(R.styleable.VectorDrawableClipPath_pathData); 13425004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette if (pathData != null) { 13435004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette mNodes = PathParser.createNodesFromPathData(pathData); 13445004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette } 1345a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1346a95c8abb366d9c39450513335f550b56da13b30aztenghui 1347a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1348a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1349a95c8abb366d9c39450513335f550b56da13b30aztenghui return true; 13504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 1351abb7d134c02ac60091108c491dafb00877093170John Hoford } 1352abb7d134c02ac60091108c491dafb00877093170John Hoford 1353a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1354a95c8abb366d9c39450513335f550b56da13b30aztenghui * Normal path, which contains all the fill / paint information. 1355a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1356a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VFullPath extends VPath { 135755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 135855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 13599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private int[] mThemeAttrs; 13609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1361a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui int mStrokeColor = Color.TRANSPARENT; 1362abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeWidth = 0; 13632e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 1364a70b4742a7a0b2edc57cbbbf83d2c6d43ebc300dztenghui int mFillColor = Color.TRANSPARENT; 13652e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float mStrokeAlpha = 1.0f; 1366abb7d134c02ac60091108c491dafb00877093170John Hoford int mFillRule; 13672e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui float mFillAlpha = 1.0f; 1368abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathStart = 0; 1369abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathEnd = 1; 1370abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathOffset = 0; 13719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 13724b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 13734b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Join mStrokeLineJoin = Paint.Join.MITER; 1374abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeMiterlimit = 4; 13759453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1376a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath() { 13779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette // Empty constructor. 13789453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 13799453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1380a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath(VFullPath copy) { 1381a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 138255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 138355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 138455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeColor = copy.mStrokeColor; 138555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeWidth = copy.mStrokeWidth; 13862e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = copy.mStrokeAlpha; 138755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillColor = copy.mFillColor; 138855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillRule = copy.mFillRule; 13892e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = copy.mFillAlpha; 139055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathStart = copy.mTrimPathStart; 139155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathEnd = copy.mTrimPathEnd; 139255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathOffset = copy.mTrimPathOffset; 139355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 139455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineCap = copy.mStrokeLineCap; 139555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 139655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 1397abb7d134c02ac60091108c491dafb00877093170John Hoford } 1398abb7d134c02ac60091108c491dafb00877093170John Hoford 13997f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 14007f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 14017f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_BUTT: 14027f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.BUTT; 14037f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_ROUND: 14047f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.ROUND; 14057f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_SQUARE: 14067f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.SQUARE; 14077f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 14087f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 14097f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 14107f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 14117f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 14127f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 14137f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 14147f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_MITER: 14157f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.MITER; 14167f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_ROUND: 14177f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.ROUND; 14187f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_BEVEL: 14197f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.BEVEL; 14207f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 14217f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 14227f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 14237f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 14247f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 1425a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1426a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1427a95c8abb366d9c39450513335f550b56da13b30aztenghui return mThemeAttrs != null; 1428eb034fbca40006c55db143047eb628c4b657730aztenghui } 1429eb034fbca40006c55db143047eb628c4b657730aztenghui 1430a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1431a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1432a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath); 1433a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1434a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1435a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1436a95c8abb366d9c39450513335f550b56da13b30aztenghui 1437a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1438a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1439a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1440a95c8abb366d9c39450513335f550b56da13b30aztenghui 1441a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 1442a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 1443a95c8abb366d9c39450513335f550b56da13b30aztenghui 14445004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette final String pathName = a.getString(R.styleable.VectorDrawablePath_name); 14455004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette if (pathName != null) { 14465004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette mPathName = pathName; 14475004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette } 14485004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette 14495004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette final String pathData = a.getString(R.styleable.VectorDrawablePath_pathData); 14505004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette if (pathData != null) { 14515004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette mNodes = PathParser.createNodesFromPathData(pathData); 14525004032ebc2aee97c5884b7f91cc33d2f98ae8b5Alan Viverette } 1453a95c8abb366d9c39450513335f550b56da13b30aztenghui 1454a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor, 1455a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor); 14562e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha, 14572e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha); 1458a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineCap = getStrokeLineCap(a.getInt( 1459a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); 1460a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineJoin = getStrokeLineJoin(a.getInt( 1461a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); 1462a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeMiterlimit = a.getFloat( 1463a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); 1464a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor, 1465a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor); 14662e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha, 14672e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha); 1468a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, 1469a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth); 1470a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, 1471a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd); 1472a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathOffset = a.getFloat( 1473a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); 1474a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathStart = a.getFloat( 1475a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); 1476a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1477a95c8abb366d9c39450513335f550b56da13b30aztenghui 1478a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1479a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1480a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1481a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1482a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1483a95c8abb366d9c39450513335f550b56da13b30aztenghui 1484607bd848269fb802550e63aa61945790616f97a7Alan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 1485a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1486a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1487a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1488a95c8abb366d9c39450513335f550b56da13b30aztenghui 1489a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1490eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1491dbcccffc3760f702887faa95b2748125bac88a89ztenghui int getStrokeColor() { 1492e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeColor; 1493e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1494e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1495eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1496dbcccffc3760f702887faa95b2748125bac88a89ztenghui void setStrokeColor(int strokeColor) { 1497e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeColor = strokeColor; 1498e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1499e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1500eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1501e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeWidth() { 1502e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeWidth; 1503e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1504e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1505eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1506e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeWidth(float strokeWidth) { 1507e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeWidth = strokeWidth; 1508e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1509e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1510eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1511dbcccffc3760f702887faa95b2748125bac88a89ztenghui float getStrokeAlpha() { 15122e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui return mStrokeAlpha; 15132e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 15142e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 15152e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1516dbcccffc3760f702887faa95b2748125bac88a89ztenghui void setStrokeAlpha(float strokeAlpha) { 15172e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mStrokeAlpha = strokeAlpha; 15182e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 15192e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 15202e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1521dbcccffc3760f702887faa95b2748125bac88a89ztenghui int getFillColor() { 1522e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillColor; 1523e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1524e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1525eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1526dbcccffc3760f702887faa95b2748125bac88a89ztenghui void setFillColor(int fillColor) { 1527e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillColor = fillColor; 1528e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1529e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1530eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1531dbcccffc3760f702887faa95b2748125bac88a89ztenghui float getFillAlpha() { 15322e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui return mFillAlpha; 15332e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 15342e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 15352e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1536dbcccffc3760f702887faa95b2748125bac88a89ztenghui void setFillAlpha(float fillAlpha) { 15372e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui mFillAlpha = fillAlpha; 15382e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui } 15392e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui 15402e17d2b232e11b3ec246c704d8c4707c8fd863faztenghui @SuppressWarnings("unused") 1541e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathStart() { 1542e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathStart; 1543e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1544e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1545eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1546e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathStart(float trimPathStart) { 1547e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathStart = trimPathStart; 1548e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1549e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1550eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1551e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathEnd() { 1552e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathEnd; 1553e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1554e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1555eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1556e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathEnd(float trimPathEnd) { 1557e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathEnd = trimPathEnd; 1558e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1559e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1560eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1561e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathOffset() { 1562e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathOffset; 1563e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1564e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1565eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1566e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathOffset(float trimPathOffset) { 1567e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathOffset = trimPathOffset; 1568e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1569abb7d134c02ac60091108c491dafb00877093170John Hoford } 1570abb7d134c02ac60091108c491dafb00877093170John Hoford} 1571