diff options
Diffstat (limited to 'AppKit/GTMLinearRGBShading.m')
-rw-r--r-- | AppKit/GTMLinearRGBShading.m | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/AppKit/GTMLinearRGBShading.m b/AppKit/GTMLinearRGBShading.m deleted file mode 100644 index f605350..0000000 --- a/AppKit/GTMLinearRGBShading.m +++ /dev/null @@ -1,192 +0,0 @@ -// -// GTMLinearRGBShading.m -// -// Copyright 2006-2008 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMLinearRGBShading.h" -#import "GTMDefines.h" - -// Carbon callback function required for CoreGraphics -static void cShadeFunction(void *info, const CGFloat *inPos, CGFloat *outVals); - -@implementation GTMLinearRGBShading -+ (id)shadingFromColor:(NSColor *)begin toColor:(NSColor *)end - fromSpaceNamed:(NSString*)colorSpaceName { - NSColor *theColors[] = { begin, end }; - CGFloat thePositions[] = { 0.0, 1.0 }; - return [[self class] shadingWithColors:theColors - fromSpaceNamed:colorSpaceName - atPositions:thePositions - count:(sizeof(thePositions)/sizeof(CGFloat))]; -} - -+ (id)shadingWithColors:(NSColor **)colors fromSpaceNamed:(NSString*)colorSpaceName - atPositions:(CGFloat *)positions count:(NSUInteger)count { - - GTMLinearRGBShading *theShading = [[[self alloc] initWithColorSpaceName:colorSpaceName] autorelease]; - for (NSUInteger i = 0; i < count; ++i) { - [theShading insertStop:colors[i] atPosition:positions[i]]; - } - return theShading; -} - -- (id)initWithColorSpaceName:(NSString*)colorSpaceName { - if ((self = [super init])) { - if ([colorSpaceName isEqualToString:NSDeviceRGBColorSpace]) { - isCalibrated_ = NO; - } else if ([colorSpaceName isEqualToString:NSCalibratedRGBColorSpace]) { - isCalibrated_ = YES; - } - else { - [self release]; - self = nil; - } - } - return self; -} - -- (void)dealloc { - if (nil != function_) { - CGFunctionRelease(function_); - } - if (nil != colorSpace_) { - CGColorSpaceRelease(colorSpace_); - } - [super dealloc]; -} - - -- (void)insertStop:(id)item atPosition:(CGFloat)position { - NSString *colorSpaceName = isCalibrated_ ? NSCalibratedRGBColorSpace : NSDeviceRGBColorSpace; - NSColor *tempColor = [item colorUsingColorSpaceName: colorSpaceName]; - if (nil != tempColor) { - [super insertStop:tempColor atPosition:position]; - } -} - -// Calculate a linear value based on our stops -- (id)valueAtPosition:(CGFloat)position { - NSUInteger positionIndex = 0; - NSUInteger colorCount = [self stopCount]; - CGFloat stop1Position = 0.0; - NSColor *stop1Color = [self stopAtIndex:positionIndex position:&stop1Position]; - positionIndex += 1; - CGFloat stop2Position = 0.0; - NSColor *stop2Color = nil; - if (colorCount > 1) { - stop2Color = [self stopAtIndex:positionIndex position:&stop2Position]; - positionIndex += 1; - } else { - // if we only have one value, that's what we return - stop2Position = stop1Position; - stop2Color = stop1Color; - } - - while (positionIndex < colorCount && stop2Position < position) { - stop1Color = stop2Color; - stop1Position = stop2Position; - stop2Color = [self stopAtIndex:positionIndex position:&stop2Position]; - positionIndex += 1; - } - - if (position <= stop1Position) { - // if we are less than our lowest position, return our first color - [stop1Color getRed:&colorValue_[0] green:&colorValue_[1] - blue:&colorValue_[2] alpha:&colorValue_[3]]; - } else if (position >= stop2Position) { - // likewise if we are greater than our highest position, return the last color - [stop2Color getRed:&colorValue_[0] green:&colorValue_[1] - blue:&colorValue_[2] alpha:&colorValue_[3]]; - } else { - // otherwise interpolate between the two - position = (position - stop1Position) / (stop2Position - stop1Position); - CGFloat red1, red2, green1, green2, blue1, blue2, alpha1, alpha2; - [stop1Color getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1]; - [stop2Color getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2]; - - colorValue_[0] = (red2 - red1) * position + red1; - colorValue_[1] = (green2 - green1) * position + green1; - colorValue_[2] = (blue2 - blue1) * position + blue1; - colorValue_[3] = (alpha2 - alpha1) * position + alpha1; - } - - // Yes, I am casting a CGFloat[] to an id to pass it by the compiler. This - // significantly improves performance though as I avoid creating an NSColor - // for every scanline which later has to be cleaned up in an autorelease pool - // somewhere. Causes guardmalloc to run significantly faster. - return (id)colorValue_; -} - -// -// switch from C to obj-C. The callback to a shader is a c function -// but we want to call our objective c object to do all the -// calculations for us. We have passed our function our -// GTMLinearRGBShading as an obj-c object in the |info| so -// we just turn around and ask it to calculate our value based -// on |inPos| and then stick the results back in |outVals| -// -// Args: -// info: is the GTMLinearRGBShading as an -// obj-C object. -// inPos: the position to calculate values for. This is a pointer to -// a single float value -// outVals: where we store our return values. Since we are calculating -// an RGBA color, this is a pointer to an array of four float values -// ranging from 0.0 to 1.0 -// -// -static void cShadeFunction(void *info, const CGFloat *inPos, CGFloat *outVals) { - id object = (id)info; - CGFloat *colorValue = (CGFloat*)[object valueAtPosition:*inPos]; - outVals[0] = colorValue[0]; - outVals[1] = colorValue[1]; - outVals[2] = colorValue[2]; - outVals[3] = colorValue[3]; -} - -- (CGFunctionRef) shadeFunction { - // lazily create the function as necessary - if (nil == function_) { - // We have to go to carbon here, and create the CGFunction. Note that this - // diposed if necessary in the dealloc call. - const CGFunctionCallbacks shadeFunctionCallbacks = { 0, &cShadeFunction, NULL }; - - // TODO: this code assumes that we have a range from 0.0 to 1.0 - // which may not be true according to the stops that the user has given us. - // In general you have stops at 0.0 and 1.0, so this will do for right now - // but may be an issue in the future. - const CGFloat inRange[2] = { 0.0, 1.0 }; - const CGFloat outRange[8] = { 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0 }; - function_ = CGFunctionCreate(self, - sizeof(inRange) / (sizeof(CGFloat) * 2), inRange, - sizeof(outRange) / (sizeof(CGFloat) * 2), outRange, - &shadeFunctionCallbacks); - } - return function_; -} - -- (CGColorSpaceRef)colorSpace { - // lazily create the colorspace as necessary - if (nil == colorSpace_) { - if (isCalibrated_) { - colorSpace_ = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - } else { - colorSpace_ = CGColorSpaceCreateDeviceRGB(); - } - } - return colorSpace_; -} -@end |