refactor clipPath native code

refactor clipPath native code
add strokeMiterlimit prop support
This commit is contained in:
Horcrux
2016-05-21 19:58:49 +08:00
parent bb9380b049
commit 6a0c47a898
30 changed files with 305 additions and 152 deletions
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2015-present, Horcrux.
* All rights reserved.
*
* This source code is licensed under the MIT-style license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.react.uimanager.annotations.ReactProp;
/**
* Shadow node for virtual RNSVGClipPath view
*/
public class RNSVGClipPathShadowNode extends RNSVGGroupShadowNode {
private String mName = null;
@ReactProp(name = "name")
public void setName(String name) {
mName = name;
markUpdated();
}
@Override
public void draw(Canvas canvas, Paint paint, float opacity) {
getSvgShadowNode().defineClipPath(getPath(canvas, paint), mName);
}
@Override
public int hitTest(Point point, View view) {
return -1;
}
}
@@ -17,46 +17,30 @@ import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.annotations.ReactProp;
/**
* Shadow node for virtual RNSVGGroup view
*/
public class RNSVGGroupShadowNode extends RNSVGVirtualNode {
private String mAsClipPath = null;
@ReactProp(name = "asClipPath")
public void setAsClipPath(String asClipPath) {
mAsClipPath = asClipPath;
markUpdated();
}
public void draw(Canvas canvas, Paint paint, float opacity) {
opacity *= mOpacity;
RNSVGSvgViewShadowNode svg = getSvgShadowNode();
if (mAsClipPath == null) {
if (opacity > MIN_OPACITY_FOR_DRAW) {
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
if (opacity > MIN_OPACITY_FOR_DRAW) {
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
for (int i = 0; i < getChildCount(); i++) {
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.setupDimensions(canvas);
child.draw(canvas, paint, opacity);
for (int i = 0; i < getChildCount(); i++) {
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.setupDimensions(canvas);
child.draw(canvas, paint, opacity);
if (child.isTouchable()) {
svg.enableTouchEvents();
}
if (child.isTouchable()) {
svg.enableTouchEvents();
}
restoreCanvas(canvas, count);
}
} else {
svg.defineClipPath(getPath(canvas, paint), mAsClipPath);
restoreCanvas(canvas, count);
}
}
@@ -74,11 +58,6 @@ public class RNSVGGroupShadowNode extends RNSVGVirtualNode {
@Override
public int hitTest(Point point, View view) {
if (mAsClipPath != null) {
return -1;
}
int viewTag = -1;
for (int i = getChildCount() - 1; i >= 0; i--) {
viewTag = ((RNSVGVirtualNode) getChildAt(i)).hitTest(point, ((ViewGroup) view).getChildAt(i));
@@ -51,10 +51,12 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
private static final int FILL_RULE_EVENODD = 0;
private static final int FILL_RULE_NONZERO = 1;
private @Nullable ReadableArray mStrokeColor;
private @Nullable ReadableArray mFillColor;
private @Nullable float[] mStrokeDasharray;
private float mStrokeWidth = 1;
private float mStrokeMiterlimit = 4;
private float mStrokeDashoffset = 0;
private Paint.Cap mStrokeLinecap = Paint.Cap.ROUND;
private Paint.Join mStrokeLinejoin = Paint.Join.ROUND;
@@ -126,6 +128,12 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
markUpdated();
}
@ReactProp(name = "strokeMiterlimit", defaultFloat = 4f)
public void setStrokeMiterlimit(float strokeMiterlimit) {
mStrokeMiterlimit = strokeMiterlimit;
markUpdated();
}
@ReactProp(name = "strokeLinecap", defaultInt = CAP_ROUND)
public void setStrokeLinecap(int strokeLinecap) {
switch (strokeLinecap) {
@@ -185,8 +193,8 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
}
restoreCanvas(canvas, count);
markUpdateSeen();
}
markUpdateSeen();
}
private void setupPath() {
@@ -243,6 +251,7 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(mStrokeLinecap);
paint.setStrokeJoin(mStrokeLinejoin);
paint.setStrokeMiter(mStrokeMiterlimit * mScale);
paint.setStrokeWidth(mStrokeWidth * mScale);
setupPaint(paint, opacity, mStrokeColor, box);
@@ -41,6 +41,7 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
/* package */ static final String CLASS_ELLIPSE = "RNSVGEllipse";
/* package */ static final String CLASS_LINE = "RNSVGLine";
/* package */ static final String CLASS_RECT = "RNSVGRect";
/* package */ static final String CLASS_CLIP_PATH = "RNSVGClipPath";
private final String mClassName;
@@ -78,6 +79,10 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
return new RNSVGRenderableViewManager(CLASS_RECT);
}
public static RNSVGRenderableViewManager createRNSVGClipPathViewManager() {
return new RNSVGRenderableViewManager(CLASS_CLIP_PATH);
}
private RNSVGRenderableViewManager(String className) {
mClassName = className;
}
@@ -114,6 +119,9 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
case CLASS_IMAGE:
mVirtualNode = new RNSVGImageShadowNode();
break;
case CLASS_CLIP_PATH:
mVirtualNode = new RNSVGClipPathShadowNode();
break;
default:
throw new IllegalStateException("Unexpected type " + mClassName);
}
@@ -141,6 +149,8 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
return RNSVGTextShadowNode.class;
case CLASS_IMAGE:
return RNSVGImageShadowNode.class;
case CLASS_CLIP_PATH:
return RNSVGClipPathShadowNode.class;
default:
throw new IllegalStateException("Unexpected type " + mClassName);
}
@@ -73,29 +73,27 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
public void draw(Canvas canvas, Paint paint, float opacity) {
opacity *= mOpacity;
if (opacity <= MIN_OPACITY_FOR_DRAW) {
return;
}
if (opacity > MIN_OPACITY_FOR_DRAW) {
String text = formatText();
if (text == null) {
return;
}
String text = formatText();
if (text == null) {
return;
}
// only set up the canvas if we have something to draw
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
RectF box = getBox(paint, text);
// only set up the canvas if we have something to draw
int count = saveAndSetupCanvas(canvas);
clip(canvas, paint);
RectF box = getBox(paint, text);
if (setupStrokePaint(paint, opacity, box)) {
drawText(canvas, paint, text);
}
if (setupFillPaint(paint, opacity, box)) {
drawText(canvas, paint, text);
}
if (setupStrokePaint(paint, opacity, box)) {
drawText(canvas, paint, text);
restoreCanvas(canvas, count);
markUpdateSeen();
}
if (setupFillPaint(paint, opacity, box)) {
drawText(canvas, paint, text);
}
restoreCanvas(canvas, count);
markUpdateSeen();
}
private void drawText(Canvas canvas, Paint paint, String text) {
@@ -33,6 +33,7 @@ public class RNSvgPackage implements ReactPackage {
RNSVGRenderableViewManager.createRNSVGRectViewManager(),
RNSVGRenderableViewManager.createRNSVGTextViewManager(),
RNSVGRenderableViewManager.createRNSVGImageViewManager(),
RNSVGRenderableViewManager.createRNSVGClipPathViewManager(),
new RNSVGSvgViewManager());
}