From d70f10b23dfcd1c28aedaa7bfca25bce7a30d110 Mon Sep 17 00:00:00 2001 From: Curtis Hard Date: Thu, 4 Sep 2014 22:19:57 +0100 Subject: [PATCH] Added support for clipPaths --- IJSVG.m | 97 +++++++++++++++--- .../IJSVGExample.xcodeproj/project.pbxproj | 10 ++ .../UserInterfaceState.xcuserstate | Bin 38253 -> 37858 bytes .../IJSVGExample/Base.lproj/MainMenu.xib | 8 +- IJSVGExample/IJSVGExample/SVGExampleView4.h | 14 +++ IJSVGExample/IJSVGExample/SVGExampleView4.m | 18 ++++ IJSVGExample/IJSVGExample/clipped.svg | 15 +++ IJSVGNode.h | 4 + IJSVGNode.m | 4 + IJSVGParser.m | 74 ++++++++++--- 10 files changed, 212 insertions(+), 32 deletions(-) create mode 100644 IJSVGExample/IJSVGExample/SVGExampleView4.h create mode 100644 IJSVGExample/IJSVGExample/SVGExampleView4.m create mode 100644 IJSVGExample/IJSVGExample/clipped.svg diff --git a/IJSVG.m b/IJSVG.m index 320b94c..768beea 100644 --- a/IJSVG.m +++ b/IJSVG.m @@ -207,21 +207,86 @@ static NSColor * _baseColor = nil; [self _applyDefaults:context node:group]; - // it could be a group or a path - for( id child in [group children] ) + dispatch_block_t drawBlock = ^{ + // it could be a group or a path + for( id child in [group children] ) + { + if( [child isKindOfClass:[IJSVGPath class]] ) + { + IJSVGPath * p = (IJSVGPath *)child; + if( p.clipPath != nil ) + { + for( id clip in p.clipPath.children ) + { + if( [clip isKindOfClass:[IJSVGGroup class]] ) + [self _drawGroup:clip + rect:rect]; + else { + + // there is a clip path, save the context + CGContextSaveGState( context ); + + // add the clip + IJSVGPath * p = (IJSVGPath *)clip; + [p.path addClip]; + + // draw the path + [self _drawPath:child + rect:rect]; + + // restore the context + CGContextRestoreGState( context ); + } + } + } else { + // as its just a path, we can happily + // just draw it in the current context + [self _drawPath:child + rect:rect]; + } + } else if( [child isKindOfClass:[IJSVGGroup class]] ) { + + // if its a group, we recursively call this method + // to generate the paths required + [self _drawGroup:child + rect:rect]; + } + } + + }; + + // group clipping + if( group.clipPath != nil ) { - if( [child isKindOfClass:[IJSVGPath class]] ) - // as its just a path, we can happily - // just draw it in the current context - [self _drawPath:child - rect:rect]; - else if( [child isKindOfClass:[IJSVGGroup class]] ) - - // if its a group, we recursively call this method - // to generate the paths required - [self _drawGroup:child - rect:rect]; - } + + // find the clipped children + for( id child in group.clipPath.children ) + { + // if its a group, run this again + if( [child isKindOfClass:[IJSVGGroup class]] ) + [self _drawGroup:child + rect:rect]; + else { + + // save the context state + CGContextSaveGState( context ); + + // find the path + IJSVGPath * p = (IJSVGPath *)child; + + // clip the context + [p.path addClip]; + + // draw the paths + drawBlock(); + + // restore again + CGContextRestoreGState( context ); + } + } + } else + // just draw the block + drawBlock(); // restore the context CGContextRestoreGState(context); @@ -289,7 +354,7 @@ static NSColor * _baseColor = nil; [path.fillColor set]; [path.path fill]; } else if( _baseColor != nil ) { - + // is there a base color? // this is basically used whenever no color // is set, its also set via [IJSVG setBaseColor], @@ -297,6 +362,8 @@ static NSColor * _baseColor = nil; [_baseColor set]; [path.path fill]; + } else { + [path.path fill]; } } diff --git a/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj b/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj index 5587dd1..4e10abf 100644 --- a/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj +++ b/IJSVGExample/IJSVGExample.xcodeproj/project.pbxproj @@ -10,6 +10,8 @@ 5910114B19B739B7009F8A35 /* IJSVGStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 5910114A19B739B7009F8A35 /* IJSVGStyle.m */; }; 5910114E19B75C9C009F8A35 /* IJSVGGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 5910114D19B75C9C009F8A35 /* IJSVGGradient.m */; }; 5910115119B75E44009F8A35 /* IJSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 5910115019B75E44009F8A35 /* IJSVGRadialGradient.m */; }; + 59459CEC19B906FE00CE493B /* clipped.svg in Resources */ = {isa = PBXBuildFile; fileRef = 59459CEB19B906FE00CE493B /* clipped.svg */; }; + 59459CEF19B9074F00CE493B /* SVGExampleView4.m in Sources */ = {isa = PBXBuildFile; fileRef = 59459CEE19B9074F00CE493B /* SVGExampleView4.m */; }; 5956657D19B62F4600D805FF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956657C19B62F4600D805FF /* main.m */; }; 5956658019B62F4600D805FF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5956657F19B62F4600D805FF /* AppDelegate.m */; }; 5956658219B62F4600D805FF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5956658119B62F4600D805FF /* Images.xcassets */; }; @@ -67,6 +69,9 @@ 5910114D19B75C9C009F8A35 /* IJSVGGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGGradient.m; path = ../../IJSVGGradient.m; sourceTree = ""; }; 5910114F19B75E44009F8A35 /* IJSVGRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IJSVGRadialGradient.h; path = ../../IJSVGRadialGradient.h; sourceTree = ""; }; 5910115019B75E44009F8A35 /* IJSVGRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IJSVGRadialGradient.m; path = ../../IJSVGRadialGradient.m; sourceTree = ""; }; + 59459CEB19B906FE00CE493B /* clipped.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = clipped.svg; sourceTree = ""; }; + 59459CED19B9074F00CE493B /* SVGExampleView4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGExampleView4.h; sourceTree = ""; }; + 59459CEE19B9074F00CE493B /* SVGExampleView4.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGExampleView4.m; sourceTree = ""; }; 5956657719B62F4600D805FF /* IJSVGExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IJSVGExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5956657B19B62F4600D805FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5956657C19B62F4600D805FF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -194,6 +199,8 @@ 59A11E6E19B89D2000E44498 /* SVGExampleView2.m */, 59A11E7019B89D6600E44498 /* SVGExampleView3.h */, 59A11E7119B89D6600E44498 /* SVGExampleView3.m */, + 59459CED19B9074F00CE493B /* SVGExampleView4.h */, + 59459CEE19B9074F00CE493B /* SVGExampleView4.m */, ); path = IJSVGExample; sourceTree = ""; @@ -201,6 +208,7 @@ 5956657A19B62F4600D805FF /* Supporting Files */ = { isa = PBXGroup; children = ( + 59459CEB19B906FE00CE493B /* clipped.svg */, 59F799E119B880CE00096CB7 /* htc_one.svg */, 59B93C6E19B7D32C0063E823 /* products.svg */, 59B93C6C19B7D1840063E823 /* paperplane.svg */, @@ -377,6 +385,7 @@ 59F799E219B880CE00096CB7 /* htc_one.svg in Resources */, 59B93C6F19B7D32C0063E823 /* products.svg in Resources */, 5956658519B62F4600D805FF /* MainMenu.xib in Resources */, + 59459CEC19B906FE00CE493B /* clipped.svg in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -427,6 +436,7 @@ 5910114E19B75C9C009F8A35 /* IJSVGGradient.m in Sources */, 59A11E6F19B89D2000E44498 /* SVGExampleView2.m in Sources */, 595665CA19B6302600D805FF /* IJSVGColor.m in Sources */, + 59459CEF19B9074F00CE493B /* SVGExampleView4.m in Sources */, 595665DB19B6302600D805FF /* IJSVGUtils.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; 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 9d2845a016cb9287b6a1550b5288eab9af0d94af..1b43fe7a59eab15564503de89133178ea506758c 100644 GIT binary patch literal 37858 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 literal 38253 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 diff --git a/IJSVGExample/IJSVGExample/Base.lproj/MainMenu.xib b/IJSVGExample/IJSVGExample/Base.lproj/MainMenu.xib index 9e017cd..545ac1d 100644 --- a/IJSVGExample/IJSVGExample/Base.lproj/MainMenu.xib +++ b/IJSVGExample/IJSVGExample/Base.lproj/MainMenu.xib @@ -689,8 +689,12 @@ - - + + + + + + diff --git a/IJSVGExample/IJSVGExample/SVGExampleView4.h b/IJSVGExample/IJSVGExample/SVGExampleView4.h new file mode 100644 index 0000000..62f8632 --- /dev/null +++ b/IJSVGExample/IJSVGExample/SVGExampleView4.h @@ -0,0 +1,14 @@ +// +// SVGExampleView4.h +// IJSVGExample +// +// Created by Curtis Hard on 04/09/2014. +// Copyright (c) 2014 Curtis Hard. All rights reserved. +// + +#import +#import "SVGView.h" + +@interface SVGExampleView4 : SVGView + +@end diff --git a/IJSVGExample/IJSVGExample/SVGExampleView4.m b/IJSVGExample/IJSVGExample/SVGExampleView4.m new file mode 100644 index 0000000..bf971cd --- /dev/null +++ b/IJSVGExample/IJSVGExample/SVGExampleView4.m @@ -0,0 +1,18 @@ +// +// SVGExampleView4.m +// IJSVGExample +// +// Created by Curtis Hard on 04/09/2014. +// Copyright (c) 2014 Curtis Hard. All rights reserved. +// + +#import "SVGExampleView4.h" + +@implementation SVGExampleView4 + +- (IJSVG *)svg +{ + return [[IJSVG svgNamed:@"clipped"] retain]; +} + +@end diff --git a/IJSVGExample/IJSVGExample/clipped.svg b/IJSVGExample/IJSVGExample/clipped.svg new file mode 100644 index 0000000..a6a4ad6 --- /dev/null +++ b/IJSVGExample/IJSVGExample/clipped.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/IJSVGNode.h b/IJSVGNode.h index 83f38ef..3e29ddf 100644 --- a/IJSVGNode.h +++ b/IJSVGNode.h @@ -11,6 +11,7 @@ @class IJSVGDef; @class IJSVGGradient; +@class IJSVGGroup; typedef NS_OPTIONS( NSInteger, IJSVGNodeType ) { IJSVGNodeTypeGroup, @@ -25,6 +26,7 @@ typedef NS_OPTIONS( NSInteger, IJSVGNodeType ) { IJSVGNodeTypeUse, IJSVGNodeTypeLinearGradient, IJSVGNodeTypeRadialGradient, + IJSVGNodeTypeClipPath, IJSVGNodeTypeNotFound }; @@ -59,6 +61,7 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991; NSString * identifier; IJSVGNode * parentNode; + IJSVGGroup * clipPath; NSArray * transforms; IJSVGWindingRule windingRule; @@ -81,6 +84,7 @@ static CGFloat IJSVGInheritedFloatValue = -99.9999991; @property ( nonatomic, retain ) NSColor * strokeColor; @property ( nonatomic, copy ) NSString * identifier; @property ( nonatomic, assign ) IJSVGNode * parentNode; +@property ( nonatomic, assign ) IJSVGGroup * clipPath; @property ( nonatomic, assign ) IJSVGWindingRule windingRule; @property ( nonatomic, retain ) NSArray * transforms; @property ( nonatomic, retain ) IJSVGDef * def; diff --git a/IJSVGNode.m b/IJSVGNode.m index 9987f11..1d28e53 100644 --- a/IJSVGNode.m +++ b/IJSVGNode.m @@ -29,6 +29,7 @@ @synthesize windingRule; @synthesize def; @synthesize fillGradient; +@synthesize clipPath; - (void)dealloc { @@ -69,6 +70,8 @@ return IJSVGNodeTypeLinearGradient; if( [string isEqualToString:@"radialgradient"] ) return IJSVGNodeTypeRadialGradient; + if( [string isEqualToString:@"clippath"] ) + return IJSVGNodeTypeClipPath; return IJSVGNodeTypeNotFound; } @@ -95,6 +98,7 @@ node.fillColor = self.fillColor; node.strokeColor = self.strokeColor; + node.clipPath = self.clipPath; node.opacity = self.opacity; node.strokeWidth = self.strokeWidth; diff --git a/IJSVGParser.m b/IJSVGParser.m index 02c4d7b..c732dac 100644 --- a/IJSVGParser.m +++ b/IJSVGParser.m @@ -153,6 +153,16 @@ - (void)_parseElementForCommonAttributes:(NSXMLElement *)element node:(IJSVGNode *)node { + + // any clippath? + NSXMLNode * clipPathAttribute = [element attributeForName:@"clip-path"]; + if( clipPathAttribute != nil ) + { + NSString * clipID = [IJSVGUtils defURL:[clipPathAttribute stringValue]]; + if( clipID ) + node.clipPath = (IJSVGGroup *)[node defForID:clipID]; + } + // work out any extra attributes // opacity NSXMLNode * opacityAttribute = [element attributeForName:@"opacity"]; @@ -257,7 +267,9 @@ // find common attributes [self _parseElementForCommonAttributes:element node:group]; - [parentGroup addChild:group]; + + if( !flag ) + [parentGroup addChild:group]; // recursively parse blocks [self _parseBlock:element @@ -265,7 +277,7 @@ def:NO]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:group]; continue; } @@ -282,10 +294,12 @@ node:path]; [self _parsePathCommandData:[[element attributeForName:@"d"] stringValue] intoPath:path]; - [parentGroup addChild:path]; + + if( !flag ) + [parentGroup addChild:path]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:path]; continue; } @@ -302,10 +316,12 @@ node:path]; [self _parsePolygon:element intoPath:path]; - [parentGroup addChild:path]; + + if( !flag ) + [parentGroup addChild:path]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:path]; continue; } @@ -322,10 +338,12 @@ node:path]; [self _parsePolyline:element intoPath:path]; - [parentGroup addChild:path]; + + if( !flag ) + [parentGroup addChild:path]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:path]; continue; } @@ -342,10 +360,12 @@ node:path]; [self _parseRect:element intoPath:path]; - [parentGroup addChild:path]; + + if( !flag ) + [parentGroup addChild:path]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:path]; continue; } @@ -365,7 +385,7 @@ [parentGroup addChild:path]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:path]; continue; } @@ -382,10 +402,12 @@ node:path]; [self _parseCircle:element intoPath:path]; - [parentGroup addChild:path]; + + if( !flag ) + [parentGroup addChild:path]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:path]; continue; } @@ -402,10 +424,12 @@ node:path]; [self _parseEllipse:element intoPath:path]; - [parentGroup addChild:path]; + + if( !flag ) + [parentGroup addChild:path]; // could be defined - if( def ) + if( flag ) [parentGroup addDef:path]; continue; } @@ -453,6 +477,26 @@ continue; } + // clippath + case IJSVGNodeTypeClipPath: { + IJSVGGroup * group = [[[IJSVGGroup alloc] init] autorelease]; + group.type = aType; + group.name = subName; + group.parentNode = parentGroup; + + // find common attributes + [self _parseElementForCommonAttributes:element + node:group]; + + // recursively parse blocks + [self _parseBlock:element + intoGroup:group + def:NO]; + + // add it as a def + [parentGroup addDef:group]; + } + } } }