From 0388f332c1e34ea2d827187b60248d53a85f5c54 Mon Sep 17 00:00:00 2001 From: Curtis Hard Date: Thu, 4 Sep 2014 13:16:09 +0100 Subject: [PATCH] More support Added support for USE tag and better support for DEF, gradients and paths. Also added another test SVG from Sketch --- IJSVG.m | 5 +- IJSVGCache.m | 16 +- IJSVGDef.h | 2 + IJSVGDef.m | 4 +- .../IJSVGExample.xcodeproj/project.pbxproj | 4 + .../UserInterfaceState.xcuserstate | Bin 30462 -> 32283 bytes IJSVGExample/IJSVGExample/SVGView.m | 2 +- IJSVGExample/IJSVGExample/htc_one.svg | 274 ++++++++++++++++++ IJSVGGroup.h | 1 + IJSVGGroup.m | 17 ++ IJSVGNode.h | 4 +- IJSVGNode.m | 41 ++- IJSVGParser.m | 134 ++++++--- IJSVGPath.m | 7 + 14 files changed, 450 insertions(+), 61 deletions(-) create mode 100644 IJSVGExample/IJSVGExample/htc_one.svg diff --git a/IJSVG.m b/IJSVG.m index 37befa4..320b94c 100644 --- a/IJSVG.m +++ b/IJSVG.m @@ -43,8 +43,11 @@ static NSColor * _baseColor = nil; { NSBundle * bundle = [NSBundle mainBundle]; NSString * str = nil; + NSString * ext = [string pathExtension]; + if( ext == nil || ext.length == 0 ) + ext = @"svg"; if( ( str = [bundle pathForResource:[string stringByDeletingPathExtension] - ofType:[string pathExtension]] ) ) + ofType:ext] ) ) return [[[self alloc] initWithFile:str delegate:delegate] autorelease]; return nil; diff --git a/IJSVGCache.m b/IJSVGCache.m index 932e233..ece4f62 100644 --- a/IJSVGCache.m +++ b/IJSVGCache.m @@ -7,6 +7,7 @@ // #import "IJSVGCache.h" +#import @implementation IJSVGCache @@ -34,20 +35,11 @@ static BOOL _enabled = YES; + (void)cacheSVG:(IJSVG *)svg fileURL:(NSURL *)aURL { - NSFileManager * fm = [NSFileManager defaultManager]; - NSDictionary * atts = [fm attributesOfItemAtPath:[aURL path] - error:nil]; - - // cache is nil ... for some reason..? - if( _cache == nil ) - { - _cache = [[NSCache alloc] init]; - [_cache setTotalCostLimit:MAX_CACHE_SIZE]; - } - + // use the malloc size for the object size, + // is this correct? [_cache setObject:svg forKey:aURL - cost:[atts fileSize]+sizeof(svg)]; + cost:malloc_size(svg)]; } + (void)setEnabled:(BOOL)flag diff --git a/IJSVGDef.h b/IJSVGDef.h index 8975bba..b41c4be 100644 --- a/IJSVGDef.h +++ b/IJSVGDef.h @@ -16,4 +16,6 @@ } +- (void)addDef:(IJSVGNode *)aDef; + @end diff --git a/IJSVGDef.m b/IJSVGDef.m index 17d060a..6e137cb 100644 --- a/IJSVGDef.m +++ b/IJSVGDef.m @@ -25,8 +25,10 @@ return self; } -- (void)addDef:(IJSVGDef *)aDef +- (void)addDef:(IJSVGNode *)aDef { + if( aDef.identifier == nil ) + return; [_dict setObject:aDef forKey:aDef.identifier]; } diff --git a/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj b/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj index 48e8885..488f192 100644 --- a/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj +++ b/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj @@ -44,6 +44,7 @@ 59A0E7A519B7334F001BA157 /* IJSVGDef.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A0E7A419B7334F001BA157 /* IJSVGDef.m */; }; 59B93C6D19B7D1840063E823 /* paperplane.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6C19B7D1840063E823 /* paperplane.svg */; }; 59B93C6F19B7D32C0063E823 /* products.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59B93C6E19B7D32C0063E823 /* products.svg */; }; + 59F799E219B880CE00096CB7 /* htc_one.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59F799E119B880CE00096CB7 /* htc_one.svg */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -128,6 +129,7 @@ 59A0E7A419B7334F001BA157 /* IJSVGDef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGDef.m; path = ../../IJSVGDef.m; sourceTree = ""; }; 59B93C6C19B7D1840063E823 /* paperplane.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = paperplane.svg; sourceTree = ""; }; 59B93C6E19B7D32C0063E823 /* products.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = products.svg; sourceTree = ""; }; + 59F799E119B880CE00096CB7 /* htc_one.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = htc_one.svg; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -184,6 +186,7 @@ 5956657A19B62F4600D805FF /* Supporting Files */ = { isa = PBXGroup; children = ( + 59F799E119B880CE00096CB7 /* htc_one.svg */, 59B93C6E19B7D32C0063E823 /* products.svg */, 59B93C6C19B7D1840063E823 /* paperplane.svg */, 595665DD19B6309C00D805FF /* test.svg */, @@ -356,6 +359,7 @@ 59B93C6D19B7D1840063E823 /* paperplane.svg in Resources */, 5956658219B62F4600D805FF /* Images.xcassets in Resources */, 595665DE19B6309C00D805FF /* test.svg in Resources */, + 59F799E219B880CE00096CB7 /* htc_one.svg in Resources */, 59B93C6F19B7D32C0063E823 /* products.svg in Resources */, 5956658519B62F4600D805FF /* MainMenu.xib in Resources */, ); diff --git a/IJSVGExample/IJSVGExample.xcodeproj/project.xcworkspace/xcuserdata/curtishard.xcuserdatad/UserInterfaceState.xcuserstate b/IJSVGExample/IJSVGExample.xcodeproj/project.xcworkspace/xcuserdata/curtishard.xcuserdatad/UserInterfaceState.xcuserstate index 4e5ba8521d15380a2a2b8bf6231a348887505ca2..1c016fff0a59d63eb800fc634c6fac969cc7769a 100644 GIT binary patch literal 32283 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 literal 30462 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 F{{ZcJyhZ>3 diff --git a/IJSVGExample/IJSVGExample/SVGView.m b/IJSVGExample/IJSVGExample/SVGView.m index ea54627..4037a00 100644 --- a/IJSVGExample/IJSVGExample/SVGView.m +++ b/IJSVGExample/IJSVGExample/SVGView.m @@ -20,7 +20,7 @@ { if( ( self = [super initWithCoder:aDecoder] ) != nil ) { - svg = [[IJSVG svgNamed:@"paperplane.svg"] retain]; + svg = [[IJSVG svgNamed:@"test"] retain]; } return self; } diff --git a/IJSVGExample/IJSVGExample/htc_one.svg b/IJSVGExample/IJSVGExample/htc_one.svg new file mode 100644 index 0000000..87f291c --- /dev/null +++ b/IJSVGExample/IJSVGExample/htc_one.svg @@ -0,0 +1,274 @@ + + + htc one + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/IJSVGGroup.h b/IJSVGGroup.h index 27f3cc4..7d67a97 100644 --- a/IJSVGGroup.h +++ b/IJSVGGroup.h @@ -18,5 +18,6 @@ - (void)addChild:(id)child; - (NSArray *)children; +- (void)purgeChildren; @end diff --git a/IJSVGGroup.m b/IJSVGGroup.m index e2c4b7d..eaf99ee 100644 --- a/IJSVGGroup.m +++ b/IJSVGGroup.m @@ -25,6 +25,23 @@ return self; } +- (id)copyWithZone:(NSZone *)zone +{ + IJSVGGroup * node = [[self class] allocWithZone:zone]; + for( IJSVGNode * childNode in self.children ) + { + childNode = [[childNode copy] autorelease]; + childNode.parentNode = node; + [node addChild:childNode]; + } + return node; +} + +- (void)purgeChildren +{ + [children removeAllObjects]; +} + - (void)addChild:(id)child { [children addObject:child]; diff --git a/IJSVGNode.h b/IJSVGNode.h index 04320a0..dd630a6 100644 --- a/IJSVGNode.h +++ b/IJSVGNode.h @@ -20,7 +20,7 @@ typedef NS_OPTIONS( NSInteger, IJSVGWindingRule ) { static CGFloat IJSVGInheritedFloatValue = -99.9999991; -@interface IJSVGNode : NSObject { +@interface IJSVGNode : NSObject { NSString * name; @@ -69,7 +69,7 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991; @property ( nonatomic, retain ) IJSVGGradient * fillGradient; - (id)initWithDef:(BOOL)flag; -- (void)addDef:(IJSVGDef *)aDef; +- (void)addDef:(IJSVGNode *)aDef; - (IJSVGDef *)defForID:(NSString *)anID; @end diff --git a/IJSVGNode.m b/IJSVGNode.m index 9f8def2..828f40f 100644 --- a/IJSVGNode.m +++ b/IJSVGNode.m @@ -48,6 +48,36 @@ return self; } +- (id)copyWithZone:(NSZone *)zone +{ + IJSVGNode * node = [[self class] allocWithZone:zone]; + node.name = self.name; + + node.x = self.x; + node.y = self.y; + node.width = self.width; + node.height = self.height; + + node.fillGradient = self.fillGradient; + + node.fillColor = self.fillColor; + node.strokeColor = self.strokeColor; + + node.opacity = self.opacity; + node.strokeWidth = self.strokeWidth; + node.fillOpacity = self.fillOpacity; + node.strokeOpacity = self.strokeOpacity; + + node.identifier = self.identifier; + + node.transforms = self.transforms; + node.def = self.def; + node.windingRule = self.windingRule; + node.parentNode = self.parentNode; + + return node; +} + - (id)initWithDef:(BOOL)flag { if( ( self = [super init] ) != nil ) @@ -71,7 +101,7 @@ return nil; } -- (void)addDef:(IJSVGDef *)aDef +- (void)addDef:(IJSVGNode *)aDef { [def addDef:aDef]; } @@ -143,4 +173,13 @@ return 0.f; } +// even though the spec explicity states fill color +// must be on the path, it can also be on the +- (NSColor *)fillColor +{ + if( fillColor == nil && parentNode != nil ) + return parentNode.fillColor; + return fillColor; +} + @end \ No newline at end of file diff --git a/IJSVGParser.m b/IJSVGParser.m index 08d71df..fe3acb8 100644 --- a/IJSVGParser.m +++ b/IJSVGParser.m @@ -145,7 +145,8 @@ // recursively self.name = svgElement.name; [self _parseBlock:svgElement - intoGroup:self]; + intoGroup:self + def:NO]; } @@ -226,21 +227,24 @@ - (void)_parseBlock:(NSXMLElement *)anElement intoGroup:(IJSVGGroup*)parentGroup + def:(BOOL)flag { + + // if flag is yes, then anything we find inside this + // + for( NSXMLElement * element in [anElement children] ) { NSString * subName = [[element name] lowercaseString]; - if( [subName isEqualToString:@"defs"] ) { - - // defs - [self _parseDef:element - intoNode:parentGroup]; + // any defs? + [self _parseBlock:element + intoGroup:parentGroup + def:YES]; continue; - } else if( [subName isEqualToString:@"g"] ) - { + } else if( [subName isEqualToString:@"g"] ) { // its a group IJSVGGroup * group = [[[IJSVGGroup alloc] init] autorelease]; @@ -252,14 +256,14 @@ node:group]; [parentGroup addChild:group]; - // could be gradients within - // the group's aswell, so work those out - [self _parseDef:element - intoNode:group]; - // recursively parse blocks [self _parseBlock:element - intoGroup:group]; + intoGroup:group + def:NO]; + + // could be defined + if( def ) + [parentGroup addDef:group]; continue; @@ -276,6 +280,11 @@ [self _parsePathCommandData:[[element attributeForName:@"d"] stringValue] intoPath:path]; [parentGroup addChild:path]; + + // could be defined + if( def ) + [parentGroup addDef:path]; + continue; } else if( [subName isEqualToString:@"polygon"] ) { @@ -291,6 +300,11 @@ [self _parsePolygon:element intoPath:path]; [parentGroup addChild:path]; + + // could be defined + if( def ) + [parentGroup addDef:path]; + continue; } else if( [subName isEqualToString:@"polyline"] ) { @@ -306,6 +320,11 @@ [self _parsePolyline:element intoPath:path]; [parentGroup addChild:path]; + + // could be defined + if( def ) + [parentGroup addDef:path]; + continue; } else if( [subName isEqualToString:@"rect"] ) { @@ -321,6 +340,11 @@ [self _parseRect:element intoPath:path]; [parentGroup addChild:path]; + + // could be defined + if( def ) + [parentGroup addDef:path]; + continue; } else if( [subName isEqualToString:@"line"] ) { @@ -336,6 +360,11 @@ [self _parseLine:element intoPath:path]; [parentGroup addChild:path]; + + // could be defined + if( def ) + [parentGroup addDef:path]; + continue; } else if( [subName isEqualToString:@"circle"] ) { @@ -351,6 +380,11 @@ [self _parseCircle:element intoPath:path]; [parentGroup addChild:path]; + + // could be defined + if( def ) + [parentGroup addDef:path]; + continue; } else if( [subName isEqualToString:@"ellipse"] ) { @@ -366,43 +400,57 @@ [self _parseEllipse:element intoPath:path]; [parentGroup addChild:path]; + + // could be defined + if( def ) + [parentGroup addDef:path]; + continue; + } else if( [subName isEqualToString:@"use"] ) { + + // its a use command + NSString * xlink = [[element attributeForName:@"xlink:href"] stringValue]; + NSString * xlinkID = [xlink substringFromIndex:1]; + IJSVGNode * node = [parentGroup defForID:xlinkID]; + if( node != nil ) + { + // copy the node + node = [[node copy] autorelease]; + node.parentNode = parentGroup; + + // grab the common attributes + [self _parseElementForCommonAttributes:element + node:node]; + [parentGroup addChild:node]; + } + + } else if( [subName isEqualToString:@"lineargradient"] ) { + + // linear gradient + IJSVGLinearGradient * gradient = [[[IJSVGLinearGradient alloc] init] autorelease]; + gradient.gradient = [IJSVGLinearGradient parseGradient:element + gradient:gradient]; + [self _parseElementForCommonAttributes:element + node:gradient]; + [parentGroup addDef:gradient]; + continue; + + } else if( [subName isEqualToString:@"radialgradient"] ) { + + // radial gradient + IJSVGRadialGradient * gradient = [[[IJSVGRadialGradient alloc] init] autorelease]; + gradient.gradient = [IJSVGRadialGradient parseGradient:element + gradient:gradient]; + [self _parseElementForCommonAttributes:element + node:gradient]; + [parentGroup addDef:gradient]; } } } #pragma mark Parser stuff! -- (void)_parseDef:(NSXMLElement *)element - intoNode:(IJSVGNode *)node -{ - for( NSXMLElement * child in [element children] ) - { - if( [[child name] isEqualToString:@"linearGradient"] ) - { - // linear gradient - IJSVGLinearGradient * gradient = [[[IJSVGLinearGradient alloc] init] autorelease]; - gradient.gradient = [IJSVGLinearGradient parseGradient:child - gradient:gradient]; - [self _parseElementForCommonAttributes:child - node:gradient]; - [node addDef:gradient]; - - } else if( [[child name] isEqualToString:@"radialGradient"] ) - { - // radial gradient - IJSVGRadialGradient * gradient = [[[IJSVGRadialGradient alloc] init] autorelease]; - gradient.gradient = [IJSVGRadialGradient parseGradient:child - gradient:gradient]; - [self _parseElementForCommonAttributes:child - node:gradient]; - [node addDef:gradient]; - - } - } -} - - (void)_parsePathCommandData:(NSString *)command intoPath:(IJSVGPath *)path { diff --git a/IJSVGPath.m b/IJSVGPath.m index 46e29ad..786c5ec 100644 --- a/IJSVGPath.m +++ b/IJSVGPath.m @@ -30,6 +30,13 @@ return self; } +- (id)copyWithZone:(NSZone *)zone +{ + IJSVGPath * node = [super copyWithZone:zone]; + [node overwritePath:self.path]; + return node; +} + - (NSPoint)currentPoint { return [subpath currentPoint];