Add fillType support to VectorDrawable
Default as non-zero, which is the same as SVG. b/27533958 Change-Id: Id20e6d3493bb4d2b4b65d7f6cdb13586631c40e4
This commit is contained in:
@@ -559,6 +559,7 @@ package android {
|
||||
field public static final int fillBefore = 16843196; // 0x10101bc
|
||||
field public static final int fillColor = 16843780; // 0x1010404
|
||||
field public static final int fillEnabled = 16843343; // 0x101024f
|
||||
field public static final int fillType = 16844064; // 0x1010520
|
||||
field public static final int fillViewport = 16843130; // 0x101017a
|
||||
field public static final int filter = 16843035; // 0x101011b
|
||||
field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4
|
||||
|
||||
@@ -654,6 +654,7 @@ package android {
|
||||
field public static final int fillBefore = 16843196; // 0x10101bc
|
||||
field public static final int fillColor = 16843780; // 0x1010404
|
||||
field public static final int fillEnabled = 16843343; // 0x101024f
|
||||
field public static final int fillType = 16844064; // 0x1010520
|
||||
field public static final int fillViewport = 16843130; // 0x101017a
|
||||
field public static final int filter = 16843035; // 0x101011b
|
||||
field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4
|
||||
|
||||
@@ -559,6 +559,7 @@ package android {
|
||||
field public static final int fillBefore = 16843196; // 0x10101bc
|
||||
field public static final int fillColor = 16843780; // 0x1010404
|
||||
field public static final int fillEnabled = 16843343; // 0x101024f
|
||||
field public static final int fillType = 16844064; // 0x1010520
|
||||
field public static final int fillViewport = 16843130; // 0x101017a
|
||||
field public static final int filter = 16843035; // 0x101011b
|
||||
field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4
|
||||
|
||||
@@ -78,11 +78,11 @@ static jlong createFullPath(JNIEnv*, jobject, jlong srcFullPathPtr) {
|
||||
static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong fullPathPtr,
|
||||
jfloat strokeWidth, jint strokeColor, jfloat strokeAlpha, jint fillColor, jfloat fillAlpha,
|
||||
jfloat trimPathStart, jfloat trimPathEnd, jfloat trimPathOffset, jfloat strokeMiterLimit,
|
||||
jint strokeLineCap, jint strokeLineJoin) {
|
||||
jint strokeLineCap, jint strokeLineJoin, jint fillType) {
|
||||
VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
|
||||
fullPath->updateProperties(strokeWidth, strokeColor, strokeAlpha, fillColor, fillAlpha,
|
||||
trimPathStart, trimPathEnd, trimPathOffset, strokeMiterLimit, strokeLineCap,
|
||||
strokeLineJoin);
|
||||
strokeLineJoin, fillType);
|
||||
}
|
||||
|
||||
static void updateFullPathFillGradient(JNIEnv*, jobject, jlong pathPtr, jlong fillGradientPtr) {
|
||||
@@ -331,7 +331,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"nDraw", "(JJJLandroid/graphics/Rect;ZZ)V", (void*)draw},
|
||||
{"nCreateFullPath", "!()J", (void*)createEmptyFullPath},
|
||||
{"nCreateFullPath", "!(J)J", (void*)createFullPath},
|
||||
{"nUpdateFullPathProperties", "!(JFIFIFFFFFII)V", (void*)updateFullPathPropertiesAndStrokeStyles},
|
||||
{"nUpdateFullPathProperties", "!(JFIFIFFFFFIII)V", (void*)updateFullPathPropertiesAndStrokeStyles},
|
||||
{"nUpdateFullPathFillGradient", "!(JJ)V", (void*)updateFullPathFillGradient},
|
||||
{"nUpdateFullPathStrokeGradient", "!(JJ)V", (void*)updateFullPathStrokeGradient},
|
||||
{"nGetFullPathProperties", "(J[BI)Z", (void*)getFullPathProperties},
|
||||
|
||||
@@ -5876,6 +5876,12 @@ i
|
||||
</attr>
|
||||
<!-- sets the Miter limit for a stroked path -->
|
||||
<attr name="strokeMiterLimit" format="float"/>
|
||||
<!-- sets the fillType for a path. It is the same as SVG's "fill-rule" properties.
|
||||
For more details, see https://www.w3.org/TR/SVG/painting.html#FillRuleProperty -->
|
||||
<attr name="fillType" format="enum">
|
||||
<enum name="nonZero" value="0"/>
|
||||
<enum name="evenOdd" value="1"/>
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Defines the clip path used in VectorDrawables. -->
|
||||
|
||||
@@ -2706,6 +2706,7 @@
|
||||
<public type="attr" name="canRecord" />
|
||||
<public type="attr" name="tunerCount" />
|
||||
<public type="attr" name="nfcAntennaPositionDrawable" />
|
||||
<public type="attr" name="fillType" />
|
||||
|
||||
<public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
|
||||
<public type="style" name="Widget.Material.SeekBar.Discrete" />
|
||||
|
||||
@@ -1281,8 +1281,10 @@ public class VectorDrawable extends Drawable {
|
||||
private static final int STROKE_LINE_CAP_INDEX = 8;
|
||||
private static final int STROKE_LINE_JOIN_INDEX = 9;
|
||||
private static final int STROKE_MITER_LIMIT_INDEX = 10;
|
||||
private static final int TOTAL_PROPERTY_COUNT = 11;
|
||||
private static final int FILL_TYPE_INDEX = 11;
|
||||
private static final int TOTAL_PROPERTY_COUNT = 12;
|
||||
|
||||
// Property map for animatable attributes.
|
||||
private final static HashMap<String, Integer> sPropertyMap
|
||||
= new HashMap<String, Integer> () {
|
||||
{
|
||||
@@ -1399,6 +1401,7 @@ public class VectorDrawable extends Drawable {
|
||||
int strokeLineCap = properties.getInt(STROKE_LINE_CAP_INDEX * 4);
|
||||
int strokeLineJoin = properties.getInt(STROKE_LINE_JOIN_INDEX * 4);
|
||||
float strokeMiterLimit = properties.getFloat(STROKE_MITER_LIMIT_INDEX * 4);
|
||||
int fillType = properties.getInt(FILL_TYPE_INDEX * 4);
|
||||
Shader fillGradient = null;
|
||||
Shader strokeGradient = null;
|
||||
// Account for any configuration changes.
|
||||
@@ -1474,10 +1477,11 @@ public class VectorDrawable extends Drawable {
|
||||
R.styleable.VectorDrawablePath_trimPathOffset, trimPathOffset);
|
||||
trimPathStart = a.getFloat(
|
||||
R.styleable.VectorDrawablePath_trimPathStart, trimPathStart);
|
||||
fillType = a.getInt(R.styleable.VectorDrawablePath_fillType, fillType);
|
||||
|
||||
nUpdateFullPathProperties(mNativePtr, strokeWidth, strokeColor, strokeAlpha,
|
||||
fillColor, fillAlpha, trimPathStart, trimPathEnd, trimPathOffset,
|
||||
strokeMiterLimit, strokeLineCap, strokeLineJoin);
|
||||
strokeMiterLimit, strokeLineCap, strokeLineJoin, fillType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1645,7 +1649,7 @@ public class VectorDrawable extends Drawable {
|
||||
private static native void nUpdateFullPathProperties(long pathPtr, float strokeWidth,
|
||||
int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart,
|
||||
float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap,
|
||||
int strokeLineJoin);
|
||||
int strokeLineJoin, int fillType);
|
||||
private static native void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr);
|
||||
private static native void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr);
|
||||
|
||||
|
||||
@@ -158,7 +158,8 @@ const SkPath& FullPath::getUpdatedPath() {
|
||||
|
||||
void FullPath::updateProperties(float strokeWidth, SkColor strokeColor, float strokeAlpha,
|
||||
SkColor fillColor, float fillAlpha, float trimPathStart, float trimPathEnd,
|
||||
float trimPathOffset, float strokeMiterLimit, int strokeLineCap, int strokeLineJoin) {
|
||||
float trimPathOffset, float strokeMiterLimit, int strokeLineCap, int strokeLineJoin,
|
||||
int fillType) {
|
||||
mProperties.strokeWidth = strokeWidth;
|
||||
mProperties.strokeColor = strokeColor;
|
||||
mProperties.strokeAlpha = strokeAlpha;
|
||||
@@ -167,6 +168,7 @@ void FullPath::updateProperties(float strokeWidth, SkColor strokeColor, float st
|
||||
mProperties.strokeMiterLimit = strokeMiterLimit;
|
||||
mProperties.strokeLineCap = strokeLineCap;
|
||||
mProperties.strokeLineJoin = strokeLineJoin;
|
||||
mProperties.fillType = fillType;
|
||||
|
||||
// If any trim property changes, mark trim dirty and update the trim path
|
||||
setTrimPathStart(trimPathStart);
|
||||
@@ -179,7 +181,7 @@ inline SkColor applyAlpha(SkColor color, float alpha) {
|
||||
return SkColorSetA(color, alphaBytes * alpha);
|
||||
}
|
||||
|
||||
void FullPath::drawPath(SkCanvas* outCanvas, const SkPath& renderPath, float strokeScale,
|
||||
void FullPath::drawPath(SkCanvas* outCanvas, SkPath& renderPath, float strokeScale,
|
||||
const SkMatrix& matrix){
|
||||
// Draw path's fill, if fill color or gradient is valid
|
||||
bool needsFill = false;
|
||||
@@ -196,6 +198,8 @@ void FullPath::drawPath(SkCanvas* outCanvas, const SkPath& renderPath, float str
|
||||
if (needsFill) {
|
||||
mPaint.setStyle(SkPaint::Style::kFill_Style);
|
||||
mPaint.setAntiAlias(true);
|
||||
SkPath::FillType ft = static_cast<SkPath::FillType>(mProperties.fillType);
|
||||
renderPath.setFillType(ft);
|
||||
outCanvas->drawPath(renderPath, mPaint);
|
||||
}
|
||||
|
||||
@@ -300,7 +304,7 @@ void FullPath::setPropertyValue(int propertyId, float value) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClipPath::drawPath(SkCanvas* outCanvas, const SkPath& renderPath,
|
||||
void ClipPath::drawPath(SkCanvas* outCanvas, SkPath& renderPath,
|
||||
float strokeScale, const SkMatrix& matrix){
|
||||
outCanvas->clipPath(renderPath, SkRegion::kIntersect_Op);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual const SkPath& getUpdatedPath();
|
||||
virtual void drawPath(SkCanvas *outCanvas, const SkPath& renderPath,
|
||||
virtual void drawPath(SkCanvas *outCanvas, SkPath& renderPath,
|
||||
float strokeScale, const SkMatrix& matrix) = 0;
|
||||
Data mData;
|
||||
SkPath mSkPath;
|
||||
@@ -118,6 +118,7 @@ struct Properties {
|
||||
int32_t strokeLineCap = SkPaint::Cap::kButt_Cap;
|
||||
int32_t strokeLineJoin = SkPaint::Join::kMiter_Join;
|
||||
float strokeMiterLimit = 4;
|
||||
int fillType = 0; /* non-zero or kWinding_FillType in Skia */
|
||||
};
|
||||
|
||||
FullPath(const FullPath& path); // for cloning
|
||||
@@ -133,7 +134,7 @@ struct Properties {
|
||||
void updateProperties(float strokeWidth, SkColor strokeColor,
|
||||
float strokeAlpha, SkColor fillColor, float fillAlpha,
|
||||
float trimPathStart, float trimPathEnd, float trimPathOffset,
|
||||
float strokeMiterLimit, int strokeLineCap, int strokeLineJoin);
|
||||
float strokeMiterLimit, int strokeLineCap, int strokeLineJoin, int fillType);
|
||||
// TODO: Cleanup: Remove the setter and getters below, and their counterparts in java and JNI
|
||||
float getStrokeWidth() {
|
||||
return mProperties.strokeWidth;
|
||||
@@ -197,7 +198,7 @@ struct Properties {
|
||||
|
||||
protected:
|
||||
const SkPath& getUpdatedPath() override;
|
||||
void drawPath(SkCanvas* outCanvas, const SkPath& renderPath,
|
||||
void drawPath(SkCanvas* outCanvas, SkPath& renderPath,
|
||||
float strokeScale, const SkMatrix& matrix) override;
|
||||
|
||||
private:
|
||||
@@ -213,6 +214,7 @@ private:
|
||||
StrokeLineCap,
|
||||
StrokeLineJoin,
|
||||
StrokeMiterLimit,
|
||||
FillType,
|
||||
Count,
|
||||
};
|
||||
// Applies trimming to the specified path.
|
||||
@@ -233,7 +235,7 @@ public:
|
||||
ClipPath(const Data& nodes) : Path(nodes) {}
|
||||
|
||||
protected:
|
||||
void drawPath(SkCanvas* outCanvas, const SkPath& renderPath,
|
||||
void drawPath(SkCanvas* outCanvas, SkPath& renderPath,
|
||||
float strokeScale, const SkMatrix& matrix) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
-->
|
||||
<vector android:height="24dp" android:viewportHeight="400.0"
|
||||
android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillType="evenOdd"
|
||||
android:fillColor="#f00"
|
||||
android:pathData="M250,75L323,301 131,161 369,161 177,301z"
|
||||
android:strokeColor="#000" android:strokeWidth="3"/>
|
||||
<path android:fillType="evenOdd"
|
||||
android:fillColor="#f00"
|
||||
android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
|
||||
android:strokeColor="#000" android:strokeWidth="3"/>
|
||||
<path android:fillType="evenOdd"
|
||||
android:fillColor="#f00"
|
||||
android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
|
||||
android:strokeColor="#000" android:strokeWidth="3"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
-->
|
||||
<vector android:height="24dp" android:viewportHeight="400.0"
|
||||
android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillType="nonZero"
|
||||
android:fillColor="#f00"
|
||||
android:pathData="M250,75L323,301 131,161 369,161 177,301z"
|
||||
android:strokeColor="#000" android:strokeWidth="3"/>
|
||||
<path android:fillType="nonZero"
|
||||
android:fillColor="#f00"
|
||||
android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
|
||||
android:strokeColor="#000" android:strokeWidth="3"/>
|
||||
<path android:fillType="nonZero"
|
||||
android:fillColor="#f00"
|
||||
android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
|
||||
android:strokeColor="#000" android:strokeWidth="3"/>
|
||||
</vector>
|
||||
@@ -35,6 +35,8 @@ import java.text.DecimalFormat;
|
||||
public class VectorDrawablePerformance extends Activity {
|
||||
private static final String LOGCAT = "VectorDrawable1";
|
||||
protected int[] icon = {
|
||||
R.drawable.vector_icon_filltype_nonzero,
|
||||
R.drawable.vector_icon_filltype_evenodd,
|
||||
R.drawable.vector_icon_gradient_1,
|
||||
R.drawable.vector_icon_gradient_2,
|
||||
R.drawable.vector_icon_gradient_3,
|
||||
|
||||
Reference in New Issue
Block a user