refactor clipPath native code

refactor clipPath native code
add strokeMiterlimit prop support
This commit is contained in:
Horcrux
2016-05-21 19:58:49 +08:00
parent bb9380b049
commit 6a0c47a898
30 changed files with 305 additions and 152 deletions
+20
View File
@@ -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 "RNSVGContainer.h"
#import "RNSVGGroup.h"
#import "RNSVGSvgView.h"
@interface RNSVGClipPath : RNSVGGroup
@property (nonatomic, strong) NSString *name;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
@end
+25
View File
@@ -0,0 +1,25 @@
/**
* 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 "RNSVGClipPath.h"
@implementation RNSVGClipPath
- (void)renderLayerTo:(CGContextRef)context
{
[[self getSvgView] defineClipPath:[self getPath:context] clipPathId:self.name];
}
// hitTest delagate
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@end
+2 -4
View File
@@ -7,16 +7,14 @@
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "RNSVGContainer.h"
#import "RNSVGNode.h"
#import "RNSVGCGFCRule.h"
#import "RNSVGSvgView.h"
#import "RNSVGNode.h"
@interface RNSVGGroup : RNSVGNode <RNSVGContainer>
@property (nonatomic, strong) NSString *asClipPath; // Current group is a <ClipPath /> element and asClipPath is its id.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (RNSVGSvgView *)getSvgView;
@end
+8 -21
View File
@@ -11,20 +11,16 @@
@implementation RNSVGGroup
- (void)renderLayerTo:(CGContextRef)context
{
if (self.asClipPath == NULL) {
RNSVGSvgView* svg = [self getSvgView];
[self clip:context];
{
RNSVGSvgView* svg = [self getSvgView];
[self clip:context];
for (RNSVGNode *node in self.subviews) {
[node renderTo:context];
for (RNSVGNode *node in self.subviews) {
[node renderTo:context];
if (node.touchable && !svg.touchable) {
self.touchable = YES;
}
if (node.touchable && !svg.touchable) {
self.touchable = YES;
}
} else {
[self defineClipPath:[self getPath:context] clipPathId:self.asClipPath];
}
}
@@ -51,14 +47,5 @@
return nil;
}
- (RNSVGSvgView *)getSvgView
{
UIView *parent = self.superview;
while ([parent class] != [RNSVGSvgView class]) {
parent = parent.superview;
}
return (RNSVGSvgView *)parent;
}
@end
+4
View File
@@ -81,6 +81,10 @@
// add hit area
CGPathAddPath(self.nodeArea, nil, CGPathCreateWithRect(CGRectMake(x, y, w, h), nil));
if (self.opacity == 0) {
return;
}
[self clip:context];
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0, h);
+13 -7
View File
@@ -31,12 +31,22 @@
return;
}
CGPathDrawingMode mode = kCGPathStroke;
BOOL fillColor = YES;
// Add path to nodeArea
CGPathAddPath(self.nodeArea, nil, _d);
if (self.stroke) {
// Add stroke to nodeArea
CGPathRef strokePath = CGPathCreateCopyByStrokingPath(_d, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit);
CGPathAddPath(self.nodeArea, nil, strokePath);
}
if (self.opacity == 0) {
return;
}
CGPathDrawingMode mode = kCGPathStroke;
BOOL fillColor = YES;
if (self.fill) {
mode = self.fillRule == kRNSVGCGFCRuleEvenodd ? kCGPathEOFill : kCGPathFill;
fillColor = [self.fill applyFillColor:context];
@@ -55,10 +65,6 @@
}
}
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);
+9
View File
@@ -14,4 +14,13 @@
@property (nonatomic, assign) BOOL touchable;
/**
* define <ClipPath></ClipPath> content as clipPath template.
*/
- (void)defineClipPath:(CGPathRef)clipPath clipPathId:(NSString *)clipPathId;
- (void)removeClipPath:(NSString *)clipPathId;
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathId;
@end
+23
View File
@@ -12,6 +12,9 @@
#import "RCTLog.h"
@implementation RNSVGSvgView
{
NSMutableDictionary *clipPaths;
}
- (void)invalidate
{
@@ -41,4 +44,24 @@
return self.touchable ? [super hitTest:point withEvent:event] : nil;
}
- (void)defineClipPath:(CGPathRef)clipPath clipPathId:(NSString *)clipPathId
{
if (clipPaths == NULL) {
clipPaths = [[NSMutableDictionary alloc] init];
}
[clipPaths setValue:[NSValue valueWithPointer:clipPath] forKey:clipPathId];
}
- (void)removeClipPath:(NSString *)clipPathId
{
if (clipPaths != NULL) {
[clipPaths removeObjectForKey:clipPathId];
}
}
- (CGPathRef)getDefinedClipPath:(NSString *)clipPathId
{
return [[clipPaths valueForKey:clipPathId] pointerValue];
}
@end