5 // Created by Jens Alfke on 3/7/08.
6 // Copyright 2008 __MyCompanyName__. All rights reserved.
10 #import "QuartzUtils.h"
13 @implementation GGBLayer
16 - (NSString*) description
18 return [NSString stringWithFormat: @"%@[(%g,%g)]", self.class,self.position.x,self.position.y];
25 #pragma mark IPHONE VERSION:
28 - (id) copyWithZone: (NSZone*)zone
30 GGBLayer *clone = [[[self class] alloc] init];
31 clone.bounds = self.bounds;
32 clone.position = self.position;
33 clone.zPosition = self.zPosition;
34 clone.anchorPoint = self.anchorPoint;
35 clone.transform = self.transform;
36 clone.hidden = self.hidden;
37 clone.doubleSided = self.doubleSided;
38 clone.sublayerTransform = self.sublayerTransform;
39 clone.masksToBounds = self.masksToBounds;
40 clone.contents = self.contents; // doesn't copy contents (shallow-copy)
41 clone.contentsRect = self.contentsRect;
42 clone.contentsGravity = self.contentsGravity;
43 clone.minificationFilter = self.minificationFilter;
44 clone.magnificationFilter = self.magnificationFilter;
45 clone.opaque = self.opaque;
46 clone.needsDisplayOnBoundsChange = self.needsDisplayOnBoundsChange;
47 clone.edgeAntialiasingMask = self.edgeAntialiasingMask;
48 clone.backgroundColor = self.backgroundColor;
49 clone.opacity = self.opacity;
50 clone.compositingFilter = self.compositingFilter;
51 clone.filters = self.filters;
52 clone.backgroundFilters = self.backgroundFilters;
53 clone.actions = self.actions;
54 clone.name = self.name;
55 clone.style = self.style;
57 clone.cornerRadius = self.cornerRadius;
58 clone.borderWidth = self.borderWidth;
59 clone.borderColor = self.borderColor;
60 clone.autoresizingMask = self.autoresizingMask;
62 for( GGBLayer *sublayer in self.sublayers ) {
63 sublayer = [sublayer copyWithZone: zone];
64 [clone addSublayer: sublayer];
70 @synthesize autoresizingMask=_autoresizingMask;
72 - (CGFloat) cornerRadius {return _cornerRadius;}
73 - (CGFloat) borderWidth {return _borderWidth;}
74 - (CGColorRef) borderColor {return _borderColor;}
76 - (void) setCornerRadius: (CGFloat)r
78 if( r != _cornerRadius ) {
80 [self setNeedsDisplay];
85 - (void) setBorderWidth: (CGFloat)w
87 if( w != _borderWidth ) {
89 self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL);
90 [self setNeedsDisplay];
95 - (void) setBackgroundColor: (CGColorRef)color
97 if( color != _realBGColor ) {
98 CGColorRelease(_realBGColor);
99 _realBGColor = CGColorRetain(color);
100 [self setNeedsDisplay];
105 - (void) setBorderColor: (CGColorRef)color
107 if( color != _borderColor ) {
108 CGColorRelease(_borderColor);
109 _borderColor = CGColorRetain(color);
110 self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL);
111 [self setNeedsDisplay];
116 - (void)drawInContext:(CGContextRef)ctx
118 CGContextSaveGState(ctx);
121 CGRect interior = CGRectInset(self.bounds, _borderWidth,_borderWidth);
122 CGContextSetFillColorWithColor(ctx, _realBGColor);
123 if( _cornerRadius <= 0.0 ) {
124 CGContextFillRect(ctx,interior);
126 CGContextBeginPath(ctx);
127 AddRoundRect(ctx,interior,_cornerRadius);
128 CGContextFillPath(ctx);
132 if( _borderWidth > 0.0 && _borderColor!=NULL ) {
133 CGRect border = CGRectInset(self.bounds, _borderWidth/2.0, _borderWidth/2.0);
134 CGContextSetStrokeColorWithColor(ctx, _borderColor);
135 CGContextSetLineWidth(ctx, _borderWidth);
137 if( _cornerRadius <= 0.0 ) {
138 CGContextStrokeRect(ctx,border);
140 CGContextBeginPath(ctx);
141 AddRoundRect(ctx,border,_cornerRadius);
142 CGContextStrokePath(ctx);
146 CGContextRestoreGState(ctx);
153 #pragma mark MAC OS VERSION:
156 - (id) copyWithZone: (NSZone*)zone
158 // NSLayer isn't copyable, but it is archivable. So create a copy by archiving to
159 // a temporary data block, then unarchiving a new layer from that block.
161 // One complication is that, due to a bug in Core Animation, CALayer can't archive
162 // a pattern-based CGColor. So as a workaround, clear the background before archiving,
163 // then restore it afterwards.
165 // Also, archiving a CALayer with an image in it leaks memory. (Filed as rdar://5786865 )
166 // As a workaround, clear the contents before archiving, then restore.
168 CGColorRef bg = CGColorRetain(self.backgroundColor);
169 self.backgroundColor = NULL;
170 id contents = [self.contents retain];
173 NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self];
175 self.backgroundColor = bg;
176 self.contents = contents;
178 GGBLayer *clone = [NSKeyedUnarchiver unarchiveObjectWithData: data];
179 clone.backgroundColor = bg;
180 clone.contents = contents;
184 return [clone retain];