add viewBox support for android

This commit is contained in:
Horcrux
2016-07-26 11:37:31 +08:00
parent f82032c21c
commit 9888a1adf2
21 changed files with 262 additions and 76 deletions

View File

@@ -5,7 +5,8 @@ import React, {
import Svg, { import Svg, {
Symbol, Symbol,
Circle, Circle,
Use Use,
Rect
} from 'react-native-svg'; } from 'react-native-svg';
class SymbolExample extends Component{ class SymbolExample extends Component{

View File

@@ -55,14 +55,14 @@ public class RNSVGCircleShadowNode extends RNSVGPathShadowNode {
@Override @Override
protected Path getPath(Canvas canvas, Paint paint) { protected Path getPath(Canvas canvas, Paint paint) {
Path path = new Path(); Path path = new Path();
float cx = PropHelper.fromPercentageToFloat(mCx, mWidth, 0, mScale); float cx = PropHelper.fromPercentageToFloat(mCx, mCanvasWidth, 0, mScale);
float cy = PropHelper.fromPercentageToFloat(mCy, mHeight, 0, mScale); float cy = PropHelper.fromPercentageToFloat(mCy, mCanvasHeight, 0, mScale);
float r; float r;
if (PropHelper.isPercentage(mR)) { if (PropHelper.isPercentage(mR)) {
r = PropHelper.fromPercentageToFloat(mR, 1, 0, 1); r = PropHelper.fromPercentageToFloat(mR, 1, 0, 1);
float powX = (float)Math.pow((mWidth * r), 2); float powX = (float)Math.pow((mCanvasWidth * r), 2);
float powY = (float)Math.pow((mHeight * r), 2); float powY = (float)Math.pow((mCanvasHeight * r), 2);
r = (float)Math.sqrt(powX + powY) / (float)Math.sqrt(2); r = (float)Math.sqrt(powX + powY) / (float)Math.sqrt(2);
} else { } else {
r = Float.parseFloat(mR) * mScale; r = Float.parseFloat(mR) * mScale;

View File

@@ -63,10 +63,10 @@ public class RNSVGEllipseShadowNode extends RNSVGPathShadowNode {
@Override @Override
protected Path getPath(Canvas canvas, Paint paint) { protected Path getPath(Canvas canvas, Paint paint) {
Path path = new Path(); Path path = new Path();
float cx = PropHelper.fromPercentageToFloat(mCx, mWidth, 0, mScale); float cx = PropHelper.fromPercentageToFloat(mCx, mCanvasWidth, 0, mScale);
float cy = PropHelper.fromPercentageToFloat(mCy, mHeight, 0, mScale); float cy = PropHelper.fromPercentageToFloat(mCy, mCanvasHeight, 0, mScale);
float rx = PropHelper.fromPercentageToFloat(mRx, mWidth, 0, mScale); float rx = PropHelper.fromPercentageToFloat(mRx, mCanvasWidth, 0, mScale);
float ry = PropHelper.fromPercentageToFloat(mRy, mHeight, 0, mScale); float ry = PropHelper.fromPercentageToFloat(mRy, mCanvasHeight, 0, mScale);
RectF oval = new RectF(cx - rx, cy - ry, cx + rx, cy + ry); RectF oval = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
path.addOval(oval, Path.Direction.CW); path.addOval(oval, Path.Direction.CW);

View File

@@ -27,7 +27,6 @@ import java.util.ArrayList;
public class RNSVGGroupShadowNode extends RNSVGPathShadowNode { public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
public void draw(Canvas canvas, Paint paint, float opacity) { public void draw(Canvas canvas, Paint paint, float opacity) {
opacity *= mOpacity;
RNSVGSvgViewShadowNode svg = getSvgShadowNode(); RNSVGSvgViewShadowNode svg = getSvgShadowNode();
if (opacity > MIN_OPACITY_FOR_DRAW) { if (opacity > MIN_OPACITY_FOR_DRAW) {
@@ -36,6 +35,7 @@ public class RNSVGGroupShadowNode extends RNSVGPathShadowNode {
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i); RNSVGVirtualNode child = (RNSVGVirtualNode) getChildAt(i);
child.setupDimensions(canvas); child.setupDimensions(canvas);
child.mergeProperties(this, mPropList, true); child.mergeProperties(this, mPropList, true);
child.draw(canvas, paint, opacity * mOpacity); child.draw(canvas, paint, opacity * mOpacity);

View File

@@ -91,10 +91,10 @@ public class RNSVGImageShadowNode extends RNSVGPathShadowNode {
int count = saveAndSetupCanvas(canvas); int count = saveAndSetupCanvas(canvas);
clip(canvas, paint); clip(canvas, paint);
float x = PropHelper.fromPercentageToFloat(mX, mWidth, 0, mScale); float x = PropHelper.fromPercentageToFloat(mX, mCanvasWidth, 0, mScale);
float y = PropHelper.fromPercentageToFloat(mY, mHeight, 0, mScale); float y = PropHelper.fromPercentageToFloat(mY, mCanvasHeight, 0, mScale);
float w = PropHelper.fromPercentageToFloat(mW, mWidth, 0, mScale); float w = PropHelper.fromPercentageToFloat(mW, mCanvasWidth, 0, mScale);
float h = PropHelper.fromPercentageToFloat(mH, mHeight, 0, mScale); float h = PropHelper.fromPercentageToFloat(mH, mCanvasHeight, 0, mScale);
canvas.drawBitmap(mBitmap, null, new Rect((int) x, (int) y, (int) (x + w), (int)(y + h)), null); canvas.drawBitmap(mBitmap, null, new Rect((int) x, (int) y, (int) (x + w), (int)(y + h)), null);
restoreCanvas(canvas, count); restoreCanvas(canvas, count);

View File

@@ -68,10 +68,10 @@ public class RNSVGLineShadowNode extends RNSVGPathShadowNode {
@Override @Override
protected Path getPath(Canvas canvas, Paint paint) { protected Path getPath(Canvas canvas, Paint paint) {
Path path = new Path(); Path path = new Path();
float x1 = PropHelper.fromPercentageToFloat(mX1, mWidth, 0, mScale); float x1 = PropHelper.fromPercentageToFloat(mX1, mCanvasWidth, 0, mScale);
float y1 = PropHelper.fromPercentageToFloat(mY1, mHeight, 0, mScale); float y1 = PropHelper.fromPercentageToFloat(mY1, mCanvasHeight, 0, mScale);
float x2 = PropHelper.fromPercentageToFloat(mX2, mWidth, 0, mScale); float x2 = PropHelper.fromPercentageToFloat(mX2, mCanvasWidth, 0, mScale);
float y2 = PropHelper.fromPercentageToFloat(mY2, mHeight, 0, mScale); float y2 = PropHelper.fromPercentageToFloat(mY2, mCanvasHeight, 0, mScale);
path.moveTo(x1, y1); path.moveTo(x1, y1);
path.lineTo(x2, y2); path.lineTo(x2, y2);

View File

@@ -78,7 +78,7 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
private ArrayList<String> mChangedList; private ArrayList<String> mChangedList;
private ArrayList<Object> mOriginProperties; private ArrayList<Object> mOriginProperties;
protected ReadableArray mPropList; protected ReadableArray mPropList = new JavaOnlyArray();;
@ReactProp(name = "d") @ReactProp(name = "d")
public void setPath(@Nullable ReadableArray shapePath) { public void setPath(@Nullable ReadableArray shapePath) {
@@ -381,8 +381,8 @@ public class RNSVGPathShadowNode extends RNSVGVirtualNode {
@Override @Override
public int hitTest(Point point, View view) { public int hitTest(Point point, View view) {
Bitmap bitmap = Bitmap.createBitmap( Bitmap bitmap = Bitmap.createBitmap(
mWidth, mCanvasWidth,
mHeight, mCanvasHeight,
Bitmap.Config.ARGB_8888); Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);

View File

@@ -87,12 +87,12 @@ public class RNSVGRectShadowNode extends RNSVGPathShadowNode {
@Override @Override
protected Path getPath(Canvas canvas, Paint paint) { protected Path getPath(Canvas canvas, Paint paint) {
Path path = new Path(); Path path = new Path();
float x = PropHelper.fromPercentageToFloat(mX, mWidth, 0, mScale); float x = PropHelper.fromPercentageToFloat(mX, mCanvasWidth, 0, mScale);
float y = PropHelper.fromPercentageToFloat(mY, mHeight, 0, mScale); float y = PropHelper.fromPercentageToFloat(mY, mCanvasHeight, 0, mScale);
float w = PropHelper.fromPercentageToFloat(mW, mWidth, 0, mScale); float w = PropHelper.fromPercentageToFloat(mW, mCanvasWidth, 0, mScale);
float h = PropHelper.fromPercentageToFloat(mH, mHeight, 0, mScale); float h = PropHelper.fromPercentageToFloat(mH, mCanvasHeight, 0, mScale);
float rx = PropHelper.fromPercentageToFloat(mRx, mWidth, 0, mScale); float rx = PropHelper.fromPercentageToFloat(mRx, mCanvasWidth, 0, mScale);
float ry = PropHelper.fromPercentageToFloat(mRy, mHeight, 0, mScale); float ry = PropHelper.fromPercentageToFloat(mRy, mCanvasHeight, 0, mScale);
if (rx != 0 || ry != 0) { if (rx != 0 || ry != 0) {
if (rx == 0) { if (rx == 0) {

View File

@@ -33,6 +33,7 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
/* package */ static final String CLASS_CLIP_PATH = "RNSVGClipPath"; /* package */ static final String CLASS_CLIP_PATH = "RNSVGClipPath";
/* package */ static final String CLASS_DEFS = "RNSVGDefs"; /* package */ static final String CLASS_DEFS = "RNSVGDefs";
/* package */ static final String CLASS_USE = "RNSVGUse"; /* package */ static final String CLASS_USE = "RNSVGUse";
/* package */ static final String CLASS_VIEW_BOX = "RNSVGViewBox";
private final String mClassName; private final String mClassName;
@@ -82,6 +83,9 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
return new RNSVGRenderableViewManager(CLASS_USE); return new RNSVGRenderableViewManager(CLASS_USE);
} }
public static RNSVGRenderableViewManager createRNSVGViewBoxViewManager() {
return new RNSVGRenderableViewManager(CLASS_VIEW_BOX);
}
private RNSVGRenderableViewManager(String className) { private RNSVGRenderableViewManager(String className) {
mClassName = className; mClassName = className;
@@ -128,6 +132,9 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
case CLASS_USE: case CLASS_USE:
mVirtualNode = new RNSVGUseShadowNode(); mVirtualNode = new RNSVGUseShadowNode();
break; break;
case CLASS_VIEW_BOX:
mVirtualNode = new RNSVGViewBoxShadowNode();
break;
default: default:
throw new IllegalStateException("Unexpected type " + mClassName); throw new IllegalStateException("Unexpected type " + mClassName);
} }
@@ -161,6 +168,8 @@ public class RNSVGRenderableViewManager extends ViewGroupManager<ViewGroup> {
return RNSVGDefsShadowNode.class; return RNSVGDefsShadowNode.class;
case CLASS_USE: case CLASS_USE:
return RNSVGUseShadowNode.class; return RNSVGUseShadowNode.class;
case CLASS_VIEW_BOX:
return RNSVGViewBoxShadowNode.class;
default: default:
throw new IllegalStateException("Unexpected type " + mClassName); throw new IllegalStateException("Unexpected type " + mClassName);
} }

View File

@@ -194,8 +194,8 @@ public class RNSVGTextShadowNode extends RNSVGPathShadowNode {
@Override @Override
public int hitTest(Point point, View view) { public int hitTest(Point point, View view) {
Bitmap bitmap = Bitmap.createBitmap( Bitmap bitmap = Bitmap.createBitmap(
mWidth, mCanvasWidth,
mHeight, mCanvasHeight,
Bitmap.Config.ARGB_8888); Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);

View File

@@ -47,6 +47,14 @@ public class RNSVGUseShadowNode extends RNSVGPathShadowNode {
markUpdated(); markUpdated();
} }
public String getWidth() {
return mWidth;
}
public String getHeight() {
return mHeight;
}
@Override @Override
public void draw(Canvas canvas, Paint paint, float opacity) { public void draw(Canvas canvas, Paint paint, float opacity) {
RNSVGVirtualNode template = getSvgShadowNode().getDefinedTemplate(mHref); RNSVGVirtualNode template = getSvgShadowNode().getDefinedTemplate(mHref);

View File

@@ -0,0 +1,184 @@
/**
* 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.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Log;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.annotations.ReactProp;
/**
* Shadow node for virtual RNSVGPath view
*/
public class RNSVGViewBoxShadowNode extends RNSVGGroupShadowNode {
private static final int MOS_MEET = 0;
private static final int MOS_SLICE = 1;
private static final int MOS_NONE = 2;
private String mMinX;
private String mMinY;
private String mVbWidth;
private String mVbHeight;
private String mBoxWidth;
private String mBoxHeight;
private String mAlign;
private int mMeetOrSlice;
private boolean mFromSymbol = false;
@ReactProp(name = "minX")
public void setMinX(String minX) {
mMinX = minX;
markUpdated();
}
@ReactProp(name = "minY")
public void setMinY(String minY) {
mMinY = minY;
markUpdated();
}
@ReactProp(name = "vbWidth")
public void setVbWidth(String vbWidth) {
mVbWidth = vbWidth;
markUpdated();
}
@ReactProp(name = "vbHeight")
public void setVbHeight(String vbHeight) {
mVbHeight = vbHeight;
markUpdated();
}
@ReactProp(name = "width")
public void setWidth(String width) {
mBoxWidth = width;
markUpdated();
}
@ReactProp(name = "height")
public void setHeight(String height) {
mBoxHeight = height;
markUpdated();
}
@ReactProp(name = "align")
public void setAlign(String align) {
mAlign = align;
markUpdated();
}
@ReactProp(name = "meetOrSlice")
public void setMeetOrSlice(int meetOrSlice) {
mMeetOrSlice = meetOrSlice;
markUpdated();
}
@Override
public void draw(Canvas canvas, Paint paint, float opacity) {
// based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform
setupDimensions(canvas);
// Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the viewBox attribute respectively.
float vbX = PropHelper.fromPercentageToFloat(mMinX, mCanvasWidth, 0, mScale);
float vbY = PropHelper.fromPercentageToFloat(mMinY, mCanvasHeight, 0, mScale);
float vbWidth = PropHelper.fromPercentageToFloat(mVbWidth, mCanvasWidth, 0, mScale);
float vbHeight = PropHelper.fromPercentageToFloat(mVbHeight, mCanvasHeight, 0, mScale);
// Let e-x, e-y, e-width, e-height be the position and size of the element respectively.
float eX = mCanvasX;
float eY = mCanvasY;
float eWidth = mBoxWidth != null ? PropHelper.fromPercentageToFloat(mBoxWidth, mCanvasWidth, 0, mScale) : mCanvasWidth;
float eHeight = mBoxHeight != null ? PropHelper.fromPercentageToFloat(mBoxHeight, mCanvasHeight, 0, mScale) : mCanvasHeight;
// Initialize scale-x to e-width/vb-width.
float scaleX = eWidth / vbWidth;
// Initialize scale-y to e-height/vb-height.
float scaleY = eHeight / vbHeight;
// Initialize translate-x to vb-x - e-x.
// Initialize translate-y to vb-y - e-y.
float translateX = vbX - eX;
float translateY = vbY - eY;
// If align is 'none'
if (mMeetOrSlice == MOS_NONE) {
// Let scale be set the smaller value of scale-x and scale-y.
// Assign scale-x and scale-y to scale.
float scale = scaleX = scaleY = Math.min(scaleX, scaleY);
// If scale is greater than 1
if (scale > 1) {
// Minus translateX by (eWidth / scale - vbWidth) / 2
// Minus translateY by (eHeight / scale - vbHeight) / 2
translateX -= (eWidth / scale - vbWidth) / 2;
translateY -= (eHeight / scale - vbHeight) / 2;
} else {
translateX -= (eWidth - vbWidth * scale) / 2;
translateY -= (eHeight - vbHeight * scale) / 2;
}
} else {
// If align is not 'none' and meetOrSlice is 'meet', set the larger of scale-x and scale-y to the smaller.
// Otherwise, if align is not 'none' and meetOrSlice is 'slice', set the smaller of scale-x and scale-y to the larger.
if (!mAlign.equals("none") && mMeetOrSlice == MOS_MEET) {
scaleX = scaleY = Math.min(scaleX, scaleY);
} else if (!mAlign.equals("none") && mMeetOrSlice == MOS_SLICE) {
scaleX = scaleY = Math.min(scaleX, scaleY);
}
// If align contains 'xMid', minus (e-width / scale-x - vb-width) / 2 from transform-x.
if (mAlign.contains("xMid")) {
translateX -= (eWidth / scaleX - vbWidth) / 2;
}
// If align contains 'xMax', minus (e-width / scale-x - vb-width) from transform-x.
if (mAlign.contains("xMax")) {
translateX -= eWidth / scaleX - vbWidth;
}
// If align contains 'yMid', minus (e-height / scale-y - vb-height) / 2 from transform-y.
if (mAlign.contains("YMid")) {
translateY -= (eHeight / scaleY - vbHeight) / 2;
}
// If align contains 'yMax', minus (e-height / scale-y - vb-height) from transform-y.
if (mAlign.contains("YMax")) {
translateY -= eHeight / scaleY - vbHeight;
}
}
canvas.scale(scaleX, scaleY);
canvas.translate(-translateX * (mFromSymbol ? scaleX : 1), -translateY * (mFromSymbol ? scaleY : 1));
super.draw(canvas, paint, opacity);
}
@Override
public void mergeProperties(RNSVGVirtualNode target, ReadableArray mergeList) {
if (target.getClass() == RNSVGUseShadowNode.class) {
mFromSymbol = true;
mBoxWidth = ((RNSVGUseShadowNode)target).getWidth();
mBoxHeight = ((RNSVGUseShadowNode)target).getHeight();
}
}
@Override
public void resetProperties() {
mBoxWidth = mBoxHeight = null;
mFromSymbol = false;
}
}

View File

@@ -17,6 +17,7 @@ import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Region; import android.graphics.Region;
import android.util.Log; import android.util.Log;
@@ -66,8 +67,10 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
private boolean mClipRuleSet; private boolean mClipRuleSet;
private boolean mClipDataSet; private boolean mClipDataSet;
protected boolean mResponsible; protected boolean mResponsible;
protected int mWidth; protected int mCanvasX;
protected int mHeight; protected int mCanvasY;
protected int mCanvasWidth;
protected int mCanvasHeight;
protected String mName; protected String mName;
private RNSVGSvgViewShadowNode mSvgShadowNode; private RNSVGSvgViewShadowNode mSvgShadowNode;
@@ -292,8 +295,12 @@ public abstract class RNSVGVirtualNode extends LayoutShadowNode {
} }
protected void setupDimensions(Canvas canvas) { protected void setupDimensions(Canvas canvas) {
mWidth = canvas.getWidth(); // TODO: not sure this is a right way to get canvas boundingBox
mHeight = canvas.getHeight(); Rect mCanvasClipBounds = canvas.getClipBounds();
mCanvasX = mCanvasClipBounds.left;
mCanvasY = mCanvasClipBounds.top;
mCanvasWidth = canvas.getWidth();
mCanvasHeight = canvas.getHeight();
} }
protected void saveDefinition() { protected void saveDefinition() {

View File

@@ -36,6 +36,7 @@ public class RNSvgPackage implements ReactPackage {
RNSVGRenderableViewManager.createRNSVGClipPathViewManager(), RNSVGRenderableViewManager.createRNSVGClipPathViewManager(),
RNSVGRenderableViewManager.createRNSVGDefsViewManager(), RNSVGRenderableViewManager.createRNSVGDefsViewManager(),
RNSVGRenderableViewManager.createRNSVGUseViewManager(), RNSVGRenderableViewManager.createRNSVGUseViewManager(),
RNSVGRenderableViewManager.createRNSVGViewBoxViewManager(),
new RNSVGSvgViewManager()); new RNSVGSvgViewManager());
} }

View File

@@ -20,16 +20,17 @@ class SymbolElement extends Component{
} }
let content = viewBox ? <ViewBox let content = viewBox ? <ViewBox
name={props.id}
viewBox={viewBox} viewBox={viewBox}
preserveAspectRatio={props.preserveAspectRatio} preserveAspectRatio={props.preserveAspectRatio}
> >
{props.children} {props.children}
</ViewBox> : props.children; </ViewBox> : <G id={props.id}>
{props.children}
</G>;
return <Defs> return <Defs>
<G id={props.id}> {content}
{content}
</G>
</Defs>; </Defs>;
} }
} }

View File

@@ -11,7 +11,7 @@ const meetOrSliceTypes = {
}; };
const alignEnum = _.reduce([ const alignEnum = _.reduce([
'xMinMin', 'xMidYMin', 'xMaxYMin', 'xMinYMin', 'xMidYMin', 'xMaxYMin',
'xMinYMid', 'xMidYMid', 'xMaxYMid', 'xMinYMid', 'xMidYMid', 'xMaxYMid',
'xMinYMax', 'xMidYMax', 'xMaxYMax', 'xMinYMax', 'xMidYMax', 'xMaxYMax',
'none' 'none'
@@ -36,7 +36,7 @@ class ViewBox extends Component{
}; };
render() { render() {
let {viewBox, preserveAspectRatio} = this.props; let {viewBox, preserveAspectRatio, name} = this.props;
let params = viewBox.trim().split(spacesRegExp); let params = viewBox.trim().split(spacesRegExp);
@@ -51,7 +51,9 @@ class ViewBox extends Component{
let meetOrSlice = meetOrSliceTypes[modes[1]] || 0; let meetOrSlice = meetOrSliceTypes[modes[1]] || 0;
let align = alignEnum[modes[0]] || 'xMidYMid'; let align = alignEnum[modes[0]] || 'xMidYMid';
return <RNSVGViewBox return <RNSVGViewBox
name={name}
minX={params[0]} minX={params[0]}
minY={params[1]} minY={params[1]}
vbWidth={params[2]} vbWidth={params[2]}

View File

@@ -16,7 +16,7 @@
[self clip:context]; [self clip:context];
for (RNSVGNode *node in self.subviews) { for (RNSVGNode *node in self.subviews) {
[node inheritProperties:self inheritedList:self.propList]; [node mergeProperties:self mergeList:self.propList inherited:YES];
[node renderTo:context]; [node renderTo:context];
if (node.responsible && !svg.responsible) { if (node.responsible && !svg.responsible) {
@@ -78,11 +78,4 @@
} }
} }
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList;
{
for (NSString *key in inheritedList) {
[self inheritProperty:parent propName:key];
}
}
@end @end

View File

@@ -71,18 +71,13 @@
*/ */
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList; - (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList;
- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray<NSString *> *)mergeList inherited:(BOOL)inherited;
/** /**
* just for template node to reset all owned properties once after rendered. * just for template node to reset all owned properties once after rendered.
*/ */
- (void)resetProperties; - (void)resetProperties;
/**
* inherit properties from parent g element
*/
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList;
- (void)inheritProperty:(__kindof RNSVGNode *)parent propName:(NSString *)propName;
- (void)beginTransparencyLayer:(CGContextRef)context; - (void)beginTransparencyLayer:(CGContextRef)context;
- (void)endTransparencyLayer:(CGContextRef)context; - (void)endTransparencyLayer:(CGContextRef)context;

View File

@@ -63,7 +63,7 @@
} else if (opacity > 1) { } else if (opacity > 1) {
opacity = 1; opacity = 1;
} }
[self invalidate]; [self invalidate];
_transparent = opacity < 1; _transparent = opacity < 1;
_opacity = opacity; _opacity = opacity;
@@ -97,17 +97,17 @@
- (void)renderTo:(CGContextRef)context - (void)renderTo:(CGContextRef)context
{ {
float opacity = self.opacity; float opacity = self.opacity;
// This needs to be painted on a layer before being composited. // This needs to be painted on a layer before being composited.
CGContextSaveGState(context); CGContextSaveGState(context);
CGContextConcatCTM(context, self.transform); CGContextConcatCTM(context, self.transform);
CGContextSetAlpha(context, opacity); CGContextSetAlpha(context, opacity);
[self beginTransparencyLayer:context]; [self beginTransparencyLayer:context];
[self renderClip:context]; [self renderClip:context];
[self renderLayerTo:context]; [self renderLayerTo:context];
[self endTransparencyLayer:context]; [self endTransparencyLayer:context];
CGContextRestoreGState(context); CGContextRestoreGState(context);
} }
@@ -175,7 +175,7 @@
while (parent && [parent class] != [RNSVGSvgView class]) { while (parent && [parent class] != [RNSVGSvgView class]) {
parent = parent.superview; parent = parent.superview;
} }
return (RNSVGSvgView *)parent; return (RNSVGSvgView *)parent;
} }
@@ -224,16 +224,6 @@
// abstract // abstract
} }
- (void)inheritProperty:(__kindof RNSVGNode *)parent propName:(NSString *)propName
{
// abstract
}
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList;
{
// abstract
}
- (void)dealloc - (void)dealloc
{ {
CGPathRelease(_clipPath); CGPathRelease(_clipPath);

View File

@@ -215,7 +215,6 @@
[self setValue:[_originProperties valueForKey:key] forKey:key]; [self setValue:[_originProperties valueForKey:key] forKey:key];
} }
} }
[super resetProperties];
_changedList = nil; _changedList = nil;
} }
@@ -231,11 +230,6 @@
} }
} }
- (void)inheritProperties:(__kindof RNSVGNode *)parent inheritedList:(NSArray<NSString *> *)inheritedList
{
[self mergeProperties:parent mergeList:inheritedList inherited:YES];
}
- (void)renderLayerTo:(CGContextRef)context - (void)renderLayerTo:(CGContextRef)context
{ {
// abstract // abstract

View File

@@ -47,7 +47,8 @@ const ViewBoxAttributes = {
vbWidth: true, vbWidth: true,
vbHeight: true, vbHeight: true,
align: true, align: true,
meetOrSlice: true meetOrSlice: true,
name: true
}; };
const NodeAttributes = { const NodeAttributes = {