Skip to content

Instantly share code, notes, and snippets.

@CodaFi
Last active June 16, 2021 22:31
Show Gist options
  • Save CodaFi/6656394 to your computer and use it in GitHub Desktop.
Save CodaFi/6656394 to your computer and use it in GitHub Desktop.
Redoing NSColor for no reason whatsoever.
//
// 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
//
// 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