Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Core/SVGDocument.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#import "SVGElement.h"

#import "SVGGroupElement.h"

#if NS_BLOCKS_AVAILABLE
typedef void (^SVGElementAggregationBlock)(SVGElement < SVGLayeredElement > * layeredElement);
#endif
Expand All @@ -25,6 +27,9 @@ typedef void (^SVGElementAggregationBlock)(SVGElement < SVGLayeredElement > * la
@property (nonatomic, readonly) NSString *desc; // 'description' is reserved by NSObject
@property (nonatomic, readonly) SVGDefsElement *defs;

/*! from the SVG spec, each "g" tag in the XML is a separate "group of graphics things" */
@property (nonatomic, retain) NSDictionary *graphicsGroups;

+ (id)documentNamed:(NSString *)name; // 'name' in mainBundle
+ (id)documentWithContentsOfFile:(NSString *)aPath;

Expand Down
7 changes: 7 additions & 0 deletions Core/SVGDocument.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ @implementation SVGDocument
@synthesize height = _height;
@synthesize version = _version;

@synthesize graphicsGroups;

@dynamic title, desc, defs;

/* TODO: parse 'viewBox' */
Expand All @@ -52,7 +54,10 @@ + (id)documentNamed:(NSString *)name {
NSString *path = [bundle pathForResource:newName ofType:extension];

if (!path)
{
NSLog(@"[%@] MISSING FILE, COULD NOT CREATE DOCUMENT: filename = %@, extension = %@", [self class], newName, extension);
return nil;
}

return [self documentWithContentsOfFile:path];
}
Expand All @@ -69,6 +74,8 @@ - (id)initWithContentsOfFile:(NSString *)aPath {
_width = _height = 100;

if (![self parseFileAtPath:aPath]) {
NSLog(@"[%@] MISSING FILE, COULD NOT CREATE DOCUMENT: path = %@", [self class], aPath);

[self release];
return nil;
}
Expand Down
4 changes: 2 additions & 2 deletions Core/SVGElement.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ - (void)parseContent:(NSString *)content {
}

- (NSString *)description {
return [NSString stringWithFormat:@"<%@ %p | localName=%@ | stringValue=%@ | children=%d>",
[self class], self, _localName, _stringValue, [_children count]];
return [NSString stringWithFormat:@"<%@ %p | id=%@ | localName=%@ | stringValue=%@ | children=%d>",
[self class], self, _identifier, _localName, _stringValue, [_children count]];
}

@end
Empty file modified Core/SVGGroupElement.h
100644 → 100755
Empty file.
1 change: 1 addition & 0 deletions Core/SVGParser.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
NSMutableString *_storedChars;
NSMutableArray *_elementStack;
__weak SVGDocument *_document;
NSMutableDictionary *_graphicsGroups;
}

- (id)initWithPath:(NSString *)aPath document:(SVGDocument *)document;
Expand Down
17 changes: 17 additions & 0 deletions Core/SVGParser.m
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ - (id)initWithPath:(NSString *)aPath document:(SVGDocument *)document {
_storedChars = [[NSMutableString alloc] init];
_elementStack = [[NSMutableArray alloc] init];
_failed = NO;
_graphicsGroups = [[NSMutableDictionary dictionary] retain];

if (!elementMap) {
elementMap = [[NSDictionary dictionaryWithObjectsAndKeys:
Expand All @@ -73,6 +74,7 @@ - (void)dealloc {
[_path release];
[_storedChars release];
[_elementStack release];
[_graphicsGroups release];

[super dealloc];
}
Expand Down Expand Up @@ -164,8 +166,12 @@ static void startElementSAX (void *ctx, const xmlChar *localname, const xmlChar
}

- (void)handleEndElement:(NSString *)name {

if ([name isEqualToString:@"svg"]) {
[_elementStack removeObject:_document];

/*! Add the dictionary of named "g" tags to the document, so applications can retrieve "named groups" from the SVG */
[_document setGraphicsGroups:_graphicsGroups];
return;
}

Expand All @@ -182,6 +188,17 @@ - (void)handleEndElement:(NSString *)name {

[_elementStack removeLastObject];

/*!
SVG Spec attaches special meaning to the "g" tag - and applications
need to be able to pull-out the "g"-tagged items later on
*/
if( [element.localName isEqualToString:@"g"] )
{
[_graphicsGroups setValue:element forKey:element.identifier];

/*! ...we'll build up the dictionary, then add it to the document when the SVG tag is closed */
}

SVGElement *parent = [_elementStack lastObject];
[parent addChild:element];

Expand Down
49 changes: 40 additions & 9 deletions Core/SVGPathElement.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
// TODO: support smooth-quadratic-bezier-curveto
// TODO: support elliptical-arc

/*! Very useful for debugging the parser - this will output one line of logging
* for every CGPath command that's actually done; you can then compare these lines
* to the input source file, and manually check what's being sent to the renderer
* versus what was expected
*/
#define DEBUG_PATH_CREATION 0

typedef struct SVGCurve
{
CGPoint c1;
Expand Down Expand Up @@ -70,8 +77,8 @@ - (CGPoint) readVerticalLinetoArgumentSequence:(NSScanner*)scanner path:(CGMutab
- (CGPoint) readHorizontalLinetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin;
- (CGPoint) readHorizontalLinetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin;

- (SVGCurve) readCurvetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin;
- (SVGCurve) readCurvetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin;
- (SVGCurve) readCurvetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin isRelative:(BOOL) isRelative;
- (SVGCurve) readCurvetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin isRelative:(BOOL) isRelative;
- (SVGCurve) readCurvetoArgument:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin;
- (SVGCurve) readSmoothCurvetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin withPrevCurve:(SVGCurve)prevCurve;
- (SVGCurve) readSmoothCurvetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin withPrevCurve:(SVGCurve)prevCurve;
Expand Down Expand Up @@ -168,12 +175,14 @@ - (void)parseData:(NSString *)data
} else if ([@"c" isEqualToString:command]) {
lastCurve = [self readCurvetoCommand:commandScanner
path:path
relativeTo:lastCoordinate];
relativeTo:lastCoordinate
isRelative:TRUE];
lastCoordinate = lastCurve.p;
} else if ([@"C" isEqualToString:command]) {
lastCurve = [self readCurvetoCommand:commandScanner
path:path
relativeTo:CGPointZero];
relativeTo:CGPointZero
isRelative:FALSE];
lastCoordinate = lastCurve.p;
} else if ([@"s" isEqualToString:command]) {
lastCurve = [self readSmoothCurvetoCommand:commandScanner
Expand Down Expand Up @@ -404,6 +413,9 @@ - (CGPoint) readMovetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRe
CGPoint p = [self readCoordinatePair:scanner];
CGPoint coord = CGPointMake(p.x+origin.x, p.y+origin.y);
CGPathMoveToPoint(path, NULL, coord.x, coord.y);
#if DEBUG_PATH_CREATION
NSLog(@"[%@] PATH: MOVED to %2.2f, %2.2f", [self class], coord.x, coord.y );
#endif

[self readCommaAndWhitespace:scanner];

Expand Down Expand Up @@ -467,7 +479,10 @@ - (CGPoint) readLinetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRe
CGPoint p = [self readCoordinatePair:scanner];
CGPoint coord = CGPointMake(p.x+origin.x, p.y+origin.y);
CGPathAddLineToPoint(path, NULL, coord.x, coord.y);

#if DEBUG_PATH_CREATION
NSLog(@"[%@] PATH: LINE to %2.2f, %2.2f", [self class], coord.x, coord.y );
#endif

[self readWhitespace:scanner];
if (![scanner isAtEnd]) {
coord = [self readLinetoArgumentSequence:scanner path:path relativeTo:(isRelative)?coord:origin isRelative:isRelative];
Expand All @@ -480,7 +495,7 @@ - (CGPoint) readLinetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRe
curveto:
( "C" | "c" ) wsp* curveto-argument-sequence
*/
- (SVGCurve) readCurvetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin
- (SVGCurve) readCurvetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin isRelative:(BOOL) isRelative
{
NSString* cmd = nil;
NSCharacterSet* cmdFormat = [NSCharacterSet characterSetWithCharactersInString:@"Cc"];
Expand All @@ -491,7 +506,7 @@ - (SVGCurve) readCurvetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path

[self readWhitespace:scanner];

SVGCurve lastCurve = [self readCurvetoArgumentSequence:scanner path:path relativeTo:origin];
SVGCurve lastCurve = [self readCurvetoArgumentSequence:scanner path:path relativeTo:origin isRelative:isRelative];
return lastCurve;
}

Expand All @@ -500,12 +515,12 @@ - (SVGCurve) readCurvetoCommand:(NSScanner*)scanner path:(CGMutablePathRef)path
curveto-argument
| curveto-argument comma-wsp? curveto-argument-sequence
*/
- (SVGCurve) readCurvetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin
- (SVGCurve) readCurvetoArgumentSequence:(NSScanner*)scanner path:(CGMutablePathRef)path relativeTo:(CGPoint)origin isRelative:(BOOL) isRelative
{
SVGCurve curve = [self readCurvetoArgument:scanner path:path relativeTo:origin];

if (![scanner isAtEnd]) {
curve = [self readCurvetoArgumentSequence:scanner path:path relativeTo:origin];
curve = [self readCurvetoArgumentSequence:scanner path:path relativeTo:(isRelative ? curve.p : origin) isRelative:isRelative];
}

return curve;
Expand All @@ -529,6 +544,9 @@ - (SVGCurve) readCurvetoArgument:(NSScanner*)scanner path:(CGMutablePathRef)path
[self readCommaAndWhitespace:scanner];

CGPathAddCurveToPoint(path, NULL, coord1.x, coord1.y, coord2.x, coord2.y, coord3.x, coord3.y);
#if DEBUG_PATH_CREATION
NSLog(@"[%@] PATH: CURVE to (%2.2f, %2.2f)..(%2.2f, %2.2f)..(%2.2f, %2.2f)", [self class], coord1.x, coord1.y, coord2.x, coord2.y, coord3.x, coord3.y );
#endif

return SVGCurveMake(coord1.x, coord1.y, coord2.x, coord2.y, coord3.x, coord3.y);
}
Expand Down Expand Up @@ -594,6 +612,10 @@ - (SVGCurve) readSmoothCurvetoArgument:(NSScanner*)scanner path:(CGMutablePathRe
}

CGPathAddCurveToPoint(path, NULL, thisCurve.c1.x, thisCurve.c1.y, thisCurve.c2.x, thisCurve.c2.y, thisCurve.p.x, thisCurve.p.y);
#if DEBUG_PATH_CREATION
NSLog(@"[%@] PATH: SMOOTH CURVE to (%2.2f, %2.2f)..(%2.2f, %2.2f)..(%2.2f, %2.2f)", [self class], thisCurve.c1.x, thisCurve.c1.y, thisCurve.c2.x, thisCurve.c2.y, thisCurve.p.x, thisCurve.p.y );
#endif

return thisCurve;
}

Expand All @@ -609,6 +631,9 @@ - (CGPoint) readVerticalLinetoArgumentSequence:(NSScanner*)scanner path:(CGMutab
CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPoint coord = CGPointMake(currentPoint.x, currentPoint.y+(vertCoord.y-currentPoint.y));
CGPathAddLineToPoint(path, NULL, coord.x, coord.y);
#if DEBUG_PATH_CREATION
NSLog(@"[%@] PATH: VERTICAL LINE to (%2.2f, %2.2f)", [self class], coord.x, coord.y );
#endif
return coord;
}

Expand Down Expand Up @@ -643,6 +668,9 @@ - (CGPoint) readHorizontalLinetoArgumentSequence:(NSScanner*)scanner path:(CGMut
CGPoint currentPoint = CGPathGetCurrentPoint(path);
CGPoint coord = CGPointMake(currentPoint.x+(horizCoord.x-currentPoint.x), currentPoint.y);
CGPathAddLineToPoint(path, NULL, coord.x, coord.y);
#if DEBUG_PATH_CREATION
NSLog(@"[%@] PATH: HORIZONTAL LINE to (%2.2f, %2.2f)", [self class], coord.x, coord.y );
#endif
return coord;
}

Expand Down Expand Up @@ -675,6 +703,9 @@ - (CGPoint) readCloseCommand:(NSScanner*)scanner path:(CGMutablePathRef)path rel
if (!ok) return origin;

CGPathCloseSubpath(path);
#if DEBUG_PATH_CREATION
NSLog(@"[%@] PATH: finished path", [self class] );
#endif

return origin;
}
Expand Down
60 changes: 60 additions & 0 deletions Samples/test-wave-1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.