diff --git a/ios/Elements/RNSVGGroup.m b/ios/Elements/RNSVGGroup.m index b6ff3872..b8caee79 100644 --- a/ios/Elements/RNSVGGroup.m +++ b/ios/Elements/RNSVGGroup.m @@ -24,7 +24,7 @@ }]; [self traverseSubviews:^(RNSVGNode *node) { - [node mergeProperties:self mergeList:self.ownedPropList inherited:YES]; + [node mergeProperties:self mergeList:self.attributeList inherited:YES]; [node renderTo:context]; return YES; }]; diff --git a/ios/Elements/RNSVGPath.m b/ios/Elements/RNSVGPath.m index 6556886a..97772e02 100644 --- a/ios/Elements/RNSVGPath.m +++ b/ios/Elements/RNSVGPath.m @@ -29,8 +29,7 @@ - (void)renderLayerTo:(CGContextRef)context { // todo: add detection if path has changed since last update. - self.d = [self getPath:context]; - CGPathRef path = self.d; + CGPathRef path = [self getPath:context]; if ((!self.fill && !self.stroke) || !path) { return; } @@ -38,14 +37,14 @@ if ([self getSvgView].responsible) { // Add path to hitArea CGMutablePathRef hitArea = CGPathCreateMutableCopy(path); - if (self.stroke) { + if (self.stroke && self.strokeWidth) { // Add stroke to hitArea CGPathRef strokePath = CGPathCreateCopyByStrokingPath(hitArea, nil, self.strokeWidth, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit); CGPathAddPath(hitArea, nil, strokePath); CGPathRelease(strokePath); } - self.hitArea = CGPathCreateCopy(hitArea); + self.hitArea = CFAutorelease(CGPathCreateCopy(hitArea)); CGPathRelease(hitArea); } @@ -75,7 +74,7 @@ } } - if (self.stroke) { + if (self.stroke && self.strokeWidth) { CGContextSetLineWidth(context, self.strokeWidth); CGContextSetLineCap(context, self.strokeLinecap); CGContextSetLineJoin(context, self.strokeLinejoin); diff --git a/ios/Elements/RNSVGUse.m b/ios/Elements/RNSVGUse.m index fea9e7a7..e56382b6 100644 --- a/ios/Elements/RNSVGUse.m +++ b/ios/Elements/RNSVGUse.m @@ -27,7 +27,7 @@ if (template) { [self beginTransparencyLayer:context]; [self clip:context]; - [template mergeProperties:self mergeList:self.ownedPropList]; + [template mergeProperties:self mergeList:self.attributeList inherited:YES]; [template renderTo:context]; [template resetProperties]; [self endTransparencyLayer:context]; diff --git a/ios/RNSVGNode.m b/ios/RNSVGNode.m index 6d397e83..d56cfd9d 100644 --- a/ios/RNSVGNode.m +++ b/ios/RNSVGNode.m @@ -116,7 +116,8 @@ - (CGPathRef)getClipPath:(CGContextRef)context { - if (self.clipPath) { + if (self.clipPath && !_cachedClipPath) { + CGPathRelease(_cachedClipPath); _cachedClipPath = CGPathRetain([[[self getSvgView] getDefinedClipPath:self.clipPath] getPath:context]); } @@ -125,7 +126,7 @@ - (void)clip:(CGContextRef)context { - CGPathRef clipPath = [self getClipPath:context]; + CGPathRef clipPath = [self getClipPath:context]; if (clipPath) { CGContextAddPath(context, clipPath); diff --git a/ios/RNSVGRenderable.h b/ios/RNSVGRenderable.h index 6866e511..29b36c66 100644 --- a/ios/RNSVGRenderable.h +++ b/ios/RNSVGRenderable.h @@ -28,7 +28,7 @@ @property (nonatomic, assign) CGFloat strokeDashoffset; @property (nonatomic, assign) CGPathRef hitArea; @property (nonatomic, copy) NSArray *propList; -@property (nonatomic, strong) NSMutableArray *ownedPropList; +@property (nonatomic, strong) NSArray *attributeList; - (void)setBoundingBox:(CGRect)boundingBox; - (CGFloat)getWidthRelatedValue:(NSString *)string; diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index 27b10998..126cef3d 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -12,7 +12,7 @@ @implementation RNSVGRenderable { NSMutableDictionary *_originProperties; - NSArray *_changedList; + NSArray *_lastMergedList; RNSVGPercentageConverter *_widthConverter; RNSVGPercentageConverter *_heightConverter; CGFloat _contextWidth; @@ -148,8 +148,8 @@ if (propList == _propList) { return; } + _attributeList = [propList copy]; _propList = propList; - self.ownedPropList = [propList mutableCopy]; [self invalidate]; } @@ -191,18 +191,20 @@ } CGAffineTransform matrix = CGAffineTransformConcat(self.matrix, transform); + CGPathRef hitArea = CGPathCreateCopyByTransformingPath(self.hitArea, &matrix); - CGPathRef clipPath = [self getClipPath]; BOOL contains = CGPathContainsPoint(hitArea, nil, point, NO); CGPathRelease(hitArea); if (contains) { + CGPathRef clipPath = [self getClipPath]; + if (!clipPath) { return self; } else { - clipPath = CGPathCreateCopyByTransformingPath(clipPath, &matrix); - BOOL result = CGPathContainsPoint(clipPath, nil, point, self.clipRule == kRNSVGCGFCRuleEvenodd); - CGPathRelease(clipPath); + CGPathRef transformedClipPath = CGPathCreateCopyByTransformingPath(clipPath, &matrix); + BOOL result = CGPathContainsPoint(transformedClipPath, nil, point, self.clipRule == kRNSVGCGFCRuleEvenodd); + CGPathRelease(transformedClipPath); return result ? self : nil; } } else { @@ -255,44 +257,38 @@ - (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray *)mergeList inherited:(BOOL)inherited { + _lastMergedList = mergeList; + if (mergeList.count == 0) { return; } - self.ownedPropList = [self.propList mutableCopy]; + NSMutableArray* attributeList = [self.propList mutableCopy]; - if (!inherited) { - _originProperties = [[NSMutableDictionary alloc] init]; - _changedList = mergeList; - } + _originProperties = [[NSMutableDictionary alloc] init]; for (NSString *key in mergeList) { if (inherited) { - [self inheritProperty:target propName:key]; + if (![attributeList containsObject:key]) { + [attributeList addObject:key]; + [_originProperties setValue:[self valueForKey:key] forKey:key]; + [self setValue:[target valueForKey:key] forKey:key]; + } } else { [_originProperties setValue:[self valueForKey:key] forKey:key]; [self setValue:[target valueForKey:key] forKey:key]; } } + + _attributeList = [attributeList copy]; } - (void)resetProperties { - if (_changedList) { - for (NSString *key in _changedList) { - [self setValue:[_originProperties valueForKey:key] forKey:key]; - } - } - _changedList = nil; -} - -- (void)inheritProperty:(__kindof RNSVGNode *)parent propName:(NSString *)propName -{ - if (![self.ownedPropList containsObject:propName]) { - // add prop to props - [self.ownedPropList addObject:propName]; - [self setValue:[parent valueForKey:propName] forKey:propName]; + for (NSString *key in _lastMergedList) { + [self setValue:[_originProperties valueForKey:key] forKey:key]; } + _attributeList = [_propList copy]; } - (void)renderLayerTo:(CGContextRef)context diff --git a/ios/RNSVGViewBox.m b/ios/RNSVGViewBox.m index fa790361..80772557 100644 --- a/ios/RNSVGViewBox.m +++ b/ios/RNSVGViewBox.m @@ -160,7 +160,7 @@ return CGAffineTransformTranslate(transform, -translateX * (_fromSymbol ? scaleX : 1), -translateY * (_fromSymbol ? scaleY : 1)); } -- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray *)mergeList +- (void)mergeProperties:(__kindof RNSVGNode *)target mergeList:(NSArray *)mergeList inherited:(BOOL)inherited { if ([target isKindOfClass:[RNSVGUse class]]) { RNSVGUse *use = target; @@ -172,8 +172,10 @@ - (void)resetProperties { - self.width = self.height = nil; - _fromSymbol = NO; + if (_fromSymbol) { + self.width = self.height = nil; + _fromSymbol = NO; + } } @end