From b5eeb1ee72913a902d9fd3af53a09ac297c7bbba Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Wed, 21 Feb 2018 00:48:03 +0200 Subject: [PATCH] Allow nesting React-Native View components inside svg --- ios/Elements/RNSVGGroup.h | 4 ++-- ios/Elements/RNSVGGroup.m | 14 +++++++------- ios/Elements/RNSVGSvgView.m | 6 +++--- ios/Elements/RNSVGSymbol.m | 6 +++--- ios/Elements/RNSVGUse.m | 4 ++-- ios/RNSVGNode.h | 4 ++-- ios/RNSVGNode.m | 16 ++++------------ ios/RNSVGRenderable.m | 6 +++--- ios/Text/RNSVGTSpan.m | 6 +++--- ios/Text/RNSVGText.m | 8 ++++---- ios/Text/RNSVGTextPath.m | 4 ++-- 11 files changed, 35 insertions(+), 43 deletions(-) diff --git a/ios/Elements/RNSVGGroup.h b/ios/Elements/RNSVGGroup.h index 163d8477..44020140 100644 --- a/ios/Elements/RNSVGGroup.h +++ b/ios/Elements/RNSVGGroup.h @@ -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; diff --git a/ios/Elements/RNSVGGroup.m b/ios/Elements/RNSVGGroup.m index 2acab72c..60397c16 100644 --- a/ios/Elements/RNSVGGroup.m +++ b/ios/Elements/RNSVGGroup.m @@ -23,14 +23,14 @@ _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]; RNSVGSvgView* svg = [self getSvgView]; @@ -45,7 +45,7 @@ [(RNSVGRenderable*)node mergeProperties:self]; } - [svgNode renderTo:context]; + [svgNode renderTo:context rect:rect]; if ([node isKindOfClass:[RNSVGRenderable class]]) { [(RNSVGRenderable*)node resetProperties]; @@ -56,7 +56,7 @@ CGContextClipToRect(context, rect); [svgView drawToContext:context withRect:(CGRect)rect]; } else { - RCTLogWarn(@"Not a RNSVGNode: %@", node.class); + [node drawRect:rect]; } return YES; @@ -90,9 +90,9 @@ [[[self getTextRoot] 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 diff --git a/ios/Elements/RNSVGSvgView.m b/ios/Elements/RNSVGSvgView.m index 8c2e032d..4bf9f3ce 100644 --- a/ios/Elements/RNSVGSvgView.m +++ b/ios/Elements/RNSVGSvgView.m @@ -135,7 +135,9 @@ for (UIView *node in self.subviews) { if ([node isKindOfClass:[RNSVGNode class]]) { RNSVGNode *svg = (RNSVGNode *)node; - [svg renderTo:context]; + [svg renderTo:context rect:rect]; + } else { + [node drawRect:rect]; } } } @@ -156,8 +158,6 @@ } [svg parseReference]; - } else { - RCTLogWarn(@"Not a RNSVGNode: %@", node.class); } } diff --git a/ios/Elements/RNSVGSymbol.m b/ios/Elements/RNSVGSymbol.m index d4fcfc34..8f3b41f0 100644 --- a/ios/Elements/RNSVGSymbol.m +++ b/ios/Elements/RNSVGSymbol.m @@ -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 diff --git a/ios/Elements/RNSVGUse.m b/ios/Elements/RNSVGUse.m index 075b4158..8656921e 100644 --- a/ios/Elements/RNSVGUse.m +++ b/ios/Elements/RNSVGUse.m @@ -22,7 +22,7 @@ } -- (void)renderLayerTo:(CGContextRef)context +- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect { RNSVGNode* template = [[self getSvgView] 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]]) { diff --git a/ios/RNSVGNode.h b/ios/RNSVGNode.h index b57e8f96..96d1d924 100644 --- a/ios/RNSVGNode.h +++ b/ios/RNSVGNode.h @@ -39,14 +39,14 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE; - (RNSVGGroup *)getTextRoot; - (RNSVGGroup *)getParentTextRoot; -- (void)renderTo:(CGContextRef)context; +- (void)renderTo:(CGContextRef)context rect:(CGRect)rect; /** * renderTo will take opacity into account and draw renderLayerTo off-screen if there is opacity * specified, then composite that onto the context. renderLayerTo always draws at opacity=1. * @abstract */ -- (void)renderLayerTo:(CGContextRef)context; +- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect; /** * get clipPath from cache diff --git a/ios/RNSVGNode.m b/ios/RNSVGNode.m index e7a19df6..bca9585d 100644 --- a/ios/RNSVGNode.m +++ b/ios/RNSVGNode.m @@ -159,7 +159,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; } } -- (void)renderTo:(CGContextRef)context +- (void)renderTo:(CGContextRef)context rect:(CGRect)rect { // abstract } @@ -199,7 +199,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; return nil; } -- (void)renderLayerTo:(CGContextRef)context +- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect { // abstract } @@ -313,16 +313,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; - (void)traverseSubviews:(BOOL (^)(__kindof UIView *node))block { for (UIView *node in self.subviews) { - if ([node isKindOfClass:[RNSVGNode class]]) { - if (!block(node)) { - break; - } - } else if ([node isKindOfClass:[RNSVGSvgView class]]) { - if (!block(node)) { - break; - } - } else { - RCTLogWarn(@"Not a RNSVGNode: %@", node.class); + if (!block(node)) { + break; } } } diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index f7c0e72b..626e7aea 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -157,7 +157,7 @@ } } -- (void)renderTo:(CGContextRef)context +- (void)renderTo:(CGContextRef)context rect:(CGRect)rect { // This needs to be painted on a layer before being composited. CGContextSaveGState(context); @@ -165,14 +165,14 @@ CGContextSetAlpha(context, self.opacity); [self beginTransparencyLayer:context]; - [self renderLayerTo:context]; + [self renderLayerTo:context rect:rect]; [self endTransparencyLayer:context]; CGContextRestoreGState(context); } -- (void)renderLayerTo:(CGContextRef)context +- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect { if (!self.fill && !self.stroke) { return; diff --git a/ios/Text/RNSVGTSpan.m b/ios/Text/RNSVGTSpan.m index bd4deaee..abbe956c 100644 --- a/ios/Text/RNSVGTSpan.m +++ b/ios/Text/RNSVGTSpan.m @@ -46,13 +46,13 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; _content = content; } -- (void)renderLayerTo:(CGContextRef)context +- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect { if (self.content) { - [self renderPathTo:context]; + [self renderPathTo:context rect:rect]; } else { [self clip:context]; - [self renderGroupTo:context]; + [self renderGroupTo:context rect:rect]; } } diff --git a/ios/Text/RNSVGText.m b/ios/Text/RNSVGText.m index 28f665a9..26133afc 100644 --- a/ios/Text/RNSVGText.m +++ b/ios/Text/RNSVGText.m @@ -19,14 +19,14 @@ RNSVGGlyphContext *_glyphContext; } -- (void)renderLayerTo:(CGContextRef)context +- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect { [self clip:context]; CGContextSaveGState(context); [self setupGlyphContext:context]; CGPathRef path = [self getGroupPath:context]; - [self renderGroupTo:context]; + [self renderGroupTo:context rect:rect]; [self releaseCachedPath]; CGContextRestoreGState(context); @@ -69,10 +69,10 @@ return (CGPathRef)CFAutorelease(CGPathCreateCopyByTransformingPath(groupPath, &CGAffineTransformIdentity)); } -- (void)renderGroupTo:(CGContextRef)context +- (void)renderGroupTo:(CGContextRef)context rect:(CGRect)rect { [self pushGlyphContext]; - [super renderGroupTo:context]; + [super renderGroupTo:context rect:rect]; [self popGlyphContext]; } diff --git a/ios/Text/RNSVGTextPath.m b/ios/Text/RNSVGTextPath.m index 1bf7bbbc..e74e54fa 100644 --- a/ios/Text/RNSVGTextPath.m +++ b/ios/Text/RNSVGTextPath.m @@ -209,9 +209,9 @@ void RNSVGPerformanceBezier_addLine(CGPoint *last, const CGPoint *next, NSMutabl *linesP = lines; } -- (void)renderLayerTo:(CGContextRef)context +- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect { - [self renderGroupTo:context]; + [self renderGroupTo:context rect:rect]; } - (CGPathRef)getPath:(CGContextRef)context