Merge remote-tracking branch 'msand/NestedSvg' into merge-test

# Conflicts:
#	ios/Elements/RNSVGGroup.m
#	ios/RNSVGNode.h
#	ios/RNSVGNode.m
This commit is contained in:
Mikael Sand
2018-03-18 23:41:58 +02:00
29 changed files with 449 additions and 270 deletions
+3 -1
View File
@@ -19,7 +19,9 @@
- (void)parseReference
{
[self traverseSubviews:^(RNSVGNode *node) {
[node parseReference];
if ([node isKindOfClass:[RNSVGNode class]]) {
[node parseReference];
}
return YES;
}];
}
+2 -2
View File
@@ -18,8 +18,8 @@
@property (nonatomic, strong) NSDictionary *font;
- (void)renderPathTo:(CGContextRef)context;
- (void)renderGroupTo:(CGContextRef)context;
- (void)renderPathTo:(CGContextRef)context rect:(CGRect)rect;
- (void)renderGroupTo:(CGContextRef)context rect:(CGRect)rect;
- (RNSVGGlyphContext *)getGlyphContext;
- (void)pushGlyphContext;
+41 -33
View File
@@ -23,30 +23,40 @@
_font = font;
}
- (void)renderLayerTo:(CGContextRef)context
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
{
[self clip:context];
[self setupGlyphContext:context];
[self renderGroupTo:context];
[self renderGroupTo:context rect:rect];
}
- (void)renderGroupTo:(CGContextRef)context
- (void)renderGroupTo:(CGContextRef)context rect:(CGRect)rect
{
[self pushGlyphContext];
[self traverseSubviews:^(RNSVGNode *node) {
if (node.responsible && !self.svgView.responsible) {
self.svgView.responsible = YES;
}
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node mergeProperties:self];
}
[self traverseSubviews:^(UIView *node) {
if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode* svgNode = (RNSVGNode*)node;
if (svgNode.responsible && !self.svgView.responsible) {
self.svgView.responsible = YES;
}
[node renderTo:context];
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node mergeProperties:self];
}
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node resetProperties];
[svgNode renderTo:context rect:rect];
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node resetProperties];
}
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
RNSVGSvgView* svgView = (RNSVGSvgView*)node;
CGRect rect = CGRectMake(0, 0, [svgView.bbWidth floatValue], [svgView.bbHeight floatValue]);
CGContextClipToRect(context, rect);
[svgView drawToContext:context withRect:(CGRect)rect];
} else {
[node drawRect:rect];
}
return YES;
@@ -81,42 +91,37 @@
[[self.textRoot getGlyphContext] popContext];
}
- (void)renderPathTo:(CGContextRef)context
- (void)renderPathTo:(CGContextRef)context rect:(CGRect)rect
{
[super renderLayerTo:context];
[super renderLayerTo:context rect:rect];
}
- (CGPathRef)getPath:(CGContextRef)context
{
CGMutablePathRef __block path = CGPathCreateMutable();
[self traverseSubviews:^(RNSVGNode *node) {
CGAffineTransform transform = node.matrix;
CGPathAddPath(path, &transform, [node getPath:context]);
if ([node isKindOfClass:[RNSVGNode class]]) {
CGAffineTransform transform = node.matrix;
CGPathAddPath(path, &transform, [node getPath:context]);
}
return YES;
}];
return (CGPathRef)CFAutorelease(path);
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transform
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitSelf = [super hitTest:point withEvent:event withTransform:transform];
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
UIView *hitSelf = [super hitTest:transformed withEvent:event];
if (hitSelf) {
return hitSelf;
}
CGAffineTransform matrix = CGAffineTransformConcat(self.matrix, transform);
CGPathRef clip = [self getClipPath];
if (clip) {
CGPathRef transformedClipPath = CGPathCreateCopyByTransformingPath(clip, &matrix);
BOOL insideClipPath = CGPathContainsPoint(clip, nil, point, self.clipRule == kRNSVGCGFCRuleEvenodd);
CGPathRelease(transformedClipPath);
if (!insideClipPath) {
return nil;
}
if (clip && !CGPathContainsPoint(clip, nil, transformed, self.clipRule == kRNSVGCGFCRuleEvenodd)) {
return nil;
}
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
@@ -130,13 +135,14 @@
return node;
}
UIView *hitChild = [node hitTest: point withEvent:event withTransform:matrix];
UIView *hitChild = [node hitTest:transformed withEvent:event];
if (hitChild) {
node.active = YES;
return (node.responsible || (node != hitChild)) ? hitChild : self;
}
}
return nil;
}
@@ -148,7 +154,9 @@
}
[self traverseSubviews:^(__kindof RNSVGNode *node) {
[node parseReference];
if ([node isKindOfClass:[RNSVGNode class]]) {
[node parseReference];
}
return YES;
}];
}
+8
View File
@@ -15,6 +15,8 @@
@interface RNSVGSvgView : UIView <RNSVGContainer>
@property (nonatomic, strong) NSString *bbWidth;
@property (nonatomic, strong) NSString *bbHeight;
@property (nonatomic, assign) CGFloat minX;
@property (nonatomic, assign) CGFloat minY;
@property (nonatomic, assign) CGFloat vbWidth;
@@ -22,6 +24,8 @@
@property (nonatomic, strong) NSString *align;
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
@property (nonatomic, assign) BOOL responsible;
@property (nonatomic, assign) CGRect boundingBox;
/**
* define <ClipPath></ClipPath> content as clipPath template.
@@ -42,4 +46,8 @@
- (CGRect)getContextBounds;
- (void)drawRect:(CGRect)rect;
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect;
@end
+61 -30
View File
@@ -16,8 +16,8 @@
NSMutableDictionary<NSString *, RNSVGNode *> *_clipPaths;
NSMutableDictionary<NSString *, RNSVGNode *> *_templates;
NSMutableDictionary<NSString *, RNSVGPainter *> *_painters;
CGRect _boundingBox;
CGAffineTransform _viewBoxTransform;
CGAffineTransform _invviewBoxTransform;
}
- (instancetype)initWithFrame:(CGRect)frame
@@ -58,7 +58,7 @@
if (minX == _minX) {
return;
}
[self invalidate];
_minX = minX;
}
@@ -68,7 +68,7 @@
if (minY == _minY) {
return;
}
[self invalidate];
_minY = minY;
}
@@ -78,7 +78,7 @@
if (vbWidth == _vbWidth) {
return;
}
[self invalidate];
_vbWidth = vbWidth;
}
@@ -88,17 +88,37 @@
if (_vbHeight == vbHeight) {
return;
}
[self invalidate];
_vbHeight = vbHeight;
}
- (void)setBBWidth:(NSString *)bbWidth
{
if ([bbWidth isEqualToString:_bbWidth]) {
return;
}
[self invalidate];
_bbWidth = bbWidth;
}
- (void)setBBHeight:(NSString *)bbHeight
{
if ([bbHeight isEqualToString:_bbHeight]) {
return;
}
[self invalidate];
_bbHeight = bbHeight;
}
- (void)setAlign:(NSString *)align
{
if ([align isEqualToString:_align]) {
return;
}
[self invalidate];
_align = align;
}
@@ -108,11 +128,32 @@
if (meetOrSlice == _meetOrSlice) {
return;
}
[self invalidate];
_meetOrSlice = meetOrSlice;
}
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect {
if (self.align) {
_viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
eRect:rect
align:self.align
meetOrSlice:self.meetOrSlice];
_invviewBoxTransform = CGAffineTransformInvert(_viewBoxTransform);
CGContextConcatCTM(context, _viewBoxTransform);
}
for (UIView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode *svg = (RNSVGNode *)node;
[svg renderTo:context rect:rect];
} else {
[node drawRect:rect];
}
}
}
- (void)drawRect:(CGRect)rect
{
_clipPaths = nil;
@@ -120,48 +161,38 @@
_painters = nil;
_boundingBox = rect;
CGContextRef context = UIGraphicsGetCurrentContext();
if (self.align) {
_viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
eRect:rect
align:self.align
meetOrSlice:self.meetOrSlice];
CGContextConcatCTM(context, _viewBoxTransform);
}
for (RNSVGNode *node in self.subviews) {
for (UIView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGNode class]]) {
if (node.responsible && !self.responsible) {
RNSVGNode *svg = (RNSVGNode *)node;
if (svg.responsible && !self.responsible) {
self.responsible = YES;
}
[node parseReference];
}
}
for (RNSVGNode *node in self.subviews) {
if ([node isKindOfClass:[RNSVGNode class]]) {
[node renderTo:context];
[svg parseReference];
}
}
[self drawToContext:context withRect:rect];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if (self.align) {
CGPoint transformed = CGPointApplyAffineTransform(point, _invviewBoxTransform);
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
if (![node isKindOfClass:[RNSVGNode class]]) {
continue;
}
if (event) {
node.active = NO;
} else if (node.active) {
return node;
}
UIView *hitChild = [node hitTest: point withEvent:event withTransform:_viewBoxTransform];
UIView *hitChild = [node hitTest:transformed withEvent:event];
if (hitChild) {
node.active = YES;
return (node.responsible || (node != hitChild)) ? hitChild : self;
+3 -3
View File
@@ -72,15 +72,15 @@
_meetOrSlice = meetOrSlice;
}
- (void)renderTo:(CGContextRef)context
- (void)renderTo:(CGContextRef)context rect:(CGRect)rect
{
// Do not render Symbol
}
- (void)renderSymbolTo:(CGContextRef)context width:(CGFloat)width height:(CGFloat)height
{
CGRect eRect = CGRectMake(0, 0, width, height);
if (self.align) {
CGRect eRect = CGRectMake(0, 0, width, height);
CGAffineTransform viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
eRect:eRect
@@ -89,7 +89,7 @@
CGContextConcatCTM(context, viewBoxTransform);
}
[self renderGroupTo:context];
[self renderGroupTo:context rect:eRect];
}
@end
+2 -2
View File
@@ -22,7 +22,7 @@
}
- (void)renderLayerTo:(CGContextRef)context
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
{
RNSVGNode* template = [self.svgView getDefinedTemplate:self.href];
if (template) {
@@ -37,7 +37,7 @@
RNSVGSymbol *symbol = (RNSVGSymbol*)template;
[symbol renderSymbolTo:context width:[self relativeOnWidth:self.width] height:[self relativeOnWidth:self.height]];
} else {
[template renderTo:context];
[template renderTo:context rect:rect];
}
if ([template isKindOfClass:[RNSVGRenderable class]]) {