Removing the use of private CoreGraphics APIs to draw shadows, and replacing with... master
authorJoseph Spiros <joseph.spiros@ithinksw.com>
Sat, 7 Aug 2010 23:05:49 +0000 (19:05 -0400)
committerJoseph Spiros <joseph.spiros@ithinksw.com>
Sat, 7 Aug 2010 23:05:49 +0000 (19:05 -0400)
ITCoreGraphicsHacks.h
ITImageCell.h
ITImageCell.m
ITTextFieldCell.h
ITTextFieldCell.m

index c818325..51a8f33 100644 (file)
@@ -12,16 +12,6 @@ typedef void * CGSGenericObj;
 typedef CGSGenericObj CGSValueObj;
 typedef void * CGSConnectionID;
 typedef void * CGSWindowID;
-typedef struct CGStyle *CGStyleRef;
-typedef struct CGShadowStyle {
-       unsigned int version;
-       float elevation;
-       float azimuth;
-       float ambient;
-       float height;
-       float radius;
-       float saturation;
-} CGShadowStyle;
 typedef unsigned char CGSBoolean;
 enum {
        kCGSFalse = 0,
@@ -35,11 +25,7 @@ typedef enum {
         CGSTagSticky           = 0x0800,   // Appears on all workspaces.
 } CGSWindowTag;
 
-extern void CGStyleRelease(CGStyleRef style);
 extern void CGSReleaseObj(void *obj);
-extern void CGContextSetStyle(CGContextRef c, CGStyleRef style);
-extern void CGStyleRelease(CGStyleRef style);
-extern CGStyleRef CGStyleCreateShadow(const CGShadowStyle *shadow);
 extern CGSValueObj CGSCreateCString(const char *string);
 extern CGSValueObj CGSCreateBoolean(CGSBoolean boolean);
 extern CGError CGSSetWindowProperty(const CGSConnectionID cid, CGSWindowID wid, const CGSValueObj key, const CGSValueObj value);
index 68ef999..8b70f2f 100644 (file)
@@ -2,12 +2,9 @@
  *     ITKit
  *     ITImageCell.h
  *
- *     Custom NSImageCell subclass that casts a shadow using CoreGraphics,
- *             providing support for versions of Cocoa that don't have the NSShadow
- *             class which was introduced in Mac OS X 10.3 (Panther), and also
- *             provides smooth scaling.
+ *     Custom NSImageCell subclass that casts a shadow and provides smooth scaling.
  *
- *     Copyright (c) 2005 iThink Software
+ *     Copyright (c) 2010 iThink Software
  *
  */
 
 @interface ITImageCell : NSImageCell {
        BOOL _scalesSmoothly;
        BOOL castsShadow;
-       float shadowElevation;
        float shadowAzimuth;
        float shadowAmbient;
        float shadowHeight;
        float shadowRadius;
-       float shadowSaturation;
 }
 
 - (BOOL)scalesSmoothly;
@@ -30,8 +25,8 @@
 - (BOOL)castsShadow;
 - (void)setCastsShadow:(BOOL)newSetting;
 
-- (float)shadowElevation; /* Light source elevation in degrees. Defaults to 45.0 */
-- (void)setShadowElevation:(float)newElevation;
+- (float)shadowElevation; /* Light source elevation in degrees. Always 45.0 */
+- (void)setShadowElevation:(float)newElevation; /* NOOP */
 
 - (float)shadowAzimuth; /* Light source azimuth in degrees. Defaults to 90.0 */
 - (void)setShadowAzimuth:(float)newAzimuth;
@@ -45,7 +40,7 @@
 - (float)shadowRadius; /* Blur radius. Defaults to 4.0 */
 - (void)setShadowRadius:(float)newRadius;
 
-- (float)shadowSaturation; /* Maximum saturation. Defaults to 1.0 */
-- (void)setShadowSaturation:(float)newSaturation;
+- (float)shadowSaturation; /* Maximum saturation. Always 1.0 */
+- (void)setShadowSaturation:(float)newSaturation; /* NOOP */
 
 @end
\ No newline at end of file
index 1ca761d..a5d6852 100644 (file)
@@ -1,6 +1,6 @@
 #import "ITImageCell.h"
-#import "ITCoreGraphicsHacks.h"
 #import <ApplicationServices/ApplicationServices.h>
+#import <ITFoundation/ITFoundation.h>
 
 @implementation ITImageCell
 
@@ -8,12 +8,10 @@
        if ((self = [super initImageCell:image])) {
                _scalesSmoothly = YES;
                castsShadow = NO;
-               shadowElevation = 45.0;
                shadowAzimuth = 90.0;
                shadowAmbient = 0.15;
                shadowHeight = 1.00;
                shadowRadius = 4.00;
-               shadowSaturation = 1.0;
        }
        return self;
 }
        if ((self = [super init])) {
                _scalesSmoothly = YES;
                castsShadow = NO;
-               shadowElevation = 45.0;
                shadowAzimuth = 90.0;
-               shadowAmbient = 0.15;
+               shadowAmbient = 0.15; // In my tests, an alpha component of 0.85 perfectly duplicates the old private API's results, resulting in identical shadows. Therefore, the ambient can remain 0.15.
                shadowHeight = 1.00;
                shadowRadius = 4.00;
-               shadowSaturation = 1.0;
        }
        return self;
 }
 
 - (void)drawWithFrame:(NSRect)rect inView:(NSView *)controlView {
-       CGSGenericObj style = nil;
-       CGShadowStyle shadow;
+       NSShadow *shadow;
        
        if (_scalesSmoothly || castsShadow) {
                [NSGraphicsContext saveGraphicsState];
        }
        
        if (_scalesSmoothly) {
-               // CGContextSetInterpolationQuality([[NSGraphicsContext currentContext] graphicsPort], kCGInterpolationHigh);
                [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
                [[NSGraphicsContext currentContext] setShouldAntialias:YES];
        }
        
        if (castsShadow) {
-               // Create the shadow style to use for drawing the string
-               shadow.version = 0;
-               shadow.elevation = shadowElevation;
-               shadow.azimuth = shadowAzimuth;
-               shadow.ambient = shadowAmbient;
-               shadow.height = shadowHeight;
-               shadow.radius = shadowRadius;
-               shadow.saturation = shadowSaturation;
-               style = CGStyleCreateShadow(&shadow);
-               CGContextSetStyle([[NSGraphicsContext currentContext] graphicsPort], style);
+               CGFloat height = ((2.0*tan((M_PI/360.0)*(shadowAzimuth-180.0)))*shadowHeight)/(1.0+pow(tan((M_PI/360.0)*(shadowAzimuth-180.0)),2.0));
+               CGFloat width = sqrt(pow(shadowHeight, 2.0)-pow(height, 2.0));
+               
+               shadow = [[NSShadow alloc] init];
+               [shadow setShadowColor:[[NSColor blackColor] colorWithAlphaComponent:(1.0 - shadowAmbient)]]; 
+               [shadow setShadowOffset:NSMakeSize(width, height)];
+               [shadow setShadowBlurRadius:shadowRadius];
+               
+               [shadow set];
        }
        
        [super drawWithFrame:rect inView:controlView];
        
-       if (castsShadow) {
-               CGStyleRelease(style);
-       }
-       
        if (_scalesSmoothly || castsShadow) {
                [NSGraphicsContext restoreGraphicsState];
        }
+       
+       if (castsShadow) {
+               [shadow release];
+       }
 }
 
 - (BOOL)scalesSmoothly {
 }
 
 - (float)shadowElevation {
-       return shadowElevation;
+       return 45.0;
 }
 
 - (void)setShadowElevation:(float)newElevation {
-       shadowElevation = newElevation;
-       [[self controlView] setNeedsDisplay:YES];
+       ITDebugLog(@"setShadowElevation: on ITImageCell objects does nothing.");
 }
 
 - (float)shadowAzimuth {
 }
 
 - (float)shadowSaturation {
-       return shadowSaturation;
+       return 1.0;
 }
 
 - (void)setShadowSaturation:(float)newSaturation {
-       shadowSaturation = newSaturation;
-       [[self controlView] setNeedsDisplay:YES];
+       ITDebugLog(@"setShadowSaturation: on ITImageCell objects does nothing.");
 }
 
 @end
\ No newline at end of file
index 9a733c6..3789552 100644 (file)
@@ -2,11 +2,9 @@
  *     ITKit
  *     ITTextFieldCell.h
  *
- *     Custom NSTextFieldCell subclass that casts a shadow using CoreGraphics,
- *             providing support for versions of Cocoa that don't have the NSShadow
- *             class which was introduced in Mac OS X 10.3 (Panther).
+ *     Custom NSTextFieldCell subclass that casts a shadow.
  *
- *     Copyright (c) 2005 iThink Software
+ *     Copyright (c) 2010 iThink Software
  *
  */
 
 
 @interface ITTextFieldCell : NSTextFieldCell {
        BOOL castsShadow;
-       float shadowElevation;
        float shadowAzimuth;
        float shadowAmbient;
        float shadowHeight;
        float shadowRadius;
-       float shadowSaturation;
 }
 
 - (BOOL)castsShadow;
 - (void)setCastsShadow:(BOOL)newSetting;
 
-- (float)shadowElevation; /* Light source elevation in degrees. Defaults to 45.0 */
-- (void)setShadowElevation:(float)newElevation;
+- (float)shadowElevation; /* Light source elevation in degrees. Always 45.0 */
+- (void)setShadowElevation:(float)newElevation; /* NOOP */
 
 - (float)shadowAzimuth; /* Light source azimuth in degrees. Defaults to 90.0 */
 - (void)setShadowAzimuth:(float)newAzimuth;
 
-- (float)shadowAmbient; /* Amount of ambient light. Defaults to 0.15 */
+- (float)shadowAmbient; /* Amount of ambient light. Defaults to 0.0 */
 - (void)setShadowAmbient:(float)newAmbient;
 
 - (float)shadowHeight; /* Height above the canvas. Defaults to 1.0 */
@@ -40,7 +36,7 @@
 - (float)shadowRadius; /* Blur radius. Defaults to 4.0 */
 - (void)setShadowRadius:(float)newRadius;
 
-- (float)shadowSaturation; /* Maximum saturation. Defaults to 1.0 */
-- (void)setShadowSaturation:(float)newSaturation;
+- (float)shadowSaturation; /* Maximum saturation. Always 1.0 */
+- (void)setShadowSaturation:(float)newSaturation; /* NOOP */
 
 @end
\ No newline at end of file
index 2dbc30c..002af3b 100644 (file)
@@ -1,18 +1,16 @@
 #import "ITTextFieldCell.h"
-#import "ITCoreGraphicsHacks.h"
 #import <ApplicationServices/ApplicationServices.h>
+#import <ITFoundation/ITFoundation.h>
 
 @implementation ITTextFieldCell
 
 - (id)initTextCell:(NSString *)string {
        if ((self = [super initTextCell:string])) {
                castsShadow = NO;
-               shadowElevation = 45.0;
                shadowAzimuth = 90.0;
-               shadowAmbient = 0.15;
+               shadowAmbient = 0.0;
                shadowHeight = 1.00;
                shadowRadius = 4.00;
-               shadowSaturation = 1.0;
        }
        return self;
 }
 - (id)initWithCoder:(NSCoder *)coder {
        if ((self = [super initWithCoder:coder])) {             
                castsShadow = NO;
-               shadowElevation = 45.0;
                shadowAzimuth = 90.0;
-               shadowAmbient = 0.15;
+               shadowAmbient = 0.0; // Unlike ITImageCell, even an alpha component of 1.0 is ligher than the old private API's results. There's not much we can do about it as we can't go "blacker" than black.
                shadowHeight = 1.00;
                shadowRadius = 4.00;
-               shadowSaturation = 1.0;
        }
        return self;
 }
 
 - (void)drawWithFrame:(NSRect)rect inView:(NSView *)controlView {
-       CGSGenericObj style = nil;
-       CGShadowStyle shadow;
+       NSShadow *shadow;
        
-       if ( castsShadow ) { 
-               // Create the shadow style to use for drawing the string
-               shadow.version = 0;
-               shadow.elevation = shadowElevation;
-               shadow.azimuth = shadowAzimuth;
-               shadow.ambient = shadowAmbient;
-               shadow.height = shadowHeight;
-               shadow.radius = shadowRadius;
-               shadow.saturation = shadowSaturation;
-               style = CGStyleCreateShadow(&shadow);
+       if (castsShadow) {
+               CGFloat height = ((2.0*tan((M_PI/360.0)*(shadowAzimuth-180.0)))*shadowHeight)/(1.0+pow(tan((M_PI/360.0)*(shadowAzimuth-180.0)),2.0));
+               CGFloat width = sqrt(pow(shadowHeight, 2.0)-pow(height, 2.0));
+               
+               shadow = [[NSShadow alloc] init];
+               [shadow setShadowColor:[[NSColor blackColor] colorWithAlphaComponent:(1.0 - shadowAmbient)]];
+               [shadow setShadowOffset:NSMakeSize(width, height)];
+               [shadow setShadowBlurRadius:shadowRadius];
                
-               // Set the context for drawing the string
                [NSGraphicsContext saveGraphicsState];
-               CGContextSetStyle([[NSGraphicsContext currentContext] graphicsPort], style);
+               [shadow set];
        }
        
        // Draw the string
@@ -56,7 +48,7 @@
        if (castsShadow) { 
                // Restore the old context
                [NSGraphicsContext restoreGraphicsState];
-               CGStyleRelease(style);
+               [shadow release];
        }
 }
 
 }
 
 - (float)shadowElevation {
-       return shadowElevation;
+       return 45.0;
 }
 
 - (void)setShadowElevation:(float)newElevation {
-       shadowElevation = newElevation;
-       [[self controlView] setNeedsDisplay:YES];
+       ITDebugLog(@"setShadowElevation: on ITTextFieldCell objects does nothing.");
 }
 
 - (float)shadowAzimuth {
 }
 
 - (float)shadowSaturation {
-       return shadowSaturation;
+       return 1.0;
 }
 
 - (void)setShadowSaturation:(float)newSaturation {
-       shadowSaturation = newSaturation;
-       [[self controlView] setNeedsDisplay:YES];
+       ITDebugLog(@"setShadowSaturation: on ITTextFieldCell objects does nothing.");
 }
 
 @end
\ No newline at end of file