Permalink
Newer
Older
100644 149 lines (118 sloc) 4.03 KB
1
//
2
// Copyright 2003,2005-2006 Chris Thomas. All rights reserved.
3
//
4
// Permission to use, copy, modify, and distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
6
// copyright notice and this permission notice appear in all copies.
7
//
8
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
//
16
17
#import "CXShading.h"
18
#import <objc/objc-runtime.h>
19
20
@implementation CXShading
21
22
static void ShadingFunction (void * info,
23
const float * in,
24
float * out)
25
{
26
_CXShadingDelegateMethod * method = (_CXShadingDelegateMethod *) info;
27
28
objc_msgSend( method->target, method->selector, in, out );
29
// NSLog( @"%X:%g: %g,%g,%g,%g", method->target, *in, out[0], out[1], out[2], out[3] );
30
}
31
32
33
- (CGFunctionRef) shadingFunctionForColorspace:(CGColorSpaceRef) colorspace info:(void *)info
34
{
35
size_t components;
36
static const float inputValueRange [2] = { 0, 1 };
37
static const float outputValueRanges [8] = { 0, 1, 0, 1, 0, 1, 0, 1 };
38
static const CGFunctionCallbacks callbacks = { 0, &ShadingFunction, NULL };
39
40
components = 1 + CGColorSpaceGetNumberOfComponents (colorspace);
41
return CGFunctionCreate ( info,
42
1,
43
inputValueRange,
44
components,
45
outputValueRanges,
46
&callbacks);
47
}
48
49
50
// kludge
51
static inline CGPoint CGPointFromNSPoint( NSPoint point )
52
{
53
return *(CGPoint *)&point;
54
}
55
56
- (void) commonInit
57
{
58
fColorSpace = CGColorSpaceCreateDeviceRGB();
59
fFunction = [self shadingFunctionForColorspace:fColorSpace info:&fMethod];
60
61
fMethod.target = self;
62
fMethod.selector = @selector(linearInterpolationFunction:toColor:);
63
}
64
65
- (id)initWithStartingColor:(NSColor *)startColor endingColor:(NSColor *)endColor
66
{
67
// Get both colors as Device RGBA
68
startColor = [startColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
69
endColor = [endColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
70
71
[startColor getRed:&fColors.from[0]
72
green:&fColors.from[1]
73
blue:&fColors.from[2]
74
alpha:&fColors.from[3]];
75
76
[endColor getRed:&fColors.to[0]
77
green:&fColors.to[1]
78
blue:&fColors.to[2]
79
alpha:&fColors.to[3]];
80
81
[self commonInit];
82
83
return self;
84
}
85
86
- (void) dealloc
87
{
88
if(fFunction != NULL)
89
{
90
CGFunctionRelease(fFunction);
91
}
92
93
if(fColorSpace != NULL)
94
{
95
CGColorSpaceRelease(fColorSpace);
96
}
97
98
if(fShading != NULL)
99
{
100
CGShadingRelease(fShading);
101
}
102
103
[super dealloc];
104
}
105
106
#if 0
107
#pragma mark -
108
#pragma mark Simple linear gradient
109
#endif
110
111
static inline float LinearInterpolate(float from, float to, float alpha)
112
{
113
return (((1.0f - alpha) * from) + (alpha * to));
114
}
115
116
- (void) linearInterpolationFunction:(const float *)alpha toColor:(float *)color
117
{
118
float a = *alpha;
119
120
color[0] = LinearInterpolate( fColors.from[0], fColors.to[0], a );
121
color[1] = LinearInterpolate( fColors.from[1], fColors.to[1], a );
122
color[2] = LinearInterpolate( fColors.from[2], fColors.to[2], a );
123
color[3] = LinearInterpolate( fColors.from[3], fColors.to[3], a );
124
}
125
126
#if 0
127
#pragma mark -
128
#pragma mark Drawing
129
#endif
130
131
- (void)drawFromPoint:(NSPoint)fromPoint toPoint:(NSPoint)toPoint
132
{
133
if(fShading != NULL)
134
{
135
CGShadingRelease(fShading);
136
}
137
138
fShading = CGShadingCreateAxial(fColorSpace, CGPointFromNSPoint(fromPoint), CGPointFromNSPoint(toPoint), fFunction, true, true);
139
if( fShading == NULL )
140
{
141
[NSException raise:@"EvilCGShading" format:@"Cannot allocate CGShading!"];
142
}
143
144
CGContextDrawShading( [[NSGraphicsContext currentContext] graphicsPort], fShading );
145
}
146
147
148
@end