Compare commits

..

8 Commits

Author SHA1 Message Date
Curtis Hard 63586f1181 Reformat 2019-11-18 22:57:55 +00:00
Curtis Hard dc94d9761b Fixes subcommands, this is fairly big bug… 2019-11-18 22:55:44 +00:00
Curtis Hard 8deef07f7f Merge branch 'feature/primitive-colors' of https://github.com/curthard89/IJSVG into feature/primitive-colors 2019-10-24 19:31:54 +01:00
Curtis Hard 2c962db6cc Refactoring of commands 2019-10-24 19:31:51 +01:00
Curtis Hard 9dda7915fa Fixes shorthand 2019-10-22 14:11:12 +01:00
Curtis Hard 1fbb56b443 Fixes shorthand not working correctly 2019-10-22 14:10:23 +01:00
Curtis Hard 4bbf2277bc Fixes exporter 2019-10-20 18:50:34 +01:00
Curtis Hard 7eeeea5167 Adds support for RRGGBBAA 2019-10-20 17:07:07 +01:00
24 changed files with 288 additions and 170 deletions
+13 -3
View File
@@ -8,6 +8,14 @@
#import <Foundation/Foundation.h>
typedef NS_OPTIONS(NSInteger, IJSVGColorStringOptions) {
IJSVGColorStringOptionNone = 1 << 0,
IJSVGColorStringOptionForceHEX = 1 << 1,
IJSVGColorStringOptionAllowShortHand = 1 << 2,
IJSVGColorStringOptionAllowRRGGBBAA = 1 << 3,
IJSVGColorStringOptionDefault = IJSVGColorStringOptionAllowShortHand
};
typedef NS_ENUM( NSInteger, IJSVGPredefinedColor ) {
IJSVGColorAliceblue,
IJSVGColorAntiquewhite,
@@ -166,14 +174,16 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
+ (NSColorSpace *)defaultColorSpace;
+ (BOOL)isColor:(NSString *)string;
+ (NSString *)colorStringFromColor:(NSColor *)color
forceHex:(BOOL)forceHex
allowShorthand:(BOOL)allowShorthand;
options:(IJSVGColorStringOptions)options;
+ (NSString *)colorStringFromColor:(NSColor *)color;
+ (NSColor *)colorFromHEXInteger:(NSInteger)hex;
+ (NSColor *)computeColor:(id)colour;
+ (NSColor *)colorFromString:(NSString *)string;
+ (NSColor *)colorFromHEXString:(NSString *)string;
+ (NSColor *)colorFromHEXString:(NSString *)string
alpha:(CGFloat)alpha;
containsAlphaComponent:(BOOL *)containsAlphaComponent;
+ (BOOL)HEXContainsAlphaComponent:(NSUInteger)hex;
+ (unsigned long)lengthOfHEXInteger:(NSUInteger)hex;
+ (NSColor *)colorFromRString:(NSString *)rString
gString:(NSString *)gString
bString:(NSString *)bString
+85 -25
View File
@@ -269,7 +269,7 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
if( [[string substringToIndex:3] isEqualToString:@"rgb"] ) {
NSRange range = [IJSVGUtils rangeOfParentheses:string];
NSString * rgbString = [string substringWithRange:range];
NSArray * parts = [rgbString componentsSeparatedByChars:","];
NSArray * parts = [rgbString ijsvg_componentsSeparatedByChars:","];
NSString * alpha = @"100%";
if(parts.count == 4) {
alpha = parts[3];
@@ -305,7 +305,7 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
return color;
}
color = [self.class colorFromHEXString:string alpha:1.f];
color = [self.class colorFromHEXString:string];
return color;
}
@@ -321,14 +321,13 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
+ (NSString *)colorStringFromColor:(NSColor *)color
{
IJSVGColorStringOptions options = IJSVGColorStringOptionDefault;
return [self colorStringFromColor:color
forceHex:NO
allowShorthand:YES];
options:options];
}
+ (NSString *)colorStringFromColor:(NSColor *)color
forceHex:(BOOL)forceHex
allowShorthand:(BOOL)allowShorthand
options:(IJSVGColorStringOptions)options
{
// convert to RGB
color = [self computeColorSpace:color];
@@ -338,26 +337,54 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
int blue = color.blueComponent * 0xFF;
int alpha = (int)(color.alphaComponent*100);
BOOL forceHex = (options & IJSVGColorStringOptionForceHEX) != 0;
BOOL allowShortHand = (options & IJSVGColorStringOptionAllowShortHand) != 0;
BOOL allowRRGGBBAA = (options & IJSVGColorStringOptionAllowRRGGBBAA) != 0;
// jsut return none
if(alpha == 0 && forceHex == NO) {
return @"none";
}
// always return hex unless criteria is met
if(forceHex || alpha == 100 ||
if(forceHex == YES || allowRRGGBBAA == YES || alpha == 100 ||
(red == 0 && green == 0 && blue == 0 && alpha == 0) ||
(red == 255 && green == 255 && blue == 255 && alpha == 100)) {
if(allowShorthand == YES) {
// we need to make sure the last 2 chars
// are the same or we cant enable shorthand
if(allowRRGGBBAA == YES) {
NSString * alphaHexString = [NSString stringWithFormat:@"%02X",
(int)(color.alphaComponent * 0xFF)];
if([alphaHexString characterAtIndex:0] !=
[alphaHexString characterAtIndex:1]) {
allowShortHand = NO;
}
}
if(allowShortHand == YES) {
NSString * r = [NSString stringWithFormat:@"%02X",red];
NSString * g = [NSString stringWithFormat:@"%02X",green];
NSString * b = [NSString stringWithFormat:@"%02X",blue];
if([r characterAtIndex:0] == [r characterAtIndex:1] &&
[g characterAtIndex:0] == [g characterAtIndex:1] &&
[b characterAtIndex:0] == [b characterAtIndex:1]) {
// allow shorthand alpha
if(allowRRGGBBAA == YES && alpha != 100) {
NSString * a = [NSString stringWithFormat:@"%02X",
(int)(color.alphaComponent * 0xFF)];
return [NSString stringWithFormat:@"#%c%c%c%c",
[r characterAtIndex:0], [g characterAtIndex:0],
[b characterAtIndex:0], [a characterAtIndex:0]];
}
return [NSString stringWithFormat:@"#%c%c%c",[r characterAtIndex:0],
[g characterAtIndex:0],[b characterAtIndex:0]];
}
}
if(allowRRGGBBAA == YES && alpha != 100) {
return [NSString stringWithFormat:@"#%02X%02X%02X%02X",red,green,
blue,(int)(color.alphaComponent * 0xFF)];
}
return [NSString stringWithFormat:@"#%02X%02X%02X",red,green,blue];
}
@@ -672,9 +699,9 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
to:(CGFloat)alphaValue
{
color = [self computeColorSpace:color];
return [self computeColorSpace:[NSColor colorWithDeviceRed:[color redComponent]
green:[color greenComponent]
blue:[color blueComponent]
return [self computeColorSpace:[NSColor colorWithDeviceRed:color.redComponent
green:color.greenComponent
blue:color.blueComponent
alpha:alphaValue]];
}
@@ -696,42 +723,75 @@ CGFloat * IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightne
return YES;
}
+ (unsigned long)lengthOfHEXInteger:(NSUInteger)hex
{
char * buffer;
asprintf(&buffer, "%lX", (long)hex);
unsigned long length = strlen(buffer);
free(buffer);
return length;
}
+ (BOOL)HEXContainsAlphaComponent:(NSUInteger)hex
{
return [self lengthOfHEXInteger:hex] == 8;
}
+ (NSColor *)colorFromHEXInteger:(NSInteger)hex
{
CGFloat alpha = 1.f;
if([self HEXContainsAlphaComponent:hex] == YES) {
alpha = (hex & 0xFF) / 255.f;
hex = hex >> 8;
}
return [self computeColorSpace:[NSColor colorWithDeviceRed:((hex >> 16) & 0xFF) / 255.f
green:((hex >> 8) & 0xFF) / 255.f
blue:(hex & 0xFF) / 255.f
alpha:1.f]];
alpha:alpha]];
}
+ (unsigned long)HEXFromArbitraryHexString:(NSString *)aString
{
const char * hexString = [aString cStringUsingEncoding:NSUTF8StringEncoding];
return strtoul(hexString, NULL, 16);
}
+ (NSColor *)colorFromHEXString:(NSString *)string
alpha:(CGFloat)alpha
{
return [self colorFromHEXString:string
containsAlphaComponent:nil];
}
+ (NSColor *)colorFromHEXString:(NSString *)string
containsAlphaComponent:(BOOL *)containsAlphaComponent
{
// absolutely no string
if( string == nil || string.length == 0 || ![self.class isHex:string] )
if( string == nil || string.length == 0 || ![self.class isHex:string] ) {
return nil;
}
if( [[string substringToIndex:1] isEqualToString:@"#"] )
if( [[string substringToIndex:1] isEqualToString:@"#"] ) {
string = [string substringFromIndex:1];
}
// whats the length?
if(string.length == 3) {
NSUInteger length = string.length;
if(length == 3 || length == 4) {
// shorthand...
NSMutableString * str = [[[NSMutableString alloc] init] autorelease];
for( NSInteger i = 0; i < string.length; i++ )
{
NSString * sub = [string substringWithRange:NSMakeRange( i, 1)];
for( NSInteger i = 0; i < length; i++ ) {
NSString * sub = [string substringWithRange:NSMakeRange(i, 1)];
[str appendFormat:@"%@%@",sub,sub];
}
string = str;
}
const char * hexString = [string cStringUsingEncoding:NSUTF8StringEncoding];
unsigned long hex = strtoul(hexString, NULL, 16);
return [self computeColorSpace:[NSColor colorWithDeviceRed:((hex>>16) & 0xFF)/255.f
green:((hex>>8) & 0xFF)/255.f
blue:(hex & 0xFF)/255.f
alpha:alpha]];
// now convert rest to hex
unsigned long hex = [self HEXFromArbitraryHexString:string];
if(containsAlphaComponent != nil) {
*containsAlphaComponent = [self HEXContainsAlphaComponent:hex];
}
return [self colorFromHEXInteger:hex];
}
@end
+19 -21
View File
@@ -9,27 +9,13 @@
#import <Foundation/Foundation.h>
#import "IJSVGPath.h"
static const NSInteger IJSVGCustomVariableParameterCount = NSNotFound;
typedef NS_ENUM( NSInteger, IJSVGCommandType ) {
IJSVGCommandTypeAbsolute,
IJSVGCommandTypeRelative
};
@class IJSVGCommand;
@protocol IJSVGCommandProtocol <NSObject>
@required
+ (void)runWithParams:(CGFloat *)params
paramCount:(NSInteger)count
command:(IJSVGCommand *)currentCommand
previousCommand:(IJSVGCommand *)command
type:(IJSVGCommandType)type
path:(IJSVGPath *)path;
+ (NSInteger)requiredParameterCount;
@end
@interface IJSVGCommand : NSObject {
NSString * commandString;
NSString * command;
@@ -40,7 +26,6 @@ typedef NS_ENUM( NSInteger, IJSVGCommandType ) {
IJSVGCommandType type;
IJSVGCommand * previousCommand;
NSInteger _currentIndex;
Class<IJSVGCommandProtocol> commandClass;
BOOL isSubCommand;
}
@@ -50,15 +35,28 @@ typedef NS_ENUM( NSInteger, IJSVGCommandType ) {
@property ( nonatomic, assign ) NSInteger parameterCount;
@property ( nonatomic, assign ) NSInteger requiredParameters;
@property ( nonatomic, assign ) IJSVGCommandType type;
@property ( nonatomic, retain ) NSMutableArray * subCommands;
@property ( nonatomic, assign ) Class<IJSVGCommandProtocol> commandClass;
@property ( nonatomic, retain ) NSMutableArray<IJSVGCommand *> * subCommands;
@property ( nonatomic, assign ) IJSVGCommand * previousCommand;
@property ( nonatomic, assign ) BOOL isSubCommand;
- (id)initWithCommandString:(NSString *)commandString;
+ (Class)commandClassForCommandChar:(char)aChar;
+ (NSInteger)requiredParameterCount;
+ (NSPoint)readCoordinatePair:(CGFloat *)pairs
index:(NSInteger)index;
+ (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;
- (id)initWithCommandString:(NSString *)commandString;
- (IJSVGCommand *)subcommandWithParameters:(CGFloat *)subParams
previousCommand:(IJSVGCommand *)command;
- (CGFloat)readFloat;
- (NSPoint)readPoint;
+110 -60
View File
@@ -9,7 +9,7 @@
#import "IJSVGCommand.h"
#import "IJSVGUtils.h"
#import "IJSVGCommandArc.h"
#import "IJSVGCommandEllipticalArc.h"
#import "IJSVGCommandMove.h"
#import "IJSVGCommandClose.h"
#import "IJSVGCommandCurve.h"
@@ -18,7 +18,7 @@
#import "IJSVGCommandHorizontalLine.h"
#import "IJSVGCommandSmoothCurve.h"
#import "IJSVGCommandQuadraticCurve.h"
#import "IJSVGCommandCommandSmoothQuadraticCurve.h"
#import "IJSVGCommandSmoothQuadraticCurve.h"
@implementation IJSVGCommand
@@ -27,70 +27,35 @@
@synthesize parameterCount;
@synthesize parameters;
@synthesize subCommands;
@synthesize commandClass;
@synthesize requiredParameters;
@synthesize type;
@synthesize previousCommand;
@synthesize isSubCommand;
- (void)dealloc
+ (BOOL)requiresCustomParameterParsing
{
[commandString release], commandString = nil;
[command release], command = nil;
[subCommands release], subCommands = nil;
free( parameters );
[super dealloc];
return NO;
}
- (id)initWithCommandString:(NSString *)str
+ (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
{
if( ( self = [super init] ) != nil )
{
// work out the basics
_currentIndex = 0;
command = [[str substringToIndex:1] copy];
type = [IJSVGUtils typeForCommandString:self.command];
commandClass = [self.class commandClassForCommandChar:[self.command characterAtIndex:0]];
parameters = [IJSVGUtils commandParameters:str count:&parameterCount];
requiredParameters = [self.commandClass requiredParameterCount];
// 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
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];
}
}
// 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 = self.subCommands.lastObject;
c.commandClass = self.commandClass;
c.isSubCommand = i == 0 ? NO : YES;
// add it to our tree
[self.subCommands addObject:c];
}
}
return self;
}
+ (NSPoint)readCoordinatePair:(CGFloat *)pairs
@@ -104,24 +69,109 @@
// register here...
}
+ (Class<IJSVGCommandProtocol>)commandClassForCommandChar:(char)aChar
+ (Class)commandClassForCommandChar:(char)aChar
{
aChar = tolower(aChar);
switch(aChar) {
case 'a': return IJSVGCommandArc.class;
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 IJSVGCommandCommandSmoothQuadraticCurve.class;
case 't': return IJSVGCommandSmoothQuadraticCurve.class;
case 'v': return IJSVGCommandVerticalLine.class;
case 'z': return IJSVGCommandClose.class;
}
return nil;
}
- (void)dealloc
{
[commandString release], commandString = nil;
[command release], command = nil;
[subCommands release], subCommands = nil;
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:&parameterCount];
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];
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandClose : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandClose : IJSVGCommand
@end
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandCurve : IJSVGCommand
@end
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandArc : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandEllipticalArc : IJSVGCommand
@end
@@ -6,11 +6,10 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandArc.h"
#import "IJSVGCommandEllipticalArc.h"
#import "IJSVGUtils.h"
@implementation IJSVGCommandArc
@implementation IJSVGCommandEllipticalArc
+ (NSInteger)requiredParameterCount
{
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandHorizontalLine : NSObject <IJSVGCommandProtocol>
@interface IJSVGCommandHorizontalLine : IJSVGCommand
@end
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandLineTo : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandLineTo : IJSVGCommand
@end
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandMove : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandMove : IJSVGCommand
@end
+1 -1
View File
@@ -26,7 +26,7 @@
{
// move to's allow more then one move to, but if there are more then one,
// we need to run the line to instead...who knew!
if( command.commandClass == self.class && currentCommand.isSubCommand == YES) {
if( command.class == self.class && currentCommand.isSubCommand == YES) {
[IJSVGCommandLineTo runWithParams:params
paramCount:count
command:currentCommand
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandQuadraticCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandQuadraticCurve : IJSVGCommand
@end
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandSmoothCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandSmoothCurve : IJSVGCommand
@end
+5 -10
View File
@@ -25,14 +25,10 @@
path:(IJSVGPath *)path
{
NSPoint firstControl = NSMakePoint( [path currentSubpath].currentPoint.x, [path currentSubpath].currentPoint.y );
if( command != nil )
{
if( command.commandClass == [IJSVGCommandCurve class] || command.commandClass == self.class )
{
if( command.commandClass == [IJSVGCommandCurve class] )
{
if( command.type == IJSVGCommandTypeAbsolute )
{
if( command != nil ) {
if( command.class == [IJSVGCommandCurve class] || command.class == self.class ) {
if( command.class == [IJSVGCommandCurve class] ) {
if( command.type == IJSVGCommandTypeAbsolute ) {
firstControl = NSMakePoint(-1*command.parameters[2] + 2*[path currentSubpath].currentPoint.x,
-1*command.parameters[3] + 2*[path currentSubpath].currentPoint.y);
} else {
@@ -54,8 +50,7 @@
}
}
}
if( type == IJSVGCommandTypeAbsolute )
{
if( type == IJSVGCommandTypeAbsolute ) {
[[path currentSubpath] curveToPoint:NSMakePoint( params[2], params[3])
controlPoint1:NSMakePoint( firstControl.x, firstControl.y )
controlPoint2:NSMakePoint(params[0], params[1])];
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandCommandSmoothQuadraticCurve : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandSmoothQuadraticCurve : IJSVGCommand
@end
@@ -6,11 +6,11 @@
// Copyright (c) 2014 Curtis Hard. All rights reserved.
//
#import "IJSVGCommandCommandSmoothQuadraticCurve.h"
#import "IJSVGCommandSmoothQuadraticCurve.h"
#import "IJSVGUtils.h"
#import "IJSVGCommandQuadraticCurve.h"
@implementation IJSVGCommandCommandSmoothQuadraticCurve
@implementation IJSVGCommandSmoothQuadraticCurve
+ (NSInteger)requiredParameterCount
{
@@ -25,13 +25,10 @@
path:(IJSVGPath *)path
{
NSPoint commandPoint = NSMakePoint( [path currentSubpath].currentPoint.x, [path currentSubpath].currentPoint.y );
if( command != nil )
{
if( command.commandClass == [IJSVGCommandQuadraticCurve class] )
{
if( command != nil ) {
if( command.class == IJSVGCommandQuadraticCurve.class ) {
// quadratic curve
if( command.type == IJSVGCommandTypeAbsolute )
{
if( command.type == IJSVGCommandTypeAbsolute ) {
commandPoint = NSMakePoint(-1*command.parameters[0] + 2*[path currentSubpath].currentPoint.x,
-1*command.parameters[1] + 2*[path currentSubpath].currentPoint.y);
} else {
@@ -40,15 +37,14 @@
commandPoint = CGPointMake(-1*(command.parameters[0] + oldPoint.x) + 2*([path currentSubpath].currentPoint.x),
-1*(command.parameters[1] + oldPoint.y) + 2*[path currentSubpath].currentPoint.y);
}
} else if( command.commandClass == self.class ) {
} else if(command.class == self.class) {
// smooth quadratic curve
commandPoint = CGPointMake(-1*(path.lastControlPoint.x) + 2*([path currentSubpath].currentPoint.x),
-1*(path.lastControlPoint.y) + 2*[path currentSubpath].currentPoint.y);
}
}
path.lastControlPoint = commandPoint;
if( type == IJSVGCommandTypeAbsolute )
{
if( type == IJSVGCommandTypeAbsolute ) {
[[path currentSubpath] addQuadCurveToPoint:NSMakePoint(params[0], params[1])
controlPoint:commandPoint];
return;
+1 -1
View File
@@ -9,6 +9,6 @@
#import <Foundation/Foundation.h>
#import "IJSVGCommand.h"
@interface IJSVGCommandVerticalLine : IJSVGCommand <IJSVGCommandProtocol>
@interface IJSVGCommandVerticalLine : IJSVGCommand
@end
+3 -1
View File
@@ -29,6 +29,7 @@ typedef NS_OPTIONS( NSInteger, IJSVGExporterOptions) {
IJSVGExporterOptionCollapseGradients = 1 << 11,
IJSVGExporterOptionCreateClasses = 1 << 12,
IJSVGExporterOptionRemoveWidthHeightAttributes = 1 << 13,
IJSVGExporterOptionColorAllowRRGGBBAA = 1 << 14,
IJSVGExporterOptionAll = IJSVGExporterOptionRemoveUselessDef|
IJSVGExporterOptionRemoveUselessGroups|
IJSVGExporterOptionCreateUseForPaths|
@@ -40,7 +41,8 @@ typedef NS_OPTIONS( NSInteger, IJSVGExporterOptions) {
IJSVGExporterOptionScaleToSizeIfNecessary|
IJSVGExporterOptionCompressOutput|
IJSVGExporterOptionCollapseGradients|
IJSVGExporterOptionRemoveWidthHeightAttributes
IJSVGExporterOptionRemoveWidthHeightAttributes|
IJSVGExporterOptionColorAllowRRGGBBAA
};
BOOL IJSVGExporterHasOption(IJSVGExporterOptions options, NSInteger option);
+15 -4
View File
@@ -956,9 +956,9 @@ NSString * IJSVGHash(NSString * key) {
atts[@"offset"] = [NSString stringWithFormat:@"%g%%",(location*100)];
// add the color
IJSVGColorStringOptions options = IJSVGColorStringOptionForceHEX|IJSVGColorStringOptionAllowShortHand;
NSString * stopColor = [IJSVGColor colorStringFromColor:aColor
forceHex:YES
allowShorthand:YES];
options:options];
if([stopColor isEqualToString:@"#000000"] == NO) {
atts[@"stop-color"] = stopColor;
}
@@ -1044,6 +1044,15 @@ NSString * IJSVGHash(NSString * key) {
return imageElement;
}
- (IJSVGColorStringOptions)colorOptions
{
IJSVGColorStringOptions options = IJSVGColorStringOptionDefault;
if((_options & IJSVGExporterOptionColorAllowRRGGBBAA) != 0) {
options |= IJSVGColorStringOptionAllowRRGGBBAA;
}
return options;
}
- (NSXMLElement *)elementForShape:(IJSVGShapeLayer *)layer
fromParent:(NSXMLElement *)parent
{
@@ -1071,7 +1080,8 @@ NSString * IJSVGHash(NSString * key) {
// fill color
if(layer.fillColor != nil) {
NSColor * fillColor = [NSColor colorWithCGColor:layer.fillColor];
NSString * colorString = [IJSVGColor colorStringFromColor:fillColor];
NSString * colorString = [IJSVGColor colorStringFromColor:fillColor
options:[self colorOptions]];
// could be none
if(colorString != nil) {
@@ -1121,7 +1131,8 @@ NSString * IJSVGHash(NSString * key) {
} else if(strokeLayer.strokeColor != nil) {
NSColor * strokeColor = [NSColor colorWithCGColor:strokeLayer.strokeColor];
NSString * strokeColorString = [IJSVGColor colorStringFromColor:strokeColor];
NSString * strokeColorString = [IJSVGColor colorStringFromColor:strokeColor
options:[self colorOptions]];
// could be none
if(strokeColorString != nil) {
+10 -8
View File
@@ -1175,14 +1175,16 @@
}
// main commands
IJSVGCommand * command = [[[IJSVGCommand alloc] initWithCommandString:string] autorelease];
for( IJSVGCommand * subCommand in [command subCommands] ) {
[subCommand.commandClass runWithParams:subCommand.parameters
paramCount:subCommand.parameterCount
command:subCommand
previousCommand:preCommand
type:subCommand.type
path:path];
// Class commandClass = [IJSVGCommand classFor]
Class commandClass = [IJSVGCommand commandClassForCommandChar:[string characterAtIndex:0]];
IJSVGCommand * command = (IJSVGCommand *)[[[commandClass alloc] initWithCommandString:string] autorelease];
for( IJSVGCommand * subCommand in [command subCommands]) {
[command.class runWithParams:subCommand.parameters
paramCount:subCommand.parameterCount
command:subCommand
previousCommand:preCommand
type:subCommand.type
path:path];
preCommand = subCommand;
}
return command;
+4 -4
View File
@@ -10,9 +10,9 @@
@interface NSString (IJSVGAdditions)
- (NSArray<NSString *> *)componentsSeparatedByChars:(char *)aChar;
- (BOOL)isNumeric;
- (BOOL)containsAlpha;
- (NSArray *)componentsSplitByWhiteSpace;
- (NSArray<NSString *> *)ijsvg_componentsSeparatedByChars:(char *)aChar;
- (BOOL)ijsvg_isNumeric;
- (BOOL)ijsvg_containsAlpha;
- (NSArray *)ijsvg_componentsSplitByWhiteSpace;
@end
+4 -4
View File
@@ -10,7 +10,7 @@
@implementation NSString (IJSVGAdditions)
- (NSArray<NSString *> *)componentsSeparatedByChars:(char *)aChar
- (NSArray<NSString *> *)ijsvg_componentsSeparatedByChars:(char *)aChar
{
NSMutableArray * comp = [[[NSMutableArray alloc] init] autorelease];
NSInteger length = self.length;
@@ -60,7 +60,7 @@
return comp;
}
- (BOOL)containsAlpha
- (BOOL)ijsvg_containsAlpha
{
const char * buffer = self.UTF8String;
unsigned long length = strlen(buffer);
@@ -72,7 +72,7 @@
return NO;
}
- (BOOL)isNumeric
- (BOOL)ijsvg_isNumeric
{
const char * buffer = self.UTF8String;
unsigned long length = strlen(buffer);
@@ -84,7 +84,7 @@
return YES;
}
- (NSArray *)componentsSplitByWhiteSpace
- (NSArray *)ijsvg_componentsSplitByWhiteSpace
{
return [self componentsSeparatedByChars:"\t\n\r "];
}
-5
View File
@@ -94,11 +94,6 @@
return @[@"fill",@"stroke-colour",@"stop-color",@"stroke"];
}
+ (BOOL)isNumeric:(NSString *)string
{
return [[NSScanner scannerWithString:string] scanFloat:NULL];
}
- (void)setProperties:(NSDictionary *)properties
replaceAll:(BOOL)flag
{