Skip to content
Open
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
10 changes: 9 additions & 1 deletion SVGKit-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@
66EEE8641688CB37002E2658 /* SVGStyleCatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 66EEE85D1688CB37002E2658 /* SVGStyleCatcher.h */; settings = {ATTRIBUTES = (Public, ); }; };
66EEE8651688CB37002E2658 /* SVGStyleElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 66EEE85E1688CB37002E2658 /* SVGStyleElement.h */; settings = {ATTRIBUTES = (Public, ); }; };
66EEE8661688CB37002E2658 /* SVGStyleElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 66EEE85F1688CB37002E2658 /* SVGStyleElement.m */; };
D431D78016A807C3006BDB76 /* UIColor-Expanded.h in Headers */ = {isa = PBXBuildFile; fileRef = D431D77F16A807C3006BDB76 /* UIColor-Expanded.h */; settings = {ATTRIBUTES = (Public, ); }; };
D431D78316A807F8006BDB76 /* UIColor-Expanded.m in Sources */ = {isa = PBXBuildFile; fileRef = D431D78216A807F8006BDB76 /* UIColor-Expanded.m */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -392,6 +394,8 @@
66EEE85D1688CB37002E2658 /* SVGStyleCatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGStyleCatcher.h; sourceTree = "<group>"; };
66EEE85E1688CB37002E2658 /* SVGStyleElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGStyleElement.h; sourceTree = "<group>"; };
66EEE85F1688CB37002E2658 /* SVGStyleElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGStyleElement.m; sourceTree = "<group>"; };
D431D77F16A807C3006BDB76 /* UIColor-Expanded.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor-Expanded.h"; sourceTree = "<group>"; };
D431D78216A807F8006BDB76 /* UIColor-Expanded.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor-Expanded.m"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -571,8 +575,8 @@
66E8633D1688C2770059C9C4 /* SVGElementInstanceList.m */,
66E8633E1688C2770059C9C4 /* SVGElementInstanceList_Internal.h */,
6668E2061688D3CF00F774A6 /* SVGGElement.h */,
66988DAF1689FF5D00EC93C7 /* SVGStylable.h */,
6668E2071688D3CF00F774A6 /* SVGGElement.m */,
66988DAF1689FF5D00EC93C7 /* SVGStylable.h */,
66E8633F1688C2770059C9C4 /* SVGLength.h */,
66E863401688C2770059C9C4 /* SVGLength.m */,
66E863411688C2770059C9C4 /* SVGMatrix.h */,
Expand Down Expand Up @@ -700,6 +704,8 @@
66E863911688C2780059C9C4 /* UIKit additions */ = {
isa = PBXGroup;
children = (
D431D77F16A807C3006BDB76 /* UIColor-Expanded.h */,
D431D78216A807F8006BDB76 /* UIColor-Expanded.m */,
66E863921688C2780059C9C4 /* SVGKFastImageView.h */,
66E863931688C2780059C9C4 /* SVGKFastImageView.m */,
66E863941688C2780059C9C4 /* SVGKImageView.h */,
Expand Down Expand Up @@ -829,6 +835,7 @@
666674C1168A556300486B68 /* StyleSheetList.h in Headers */,
666674C5168A55AF00486B68 /* StyleSheet.h in Headers */,
666674C9168A561C00486B68 /* MediaList.h in Headers */,
D431D78016A807C3006BDB76 /* UIColor-Expanded.h in Headers */,
6694BB7B16967407007D0947 /* DOMGlobalSettings.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -982,6 +989,7 @@
666674C6168A55AF00486B68 /* StyleSheet.m in Sources */,
666674CA168A561C00486B68 /* MediaList.m in Sources */,
66372F5A16960D4F008C6C56 /* SVGRect.m in Sources */,
D431D78316A807F8006BDB76 /* UIColor-Expanded.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 2 additions & 0 deletions Source/DOM classes/SVG-DOM/SVGGElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
SVGTransformable {
*/

#import <UIKit/UIKit.h>

#import "SVGElement.h"
#import "SVGElement_ForParser.h"

Expand Down
79 changes: 54 additions & 25 deletions Source/DOM classes/SVG-DOM/SVGGElement.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,63 @@ - (CALayer *) newLayer
}

- (void)layoutLayer:(CALayer *)layer {
CGRect mainRect = CGRectZero;

/** Adam: make a frame thats the UNION of all sublayers frames */
for ( CALayer *currentLayer in [layer sublayers] )
{
CGRect subLayerFrame = currentLayer.frame;
mainRect = CGRectUnion(mainRect, subLayerFrame);
CGRect frameRect = CGRectZero;
CGRect mainRect = CGRectZero;
CGRect boundsRect = CGRectZero;

NSArray *sublayers = [layer sublayers];

for (NSUInteger n = 0; n < [sublayers count]; n++) {
CALayer *currentLayer = [sublayers objectAtIndex:n];

if (n == 0) {
frameRect = currentLayer.frame;
}
else {
frameRect = CGRectUnion(frameRect, currentLayer.frame);
}
mainRect = CGRectUnion(mainRect, currentLayer.frame);
}

boundsRect = CGRectOffset(frameRect, -frameRect.origin.x, -frameRect.origin.y);

for (CALayer *currentLayer in sublayers) {
[currentLayer setAffineTransform:CGAffineTransformConcat(currentLayer.affineTransform, CGAffineTransformMakeTranslation(-frameRect.origin.x, -frameRect.origin.y))];
}

layer.frame = mainRect;
layer.frame = boundsRect;

/** (dont know why this is here): set each sublayer to have a frame the same size as the parent frame, but with 0 offset.

if I understand this correctly, the person who wrote it should have just written:

"currentLayer.bounds = layer.frame"

i.e. make every layer have the same size as the parent layer.

But whoever wrote this didn't document their code, so I have no idea if thats correct or not
*/
for (CALayer *currentLayer in [layer sublayers]) {
CGRect frame = currentLayer.frame;
frame.origin.x -= mainRect.origin.x;
frame.origin.y -= mainRect.origin.y;

currentLayer.frame = frame;
}
#if OUTLINE_SHAPES

layer.borderColor = [UIColor redColor].CGColor;
layer.borderWidth = 2.0f;

NSString* textToDraw = [NSString stringWithFormat:@"%@ (%@): {%.1f, %.1f} {%.1f, %.1f}", self.identifier, [self class], layer.frame.origin.x, layer.frame.origin.y, layer.frame.size.width, layer.frame.size.height];

UIFont* fontToDraw = [UIFont fontWithName:@"Helvetica"
size:10.0f];
CGSize sizeOfTextRect = [textToDraw sizeWithFont:fontToDraw];

CATextLayer *debugText = [[[CATextLayer alloc] init] autorelease];
[debugText setFont:@"Helvetica"];
[debugText setFontSize:10.0f];
[debugText setFrame:CGRectMake(0, 0, sizeOfTextRect.width, sizeOfTextRect.height)];
[debugText setString:textToDraw];
[debugText setAlignmentMode:kCAAlignmentLeft];
[debugText setForegroundColor:[UIColor redColor].CGColor];
[debugText setContentsScale:[[UIScreen mainScreen] scale]];
[debugText setShouldRasterize:NO];
[layer addSublayer:debugText];

#endif

//applying transform relative to centerpoint
CGAffineTransform tr1 = layer.affineTransform;
tr1 = CGAffineTransformConcat(tr1, CGAffineTransformMakeTranslation(frameRect.size.width/2, frameRect.size.height/2));
CGAffineTransform tr2 = CGAffineTransformConcat(tr1, self.transformRelative);
tr2 = CGAffineTransformConcat(tr2, CGAffineTransformInvert(tr1));
tr1 = CGAffineTransformConcat(CGAffineTransformMakeTranslation(frameRect.origin.x, frameRect.origin.y), tr2);
[layer setAffineTransform:tr1];
}

@end
1 change: 1 addition & 0 deletions Source/DOM classes/Unported or Partial DOM/SVGElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "SVGStylable.h"

#define DEBUG_SVG_ELEMENT_PARSING 0
#define OUTLINE_SHAPES 1

@class SVGSVGElement;
//obj-c's compiler sucks, and doesn't allow this line: #import "SVGSVGElement.h"
Expand Down
25 changes: 15 additions & 10 deletions Source/DOM classes/Unported or Partial DOM/SVGElement.m
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,9 @@ - (void)postProcessAttributesAddingErrorsTo:(SVGKParseResult *)parseResult {
return;
}
NSString* command = [transformString substringToIndex:loc.location];
NSArray* parameterStrings = [[transformString substringFromIndex:loc.location+1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]];

//we MUST take SPACE character into consideration as a parameters separator
NSArray* parameterStrings = [[transformString substringFromIndex:loc.location+1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@", "]];

command = [command stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" "]];

Expand Down Expand Up @@ -274,25 +276,24 @@ - (void)postProcessAttributesAddingErrorsTo:(SVGKParseResult *)parseResult {
https://github.com/warpflyght/SVGKit/commit/c1bd9b3d0607635dda14ec03579793fc682763d9

*/
NSArray *rotateStrings = [[parameterStrings objectAtIndex:0] componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if( [rotateStrings count] == 1)
if( [parameterStrings count] == 1)
{
CGFloat degrees = [[rotateStrings objectAtIndex:0] floatValue];
CGFloat degrees = [[parameterStrings objectAtIndex:0] floatValue];
CGFloat radians = degrees * M_PI / 180.0;

CGAffineTransform nt = CGAffineTransformMakeRotation(radians);
self.transformRelative = CGAffineTransformConcat( self.transformRelative, nt );
}
else if( [rotateStrings count] == 3)
else if( [parameterStrings count] == 3)
{
CGFloat degrees = [[rotateStrings objectAtIndex:0] floatValue];
CGFloat degrees = [[parameterStrings objectAtIndex:0] floatValue];
CGFloat radians = degrees * M_PI / 180.0;
CGFloat centerX = [[rotateStrings objectAtIndex:1] floatValue];
CGFloat centerY = [[rotateStrings objectAtIndex:2] floatValue];
CGFloat centerX = [[parameterStrings objectAtIndex:1] floatValue];
CGFloat centerY = [[parameterStrings objectAtIndex:2] floatValue];
CGAffineTransform nt = CGAffineTransformIdentity;
nt = CGAffineTransformConcat( nt, CGAffineTransformMakeTranslation(centerX, centerY) );
nt = CGAffineTransformConcat( nt, CGAffineTransformMakeTranslation(-centerX, -centerY) );
nt = CGAffineTransformConcat( nt, CGAffineTransformMakeRotation(radians) );
nt = CGAffineTransformConcat( nt, CGAffineTransformMakeTranslation(-1.0 * centerX, -1.0 * centerY) );
nt = CGAffineTransformConcat( nt, CGAffineTransformMakeTranslation(centerX, centerY) );
self.transformRelative = CGAffineTransformConcat( self.transformRelative, nt );
} else
{
Expand Down Expand Up @@ -507,6 +508,10 @@ -(NSString *)cascadedFill
{
return [self cascadedValueForStylableProperty:@"fill"];
}
// TODO:
// Property "opacity" should be applied to the whole object, not just for the fill.
// We have "fill-opacity" just for the case. We should use it here.
// But [self cascadedFillOpacity] returns us the value of "opacity" prop. That's wrong.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I'd like to remove these convenience methods, and force all code to call through the "cascadedValueForStylableProperty:" method.

And ... make that method check if the incoming property CAN be cascaded (using the table from SVG Spec)

-(NSString *)cascadedFillOpacity
{
return [self cascadedValueForStylableProperty:@"opacity"];
Expand Down
2 changes: 2 additions & 0 deletions Source/DOM classes/Unported or Partial DOM/SVGGroupElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// Copyright Matt Rajca 2010-2011. All rights reserved.
//

#import <UIKit/UIKit.h>

#import "SVGElement.h"
#import "SVGLayeredElement.h"

Expand Down
79 changes: 54 additions & 25 deletions Source/DOM classes/Unported or Partial DOM/SVGGroupElement.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,34 +53,63 @@ - (CALayer *) newLayer
}

- (void)layoutLayer:(CALayer *)layer {
CGRect mainRect = CGRectZero;

/** Adam: make a frame thats the UNION of all sublayers frames */
for ( CALayer *currentLayer in [layer sublayers] )
{
CGRect subLayerFrame = currentLayer.frame;
mainRect = CGRectUnion(mainRect, subLayerFrame);
CGRect frameRect = CGRectZero;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this been tested with all the current samples in Demo-iOS project? I don't know preciesly what the original was intended to do, but it seems to be forcing Apple to expand the bounds of each CALAyer to fit its content (because Apple's API isn't very good to start with)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested this with SOME of the current samples.
The difference is that in my code layer bounds do not include {0,0} point, it just perfectly fits the content, helping us to perform transforms correctly.

You can clearly see the difference with the introduced debug option OUTLINE_SHAPES enabled.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of Apple's API requires 0,0 to be included, otherwise all the co-ordinate systems are broken.

Transforms are currently correct in all the samples. I'll try merging OUTLINE-SHAPES (looks very useful!), but also: do you have an example SVG that renders incorrectly with 0,0 included? would be good to add as a test case

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, actually, as it seems to me, all the coordinate systems with groups are broken now. Just because they are not transformed.
Also, instead of just transforming CALayer for group element, we need some magic like:

for (CALayer *currentLayer in [layer sublayers]) {
   CGRect frame = currentLayer.frame;
   frame.origin.x -= mainRect.origin.x;
   frame.origin.y -= mainRect.origin.y;
   currentLayer.frame = frame;
}

They have a good explanation here: http://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace
(pictures are really useful!)

It seems to render correctly, though (at least, until there's no transformed text). I will try to draw an example.

CGRect mainRect = CGRectZero;
CGRect boundsRect = CGRectZero;

NSArray *sublayers = [layer sublayers];

for (NSUInteger n = 0; n < [sublayers count]; n++) {
CALayer *currentLayer = [sublayers objectAtIndex:n];

if (n == 0) {
frameRect = currentLayer.frame;
}
else {
frameRect = CGRectUnion(frameRect, currentLayer.frame);
}
mainRect = CGRectUnion(mainRect, currentLayer.frame);
}

boundsRect = CGRectOffset(frameRect, -frameRect.origin.x, -frameRect.origin.y);

for (CALayer *currentLayer in sublayers) {
[currentLayer setAffineTransform:CGAffineTransformConcat(currentLayer.affineTransform, CGAffineTransformMakeTranslation(-frameRect.origin.x, -frameRect.origin.y))];
}

layer.frame = mainRect;
layer.frame = boundsRect;

/** Adam:(dont know why this is here): set each sublayer to have a frame the same size as the parent frame, but with 0 offset.

Adam: if I understand this correctly, the person who wrote it should have just written:

"currentLayer.bounds = layer.frame"

i.e. make every layer have the same size as the parent layer.

But whoever wrote this didn't document their bad code, so I have no idea if thats correct or not
*/
for (CALayer *currentLayer in [layer sublayers]) {
CGRect frame = currentLayer.frame;
frame.origin.x -= mainRect.origin.x;
frame.origin.y -= mainRect.origin.y;

currentLayer.frame = frame;
}
#if OUTLINE_SHAPES

layer.borderColor = [UIColor redColor].CGColor;
layer.borderWidth = 2.0f;

NSString* textToDraw = [NSString stringWithFormat:@"%@ (%@): {%.1f, %.1f} {%.1f, %.1f}", self.identifier, [self class], layer.frame.origin.x, layer.frame.origin.y, layer.frame.size.width, layer.frame.size.height];

UIFont* fontToDraw = [UIFont fontWithName:@"Helvetica"
size:10.0f];
CGSize sizeOfTextRect = [textToDraw sizeWithFont:fontToDraw];

CATextLayer *debugText = [[[CATextLayer alloc] init] autorelease];
[debugText setFont:@"Helvetica"];
[debugText setFontSize:10.0f];
[debugText setFrame:CGRectMake(0, 0, sizeOfTextRect.width, sizeOfTextRect.height)];
[debugText setString:textToDraw];
[debugText setAlignmentMode:kCAAlignmentLeft];
[debugText setForegroundColor:[UIColor redColor].CGColor];
[debugText setContentsScale:[[UIScreen mainScreen] scale]];
[debugText setShouldRasterize:NO];
[layer addSublayer:debugText];

#endif

//applying transform relative to centerpoint
CGAffineTransform tr1 = layer.affineTransform;
tr1 = CGAffineTransformConcat(tr1, CGAffineTransformMakeTranslation(frameRect.size.width/2, frameRect.size.height/2));
CGAffineTransform tr2 = CGAffineTransformConcat(tr1, self.transformRelative);
tr2 = CGAffineTransformConcat(tr2, CGAffineTransformInvert(tr1));
tr1 = CGAffineTransformConcat(CGAffineTransformMakeTranslation(frameRect.origin.x, frameRect.origin.y), tr2);
[layer setAffineTransform:tr1];
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ - (void)postProcessAttributesAddingErrorsTo:(SVGKParseResult *)parseResult {
_ry = [[self getAttribute:@"ry"] floatValue];

CGMutablePathRef path = CGPathCreateMutable();
CGRect rect = CGRectMake(_x, _y, _width, _height);
CGRect rect = CGRectMake(0, 0, _width, _height);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does this work? It seems to be ignoring the X and Y attributes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

X and Y attributes are taken into account in the parent class (SVGShapeElement, line 194). That was made to have correct layer bounds with transforms. Also, can be seen with OUTLINE_SHAPES enabled.


if (_rx == 0 && _ry == 0) {
CGPathAddRect(path, NULL, rect);
Expand Down
2 changes: 1 addition & 1 deletion Source/DOM classes/Unported or Partial DOM/SVGSVGElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,6 @@

@property (nonatomic, readonly) CGRect viewBoxFrame; // FIXME: this has NON TRIVIAL relationship to the viewport property above

- (SVGElement *)findFirstElementOfClass:(Class)class; /*< temporary convenience method until SVGDocument support is complete */
- (SVGElement *)findFirstElementOfClass:(Class)cl; /*< temporary convenience method until SVGDocument support is complete */

@end
4 changes: 2 additions & 2 deletions Source/DOM classes/Unported or Partial DOM/SVGSVGElement.m
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ - (void)postProcessAttributesAddingErrorsTo:(SVGKParseResult *)parseResult {
}
}

- (SVGElement *)findFirstElementOfClass:(Class)class {
- (SVGElement *)findFirstElementOfClass:(Class)cl {
for (SVGElement *element in self.childNodes)
{
if ([element isKindOfClass:class])
if ([element isKindOfClass:cl])
return element;
}

Expand Down
4 changes: 4 additions & 0 deletions Source/DOM classes/Unported or Partial DOM/SVGShapeElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
CGRect _layerRect;
}

@property (nonatomic, readonly) CGFloat x;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accoridng to SVG spec, there's no X nor Y in SVGShapeElement - they only exist in SVGRectElement

(some of these SVG*Element classes are badly wrong in SVGKit right now, but I'm moving them all towards being spec-compliant)


@property (nonatomic, readonly) CGFloat y;

@property (nonatomic, readwrite) CGFloat opacity;

@property (nonatomic) float fillOpacity, strokeOpacity;
Expand Down
Loading