VectorDrawable.java revision 8d0d24f7a2b1a59060aa18926984491691d3c667
1abb7d134c02ac60091108c491dafb00877093170John Hoford/* 2abb7d134c02ac60091108c491dafb00877093170John Hoford * Copyright (C) 2014 The Android Open Source Project 3abb7d134c02ac60091108c491dafb00877093170John Hoford * 4abb7d134c02ac60091108c491dafb00877093170John Hoford * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5abb7d134c02ac60091108c491dafb00877093170John Hoford * in compliance with the License. You may obtain a copy of the License at 6abb7d134c02ac60091108c491dafb00877093170John Hoford * 7abb7d134c02ac60091108c491dafb00877093170John Hoford * http://www.apache.org/licenses/LICENSE-2.0 8abb7d134c02ac60091108c491dafb00877093170John Hoford * 9abb7d134c02ac60091108c491dafb00877093170John Hoford * Unless required by applicable law or agreed to in writing, software distributed under the License 10abb7d134c02ac60091108c491dafb00877093170John Hoford * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11abb7d134c02ac60091108c491dafb00877093170John Hoford * or implied. See the License for the specific language governing permissions and limitations under 12abb7d134c02ac60091108c491dafb00877093170John Hoford * the License. 13abb7d134c02ac60091108c491dafb00877093170John Hoford */ 14abb7d134c02ac60091108c491dafb00877093170John Hoford 15abb7d134c02ac60091108c491dafb00877093170John Hofordpackage android.graphics.drawable; 16abb7d134c02ac60091108c491dafb00877093170John Hoford 17b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList; 18abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources; 19abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.content.res.Resources.Theme; 204b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viveretteimport android.content.res.TypedArray; 21abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Canvas; 222af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghuiimport android.graphics.Color; 23abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.ColorFilter; 24abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Matrix; 25abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Paint; 26abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Path; 27abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PathMeasure; 28abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.PixelFormat; 29b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuffColorFilter; 30abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Rect; 31abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.graphics.Region; 32b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode; 33e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghuiimport android.util.ArrayMap; 34abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.AttributeSet; 35abb7d134c02ac60091108c491dafb00877093170John Hofordimport android.util.Log; 36cf4832f69c8786b098ce18c24319021f8cd6733aztenghuiimport android.util.PathParser; 374b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport android.util.Xml; 38abb7d134c02ac60091108c491dafb00877093170John Hoford 39abb7d134c02ac60091108c491dafb00877093170John Hofordimport com.android.internal.R; 40abb7d134c02ac60091108c491dafb00877093170John Hoford 41abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParser; 42abb7d134c02ac60091108c491dafb00877093170John Hofordimport org.xmlpull.v1.XmlPullParserException; 434b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viveretteimport org.xmlpull.v1.XmlPullParserFactory; 44abb7d134c02ac60091108c491dafb00877093170John Hoford 45abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.io.IOException; 46abb7d134c02ac60091108c491dafb00877093170John Hofordimport java.util.ArrayList; 474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghuiimport java.util.Stack; 484b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 49abb7d134c02ac60091108c491dafb00877093170John Hoford/** 50d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * This lets you create a drawable based on an XML vector graphic It can be 51d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * defined in an XML file with the <code><vector></code> element. 52abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 5346e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * The vector drawable has the following elements: 54abb7d134c02ac60091108c491dafb00877093170John Hoford * <p/> 55abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 56177dffd869ff1f5bdf816faead01a7dc4980bf75ztenghui * <dt><code><vector></code></dt> 57e3c45e7a6b2a7d2176aa46ee482e299b54feeb9fztenghui * <dd>Used to defined a vector drawable</dd> 58abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><size></code></dt> 59abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the intrinsic Width Height size of the drawable using 60d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:width</code> and <code>android:height</code></dd> 61abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><viewport></code></dt> 62abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Used to defined the size of the virtual canvas the paths are drawn on. 63d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * The size is defined using the attributes <code>android:viewportHeight</code> 64d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <code>android:viewportWidth</code></dd> 656d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dt><code><group></code></dt> 66452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>Defines a group of paths or subgroups, plus transformation information. 67452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * The transformations are defined in the same coordinates as the viewport. 68452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * And the transformations are applied in the order of scale, rotate then translate. </dd> 69452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:rotation</code> 70452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The degrees of rotation of the group.</dd></dt> 71452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotX</code> 72452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The X coordinate of the pivot for the scale and rotation of the group</dd></dt> 73452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:pivotY</code> 74452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The Y coordinate of the pivot for the scale and rotation of the group</dd></dt> 75452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleX</code> 76452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the X Coordinate</dd></dt> 77452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:scaleY</code> 78452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of scale on the Y coordinate</dd></dt> 79452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateX</code> 80452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the X coordinate</dd></dt> 81452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dt><code>android:translateY</code> 82452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui * <dd>The amount of translation on the Y coordinate</dd></dt> 83abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code><path></code></dt> 846d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui * <dd>Defines paths to be drawn. 85abb7d134c02ac60091108c491dafb00877093170John Hoford * <dl> 86abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:name</code> 87abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the name of the path.</dd></dt> 88abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:pathData</code> 8946e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * <dd>Defines path string. This is using exactly same format as "d" attribute 9046e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui * in the SVG's path data</dd></dt> 91abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fill</code> 92abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Defines the color to fill the path (none if not present).</dd></dt> 93abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:stroke</code> 94d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Defines the color to draw the path outline (none if not present).</dd> 95d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * </dt> 96abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeWidth</code> 97abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The width a path stroke</dd></dt> 98abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeOpacity</code> 99abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity of a path stroke</dd></dt> 100abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:fillOpacity</code> 101abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The opacity to fill the path with</dd></dt> 102abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathStart</code> 103abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the start from 0 to 1</dd></dt> 104abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathEnd</code> 105abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>The fraction of the path to trim from the end from 0 to 1</dd></dt> 106abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:trimPathOffset</code> 107d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * <dd>Shift trim region (allows showed region to include the start and end) 108d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette * from 0 to 1</dd></dt> 109abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:clipToPath</code> 110abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Path will set the clip path</dd></dt> 111abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineCap</code> 112abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the linecap for a stroked path: butt, round, square</dd></dt> 113abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeLineJoin</code> 114abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the lineJoin for a stroked path: miter,round,bevel</dd></dt> 115abb7d134c02ac60091108c491dafb00877093170John Hoford * <dt><code>android:strokeMiterLimit</code> 116abb7d134c02ac60091108c491dafb00877093170John Hoford * <dd>Sets the Miter limit for a stroked path</dd></dt> 117abb7d134c02ac60091108c491dafb00877093170John Hoford * </dl> 118abb7d134c02ac60091108c491dafb00877093170John Hoford * </dd> 119abb7d134c02ac60091108c491dafb00877093170John Hoford */ 120abb7d134c02ac60091108c491dafb00877093170John Hofordpublic class VectorDrawable extends Drawable { 1219453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private static final String LOGTAG = VectorDrawable.class.getSimpleName(); 1229453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 123abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_SIZE = "size"; 124abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VIEWPORT = "viewport"; 1256d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui private static final String SHAPE_GROUP = "group"; 126abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_PATH = "path"; 127abb7d134c02ac60091108c491dafb00877093170John Hoford private static final String SHAPE_VECTOR = "vector"; 128abb7d134c02ac60091108c491dafb00877093170John Hoford 129abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_BUTT = 0; 130abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_ROUND = 1; 131abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINECAP_SQUARE = 2; 1329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 133abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_MITER = 0; 134abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_ROUND = 1; 135abb7d134c02ac60091108c491dafb00877093170John Hoford private static final int LINEJOIN_BEVEL = 2; 1369453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1374d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final boolean DBG_VECTOR_DRAWABLE = false; 1384d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 13955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private VectorDrawableState mVectorState; 140e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 141b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette private PorterDuffColorFilter mTintFilter; 142b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 14355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private boolean mMutated; 14455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 145abb7d134c02ac60091108c491dafb00877093170John Hoford public VectorDrawable() { 14655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(); 147abb7d134c02ac60091108c491dafb00877093170John Hoford } 148abb7d134c02ac60091108c491dafb00877093170John Hoford 1499453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private VectorDrawable(VectorDrawableState state, Resources res, Theme theme) { 15016c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui if (theme != null && state.canApplyTheme()) { 15116c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui // If we need to apply a theme, implicitly mutate. 15216c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = new VectorDrawableState(state); 1539453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette applyTheme(theme); 15416c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui } else { 15516c1bd5db8f4f18e1eee8b19006bba5f06a88123ztenghui mVectorState = state; 1569453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 157b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 158b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 159b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 160abb7d134c02ac60091108c491dafb00877093170John Hoford } 161abb7d134c02ac60091108c491dafb00877093170John Hoford 16255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 16355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public Drawable mutate() { 16455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!mMutated && super.mutate() == this) { 16555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState = new VectorDrawableState(mVectorState); 16655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mMutated = true; 16755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 16855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return this; 16955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 17055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 171e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui Object getTargetByName(String name) { 17255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState.mVPathRenderer.mVGTargetsMap.get(name); 173e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 174e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 175abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 176abb7d134c02ac60091108c491dafb00877093170John Hoford public ConstantState getConstantState() { 17755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVectorState.mChangingConfigurations = getChangingConfigurations(); 17855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mVectorState; 179abb7d134c02ac60091108c491dafb00877093170John Hoford } 180abb7d134c02ac60091108c491dafb00877093170John Hoford 1814554a6a5137d8e9bdfb623ad84ff344a48b7eb9dAlan Viverette @Override 182abb7d134c02ac60091108c491dafb00877093170John Hoford public void draw(Canvas canvas) { 1834b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final int saveCount = canvas.save(); 1844b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final Rect bounds = getBounds(); 1854b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.translate(bounds.left, bounds.top); 186ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVectorState.mVPathRenderer.draw(canvas, bounds.width(), bounds.height()); 1874b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette canvas.restoreToCount(saveCount); 188abb7d134c02ac60091108c491dafb00877093170John Hoford } 189abb7d134c02ac60091108c491dafb00877093170John Hoford 190abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 191e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public int getAlpha() { 192e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mVectorState.mVPathRenderer.getRootAlpha(); 193e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 194e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 195e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui @Override 196abb7d134c02ac60091108c491dafb00877093170John Hoford public void setAlpha(int alpha) { 1972af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui if (mVectorState.mVPathRenderer.getRootAlpha() != alpha) { 1982af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mVectorState.mVPathRenderer.setRootAlpha(alpha); 199abb7d134c02ac60091108c491dafb00877093170John Hoford invalidateSelf(); 200abb7d134c02ac60091108c491dafb00877093170John Hoford } 201abb7d134c02ac60091108c491dafb00877093170John Hoford } 202abb7d134c02ac60091108c491dafb00877093170John Hoford 203abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 204abb7d134c02ac60091108c491dafb00877093170John Hoford public void setColorFilter(ColorFilter colorFilter) { 205b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 206b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (colorFilter != null) { 207b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Color filter overrides tint. 208b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = null; 209b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } else if (state.mTint != null && state.mTintMode != null) { 210b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette // Restore the tint filter, if we need one. 211b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final int color = state.mTint.getColorForState(getState(), Color.TRANSPARENT); 212b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = new PorterDuffColorFilter(color, state.mTintMode); 213b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette colorFilter = mTintFilter; 214b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 215b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 216b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mVPathRenderer.setColorFilter(colorFilter); 217fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette invalidateSelf(); 218abb7d134c02ac60091108c491dafb00877093170John Hoford } 219abb7d134c02ac60091108c491dafb00877093170John Hoford 220abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 221b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette public void setTint(ColorStateList tint, Mode tintMode) { 222b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 223b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != tint || state.mTintMode != tintMode) { 224b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTint = tint; 225b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette state.mTintMode = tintMode; 226b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 227b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, tintMode); 228b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 229b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette invalidateSelf(); 230b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 231b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 232b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 233b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 234b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette protected boolean onStateChange(int[] stateSet) { 235b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette final VectorDrawableState state = mVectorState; 236b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette if (state.mTint != null && state.mTintMode != null) { 237b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 238b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mVectorState.mVPathRenderer.setColorFilter(mTintFilter); 239b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return true; 240b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 241b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette return false; 242b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 243b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 244b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 245abb7d134c02ac60091108c491dafb00877093170John Hoford public int getOpacity() { 246abb7d134c02ac60091108c491dafb00877093170John Hoford return PixelFormat.TRANSLUCENT; 247abb7d134c02ac60091108c491dafb00877093170John Hoford } 248abb7d134c02ac60091108c491dafb00877093170John Hoford 249abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 250abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicWidth() { 251ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseWidth; 252abb7d134c02ac60091108c491dafb00877093170John Hoford } 253abb7d134c02ac60091108c491dafb00877093170John Hoford 254abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 255abb7d134c02ac60091108c491dafb00877093170John Hoford public int getIntrinsicHeight() { 256ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui return (int) mVectorState.mVPathRenderer.mBaseHeight; 257abb7d134c02ac60091108c491dafb00877093170John Hoford } 258abb7d134c02ac60091108c491dafb00877093170John Hoford 259abb7d134c02ac60091108c491dafb00877093170John Hoford @Override 2609453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 2619453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return super.canApplyTheme() || mVectorState != null && mVectorState.canApplyTheme(); 2629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 2639453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 2649453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette @Override 2659453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 2669453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette super.applyTheme(t); 2679453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 2689453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VectorDrawableState state = mVectorState; 269ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer path = state.mVPathRenderer; 2709453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (path != null && path.canApplyTheme()) { 2719453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.applyTheme(t); 2729453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 2739453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 2749453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 2754b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette /** @hide */ 2764b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette public static VectorDrawable create(Resources resources, int rid) { 2774b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette try { 2784b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final XmlPullParser xpp = resources.getXml(rid); 2794b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final AttributeSet attrs = Xml.asAttributeSet(xpp); 2804b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 2814b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette factory.setNamespaceAware(true); 2824b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 2834b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette final VectorDrawable drawable = new VectorDrawable(); 2844b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette drawable.inflate(resources, xpp, attrs); 2854b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 2864b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return drawable; 2874b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (XmlPullParserException e) { 2884b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 2894b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } catch (IOException e) { 2904b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette Log.e(LOGTAG, "parser error", e); 2914b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 2924b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette return null; 2934b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette } 2944b1a7c203d5e32c8b2dc7f4f54f28559ca31860aAlan Viverette 2952af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private static int applyAlpha(int color, float alpha) { 2962af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int alphaBytes = Color.alpha(color); 2972af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color &= 0x00FFFFFF; 2982af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui color |= ((int) (alphaBytes * alpha)) << 24; 2992af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return color; 3002af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 3012af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 3029cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette @Override 3039cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette public void inflate(Resources res, XmlPullParser parser, AttributeSet attrs, Theme theme) 3049cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette throws XmlPullParserException, IOException { 3058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final TypedArray a = obtainAttributes(res, theme, attrs, R.styleable.VectorDrawable); 3069cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette updateStateFromTypedArray(a); 3079cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette a.recycle(); 3089cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3099cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 31055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui inflateInternal(res, parser, attrs, theme); 3119cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3129cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 3139cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mVPathRenderer.setColorFilter(mTintFilter); 3149cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3159cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3169cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 3179cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final VectorDrawableState state = mVectorState; 3189cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 3208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 3218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 3229cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette // Extract the theme attributes, if any. 3239cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 3249cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3259cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1); 3269cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tintMode != -1) { 3279cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN); 3289cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3299cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 3309cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint); 3319cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette if (tint != null) { 3329cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette state.mTint = tint; 3339cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3349cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette } 3359cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette 33655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private void inflateInternal(Resources res, XmlPullParser parser, AttributeSet attrs, 3378e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette Theme theme) throws XmlPullParserException, IOException { 3388e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final VectorDrawableState state = mVectorState; 339ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui final VPathRenderer pathRenderer = new VPathRenderer(); 34055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui state.mVPathRenderer = pathRenderer; 3419453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 342abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noSizeTag = true; 343abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noViewportTag = true; 344abb7d134c02ac60091108c491dafb00877093170John Hoford boolean noPathTag = true; 3459453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3464d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Use a stack to help to build the group tree. 3474d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The top of the stack is always the current group. 3484d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final Stack<VGroup> groupStack = new Stack<VGroup>(); 3494d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(pathRenderer.mRootGroup); 350abb7d134c02ac60091108c491dafb00877093170John Hoford 351abb7d134c02ac60091108c491dafb00877093170John Hoford int eventType = parser.getEventType(); 352abb7d134c02ac60091108c491dafb00877093170John Hoford while (eventType != XmlPullParser.END_DOCUMENT) { 353abb7d134c02ac60091108c491dafb00877093170John Hoford if (eventType == XmlPullParser.START_TAG) { 3549453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final String tagName = parser.getName(); 3554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final VGroup currentGroup = groupStack.peek(); 3564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 357abb7d134c02ac60091108c491dafb00877093170John Hoford if (SHAPE_PATH.equals(tagName)) { 3589453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final VPath path = new VPath(); 3599453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette path.inflate(res, attrs, theme); 3608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(path); 361e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (path.getPathName() != null) { 36255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(path.getPathName(), path); 363e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 364abb7d134c02ac60091108c491dafb00877093170John Hoford noPathTag = false; 3658e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= path.mChangingConfigurations; 366abb7d134c02ac60091108c491dafb00877093170John Hoford } else if (SHAPE_SIZE.equals(tagName)) { 367ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui pathRenderer.parseSize(res, attrs); 368abb7d134c02ac60091108c491dafb00877093170John Hoford noSizeTag = false; 3698e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; 370abb7d134c02ac60091108c491dafb00877093170John Hoford } else if (SHAPE_VIEWPORT.equals(tagName)) { 371ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui pathRenderer.parseViewport(res, attrs); 372abb7d134c02ac60091108c491dafb00877093170John Hoford noViewportTag = false; 3738e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= pathRenderer.mChangingConfigurations; 3746d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } else if (SHAPE_GROUP.equals(tagName)) { 3754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui VGroup newChildGroup = new VGroup(); 3764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui newChildGroup.inflate(res, attrs, theme); 3778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui currentGroup.mChildren.add(newChildGroup); 3784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.push(newChildGroup); 379e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (newChildGroup.getGroupName() != null) { 38055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui pathRenderer.mVGTargetsMap.put(newChildGroup.getGroupName(), 38155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui newChildGroup); 382e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 3838e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= newChildGroup.mChangingConfigurations; 384abb7d134c02ac60091108c491dafb00877093170John Hoford } 3854d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } else if (eventType == XmlPullParser.END_TAG) { 3864d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui final String tagName = parser.getName(); 3874d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (SHAPE_GROUP.equals(tagName)) { 3884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui groupStack.pop(); 3894d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 390abb7d134c02ac60091108c491dafb00877093170John Hoford } 391abb7d134c02ac60091108c491dafb00877093170John Hoford eventType = parser.next(); 392abb7d134c02ac60091108c491dafb00877093170John Hoford } 3939453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 3944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the tree out for debug. 3954d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui if (DBG_VECTOR_DRAWABLE) { 3964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui printGroupTree(pathRenderer.mRootGroup, 0); 3976d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui } 3986d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 39946e546c28fd52b4dedf0a0fbd313db589cb9048bztenghui if (noSizeTag || noViewportTag || noPathTag) { 4009453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final StringBuffer tag = new StringBuffer(); 4019453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 402abb7d134c02ac60091108c491dafb00877093170John Hoford if (noSizeTag) { 4039453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_SIZE); 404abb7d134c02ac60091108c491dafb00877093170John Hoford } 4059453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 406d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (noViewportTag) { 407d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (tag.length() > 0) { 408abb7d134c02ac60091108c491dafb00877093170John Hoford tag.append(" & "); 409abb7d134c02ac60091108c491dafb00877093170John Hoford } 4109453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_SIZE); 411abb7d134c02ac60091108c491dafb00877093170John Hoford } 4129453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 413d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (noPathTag) { 414d20974bd51852c71114b6e0e4ffdc3613a4d90aaAlan Viverette if (tag.length() > 0) { 415abb7d134c02ac60091108c491dafb00877093170John Hoford tag.append(" or "); 416abb7d134c02ac60091108c491dafb00877093170John Hoford } 4179453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette tag.append(SHAPE_PATH); 418abb7d134c02ac60091108c491dafb00877093170John Hoford } 4199453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 4209453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette throw new XmlPullParserException("no " + tag + " defined"); 421abb7d134c02ac60091108c491dafb00877093170John Hoford } 422abb7d134c02ac60091108c491dafb00877093170John Hoford } 423abb7d134c02ac60091108c491dafb00877093170John Hoford 4244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void printGroupTree(VGroup currentGroup, int level) { 4254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui String indent = ""; 4268d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < level; i++) { 4274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui indent += " "; 4284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Print the current node 4308d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "current group is :" + currentGroup.getGroupName() 4314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui + " rotation is " + currentGroup.mRotate); 4328d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Log.v(LOGTAG, indent + "matrix is :" + currentGroup.getLocalMatrix().toString()); 4338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Then print all the children groups 4348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 4358d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 4368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 4378d0d24f7a2b1a59060aa18926984491691d3c667ztenghui printGroupTree((VGroup) child, level + 1); 4388d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 4394d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 4414d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 44255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui @Override 44355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public int getChangingConfigurations() { 44455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return super.getChangingConfigurations() | mVectorState.mChangingConfigurations; 44555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 44655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 4475c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette private static class VectorDrawableState extends ConstantState { 4489cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette int[] mThemeAttrs; 4495c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette int mChangingConfigurations; 450ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui VPathRenderer mVPathRenderer; 451b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette ColorStateList mTint; 452b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette Mode mTintMode; 4535c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 45455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Deep copy for mutate() or implicitly mutate. 4555c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public VectorDrawableState(VectorDrawableState copy) { 4565c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette if (copy != null) { 4579cd14fc710cf81cc6d1c47d599abe349d3aa87dcAlan Viverette mThemeAttrs = copy.mThemeAttrs; 4585c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 459ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui mVPathRenderer = new VPathRenderer(copy.mVPathRenderer); 460b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTint = copy.mTint; 461b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mTintMode = copy.mTintMode; 4625c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 4635c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 4645c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 46555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VectorDrawableState() { 46655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mVPathRenderer = new VPathRenderer(); 46755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 46855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 4695c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 4705c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable() { 4715c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, null, null); 4725c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 4735c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 4745c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 4755c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res) { 4765c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, null); 4775c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 4785c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 4795c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 4805c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public Drawable newDrawable(Resources res, Theme theme) { 4815c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return new VectorDrawable(this, res, theme); 4825c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 4835c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 4845c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette @Override 4855c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette public int getChangingConfigurations() { 4865c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette return mChangingConfigurations; 4875c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 4885c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette } 4895c981a100ef30d2925588b69f8b9fe349ee5bfdeAlan Viverette 490ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui private static class VPathRenderer { 4914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui /* Right now the internal data structure is organized as a tree. 4924d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Each node can be a group node, or a path. 4934d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * A group node can have groups or paths as children, but a path node has 4944d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * no children. 4954d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * One example can be: 4964d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Root Group 4974d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / | \ 4984d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Group Path Group 4994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * / \ | 5004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * Path Path Path 5014d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui * 5024d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui */ 50355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables that only used temporarily inside the draw() call, so there 50455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // is no need for deep copying. 5054b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mPath = new Path(); 5064b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private final Path mRenderPath = new Path(); 5074d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private static final Matrix IDENTITY_MATRIX = new Matrix(); 50855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mFinalPathMatrix = new Matrix(); 5094b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 5104b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mStrokePaint; 5114b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette private Paint mFillPaint; 512fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette private ColorFilter mColorFilter; 513abb7d134c02ac60091108c491dafb00877093170John Hoford private PathMeasure mPathMeasure; 5144b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 51555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 51655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 5178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 51855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final VGroup mRootGroup; 5194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mBaseWidth = 0; 5204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mBaseHeight = 0; 5214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mViewportWidth = 0; 5224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private float mViewportHeight = 0; 5232af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private int mRootAlpha = 0xFF; 5249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 52555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui final ArrayMap<String, Object> mVGTargetsMap = new ArrayMap<String, Object>(); 526abb7d134c02ac60091108c491dafb00877093170John Hoford 527ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer() { 5284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mRootGroup = new VGroup(); 529abb7d134c02ac60091108c491dafb00877093170John Hoford } 5309453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5312af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public void setRootAlpha(int alpha) { 5322af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mRootAlpha = alpha; 5332af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 5342af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 5352af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui public int getRootAlpha() { 5362af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui return mRootAlpha; 5372af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui } 5382af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui 539ddbbb8ae8561c9e61becd03faa40997d76ab5a51ztenghui public VPathRenderer(VPathRenderer copy) { 54055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); 541abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseWidth = copy.mBaseWidth; 542abb7d134c02ac60091108c491dafb00877093170John Hoford mBaseHeight = copy.mBaseHeight; 543abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportWidth = copy.mViewportHeight; 544abb7d134c02ac60091108c491dafb00877093170John Hoford mViewportHeight = copy.mViewportHeight; 5458e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations = copy.mChangingConfigurations; 54655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRootAlpha = copy.mRootAlpha; 547abb7d134c02ac60091108c491dafb00877093170John Hoford } 548abb7d134c02ac60091108c491dafb00877093170John Hoford 5499453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public boolean canApplyTheme() { 5504d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // If one of the paths can apply theme, then return true; 5514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return recursiveCanApplyTheme(mRootGroup); 5524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5534d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 5544d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private boolean recursiveCanApplyTheme(VGroup currentGroup) { 5554d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, if there is one path return true, 5564d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // then we return true for the whole tree. 5578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 5588d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 5598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 5608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 5618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 5628d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 5638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme() 5648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui || recursiveCanApplyTheme(childGroup)) { 5658d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 5668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 5678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 5688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 5698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 5708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui return true; 5718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 5724d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5734d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5749453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette return false; 5759453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 5769453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 5779453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void applyTheme(Theme t) { 5784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Apply theme to every path of the tree. 5794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui recursiveApplyTheme(mRootGroup, t); 5804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 5814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 5824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void recursiveApplyTheme(VGroup currentGroup, Theme t) { 5834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // We can do a tree traverse here, apply theme to all paths which 5844d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // can apply theme. 5858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = currentGroup.mChildren; 5868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 5878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = children.get(i); 5888d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 5898d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 5908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childGroup.canApplyTheme()) { 5918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childGroup.applyTheme(t); 5928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 5938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui recursiveApplyTheme(childGroup, t); 5948d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 5958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 5968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (childPath.canApplyTheme()) { 5978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui childPath.applyTheme(t); 5988d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 5994d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 6004d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 601abb7d134c02ac60091108c491dafb00877093170John Hoford } 602abb7d134c02ac60091108c491dafb00877093170John Hoford 603fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette public void setColorFilter(ColorFilter colorFilter) { 604fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mColorFilter = colorFilter; 605fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 606fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mFillPaint != null) { 607fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mFillPaint.setColorFilter(colorFilter); 608fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 609fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 610fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mStrokePaint != null) { 611fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mStrokePaint.setColorFilter(colorFilter); 612fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 6136d9c422de5e0a3890dd723cb1b9264d4507053e9ztenghui 614fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } 615fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 6164d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix, 6172af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float currentAlpha, Canvas canvas, int w, int h) { 6184d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Calculate current group's matrix by preConcat the parent's and 6194d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // and the current one on the top of the stack. 6204d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Basically the Mfinal = Mviewport * M0 * M1 * M2; 6214d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Mi the local matrix at level i of the group tree. 6224d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.set(currentMatrix); 6234d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 6244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix); 6254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 6262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha; 6278d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 6288d0d24f7a2b1a59060aa18926984491691d3c667ztenghui // Draw the group tree in the same order as the XML file. 6298d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < currentGroup.mChildren.size(); i++) { 6308d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object child = currentGroup.mChildren.get(i); 6318d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (child instanceof VGroup) { 6328d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup childGroup = (VGroup) child; 6338d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawGroupTree(childGroup, currentGroup.mStackedMatrix, 6348d0d24f7a2b1a59060aa18926984491691d3c667ztenghui stackedAlpha, canvas, w, h); 6358d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (child instanceof VPath) { 6368d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath childPath = (VPath) child; 6378d0d24f7a2b1a59060aa18926984491691d3c667ztenghui drawPath(currentGroup, childPath, stackedAlpha, canvas, w, h); 6388d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 639abb7d134c02ac60091108c491dafb00877093170John Hoford } 6404d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 641abb7d134c02ac60091108c491dafb00877093170John Hoford 6424d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public void draw(Canvas canvas, int w, int h) { 6434d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // Travese the tree in pre-order to draw. 6442af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF, canvas, w, h); 645abb7d134c02ac60091108c491dafb00877093170John Hoford } 646abb7d134c02ac60091108c491dafb00877093170John Hoford 6478d0d24f7a2b1a59060aa18926984491691d3c667ztenghui private void drawPath(VGroup vGroup, VPath vPath, float stackedAlpha, 6488d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Canvas canvas, int w, int h) { 6499453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final float scale = Math.min(h / mViewportHeight, w / mViewportWidth); 650abb7d134c02ac60091108c491dafb00877093170John Hoford 6514d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.set(vGroup.mStackedMatrix); 6524d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mFinalPathMatrix.postScale(scale, scale, mViewportWidth / 2f, mViewportHeight / 2f); 6538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mFinalPathMatrix.postTranslate( 6548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette w / 2f - mViewportWidth / 2f, h / 2f - mViewportHeight / 2f); 655abb7d134c02ac60091108c491dafb00877093170John Hoford 6568d0d24f7a2b1a59060aa18926984491691d3c667ztenghui vPath.toPath(mPath); 6578d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Path path = mPath; 658abb7d134c02ac60091108c491dafb00877093170John Hoford 6598d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mTrimPathStart != 0.0f || vPath.mTrimPathEnd != 1.0f) { 6608d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float start = (vPath.mTrimPathStart + vPath.mTrimPathOffset) % 1.0f; 6618d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float end = (vPath.mTrimPathEnd + vPath.mTrimPathOffset) % 1.0f; 6629453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 6638d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mPathMeasure == null) { 6648d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure = new PathMeasure(); 6654b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette } 6668d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.setPath(mPath, false); 6678d0d24f7a2b1a59060aa18926984491691d3c667ztenghui 6688d0d24f7a2b1a59060aa18926984491691d3c667ztenghui float len = mPathMeasure.getLength(); 6698d0d24f7a2b1a59060aa18926984491691d3c667ztenghui start = start * len; 6708d0d24f7a2b1a59060aa18926984491691d3c667ztenghui end = end * len; 6718d0d24f7a2b1a59060aa18926984491691d3c667ztenghui path.reset(); 6728d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (start > end) { 6738d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(start, len, path, true); 6748d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(0f, end, path, true); 6758d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 6768d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mPathMeasure.getSegment(start, end, path, true); 6778d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui path.rLineTo(0, 0); // fix bug in measure 6798d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 6804b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 6818d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.reset(); 6829453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 6838d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mRenderPath.addPath(path, mFinalPathMatrix); 6844b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 6858d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mClip) { 6868d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.clipPath(mRenderPath, Region.Op.REPLACE); 6878d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else { 6888d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mFillColor != 0) { 6898d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mFillPaint == null) { 6908d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint = new Paint(); 6918d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColorFilter(mColorFilter); 6928d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setStyle(Paint.Style.FILL); 6938d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setAntiAlias(true); 69463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 6958d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mFillPaint.setColor(applyAlpha(vPath.mFillColor, stackedAlpha)); 6968d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, mFillPaint); 6978d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 69863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 6998d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeColor != 0) { 7008d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (mStrokePaint == null) { 7018d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint = new Paint(); 7028d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setColorFilter(mColorFilter); 7038d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setStyle(Paint.Style.STROKE); 7048d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mStrokePaint.setAntiAlias(true); 7058d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 7064b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 7078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final Paint strokePaint = mStrokePaint; 7088d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeLineJoin != null) { 7098d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeJoin(vPath.mStrokeLineJoin); 7108d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 711abb7d134c02ac60091108c491dafb00877093170John Hoford 7128d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (vPath.mStrokeLineCap != null) { 7138d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeCap(vPath.mStrokeLineCap); 7148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 71563cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 7168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeMiter(vPath.mStrokeMiterlimit * scale); 71763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 7188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setColor(applyAlpha(vPath.mStrokeColor, stackedAlpha)); 7198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui strokePaint.setStrokeWidth(vPath.mStrokeWidth * scale); 7208d0d24f7a2b1a59060aa18926984491691d3c667ztenghui canvas.drawPath(mRenderPath, strokePaint); 72163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 722abb7d134c02ac60091108c491dafb00877093170John Hoford } 723abb7d134c02ac60091108c491dafb00877093170John Hoford } 724abb7d134c02ac60091108c491dafb00877093170John Hoford 725abb7d134c02ac60091108c491dafb00877093170John Hoford private void parseViewport(Resources r, AttributeSet attrs) 726abb7d134c02ac60091108c491dafb00877093170John Hoford throws XmlPullParserException { 7274b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableViewport); 7288e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 7298e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 7308e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 7318e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 7328e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mViewportWidth = a.getFloat( 7338e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableViewport_viewportWidth, mViewportWidth); 7348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mViewportHeight = a.getFloat( 7358e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableViewport_viewportHeight, mViewportHeight); 736fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 737fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mViewportWidth <= 0) { 738fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 739fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<viewport> tag requires viewportWidth > 0"); 740fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } else if (mViewportHeight <= 0) { 741fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 742fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<viewport> tag requires viewportHeight > 0"); 743abb7d134c02ac60091108c491dafb00877093170John Hoford } 744fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 745abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 746abb7d134c02ac60091108c491dafb00877093170John Hoford } 747abb7d134c02ac60091108c491dafb00877093170John Hoford 748abb7d134c02ac60091108c491dafb00877093170John Hoford private void parseSize(Resources r, AttributeSet attrs) 7498d0d24f7a2b1a59060aa18926984491691d3c667ztenghui throws XmlPullParserException { 7504b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette final TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawableSize); 7518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 7528e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 7538e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 7548e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 755fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mBaseWidth = a.getDimension(R.styleable.VectorDrawableSize_width, mBaseWidth); 756fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette mBaseHeight = a.getDimension(R.styleable.VectorDrawableSize_height, mBaseHeight); 757fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 758fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette if (mBaseWidth <= 0) { 759fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 760fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<size> tag requires width > 0"); 761fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette } else if (mBaseHeight <= 0) { 762fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette throw new XmlPullParserException(a.getPositionDescription() + 763fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette "<size> tag requires height > 0"); 764abb7d134c02ac60091108c491dafb00877093170John Hoford } 765fd6e411767735478ee0f69ba01d77def4c6b2627Alan Viverette 766abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 767abb7d134c02ac60091108c491dafb00877093170John Hoford } 7684b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette 769abb7d134c02ac60091108c491dafb00877093170John Hoford } 770abb7d134c02ac60091108c491dafb00877093170John Hoford 771e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui static class VGroup { 77255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mStackedMatrix is only used temporarily when drawing, it combines all 77355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // the parents' local matrices with the current one. 77455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private final Matrix mStackedMatrix = new Matrix(); 77555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 77655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 77755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 7788d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> mChildren = new ArrayList<Object>(); 779abb7d134c02ac60091108c491dafb00877093170John Hoford 78063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mRotate = 0; 78163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotX = 0; 78263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private float mPivotY = 0; 783452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleX = 1; 784452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mScaleY = 1; 785452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateX = 0; 786452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui private float mTranslateY = 0; 7872af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui private float mGroupAlpha = 1; 7884d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 78955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // mLocalMatrix is updated based on the update of transformation information, 79055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // either parsed from the XML or by animation. 7914d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private final Matrix mLocalMatrix = new Matrix(); 7928e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private int mChangingConfigurations; 79363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui private int[] mThemeAttrs; 794e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui private String mGroupName = null; 795e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 79655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup(VGroup copy, ArrayMap<String, Object> targetsMap) { 79755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mRotate = copy.mRotate; 79855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotX = copy.mPivotX; 79955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPivotY = copy.mPivotY; 80055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleX = copy.mScaleX; 80155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mScaleY = copy.mScaleY; 80255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateX = copy.mTranslateX; 80355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTranslateY = copy.mTranslateY; 80455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupAlpha = copy.mGroupAlpha; 80555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 80655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mGroupName = copy.mGroupName; 80755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 80855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mGroupName != null) { 80955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui targetsMap.put(mGroupName, this); 81055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 81155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 81255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mLocalMatrix.set(copy.mLocalMatrix); 81355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 8148d0d24f7a2b1a59060aa18926984491691d3c667ztenghui final ArrayList<Object> children = copy.mChildren; 8158d0d24f7a2b1a59060aa18926984491691d3c667ztenghui for (int i = 0; i < children.size(); i++) { 8168d0d24f7a2b1a59060aa18926984491691d3c667ztenghui Object copyChild = children.get(i); 8178d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (copyChild instanceof VGroup) { 8188d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VGroup copyGroup = (VGroup) copyChild; 8198d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(new VGroup(copyGroup, targetsMap)); 8208d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } else if (copyChild instanceof VPath) { 8218d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath copyPath = (VPath) copyChild; 8228d0d24f7a2b1a59060aa18926984491691d3c667ztenghui VPath newPath = new VPath(copyPath); 8238d0d24f7a2b1a59060aa18926984491691d3c667ztenghui mChildren.add(newPath); 8248d0d24f7a2b1a59060aa18926984491691d3c667ztenghui if (newPath.mPathName != null) { 8258d0d24f7a2b1a59060aa18926984491691d3c667ztenghui targetsMap.put(newPath.mPathName, newPath); 8268d0d24f7a2b1a59060aa18926984491691d3c667ztenghui } 82755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 82855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 82955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 83055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 83155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VGroup() { 83255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 83355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 834e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui /* Getter and Setter */ 835e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getRotation() { 836e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mRotate; 837e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 838e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 839e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setRotation(float rotation) { 840e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (rotation != mRotate) { 841e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mRotate = rotation; 842e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 843e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 844e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 845e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 846e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotX() { 847e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotX; 848e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 849e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 850e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotX(float pivotX) { 851e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotX != mPivotX) { 852e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotX = pivotX; 853e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 854e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 855e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 856e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 857e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getPivotY() { 858e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPivotY; 859e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 860e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 861e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setPivotY(float pivotY) { 862e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (pivotY != mPivotY) { 863e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mPivotY = pivotY; 864e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 865e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 866e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 867e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 868e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleX() { 869e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleX; 870e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 8714d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 872e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleX(float scaleX) { 873e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleX != mScaleX) { 874e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleX = scaleX; 875e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 876e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 877e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 878e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 879e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getScaleY() { 880e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mScaleY; 881e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 882e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 883e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setScaleY(float scaleY) { 884e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (scaleY != mScaleY) { 885e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mScaleY = scaleY; 886e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 887e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 888e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 889e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 890e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateX() { 891e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateX; 892e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 893e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 894e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateX(float translateX) { 895e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateX != mTranslateX) { 896e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateX = translateX; 897e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 898e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 899e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 900e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 901e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getTranslateY() { 902e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTranslateY; 903e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 904e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 905e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setTranslateY(float translateY) { 906e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (translateY != mTranslateY) { 907e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTranslateY = translateY; 908e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui updateLocalMatrix(); 909e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 910e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 911e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 912e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public float getAlpha() { 913e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mGroupAlpha; 914e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 915e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 916e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public void setAlpha(float groupAlpha) { 917e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui if (groupAlpha != mGroupAlpha) { 918e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mGroupAlpha = groupAlpha; 919e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 920e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 921e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 922e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public String getGroupName() { 923e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mGroupName; 9244d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 9254d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9264d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public Matrix getLocalMatrix() { 9274d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return mLocalMatrix; 9284d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 9294d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9304d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui public boolean canApplyTheme() { 9314d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui return mThemeAttrs != null; 9324d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 9334d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void inflate(Resources res, AttributeSet attrs, Theme theme) { 9358e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = obtainAttributes(res, theme, attrs, 9368e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawableGroup); 9378e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 9388e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette a.recycle(); 9398e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 9408e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 9418e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 9428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 9438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 94463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 9458e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 9468e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mThemeAttrs = a.extractThemeAttrs(); 94763cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 94863cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mRotate = a.getFloat(R.styleable.VectorDrawableGroup_rotation, mRotate); 94963cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mPivotX = a.getFloat(R.styleable.VectorDrawableGroup_pivotX, mPivotX); 95063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui mPivotY = a.getFloat(R.styleable.VectorDrawableGroup_pivotY, mPivotY); 951452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mScaleX = a.getFloat(R.styleable.VectorDrawableGroup_scaleX, mScaleX); 952452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY); 953452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX); 954452f6ece7fe2fd1a85fca53f54e90bf041083b21ztenghui mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY); 9552af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha); 95663cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 9578e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final String groupName = a.getString(R.styleable.VectorDrawableGroup_name); 9588e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (groupName != null) { 9598e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mGroupName = groupName; 96063cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 96163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 9628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateLocalMatrix(); 9638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 9644d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9658e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void applyTheme(Theme t) { 9668e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (mThemeAttrs == null) { 9678e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return; 9684d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 9694d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui 9708e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 9718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 97263cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 97363cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui } 97463cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui 9754d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui private void updateLocalMatrix() { 9764d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // The order we apply is the same as the 9774d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui // RenderNode.cpp::applyViewPropertyTransforms(). 9784d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.reset(); 9794d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postTranslate(-mPivotX, -mPivotY); 9804d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postScale(mScaleX, mScaleY); 9814d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postRotate(mRotate, 0, 0); 9824d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY); 9834d24caf1dec2babf273b18c99638fe2a0635ced4ztenghui } 984abb7d134c02ac60091108c491dafb00877093170John Hoford } 985abb7d134c02ac60091108c491dafb00877093170John Hoford 986cf4832f69c8786b098ce18c24319021f8cd6733aztenghui private static class VPath { 98755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui ///////////////////////////////////////////////////// 98855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui // Variables below need to be copied (deep copy if applicable) for mutation. 9899453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private int[] mThemeAttrs; 9909453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 991abb7d134c02ac60091108c491dafb00877093170John Hoford int mStrokeColor = 0; 992abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeWidth = 0; 993abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeOpacity = Float.NaN; 9942af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui int mFillColor = Color.BLACK; 995abb7d134c02ac60091108c491dafb00877093170John Hoford int mFillRule; 996abb7d134c02ac60091108c491dafb00877093170John Hoford float mFillOpacity = Float.NaN; 997abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathStart = 0; 998abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathEnd = 1; 999abb7d134c02ac60091108c491dafb00877093170John Hoford float mTrimPathOffset = 0; 10009453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 1001abb7d134c02ac60091108c491dafb00877093170John Hoford boolean mClip = false; 10024b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Cap mStrokeLineCap = Paint.Cap.BUTT; 10034b3988d159e1c9faa2a7e16c9aca9951264bb429Alan Viverette Paint.Join mStrokeLineJoin = Paint.Join.MITER; 1004abb7d134c02ac60091108c491dafb00877093170John Hoford float mStrokeMiterlimit = 4; 10059453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 100655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private PathParser.PathDataNode[] mNodes = null; 10078d0d24f7a2b1a59060aa18926984491691d3c667ztenghui String mPathName; 100855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui private int mChangingConfigurations; 1009abb7d134c02ac60091108c491dafb00877093170John Hoford 10109453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public VPath() { 10119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette // Empty constructor. 10129453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 10139453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 101455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public VPath(VPath copy) { 101555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mThemeAttrs = copy.mThemeAttrs; 101655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 101755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeColor = copy.mStrokeColor; 101855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeWidth = copy.mStrokeWidth; 101955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeOpacity = copy.mStrokeOpacity; 102055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillColor = copy.mFillColor; 102155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillRule = copy.mFillRule; 102255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mFillOpacity = copy.mFillOpacity; 102355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathStart = copy.mTrimPathStart; 102455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathEnd = copy.mTrimPathEnd; 102555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mTrimPathOffset = copy.mTrimPathOffset; 102655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 102755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mClip = copy.mClip; 102855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineCap = copy.mStrokeLineCap; 102955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeLineJoin = copy.mStrokeLineJoin; 103055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mStrokeMiterlimit = copy.mStrokeMiterlimit; 103155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 103255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.deepCopyNodes(copy.mNodes); 103355f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mPathName = copy.mPathName; 103455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mChangingConfigurations = copy.mChangingConfigurations; 103555f765441c6cec6b2990de12f68d1c4ac444d35cztenghui } 103655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 1037abb7d134c02ac60091108c491dafb00877093170John Hoford public void toPath(Path path) { 1038abb7d134c02ac60091108c491dafb00877093170John Hoford path.reset(); 103955f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (mNodes != null) { 104055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui PathParser.PathDataNode.nodesToPath(mNodes, path); 1041abb7d134c02ac60091108c491dafb00877093170John Hoford } 1042abb7d134c02ac60091108c491dafb00877093170John Hoford } 1043abb7d134c02ac60091108c491dafb00877093170John Hoford 1044e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui public String getPathName() { 1045e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mPathName; 1046abb7d134c02ac60091108c491dafb00877093170John Hoford } 1047abb7d134c02ac60091108c491dafb00877093170John Hoford 10487f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Cap getStrokeLineCap(int id, Paint.Cap defValue) { 10497f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 10507f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_BUTT: 10517f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.BUTT; 10527f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_ROUND: 10537f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.ROUND; 10547f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINECAP_SQUARE: 10557f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Cap.SQUARE; 10567f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 10577f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 10587f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 10597f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 10607f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 10617f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette private Paint.Join getStrokeLineJoin(int id, Paint.Join defValue) { 10627f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette switch (id) { 10637f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_MITER: 10647f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.MITER; 10657f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_ROUND: 10667f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.ROUND; 10677f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette case LINEJOIN_BEVEL: 10687f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return Paint.Join.BEVEL; 10697f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette default: 10707f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette return defValue; 10717f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 10727f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette } 10737f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette 1074eb034fbca40006c55db143047eb628c4b657730aztenghui /* Setters and Getters, mostly used by animator from AnimatedVectorDrawable. */ 1075eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1076eb034fbca40006c55db143047eb628c4b657730aztenghui public PathParser.PathDataNode[] getPathData() { 107755f765441c6cec6b2990de12f68d1c4ac444d35cztenghui return mNodes; 1078eb034fbca40006c55db143047eb628c4b657730aztenghui } 1079eb034fbca40006c55db143047eb628c4b657730aztenghui 1080eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 108155f765441c6cec6b2990de12f68d1c4ac444d35cztenghui public void setPathData(PathParser.PathDataNode[] nodes) { 108255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui if (!PathParser.canMorph(mNodes, nodes)) { 1083eb034fbca40006c55db143047eb628c4b657730aztenghui // This should not happen in the middle of animation. 108455f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.deepCopyNodes(nodes); 1085eb034fbca40006c55db143047eb628c4b657730aztenghui } else { 108655f765441c6cec6b2990de12f68d1c4ac444d35cztenghui PathParser.updateNodes(mNodes, nodes); 1087eb034fbca40006c55db143047eb628c4b657730aztenghui } 1088eb034fbca40006c55db143047eb628c4b657730aztenghui } 1089eb034fbca40006c55db143047eb628c4b657730aztenghui 1090eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1091e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getStroke() { 1092e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeColor; 1093e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1094e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1095eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1096e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStroke(int strokeColor) { 1097e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeColor = strokeColor; 1098e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1099e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1100eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1101e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeWidth() { 1102e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeWidth; 1103e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1104e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1105eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1106e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeWidth(float strokeWidth) { 1107e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeWidth = strokeWidth; 1108e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1109e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1110eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1111e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getStrokeOpacity() { 1112e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mStrokeOpacity; 1113e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1114e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1115eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1116e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setStrokeOpacity(float strokeOpacity) { 1117e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mStrokeOpacity = strokeOpacity; 1118e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1119e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1120eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1121e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui int getFill() { 1122e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillColor; 1123e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1124e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1125eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1126e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFill(int fillColor) { 1127e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillColor = fillColor; 1128e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1129e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1130eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1131e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getFillOpacity() { 1132e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mFillOpacity; 1133e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1134e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1135eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1136e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setFillOpacity(float fillOpacity) { 1137e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mFillOpacity = fillOpacity; 1138e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1139e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1140eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1141e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathStart() { 1142e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathStart; 1143e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1144e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1145eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1146e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathStart(float trimPathStart) { 1147e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathStart = trimPathStart; 1148e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1149e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1150eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1151e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathEnd() { 1152e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathEnd; 1153e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1154e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1155eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1156e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathEnd(float trimPathEnd) { 1157e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathEnd = trimPathEnd; 1158e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1159e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1160eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1161e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui float getTrimPathOffset() { 1162e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui return mTrimPathOffset; 1163e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1164e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 1165eb034fbca40006c55db143047eb628c4b657730aztenghui @SuppressWarnings("unused") 1166e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui void setTrimPathOffset(float trimPathOffset) { 1167e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui mTrimPathOffset = trimPathOffset; 1168e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui } 1169e5e92602a41a4ddc7b42cd1c171a0edfbd09b8daztenghui 11708e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public boolean canApplyTheme() { 11718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return mThemeAttrs != null; 11728e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 11738e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 11749453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette public void inflate(Resources r, AttributeSet attrs, Theme theme) { 11759453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.VectorDrawablePath); 11768e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 1177abb7d134c02ac60091108c491dafb00877093170John Hoford a.recycle(); 1178abb7d134c02ac60091108c491dafb00877093170John Hoford } 1179abb7d134c02ac60091108c491dafb00877093170John Hoford 11808e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette private void updateStateFromTypedArray(TypedArray a) { 11818e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 11828e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 11839453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 11848e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 11858e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mThemeAttrs = a.extractThemeAttrs(); 11869453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 11877f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mClip = a.getBoolean(R.styleable.VectorDrawablePath_clipToPath, mClip); 118855f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 11898e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette mPathName = a.getString(R.styleable.VectorDrawablePath_name); 119055f765441c6cec6b2990de12f68d1c4ac444d35cztenghui mNodes = PathParser.createNodesFromPathData(a.getString( 11918e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette R.styleable.VectorDrawablePath_pathData)); 119255f765441c6cec6b2990de12f68d1c4ac444d35cztenghui 11937f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mFillColor = a.getColor(R.styleable.VectorDrawablePath_fill, mFillColor); 11947f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mFillOpacity = a.getFloat(R.styleable.VectorDrawablePath_fillOpacity, mFillOpacity); 11957f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeLineCap = getStrokeLineCap(a.getInt( 11967f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap); 11977f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeLineJoin = getStrokeLineJoin(a.getInt( 11987f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeLineJoin, -1), mStrokeLineJoin); 11997f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeMiterlimit = a.getFloat( 12007f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit); 12017f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_stroke, mStrokeColor); 12027f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeOpacity = a.getFloat( 12037f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_strokeOpacity, mStrokeOpacity); 12047f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, mStrokeWidth); 12057f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd, mTrimPathEnd); 12067f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathOffset = a.getFloat( 12077f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_trimPathOffset, mTrimPathOffset); 12087f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette mTrimPathStart = a.getFloat( 12097f1ab7a43fd7e65bbd7460334014ecc73dbb1b8dAlan Viverette R.styleable.VectorDrawablePath_trimPathStart, mTrimPathStart); 12109453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12119453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette updateColorAlphas(); 12128e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12138e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 12148e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette public void applyTheme(Theme t) { 12158e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette if (mThemeAttrs == null) { 12168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette return; 12178e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette } 12188e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 12198e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath); 12208e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette updateStateFromTypedArray(a); 122163cfd85bcce488a3f3952bd1db523a727d30ca39ztenghui a.recycle(); 12229453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 12239453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12249453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette private void updateColorAlphas() { 12259453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (!Float.isNaN(mFillOpacity)) { 12262af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mFillColor = applyAlpha(mFillColor, mFillOpacity); 12279453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 12289453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette 12299453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette if (!Float.isNaN(mStrokeOpacity)) { 12302af745b56cf4bdfdd9c05d90a4ccc740bf77a4feztenghui mStrokeColor = applyAlpha(mStrokeColor, mStrokeOpacity); 12319453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 12329453b7cfd4bbb35467bd7f947f850bd154982fceAlan Viverette } 1233abb7d134c02ac60091108c491dafb00877093170John Hoford } 1234abb7d134c02ac60091108c491dafb00877093170John Hoford} 1235