Skip to content
Browse files

FIXED: SVG <g> elements now layout their CALayer output correctly (fi…

…xes a long-running bug introduced because we didn't understand how the original code from 2010 was intended to work, and got it wrong. I've added extensive code docs to make it clearer for future maintainers)
  • Loading branch information...
1 parent 3375aaa commit 0dd5eae4905e1b758dc1133e2775d7418e32f0d7 adamgit committed May 11, 2013
Showing with 18 additions and 11 deletions.
  1. +18 −11 Source/DOM classes/SVG-DOM/SVGGElement.m
29 Source/DOM classes/SVG-DOM/SVGGElement.m
@@ -19,32 +19,39 @@ - (CALayer *) newLayer
- (void)layoutLayer:(CALayer *)layer {
CGRect mainRect = CGRectZero;
- /** Adam: make a frame thats the UNION of all sublayers frames */
+ /** we don't want the rect to be union'd with 0,0, so we need to initialize it to one of the subrects */
+ if( layer.sublayers.count > 0 )
+ mainRect = ((CALayer*)[layer.sublayers objectAtIndex:0]).frame;
+ /** make mainrect the UNION of all sublayer's frames (i.e. their individual "bounds" inside THIS layer's space) */
for ( CALayer *currentLayer in [layer sublayers] )
CGRect subLayerFrame = currentLayer.frame;
mainRect = CGRectUnion(mainRect, subLayerFrame);
+ /** use mainrect (union of all sub-layer bounds) this layer's FRAME
+ i.e. top-left-corner of this layer will be "the top left corner of the convex-hull rect of all sublayers"
+ AND: bottom-right-corner of this layer will be "the bottom-right corner of the convex-hull rect of all sublayers"
+ */
layer.frame = mainRect;
- /** (dont know why this is here): set each sublayer to have a frame the same size as the parent frame, but with 0 offset.
+ /** Changing THIS layer's frame now means all DIRECT sublayers are offset by too much (because when we change the offset
+ of the parent frame (this.frame), Apple *does not* shift the sublayers around to keep them in same place.
- 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
- */
+ NB: there are bugs in some Apple code in Interface Builder where it attempts to do exactly that (incorrectly, as the API
+ is specifically designed NOT to do this), and ... Fails. But in code, thankfully, Apple *almost* never does this (there are a few method
+ calls where it appears someone at Apple forgot how their API works, and tried to do the offsetting automatically. "Paved
+ with good intentions...".
+ */
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;

0 comments on commit 0dd5eae

Please sign in to comment.
Something went wrong with that request. Please try again.