refactor shape elements add responder system.
refactor shape elements add responder system. Just iOS.
This commit is contained in:
Родитель
1f7a908406
Коммит
8d01e8eccb
|
@ -570,6 +570,10 @@ npm install
|
|||
3. Pattern element
|
||||
4. Image element (Android)
|
||||
5. calculate bounding box only if necessary.
|
||||
6. miterLimit
|
||||
7. move percentage convert and context bounding box to renderable
|
||||
8. implement touchable elements ()
|
||||
9. implement Animated elements
|
||||
|
||||
#### Thanks:
|
||||
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import {PropTypes} from 'react';
|
||||
import Shape, {CIRCLE} from './Shape';
|
||||
import React, {PropTypes, Component} from 'react';
|
||||
import extractProps from '../lib/extract/extractProps';
|
||||
import {RenderableAttributes} from '../lib/attributes';
|
||||
import {requireNativeComponent} from 'react-native';
|
||||
import mergeContext from '../lib/mergeContext';
|
||||
import {circleProps, pathProps, fillProps, strokeProps} from '../lib/props';
|
||||
import SvgTouchableMixin from '../lib/SvgTouchableMixin';
|
||||
import _ from 'lodash';
|
||||
|
||||
class Circle extends Shape{
|
||||
class Circle extends Component{
|
||||
static displayName = 'Circle';
|
||||
static propTypes = {
|
||||
...pathProps,
|
||||
|
@ -16,10 +21,34 @@ class Circle extends Shape{
|
|||
isInGroup: PropTypes.bool
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = CIRCLE;
|
||||
//constructor() {
|
||||
// super(...arguments);
|
||||
// _.forEach(SvgTouchableMixin, (method, key) => {
|
||||
// this[key] = method.bind(this);
|
||||
// });
|
||||
//
|
||||
// this.state = this.touchableGetInitialState();
|
||||
//};
|
||||
|
||||
render() {
|
||||
let props = mergeContext(this.props, this.context);
|
||||
return <RNSVGCircle
|
||||
{...extractProps(props)}
|
||||
cx={props.cx.toString()}
|
||||
cy={props.cy.toString()}
|
||||
r={props.r.toString()}
|
||||
//onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder}
|
||||
//onResponderTerminationRequest={this.touchableHandleResponderTerminationRequest}
|
||||
//onResponderGrant={this.touchableHandleResponderGrant}
|
||||
//onResponderMove={this.touchableHandleResponderMove}
|
||||
//onResponderRelease={this.touchableHandleResponderRelease}
|
||||
//onResponderTerminate={this.touchableHandleResponderTerminate}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const RNSVGCircle = requireNativeComponent('RNSVGCircle', null);
|
||||
|
||||
export default Circle;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import {PropTypes} from 'react';
|
||||
import Shape, {ELLIPSE} from './Shape';
|
||||
import React, {PropTypes, Component} from 'react';
|
||||
import extractProps from '../lib/extract/extractProps';
|
||||
import {RenderableAttributes} from '../lib/attributes';
|
||||
import {requireNativeComponent} from 'react-native';
|
||||
import mergeContext from '../lib/mergeContext';
|
||||
import {ellipseProps, pathProps, fillProps, strokeProps} from '../lib/props';
|
||||
|
||||
class Ellipse extends Shape{
|
||||
|
||||
class Ellipse extends Component{
|
||||
static displayName = 'Ellipse';
|
||||
static propTypes = {
|
||||
...pathProps,
|
||||
|
@ -16,10 +20,17 @@ class Ellipse extends Shape{
|
|||
isInGroup: PropTypes.bool
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = ELLIPSE;
|
||||
render() {
|
||||
let props = mergeContext(this.props, this.context);
|
||||
return <RNSVGEllipse
|
||||
{...extractProps(props)}
|
||||
cx={props.cx.toString()}
|
||||
cy={props.cy.toString()}
|
||||
rx={props.rx.toString()}
|
||||
ry={props.ry.toString()}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
const RNSVGEllipse = requireNativeComponent('RNSVGEllipse', null);
|
||||
export default Ellipse;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React, {Component, PropTypes} from 'react';
|
||||
import {requireNativeComponent} from 'react-native';
|
||||
import extractProps from '../lib/extract/extractProps';
|
||||
import {ImageAttributes} from '../lib/attributes';
|
||||
import {numberProp} from '../lib/props';
|
||||
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
|
||||
import createReactNativeComponentClass from 'react-native/Libraries/ReactNative/createReactNativeComponentClass';
|
||||
import formatPercentageProps from '../lib/formatPercentageProps';
|
||||
|
||||
|
||||
class Image extends Component{
|
||||
static displayName = 'Image';
|
||||
|
@ -19,18 +19,18 @@ class Image extends Component{
|
|||
|
||||
|
||||
render() {
|
||||
let {props} = this;
|
||||
return <RNSVGImage
|
||||
{...extractProps(this.props, {transform: true})}
|
||||
layout={formatPercentageProps(this.props, ['x', 'y', 'width', 'height'])}
|
||||
src={resolveAssetSource(this.props.href)}
|
||||
{...extractProps(props, {transform: true, responder: true})}
|
||||
x={props.x.toString()}
|
||||
y={props.y.toString()}
|
||||
width={props.width.toString()}
|
||||
height={props.height.toString()}
|
||||
src={resolveAssetSource(props.href)}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
let RNSVGImage = createReactNativeComponentClass({
|
||||
validAttributes: ImageAttributes,
|
||||
uiViewClassName: 'RNSVGImage'
|
||||
});
|
||||
|
||||
const RNSVGImage = requireNativeComponent('RNSVGImage', null);
|
||||
|
||||
export default Image;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import {PropTypes} from 'react';
|
||||
import Shape, {LINE} from './Shape';
|
||||
import React, {PropTypes, Component} from 'react';
|
||||
import extractProps from '../lib/extract/extractProps';
|
||||
import {RenderableAttributes} from '../lib/attributes';
|
||||
import {requireNativeComponent} from 'react-native';
|
||||
import mergeContext from '../lib/mergeContext';
|
||||
import {lineProps, pathProps, fillProps, strokeProps} from '../lib/props';
|
||||
|
||||
class Line extends Shape{
|
||||
class Line extends Component{
|
||||
static displayName = 'Line';
|
||||
static propTypes = {
|
||||
...pathProps,
|
||||
|
@ -16,10 +19,17 @@ class Line extends Shape{
|
|||
isInGroup: PropTypes.bool
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = LINE;
|
||||
render() {
|
||||
let props = mergeContext(this.props, this.context);
|
||||
return <RNSVGLine
|
||||
{...extractProps(props)}
|
||||
x1={props.x1.toString()}
|
||||
y1={props.y1.toString()}
|
||||
x2={props.x2.toString()}
|
||||
y2={props.y2.toString()}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
const RNSVGLine = requireNativeComponent('RNSVGLine', null);
|
||||
export default Line;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import {PropTypes} from 'react';
|
||||
import Shape, {RECT} from './Shape';
|
||||
import React, {PropTypes, Component} from 'react';
|
||||
import './Path'; // must import Path first, don`t know why. without this will throw an `Super expression must either be null or a function, not undefined`
|
||||
import extractProps from '../lib/extract/extractProps';
|
||||
import {RenderableAttributes} from '../lib/attributes';
|
||||
import {requireNativeComponent} from 'react-native';
|
||||
import mergeContext from '../lib/mergeContext';
|
||||
import {rectProps, pathProps, fillProps, strokeProps} from '../lib/props';
|
||||
|
||||
class Rect extends Shape{
|
||||
class Rect extends Component{
|
||||
static displayName = 'Rect';
|
||||
static propTypes = {
|
||||
...pathProps,
|
||||
|
@ -16,10 +20,25 @@ class Rect extends Shape{
|
|||
isInGroup: PropTypes.bool
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = RECT;
|
||||
render() {
|
||||
let props = mergeContext(this.props, this.context);
|
||||
|
||||
return <RNSVGRect
|
||||
{...extractProps({
|
||||
...props,
|
||||
x: null,
|
||||
y: null
|
||||
})}
|
||||
x={props.x.toString()}
|
||||
y={props.y.toString()}
|
||||
width={props.width.toString()}
|
||||
height={props.height.toString()}
|
||||
rx={props.rx ? props.rx.toString() : '0'}
|
||||
ry={props.ry ? props.ry.toString() : '0'}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
const RNSVGRect = requireNativeComponent('RNSVGRect', null);
|
||||
|
||||
export default Rect;
|
||||
|
|
|
@ -67,6 +67,12 @@ class Svg extends Component{
|
|||
|
||||
return (
|
||||
<NativeSvgView
|
||||
{...props}
|
||||
opacity={null}
|
||||
width={null}
|
||||
height={null}
|
||||
viewbox={null}
|
||||
preserveAspectRatio={null}
|
||||
ref={ele => this.root = ele}
|
||||
style={[
|
||||
props.style,
|
||||
|
@ -86,6 +92,6 @@ class Svg extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
const NativeSvgView = requireNativeComponent('RNSVGSvgView', Svg);
|
||||
const NativeSvgView = requireNativeComponent('RNSVGSvgView', null);
|
||||
|
||||
export default Svg;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, {Component, PropTypes} from 'react';
|
||||
import {requireNativeComponent} from 'react-native';
|
||||
import Defs from './Defs';
|
||||
import _ from 'lodash';
|
||||
import createReactNativeComponentClass from 'react-native/Libraries/ReactNative/createReactNativeComponentClass';
|
||||
import extractProps from '../lib/extract/extractProps';
|
||||
import extractText from '../lib/extract/extractText';
|
||||
import {TextAttributes} from '../lib/attributes';
|
||||
|
@ -53,9 +53,9 @@ class Text extends Component{
|
|||
<Text {...this.props} id={null} />
|
||||
</Defs.Item>;
|
||||
}
|
||||
// TODO: support percent gradients
|
||||
|
||||
return (
|
||||
<NativeText
|
||||
<RNSVGText
|
||||
{...extractProps({...props, x, y})}
|
||||
{...extractText(props)}
|
||||
/>
|
||||
|
@ -63,9 +63,8 @@ class Text extends Component{
|
|||
}
|
||||
}
|
||||
|
||||
let NativeText = createReactNativeComponentClass({
|
||||
validAttributes: TextAttributes,
|
||||
uiViewClassName: 'RNSVGText'
|
||||
const RNSVGText = requireNativeComponent('RNSVGText', null, {
|
||||
nativeOnly: TextAttributes
|
||||
});
|
||||
|
||||
export default Text;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "RNSVGPercentageConverter.h"
|
||||
|
||||
@interface RNSVGBrush : NSObject
|
||||
{
|
||||
|
@ -29,8 +30,6 @@
|
|||
|
||||
- (BOOL)applyStrokeColor:(CGContextRef)context;
|
||||
|
||||
- (CGFloat)getActualProp:(int)percent relative:(CGFloat)relative offset:(CGFloat)offset;
|
||||
|
||||
/**
|
||||
* paint fills the context with a brush. The context is assumed to
|
||||
* be clipped.
|
||||
|
|
|
@ -29,30 +29,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (CGFloat)getActualProp:(int)index relative:(CGFloat)relative offset:(CGFloat)offset
|
||||
{
|
||||
id coord = [_points objectAtIndex:index];
|
||||
|
||||
if ([coord isKindOfClass:[NSString class]]) {
|
||||
__block float matched = [coord floatValue];
|
||||
NSString *percentage = (NSString *)coord;
|
||||
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:@"^(\\-?\\d+(?:\\.\\d+)?)%$" options:0 error:NULL];
|
||||
[regex enumerateMatchesInString:percentage
|
||||
options:0
|
||||
range:NSMakeRange(0, percentage.length)
|
||||
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
|
||||
{
|
||||
|
||||
matched = [[percentage substringWithRange:NSMakeRange(result.range.location, result.range.length)] floatValue];
|
||||
matched = matched / 100 * relative + offset;
|
||||
}];
|
||||
|
||||
return matched;
|
||||
} else {
|
||||
return [coord floatValue];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)paint:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
|
|
|
@ -49,10 +49,11 @@
|
|||
float offsetX = (midX - width / 2);
|
||||
float offsetY = (midY - height / 2);
|
||||
|
||||
CGFloat x1 = [self getActualProp:0 relative:width offset:offsetX];
|
||||
CGFloat y1 = [self getActualProp:1 relative:height offset:offsetY];
|
||||
CGFloat x2 = [self getActualProp:2 relative:width offset:offsetX];
|
||||
CGFloat y2 = [self getActualProp:3 relative:height offset:offsetY];
|
||||
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
|
||||
CGFloat x1 = [convert stringToFloat:(NSString *)[_points objectAtIndex:0] relative:width offset:offsetX];
|
||||
CGFloat y1 = [convert stringToFloat:(NSString *)[_points objectAtIndex:1] relative:height offset:offsetY];
|
||||
CGFloat x2 = [convert stringToFloat:(NSString *)[_points objectAtIndex:2] relative:width offset:offsetX];
|
||||
CGFloat y2 = [convert stringToFloat:(NSString *)[_points objectAtIndex:3] relative:height offset:offsetY];
|
||||
CGContextDrawLinearGradient(context, _gradient, CGPointMake(x1, y1), CGPointMake(x2, y2), extendOptions);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#import "RNSVGRadialGradient.h"
|
||||
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
#import "RNSVGNode.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RNSVGRadialGradient
|
||||
|
@ -60,12 +61,15 @@
|
|||
float midY = CGRectGetMidY(box);
|
||||
float offsetX = (midX - width / 2);
|
||||
float offsetY = (midY - height / 2);
|
||||
CGFloat rx = [self getActualProp:2 relative:width offset:0];
|
||||
CGFloat ry = [self getActualProp:3 relative:height offset:0];
|
||||
CGFloat fx = [self getActualProp:0 relative:width offset:offsetX];
|
||||
CGFloat fy = [self getActualProp:1 relative:height offset:offsetY] / (ry / rx);
|
||||
CGFloat cx = [self getActualProp:4 relative:width offset:offsetX];
|
||||
CGFloat cy = [self getActualProp:5 relative:height offset:offsetY] / (ry / rx);
|
||||
|
||||
|
||||
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
|
||||
CGFloat rx = [convert stringToFloat:(NSString *)[_points objectAtIndex:2] relative:width offset:0];
|
||||
CGFloat ry = [convert stringToFloat:(NSString *)[_points objectAtIndex:3] relative:height offset:0];
|
||||
CGFloat fx = [convert stringToFloat:(NSString *)[_points objectAtIndex:0] relative:width offset:offsetX];
|
||||
CGFloat fy = [convert stringToFloat:(NSString *)[_points objectAtIndex:1] relative:height offset:offsetY] / (ry / rx);
|
||||
CGFloat cx = [convert stringToFloat:(NSString *)[_points objectAtIndex:4] relative:width offset:offsetX];
|
||||
CGFloat cy = [convert stringToFloat:(NSString *)[_points objectAtIndex:5] relative:height offset:offsetY] / (ry / rx);
|
||||
|
||||
CGAffineTransform transform = CGAffineTransformMakeScale(1, ry / rx);
|
||||
CGContextConcatCTM(context, transform);
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGContainer.h"
|
||||
#import "RNSVGNode.h"
|
||||
#import "RNSVGCGFCRule.h"
|
||||
|
||||
@interface RNSVGGroup : RNSVGNode <RNSVGContainer>
|
||||
@property (nonatomic, strong) NSString *asClipPath; // Current group is a <ClipPath /> element and asClipPath is its id.
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGGroup.h"
|
||||
|
||||
@implementation RNSVGGroup
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
if (self.asClipPath == NULL) {
|
||||
[self clip:context];
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
[node renderTo:context];
|
||||
}
|
||||
} else {
|
||||
[self defineClipPath:[self getPath:context] clipPathId:self.asClipPath];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
CGAffineTransform transform = node.transform;
|
||||
CGPathAddPath(path, &transform, [node getPath:context]);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGRenderable.h"
|
||||
|
||||
@interface RNSVGImage : RNSVGRenderable
|
||||
@property (nonatomic, assign) id src;
|
||||
@property (nonatomic, strong) NSString* x;
|
||||
@property (nonatomic, strong) NSString* y;
|
||||
@property (nonatomic, strong) NSString* width;
|
||||
@property (nonatomic, strong) NSString* height;
|
||||
|
||||
@end
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGImage.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RNSVGImage
|
||||
{
|
||||
CGImageRef image;
|
||||
}
|
||||
- (void)setSrc:(id)src
|
||||
{
|
||||
if (src == _src) {
|
||||
return;
|
||||
}
|
||||
_src = src;
|
||||
CGImageRelease(image);
|
||||
image = CGImageRetain([RCTConvert CGImage:src]);
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)setX:(NSString *)x
|
||||
{
|
||||
if (x == _x) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_x = x;
|
||||
}
|
||||
|
||||
- (void)setY:(NSString *)y
|
||||
{
|
||||
if (y == _y) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_y = y;
|
||||
}
|
||||
|
||||
- (void)setWidth:(NSString *)width
|
||||
{
|
||||
if (width == _width) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_width = width;
|
||||
}
|
||||
|
||||
- (void)setHeight:(NSString *)height
|
||||
{
|
||||
if (height == _height) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_height = height;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGImageRelease(image);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
CGRect box = CGContextGetClipBoundingBox(context);
|
||||
float height = CGRectGetHeight(box);
|
||||
float width = CGRectGetWidth(box);
|
||||
|
||||
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
|
||||
CGFloat x = [convert stringToFloat:self.x relative:width offset:0];
|
||||
CGFloat y = [convert stringToFloat:self.y relative:height offset:0];
|
||||
CGFloat w = [convert stringToFloat:self.width relative:width offset:0];
|
||||
CGFloat h = [convert stringToFloat:self.height relative:height offset:0];
|
||||
|
||||
// add hit area
|
||||
CGPathAddPath(self.nodeArea, nil, CGPathCreateWithRect(CGRectMake(x, y, w, h), nil));
|
||||
|
||||
[self clip:context];
|
||||
CGContextSaveGState(context);
|
||||
CGContextTranslateCTM(context, 0, h);
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
CGContextDrawImage(context, CGRectMake(x, -y, w, h), image);
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGRenderable.h"
|
||||
|
||||
@interface RNSVGPath : RNSVGRenderable
|
||||
|
||||
@property (nonatomic, assign) CGPathRef d;
|
||||
|
||||
@end
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGPath.h"
|
||||
|
||||
@implementation RNSVGPath
|
||||
|
||||
- (void)setD:(CGPathRef)d
|
||||
{
|
||||
if (d == _d) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGPathRelease(_d);
|
||||
_d = CGPathRetain(d);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_d);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
if ((!self.fill && !self.stroke) || !self.d) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGPathDrawingMode mode = kCGPathStroke;
|
||||
BOOL fillColor = YES;
|
||||
|
||||
// Add path to nodeArea
|
||||
CGPathAddPath(self.nodeArea, nil, _d);
|
||||
|
||||
if (self.fill) {
|
||||
mode = self.fillRule == kRNSVGCGFCRuleEvenodd ? kCGPathEOFill : kCGPathFill;
|
||||
fillColor = [self.fill applyFillColor:context];
|
||||
|
||||
if (!fillColor) {
|
||||
[self clip:context];
|
||||
|
||||
CGContextSaveGState(context);
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextClip(context);
|
||||
[self.fill paint:context];
|
||||
CGContextRestoreGState(context);
|
||||
if (!self.stroke) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self.stroke) {
|
||||
// Add stroke to nodeArea
|
||||
CGPathRef strokePath = CGPathCreateCopyByStrokingPath(_d, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, 0);
|
||||
CGPathAddPath(self.nodeArea, nil, strokePath);
|
||||
|
||||
CGContextSetLineWidth(context, self.strokeWidth);
|
||||
CGContextSetLineCap(context, self.strokeLinecap);
|
||||
CGContextSetLineJoin(context, self.strokeLinejoin);
|
||||
RNSVGCGFloatArray dash = self.strokeDasharray;
|
||||
|
||||
if (dash.count) {
|
||||
CGContextSetLineDash(context, self.strokeDashoffset, dash.array, dash.count);
|
||||
}
|
||||
|
||||
if (!fillColor) {
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextReplacePathWithStrokedPath(context);
|
||||
CGContextClip(context);
|
||||
}
|
||||
|
||||
if ([self.stroke applyStrokeColor:context]) {
|
||||
if (mode == kCGPathFill) {
|
||||
mode = kCGPathFillStroke;
|
||||
} else if (mode == kCGPathEOFill) {
|
||||
mode = kCGPathEOFillStroke;
|
||||
}
|
||||
} else {
|
||||
// draw fill
|
||||
[self clip:context];
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextDrawPath(context, mode);
|
||||
|
||||
// draw stroke
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextReplacePathWithStrokedPath(context);
|
||||
CGContextClip(context);
|
||||
[self.stroke paint:context];
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[self clip:context];
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextDrawPath(context, mode);
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
return self.d;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RNSVGContainer.h"
|
||||
|
||||
@interface RNSVGSvgView : UIView <RNSVGContainer>
|
||||
@end
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGSvgView.h"
|
||||
|
||||
#import "RNSVGNode.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RNSVGSvgView
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
[node renderTo:context];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
|
||||
{
|
||||
self.backgroundColor = inheritedBackgroundColor;
|
||||
}
|
||||
|
||||
@end
|
|
@ -7,30 +7,37 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0CF68B051AF0549300FF9E5C /* RNSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68ADE1AF0549300FF9E5C /* RNSVGGroup.m */; };
|
||||
0CF68B061AF0549300FF9E5C /* RNSVGNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE01AF0549300FF9E5C /* RNSVGNode.m */; };
|
||||
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE21AF0549300FF9E5C /* RNSVGRenderable.m */; };
|
||||
0CF68B0A1AF0549300FF9E5C /* RNSVGText.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE81AF0549300FF9E5C /* RNSVGText.m */; };
|
||||
0CF68B0B1AF0549300FF9E5C /* RNSVGBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEC1AF0549300FF9E5C /* RNSVGBrush.m */; };
|
||||
0CF68B0C1AF0549300FF9E5C /* RNSVGLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEE1AF0549300FF9E5C /* RNSVGLinearGradient.m */; };
|
||||
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* RNSVGPattern.m */; };
|
||||
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */; };
|
||||
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */; };
|
||||
0CF68B101AF0549300FF9E5C /* RCTConvert+RNSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF71AF0549300FF9E5C /* RCTConvert+RNSVG.m */; };
|
||||
0CF68B111AF0549300FF9E5C /* RNSVGGroupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFA1AF0549300FF9E5C /* RNSVGGroupManager.m */; };
|
||||
0CF68B121AF0549300FF9E5C /* RNSVGNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFC1AF0549300FF9E5C /* RNSVGNodeManager.m */; };
|
||||
0CF68B131AF0549300FF9E5C /* RNSVGRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFE1AF0549300FF9E5C /* RNSVGRenderableManager.m */; };
|
||||
0CF68B161AF0549300FF9E5C /* RNSVGTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* RNSVGTextManager.m */; };
|
||||
108FD88C1CDAF09B00A65FB3 /* RNSVGImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */; };
|
||||
108FD88F1CDAF0A300A65FB3 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */; };
|
||||
10A062FE1CC732020000CEEF /* RNSVGPathManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A062FB1CC732020000CEEF /* RNSVGPathManager.m */; };
|
||||
10A062FF1CC732020000CEEF /* RNSVGSvgViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A062FD1CC732020000CEEF /* RNSVGSvgViewManager.m */; };
|
||||
10A063041CC7320C0000CEEF /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A063011CC7320C0000CEEF /* RNSVGPath.m */; };
|
||||
10A063051CC7320C0000CEEF /* RNSVGSvgView.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A063031CC7320C0000CEEF /* RNSVGSvgView.m */; };
|
||||
10B898DF1CE45973003CD3D4 /* RNSVGGlyphCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 10B898DE1CE45973003CD3D4 /* RNSVGGlyphCache.m */; };
|
||||
10B898E11CE490FC003CD3D4 /* UIBezierPath-Points.m in Sources */ = {isa = PBXBuildFile; fileRef = 10B898E01CE490FC003CD3D4 /* UIBezierPath-Points.m */; };
|
||||
10C068671CCF0F87007C6982 /* RNSVGShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 10C068651CCF0F87007C6982 /* RNSVGShape.m */; };
|
||||
10C0686A1CCF1061007C6982 /* RNSVGShapeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10C068691CCF1061007C6982 /* RNSVGShapeManager.m */; };
|
||||
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */; };
|
||||
1039D28A1CE71EB7001E90A8 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2841CE71EB7001E90A8 /* RNSVGImage.m */; };
|
||||
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2861CE71EB7001E90A8 /* RNSVGPath.m */; };
|
||||
1039D28C1CE71EB7001E90A8 /* RNSVGSvgView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2881CE71EB7001E90A8 /* RNSVGSvgView.m */; };
|
||||
1039D2941CE71EC2001E90A8 /* RnSVGGlyphCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D28E1CE71EC2001E90A8 /* RnSVGGlyphCache.m */; };
|
||||
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2901CE71EC2001E90A8 /* RNSVGText.m */; };
|
||||
1039D2961CE71EC2001E90A8 /* UIBezierPath-Points.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2931CE71EC2001E90A8 /* UIBezierPath-Points.m */; };
|
||||
1039D2A01CE72177001E90A8 /* RCTConvert+RNSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */; };
|
||||
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */; };
|
||||
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D1D1CE74E3100887C2B /* RNSVGCircleManager.m */; };
|
||||
10BA0D351CE74E3100887C2B /* RNSVGEllipseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D1F1CE74E3100887C2B /* RNSVGEllipseManager.m */; };
|
||||
10BA0D361CE74E3100887C2B /* RNSVGGroupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D211CE74E3100887C2B /* RNSVGGroupManager.m */; };
|
||||
10BA0D371CE74E3100887C2B /* RNSVGImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D231CE74E3100887C2B /* RNSVGImageManager.m */; };
|
||||
10BA0D381CE74E3100887C2B /* RNSVGLineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D251CE74E3100887C2B /* RNSVGLineManager.m */; };
|
||||
10BA0D391CE74E3100887C2B /* RNSVGNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D271CE74E3100887C2B /* RNSVGNodeManager.m */; };
|
||||
10BA0D3A1CE74E3100887C2B /* RNSVGPathManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D291CE74E3100887C2B /* RNSVGPathManager.m */; };
|
||||
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D2B1CE74E3100887C2B /* RNSVGRectManager.m */; };
|
||||
10BA0D3C1CE74E3100887C2B /* RNSVGRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D2D1CE74E3100887C2B /* RNSVGRenderableManager.m */; };
|
||||
10BA0D3E1CE74E3100887C2B /* RNSVGSvgViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D311CE74E3100887C2B /* RNSVGSvgViewManager.m */; };
|
||||
10BA0D3F1CE74E3100887C2B /* RNSVGTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D331CE74E3100887C2B /* RNSVGTextManager.m */; };
|
||||
10BA0D481CE74E3D00887C2B /* RNSVGCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D411CE74E3D00887C2B /* RNSVGCircle.m */; };
|
||||
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D431CE74E3D00887C2B /* RNSVGEllipse.m */; };
|
||||
10BA0D4A1CE74E3D00887C2B /* RNSVGLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D451CE74E3D00887C2B /* RNSVGLine.m */; };
|
||||
10BA0D4B1CE74E3D00887C2B /* RNSVGRect.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D471CE74E3D00887C2B /* RNSVGRect.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
|
@ -47,17 +54,10 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
0CF68AC11AF0540F00FF9E5C /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNSVG.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0CF68ADB1AF0549300FF9E5C /* RNSVGCGFloatArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGCGFloatArray.h; sourceTree = "<group>"; };
|
||||
0CF68ADC1AF0549300FF9E5C /* RNSVGContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGContainer.h; sourceTree = "<group>"; };
|
||||
0CF68ADD1AF0549300FF9E5C /* RNSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGGroup.h; sourceTree = "<group>"; };
|
||||
0CF68ADE1AF0549300FF9E5C /* RNSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGGroup.m; sourceTree = "<group>"; };
|
||||
0CF68ADF1AF0549300FF9E5C /* RNSVGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGNode.h; sourceTree = "<group>"; };
|
||||
0CF68AE01AF0549300FF9E5C /* RNSVGNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGNode.m; sourceTree = "<group>"; };
|
||||
0CF68AE11AF0549300FF9E5C /* RNSVGRenderable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGRenderable.h; sourceTree = "<group>"; };
|
||||
0CF68AE21AF0549300FF9E5C /* RNSVGRenderable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRenderable.m; sourceTree = "<group>"; };
|
||||
0CF68AE71AF0549300FF9E5C /* RNSVGText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGText.h; sourceTree = "<group>"; };
|
||||
0CF68AE81AF0549300FF9E5C /* RNSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGText.m; sourceTree = "<group>"; };
|
||||
0CF68AE91AF0549300FF9E5C /* RNSVGTextFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGTextFrame.h; sourceTree = "<group>"; };
|
||||
0CF68AEB1AF0549300FF9E5C /* RNSVGBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGBrush.h; sourceTree = "<group>"; };
|
||||
0CF68AEC1AF0549300FF9E5C /* RNSVGBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGBrush.m; sourceTree = "<group>"; };
|
||||
0CF68AED1AF0549300FF9E5C /* RNSVGLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGLinearGradient.h; sourceTree = "<group>"; };
|
||||
|
@ -68,37 +68,58 @@
|
|||
0CF68AF21AF0549300FF9E5C /* RNSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRadialGradient.m; sourceTree = "<group>"; };
|
||||
0CF68AF31AF0549300FF9E5C /* RNSVGSolidColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSolidColor.h; sourceTree = "<group>"; };
|
||||
0CF68AF41AF0549300FF9E5C /* RNSVGSolidColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSolidColor.m; sourceTree = "<group>"; };
|
||||
0CF68AF61AF0549300FF9E5C /* RCTConvert+RNSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+RNSVG.h"; sourceTree = "<group>"; };
|
||||
0CF68AF71AF0549300FF9E5C /* RCTConvert+RNSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+RNSVG.m"; sourceTree = "<group>"; };
|
||||
0CF68AF91AF0549300FF9E5C /* RNSVGGroupManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGGroupManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFA1AF0549300FF9E5C /* RNSVGGroupManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGGroupManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFB1AF0549300FF9E5C /* RNSVGNodeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGNodeManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFC1AF0549300FF9E5C /* RNSVGNodeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGNodeManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFD1AF0549300FF9E5C /* RNSVGRenderableManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGRenderableManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFE1AF0549300FF9E5C /* RNSVGRenderableManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRenderableManager.m; sourceTree = "<group>"; };
|
||||
0CF68B031AF0549300FF9E5C /* RNSVGTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGTextManager.h; sourceTree = "<group>"; };
|
||||
0CF68B041AF0549300FF9E5C /* RNSVGTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGTextManager.m; sourceTree = "<group>"; };
|
||||
108FD88A1CDAF09B00A65FB3 /* RNSVGImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGImageManager.h; sourceTree = "<group>"; };
|
||||
108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGImageManager.m; sourceTree = "<group>"; };
|
||||
108FD88D1CDAF0A300A65FB3 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGImage.h; sourceTree = "<group>"; };
|
||||
108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGImage.m; sourceTree = "<group>"; };
|
||||
10A062FA1CC732020000CEEF /* RNSVGPathManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGPathManager.h; sourceTree = "<group>"; };
|
||||
10A062FB1CC732020000CEEF /* RNSVGPathManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPathManager.m; sourceTree = "<group>"; };
|
||||
10A062FC1CC732020000CEEF /* RNSVGSvgViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSvgViewManager.h; sourceTree = "<group>"; };
|
||||
10A062FD1CC732020000CEEF /* RNSVGSvgViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSvgViewManager.m; sourceTree = "<group>"; };
|
||||
10A063001CC7320C0000CEEF /* RNSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGPath.h; sourceTree = "<group>"; };
|
||||
10A063011CC7320C0000CEEF /* RNSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPath.m; sourceTree = "<group>"; };
|
||||
10A063021CC7320C0000CEEF /* RNSVGSvgView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSvgView.h; sourceTree = "<group>"; };
|
||||
10A063031CC7320C0000CEEF /* RNSVGSvgView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSvgView.m; sourceTree = "<group>"; };
|
||||
10B898DD1CE4591F003CD3D4 /* RNSVGGlyphCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGGlyphCache.h; sourceTree = "<group>"; };
|
||||
10B898DE1CE45973003CD3D4 /* RNSVGGlyphCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGGlyphCache.m; sourceTree = "<group>"; };
|
||||
10B898E01CE490FC003CD3D4 /* UIBezierPath-Points.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBezierPath-Points.m"; sourceTree = "<group>"; };
|
||||
10B898E21CE4910A003CD3D4 /* UIBezierPath-Points.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIBezierPath-Points.h"; sourceTree = "<group>"; };
|
||||
10C068641CCF0F87007C6982 /* RNSVGShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGShape.h; sourceTree = SOURCE_ROOT; };
|
||||
10C068651CCF0F87007C6982 /* RNSVGShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGShape.m; sourceTree = SOURCE_ROOT; };
|
||||
10C068681CCF1061007C6982 /* RNSVGShapeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGShapeManager.h; sourceTree = "<group>"; };
|
||||
10C068691CCF1061007C6982 /* RNSVGShapeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGShapeManager.m; sourceTree = "<group>"; };
|
||||
10FEAC6A1CC7D05200F1C23C /* RNSVGCGFCRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGCGFCRule.h; sourceTree = "<group>"; };
|
||||
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGGroup.h; path = Elements/RNSVGGroup.h; sourceTree = "<group>"; };
|
||||
1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGGroup.m; path = Elements/RNSVGGroup.m; sourceTree = "<group>"; };
|
||||
1039D2831CE71EB7001E90A8 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGImage.h; path = Elements/RNSVGImage.h; sourceTree = "<group>"; };
|
||||
1039D2841CE71EB7001E90A8 /* RNSVGImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGImage.m; path = Elements/RNSVGImage.m; sourceTree = "<group>"; };
|
||||
1039D2851CE71EB7001E90A8 /* RNSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPath.h; path = Elements/RNSVGPath.h; sourceTree = "<group>"; };
|
||||
1039D2861CE71EB7001E90A8 /* RNSVGPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPath.m; path = Elements/RNSVGPath.m; sourceTree = "<group>"; };
|
||||
1039D2871CE71EB7001E90A8 /* RNSVGSvgView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGSvgView.h; path = Elements/RNSVGSvgView.h; sourceTree = "<group>"; };
|
||||
1039D2881CE71EB7001E90A8 /* RNSVGSvgView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGSvgView.m; path = Elements/RNSVGSvgView.m; sourceTree = "<group>"; };
|
||||
1039D28D1CE71EC2001E90A8 /* RNSVGGlyphCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGGlyphCache.h; path = Text/RNSVGGlyphCache.h; sourceTree = "<group>"; };
|
||||
1039D28E1CE71EC2001E90A8 /* RnSVGGlyphCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RnSVGGlyphCache.m; path = Text/RnSVGGlyphCache.m; sourceTree = "<group>"; };
|
||||
1039D28F1CE71EC2001E90A8 /* RNSVGText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGText.h; path = Text/RNSVGText.h; sourceTree = "<group>"; };
|
||||
1039D2901CE71EC2001E90A8 /* RNSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGText.m; path = Text/RNSVGText.m; sourceTree = "<group>"; };
|
||||
1039D2911CE71EC2001E90A8 /* RNSVGTextFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTextFrame.h; path = Text/RNSVGTextFrame.h; sourceTree = "<group>"; };
|
||||
1039D2921CE71EC2001E90A8 /* UIBezierPath-Points.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIBezierPath-Points.h"; path = "Text/UIBezierPath-Points.h"; sourceTree = "<group>"; };
|
||||
1039D2931CE71EC2001E90A8 /* UIBezierPath-Points.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIBezierPath-Points.m"; path = "Text/UIBezierPath-Points.m"; sourceTree = "<group>"; };
|
||||
1039D29B1CE72177001E90A8 /* RCTConvert+RNSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RCTConvert+RNSVG.h"; path = "Utils/RCTConvert+RNSVG.h"; sourceTree = "<group>"; };
|
||||
1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+RNSVG.m"; path = "Utils/RCTConvert+RNSVG.m"; sourceTree = "<group>"; };
|
||||
1039D29D1CE72177001E90A8 /* RNSVGCGFCRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGCGFCRule.h; path = Utils/RNSVGCGFCRule.h; sourceTree = "<group>"; };
|
||||
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGCGFloatArray.h; path = Utils/RNSVGCGFloatArray.h; sourceTree = "<group>"; };
|
||||
1039D2A11CE721A7001E90A8 /* RNSVGContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGContainer.h; sourceTree = "<group>"; };
|
||||
1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPercentageConverter.h; path = Utils/RNSVGPercentageConverter.h; sourceTree = "<group>"; };
|
||||
1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPercentageConverter.m; path = Utils/RNSVGPercentageConverter.m; sourceTree = "<group>"; };
|
||||
10BA0D1C1CE74E3100887C2B /* RNSVGCircleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGCircleManager.h; sourceTree = "<group>"; };
|
||||
10BA0D1D1CE74E3100887C2B /* RNSVGCircleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGCircleManager.m; sourceTree = "<group>"; };
|
||||
10BA0D1E1CE74E3100887C2B /* RNSVGEllipseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGEllipseManager.h; sourceTree = "<group>"; };
|
||||
10BA0D1F1CE74E3100887C2B /* RNSVGEllipseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGEllipseManager.m; sourceTree = "<group>"; };
|
||||
10BA0D201CE74E3100887C2B /* RNSVGGroupManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGGroupManager.h; sourceTree = "<group>"; };
|
||||
10BA0D211CE74E3100887C2B /* RNSVGGroupManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGGroupManager.m; sourceTree = "<group>"; };
|
||||
10BA0D221CE74E3100887C2B /* RNSVGImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGImageManager.h; sourceTree = "<group>"; };
|
||||
10BA0D231CE74E3100887C2B /* RNSVGImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGImageManager.m; sourceTree = "<group>"; };
|
||||
10BA0D241CE74E3100887C2B /* RNSVGLineManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGLineManager.h; sourceTree = "<group>"; };
|
||||
10BA0D251CE74E3100887C2B /* RNSVGLineManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGLineManager.m; sourceTree = "<group>"; };
|
||||
10BA0D261CE74E3100887C2B /* RNSVGNodeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGNodeManager.h; sourceTree = "<group>"; };
|
||||
10BA0D271CE74E3100887C2B /* RNSVGNodeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGNodeManager.m; sourceTree = "<group>"; };
|
||||
10BA0D281CE74E3100887C2B /* RNSVGPathManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGPathManager.h; sourceTree = "<group>"; };
|
||||
10BA0D291CE74E3100887C2B /* RNSVGPathManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGPathManager.m; sourceTree = "<group>"; };
|
||||
10BA0D2A1CE74E3100887C2B /* RNSVGRectManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGRectManager.h; sourceTree = "<group>"; };
|
||||
10BA0D2B1CE74E3100887C2B /* RNSVGRectManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRectManager.m; sourceTree = "<group>"; };
|
||||
10BA0D2C1CE74E3100887C2B /* RNSVGRenderableManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGRenderableManager.h; sourceTree = "<group>"; };
|
||||
10BA0D2D1CE74E3100887C2B /* RNSVGRenderableManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGRenderableManager.m; sourceTree = "<group>"; };
|
||||
10BA0D301CE74E3100887C2B /* RNSVGSvgViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSvgViewManager.h; sourceTree = "<group>"; };
|
||||
10BA0D311CE74E3100887C2B /* RNSVGSvgViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSvgViewManager.m; sourceTree = "<group>"; };
|
||||
10BA0D321CE74E3100887C2B /* RNSVGTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGTextManager.h; sourceTree = "<group>"; };
|
||||
10BA0D331CE74E3100887C2B /* RNSVGTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGTextManager.m; sourceTree = "<group>"; };
|
||||
10BA0D401CE74E3D00887C2B /* RNSVGCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGCircle.h; path = Shapes/RNSVGCircle.h; sourceTree = "<group>"; };
|
||||
10BA0D411CE74E3D00887C2B /* RNSVGCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGCircle.m; path = Shapes/RNSVGCircle.m; sourceTree = "<group>"; };
|
||||
10BA0D421CE74E3D00887C2B /* RNSVGEllipse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGEllipse.h; path = Shapes/RNSVGEllipse.h; sourceTree = "<group>"; };
|
||||
10BA0D431CE74E3D00887C2B /* RNSVGEllipse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGEllipse.m; path = Shapes/RNSVGEllipse.m; sourceTree = "<group>"; };
|
||||
10BA0D441CE74E3D00887C2B /* RNSVGLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGLine.h; path = Shapes/RNSVGLine.h; sourceTree = "<group>"; };
|
||||
10BA0D451CE74E3D00887C2B /* RNSVGLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGLine.m; path = Shapes/RNSVGLine.m; sourceTree = "<group>"; };
|
||||
10BA0D461CE74E3D00887C2B /* RNSVGRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGRect.h; path = Shapes/RNSVGRect.h; sourceTree = "<group>"; };
|
||||
10BA0D471CE74E3D00887C2B /* RNSVGRect.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGRect.m; path = Shapes/RNSVGRect.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -115,34 +136,17 @@
|
|||
0CF68AB81AF0540F00FF9E5C = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1039D29A1CE7212C001E90A8 /* Utils */,
|
||||
1039D2801CE71DCF001E90A8 /* Elements */,
|
||||
1039D27F1CE71D9B001E90A8 /* Text */,
|
||||
1039D27E1CE71C70001E90A8 /* Shapes */,
|
||||
0CF68AEA1AF0549300FF9E5C /* Brushes */,
|
||||
0CF68AF81AF0549300FF9E5C /* ViewManagers */,
|
||||
0CF68ADB1AF0549300FF9E5C /* RNSVGCGFloatArray.h */,
|
||||
10FEAC6A1CC7D05200F1C23C /* RNSVGCGFCRule.h */,
|
||||
0CF68ADC1AF0549300FF9E5C /* RNSVGContainer.h */,
|
||||
0CF68ADD1AF0549300FF9E5C /* RNSVGGroup.h */,
|
||||
0CF68ADE1AF0549300FF9E5C /* RNSVGGroup.m */,
|
||||
10C068641CCF0F87007C6982 /* RNSVGShape.h */,
|
||||
10C068651CCF0F87007C6982 /* RNSVGShape.m */,
|
||||
108FD88D1CDAF0A300A65FB3 /* RNSVGImage.h */,
|
||||
108FD88E1CDAF0A300A65FB3 /* RNSVGImage.m */,
|
||||
10A063001CC7320C0000CEEF /* RNSVGPath.h */,
|
||||
10A063011CC7320C0000CEEF /* RNSVGPath.m */,
|
||||
1039D2A11CE721A7001E90A8 /* RNSVGContainer.h */,
|
||||
0CF68ADF1AF0549300FF9E5C /* RNSVGNode.h */,
|
||||
0CF68AE01AF0549300FF9E5C /* RNSVGNode.m */,
|
||||
10A063021CC7320C0000CEEF /* RNSVGSvgView.h */,
|
||||
10A063031CC7320C0000CEEF /* RNSVGSvgView.m */,
|
||||
0CF68AE11AF0549300FF9E5C /* RNSVGRenderable.h */,
|
||||
0CF68AE21AF0549300FF9E5C /* RNSVGRenderable.m */,
|
||||
0CF68AE71AF0549300FF9E5C /* RNSVGText.h */,
|
||||
0CF68AE81AF0549300FF9E5C /* RNSVGText.m */,
|
||||
0CF68AE91AF0549300FF9E5C /* RNSVGTextFrame.h */,
|
||||
0CF68AF61AF0549300FF9E5C /* RCTConvert+RNSVG.h */,
|
||||
0CF68AF71AF0549300FF9E5C /* RCTConvert+RNSVG.m */,
|
||||
10B898DD1CE4591F003CD3D4 /* RNSVGGlyphCache.h */,
|
||||
10B898DE1CE45973003CD3D4 /* RNSVGGlyphCache.m */,
|
||||
10B898E21CE4910A003CD3D4 /* UIBezierPath-Points.h */,
|
||||
10B898E01CE490FC003CD3D4 /* UIBezierPath-Points.m */,
|
||||
0CF68AC21AF0540F00FF9E5C /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
|
@ -175,26 +179,89 @@
|
|||
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
108FD88A1CDAF09B00A65FB3 /* RNSVGImageManager.h */,
|
||||
108FD88B1CDAF09B00A65FB3 /* RNSVGImageManager.m */,
|
||||
10C068681CCF1061007C6982 /* RNSVGShapeManager.h */,
|
||||
10C068691CCF1061007C6982 /* RNSVGShapeManager.m */,
|
||||
10A062FA1CC732020000CEEF /* RNSVGPathManager.h */,
|
||||
10A062FB1CC732020000CEEF /* RNSVGPathManager.m */,
|
||||
10A062FC1CC732020000CEEF /* RNSVGSvgViewManager.h */,
|
||||
10A062FD1CC732020000CEEF /* RNSVGSvgViewManager.m */,
|
||||
0CF68AF91AF0549300FF9E5C /* RNSVGGroupManager.h */,
|
||||
0CF68AFA1AF0549300FF9E5C /* RNSVGGroupManager.m */,
|
||||
0CF68AFB1AF0549300FF9E5C /* RNSVGNodeManager.h */,
|
||||
0CF68AFC1AF0549300FF9E5C /* RNSVGNodeManager.m */,
|
||||
0CF68AFD1AF0549300FF9E5C /* RNSVGRenderableManager.h */,
|
||||
0CF68AFE1AF0549300FF9E5C /* RNSVGRenderableManager.m */,
|
||||
0CF68B031AF0549300FF9E5C /* RNSVGTextManager.h */,
|
||||
0CF68B041AF0549300FF9E5C /* RNSVGTextManager.m */,
|
||||
10BA0D1C1CE74E3100887C2B /* RNSVGCircleManager.h */,
|
||||
10BA0D1D1CE74E3100887C2B /* RNSVGCircleManager.m */,
|
||||
10BA0D1E1CE74E3100887C2B /* RNSVGEllipseManager.h */,
|
||||
10BA0D1F1CE74E3100887C2B /* RNSVGEllipseManager.m */,
|
||||
10BA0D201CE74E3100887C2B /* RNSVGGroupManager.h */,
|
||||
10BA0D211CE74E3100887C2B /* RNSVGGroupManager.m */,
|
||||
10BA0D221CE74E3100887C2B /* RNSVGImageManager.h */,
|
||||
10BA0D231CE74E3100887C2B /* RNSVGImageManager.m */,
|
||||
10BA0D241CE74E3100887C2B /* RNSVGLineManager.h */,
|
||||
10BA0D251CE74E3100887C2B /* RNSVGLineManager.m */,
|
||||
10BA0D261CE74E3100887C2B /* RNSVGNodeManager.h */,
|
||||
10BA0D271CE74E3100887C2B /* RNSVGNodeManager.m */,
|
||||
10BA0D281CE74E3100887C2B /* RNSVGPathManager.h */,
|
||||
10BA0D291CE74E3100887C2B /* RNSVGPathManager.m */,
|
||||
10BA0D2A1CE74E3100887C2B /* RNSVGRectManager.h */,
|
||||
10BA0D2B1CE74E3100887C2B /* RNSVGRectManager.m */,
|
||||
10BA0D2C1CE74E3100887C2B /* RNSVGRenderableManager.h */,
|
||||
10BA0D2D1CE74E3100887C2B /* RNSVGRenderableManager.m */,
|
||||
10BA0D301CE74E3100887C2B /* RNSVGSvgViewManager.h */,
|
||||
10BA0D311CE74E3100887C2B /* RNSVGSvgViewManager.m */,
|
||||
10BA0D321CE74E3100887C2B /* RNSVGTextManager.h */,
|
||||
10BA0D331CE74E3100887C2B /* RNSVGTextManager.m */,
|
||||
);
|
||||
path = ViewManagers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1039D27E1CE71C70001E90A8 /* Shapes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
10BA0D401CE74E3D00887C2B /* RNSVGCircle.h */,
|
||||
10BA0D411CE74E3D00887C2B /* RNSVGCircle.m */,
|
||||
10BA0D421CE74E3D00887C2B /* RNSVGEllipse.h */,
|
||||
10BA0D431CE74E3D00887C2B /* RNSVGEllipse.m */,
|
||||
10BA0D441CE74E3D00887C2B /* RNSVGLine.h */,
|
||||
10BA0D451CE74E3D00887C2B /* RNSVGLine.m */,
|
||||
10BA0D461CE74E3D00887C2B /* RNSVGRect.h */,
|
||||
10BA0D471CE74E3D00887C2B /* RNSVGRect.m */,
|
||||
);
|
||||
name = Shapes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1039D27F1CE71D9B001E90A8 /* Text */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1039D28D1CE71EC2001E90A8 /* RNSVGGlyphCache.h */,
|
||||
1039D28E1CE71EC2001E90A8 /* RnSVGGlyphCache.m */,
|
||||
1039D28F1CE71EC2001E90A8 /* RNSVGText.h */,
|
||||
1039D2901CE71EC2001E90A8 /* RNSVGText.m */,
|
||||
1039D2911CE71EC2001E90A8 /* RNSVGTextFrame.h */,
|
||||
1039D2921CE71EC2001E90A8 /* UIBezierPath-Points.h */,
|
||||
1039D2931CE71EC2001E90A8 /* UIBezierPath-Points.m */,
|
||||
);
|
||||
name = Text;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1039D2801CE71DCF001E90A8 /* Elements */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */,
|
||||
1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */,
|
||||
1039D2831CE71EB7001E90A8 /* RNSVGImage.h */,
|
||||
1039D2841CE71EB7001E90A8 /* RNSVGImage.m */,
|
||||
1039D2851CE71EB7001E90A8 /* RNSVGPath.h */,
|
||||
1039D2861CE71EB7001E90A8 /* RNSVGPath.m */,
|
||||
1039D2871CE71EB7001E90A8 /* RNSVGSvgView.h */,
|
||||
1039D2881CE71EB7001E90A8 /* RNSVGSvgView.m */,
|
||||
);
|
||||
name = Elements;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1039D29A1CE7212C001E90A8 /* Utils */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */,
|
||||
1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */,
|
||||
1039D29B1CE72177001E90A8 /* RCTConvert+RNSVG.h */,
|
||||
1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */,
|
||||
1039D29D1CE72177001E90A8 /* RNSVGCGFCRule.h */,
|
||||
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */,
|
||||
);
|
||||
name = Utils;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -250,30 +317,37 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
10C068671CCF0F87007C6982 /* RNSVGShape.m in Sources */,
|
||||
0CF68B161AF0549300FF9E5C /* RNSVGTextManager.m in Sources */,
|
||||
10A063041CC7320C0000CEEF /* RNSVGPath.m in Sources */,
|
||||
0CF68B111AF0549300FF9E5C /* RNSVGGroupManager.m in Sources */,
|
||||
10BA0D3F1CE74E3100887C2B /* RNSVGTextManager.m in Sources */,
|
||||
1039D28A1CE71EB7001E90A8 /* RNSVGImage.m in Sources */,
|
||||
10BA0D4B1CE74E3D00887C2B /* RNSVGRect.m in Sources */,
|
||||
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */,
|
||||
1039D2941CE71EC2001E90A8 /* RnSVGGlyphCache.m in Sources */,
|
||||
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */,
|
||||
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
|
||||
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */,
|
||||
0CF68B0D1AF0549300FF9E5C /* RNSVGPattern.m in Sources */,
|
||||
0CF68B0A1AF0549300FF9E5C /* RNSVGText.m in Sources */,
|
||||
0CF68B121AF0549300FF9E5C /* RNSVGNodeManager.m in Sources */,
|
||||
0CF68B051AF0549300FF9E5C /* RNSVGGroup.m in Sources */,
|
||||
10A062FF1CC732020000CEEF /* RNSVGSvgViewManager.m in Sources */,
|
||||
0CF68B131AF0549300FF9E5C /* RNSVGRenderableManager.m in Sources */,
|
||||
108FD88F1CDAF0A300A65FB3 /* RNSVGImage.m in Sources */,
|
||||
0CF68B0E1AF0549300FF9E5C /* RNSVGRadialGradient.m in Sources */,
|
||||
10A063051CC7320C0000CEEF /* RNSVGSvgView.m in Sources */,
|
||||
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */,
|
||||
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */,
|
||||
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */,
|
||||
10B898E11CE490FC003CD3D4 /* UIBezierPath-Points.m in Sources */,
|
||||
0CF68B101AF0549300FF9E5C /* RCTConvert+RNSVG.m in Sources */,
|
||||
10C0686A1CCF1061007C6982 /* RNSVGShapeManager.m in Sources */,
|
||||
108FD88C1CDAF09B00A65FB3 /* RNSVGImageManager.m in Sources */,
|
||||
10A062FE1CC732020000CEEF /* RNSVGPathManager.m in Sources */,
|
||||
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */,
|
||||
0CF68B061AF0549300FF9E5C /* RNSVGNode.m in Sources */,
|
||||
10BA0D3E1CE74E3100887C2B /* RNSVGSvgViewManager.m in Sources */,
|
||||
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColor.m in Sources */,
|
||||
10BA0D3A1CE74E3100887C2B /* RNSVGPathManager.m in Sources */,
|
||||
1039D2961CE71EC2001E90A8 /* UIBezierPath-Points.m in Sources */,
|
||||
10BA0D3C1CE74E3100887C2B /* RNSVGRenderableManager.m in Sources */,
|
||||
0CF68B0C1AF0549300FF9E5C /* RNSVGLinearGradient.m in Sources */,
|
||||
10B898DF1CE45973003CD3D4 /* RNSVGGlyphCache.m in Sources */,
|
||||
10BA0D371CE74E3100887C2B /* RNSVGImageManager.m in Sources */,
|
||||
10BA0D391CE74E3100887C2B /* RNSVGNodeManager.m in Sources */,
|
||||
10BA0D381CE74E3100887C2B /* RNSVGLineManager.m in Sources */,
|
||||
10BA0D481CE74E3D00887C2B /* RNSVGCircle.m in Sources */,
|
||||
10BA0D351CE74E3100887C2B /* RNSVGEllipseManager.m in Sources */,
|
||||
1039D2A01CE72177001E90A8 /* RCTConvert+RNSVG.m in Sources */,
|
||||
0CF68B0B1AF0549300FF9E5C /* RNSVGBrush.m in Sources */,
|
||||
10BA0D361CE74E3100887C2B /* RNSVGGroupManager.m in Sources */,
|
||||
10BA0D4A1CE74E3D00887C2B /* RNSVGLine.m in Sources */,
|
||||
1039D28C1CE71EB7001E90A8 /* RNSVGSvgView.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -50,7 +50,7 @@ static NSMutableDictionary *ClipPaths;
|
|||
- (void)renderTo:(CGContextRef)context
|
||||
{
|
||||
float opacity = self.opacity;
|
||||
|
||||
|
||||
if (opacity <= 0) {
|
||||
// Nothing to paint
|
||||
return;
|
||||
|
@ -60,7 +60,7 @@ static NSMutableDictionary *ClipPaths;
|
|||
if (!transparent) {
|
||||
opacity = 1;
|
||||
}
|
||||
|
||||
|
||||
// This needs to be painted on a layer before being composited.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
|
@ -101,20 +101,6 @@ static NSMutableDictionary *ClipPaths;
|
|||
[ClipPaths setValue:[NSValue valueWithPointer:_clipPath] forKey:clipPathId];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_clipPath);
|
||||
if (definedClipPathId) {
|
||||
[ClipPaths removeObjectForKey:definedClipPathId];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath: (CGContextRef) context
|
||||
{
|
||||
// abstract
|
||||
|
@ -141,4 +127,22 @@ static NSMutableDictionary *ClipPaths;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
|
||||
{
|
||||
self.backgroundColor = inheritedBackgroundColor;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_clipPath);
|
||||
if (definedClipPathId) {
|
||||
[ClipPaths removeObjectForKey:definedClipPathId];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
@property (nonatomic, assign) CGLineJoin strokeLinejoin;
|
||||
@property (nonatomic, assign) RNSVGCGFloatArray strokeDasharray;
|
||||
@property (nonatomic, assign) CGFloat strokeDashoffset;
|
||||
@property (nonatomic, assign) CGMutablePathRef nodeArea;
|
||||
|
||||
- (CGFloat)getActualProp:(NSDictionary *) prop relative:(float)relative;
|
||||
|
||||
|
|
|
@ -10,6 +10,15 @@
|
|||
|
||||
@implementation RNSVGRenderable
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_nodeArea = CGPathCreateMutable();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setFill:(RNSVGBrush *)fill
|
||||
{
|
||||
[self invalidate];
|
||||
|
@ -60,6 +69,7 @@
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_nodeArea);
|
||||
if (_strokeDasharray.array) {
|
||||
free(_strokeDasharray.array);
|
||||
}
|
||||
|
@ -91,6 +101,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
// hitTest delagate
|
||||
- (UIView *)hitTest:(CGPoint)point
|
||||
withEvent:(UIEvent *)event
|
||||
{
|
||||
if (self.nodeArea != NULL && CGPathContainsPoint(self.nodeArea, nil, point, NO)) {
|
||||
return self;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
}
|
||||
default:
|
||||
RCTLogError(@"Invalid Shape type %d at %@", type, self.shape);
|
||||
//CGPathRelease(path);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGRenderable.h"
|
||||
#import "RNSVGPath.h"
|
||||
|
||||
@interface RNSVGCircle : RNSVGPath
|
||||
|
||||
@property (nonatomic, strong) NSString* cx;
|
||||
@property (nonatomic, strong) NSString* cy;
|
||||
@property (nonatomic, strong) NSString* r;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGCircle.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RNSVGCircle
|
||||
|
||||
- (void)setCx:(NSString *)cx
|
||||
{
|
||||
if (cx == _cx) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_cx = cx;
|
||||
}
|
||||
|
||||
- (void)setCy:(NSString *)cy
|
||||
{
|
||||
if (cy == _cy) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_cy = cy;
|
||||
}
|
||||
|
||||
- (void)setR:(NSString *)r
|
||||
{
|
||||
if (r == _r) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_r = r;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGRect box = CGContextGetClipBoundingBox(context);
|
||||
float height = CGRectGetHeight(box);
|
||||
float width = CGRectGetWidth(box);
|
||||
|
||||
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
|
||||
CGFloat cx = [convert stringToFloat:self.cx relative:width offset:0];
|
||||
CGFloat cy = [convert stringToFloat:self.cy relative:height offset:0];
|
||||
CGFloat r;
|
||||
|
||||
// radius in percentage calculate formula:
|
||||
// radius = sqrt(pow((width*percent), 2) + pow((height*percent), 2)) / sqrt(2)
|
||||
|
||||
if ([convert isPercentage:self.r]) {
|
||||
CGFloat radiusPercent = [convert percentageToFloat:self.r relative:1 offset:0];
|
||||
r = sqrt(pow((width * radiusPercent), 2) + pow((height * radiusPercent), 2)) / sqrt(2);
|
||||
} else {
|
||||
r = [self.r floatValue];
|
||||
}
|
||||
|
||||
CGPathAddArc(path, nil, cx, cy, r, 0, 2*M_PI, YES);
|
||||
return path;
|
||||
}
|
||||
|
||||
- (CGFloat)getActualProp:(NSString *)name relative:(float)relative
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGRenderable.h"
|
||||
#import "RNSVGPath.h"
|
||||
|
||||
@interface RNSVGEllipse : RNSVGPath
|
||||
@property (nonatomic, strong) NSString* cx;
|
||||
@property (nonatomic, strong) NSString* cy;
|
||||
@property (nonatomic, strong) NSString* rx;
|
||||
@property (nonatomic, strong) NSString* ry;
|
||||
@end
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGEllipse.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RNSVGEllipse
|
||||
|
||||
- (void)setCx:(NSString *)cx
|
||||
{
|
||||
if (cx == _cx) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_cx = cx;
|
||||
}
|
||||
|
||||
- (void)setCy:(NSString *)cy
|
||||
{
|
||||
if (cy == _cy) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_cy = cy;
|
||||
}
|
||||
|
||||
- (void)setRx:(NSString *)rx
|
||||
{
|
||||
if (rx == _rx) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_rx = rx;
|
||||
}
|
||||
|
||||
- (void)setRy:(NSString *)ry
|
||||
{
|
||||
if (ry == _ry) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_ry = ry;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGRect box = CGContextGetClipBoundingBox(context);
|
||||
float height = CGRectGetHeight(box);
|
||||
float width = CGRectGetWidth(box);
|
||||
|
||||
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
|
||||
CGFloat cx = [convert stringToFloat:self.cx relative:width offset:0];
|
||||
CGFloat cy = [convert stringToFloat:self.cy relative:height offset:0];
|
||||
CGFloat rx = [convert stringToFloat:self.rx relative:width offset:0];
|
||||
CGFloat ry = [convert stringToFloat:self.ry relative:height offset:0];
|
||||
CGPathAddEllipseInRect(path, nil, CGRectMake(cx - rx, cy - ry, rx * 2, ry * 2));
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGRenderable.h"
|
||||
#import "RNSVGPath.h"
|
||||
|
||||
@interface RNSVGLine : RNSVGPath
|
||||
@property (nonatomic, strong) NSString* x1;
|
||||
@property (nonatomic, strong) NSString* y1;
|
||||
@property (nonatomic, strong) NSString* x2;
|
||||
@property (nonatomic, strong) NSString* y2;
|
||||
@end
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGLine.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RNSVGLine
|
||||
|
||||
- (void)setX1:(NSString *)x1
|
||||
{
|
||||
if (x1 == _x1) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_x1 = x1;
|
||||
}
|
||||
|
||||
- (void)setY1:(NSString *)y1
|
||||
{
|
||||
if (y1 == _y1) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_y1 = y1;
|
||||
}
|
||||
|
||||
- (void)setX2:(NSString *)x2
|
||||
{
|
||||
if (x2 == _x2) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_x2 = x2;
|
||||
}
|
||||
|
||||
- (void)setY2:(NSString *)y2
|
||||
{
|
||||
if (y2 == _y2) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_y2 = y2;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGRect box = CGContextGetClipBoundingBox(context);
|
||||
float height = CGRectGetHeight(box);
|
||||
float width = CGRectGetWidth(box);
|
||||
|
||||
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
|
||||
CGFloat x1 = [convert stringToFloat:self.x1 relative:width offset:0];
|
||||
CGFloat y1 = [convert stringToFloat:self.y1 relative:height offset:0];
|
||||
CGFloat x2 = [convert stringToFloat:self.x2 relative:width offset:0];
|
||||
CGFloat y2 = [convert stringToFloat:self.y2 relative:height offset:0];
|
||||
CGPathMoveToPoint(path, nil, x1, y1);
|
||||
CGPathAddLineToPoint(path, nil, x2, y2);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "RNSVGRenderable.h"
|
||||
#import "RNSVGPath.h"
|
||||
|
||||
@interface RNSVGRect : RNSVGPath
|
||||
|
||||
@property (nonatomic, strong) NSString* x;
|
||||
@property (nonatomic, strong) NSString* y;
|
||||
@property (nonatomic, strong) NSString* width;
|
||||
@property (nonatomic, strong) NSString* height;
|
||||
@property (nonatomic, strong) NSString* rx;
|
||||
@property (nonatomic, strong) NSString* ry;
|
||||
|
||||
@end
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGRect.h"
|
||||
#import "RCTLog.h"
|
||||
|
||||
@implementation RNSVGRect
|
||||
|
||||
- (void)setX:(NSString *)x
|
||||
{
|
||||
if (x == _x) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_x = x;
|
||||
}
|
||||
|
||||
- (void)setY:(NSString *)y
|
||||
{
|
||||
if (y == _y) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_y = y;
|
||||
}
|
||||
|
||||
- (void)setWidth:(NSString *)width
|
||||
{
|
||||
if (width == _width) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_width = width;
|
||||
}
|
||||
|
||||
- (void)setHeight:(NSString *)height
|
||||
{
|
||||
if (height == _height) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_height = height;
|
||||
}
|
||||
|
||||
- (void)setRx:(NSString *)rx
|
||||
{
|
||||
if (rx == _rx) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_rx = rx;
|
||||
}
|
||||
|
||||
- (void)setRy:(NSString *)ry
|
||||
{
|
||||
if (ry == _ry) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
_ry = ry;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
|
||||
CGRect box = CGContextGetClipBoundingBox(context);
|
||||
float height = CGRectGetHeight(box);
|
||||
float width = CGRectGetWidth(box);
|
||||
|
||||
RNSVGPercentageConverter* convert = [[RNSVGPercentageConverter alloc] init];
|
||||
CGFloat x = [convert stringToFloat:self.x relative:width offset:0];
|
||||
CGFloat y = [convert stringToFloat:self.y relative:height offset:0];
|
||||
CGFloat w = [convert stringToFloat:self.width relative:width offset:0];
|
||||
CGFloat h = [convert stringToFloat:self.height relative:height offset:0];
|
||||
CGFloat rx = [convert stringToFloat:self.rx relative:width offset:0];
|
||||
CGFloat ry = [convert stringToFloat:self.ry relative:height offset:0];
|
||||
|
||||
|
||||
if (rx != 0 || ry != 0) {
|
||||
if (rx == 0) {
|
||||
rx = ry;
|
||||
} else if (ry == 0) {
|
||||
ry = rx;
|
||||
}
|
||||
|
||||
if (rx > w / 2) {
|
||||
rx = w / 2;
|
||||
}
|
||||
|
||||
if (ry > h / 2) {
|
||||
ry = h / 2;
|
||||
}
|
||||
|
||||
CGPathAddRoundedRect(path, nil, CGRectMake(x, y, w, h), rx, ry);
|
||||
} else {
|
||||
CGPathAddRect(path, nil, CGRectMake(x, y, w, h));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// This implements a very simple glyph cache.
|
||||
// It maps from CTFontRef to CGGlyph to CGPathRef in order to reuse glyphs.
|
||||
// It does NOT try to retain the keys that are used (CTFontRef or CGGlyph)
|
||||
// but that is not an issue with respect to how it is used by this sample.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import "RNSVGRenderable.h"
|
||||
|
||||
@interface RNSVGGlyphCache : NSObject
|
||||
{
|
||||
CFMutableDictionaryRef cache;
|
||||
}
|
||||
|
||||
- (id)init;
|
||||
- (CGPathRef)pathForGlyph:(CGGlyph)glyph fromFont:(CTFontRef)font;
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "UIBezierPath-Points.h"
|
||||
#import "RNSVGPath.h"
|
||||
#import "RNSVGTextFrame.h"
|
||||
#import "RNSVGGlyphCache.h"
|
||||
|
||||
@interface RNSVGText : RNSVGPath
|
||||
|
||||
@property (nonatomic, assign) CTTextAlignment alignment;
|
||||
@property (nonatomic, assign) RNSVGTextFrame textFrame;
|
||||
@property (nonatomic, assign) CGPathRef path;
|
||||
|
||||
@end
|
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGText.h"
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
@implementation RNSVGText
|
||||
|
||||
static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
||||
{
|
||||
if (frame.count) {
|
||||
// We must release each line before freeing up this struct
|
||||
for (int i = 0; i < frame.count; i++) {
|
||||
CFRelease(frame.lines[i]);
|
||||
}
|
||||
free(frame.lines);
|
||||
free(frame.widths);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setAlignment:(CTTextAlignment)alignment
|
||||
{
|
||||
[self invalidate];
|
||||
_alignment = alignment;
|
||||
}
|
||||
|
||||
- (void)setTextFrame:(RNSVGTextFrame)frame
|
||||
{
|
||||
if (frame.lines != _textFrame.lines) {
|
||||
RNSVGFreeTextFrame(_textFrame);
|
||||
}
|
||||
[self invalidate];
|
||||
_textFrame = frame;
|
||||
}
|
||||
|
||||
- (void)setPath:(CGPathRef)path
|
||||
{
|
||||
if (path == _path) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGPathRelease(_path);
|
||||
_path = CGPathRetain(path);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_path);
|
||||
RNSVGFreeTextFrame(_textFrame);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
self.d = [self getPath: context];
|
||||
[super renderLayerTo:context];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
RNSVGTextFrame frame = self.textFrame;
|
||||
for (int i = 0; i < frame.count; i++) {
|
||||
CGFloat shift;
|
||||
CGFloat width = frame.widths[i];
|
||||
switch (self.alignment) {
|
||||
case kCTTextAlignmentRight:
|
||||
shift = width;
|
||||
break;
|
||||
case kCTTextAlignmentCenter:
|
||||
shift = width / 2;
|
||||
break;
|
||||
default:
|
||||
shift = 0;
|
||||
break;
|
||||
}
|
||||
// We should consider snapping this shift to device pixels to improve rendering quality
|
||||
// when a line has subpixel width.
|
||||
CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path == NULL ? 0 : -frame.lineHeight));
|
||||
CGPathAddPath(path, &offset, [self setLinePath:frame.lines[i]]);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
- (CGPathRef)setLinePath:(CTLineRef)line
|
||||
{
|
||||
|
||||
CGAffineTransform upsideDown = CGAffineTransformMakeScale(1.0, -1.0);
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
RNSVGGlyphCache *cache = [[RNSVGGlyphCache alloc] init];
|
||||
CTLineGetGlyphRuns(line);
|
||||
CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
|
||||
CFIndex runCount = CFArrayGetCount(glyphRuns);
|
||||
CFIndex glyphIndex = 0;
|
||||
for(CFIndex i = 0; i < runCount; ++i)
|
||||
{
|
||||
|
||||
// For each run, we need to get the glyphs, their font (to get the path) and their locations.
|
||||
CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, i);
|
||||
CFIndex runGlyphCount = CTRunGetGlyphCount(run);
|
||||
CGPoint positions[runGlyphCount];
|
||||
CGGlyph glyphs[runGlyphCount];
|
||||
|
||||
// Grab the glyphs, positions, and font
|
||||
CTRunGetPositions(run, CFRangeMake(0, 0), positions);
|
||||
CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
|
||||
CFDictionaryRef attributes = CTRunGetAttributes(run);
|
||||
CTFontRef runFont = CFDictionaryGetValue(attributes, kCTFontAttributeName);
|
||||
for(CFIndex j = 0; j < runGlyphCount; ++j, ++glyphIndex) {
|
||||
CGPathRef letter = [cache pathForGlyph:glyphs[j] fromFont:runFont];
|
||||
CGPoint point = positions[j];
|
||||
if (letter != NULL) {
|
||||
CGAffineTransform transform;
|
||||
|
||||
// draw glyphs along path
|
||||
if (self.path != NULL) {
|
||||
CGPoint slope;
|
||||
CGRect bounding = CGPathGetBoundingBox(letter);
|
||||
UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:self.path];
|
||||
CGFloat percentConsumed = (point.x + bounding.size.width) / path.length;
|
||||
if (percentConsumed >= 1.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CGPoint targetPoint = [path pointAtPercent:percentConsumed withSlope: &slope];
|
||||
float angle = atan(slope.y / slope.x); // + M_PI;
|
||||
if (slope.x < 0) angle += M_PI; // going left, update the angle
|
||||
transform = CGAffineTransformMakeTranslation(targetPoint.x - bounding.size.width, targetPoint.y);
|
||||
transform = CGAffineTransformRotate(transform, angle);
|
||||
transform = CGAffineTransformScale(transform, 1.0, -1.0);
|
||||
} else {
|
||||
transform = CGAffineTransformTranslate(upsideDown, point.x, point.y);
|
||||
}
|
||||
CGPathAddPath(path, &transform, letter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
// A little helper to make sure we have a set of lines including width ready for use.
|
||||
// We assume that we will only this in one place so no reference counting is necessary.
|
||||
// Needs to be freed when dealloced.
|
||||
|
||||
// This is fragile since this relies on these values not getting reused. Consider
|
||||
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
CGFloat baseLine; // Distance from the origin to the base line of the first line
|
||||
CGFloat lineHeight; // Distance between lines
|
||||
CTLineRef *lines;
|
||||
CGFloat *widths; // Width of each line
|
||||
} RNSVGTextFrame;
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGGlyphCache.h"
|
||||
|
||||
@implementation RNSVGGlyphCache
|
||||
|
||||
-(id)init
|
||||
{
|
||||
self = [super init];
|
||||
if(self != nil)
|
||||
{
|
||||
cache = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
CFRelease(cache);
|
||||
}
|
||||
|
||||
-(CGPathRef)pathForGlyph:(CGGlyph)glyph fromFont:(CTFontRef)font
|
||||
{
|
||||
// First we lookup the font to get to its glyph dictionary
|
||||
CFMutableDictionaryRef glyphDict = (CFMutableDictionaryRef)CFDictionaryGetValue(cache, font);
|
||||
if(glyphDict == NULL)
|
||||
{
|
||||
// And if this font hasn't been seen before, we'll create and set the dictionary for it
|
||||
glyphDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
|
||||
CFDictionarySetValue(cache, font, glyphDict);
|
||||
CFRelease(glyphDict);
|
||||
}
|
||||
// Next we try to get a path for the given glyph from the glyph dictionary
|
||||
CGPathRef path = (CGPathRef)CFDictionaryGetValue(glyphDict, (const void *)(uintptr_t)glyph);
|
||||
if(path == NULL)
|
||||
{
|
||||
// If the path hasn't been seen before, then we'll create the path from the font & glyph and cache it.
|
||||
path = CTFontCreatePathForGlyph(font, glyph, NULL);
|
||||
if(path == NULL)
|
||||
{
|
||||
// If a glyph does not have a path, then we need a placeholder to set in the dictionary
|
||||
path = (CGPathRef)kCFNull;
|
||||
}
|
||||
CFDictionarySetValue(glyphDict, (const void *)(uintptr_t)glyph, path);
|
||||
CFRelease(path);
|
||||
}
|
||||
if(path == (CGPathRef)kCFNull)
|
||||
{
|
||||
// If we got the placeholder, then set the path to NULL
|
||||
// (this will happen either after discovering the glyph path is NULL,
|
||||
// or after looking that up in the dictionary).
|
||||
path = NULL;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Erica Sadun, http://ericasadun.com
|
||||
iPhone Developer's Cookbook, 6.x Edition
|
||||
BSD License, Use at your own risk
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIBezierPath (Points)
|
||||
@property (nonatomic, readonly) NSArray *points;
|
||||
@property (nonatomic, readonly) NSArray *bezierElements;
|
||||
@property (nonatomic, readonly) CGFloat length;
|
||||
|
||||
- (NSArray *) pointPercentArray;
|
||||
- (CGPoint) pointAtPercent: (CGFloat) percent withSlope: (CGPoint *) slope;
|
||||
+ (UIBezierPath *) pathWithPoints: (NSArray *) points;
|
||||
+ (UIBezierPath *) pathWithElements: (NSArray *) elements;
|
||||
@end
|
|
@ -0,0 +1,219 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Erica Sadun, http://ericasadun.com
|
||||
iPhone Developer's Cookbook, 6.x Edition
|
||||
BSD License, Use at your own risk
|
||||
*/
|
||||
|
||||
#import "UIBezierPath-Points.h"
|
||||
|
||||
#define POINTSTRING(_CGPOINT_) (NSStringFromCGPoint(_CGPOINT_))
|
||||
#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]
|
||||
#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]
|
||||
|
||||
// Return distance between two points
|
||||
static float distance (CGPoint p1, CGPoint p2)
|
||||
{
|
||||
float dx = p2.x - p1.x;
|
||||
float dy = p2.y - p1.y;
|
||||
|
||||
return sqrt(dx*dx + dy*dy);
|
||||
}
|
||||
|
||||
@implementation UIBezierPath (Points)
|
||||
void getPointsFromBezier(void *info, const CGPathElement *element)
|
||||
{
|
||||
NSMutableArray *bezierPoints = (__bridge NSMutableArray *)info;
|
||||
CGPathElementType type = element->type;
|
||||
CGPoint *points = element->points;
|
||||
if (type != kCGPathElementCloseSubpath)
|
||||
{
|
||||
if ((type == kCGPathElementAddLineToPoint) ||
|
||||
(type == kCGPathElementMoveToPoint))
|
||||
[bezierPoints addObject:VALUE(0)];
|
||||
else if (type == kCGPathElementAddQuadCurveToPoint)
|
||||
[bezierPoints addObject:VALUE(1)];
|
||||
else if (type == kCGPathElementAddCurveToPoint)
|
||||
[bezierPoints addObject:VALUE(2)];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)points
|
||||
{
|
||||
NSMutableArray *points = [NSMutableArray array];
|
||||
CGPathApply(self.CGPath, (__bridge void *)points, getPointsFromBezier);
|
||||
return points;
|
||||
}
|
||||
|
||||
// Return a Bezier path buit with the supplied points
|
||||
+ (UIBezierPath *) pathWithPoints: (NSArray *) points
|
||||
{
|
||||
UIBezierPath *path = [UIBezierPath bezierPath];
|
||||
if (points.count == 0) return path;
|
||||
[path moveToPoint:POINT(0)];
|
||||
for (int i = 1; i < points.count; i++)
|
||||
[path addLineToPoint:POINT(i)];
|
||||
return path;
|
||||
}
|
||||
|
||||
- (CGFloat) length
|
||||
{
|
||||
NSArray *points = self.points;
|
||||
float totalPointLength = 0.0f;
|
||||
for (int i = 1; i < points.count; i++)
|
||||
totalPointLength += distance(POINT(i), POINT(i-1));
|
||||
return totalPointLength;
|
||||
}
|
||||
|
||||
- (NSArray *) pointPercentArray
|
||||
{
|
||||
// Use total length to calculate the percent of path consumed at each control point
|
||||
NSArray *points = self.points;
|
||||
int pointCount = points.count;
|
||||
|
||||
float totalPointLength = self.length;
|
||||
float distanceTravelled = 0.0f;
|
||||
|
||||
NSMutableArray *pointPercentArray = [NSMutableArray array];
|
||||
[pointPercentArray addObject:@(0.0)];
|
||||
|
||||
for (int i = 1; i < pointCount; i++)
|
||||
{
|
||||
distanceTravelled += distance(POINT(i), POINT(i-1));
|
||||
[pointPercentArray addObject:@(distanceTravelled / totalPointLength)];
|
||||
}
|
||||
|
||||
// Add a final item just to stop with. Probably not needed.
|
||||
[pointPercentArray addObject:[NSNumber numberWithFloat:1.1f]]; // 110%
|
||||
|
||||
return pointPercentArray;
|
||||
}
|
||||
|
||||
- (CGPoint) pointAtPercent: (CGFloat) percent withSlope: (CGPoint *) slope
|
||||
{
|
||||
NSArray *points = self.points;
|
||||
NSArray *percentArray = self.pointPercentArray;
|
||||
CFIndex lastPointIndex = points.count - 1;
|
||||
|
||||
if (!points.count) {
|
||||
return CGPointZero;
|
||||
}
|
||||
|
||||
// Check for 0% and 100%
|
||||
if (percent <= 0.0f) {
|
||||
return POINT(0);
|
||||
}
|
||||
if (percent >= 1.0f) {
|
||||
return POINT(lastPointIndex);
|
||||
}
|
||||
|
||||
// Find a corresponding pair of points in the path
|
||||
CFIndex index = 1;
|
||||
while ((index < percentArray.count) &&
|
||||
(percent > ((NSNumber *)percentArray[index]).floatValue)) {
|
||||
index++;
|
||||
}
|
||||
|
||||
// This should not happen.
|
||||
if (index > lastPointIndex) {
|
||||
return POINT(lastPointIndex);
|
||||
}
|
||||
|
||||
// Calculate the intermediate distance between the two points
|
||||
CGPoint point1 = POINT(index -1);
|
||||
CGPoint point2 = POINT(index);
|
||||
|
||||
float percent1 = [[percentArray objectAtIndex:index - 1] floatValue];
|
||||
float percent2 = [[percentArray objectAtIndex:index] floatValue];
|
||||
float percentOffset = (percent - percent1) / (percent2 - percent1);
|
||||
|
||||
float dx = point2.x - point1.x;
|
||||
float dy = point2.y - point1.y;
|
||||
|
||||
// Store dy, dx for retrieving arctan
|
||||
if (slope) {
|
||||
*slope = CGPointMake(dx, dy);
|
||||
}
|
||||
|
||||
// Calculate new point
|
||||
CGFloat newX = point1.x + (percentOffset * dx);
|
||||
CGFloat newY = point1.y + (percentOffset * dy);
|
||||
CGPoint targetPoint = CGPointMake(newX, newY);
|
||||
|
||||
return targetPoint;
|
||||
}
|
||||
|
||||
void getBezierElements(void *info, const CGPathElement *element)
|
||||
{
|
||||
NSMutableArray *bezierElements = (__bridge NSMutableArray *)info;
|
||||
CGPathElementType type = element->type;
|
||||
CGPoint *points = element->points;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case kCGPathElementCloseSubpath:
|
||||
[bezierElements addObject:@[@(type)]];
|
||||
break;
|
||||
case kCGPathElementMoveToPoint:
|
||||
case kCGPathElementAddLineToPoint:
|
||||
[bezierElements addObject:@[@(type), VALUE(0)]];
|
||||
break;
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
[bezierElements addObject:@[@(type), VALUE(0), VALUE(1)]];
|
||||
break;
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
[bezierElements addObject:@[@(type), VALUE(0), VALUE(1), VALUE(2)]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *) bezierElements
|
||||
{
|
||||
NSMutableArray *elements = [NSMutableArray array];
|
||||
CGPathApply(self.CGPath, (__bridge void *)elements, getBezierElements);
|
||||
return elements;
|
||||
}
|
||||
|
||||
+ (UIBezierPath *) pathWithElements: (NSArray *) elements
|
||||
{
|
||||
UIBezierPath *path = [UIBezierPath bezierPath];
|
||||
if (elements.count == 0) return path;
|
||||
|
||||
for (NSArray *points in elements)
|
||||
{
|
||||
if (!points.count) continue;
|
||||
CGPathElementType elementType = [points[0] integerValue];
|
||||
switch (elementType)
|
||||
{
|
||||
case kCGPathElementCloseSubpath:
|
||||
[path closePath];
|
||||
break;
|
||||
case kCGPathElementMoveToPoint:
|
||||
if (points.count == 2)
|
||||
[path moveToPoint:POINT(1)];
|
||||
break;
|
||||
case kCGPathElementAddLineToPoint:
|
||||
if (points.count == 2)
|
||||
[path addLineToPoint:POINT(1)];
|
||||
break;
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
if (points.count == 3)
|
||||
[path addQuadCurveToPoint:POINT(2) controlPoint:POINT(1)];
|
||||
break;
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
if (points.count == 4)
|
||||
[path addCurveToPoint:POINT(3) controlPoint1:POINT(1) controlPoint2:POINT(2)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
@end
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#import "RNSVGBrush.h"
|
||||
#import "RNSVGCGFloatArray.h"
|
||||
#import "RNSVGTextFrame.h"
|
||||
#import "RCTConvert.h"
|
||||
#import "RNSVGCGFCRule.h"
|
||||
|
||||
@interface RCTConvert (RNSVG)
|
||||
|
||||
+ (CGPathRef)CGPath:(id)json;
|
||||
+ (CTTextAlignment)CTTextAlignment:(id)json;
|
||||
+ (RNSVGCGFCRule)RNSVGCGFCRule:(id)json;
|
||||
+ (RNSVGTextFrame)RNSVGTextFrame:(id)json;
|
||||
+ (RNSVGCGFloatArray)RNSVGCGFloatArray:(id)json;
|
||||
+ (RNSVGBrush *)RNSVGBrush:(id)json;
|
||||
|
||||
+ (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGRect)CGRect:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGColorRef)CGColor:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGGradientRef)CGGradient:(id)json offset:(NSUInteger)offset;
|
||||
|
||||
@end
|
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
|
||||
#import "RNSVGLinearGradient.h"
|
||||
#import "RNSVGPattern.h"
|
||||
#import "RNSVGRadialGradient.h"
|
||||
#import "RNSVGSolidColor.h"
|
||||
#import "RCTLog.h"
|
||||
#import "RNSVGCGFCRule.h"
|
||||
|
||||
@implementation RCTConvert (RNSVG)
|
||||
|
||||
+ (CGPathRef)CGPath:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
|
||||
NSUInteger count = [arr count];
|
||||
|
||||
#define NEXT_VALUE [self double:arr[i++]]
|
||||
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, NULL, 0, 0);
|
||||
|
||||
@try {
|
||||
NSUInteger i = 0;
|
||||
while (i < count) {
|
||||
NSUInteger type = [arr[i++] unsignedIntegerValue];
|
||||
switch (type) {
|
||||
case 0:
|
||||
CGPathMoveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 1:
|
||||
CGPathCloseSubpath(path);
|
||||
break;
|
||||
case 2:
|
||||
CGPathAddLineToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 3:
|
||||
CGPathAddCurveToPoint(path, NULL, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE);
|
||||
break;
|
||||
case 4:
|
||||
CGPathAddArc(path, NULL, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE, NEXT_VALUE == 0);
|
||||
break;
|
||||
default:
|
||||
RCTLogError(@"Invalid CGPath type %zd at element %zd of %@", type, i, arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
RCTLogError(@"Invalid CGPath format: %@", arr);
|
||||
CGPathRelease(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
}
|
||||
|
||||
RCT_ENUM_CONVERTER(CTTextAlignment, (@{
|
||||
@"auto": @(kCTTextAlignmentNatural),
|
||||
@"left": @(kCTTextAlignmentLeft),
|
||||
@"center": @(kCTTextAlignmentCenter),
|
||||
@"right": @(kCTTextAlignmentRight),
|
||||
@"justify": @(kCTTextAlignmentJustified),
|
||||
}), kCTTextAlignmentNatural, integerValue)
|
||||
|
||||
RCT_ENUM_CONVERTER(RNSVGCGFCRule, (@{
|
||||
@"evenodd": @(kRNSVGCGFCRuleEvenodd),
|
||||
@"nonzero": @(kRNSVGCGFCRuleNonzero),
|
||||
}), kRNSVGCGFCRuleNonzero, intValue)
|
||||
|
||||
// This takes a tuple of text lines and a font to generate a CTLine for each text line.
|
||||
// This prepares everything for rendering a frame of text in RNSVGText.
|
||||
+ (RNSVGTextFrame)RNSVGTextFrame:(id)json
|
||||
{
|
||||
NSDictionary *dict = [self NSDictionary:json];
|
||||
RNSVGTextFrame frame;
|
||||
frame.count = 0;
|
||||
|
||||
NSArray *lines = [self NSArray:dict[@"lines"]];
|
||||
NSUInteger lineCount = [lines count];
|
||||
if (lineCount == 0) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
NSDictionary *fontDict = dict[@"font"];
|
||||
CTFontRef font = (__bridge CTFontRef)[self UIFont:nil withFamily:fontDict[@"fontFamily"] size:fontDict[@"fontSize"] weight:fontDict[@"fontWeight"] style:fontDict[@"fontStyle"] scaleMultiplier:1.0];
|
||||
if (!font) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Create a dictionary for this font
|
||||
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{
|
||||
(NSString *)kCTFontAttributeName: (__bridge id)font,
|
||||
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
||||
};
|
||||
|
||||
// Set up text frame with font metrics
|
||||
CGFloat size = CTFontGetSize(font);
|
||||
frame.count = lineCount;
|
||||
frame.baseLine = size; // estimate base line
|
||||
frame.lineHeight = size * 1.1; // Base on RNSVG canvas line height estimate
|
||||
frame.lines = malloc(sizeof(CTLineRef) * lineCount);
|
||||
frame.widths = malloc(sizeof(CGFloat) * lineCount);
|
||||
|
||||
[lines enumerateObjectsUsingBlock:^(NSString *text, NSUInteger i, BOOL *stop) {
|
||||
|
||||
CFStringRef string = (__bridge CFStringRef)text;
|
||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||
CTLineRef line = CTLineCreateWithAttributedString(attrString);
|
||||
CFRelease(attrString);
|
||||
|
||||
frame.lines[i] = line;
|
||||
frame.widths[i] = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
|
||||
}];
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
+ (RNSVGCGFloatArray)RNSVGCGFloatArray:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
NSUInteger count = arr.count;
|
||||
|
||||
RNSVGCGFloatArray array;
|
||||
array.count = count;
|
||||
array.array = NULL;
|
||||
|
||||
if (count) {
|
||||
// Ideally, these arrays should already use the same memory layout.
|
||||
// In that case we shouldn't need this new malloc.
|
||||
array.array = malloc(sizeof(CGFloat) * count);
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
array.array[i] = [arr[i] doubleValue];
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
+ (RNSVGBrush *)RNSVGBrush:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
NSUInteger type = [self NSUInteger:arr.firstObject];
|
||||
|
||||
switch (type) {
|
||||
case 0: // solid color
|
||||
// These are probably expensive allocations since it's often the same value.
|
||||
// We should memoize colors but look ups may be just as expensive.
|
||||
return [[RNSVGSolidColor alloc] initWithArray:arr];
|
||||
case 1: // linear gradient
|
||||
return [[RNSVGLinearGradient alloc] initWithArray:arr];
|
||||
case 2: // radial gradient
|
||||
return [[RNSVGRadialGradient alloc] initWithArray:arr];
|
||||
case 3: // pattern
|
||||
// TODO:
|
||||
return nil;
|
||||
return [[RNSVGPattern alloc] initWithArray:arr];
|
||||
default:
|
||||
RCTLogError(@"Unknown brush type: %zd", type);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 2) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", 2 + offset, arr);
|
||||
return CGPointZero;
|
||||
}
|
||||
return (CGPoint){
|
||||
[self CGFloat:arr[offset]],
|
||||
[self CGFloat:arr[offset + 1]],
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGRect)CGRect:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", 4 + offset, arr);
|
||||
return CGRectZero;
|
||||
}
|
||||
return (CGRect){
|
||||
{[self CGFloat:arr[offset]], [self CGFloat:arr[offset + 1]]},
|
||||
{[self CGFloat:arr[offset + 2]], [self CGFloat:arr[offset + 3]]},
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGColorRef)CGColor:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", 4 + offset, arr);
|
||||
return NULL;
|
||||
}
|
||||
return [self CGColor:[arr subarrayWithRange:(NSRange){offset, 4}]];
|
||||
}
|
||||
|
||||
+ (CGGradientRef)CGGradient:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", offset, arr);
|
||||
return NULL;
|
||||
}
|
||||
arr = [arr subarrayWithRange:(NSRange){offset, arr.count - offset}];
|
||||
RNSVGCGFloatArray colorsAndOffsets = [self RNSVGCGFloatArray:arr];
|
||||
size_t stops = colorsAndOffsets.count / 5;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
CGGradientRef gradient = CGGradientCreateWithColorComponents(
|
||||
rgb,
|
||||
colorsAndOffsets.array,
|
||||
colorsAndOffsets.array + stops * 4,
|
||||
stops
|
||||
);
|
||||
CGColorSpaceRelease(rgb);
|
||||
free(colorsAndOffsets.array);
|
||||
return (CGGradientRef)CFAutorelease(gradient);
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
typedef CF_ENUM(int32_t, RNSVGCGFCRule) {
|
||||
kRNSVGCGFCRuleEvenodd,
|
||||
kRNSVGCGFCRuleNonzero
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// A little helper to make sure we have the right memory allocation ready for use.
|
||||
// We assume that we will only this in one place so no reference counting is necessary.
|
||||
// Needs to be freed when dealloced.
|
||||
|
||||
// This is fragile since this relies on these values not getting reused. Consider
|
||||
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
CGFloat *array;
|
||||
} RNSVGCGFloatArray;
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface RNSVGPercentageConverter : NSObject
|
||||
|
||||
- (NSRegularExpression *) getPercentageRegularExpression;
|
||||
|
||||
- (float) percentageToFloat:(NSString *)percentage relative:(float)relative offset:(float)offset;
|
||||
|
||||
- (float) stringToFloat:(NSString *)string relative:(float)relative offset:(float)offset;
|
||||
|
||||
- (BOOL) isPercentage:(NSString *) string;
|
||||
|
||||
@end
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGPercentageConverter.h"
|
||||
|
||||
@implementation RNSVGPercentageConverter
|
||||
{
|
||||
NSRegularExpression *percentageRegularExpression;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
percentageRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"^(\\-?\\d+(?:\\.\\d+)?)%$" options:0 error:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSRegularExpression *) getPercentageRegularExpression
|
||||
{
|
||||
return percentageRegularExpression;
|
||||
}
|
||||
|
||||
- (float) stringToFloat:(NSString *)percentage relative:(float)relative offset:(float)offset
|
||||
{
|
||||
if ([self isPercentage:percentage] == NO) {
|
||||
return [percentage floatValue];
|
||||
} else {
|
||||
return [self percentageToFloat:percentage relative:relative offset:offset];
|
||||
}
|
||||
}
|
||||
|
||||
- (float) percentageToFloat:(NSString *)percentage relative:(float)relative offset:(float)offset
|
||||
{
|
||||
|
||||
|
||||
__block float matched;
|
||||
[percentageRegularExpression enumerateMatchesInString:percentage
|
||||
options:0
|
||||
range:NSMakeRange(0, percentage.length)
|
||||
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
|
||||
{
|
||||
|
||||
matched = [[percentage substringWithRange:NSMakeRange(result.range.location, result.range.length)] floatValue];
|
||||
matched = matched / 100 * relative + offset;
|
||||
}];
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
- (BOOL) isPercentage:(NSString *) string
|
||||
{
|
||||
return [percentageRegularExpression firstMatchInString:string options:0 range:NSMakeRange(0, [string length])] != NULL;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGRenderableManager.h"
|
||||
|
||||
@interface RNSVGCircleManager : RNSVGRenderableManager
|
||||
|
||||
@end
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGCircleManager.h"
|
||||
|
||||
#import "RNSVGCircle.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
|
||||
@implementation RNSVGCircleManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RNSVGRenderable *)node
|
||||
{
|
||||
return [RNSVGCircle new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(cx, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(cy, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(r, NSString)
|
||||
|
||||
// fix me: these should inherited from renderable
|
||||
RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(fillRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(stroke, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipPath, CGPath)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDasharray, RNSVGCGFloatArray)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDashoffset, CGFloat)
|
||||
|
||||
@end
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGRenderableManager.h"
|
||||
|
||||
@interface RNSVGEllipseManager : RNSVGRenderableManager
|
||||
|
||||
@end
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGEllipseManager.h"
|
||||
|
||||
#import "RNSVGEllipse.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
|
||||
@implementation RNSVGEllipseManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RNSVGRenderable *)node
|
||||
{
|
||||
return [RNSVGEllipse new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(cx, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(cy, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(rx, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(ry, NSString)
|
||||
|
||||
// fix me: these should inherited from renderable
|
||||
RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(fillRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(stroke, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipPath, CGPath)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDasharray, RNSVGCGFloatArray)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDashoffset, CGFloat)
|
||||
|
||||
@end
|
|
@ -20,7 +20,10 @@ RCT_EXPORT_MODULE()
|
|||
return [RNSVGImage new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(layout, NSDictionary)
|
||||
RCT_EXPORT_VIEW_PROPERTY(x, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(y, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(width, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(height, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(src, id)
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGRenderableManager.h"
|
||||
|
||||
@interface RNSVGLineManager : RNSVGRenderableManager
|
||||
|
||||
@end
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGLineManager.h"
|
||||
|
||||
#import "RNSVGLine.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
|
||||
@implementation RNSVGLineManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RNSVGRenderable *)node
|
||||
{
|
||||
return [RNSVGLine new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(x1, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(y1, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(x2, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(y2, NSString)
|
||||
|
||||
// fix me: these should inherited from renderable
|
||||
RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(fillRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(stroke, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipPath, CGPath)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDasharray, RNSVGCGFloatArray)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDashoffset, CGFloat)
|
||||
|
||||
@end
|
|
@ -16,17 +16,17 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (RNSVGNode *)node
|
||||
{
|
||||
return [RNSVGNode new];
|
||||
return [RNSVGNode new];
|
||||
}
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [self node];
|
||||
return [self node];
|
||||
}
|
||||
|
||||
- (RCTShadowView *)shadowView
|
||||
{
|
||||
return nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGRenderableManager.h"
|
||||
|
||||
@interface RNSVGRectManager : RNSVGRenderableManager
|
||||
|
||||
@end
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#import "RNSVGRectManager.h"
|
||||
|
||||
#import "RNSVGRect.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
|
||||
@implementation RNSVGRectManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RNSVGRenderable *)node
|
||||
{
|
||||
return [RNSVGRect new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(x, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(y, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(width, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(height, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(rx, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(ry, NSString)
|
||||
|
||||
// fix me: these should inherited from renderable
|
||||
RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(fillRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(stroke, RNSVGBrush)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipPath, CGPath)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clipRule, RNSVGCGFCRule)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDasharray, RNSVGCGFloatArray)
|
||||
RCT_EXPORT_VIEW_PROPERTY(strokeDashoffset, CGFloat)
|
||||
|
||||
@end
|
|
@ -17,7 +17,7 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (RNSVGRenderable *)node
|
||||
{
|
||||
return [RNSVGShape new];
|
||||
return [RNSVGShape new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(shape, NSDictionary)
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
#import "RNSVGSvgViewManager.h"
|
||||
|
||||
#import "RNSVGSvgView.h"
|
||||
|
||||
@implementation RNSVGSvgViewManager
|
||||
|
|
|
@ -24,4 +24,6 @@ RCT_EXPORT_VIEW_PROPERTY(alignment, CTTextAlignment)
|
|||
RCT_REMAP_VIEW_PROPERTY(frame, textFrame, RNSVGTextFrame)
|
||||
RCT_EXPORT_VIEW_PROPERTY(path, CGPath)
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import Touchable from 'react-native/Libraries/Components/Touchable/Touchable';
|
||||
const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
|
||||
export default {
|
||||
...Touchable.Mixin,
|
||||
touchableHandlePress: function(e) {
|
||||
this.props.onPress && this.props.onPress(e);
|
||||
},
|
||||
|
||||
touchableHandleActivePressIn: function(e) {
|
||||
this.props.onPressIn && this.props.onPressIn(e);
|
||||
},
|
||||
|
||||
touchableHandleActivePressOut: function(e) {
|
||||
this.props.onPressOut && this.props.onPressOut(e);
|
||||
},
|
||||
|
||||
touchableHandleLongPress: function(e) {
|
||||
this.props.onLongPress && this.props.onLongPress(e);
|
||||
},
|
||||
|
||||
touchableGetPressRectOffset: function() {
|
||||
return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET;
|
||||
},
|
||||
|
||||
touchableGetHitSlop: function() {
|
||||
return this.props.hitSlop;
|
||||
},
|
||||
|
||||
touchableGetHighlightDelayMS: function() {
|
||||
return this.props.delayPressIn || 0;
|
||||
},
|
||||
|
||||
touchableGetLongPressDelayMS: function() {
|
||||
return this.props.delayLongPress === 0 ? 0 :
|
||||
this.props.delayLongPress || 500;
|
||||
},
|
||||
|
||||
touchableGetPressOutDelayMS: function() {
|
||||
return this.props.delayPressOut || 0;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
import _ from 'lodash';
|
||||
import ReactNativeViewAttributes from 'react-native/Libraries/Components/View/ReactNativeViewAttributes';
|
||||
|
||||
function arrayDiffer(a, b) {
|
||||
if (_.isNil(a)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.length !== b.length) {
|
||||
return true;
|
||||
}
|
||||
|
@ -57,6 +59,7 @@ function fontAndLinesDiffer(a, b) {
|
|||
}
|
||||
|
||||
const NodeAttributes = {
|
||||
...ReactNativeViewAttributes.UIView,
|
||||
transform: {
|
||||
diff: arrayDiffer
|
||||
},
|
||||
|
|
|
@ -2,14 +2,16 @@ import extractFill from './extractFill';
|
|||
import extractStroke from './extractStroke';
|
||||
import extractTransform from './extractTransform';
|
||||
import extractClipping from './extractClipping';
|
||||
import extractResponder from './extractResponder';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default function(props, options = {stroke: true, transform: true, fill: true}) {
|
||||
export default function(props, options = {stroke: true, transform: true, fill: true, responder: true}) {
|
||||
if (props.visible === false) {
|
||||
return {
|
||||
opacity: 0
|
||||
};
|
||||
}
|
||||
|
||||
let extractedProps = {
|
||||
opacity: +props.opacity || 1
|
||||
};
|
||||
|
@ -30,5 +32,9 @@ export default function(props, options = {stroke: true, transform: true, fill: t
|
|||
extractedProps.transform = extractTransform(props);
|
||||
}
|
||||
|
||||
if (options.responder) {
|
||||
_.assign(extractedProps, extractResponder(props));
|
||||
}
|
||||
|
||||
return extractedProps;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import {responderPropsKeys} from '../props';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default function (props) {
|
||||
return _.pick(props, responderPropsKeys);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import _ from 'lodash';
|
||||
|
||||
export default function (props, context) {
|
||||
if (context.isInGroup) {
|
||||
props = _.defaults({}, props, context, {
|
||||
isInGroup: null
|
||||
});
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
34
lib/props.js
34
lib/props.js
|
@ -1,7 +1,32 @@
|
|||
import {PropTypes} from 'react';
|
||||
import {PanResponder} from 'react-native';
|
||||
|
||||
const numberProp = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
||||
|
||||
|
||||
const touchableProps = {
|
||||
disabled: PropTypes.bool,
|
||||
onPress: PropTypes.func,
|
||||
onPressIn: PropTypes.func,
|
||||
onPressOut: PropTypes.func,
|
||||
onLongPress: PropTypes.func,
|
||||
delayPressIn: PropTypes.number,
|
||||
delayPressOut: PropTypes.number,
|
||||
delayLongPress: PropTypes.number
|
||||
};
|
||||
|
||||
const touchablePropsKeys = Object.keys(touchableProps);
|
||||
|
||||
const responderPropsKeys = [
|
||||
...Object.keys(PanResponder.create({onStartShouldSetPanResponder: () => {}}).panHandlers),
|
||||
'pointerEvents'
|
||||
];
|
||||
|
||||
const responderProps = responderPropsKeys.reduce((props, name) => {
|
||||
props[name] = PropTypes.func;
|
||||
return props;
|
||||
}, {});
|
||||
|
||||
const fillProps = {
|
||||
fill: PropTypes.string,
|
||||
fillOpacity: numberProp,
|
||||
|
@ -50,7 +75,8 @@ const pathProps = {
|
|||
...fillProps,
|
||||
...strokeProps,
|
||||
...clipProps,
|
||||
...transformProps
|
||||
...transformProps,
|
||||
...responderProps
|
||||
};
|
||||
|
||||
const circleProps = {
|
||||
|
@ -104,5 +130,9 @@ export {
|
|||
lineProps,
|
||||
rectProps,
|
||||
contextProps,
|
||||
pathProps
|
||||
pathProps,
|
||||
responderProps,
|
||||
responderPropsKeys,
|
||||
touchableProps,
|
||||
touchablePropsKeys
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче