VectorDrawable.java revision 0670f029a4e59448aa53b46a98e60dff6404f360
1abb7d134c02ac60091108c491dafb00877093170John Hoford/* 2abb7d134c02ac60091108c491dafb00877093170John Hoford * Copyright (C) 2014 The Android Open Source Project 3abb7d134c02ac60091108c491dafb00877093170John Hoford * 4abb7d134c02ac60091108c491dafb00877093170John Hoford * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5abb7d134c02ac60091108c491dafb00877093170John Hoford * in compliance with the License. You may obtain a copy of the License at 6abb7d134c02ac60091108c491dafb00877093170John Hoford * 7abb7d134c02ac60091108c491dafb00877093170John Hoford * http://www.apache.org/licenses/LICENSE-2.0 8abb7d134c02ac60091108c491dafb00877093170John Hoford * 9abb7d134c02ac60091108c491dafb00877093170John Hoford * Unless required by applicable law or agreed to in writing, software distributed under the License 10abb7d134c02ac60091108c491dafb00877093170John Hoford * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11abb7d134c02ac60091108c491dafb00877093170John Hoford * or implied. See the License for the specific language governing permissions and limitations under 12abb7d134c02ac60091108c491dafb00877093170John Hoford * the License. 13abb7d134c02ac60091108c491dafb00877093170John Hoford */ 14abb7d134c02ac60091108c491dafb00877093170John Hoford 15abb7d134c02ac60091108c491dafb00877093170John Hofordpackage android.graphics.drawable; 16abb7d134c02ac60091108c491dafb00877093170John Hoford 17b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList; 18abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources; 19abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources.Theme; 204b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viveretteimport android.content.res.TypedArray; 21482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghuiimport android.graphics.Bitmap; 22abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Canvas; 232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghuiimport android.graphics.Color; 24abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.ColorFilter; 25abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Matrix; 26abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Paint; 27abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Path; 28abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PathMeasure; 29abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PixelFormat; 30b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuffColorFilter; 31abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Rect; 32abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Region; 33b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode; 34e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.ArrayMap; 35abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.AttributeSet; 36738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghuiimport android.util.LayoutDirection; 37abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.Log; 38cf4832f69c8786b098ce18c24319021f8cd6733aztenghuiimport android.util.PathParser; 394b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport android.util.Xml; 40abb7d134c02ac60091108c491dafb00877093170John Hoford 41abb7d134c02ac60091108c491dafb00877093170John Hofordimport com.android.internal.R; 42abb7d134c02ac60091108c491dafb00877093170John Hoford 43abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParser; 44abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParserException; 454b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport org.xmlpull.v1.XmlPullParserFactory; 46abb7d134c02ac60091108c491dafb00877093170John Hoford 47abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException; 48abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList; 494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack; 504b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 51abb7d134c02ac60091108c491dafb00877093170John Hoford/** 52d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * This lets you create a drawable based on an XML vector graphic It can be 53d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code><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> 61a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:width</code></dt> 62a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic width of the drawable. 63a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 64a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:height</code></dt> 65a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the intrinsic height the drawable. 66a95c8abb366d9c39450513335f550b56da13b30aztenghui * This support all the dimension units, normally specified with dp.</dd> 67a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportWidth</code></dt> 68a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the width of the viewport space. Viewport is basically 69a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 70a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:viewportHeight</code></dt> 71a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Used to defined the height of the viewport space. Viewport is basically 72a95c8abb366d9c39450513335f550b56da13b30aztenghui * the virtual canvas where the paths are drawn on.</dd> 73a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tint</code></dt> 74a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd> 75a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:tintMode</code></dt> 76a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd> 77a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:autoMirrored</code></dt> 78a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Indicates if the drawable needs to be mirrored when its layout direction is 79a95c8abb366d9c39450513335f550b56da13b30aztenghui * RTL (right-to-left).</dd> 80a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 81a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 82a95c8abb366d9c39450513335f550b56da13b30aztenghui * 83a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 846d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code><group></code></dt> 85452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information. 86452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport. 87a95c8abb366d9c39450513335f550b56da13b30aztenghui * And the transformations are applied in the order of scale, rotate then translate. 88a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 89a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:rotation</code></dt> 90a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The degrees of rotation of the group.</dd> 91a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotX</code></dt> 92a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group. 93a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 94a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pivotY</code></dt> 95a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group. 96a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 97a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleX</code></dt> 98a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the X Coordinate.</dd> 99a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:scaleY</code></dt> 100a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of scale on the Y coordinate.</dd> 101a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateX</code></dt> 102a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the X coordinate. 103a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 104a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:translateY</code></dt> 105a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The amount of translation on the Y coordinate. 106a95c8abb366d9c39450513335f550b56da13b30aztenghui * This is defined in the viewport space.</dd> 107f143ae8ffecc46008b9f6a9fa85d77324b5a145bztenghui * <dt><code>android:alpha</code></dt> 108f143ae8ffecc46008b9f6a9fa85d77324b5a145bztenghui * <dd>The amount of transparency.</dd> 109a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 110a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 111a95c8abb366d9c39450513335f550b56da13b30aztenghui * 112a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 113abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><path></code></dt> 1146d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn. 115abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 116a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 117a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the path.</dd> 118a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 11946e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute 120a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data. This is defined in the viewport space.</dd> 121a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:fillColor</code></dt> 122f143ae8ffecc46008b9f6a9fa85d77324b5a145bztenghui * <dd>Defines the color to fill the path (black if not present).</dd> 123a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeColor</code></dt> 124d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd> 125a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeWidth</code></dt> 126a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The width a path stroke.</dd> 127a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathStart</code></dt> 128a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd> 129a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathEnd</code></dt> 130a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd> 131a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:trimPathOffset</code></dt> 132a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Shift trim region (allows showed region to include the start and end), in the range 133a95c8abb366d9c39450513335f550b56da13b30aztenghui * from 0 to 1.</dd> 134a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineCap</code></dt> 135a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the linecap for a stroked path: butt, round, square.</dd> 136a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeLineJoin</code></dt> 137a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd> 138a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:strokeMiterLimit</code></dt> 139a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Sets the Miter limit for a stroked path.</dd> 140a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 141a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl> 142a95c8abb366d9c39450513335f550b56da13b30aztenghui * 143a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 144a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code><clip-path></code></dt> 145a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines path to be the current clip. 146a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dl> 147a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:name</code></dt> 148a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines the name of the clip path.</dd> 149a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dt><code>android:pathData</code></dt> 150a95c8abb366d9c39450513335f550b56da13b30aztenghui * <dd>Defines clip path string. This is using exactly same format as "d" attribute 151a95c8abb366d9c39450513335f550b56da13b30aztenghui * in the SVG's path data.</dd> 152a95c8abb366d9c39450513335f550b56da13b30aztenghui * </dl></dd> 153abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl> 154a95c8abb366d9c39450513335f550b56da13b30aztenghui * <li>Here is a simple VectorDrawable in this vectordrawable.xml file. 155a95c8abb366d9c39450513335f550b56da13b30aztenghui * <pre> 156a95c8abb366d9c39450513335f550b56da13b30aztenghui * <vector xmlns:android="http://schemas.android.com/apk/res/android" 157a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:height="64dp" 158a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:width="64dp" 159a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportHeight="600" 160a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:viewportWidth="600" > 161a95c8abb366d9c39450513335f550b56da13b30aztenghui * <group 162a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="rotationGroup" 163a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotX="300.0" 164a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pivotY="300.0" 165a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:rotation="45.0" > 166a95c8abb366d9c39450513335f550b56da13b30aztenghui * <path 167a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:name="v" 168a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:fillColor="#000000" 169a95c8abb366d9c39450513335f550b56da13b30aztenghui * android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 170a95c8abb366d9c39450513335f550b56da13b30aztenghui * </group> 171a95c8abb366d9c39450513335f550b56da13b30aztenghui * </vector> 172a95c8abb366d9c39450513335f550b56da13b30aztenghui * </pre></li> 173abb7d134c02ac60091108c491dafb00877093170John Hoford */ 174a95c8abb366d9c39450513335f550b56da13b30aztenghui 175abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable { 1769453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private static final String LOGTAG = VectorDrawable.class.getSimpleName(); 1779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 178a95c8abb366d9c39450513335f550b56da13b30aztenghui private static final String SHAPE_CLIP_PATH = "clip-path"; 1796d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui private static final String SHAPE_GROUP = "group"; 180abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_PATH = "path"; 181abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VECTOR = "vector"; 182abb7d134c02ac60091108c491dafb00877093170John Hoford 183abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_BUTT = 0; 184abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_ROUND = 1; 185abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_SQUARE = 2; 1869453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 187abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_MITER = 0; 188abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_ROUND = 1; 189abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_BEVEL = 2; 1909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final boolean DBG_VECTOR_DRAWABLE = false; 1924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 19355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private VectorDrawableState mVectorState; 194e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 195b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette private PorterDuffColorFilter mTintFilter; 196b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 19755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private boolean mMutated; 19855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 199482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // AnimatedVectorDrawable needs to turn off the cache all the time, otherwise, 200482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // caching the bitmap by default is allowed. 201482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui private boolean mAllowCaching = true; 202482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 203abb7d134c02ac60091108c491dafb00877093170John Hoford public VectorDrawable() { 20455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(); 205abb7d134c02ac60091108c491dafb00877093170John Hoford } 206abb7d134c02ac60091108c491dafb00877093170John Hoford 2079453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) { 20816c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui if (theme != null && state.canApplyTheme()) { 20916c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui // If we need to apply a theme, implicitly mutate. 21016c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = new VectorDrawableState(state); 2119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette applyTheme(theme); 21216c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui } else { 21316c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = state; 2149453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 215b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 216b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 217b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 218abb7d134c02ac60091108c491dafb00877093170John Hoford } 219abb7d134c02ac60091108c491dafb00877093170John Hoford 22055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 22155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public Drawable mutate() { 22255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!mMutated && super.mutate() == this) { 22355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(mVectorState); 22455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mMutated = true; 22555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 22655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return this; 22755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 22855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 229e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Object getTargetByName(String name) { 23055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); 231e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 232e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 233abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 234abb7d134c02ac60091108c491dafb00877093170John Hoford public ConstantState getConstantState() { 23555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState.mChangingConfigurations = getChangingConfigurations(); 23655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState; 237abb7d134c02ac60091108c491dafb00877093170John Hoford } 238abb7d134c02ac60091108c491dafb00877093170John Hoford 2394554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette @Override 240abb7d134c02ac60091108c491dafb00877093170John Hoford public void draw(Canvas canvas) { 2414b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final Rect bounds = getBounds(); 2421968201b44567262e7b2e382eee3d88990748d89Dan Sandler if (bounds.width() == 0 || bounds.height() == 0) { 2431968201b44567262e7b2e382eee3d88990748d89Dan Sandler // too small to draw 2441968201b44567262e7b2e382eee3d88990748d89Dan Sandler return; 2451968201b44567262e7b2e382eee3d88990748d89Dan Sandler } 2461968201b44567262e7b2e382eee3d88990748d89Dan Sandler 2470670f029a4e59448aa53b46a98e60dff6404f360ztenghui final int saveCount = canvas.save(); 248738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui final boolean needMirroring = needMirroring(); 249738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2504b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.translate(bounds.left, bounds.top); 251738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (needMirroring) { 252738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.translate(bounds.width(), 0); 253738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui canvas.scale(-1.0f, 1.0f); 254738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 255482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 256482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (!mAllowCaching) { 257482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height()); 258482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } else { 259482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap bitmap = mVectorState.mCachedBitmap; 260482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui if (bitmap == null || !mVectorState.canReuseCache(bounds.width(), 261482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui bounds.height())) { 262482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), 263482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap.Config.ARGB_8888); 264482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Canvas tmpCanvas = new Canvas(bitmap); 265482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height()); 266482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.mCachedBitmap = bitmap; 267482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 268482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mVectorState.updateCacheStates(); 269482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 27066613415966f2f1a43cdaa76560eb6d53a05f15dztenghui // The bitmap's size is the same as the bounds. 27166613415966f2f1a43cdaa76560eb6d53a05f15dztenghui canvas.drawBitmap(bitmap, 0, 0, null); 272482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 273738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 2744b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.restoreToCount(saveCount); 275abb7d134c02ac60091108c491dafb00877093170John Hoford } 276abb7d134c02ac60091108c491dafb00877093170John Hoford 277abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 278e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getAlpha() { 279e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mVectorState.mVPathRenderer.getRootAlpha(); 280e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 281e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 282e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 283abb7d134c02ac60091108c491dafb00877093170John Hoford public void setAlpha(int alpha) { 2842af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) { 2852af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mVectorState.mVPathRenderer.setRootAlpha(alpha); 286abb7d134c02ac60091108c491dafb00877093170John Hoford invalidateSelf(); 287abb7d134c02ac60091108c491dafb00877093170John Hoford } 288abb7d134c02ac60091108c491dafb00877093170John Hoford } 289abb7d134c02ac60091108c491dafb00877093170John Hoford 290abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 291abb7d134c02ac60091108c491dafb00877093170John Hoford public void setColorFilter(ColorFilter colorFilter) { 292b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 293b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (colorFilter != null) { 294b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Color filter overrides tint. 295b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = null; 296b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } else if (state.mTint != null && state.mTintMode != null) { 297b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Restore the tint filter, if we need one. 298b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT); 299b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = new PorterDuffColorFilter(color, state.mTintMode); 300b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette colorFilter = mTintFilter; 301b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 302b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 303b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mVPathRenderer.setColorFilter(colorFilter); 304fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette invalidateSelf(); 305abb7d134c02ac60091108c491dafb00877093170John Hoford } 306abb7d134c02ac60091108c491dafb00877093170John Hoford 307abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 308a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintList(ColorStateList tint) { 309b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 310a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTint != tint) { 311b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTint = tint; 312a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode); 313a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette state.mVPathRenderer.setColorFilter(mTintFilter); 314a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette invalidateSelf(); 315a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 316a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette } 317b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 318a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette @Override 319a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette public void setTintMode(Mode tintMode) { 320a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette final VectorDrawableState state = mVectorState; 321a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette if (state.mTintMode != tintMode) { 322a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette state.mTintMode = tintMode; 323a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode); 324a426445dfdab43886dd894f2ba8a1d55bfcbb278Alan Viverette state.mVPathRenderer.setColorFilter(mTintFilter); 325b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette invalidateSelf(); 326b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 327b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 328b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 329b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 330b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette protected boolean onStateChange(int[] stateSet) { 331b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 332b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != null && state.mTintMode != null) { 333b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 334b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 335b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return true; 336b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 337b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return false; 338b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 339b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 340b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 341abb7d134c02ac60091108c491dafb00877093170John Hoford public int getOpacity() { 342abb7d134c02ac60091108c491dafb00877093170John Hoford return PixelFormat.TRANSLUCENT; 343abb7d134c02ac60091108c491dafb00877093170John Hoford } 344abb7d134c02ac60091108c491dafb00877093170John Hoford 345abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 346abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicWidth() { 347ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseWidth; 348abb7d134c02ac60091108c491dafb00877093170John Hoford } 349abb7d134c02ac60091108c491dafb00877093170John Hoford 350abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 351abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicHeight() { 352ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseHeight; 353abb7d134c02ac60091108c491dafb00877093170John Hoford } 354abb7d134c02ac60091108c491dafb00877093170John Hoford 355abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 3569453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 3579453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme(); 3589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette @Override 3619453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 3629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette super.applyTheme(t); 3639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VectorDrawableState state = mVectorState; 365ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer path = state.mVPathRenderer; 3669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (path != null && path.canApplyTheme()) { 3679453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.applyTheme(t); 3689453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3699453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 3709453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3714b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette /** @hide */ 3724b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette public static VectorDrawable create(Resources resources, int rid) { 3734b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette try { 374874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final XmlPullParser parser = resources.getXml(rid); 375874bcd82c223ce58c9d76edcf619b3988c672307ztenghui final AttributeSet attrs = Xml.asAttributeSet(parser); 376874bcd82c223ce58c9d76edcf619b3988c672307ztenghui int type; 377874bcd82c223ce58c9d76edcf619b3988c672307ztenghui while ((type=parser.next()) != XmlPullParser.START_TAG && 378874bcd82c223ce58c9d76edcf619b3988c672307ztenghui type != XmlPullParser.END_DOCUMENT) { 379874bcd82c223ce58c9d76edcf619b3988c672307ztenghui // Empty loop 380874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 381874bcd82c223ce58c9d76edcf619b3988c672307ztenghui if (type != XmlPullParser.START_TAG) { 382874bcd82c223ce58c9d76edcf619b3988c672307ztenghui throw new XmlPullParserException("No start tag found"); 383874bcd82c223ce58c9d76edcf619b3988c672307ztenghui } 3844b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 3854b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final VectorDrawable drawable = new VectorDrawable(); 386874bcd82c223ce58c9d76edcf619b3988c672307ztenghui drawable.inflate(resources, parser, attrs); 3874b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 3884b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return drawable; 3894b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (XmlPullParserException e) { 3904b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 3914b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (IOException e) { 3924b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 3934b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 3944b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return null; 3954b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 3964b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 3972af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private static int applyAlpha(int color, float alpha) { 3982af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int alphaBytes = Color.alpha(color); 3992af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color &= 0x00FFFFFF; 4002af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color |= ((int) (alphaBytes * alpha)) << 24; 4012af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return color; 4022af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 4032af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 4049cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette @Override 4059cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 4069cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette throws XmlPullParserException, IOException { 407a95c8abb366d9c39450513335f550b56da13b30aztenghui final VectorDrawableState state = mVectorState; 408a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 409a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mVPathRenderer = pathRenderer; 410a95c8abb366d9c39450513335f550b56da13b30aztenghui 411a95c8abb366d9c39450513335f550b56da13b30aztenghui TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable); 4129cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette updateStateFromTypedArray(a); 4139cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette a.recycle(); 4149cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 415a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mCacheDirty = true; 41655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui inflateInternal(res, parser, attrs, theme); 4179cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4189cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 4199cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mVPathRenderer.setColorFilter(mTintFilter); 4209cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4219cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 422a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) throws XmlPullParserException { 4239cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 424a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 4259cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 4278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 4288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 4299cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette // Extract the theme attributes, if any. 4309cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 4319cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4329cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1); 4339cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tintMode != -1) { 4349cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN); 4359cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4369cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 4379cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint); 4389cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tint != null) { 4399cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTint = tint; 4409cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 441738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 442738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui state.mAutoMirrored = a.getBoolean( 443738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui R.styleable.VectorDrawable_autoMirrored, state.mAutoMirrored); 444a95c8abb366d9c39450513335f550b56da13b30aztenghui 445a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportWidth = a.getFloat( 446a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportWidth, pathRenderer.mViewportWidth); 447a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mViewportHeight = a.getFloat( 448a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_viewportHeight, pathRenderer.mViewportHeight); 449a95c8abb366d9c39450513335f550b56da13b30aztenghui 450a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mViewportWidth <= 0) { 451a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 4521c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportWidth > 0"); 453a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mViewportHeight <= 0) { 454a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 4551c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires viewportHeight > 0"); 456a95c8abb366d9c39450513335f550b56da13b30aztenghui } 457a95c8abb366d9c39450513335f550b56da13b30aztenghui 458a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseWidth = a.getDimension( 459a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_width, pathRenderer.mBaseWidth); 460a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mBaseHeight = a.getDimension( 461a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawable_height, pathRenderer.mBaseHeight); 462a95c8abb366d9c39450513335f550b56da13b30aztenghui 463a95c8abb366d9c39450513335f550b56da13b30aztenghui if (pathRenderer.mBaseWidth <= 0) { 464a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 4651c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires width > 0"); 466a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (pathRenderer.mBaseHeight <= 0) { 467a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new XmlPullParserException(a.getPositionDescription() + 4681c4d8b2173bf4b5bbac94748959752599775628dztenghui "<vector> tag requires height > 0"); 469a95c8abb366d9c39450513335f550b56da13b30aztenghui } 4709cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 4719cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 47255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 4738e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette Theme theme) throws XmlPullParserException, IOException { 4748e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final VectorDrawableState state = mVectorState; 475a95c8abb366d9c39450513335f550b56da13b30aztenghui final VPathRenderer pathRenderer = state.mVPathRenderer; 476abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noPathTag = true; 4779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 4784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Use a stack to help to build the group tree. 4794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The top of the stack is always the current group. 4804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 4814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(pathRenderer.mRootGroup); 482abb7d134c02ac60091108c491dafb00877093170John Hoford 483abb7d134c02ac60091108c491dafb00877093170John Hoford int eventType = parser.getEventType(); 484abb7d134c02ac60091108c491dafb00877093170John Hoford while (eventType != XmlPullParser.END_DOCUMENT) { 485abb7d134c02ac60091108c491dafb00877093170John Hoford if (eventType == XmlPullParser.START_TAG) { 4869453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final String tagName = parser.getName(); 4874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final VGroup currentGroup = groupStack.peek(); 4884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 489abb7d134c02ac60091108c491dafb00877093170John Hoford if (SHAPE_PATH.equals(tagName)) { 490a95c8abb366d9c39450513335f550b56da13b30aztenghui final VFullPath path = new VFullPath(); 4919453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.inflate(res, attrs, theme); 4928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(path); 493e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (path.getPathName() != null) { 49455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 495e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 496abb7d134c02ac60091108c491dafb00877093170John Hoford noPathTag = false; 4978e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= path.mChangingConfigurations; 498a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (SHAPE_CLIP_PATH.equals(tagName)) { 499a95c8abb366d9c39450513335f550b56da13b30aztenghui final VClipPath path = new VClipPath(); 500a95c8abb366d9c39450513335f550b56da13b30aztenghui path.inflate(res, attrs, theme); 501a95c8abb366d9c39450513335f550b56da13b30aztenghui currentGroup.mChildren.add(path); 502a95c8abb366d9c39450513335f550b56da13b30aztenghui if (path.getPathName() != null) { 503a95c8abb366d9c39450513335f550b56da13b30aztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 504a95c8abb366d9c39450513335f550b56da13b30aztenghui } 505a95c8abb366d9c39450513335f550b56da13b30aztenghui state.mChangingConfigurations |= path.mChangingConfigurations; 5066d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 5074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui VGroup newChildGroup = new VGroup(); 5084d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui newChildGroup.inflate(res, attrs, theme); 5098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(newChildGroup); 5104d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(newChildGroup); 511e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (newChildGroup.getGroupName() != null) { 51255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 51355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui newChildGroup); 514e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 5158e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 516abb7d134c02ac60091108c491dafb00877093170John Hoford } 5174d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } else if (eventType == XmlPullParser.END_TAG) { 5184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final String tagName = parser.getName(); 5194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (SHAPE_GROUP.equals(tagName)) { 5204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.pop(); 5214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 522abb7d134c02ac60091108c491dafb00877093170John Hoford } 523abb7d134c02ac60091108c491dafb00877093170John Hoford eventType = parser.next(); 524abb7d134c02ac60091108c491dafb00877093170John Hoford } 5259453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the tree out for debug. 5274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (DBG_VECTOR_DRAWABLE) { 5284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 5296d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } 5306d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 531a95c8abb366d9c39450513335f550b56da13b30aztenghui if (noPathTag) { 5329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final StringBuffer tag = new StringBuffer(); 5339453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 534a95c8abb366d9c39450513335f550b56da13b30aztenghui if (tag.length() > 0) { 535a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(" or "); 536abb7d134c02ac60091108c491dafb00877093170John Hoford } 537a95c8abb366d9c39450513335f550b56da13b30aztenghui tag.append(SHAPE_PATH); 5389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5399453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette throw new XmlPullParserException("no " + tag + " defined"); 540abb7d134c02ac60091108c491dafb00877093170John Hoford } 541abb7d134c02ac60091108c491dafb00877093170John Hoford } 542abb7d134c02ac60091108c491dafb00877093170John Hoford 5434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void printGroupTree(VGroup currentGroup, int level) { 5444d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui String indent = ""; 5458d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < level; i++) { 5464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui indent += " "; 5474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5484d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the current node 5498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 5504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui + " rotation is " + currentGroup.mRotate); 5518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 5528d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Then print all the children groups 5538d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 5548d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 5558d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 5568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui printGroupTree((VGroup) child, level + 1); 5578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 5584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5604d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 56155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 56255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public int getChangingConfigurations() { 56355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return super.getChangingConfigurations() | mVectorState.mChangingConfigurations; 56455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 56555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 566482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui void setAllowCaching(boolean allowCaching) { 567482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mAllowCaching = allowCaching; 568482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 569482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 570738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui private boolean needMirroring() { 571738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL; 572738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 573738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 574738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 575738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public void setAutoMirrored(boolean mirrored) { 576738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui if (mVectorState.mAutoMirrored != mirrored) { 577738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mVectorState.mAutoMirrored = mirrored; 578738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui invalidateSelf(); 579738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 580738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 581738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 582738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui @Override 583738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui public boolean isAutoMirrored() { 584738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui return mVectorState.mAutoMirrored; 585738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui } 586738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui 5875c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette private static class VectorDrawableState extends ConstantState { 5889cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette int[] mThemeAttrs; 5895c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette int mChangingConfigurations; 590ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui VPathRenderer mVPathRenderer; 591b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette ColorStateList mTint; 592b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette Mode mTintMode; 593738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui boolean mAutoMirrored; 5945c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 595482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Bitmap mCachedBitmap; 596482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int[] mCachedThemeAttrs; 597482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui ColorStateList mCachedTint; 598482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui Mode mCachedTintMode; 599482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui int mCachedRootAlpha; 600670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCachedAutoMirrored; 601670689af43358568bf2b5916284f1cac5762f428ztenghui boolean mCacheDirty; 602482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 60355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Deep copy for mutate() or implicitly mutate. 6045c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public VectorDrawableState(VectorDrawableState copy) { 6055c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette if (copy != null) { 6069cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mThemeAttrs = copy.mThemeAttrs; 6075c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 608ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 609b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = copy.mTint; 610b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = copy.mTintMode; 611738177caf6a755a59ca6b17bb968be0aa4e8e10fztenghui mAutoMirrored = copy.mAutoMirrored; 6125c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6135c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6145c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 615482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public boolean canReuseCache(int width, int height) { 616670689af43358568bf2b5916284f1cac5762f428ztenghui if (!mCacheDirty 617670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedThemeAttrs == mThemeAttrs 618482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTint == mTint 619482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedTintMode == mTintMode 620670689af43358568bf2b5916284f1cac5762f428ztenghui && mCachedAutoMirrored == mAutoMirrored 621482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && width == mCachedBitmap.getWidth() 622482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && height == mCachedBitmap.getHeight() 623482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui && mCachedRootAlpha == mVPathRenderer.getRootAlpha()) { 624482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return true; 625482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 626482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui return false; 627482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 628482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 629482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui public void updateCacheStates() { 630482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // Use shallow copy here and shallow comparison in canReuseCache(), 631482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui // likely hit cache miss more, but practically not much difference. 632482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedThemeAttrs = mThemeAttrs; 633482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTint = mTint; 634482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedTintMode = mTintMode; 635482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui mCachedRootAlpha = mVPathRenderer.getRootAlpha(); 636670689af43358568bf2b5916284f1cac5762f428ztenghui mCachedAutoMirrored = mAutoMirrored; 637670689af43358568bf2b5916284f1cac5762f428ztenghui mCacheDirty = false; 638482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui } 639482eb53c8a7d5180a2d0ce3b0a779c18960aa8cdztenghui 64055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VectorDrawableState() { 64155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVPathRenderer = new VPathRenderer(); 64255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 64355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 6445c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 6455c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable() { 6465c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, null, null); 6475c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6485c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 6495c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 6505c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res) { 6515c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, null); 6525c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6535c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 6545c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 6555c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res, Theme theme) { 6565c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, theme); 6575c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6585c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 6595c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 6605c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public int getChangingConfigurations() { 6615c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return mChangingConfigurations; 6625c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6635c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 6645c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 665ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui private static class VPathRenderer { 6664d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui /* Right now the internal data structure is organized as a tree. 6674d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Each node can be a group node, or a path. 6684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * A group node can have groups or paths as children, but a path node has 6694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * no children. 6704d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * One example can be: 6714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Root Group 6724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / | \ 6734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Group Path Group 6744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / \ | 6754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Path Path Path 6764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * 6774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui */ 67855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables that only used temporarily inside the draw() call, so there 67955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // is no need for deep copying. 6804b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mPath = new Path(); 6814b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mRenderPath = new Path(); 6824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final Matrix IDENTITY_MATRIX = new Matrix(); 68355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mFinalPathMatrix = new Matrix(); 6844b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 6854b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mStrokePaint; 6864b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mFillPaint; 687fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette private ColorFilter mColorFilter; 688abb7d134c02ac60091108c491dafb00877093170John Hoford private PathMeasure mPathMeasure; 6894b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 69055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 69155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 6928e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 69355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final VGroup mRootGroup; 694a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseWidth = 0; 695a95c8abb366d9c39450513335f550b56da13b30aztenghui float mBaseHeight = 0; 696a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportWidth = 0; 697a95c8abb366d9c39450513335f550b56da13b30aztenghui float mViewportHeight = 0; 6982af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private int mRootAlpha = 0xFF; 6999453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 70055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 701abb7d134c02ac60091108c491dafb00877093170John Hoford 702ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer() { 7034d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mRootGroup = new VGroup(); 704abb7d134c02ac60091108c491dafb00877093170John Hoford } 7059453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 7062af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public void setRootAlpha(int alpha) { 7072af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mRootAlpha = alpha; 7082af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 7092af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 7102af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public int getRootAlpha() { 7112af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return mRootAlpha; 7122af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 7132af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 714ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer(VPathRenderer copy) { 71555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 716abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseWidth = copy.mBaseWidth; 717abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseHeight = copy.mBaseHeight; 7185eb5cde467081d1af628e5463ba55f110265a86fztenghui mViewportWidth = copy.mViewportWidth; 719abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportHeight = copy.mViewportHeight; 7208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 72155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootAlpha = copy.mRootAlpha; 722abb7d134c02ac60091108c491dafb00877093170John Hoford } 723abb7d134c02ac60091108c491dafb00877093170John Hoford 7249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 7254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // If one of the paths can apply theme, then return true; 7264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return recursiveCanApplyTheme(mRootGroup); 7274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 7284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 7294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private boolean recursiveCanApplyTheme(VGroup currentGroup) { 7304d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, if there is one path return true, 7314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // then we return true for the whole tree. 7328d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 7338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 7348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 7358d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 7368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 7378d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 7388d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme() 7398d0d24f7a2b1a59060aa18926984491691d3c667ztenghui || recursiveCanApplyTheme(childGroup)) { 7408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 7418d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7428d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 7438d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 7448d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 7458d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 7468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 7484d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 7499453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return false; 7509453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 7519453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 7529453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 7534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Apply theme to every path of the tree. 7544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui recursiveApplyTheme(mRootGroup, t); 7554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 7564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 7574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void recursiveApplyTheme(VGroup currentGroup, Theme t) { 7584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, apply theme to all paths which 7594d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // can apply theme. 7608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 7618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 7628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 7638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 7648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 7658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme()) { 7668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childGroup.applyTheme(t); 7678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui recursiveApplyTheme(childGroup, t); 7698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 7708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 7718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 7728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childPath.applyTheme(t); 7738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7744d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 7754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 776abb7d134c02ac60091108c491dafb00877093170John Hoford } 777abb7d134c02ac60091108c491dafb00877093170John Hoford 778fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette public void setColorFilter(ColorFilter colorFilter) { 779fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mColorFilter = colorFilter; 780fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 781fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mFillPaint != null) { 782fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mFillPaint.setColorFilter(colorFilter); 783fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 784fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 785fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mStrokePaint != null) { 786fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mStrokePaint.setColorFilter(colorFilter); 787fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 7886d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 789fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 790fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 7914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 7922af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float currentAlpha, Canvas canvas, int w, int h) { 7934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Calculate current group's matrix by preConcat the parent's and 7944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // and the current one on the top of the stack. 7954d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 7964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Mi the local matrix at level i of the group tree. 7974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 7984d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 7994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 8004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 8012af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha; 8028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 8038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Draw the group tree in the same order as the XML file. 8048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 8058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 8068d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 8078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 8088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 8098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui stackedAlpha, canvas, w, h); 8108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 8118d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 8128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawPath(currentGroup, childPath, stackedAlpha, canvas, w, h); 8138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 814abb7d134c02ac60091108c491dafb00877093170John Hoford } 8154d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 816abb7d134c02ac60091108c491dafb00877093170John Hoford 8174d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public void draw(Canvas canvas, int w, int h) { 8184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Travese the tree in pre-order to draw. 819a95c8abb366d9c39450513335f550b56da13b30aztenghui drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF, 820a95c8abb366d9c39450513335f550b56da13b30aztenghui canvas, w, h); 821abb7d134c02ac60091108c491dafb00877093170John Hoford } 822abb7d134c02ac60091108c491dafb00877093170John Hoford 8238d0d24f7a2b1a59060aa18926984491691d3c667ztenghui private void drawPath(VGroup vGroup, VPath vPath, float stackedAlpha, 8248d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Canvas canvas, int w, int h) { 8259d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleX = w / mViewportWidth; 8269d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float scaleY = h / mViewportHeight; 8279d59a76dd0e850558e83ef1a48fefd865fac1336ztenghui final float minScale = Math.min(scaleX, scaleY); 828abb7d134c02ac60091108c491dafb00877093170John Hoford 8294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.set(vGroup.mStackedMatrix); 8305a836f74df027bb568da17fbde4e641b6a56d2a9ztenghui mFinalPathMatrix.postScale(scaleX, scaleY); 831abb7d134c02ac60091108c491dafb00877093170John Hoford 8328d0d24f7a2b1a59060aa18926984491691d3c667ztenghui vPath.toPath(mPath); 8338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Path path = mPath; 834abb7d134c02ac60091108c491dafb00877093170John Hoford 8358d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.reset(); 8369453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 837a95c8abb366d9c39450513335f550b56da13b30aztenghui if (vPath.isClipPath()) { 838a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 8398d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.clipPath(mRenderPath, Region.Op.REPLACE); 8408d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 841a95c8abb366d9c39450513335f550b56da13b30aztenghui VFullPath fullPath = (VFullPath) vPath; 842a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) { 843a95c8abb366d9c39450513335f550b56da13b30aztenghui float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f; 844a95c8abb366d9c39450513335f550b56da13b30aztenghui float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f; 845a95c8abb366d9c39450513335f550b56da13b30aztenghui 846a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mPathMeasure == null) { 847a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure = new PathMeasure(); 848a95c8abb366d9c39450513335f550b56da13b30aztenghui } 849a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.setPath(mPath, false); 850a95c8abb366d9c39450513335f550b56da13b30aztenghui 851a95c8abb366d9c39450513335f550b56da13b30aztenghui float len = mPathMeasure.getLength(); 852a95c8abb366d9c39450513335f550b56da13b30aztenghui start = start * len; 853a95c8abb366d9c39450513335f550b56da13b30aztenghui end = end * len; 854a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 855a95c8abb366d9c39450513335f550b56da13b30aztenghui if (start > end) { 856a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, len, path, true); 857a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(0f, end, path, true); 858a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 859a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathMeasure.getSegment(start, end, path, true); 860a95c8abb366d9c39450513335f550b56da13b30aztenghui } 861a95c8abb366d9c39450513335f550b56da13b30aztenghui path.rLineTo(0, 0); // fix bug in measure 862a95c8abb366d9c39450513335f550b56da13b30aztenghui } 863a95c8abb366d9c39450513335f550b56da13b30aztenghui mRenderPath.addPath(path, mFinalPathMatrix); 864a95c8abb366d9c39450513335f550b56da13b30aztenghui 865a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mFillColor != 0) { 8668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mFillPaint == null) { 8678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint = new Paint(); 8688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColorFilter(mColorFilter); 8698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setStyle(Paint.Style.FILL); 8708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setAntiAlias(true); 87163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 872a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillPaint.setColor(applyAlpha(fullPath.mFillColor, stackedAlpha)); 8738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, mFillPaint); 8748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 87563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 876a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeColor != 0) { 8778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mStrokePaint == null) { 8788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint = new Paint(); 8798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setColorFilter(mColorFilter); 8808d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 8818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setAntiAlias(true); 8828d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 8834b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 8848d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Paint strokePaint = mStrokePaint; 885a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineJoin != null) { 886a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin); 8878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 888abb7d134c02ac60091108c491dafb00877093170John Hoford 889a95c8abb366d9c39450513335f550b56da13b30aztenghui if (fullPath.mStrokeLineCap != null) { 890a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeCap(fullPath.mStrokeLineCap); 8918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 89263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 893c4d651ec8a8c190c5df173166357c2fdf47472ceztenghui strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit); 89463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 895a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, stackedAlpha)); 896a95c8abb366d9c39450513335f550b56da13b30aztenghui strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale); 8978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, strokePaint); 89863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 899abb7d134c02ac60091108c491dafb00877093170John Hoford } 900abb7d134c02ac60091108c491dafb00877093170John Hoford } 901abb7d134c02ac60091108c491dafb00877093170John Hoford } 902abb7d134c02ac60091108c491dafb00877093170John Hoford 903a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VGroup { 90455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 90555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // the parents' local matrices with the current one. 90655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mStackedMatrix = new Matrix(); 90755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 90855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 90955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 9108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 911abb7d134c02ac60091108c491dafb00877093170John Hoford 91263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mRotate = 0; 91363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotX = 0; 91463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotY = 0; 915452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleX = 1; 916452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleY = 1; 917452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateX = 0; 918452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateY = 0; 9192af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private float mGroupAlpha = 1; 9204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 92155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mLocalMatrix is updated based on the update of transformation information, 92255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // either parsed from the XML or by animation. 9234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private final Matrix mLocalMatrix = new Matrix(); 9248e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 92563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private int[] mThemeAttrs; 926e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private String mGroupName = null; 927e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 92855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 92955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRotate = copy.mRotate; 93055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotX = copy.mPivotX; 93155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotY = copy.mPivotY; 93255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleX = copy.mScaleX; 93355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleY = copy.mScaleY; 93455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateX = copy.mTranslateX; 93555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateY = copy.mTranslateY; 93655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupAlpha = copy.mGroupAlpha; 93755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 93855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupName = copy.mGroupName; 93955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 94055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mGroupName != null) { 94155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui targetsMap.put(mGroupName, this); 94255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 94355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 94455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mLocalMatrix.set(copy.mLocalMatrix); 94555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 9468d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = copy.mChildren; 9478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 9488d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object copyChild = children.get(i); 9498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (copyChild instanceof VGroup) { 9508d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup copyGroup = (VGroup) copyChild; 9518d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 952a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 953a95c8abb366d9c39450513335f550b56da13b30aztenghui VPath newPath = null; 954a95c8abb366d9c39450513335f550b56da13b30aztenghui if (copyChild instanceof VFullPath) { 955a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VFullPath((VFullPath) copyChild); 956a95c8abb366d9c39450513335f550b56da13b30aztenghui } else if (copyChild instanceof VClipPath) { 957a95c8abb366d9c39450513335f550b56da13b30aztenghui newPath = new VClipPath((VClipPath) copyChild); 958a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 959a95c8abb366d9c39450513335f550b56da13b30aztenghui throw new IllegalStateException("Unknown object in the tree!"); 960a95c8abb366d9c39450513335f550b56da13b30aztenghui } 9618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(newPath); 9628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (newPath.mPathName != null) { 9638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui targetsMap.put(newPath.mPathName, newPath); 9648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 96555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 96655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 96755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 96855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 96955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup() { 97055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 97155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 972a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getGroupName() { 973a95c8abb366d9c39450513335f550b56da13b30aztenghui return mGroupName; 974a95c8abb366d9c39450513335f550b56da13b30aztenghui } 975a95c8abb366d9c39450513335f550b56da13b30aztenghui 976a95c8abb366d9c39450513335f550b56da13b30aztenghui public Matrix getLocalMatrix() { 977a95c8abb366d9c39450513335f550b56da13b30aztenghui return mLocalMatrix; 978a95c8abb366d9c39450513335f550b56da13b30aztenghui } 979a95c8abb366d9c39450513335f550b56da13b30aztenghui 980a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 981a95c8abb366d9c39450513335f550b56da13b30aztenghui return mThemeAttrs != null; 982a95c8abb366d9c39450513335f550b56da13b30aztenghui } 983a95c8abb366d9c39450513335f550b56da13b30aztenghui 984a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources res, AttributeSet attrs, Theme theme) { 985a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(res, theme, attrs, 986a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableGroup); 987a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 988a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 989a95c8abb366d9c39450513335f550b56da13b30aztenghui } 990a95c8abb366d9c39450513335f550b56da13b30aztenghui 991a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 992a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 993a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 994a95c8abb366d9c39450513335f550b56da13b30aztenghui 995a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 996a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 997a95c8abb366d9c39450513335f550b56da13b30aztenghui 998a95c8abb366d9c39450513335f550b56da13b30aztenghui mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); 999a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); 1000a95c8abb366d9c39450513335f550b56da13b30aztenghui mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); 1001a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); 1002a95c8abb366d9c39450513335f550b56da13b30aztenghui mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); 1003a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); 1004a95c8abb366d9c39450513335f550b56da13b30aztenghui mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); 1005a95c8abb366d9c39450513335f550b56da13b30aztenghui mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha); 1006a95c8abb366d9c39450513335f550b56da13b30aztenghui 1007a95c8abb366d9c39450513335f550b56da13b30aztenghui final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); 1008a95c8abb366d9c39450513335f550b56da13b30aztenghui if (groupName != null) { 1009a95c8abb366d9c39450513335f550b56da13b30aztenghui mGroupName = groupName; 1010a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1011a95c8abb366d9c39450513335f550b56da13b30aztenghui 1012a95c8abb366d9c39450513335f550b56da13b30aztenghui updateLocalMatrix(); 1013a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1014a95c8abb366d9c39450513335f550b56da13b30aztenghui 1015a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1016a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1017a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1018a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1019a95c8abb366d9c39450513335f550b56da13b30aztenghui 1020a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = t.resolveAttributes(mThemeAttrs, 1021a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableGroup); 1022a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1023a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1024a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1025a95c8abb366d9c39450513335f550b56da13b30aztenghui 1026a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateLocalMatrix() { 1027a95c8abb366d9c39450513335f550b56da13b30aztenghui // The order we apply is the same as the 1028a95c8abb366d9c39450513335f550b56da13b30aztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 1029a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.reset(); 1030a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 1031a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 1032a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 1033a95c8abb366d9c39450513335f550b56da13b30aztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 1034a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1035a95c8abb366d9c39450513335f550b56da13b30aztenghui 1036a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1037a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1038e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getRotation() { 1039e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mRotate; 1040e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1041e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1042a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1043e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setRotation(float rotation) { 1044e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (rotation != mRotate) { 1045e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mRotate = rotation; 1046e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1047e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1048e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1049e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1050a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1051e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotX() { 1052e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotX; 1053e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1054e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1055a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1056e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotX(float pivotX) { 1057e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotX != mPivotX) { 1058e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotX = pivotX; 1059e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1060e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1061e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1062e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1063a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1064e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotY() { 1065e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotY; 1066e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1067e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1068a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1069e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotY(float pivotY) { 1070e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotY != mPivotY) { 1071e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotY = pivotY; 1072e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1073e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1074e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1075e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1076a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1077e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleX() { 1078e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleX; 1079e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 10804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1081a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1082e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleX(float scaleX) { 1083e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleX != mScaleX) { 1084e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleX = scaleX; 1085e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1086e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1087e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1088e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1089a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1090e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleY() { 1091e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleY; 1092e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1093e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1094a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1095e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleY(float scaleY) { 1096e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleY != mScaleY) { 1097e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleY = scaleY; 1098e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1099e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1100e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1101e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1102a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1103e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateX() { 1104e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateX; 1105e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1106e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1107a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1108e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateX(float translateX) { 1109e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateX != mTranslateX) { 1110e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateX = translateX; 1111e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1112e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1113e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1114e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1115a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1116e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateY() { 1117e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateY; 1118e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1119e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1120a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1121e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateY(float translateY) { 1122e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateY != mTranslateY) { 1123e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateY = translateY; 1124e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 1125e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1126e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1127e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1128a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1129e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getAlpha() { 1130e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mGroupAlpha; 1131e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1132e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1133a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1134e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setAlpha(float groupAlpha) { 1135e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (groupAlpha != mGroupAlpha) { 1136e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mGroupAlpha = groupAlpha; 1137e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1138e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1139a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1140e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1141a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1142a95c8abb366d9c39450513335f550b56da13b30aztenghui * Common Path information for clip path and normal path. 1143a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1144a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VPath { 1145a95c8abb366d9c39450513335f550b56da13b30aztenghui protected PathParser.PathDataNode[] mNodes = null; 1146a95c8abb366d9c39450513335f550b56da13b30aztenghui String mPathName; 1147a95c8abb366d9c39450513335f550b56da13b30aztenghui int mChangingConfigurations; 1148a95c8abb366d9c39450513335f550b56da13b30aztenghui 1149a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath() { 1150a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 11514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 11524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1153a95c8abb366d9c39450513335f550b56da13b30aztenghui public VPath(VPath copy) { 1154a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = copy.mPathName; 1155a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations = copy.mChangingConfigurations; 1156a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 11574d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 11584d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1159a95c8abb366d9c39450513335f550b56da13b30aztenghui public void toPath(Path path) { 1160a95c8abb366d9c39450513335f550b56da13b30aztenghui path.reset(); 1161a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mNodes != null) { 1162a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 1163a95c8abb366d9c39450513335f550b56da13b30aztenghui } 11644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 11654d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1166a95c8abb366d9c39450513335f550b56da13b30aztenghui public String getPathName() { 1167a95c8abb366d9c39450513335f550b56da13b30aztenghui return mPathName; 11688e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 11698e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 1170a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1171a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1172a95c8abb366d9c39450513335f550b56da13b30aztenghui } 117363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1174a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1175a95c8abb366d9c39450513335f550b56da13b30aztenghui } 117663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1177a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1178a95c8abb366d9c39450513335f550b56da13b30aztenghui return false; 1179a95c8abb366d9c39450513335f550b56da13b30aztenghui } 118063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1181a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1182a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1183a95c8abb366d9c39450513335f550b56da13b30aztenghui public PathParser.PathDataNode[] getPathData() { 1184a95c8abb366d9c39450513335f550b56da13b30aztenghui return mNodes; 1185a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1186a95c8abb366d9c39450513335f550b56da13b30aztenghui 1187a95c8abb366d9c39450513335f550b56da13b30aztenghui @SuppressWarnings("unused") 1188a95c8abb366d9c39450513335f550b56da13b30aztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 1189a95c8abb366d9c39450513335f550b56da13b30aztenghui if (!PathParser.canMorph(mNodes, nodes)) { 1190a95c8abb366d9c39450513335f550b56da13b30aztenghui // This should not happen in the middle of animation. 1191a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.deepCopyNodes(nodes); 1192a95c8abb366d9c39450513335f550b56da13b30aztenghui } else { 1193a95c8abb366d9c39450513335f550b56da13b30aztenghui PathParser.updateNodes(mNodes, nodes); 119463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 1195a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1196a95c8abb366d9c39450513335f550b56da13b30aztenghui } 119763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1198a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1199a95c8abb366d9c39450513335f550b56da13b30aztenghui * Clip path, which only has name and pathData. 1200a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1201a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VClipPath extends VPath{ 1202a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath() { 1203a95c8abb366d9c39450513335f550b56da13b30aztenghui // Empty constructor. 12048e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12054d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1206a95c8abb366d9c39450513335f550b56da13b30aztenghui public VClipPath(VClipPath copy) { 1207a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 1208a95c8abb366d9c39450513335f550b56da13b30aztenghui } 12094d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 1210a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1211a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1212a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableClipPath); 12138e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 121463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 121563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 121663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 1217a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1218a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1219a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1220a95c8abb366d9c39450513335f550b56da13b30aztenghui 1221a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = a.getString(R.styleable.VectorDrawableClipPath_name); 1222a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 1223a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawableClipPath_pathData)); 1224a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1225a95c8abb366d9c39450513335f550b56da13b30aztenghui 1226a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1227a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean isClipPath() { 1228a95c8abb366d9c39450513335f550b56da13b30aztenghui return true; 12294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 1230abb7d134c02ac60091108c491dafb00877093170John Hoford } 1231abb7d134c02ac60091108c491dafb00877093170John Hoford 1232a95c8abb366d9c39450513335f550b56da13b30aztenghui /** 1233a95c8abb366d9c39450513335f550b56da13b30aztenghui * Normal path, which contains all the fill / paint information. 1234a95c8abb366d9c39450513335f550b56da13b30aztenghui */ 1235a95c8abb366d9c39450513335f550b56da13b30aztenghui private static class VFullPath extends VPath { 123655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 123755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 12389453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private int[] mThemeAttrs; 12399453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1240abb7d134c02ac60091108c491dafb00877093170John Hoford int mStrokeColor = 0; 1241abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeWidth = 0; 12422af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int mFillColor = Color.BLACK; 1243abb7d134c02ac60091108c491dafb00877093170John Hoford int mFillRule; 1244abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathStart = 0; 1245abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathEnd = 1; 1246abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathOffset = 0; 12479453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12484b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 12494b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Join mStrokeLineJoin = Paint.Join.MITER; 1250abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeMiterlimit = 4; 12519453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1252a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath() { 12539453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette // Empty constructor. 12549453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 12559453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1256a95c8abb366d9c39450513335f550b56da13b30aztenghui public VFullPath(VFullPath copy) { 1257a95c8abb366d9c39450513335f550b56da13b30aztenghui super(copy); 125855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 125955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 126055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeColor = copy.mStrokeColor; 126155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeWidth = copy.mStrokeWidth; 126255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillColor = copy.mFillColor; 126355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillRule = copy.mFillRule; 126455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathStart = copy.mTrimPathStart; 126555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathEnd = copy.mTrimPathEnd; 126655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathOffset = copy.mTrimPathOffset; 126755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 126855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineCap = copy.mStrokeLineCap; 126955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 127055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 1271abb7d134c02ac60091108c491dafb00877093170John Hoford } 1272abb7d134c02ac60091108c491dafb00877093170John Hoford 12737f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 12747f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 12757f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_BUTT: 12767f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.BUTT; 12777f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_ROUND: 12787f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.ROUND; 12797f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_SQUARE: 12807f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.SQUARE; 12817f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 12827f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 12837f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 12847f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 12857f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 12867f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 12877f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 12887f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_MITER: 12897f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.MITER; 12907f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_ROUND: 12917f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.ROUND; 12927f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_BEVEL: 12937f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.BEVEL; 12947f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 12957f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 12967f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 12977f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 12987f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 1299a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1300a95c8abb366d9c39450513335f550b56da13b30aztenghui public boolean canApplyTheme() { 1301a95c8abb366d9c39450513335f550b56da13b30aztenghui return mThemeAttrs != null; 1302eb034fbca40006c55db143047eb628c4b657730aztenghui } 1303eb034fbca40006c55db143047eb628c4b657730aztenghui 1304a95c8abb366d9c39450513335f550b56da13b30aztenghui public void inflate(Resources r, AttributeSet attrs, Theme theme) { 1305a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = obtainAttributes(r, theme, attrs, 1306a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath); 1307a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1308a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1309a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1310a95c8abb366d9c39450513335f550b56da13b30aztenghui 1311a95c8abb366d9c39450513335f550b56da13b30aztenghui private void updateStateFromTypedArray(TypedArray a) { 1312a95c8abb366d9c39450513335f550b56da13b30aztenghui // Account for any configuration changes. 1313a95c8abb366d9c39450513335f550b56da13b30aztenghui mChangingConfigurations |= a.getChangingConfigurations(); 1314a95c8abb366d9c39450513335f550b56da13b30aztenghui 1315a95c8abb366d9c39450513335f550b56da13b30aztenghui // Extract the theme attributes, if any. 1316a95c8abb366d9c39450513335f550b56da13b30aztenghui mThemeAttrs = a.extractThemeAttrs(); 1317a95c8abb366d9c39450513335f550b56da13b30aztenghui 1318a95c8abb366d9c39450513335f550b56da13b30aztenghui mPathName = a.getString(R.styleable.VectorDrawablePath_name); 1319a95c8abb366d9c39450513335f550b56da13b30aztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 1320a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_pathData)); 1321a95c8abb366d9c39450513335f550b56da13b30aztenghui 1322a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor, 1323a95c8abb366d9c39450513335f550b56da13b30aztenghui mFillColor); 1324a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineCap = getStrokeLineCap(a.getInt( 1325a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); 1326a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeLineJoin = getStrokeLineJoin(a.getInt( 1327a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); 1328a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeMiterlimit = a.getFloat( 1329a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); 1330a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor, 1331a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeColor); 1332a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, 1333a95c8abb366d9c39450513335f550b56da13b30aztenghui mStrokeWidth); 1334a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, 1335a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathEnd); 1336a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathOffset = a.getFloat( 1337a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); 1338a95c8abb366d9c39450513335f550b56da13b30aztenghui mTrimPathStart = a.getFloat( 1339a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); 1340a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1341a95c8abb366d9c39450513335f550b56da13b30aztenghui 1342a95c8abb366d9c39450513335f550b56da13b30aztenghui @Override 1343a95c8abb366d9c39450513335f550b56da13b30aztenghui public void applyTheme(Theme t) { 1344a95c8abb366d9c39450513335f550b56da13b30aztenghui if (mThemeAttrs == null) { 1345a95c8abb366d9c39450513335f550b56da13b30aztenghui return; 1346a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1347a95c8abb366d9c39450513335f550b56da13b30aztenghui 1348a95c8abb366d9c39450513335f550b56da13b30aztenghui final TypedArray a = t.resolveAttributes(mThemeAttrs, 1349a95c8abb366d9c39450513335f550b56da13b30aztenghui R.styleable.VectorDrawablePath); 1350a95c8abb366d9c39450513335f550b56da13b30aztenghui updateStateFromTypedArray(a); 1351a95c8abb366d9c39450513335f550b56da13b30aztenghui a.recycle(); 1352a95c8abb366d9c39450513335f550b56da13b30aztenghui } 1353a95c8abb366d9c39450513335f550b56da13b30aztenghui 1354a95c8abb366d9c39450513335f550b56da13b30aztenghui /* Setters and Getters, used by animator from AnimatedVectorDrawable. */ 1355eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1356e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getStroke() { 1357e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeColor; 1358e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1359e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1360eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1361e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStroke(int strokeColor) { 1362e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeColor = strokeColor; 1363e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1364e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1365eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1366e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeWidth() { 1367e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeWidth; 1368e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1369e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1370eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1371e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeWidth(float strokeWidth) { 1372e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeWidth = strokeWidth; 1373e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1374e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1375eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1376e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getFill() { 1377e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillColor; 1378e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1379e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1380eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1381e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFill(int fillColor) { 1382e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillColor = fillColor; 1383e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1384e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1385eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1386e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathStart() { 1387e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathStart; 1388e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1389e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1390eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1391e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathStart(float trimPathStart) { 1392e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathStart = trimPathStart; 1393e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1394e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1395eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1396e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathEnd() { 1397e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathEnd; 1398e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1399e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1400eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1401e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathEnd(float trimPathEnd) { 1402e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathEnd = trimPathEnd; 1403e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1404e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1405eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1406e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathOffset() { 1407e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathOffset; 1408e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1409e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1410eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1411e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathOffset(float trimPathOffset) { 1412e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathOffset = trimPathOffset; 1413e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1414abb7d134c02ac60091108c491dafb00877093170John Hoford } 1415abb7d134c02ac60091108c491dafb00877093170John Hoford} 1416