Last active
June 16, 2021 22:31
-
-
Save CodaFi/6656394 to your computer and use it in GitHub Desktop.
Redoing NSColor for no reason whatsoever.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NUIColor.h | |
// NUIKit | |
// | |
// Created by Robert Widmann on 9/21/13. | |
// Copyright (c) 2013 CodaFi. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
#import <CoreGraphics/CoreGraphics.h> | |
#import <QuartzCore/CoreImage.h> | |
#import <NUIKit/NUIKitDefines.h> | |
/** | |
* An NUIColor object represents color and sometimes opacity. They are used to store color data and | |
* have conveiences built in to set drawing and stroke colors. | |
* | |
* Colors and immutable and thread-safe. | |
*/ | |
@interface NUIColor : NSObject <NSSecureCoding, NSCopying> { | |
@private | |
} | |
#pragma mark - Convenience Initializers | |
/** | |
* Creates and returns a color object using the specified opacity and grayscale values. | |
*/ | |
+ (NUIColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha; | |
/** | |
* Creates and returns a color object using the specified opacity and HSB color space component | |
* values. | |
*/ | |
+ (NUIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha; | |
/** | |
* Creates and returns a color object using the specified opacity and RGB component values. | |
*/ | |
+ (NUIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; | |
/** | |
* Creates and returns a color object using the specified Quartz color reference. | |
*/ | |
+ (NUIColor *)colorWithCGColor:(CGColorRef)cgColor; | |
/** | |
* Converts a Core Image color object to its NUIColor equivalent | |
*/ | |
+ (NUIColor *)colorWithCIColor:(CIColor *)ciColor; | |
#pragma mark - Initializers | |
/** | |
* Initializes and returns a color object using the specified opacity and grayscale values. | |
*/ | |
- (NUIColor *)initWithWhite:(CGFloat)white alpha:(CGFloat)alpha; | |
/** | |
* Initializes and returns a color object using the specified opacity and HSB color space component | |
* values. | |
*/ | |
- (NUIColor *)initWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha; | |
/** | |
* Initializes and returns a color object using the specified opacity and RGB component values. | |
*/ | |
- (NUIColor *)initWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; | |
/** | |
* Initializes and returns a color object using the specified Quartz color reference. | |
*/ | |
- (NUIColor *)initWithCGColor:(CGColorRef)cgColor; | |
/** | |
* Initializes and returns a color object using the specified Core Image color. | |
*/ | |
- (NUIColor *)initWithCIColor:(CIColor *)ciColor; | |
#pragma mark - Cached Color Convenience Initializers | |
/** | |
* Returns a color object whose grayscale value is 0.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)blackColor; | |
/** | |
* Returns a color object whose grayscale value is 1/3 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)darkGrayColor; | |
/** | |
* Returns a color object whose grayscale value is 2/3 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)lightGrayColor; | |
/** | |
* Returns a color object whose grayscale value is 1.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)whiteColor; | |
/** | |
* Returns a color object whose grayscale value is 0.5 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)grayColor; | |
/** | |
* Returns a color object whose RGB values are 1.0, 0.0, and 0.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)redColor; | |
/** | |
* Returns a color object whose RGB values are 0.0, 1.0, and 0.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)greenColor; | |
/** | |
* Returns a color object whose RGB values are 0.0, 0.0, and 1.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)blueColor; | |
/** | |
* Returns a color object whose grayscale value is 0.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)cyanColor; | |
/** | |
* Returns a color object whose RGB values are 1.0, 1.0, and 0.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)yellowColor; | |
/** | |
* Returns a color object whose RGB values are 1.0, 0.0, and 1.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)magentaColor; | |
/** | |
* Returns a color object whose RGB values are 1.0, 0.5, and 0.0 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)orangeColor; | |
/** | |
* Returns a color object whose RGB values are 0.5, 0.0, and 0.5 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)purpleColor; | |
/** | |
* Returns a color object whose RGB values are 0.6, 0.4, and 0.2 and whose alpha value is 1.0. | |
*/ | |
+ (NUIColor *)brownColor; | |
/** | |
* Returns a color object whose grayscale and alpha values are both 0.0. | |
*/ | |
+ (NUIColor *)clearColor; | |
#pragma mark - Drawing Operations | |
/** | |
* Sets the color of subsequent stroke and fill operations to the color that the receiver | |
* represents. | |
*/ | |
- (void)set; | |
/** | |
* Sets the color of subsequent fill operations to the color that the receiver represents. | |
*/ | |
- (void)setFill; | |
/** | |
* Sets the color of subsequent stroke operations to the color that the receiver represents. | |
*/ | |
- (void)setStroke; | |
#pragma mark - Color Information | |
/** | |
* Returns the grayscale components of the color. | |
*/ | |
- (BOOL)getWhite:(CGFloat *)white alpha:(CGFloat *)alpha; | |
/** | |
* Returns the components that make up the color in the HSB color space. | |
*/ | |
- (BOOL)getHue:(CGFloat *)hue saturation:(CGFloat *)saturation brightness:(CGFloat *)brightness alpha:(CGFloat *)alpha; | |
/** | |
* Returns the components that make up the color in the RGB color space. | |
*/ | |
- (BOOL)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha; | |
/** | |
* Returns a color in the same color space as the receiver with the specified alpha component. | |
*/ | |
- (NUIColor *)colorWithAlphaComponent:(CGFloat)alpha; | |
/// Access the underlying CGColor or CIColor. | |
@property(nonatomic,readonly) CGColorRef CGColor; | |
- (CGColorRef)CGColor NS_RETURNS_INNER_POINTER; | |
@property(nonatomic,readonly) CIColor *CIColor; | |
@end | |
@interface CIColor(UIKitAdditions) | |
- (id)initWithColor:(NUIColor *)color; | |
@end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NUIColor.m | |
// NUIKit | |
// | |
// Created by Robert Widmann on 9/21/13. | |
// Copyright (c) 2013 CodaFi. All rights reserved. | |
// | |
#import "NUIColor.h" | |
#import "NUIGraphics.h" | |
@interface NUIDeviceWhiteColor : NUIColor { | |
CGFloat alphaComponent; | |
CGColorRef cachedColor; | |
long cachedColorOnceToken; | |
CGFloat whiteComponent; | |
} | |
- (id)initWithWhite:(CGFloat)white alpha:(CGFloat)alpha; | |
- (id)initWithCGColor:(CGColorRef)color; | |
- (CGColorRef)CGColor; | |
- (CGColorRef)_createCGColorWithAlpha:(CGFloat)alpha; | |
- (CGFloat)alphaComponent; | |
@end | |
@implementation NUIDeviceWhiteColor | |
#pragma mark - Lifecycle | |
- (id)initWithWhite:(CGFloat)white alpha:(CGFloat)alpha { | |
self = [super init]; | |
alphaComponent = alpha; | |
whiteComponent = white; | |
return self; | |
} | |
- (id)initWithCGColor:(CGColorRef)color { | |
self = [super init]; | |
cachedColor = CGColorRetain(color); | |
whiteComponent = CGColorGetAlpha(color); | |
alphaComponent = CGColorGetComponents(color)[3]; | |
return self; | |
} | |
- (void)dealloc { | |
if (cachedColor != NULL) { | |
CGColorRelease(cachedColor); | |
} | |
NUI_SAFE_DEALLOC; | |
} | |
#pragma mark - NSCopying | |
- (id)copyWithZone:(NSZone *)zone { | |
return NUI_SAFE_RETAIN(self); | |
} | |
#pragma mark - NSObject | |
- (NSUInteger)hash { | |
return (NSUInteger)alphaComponent ^ (NSUInteger)whiteComponent; | |
} | |
- (BOOL)isEqual:(id)otherColor { | |
if (self == otherColor) return YES; | |
if (![otherColor isKindOfClass:NUIColor.class]) { | |
return NO; | |
} | |
return [otherColor hash] == self.hash; | |
} | |
- (NSString *)description { | |
return [NSString stringWithFormat:@"NUIDeviceWhiteColorSpace %g %g", whiteComponent, alphaComponent]; | |
} | |
#pragma mark - Getters | |
- (CGColorRef)CGColor { | |
if (cachedColor == NULL) { | |
CGColorRef color = [self _createCGColorWithAlpha:alphaComponent]; | |
if (color != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, color, (void * volatile *)&cachedColor); | |
if (!result) { | |
CGColorRelease(color); | |
} | |
} | |
} | |
return cachedColor; | |
} | |
- (CGFloat)alphaComponent { | |
return alphaComponent; | |
} | |
- (BOOL)getWhite:(CGFloat *)whitePtr alpha:(CGFloat *)alphaPtr { | |
if (whitePtr) { | |
*whitePtr = whiteComponent; | |
} | |
if (alphaPtr) { | |
*alphaPtr = alphaComponent; | |
} | |
return YES; | |
} | |
#pragma mark - NUIColor | |
- (id)colorWithAlphaComponent:(CGFloat)alpha { | |
return [[NUIDeviceWhiteColor alloc] initWithWhite:whiteComponent alpha:alpha]; | |
} | |
- (void)set { | |
CGContextRef context = NUIGraphicsGetCurrentContext(); | |
CGColorRef color = self.CGColor; | |
CGContextSetFillColorWithColor(context, color); | |
CGContextSetStrokeColorWithColor(context, color); | |
} | |
- (void)setFill { | |
CGContextRef context = NUIGraphicsGetCurrentContext(); | |
CGColorRef color = self.CGColor; | |
CGContextSetFillColorWithColor(context, color); | |
} | |
- (void)setStroke { | |
CGContextRef context = NUIGraphicsGetCurrentContext(); | |
CGColorRef color = self.CGColor; | |
CGContextSetStrokeColorWithColor(context, color); | |
} | |
#pragma mark - Internal | |
- (CGColorRef)_createCGColorWithAlpha:(CGFloat)alpha { | |
CGFloat components[2]; | |
components[0] = whiteComponent; | |
components[1] = alpha; | |
static CGColorSpaceRef grayColorSpaceRef; | |
if (!grayColorSpaceRef) { | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); | |
if (colorSpace != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, colorSpace, (void * volatile *)&grayColorSpaceRef); | |
if (!result) { | |
CGColorSpaceRelease(colorSpace); | |
} | |
} | |
} | |
return CGColorCreate(grayColorSpaceRef, components); | |
} | |
@end | |
@interface NUICachedDeviceWhiteColor : NUIDeviceWhiteColor | |
- (void)flushInstance; | |
@end | |
@implementation NUICachedDeviceWhiteColor | |
- (oneway void)release {} | |
- (id)retain { | |
return self; | |
} | |
- (NSUInteger)retainCount { | |
return NSUIntegerMax; | |
} | |
- (id)autorelease { | |
return self; | |
} | |
- (id)copyWithZone:(NSZone *)zone { | |
return self; | |
} | |
#pragma clang diagnostic push | |
#pragma clang diagnostic ignored "-Wall" | |
- (void)dealloc {} | |
#pragma clang diagnostic pop | |
- (void)flushInstance { | |
NUI_SAFE_DEALLOC; | |
} | |
@end | |
@interface NUIDeviceRGBColor : NUIColor { | |
CGFloat alphaComponent; | |
CGFloat blueComponent; | |
CGColorRef cachedColor; | |
long cachedColorOnceToken; | |
CGFloat greenComponent; | |
CGFloat redComponent; | |
} | |
- (id)initWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha; | |
- (id)initWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; | |
- (id)initWithCGColor:(CGColorRef)cgColor; | |
- (CGColorRef)_createCGColorWithAlpha:(CGFloat)alpha; | |
- (CGFloat)alphaComponent; | |
@end | |
@implementation NUIDeviceRGBColor | |
#pragma mark - Lifecycle | |
- (id)initWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha { | |
CGFloat r, g, b, f, p, q, t; | |
int i; | |
i = floor(hue * 6); | |
f = hue * 6 - i; | |
p = brightness * (1 - saturation); | |
q = brightness * (1 - f * saturation); | |
t = brightness * (1 - (1 - f) * saturation); | |
switch (i % 6) { | |
case 0: | |
r = brightness, g = t, b = p; | |
break; | |
case 1: | |
r = q, g = brightness, b = p; | |
break; | |
case 2: | |
r = p, g = brightness, b = t; | |
break; | |
case 3: | |
r = p, g = q, b = brightness; | |
break; | |
case 4: | |
r = t, g = p, b = brightness; | |
break; | |
case 5: | |
r = brightness, g = p, b = q; | |
break; | |
} | |
return [self initWithRed:r green:g blue:b alpha:alpha];; | |
} | |
- (id)initWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { | |
self = [super init]; | |
redComponent = red; | |
greenComponent = green; | |
blueComponent = blue; | |
alphaComponent = alpha; | |
return self; | |
} | |
- (id)initWithCGColor:(CGColorRef)color { | |
self = [super init]; | |
cachedColor = CGColorRetain(color); | |
const CGFloat *components = CGColorGetComponents(color); | |
redComponent = components[0]; | |
greenComponent = components[1]; | |
blueComponent = components[2]; | |
alphaComponent = components[3]; | |
return self; | |
} | |
- (void)dealloc { | |
if (cachedColor != NULL) { | |
CGColorRelease(cachedColor); | |
} | |
NUI_SAFE_DEALLOC; | |
} | |
#pragma mark - NSCopying | |
- (id)copyWithZone:(NSZone *)zone { | |
return NUI_SAFE_RETAIN(self); | |
} | |
#pragma mark - NSObject | |
- (NSUInteger)hash { | |
return (NSUInteger)redComponent ^ (NSUInteger)greenComponent ^ (NSUInteger)blueComponent ^ (NSUInteger)alphaComponent; | |
} | |
- (BOOL)isEqual:(id)otherColor { | |
if (self == otherColor) return YES; | |
if (![otherColor isKindOfClass:NUIColor.class]) { | |
return NO; | |
} | |
return [otherColor hash] == self.hash; | |
} | |
- (NSString *)description { | |
return [NSString stringWithFormat:@"NUIDeviceRGBColor %g %g %g %g", redComponent, greenComponent, blueComponent, alphaComponent]; | |
} | |
#pragma mark - Getters | |
- (CGColorRef)CGColor { | |
if (cachedColor == NULL) { | |
CGColorRef color = [self _createCGColorWithAlpha:alphaComponent]; | |
if (color != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, color, (void * volatile *)&cachedColor); | |
if (!result) { | |
CGColorRelease(color); | |
} | |
} | |
} | |
return cachedColor; | |
} | |
- (CGFloat)alphaComponent { | |
return alphaComponent; | |
} | |
- (BOOL)getRed:(CGFloat *)redPtr green:(CGFloat *)greenPtr blue:(CGFloat *)bluePtr alpha:(CGFloat *)alphaPtr { | |
if (redPtr) { | |
*redPtr = redComponent; | |
} | |
if (greenPtr) { | |
*greenPtr = greenComponent; | |
} | |
if (bluePtr) { | |
*bluePtr = blueComponent; | |
} | |
if (alphaPtr) { | |
*alphaPtr = alphaComponent; | |
} | |
return YES; | |
} | |
- (BOOL)getHue:(CGFloat *)huePtr saturation:(CGFloat *)saturationPtr brightness:(CGFloat *)brightnessPtr alpha:(CGFloat *)alphaPtr { | |
CGFloat h, s, v; | |
double min, max, delta; | |
min = (redComponent < greenComponent) ? redComponent : greenComponent; | |
min = (min < blueComponent) ? min : blueComponent; | |
max = (redComponent > greenComponent) ? redComponent : greenComponent; | |
max = (max > blueComponent) ? max : blueComponent; | |
v = max; | |
delta = max - min; | |
if(max > 0.0) { | |
s = (delta / max); | |
} else { | |
s = 0.0; | |
h = NAN; | |
return NO; | |
} | |
if(redComponent >= max) { | |
h = (greenComponent - blueComponent) / delta; // between yellow & magenta | |
} else { | |
if(greenComponent >= max) { | |
h = 2.0 + (blueComponent - redComponent) / delta; // between cyan & yellow | |
} else { | |
h = 4.0 + (redComponent - greenComponent) / delta; // between magenta & cyan | |
} | |
} | |
h *= 60.0; | |
if(h < 0.0 ) h += 360.0; | |
if (huePtr) { | |
*huePtr = h; | |
} | |
if (saturationPtr) { | |
*saturationPtr = s; | |
} | |
if (brightnessPtr) { | |
*brightnessPtr = v; | |
} | |
if (alphaPtr) { | |
*alphaPtr = alphaComponent; | |
} | |
return YES; | |
} | |
#pragma mark - NUIColor | |
- (BOOL)getWhite:(CGFloat *)whitePtr alpha:(CGFloat *)alphaPtr { | |
if (whitePtr) { | |
*whitePtr = (redComponent + greenComponent + blueComponent); | |
} | |
if (alphaPtr) { | |
*alphaPtr = alphaComponent; | |
} | |
return YES; | |
} | |
- (id)colorWithAlphaComponent:(CGFloat)alpha { | |
return [[NUIDeviceRGBColor alloc]initWithRed:redComponent green:greenComponent blue:blueComponent alpha:alpha]; | |
} | |
- (void)set { | |
CGContextRef context = NUIGraphicsGetCurrentContext(); | |
CGColorRef color = self.CGColor; | |
CGContextSetFillColorWithColor(context, color); | |
CGContextSetStrokeColorWithColor(context, color); | |
} | |
- (void)setFill { | |
CGContextRef context = NUIGraphicsGetCurrentContext(); | |
CGColorRef color = self.CGColor; | |
CGContextSetFillColorWithColor(context, color); | |
} | |
- (void)setStroke { | |
CGContextRef context = NUIGraphicsGetCurrentContext(); | |
CGColorRef color = self.CGColor; | |
CGContextSetStrokeColorWithColor(context, color); | |
} | |
#pragma mark - Internal | |
- (CGColorRef)_createCGColorWithAlpha:(CGFloat)alpha { | |
CGFloat components[4]; | |
components[0] = redComponent; | |
components[1] = greenComponent; | |
components[2] = blueComponent; | |
components[3] = alpha; | |
static CGColorSpaceRef rgbColorSpaceRef; | |
if (!rgbColorSpaceRef) { | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); | |
if (colorSpace != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, colorSpace, (void * volatile *)&rgbColorSpaceRef); | |
if (!result) { | |
CGColorSpaceRelease(colorSpace); | |
} | |
} | |
} | |
return CGColorCreate(rgbColorSpaceRef, components); | |
} | |
@end | |
@interface NUICachedDeviceRGBColor : NUIDeviceRGBColor | |
- (void)flushInstance; | |
@end | |
@implementation NUICachedDeviceRGBColor | |
- (oneway void)release {} | |
- (id)retain { | |
return self; | |
} | |
- (NSUInteger)retainCount { | |
return NSUIntegerMax; | |
} | |
- (id)autorelease { | |
return self; | |
} | |
- (id)copyWithZone:(NSZone *)zone { | |
return self; | |
} | |
#pragma clang diagnostic push | |
#pragma clang diagnostic ignored "-Wall" | |
- (void)dealloc {} | |
#pragma clang diagnostic pop | |
- (void)flushInstance { | |
NUI_SAFE_DEALLOC; | |
} | |
@end | |
@interface NUICIColor : NUIColor { | |
CIColor *_ciColor; | |
NUIColor *_rgbColor; | |
} | |
- (CIColor *)CIColor; | |
- (id)initWithCIColor:(CIColor *)color; | |
@end | |
@implementation NUICIColor | |
#pragma mark - Lifecycle | |
- (id)initWithCIColor:(CIColor *)color { | |
self = [super init]; | |
if (color == nil) { | |
return nil; | |
} | |
_ciColor = NUI_SAFE_RETAIN(color); | |
return self; | |
} | |
- (void)dealloc { | |
NUI_SAFE_RELEASE(_ciColor); | |
NUI_SAFE_DEALLOC; | |
} | |
#pragma mark - NSCopying | |
- (id)copyWithZone:(NSZone *)zone { | |
return NUI_SAFE_RETAIN(self); | |
} | |
#pragma mark - NSObject | |
- (NSString *)description { | |
return [NSString stringWithFormat:@"CIColorSpace %g %g %g %g", _ciColor.red,_ciColor.green,_ciColor.blue, _ciColor.alpha]; | |
} | |
- (NSUInteger)hash { | |
return _ciColor.hash; | |
} | |
- (BOOL)isEqual:(id)otherColor { | |
if (self == otherColor) return YES; | |
if (![otherColor isKindOfClass:NUIColor.class]) { | |
return NO; | |
} | |
return [otherColor CIColor] == self.CIColor; | |
} | |
#pragma mark - NUIColor | |
- (BOOL)getWhite:(CGFloat *)whitePtr alpha:(CGFloat *)alphaPtr { | |
if (whitePtr) { | |
*whitePtr = (_ciColor.red + _ciColor.green + _ciColor.blue); | |
} | |
if (alphaPtr) { | |
*alphaPtr = _ciColor.alpha; | |
} | |
return YES; | |
} | |
- (id)colorWithAlphaComponent:(CGFloat)alpha { | |
return [NUIDeviceRGBColor colorWithRed:_ciColor.red green:_ciColor.green blue:_ciColor.blue alpha:alpha]; | |
} | |
- (CGColorRef)CGColor { | |
return [self._rgbColor CGColor]; | |
} | |
- (BOOL)getRed:(CGFloat *)redPtr green:(CGFloat *)greenPtr blue:(CGFloat *)bluePtr alpha:(CGFloat *)alphaPtr { | |
if (redPtr) { | |
*redPtr = _ciColor.red; | |
} | |
if (greenPtr) { | |
*greenPtr = _ciColor.green; | |
} | |
if (bluePtr) { | |
*bluePtr = _ciColor.blue; | |
} | |
if (alphaPtr) { | |
*alphaPtr = _ciColor.alpha; | |
} | |
return YES; | |
} | |
- (void)set { | |
[self._rgbColor set]; | |
} | |
- (void)setFill { | |
[self._rgbColor setFill]; | |
} | |
- (void)setStroke { | |
[self._rgbColor setStroke]; | |
} | |
#pragma mark - Internal | |
- (CIColor *)CIColor { | |
return _ciColor; | |
} | |
- (NUIDeviceRGBColor *)_rgbColor { | |
static NUIDeviceRGBColor *rgbColor; | |
if (rgbColor == nil) { | |
rgbColor = [[NUIDeviceRGBColor alloc] initWithRed:_ciColor.red green:_ciColor.green blue:_ciColor.blue alpha:_ciColor.alpha]; | |
} | |
return rgbColor; | |
} | |
@end | |
@implementation NUIColor { | |
@package | |
NSString *systemColorName; | |
} | |
+ (NUIColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha { | |
return NUI_SAFE_AUTORELEASE([[NUIDeviceWhiteColor alloc] initWithWhite:white alpha:alpha]); | |
} | |
+ (NUIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha { | |
return NUI_SAFE_AUTORELEASE([[NUIDeviceRGBColor alloc] initWithHue:hue saturation:saturation brightness:brightness alpha:alpha]); | |
} | |
+ (NUIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { | |
return NUI_SAFE_AUTORELEASE([[NUIDeviceRGBColor alloc] initWithRed:red green:green blue:blue alpha:alpha]); | |
} | |
+ (NUIColor *)colorWithCGColor:(CGColorRef)cgColor { | |
if (cgColor != NULL) { | |
static CGColorSpaceRef rgbColorSpaceRef; | |
if (!rgbColorSpaceRef) { | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); | |
if (colorSpace != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, rgbColorSpaceRef, (void * volatile *)&colorSpace); | |
if (!result) { | |
CGColorSpaceRelease(colorSpace); | |
} | |
} | |
} | |
if (CGColorGetColorSpace(cgColor) != rgbColorSpaceRef) { | |
static CGColorSpaceRef grayColorSpaceRef; | |
if (!grayColorSpaceRef) { | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); | |
if (colorSpace != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, grayColorSpaceRef, (void * volatile *)&colorSpace); | |
if (!result) { | |
CGColorSpaceRelease(colorSpace); | |
} | |
} | |
} | |
return NUI_SAFE_AUTORELEASE([[NUIDeviceWhiteColor alloc] initWithCGColor:cgColor]); | |
} | |
return NUI_SAFE_AUTORELEASE([[NUIDeviceRGBColor alloc] initWithCGColor:cgColor]); | |
} | |
return nil; | |
} | |
+ (NUIColor *)colorWithCIColor:(CIColor *)ciColor { | |
return NUI_SAFE_AUTORELEASE([[NUIColor alloc] initWithCIColor:ciColor]); | |
} | |
- (NUIColor *)initWithWhite:(CGFloat)white alpha:(CGFloat)alpha { | |
return [[NUIDeviceWhiteColor alloc] initWithWhite:white alpha:alpha]; | |
} | |
- (NUIColor *)initWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha { | |
return [[NUIDeviceRGBColor alloc] initWithHue:hue saturation:saturation brightness:brightness alpha:alpha]; | |
} | |
- (NUIColor *)initWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { | |
return [[NUIDeviceRGBColor alloc] initWithRed:red green:green blue:blue alpha:alpha]; | |
} | |
- (NUIColor *)initWithCGColor:(CGColorRef)cgColor { | |
if (cgColor != NULL) { | |
static CGColorSpaceRef rgbColorSpaceRef; | |
if (!rgbColorSpaceRef) { | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); | |
if (colorSpace != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, rgbColorSpaceRef, (void * volatile *)&colorSpace); | |
if (!result) { | |
CGColorSpaceRelease(colorSpace); | |
} | |
} | |
} | |
if (CGColorGetColorSpace(cgColor) != rgbColorSpaceRef) { | |
static CGColorSpaceRef grayColorSpaceRef; | |
if (!grayColorSpaceRef) { | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); | |
if (colorSpace != NULL) { | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, grayColorSpaceRef, (void * volatile *)&colorSpace); | |
if (!result) { | |
CGColorSpaceRelease(colorSpace); | |
} | |
} | |
} | |
return [[NUIDeviceWhiteColor alloc] initWithCGColor:cgColor]; | |
} | |
return [[NUIDeviceRGBColor alloc] initWithCGColor:cgColor]; | |
} | |
return nil; | |
} | |
- (NUIColor *)initWithCIColor:(CIColor *)ciColor { | |
return [[NUICIColor alloc] initWithCIColor:ciColor]; | |
} | |
+ (NUIColor *)blackColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceWhiteColor *cachedColor = [[NUICachedDeviceWhiteColor alloc] initWithWhite:0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)darkGrayColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceWhiteColor *cachedColor = [[NUICachedDeviceWhiteColor alloc] initWithWhite:0.333 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)lightGrayColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceWhiteColor *cachedColor = [[NUICachedDeviceWhiteColor alloc] initWithWhite:0.667 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)whiteColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceWhiteColor *cachedColor = [[NUICachedDeviceWhiteColor alloc] initWithWhite:1.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)grayColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceWhiteColor *cachedColor = [[NUICachedDeviceWhiteColor alloc] initWithWhite:0.5 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)redColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:1.0 green:0.0 blue:0.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)greenColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:0.0 green:1.0 blue:0.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)blueColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:0.0 green:0.0 blue:1.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)cyanColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:0.0 green:1.0 blue:1.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)yellowColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:1.0 green:1.0 blue:0.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)magentaColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:1.0 green:0.0 blue:1.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)orangeColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:1.0 green:0.5 blue:0.0 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)purpleColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:0.5 green:0.0 blue:0.5 alpha:1.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)brownColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceRGBColor *cachedColor = [[NUICachedDeviceRGBColor alloc] initWithRed:0.6 green:0.4 blue:0.2 alpha:1.0]; | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
+ (NUIColor *)clearColor { | |
static NUIColor *c; | |
if (c == nil) { | |
NUICachedDeviceWhiteColor *cachedColor = [[NUICachedDeviceWhiteColor alloc] initWithWhite:0.0 alpha:0.0]; | |
cachedColor->systemColorName = NSStringFromSelector(_cmd); | |
bool result = OSAtomicCompareAndSwapPtrBarrier(NULL, cachedColor, (void * volatile *)&c); | |
if (!result) { | |
[cachedColor flushInstance]; | |
cachedColor = nil; | |
} | |
} | |
return c; | |
} | |
- (BOOL)getWhite:(CGFloat *)white alpha:(CGFloat *)alpha { | |
return NO; | |
} | |
- (BOOL)getHue:(CGFloat *)hue saturation:(CGFloat *)saturation brightness:(CGFloat *)brightness alpha:(CGFloat *)alpha { | |
return NO; | |
} | |
- (BOOL)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha { | |
return NO; | |
} | |
- (NUIColor *)colorWithAlphaComponent:(CGFloat)alpha { | |
return nil; | |
} | |
- (CGColorRef)CGColor { | |
return NULL; | |
} | |
- (CIColor *)CIColor { | |
return nil; | |
} | |
- (void)set {} | |
- (void)setFill {} | |
- (void)setStroke {} | |
#pragma mark - NSSecureCoding | |
+ (BOOL)supportsSecureCoding { | |
return YES; | |
} | |
- (id)initWithCoder:(NSCoder *)aDecoder { | |
NSString *sysColorName = [aDecoder decodeObjectForKey:@"NUISystemColorName"]; | |
SEL systemInitializer = NSSelectorFromString(sysColorName); | |
if (systemInitializer == NULL) { | |
int componentCount = [aDecoder decodeIntForKey:@"NUIColorComponentsCount"]; | |
if (componentCount == 2) { | |
return [NUIColor colorWithWhite:[aDecoder decodeIntForKey:@"NUIWhiteComponent"] alpha:[aDecoder decodeIntForKey:@"NUIAlphaComponent"]]; | |
} else if (componentCount == 4) { | |
CGFloat red = [aDecoder decodeFloatForKey:@"NUIRedComponent"]; | |
CGFloat green = [aDecoder decodeFloatForKey:@"NUIGreenComponent"]; | |
CGFloat blue = [aDecoder decodeFloatForKey:@"NUIBlueComponent"]; | |
CGFloat alpha = [aDecoder decodeFloatForKey:@"NUIAlphaComponent"]; | |
return [NUIColor colorWithRed:red green:green blue:blue alpha:alpha]; | |
} | |
return nil; | |
} | |
if ([self.class respondsToSelector:systemInitializer]) { | |
return [NUIColor.class performSelector:systemInitializer]; | |
} | |
return nil; | |
} | |
- (void)encodeWithCoder:(NSCoder *)aCoder { | |
[aCoder encodeObject:systemColorName forKey:@"NUISystemColorName"]; | |
[aCoder encodeInt:(int)CGColorGetNumberOfComponents(self.CGColor) forKey:@"NUIColorComponentsCount"]; | |
CGFloat red, green, blue, alpha; | |
[self getRed:&red green:&green blue:&blue alpha:&alpha]; | |
[aCoder encodeFloat:red forKey:@"NUIRedComponent"]; | |
[aCoder encodeFloat:green forKey:@"NUIGreenComponent"]; | |
[aCoder encodeFloat:blue forKey:@"NUIBlueComponent"]; | |
[aCoder encodeFloat:alpha forKey:@"NUIAlphaComponent"]; | |
} | |
#pragma mark - NSCopying | |
- (id)copyWithZone:(NSZone *)zone { | |
NSAssert(0, @"-copy is not implemented on abstract superclass NUIColor"); | |
return nil; | |
} | |
@end | |
@implementation CIColor(UIKitAdditions) | |
- (id)initWithColor:(NUIColor *)color { | |
return [CIColor colorWithCGColor:color.CGColor]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment