211 lines
5.9 KiB
Objective-C
211 lines
5.9 KiB
Objective-C
//
|
|
// IJSVGCommand.m
|
|
// IconJar
|
|
//
|
|
// Created by Curtis Hard on 30/08/2014.
|
|
// Copyright (c) 2014 Curtis Hard. All rights reserved.
|
|
//
|
|
|
|
#import "IJSVGCommand.h"
|
|
#import "IJSVGUtils.h"
|
|
|
|
#import "IJSVGCommandClose.h"
|
|
#import "IJSVGCommandCurve.h"
|
|
#import "IJSVGCommandEllipticalArc.h"
|
|
#import "IJSVGCommandHorizontalLine.h"
|
|
#import "IJSVGCommandLineTo.h"
|
|
#import "IJSVGCommandMove.h"
|
|
#import "IJSVGCommandQuadraticCurve.h"
|
|
#import "IJSVGCommandSmoothCurve.h"
|
|
#import "IJSVGCommandSmoothQuadraticCurve.h"
|
|
#import "IJSVGCommandVerticalLine.h"
|
|
|
|
@implementation IJSVGCommand
|
|
|
|
@synthesize commandString;
|
|
@synthesize command;
|
|
@synthesize parameterCount;
|
|
@synthesize parameters;
|
|
@synthesize subCommands;
|
|
@synthesize requiredParameters;
|
|
@synthesize type;
|
|
@synthesize previousCommand;
|
|
@synthesize isSubCommand;
|
|
|
|
+ (BOOL)requiresCustomParameterParsing
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
+ (NSInteger)requiredParameterCount
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
+ (void)runWithParams:(CGFloat*)params
|
|
paramCount:(NSInteger)count
|
|
command:(IJSVGCommand*)currentCommand
|
|
previousCommand:(IJSVGCommand*)command
|
|
type:(IJSVGCommandType)type
|
|
path:(IJSVGPath*)path
|
|
{
|
|
}
|
|
|
|
+ (void)parseParams:(CGFloat*)params
|
|
paramCount:(NSInteger)paramCount
|
|
intoArray:(NSMutableArray<IJSVGCommand*>*)commands
|
|
parentCommand:(IJSVGCommand*)parentCommand
|
|
{
|
|
}
|
|
|
|
+ (NSPoint)readCoordinatePair:(CGFloat*)pairs
|
|
index:(NSInteger)index
|
|
{
|
|
return NSMakePoint(pairs[index * 2], pairs[index * 2 + 1]);
|
|
}
|
|
|
|
+ (void)load
|
|
{
|
|
// register here...
|
|
}
|
|
|
|
+ (Class)commandClassForCommandChar:(char)aChar
|
|
{
|
|
aChar = tolower(aChar);
|
|
switch (aChar) {
|
|
case 'a':
|
|
return IJSVGCommandEllipticalArc.class;
|
|
case 'c':
|
|
return IJSVGCommandCurve.class;
|
|
case 'h':
|
|
return IJSVGCommandHorizontalLine.class;
|
|
case 'l':
|
|
return IJSVGCommandLineTo.class;
|
|
case 'm':
|
|
return IJSVGCommandMove.class;
|
|
case 'q':
|
|
return IJSVGCommandQuadraticCurve.class;
|
|
case 's':
|
|
return IJSVGCommandSmoothCurve.class;
|
|
case 't':
|
|
return IJSVGCommandSmoothQuadraticCurve.class;
|
|
case 'v':
|
|
return IJSVGCommandVerticalLine.class;
|
|
case 'z':
|
|
return IJSVGCommandClose.class;
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
(void)([commandString release]), commandString = nil;
|
|
(void)([command release]), command = nil;
|
|
(void)([subCommands release]), subCommands = nil;
|
|
(void)(free(parameters)), parameters = nil;
|
|
[super dealloc];
|
|
}
|
|
|
|
- (id)initWithCommandString:(NSString*)str
|
|
{
|
|
if ((self = [super init]) != nil) {
|
|
// work out the basics
|
|
_currentIndex = 0;
|
|
command = [[str substringToIndex:1] copy];
|
|
type = [IJSVGUtils typeForCommandString:self.command];
|
|
parameters = [IJSVGUtils commandParameters:str
|
|
count:¶meterCount];
|
|
requiredParameters = [self.class requiredParameterCount];
|
|
|
|
// check what required params we need
|
|
if (requiredParameters == IJSVGCustomVariableParameterCount) {
|
|
// looks like we require variable params
|
|
subCommands = [[NSMutableArray alloc] init];
|
|
|
|
// parse the custom params
|
|
[self.class parseParams:parameters
|
|
paramCount:parameterCount
|
|
intoArray:subCommands
|
|
parentCommand:self];
|
|
} else {
|
|
// now work out the sets of parameters we have
|
|
// each command could have a series of subcommands
|
|
// if there is a multiple of commands in a command
|
|
// then we need to work those out...
|
|
NSInteger sets = 1;
|
|
if (self.requiredParameters != 0) {
|
|
sets = (self.parameterCount / self.requiredParameters);
|
|
}
|
|
|
|
subCommands = [[NSMutableArray alloc] initWithCapacity:sets];
|
|
|
|
// interate over the sets
|
|
IJSVGCommand* lastCommand = nil;
|
|
for (NSInteger i = 0; i < sets; i++) {
|
|
// memory for this will be handled by the created subcommand
|
|
CGFloat* subParams = 0;
|
|
if (self.requiredParameters != 0) {
|
|
subParams = (CGFloat*)malloc(self.requiredParameters * sizeof(CGFloat));
|
|
for (NSInteger p = 0; p < self.requiredParameters; p++) {
|
|
subParams[p] = self.parameters[i * self.requiredParameters + p];
|
|
}
|
|
}
|
|
|
|
// generate the subcommand
|
|
IJSVGCommand* command = [self subcommandWithParameters:subParams
|
|
previousCommand:lastCommand];
|
|
|
|
// make sure we assign the last command or hell breaks
|
|
// lose and the firey demons will run wild, namely, commands will break
|
|
// if they are multiples of a set
|
|
lastCommand = command;
|
|
|
|
// add it to our tree
|
|
[subCommands addObject:command];
|
|
}
|
|
}
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (IJSVGCommand*)subcommandWithParameters:(CGFloat*)subParams
|
|
previousCommand:(IJSVGCommand*)aPreviousCommand
|
|
{
|
|
// create a subcommand per set
|
|
IJSVGCommand* c = [[[self.class alloc] init] autorelease];
|
|
c.parameterCount = self.requiredParameters;
|
|
c.parameters = subParams;
|
|
c.type = self.type;
|
|
c.command = self.command;
|
|
c.previousCommand = aPreviousCommand;
|
|
c.isSubCommand = aPreviousCommand != nil;
|
|
return c;
|
|
}
|
|
|
|
- (CGFloat)readFloat
|
|
{
|
|
CGFloat f = parameters[_currentIndex];
|
|
_currentIndex++;
|
|
return f;
|
|
}
|
|
|
|
- (NSPoint)readPoint
|
|
{
|
|
CGFloat x = parameters[_currentIndex];
|
|
CGFloat y = parameters[_currentIndex + 1];
|
|
_currentIndex += 2;
|
|
return NSMakePoint(x, y);
|
|
}
|
|
|
|
- (BOOL)readBOOL
|
|
{
|
|
return [self readFloat] == 1;
|
|
}
|
|
|
|
- (void)resetRead
|
|
{
|
|
_currentIndex = 0;
|
|
}
|
|
|
|
@end
|