Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 35fc5157b3 | |||
| 3742cfd16e | |||
| b47b487a8d | |||
| 6dc767f88e | |||
| f8efb68277 | |||
| 27c4638fa7 | |||
| 7c8bfa937e | |||
| fdc30123a4 | |||
| 80ef3790d2 | |||
| ded0c9b839 | |||
| 6585501f5d | |||
| 846f0fe27c | |||
| 0c64626e3e | |||
| 9ea09ebeee | |||
| 0c04202ad1 | |||
| e66ee5e5a1 | |||
| a97272252d |
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 53;
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -764,7 +764,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = YES;
|
||||
LastUpgradeCheck = 1430;
|
||||
LastUpgradeCheck = 1600;
|
||||
ORGANIZATIONNAME = "Curtis Hard";
|
||||
TargetAttributes = {
|
||||
594CF46E238FF38E009B251B = {
|
||||
@@ -926,9 +926,9 @@
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@@ -951,6 +951,7 @@
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "-Wl,-no_warn_duplicate_libraries";
|
||||
PRODUCT_MODULE_NAME = IJSVG;
|
||||
SDKROOT = macosx;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@@ -999,6 +1000,7 @@
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREFIX_HEADER = "";
|
||||
@@ -1014,6 +1016,7 @@
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
OTHER_LDFLAGS = "-Wl,-no_warn_duplicate_libraries";
|
||||
PRODUCT_MODULE_NAME = IJSVG;
|
||||
SDKROOT = macosx;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@@ -1043,7 +1046,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 2.2.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
@@ -1073,7 +1076,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 2.2.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.iconjar.ijsvg;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1430"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -294,22 +294,12 @@ CGFloat* IJSVGColorCSSHSLToHSB(CGFloat hue, CGFloat saturation, CGFloat lightnes
|
||||
NSInteger floatCount = 0;
|
||||
CGFloat *params = [IJSVGUtils scanFloatsFromCString:method->parameters
|
||||
size:&floatCount];
|
||||
|
||||
// Make sure the floats are not negative
|
||||
BOOL validParam = true;
|
||||
for(int i = 0; i < floatCount; i++) {
|
||||
if(params[i] == -0x0) {
|
||||
validParam = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
((void)free(params)), params = NULL;
|
||||
|
||||
// If we dont, just return black
|
||||
if(validParam == NO) {
|
||||
(void)free(params), params = NULL;
|
||||
if(floatCount < 3) {
|
||||
return [self computeColorSpace:NSColor.blackColor];
|
||||
}
|
||||
|
||||
// Make sure the floats are not negative
|
||||
// parse the parameters
|
||||
NSString* parameters = [NSString stringWithUTF8String:method->parameters];
|
||||
NSArray* parts = [parameters ijsvg_componentsSeparatedByChars:","];
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class IJSVG;
|
||||
@class IJSVGParser;
|
||||
|
||||
@interface IJSVG : NSObject <NSPasteboardWriting> {
|
||||
|
||||
@@ -30,6 +31,7 @@
|
||||
CGRect _viewBox;
|
||||
CGFloat _backingScale;
|
||||
IJSVGUnitSize* _intrinsicSize;
|
||||
IJSVGParser* _parser;
|
||||
}
|
||||
|
||||
// set this to be called when the layer is about to draw, it will call this
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#import <IJSVG/IJSVGTransaction.h>
|
||||
#import <IJSVG/IJSVGThreadManager.h>
|
||||
|
||||
@interface IJSVG (private)
|
||||
@property (nonatomic, strong) IJSVGParser* parser;
|
||||
@end
|
||||
|
||||
@implementation IJSVG
|
||||
|
||||
// these are explicitly implemented
|
||||
@@ -174,10 +178,10 @@
|
||||
NSError* anError = nil;
|
||||
|
||||
// create the group
|
||||
IJSVGParser* parser = [IJSVGParser parserForFileURL:aURL
|
||||
IJSVGParser *parser = [IJSVGParser parserForFileURL:aURL
|
||||
error:&anError];
|
||||
_rootNode = parser.rootNode;
|
||||
|
||||
self.parser = parser;
|
||||
|
||||
[self _setupBasicInfoFromGroup];
|
||||
[self _setupBasicsFromAnyInitializer];
|
||||
|
||||
@@ -199,6 +203,16 @@
|
||||
error:nil];
|
||||
}
|
||||
|
||||
- (void)setParser:(IJSVGParser*)parser {
|
||||
_rootNode = [parser rootNodeWithSize:CGSizeZero];
|
||||
|
||||
// if the rootNode has any form of relative units, we need to keep hold of
|
||||
// the parser so when we render, we can ask for new values.
|
||||
if(_rootNode.viewBoxContainsRelativeUnits) {
|
||||
_parser = parser;
|
||||
}
|
||||
}
|
||||
|
||||
- (id)initWithSVGData:(NSData*)data
|
||||
error:(NSError**)error
|
||||
{
|
||||
@@ -224,9 +238,9 @@
|
||||
|
||||
// setup the parser
|
||||
IJSVGParser* parser = [[IJSVGParser alloc] initWithSVGString:string
|
||||
error:&anError];
|
||||
_rootNode = parser.rootNode;
|
||||
|
||||
error:&anError];
|
||||
self.parser = parser;
|
||||
|
||||
[self _setupBasicInfoFromGroup];
|
||||
[self _setupBasicsFromAnyInitializer];
|
||||
|
||||
@@ -625,7 +639,7 @@
|
||||
}
|
||||
}
|
||||
CGContextSetInterpolationQuality(ctx, quality);
|
||||
IJSVGRootLayer* rootLayer = self.rootLayer;
|
||||
IJSVGRootLayer* rootLayer = [self rootLayerWithRect:rect];
|
||||
[rootLayer renderInContext:ctx
|
||||
viewPort:rect
|
||||
backingScale:backingScale
|
||||
@@ -647,16 +661,35 @@
|
||||
return _layerTree;
|
||||
}
|
||||
|
||||
- (IJSVGRootLayer*)rootLayerWithRect:(CGRect)rect {
|
||||
// no parser, which means there is no need to recompute the value
|
||||
if(_parser == nil || !_rootNode.viewBoxContainsRelativeUnits ||
|
||||
CGSizeEqualToSize(_rootNode.clientSize, rect.size)) {
|
||||
return self.rootLayer;
|
||||
}
|
||||
|
||||
// if we do have a parser, that means the node has relative values, lets recompute
|
||||
__weak IJSVG* weakSelf = self;
|
||||
[self performBlock:^{
|
||||
IJSVG* strongSelf = weakSelf;
|
||||
strongSelf->_rootNode = [strongSelf->_parser rootNodeWithSize:rect.size];
|
||||
strongSelf->_rootLayer = [strongSelf.layerTree rootLayerForRootNode:strongSelf->_rootNode];
|
||||
}];
|
||||
return _rootLayer;
|
||||
}
|
||||
|
||||
- (IJSVGRootLayer*)rootLayer
|
||||
{
|
||||
if(_rootLayer == nil) {
|
||||
__weak IJSVG* weakSelf = self;
|
||||
[self performBlock:^{
|
||||
IJSVG* strongSelf = weakSelf;
|
||||
strongSelf->_rootLayer = [strongSelf.layerTree rootLayerForRootNode:strongSelf->_rootNode];
|
||||
}];
|
||||
}
|
||||
if(_rootLayer != nil) {
|
||||
return _rootLayer;
|
||||
}
|
||||
|
||||
__weak IJSVG* weakSelf = self;
|
||||
[self performBlock:^{
|
||||
IJSVG* strongSelf = weakSelf;
|
||||
strongSelf->_rootLayer = [strongSelf.layerTree rootLayerForRootNode:strongSelf->_rootNode];
|
||||
}];
|
||||
return _rootLayer;
|
||||
}
|
||||
|
||||
- (CGFloat)backingScaleFactor
|
||||
|
||||
@@ -396,13 +396,21 @@ intoUserSpaceUnitsFrom:(CALayer<IJSVGDrawableLayer>*)fromLayer
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
CGImageRef ref = [self newImageForLayer:layer
|
||||
options:options
|
||||
colorSpace:colorSpace
|
||||
bitmapInfo:kCGImageAlphaNone
|
||||
scale:scale];
|
||||
CGImageRef alphaMask = [self newImageForLayer:layer
|
||||
options:options
|
||||
colorSpace:colorSpace
|
||||
bitmapInfo:kCGImageAlphaNone
|
||||
scale:scale];
|
||||
// low - high pairs
|
||||
const CGFloat colors[6] = {
|
||||
0.f, 11.f,
|
||||
0.f, 11.f,
|
||||
0.f, 11.f
|
||||
};
|
||||
CGImageRef masked = CGImageCreateWithMaskingColors(alphaMask, colors);
|
||||
CGImageRelease(alphaMask);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
return ref;
|
||||
return masked;
|
||||
}
|
||||
|
||||
+ (CGImageRef)newImageWithSize:(CGSize)size
|
||||
@@ -428,8 +436,10 @@ intoUserSpaceUnitsFrom:(CALayer<IJSVGDrawableLayer>*)fromLayer
|
||||
bitmapInfo:(uint32_t)bitmapInfo
|
||||
scale:(CGFloat)scale
|
||||
{
|
||||
CALayer<IJSVGDrawableLayer>* referenceLayer = layer.referencingLayer ?: layer;
|
||||
CGRect frame = layer.outerBoundingBox;
|
||||
CGRect bounds = layer.innerBoundingBox;
|
||||
CGRect bounds = CGRectApplyAffineTransform(layer.innerBoundingBox,
|
||||
[self userSpaceTransformForLayer:referenceLayer]);
|
||||
CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
|
||||
ceilf(frame.size.width*scale),
|
||||
ceilf(frame.size.height*scale),
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
[storage setBit:IJSVGNodeAttributeClipPath];
|
||||
[storage setBit:IJSVGNodeAttributeMask];
|
||||
[storage setBit:IJSVGNodeAttributeOpacity];
|
||||
[storage setBit:IJSVGNodeAttributeBlendMode];
|
||||
return storage;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
@interface IJSVGRootNode : IJSVGGroup
|
||||
|
||||
@property (nonatomic, assign) CGSize clientSize;
|
||||
@property (nonatomic, assign) BOOL viewBoxContainsRelativeUnits;
|
||||
@property (nonatomic, assign) IJSVGIntrinsicDimensions intrinsicDimensions;
|
||||
@property (nonatomic, strong) IJSVGUnitSize* intrinsicSize;
|
||||
@property (nonatomic, readonly) CGRect bounds;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
- (IJSVGRootNode *)rootNode
|
||||
{
|
||||
IJSVGRootNode* rootNode = nil;
|
||||
if((rootNode = [super rootNode]) == self) {
|
||||
if((rootNode = super.rootNode) == self) {
|
||||
IJSVGNode* parent = self.parentNode;
|
||||
if([parent isKindOfClass:IJSVGRootNode.class]) {
|
||||
return (IJSVGRootNode*)parent;
|
||||
|
||||
@@ -153,6 +153,16 @@ CGFloat* _Nullable IJSVGParsePathDataStreamSequence(const char* commandChars, NS
|
||||
// null value of the end of the string instead of nulling out
|
||||
// with memset \0 - huzzah!
|
||||
dataStream->charBuffer[bufferCount] = '\0';
|
||||
|
||||
// lets check to make the buffer actually has a valid float, and
|
||||
// not either just a sign or white space or some random char.
|
||||
if(strlen(dataStream->charBuffer) == 1 && !VALID_DIGIT(dataStream->charBuffer[0])) {
|
||||
isDecimal = false;
|
||||
bufferCount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// actually add the float into the buffer
|
||||
dataStream->floatBuffer[counter++] = IJSVGParseFloat(dataStream->charBuffer);
|
||||
|
||||
// reset
|
||||
@@ -166,7 +176,7 @@ CGFloat* _Nullable IJSVGParsePathDataStreamSequence(const char* commandChars, NS
|
||||
if(commandsFound != NULL) {
|
||||
*commandsFound = (NSInteger)round(counter / commandLength);
|
||||
}
|
||||
|
||||
|
||||
// allocate the new buffer from memory
|
||||
CGFloat* floats = (CGFloat*)malloc(sizeof(CGFloat) * counter);
|
||||
memcpy(floats, dataStream->floatBuffer, counter * sizeof(CGFloat));
|
||||
|
||||
@@ -127,9 +127,11 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers);
|
||||
IJSVGStyleSheet* _styleSheet;
|
||||
NSMutableDictionary<NSString*, NSXMLElement*>* _detachedReferences;
|
||||
IJSVGThreadManager* _threadManager;
|
||||
CGSize _rootSize;
|
||||
IJSVGRootNode* _rootNode;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong, readonly) IJSVGRootNode* rootNode;
|
||||
@property (nonatomic, assign) CGSize defaultSize;
|
||||
|
||||
+ (BOOL)isDataSVG:(NSData*)data;
|
||||
|
||||
@@ -142,4 +144,6 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers);
|
||||
+ (IJSVGParser*)parserForFileURL:(NSURL*)aURL
|
||||
error:(NSError**)error;
|
||||
|
||||
- (IJSVGRootNode*)rootNodeWithSize:(CGSize)size;
|
||||
|
||||
@end
|
||||
|
||||
@@ -121,6 +121,8 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
error:(NSError**)error
|
||||
{
|
||||
if((self = [super init]) != nil) {
|
||||
// just some generic value to get it up n running.
|
||||
_defaultSize = CGSizeMake(200.f, 200.f);
|
||||
|
||||
// use NSXMLDocument as its the easiest thing to do on OSX
|
||||
NSError* anError = nil;
|
||||
@@ -138,19 +140,12 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
error:error];
|
||||
}
|
||||
|
||||
// attempt to parse the file
|
||||
[self begin];
|
||||
|
||||
// check the actual parsed SVG
|
||||
anError = nil;
|
||||
if([self _validateParse:&anError] == NO) {
|
||||
*error = anError;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// we have actually finished with the document at this point
|
||||
// so just get rid of it
|
||||
_document = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -211,7 +206,36 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)begin
|
||||
- (IJSVGRootNode*)rootNodeWithSize:(CGSize)size
|
||||
{
|
||||
__weak IJSVGParser* weakSelf = self;
|
||||
[self beginWithSetup:^{
|
||||
// if we have passed in a value that is not zero, we can just set it to that
|
||||
// else we need to compute it, as we can treat zero as auto.
|
||||
IJSVGParser* strongSelf = weakSelf;
|
||||
CGSize computeSize = size;
|
||||
if(!CGSizeEqualToSize(CGSizeZero, computeSize)) {
|
||||
strongSelf->_rootSize = size;
|
||||
return;
|
||||
}
|
||||
|
||||
// compute the value, if the value is still a nil size, we just need to
|
||||
// fallback to some generic value, which is against this object.
|
||||
IJSVGRootNode* node = [self rootNode:NO];
|
||||
if(node.viewBox == nil) {
|
||||
strongSelf->_rootSize = strongSelf->_defaultSize;
|
||||
return;
|
||||
}
|
||||
|
||||
// at this point we can just compute it again from the viewBox size.
|
||||
computeSize = [node.viewBox.size computeValue:CGSizeZero];
|
||||
strongSelf->_rootSize = CGSizeEqualToSize(CGSizeZero, computeSize) ?
|
||||
strongSelf->_defaultSize : computeSize;
|
||||
}];
|
||||
return _rootNode;
|
||||
}
|
||||
|
||||
- (void)beginWithSetup:(dispatch_block_t __nullable)setup
|
||||
{
|
||||
// setup basics to begin with
|
||||
_styleSheet = [[IJSVGStyleSheet alloc] init];
|
||||
@@ -219,12 +243,17 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
_threadManager = manager;
|
||||
_commandDataStream = manager.pathDataStream;
|
||||
_detachedReferences = [[NSMutableDictionary alloc] init];
|
||||
if(setup != nil) {
|
||||
setup();
|
||||
}
|
||||
_rootNode = [[IJSVGRootNode alloc] init];
|
||||
_rootNode.clientSize = _rootSize;
|
||||
IJSVGNodeParserPostProcessBlock postProcessBlock = nil;
|
||||
[self parseSVGElement:_document.rootElement
|
||||
ontoNode:_rootNode
|
||||
parentNode:nil
|
||||
postProcessBlock:&postProcessBlock];
|
||||
postProcessBlock:&postProcessBlock
|
||||
recursive:YES];
|
||||
if(postProcessBlock != nil) {
|
||||
postProcessBlock();
|
||||
}
|
||||
@@ -232,6 +261,23 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
_detachedReferences = nil;
|
||||
}
|
||||
|
||||
- (IJSVGRootNode*)rootNode:(BOOL)recursive
|
||||
{
|
||||
IJSVGNodeParserPostProcessBlock postProcessBlock = nil;
|
||||
IJSVGRootNode* node = [[IJSVGRootNode alloc] init];
|
||||
node.clientSize = _rootSize;
|
||||
[self parseSVGElement:_document.rootElement
|
||||
ontoNode:node
|
||||
parentNode:nil
|
||||
postProcessBlock:&postProcessBlock
|
||||
recursive:NO];
|
||||
if(postProcessBlock != nil) {
|
||||
postProcessBlock();
|
||||
}
|
||||
[node postProcess];
|
||||
return node;
|
||||
}
|
||||
|
||||
- (void)computeDefsForElement:(NSXMLElement*)element
|
||||
parentNode:(IJSVGNode*)parentNode
|
||||
{
|
||||
@@ -250,22 +296,26 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
- (void)computeViewBoxForRootNode:(IJSVGRootNode*)node
|
||||
{
|
||||
if(node.viewBox == nil) {
|
||||
CGFloat width = node.width.value;
|
||||
CGFloat height = node.height.value;
|
||||
IJSVGUnitLength* width = node.width;
|
||||
IJSVGUnitLength* height = node.height;
|
||||
|
||||
CGFloat cw = [width computeValue:_rootSize.width];
|
||||
CGFloat ch = [height computeValue:_rootSize.height];
|
||||
|
||||
if(height == 0.f && width != 0.f) {
|
||||
height = width;
|
||||
} else if(width == 0.f && height != 0.f) {
|
||||
width = height;
|
||||
if(ch == 0.f && cw != 0.f) {
|
||||
ch = cw;
|
||||
} else if(cw == 0.f && ch != 0.f) {
|
||||
cw = ch;
|
||||
}
|
||||
// nothing we can do, its a nil viewBox and has
|
||||
// no width or height
|
||||
if(width == 0.f && height == 0.f) {
|
||||
if(cw == 0.f && ch == 0.f) {
|
||||
return;
|
||||
}
|
||||
node.viewBox = [IJSVGUnitRect rectWithX:0.f y:0.f
|
||||
width:width
|
||||
height:height];
|
||||
IJSVGUnitSize* size = [IJSVGUnitSize sizeWithWidth:width
|
||||
height:height];
|
||||
node.viewBox = [IJSVGUnitRect rectWithOrigin:IJSVGUnitPoint.zeroPoint
|
||||
size:size];
|
||||
}
|
||||
|
||||
IJSVGIntrinsicDimensions dimensions = IJSVGIntrinsicDimensionNone;
|
||||
@@ -279,11 +329,25 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
dimensions |= IJSVGIntrinsicDimensionHeight;
|
||||
hl = node.height;
|
||||
}
|
||||
|
||||
// make note if we are using relative units for the width or height.
|
||||
if(wl.type == IJSVGUnitLengthTypePercentage ||
|
||||
hl.type == IJSVGUnitLengthTypePercentage) {
|
||||
node.viewBoxContainsRelativeUnits = YES;
|
||||
}
|
||||
|
||||
// store the width and height
|
||||
node.intrinsicDimensions = dimensions;
|
||||
node.intrinsicSize = [IJSVGUnitSize sizeWithWidth:wl
|
||||
height:hl];
|
||||
|
||||
// compute the new width and height based on the passed in size as the fall
|
||||
// back for all the percentage values.
|
||||
CGSize computedSize = CGSizeMake([wl computeValue:_rootSize.width],
|
||||
[hl computeValue:_rootSize.height]);
|
||||
node.intrinsicSize = [IJSVGUnitSize sizeWithCGSize:computedSize];
|
||||
|
||||
// compute the viewbox
|
||||
CGRect computedViewBox = [node.viewBox computeValue:_rootSize];
|
||||
node.viewBox.size = [IJSVGUnitSize sizeWithCGSize:computedViewBox.size];
|
||||
}
|
||||
|
||||
- (IJSVGNodeParserPostProcessBlock)computeAttributesFromElement:(NSXMLElement*)element
|
||||
@@ -1004,6 +1068,21 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
attribute = attribute.copy;
|
||||
[copy addAttribute:attribute];
|
||||
}
|
||||
|
||||
// if we merge an element, we need to also maintain its children, if the
|
||||
// reference element has children and the referencing element does not,
|
||||
// use those else use the referencing element children.
|
||||
if (element.childCount != 0) {
|
||||
// remove any old children
|
||||
for(__strong NSXMLElement* child in copy.children) {
|
||||
[copy removeChildAtIndex:child.index];
|
||||
}
|
||||
|
||||
// add the new ones from the copy
|
||||
for(__strong NSXMLElement* child in element.children) {
|
||||
[copy addChild:child.copy];
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -1385,6 +1464,7 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
ontoNode:(IJSVGRootNode*)node
|
||||
parentNode:(IJSVGNode*)parentNode
|
||||
postProcessBlock:(IJSVGNodeParserPostProcessBlock*)postProcessBlock
|
||||
recursive:(BOOL)recursive
|
||||
{
|
||||
node.type = IJSVGNodeTypeSVG;
|
||||
node.name = element.localName;
|
||||
@@ -1414,8 +1494,10 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
[self computeViewBoxForRootNode:node];
|
||||
|
||||
// recursively compute children
|
||||
[self computeElement:element
|
||||
parentNode:node];
|
||||
if(recursive == YES) {
|
||||
[self computeElement:element
|
||||
parentNode:node];
|
||||
}
|
||||
}
|
||||
|
||||
- (IJSVGNode*)parseSVGElement:(NSXMLElement*)element
|
||||
@@ -1426,7 +1508,8 @@ void IJSVGParserMallocBuffersFree(IJSVGParserMallocBuffers* buffers)
|
||||
[self parseSVGElement:element
|
||||
ontoNode:node
|
||||
parentNode:parentNode
|
||||
postProcessBlock:postProcessBlock];
|
||||
postProcessBlock:postProcessBlock
|
||||
recursive:YES];
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -606,10 +606,12 @@
|
||||
// we need to move all the layers back if they are into the userSpace
|
||||
// coordinate system
|
||||
for(CALayer<IJSVGDrawableLayer> *childLayer in maskLayer.sublayers) {
|
||||
childLayer.frame = CGRectApplyAffineTransform(childLayer.frame,
|
||||
userSpaceTransform);
|
||||
CGRect innerBoundingBox = childLayer.innerBoundingBox;
|
||||
CGAffineTransform innerTransform = CGAffineTransformMakeTranslation(-innerBoundingBox.origin.x,
|
||||
-innerBoundingBox.origin.y);
|
||||
childLayer.frame = CGRectApplyAffineTransform(childLayer.frame, userSpaceTransform);
|
||||
childLayer.frame = CGRectApplyAffineTransform(childLayer.frame, innerTransform);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(maskNode.units == IJSVGUnitUserSpaceOnUse) {
|
||||
|
||||
@@ -94,7 +94,7 @@ IJSVGParsingStringMethod** IJSVGParsingMethodParseString(const char* string,
|
||||
// now we can add
|
||||
if(methodCount + 1 > currentBufferSize) {
|
||||
currentBufferSize += defBufferSize;
|
||||
*methods = *(IJSVGParsingStringMethod**)realloc(methods, sizeof(IJSVGParsingStringMethod*)*currentBufferSize);
|
||||
methods = (IJSVGParsingStringMethod**)realloc(methods, sizeof(IJSVGParsingStringMethod*)*currentBufferSize);
|
||||
}
|
||||
methods[methodCount++] = method;
|
||||
method = NULL;
|
||||
|
||||
@@ -61,7 +61,7 @@ char* IJSVGTimmedCharBufferCreate(const char* buffer)
|
||||
while(length-1 > 0 && isspace(buffer[length-1])) {
|
||||
length--;
|
||||
}
|
||||
while(isspace(buffer[start])) {
|
||||
while(isspace(buffer[start]) && start < length) {
|
||||
start++;
|
||||
}
|
||||
char* chars = (char*)malloc(sizeof(char)*((length-start)+1) ?: sizeof(char));
|
||||
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user