You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.1 KiB
150 lines
4.1 KiB
/** |
|
Copyright (c) 2014-present, Facebook, Inc. |
|
All rights reserved. |
|
|
|
This source code is licensed under the BSD-style license found in the |
|
LICENSE file in the root directory of this source tree. An additional grant |
|
of patent rights can be found in the PATENTS file in the same directory. |
|
*/ |
|
|
|
#import "POPCGUtils.h" |
|
|
|
#import <objc/runtime.h> |
|
|
|
void POPCGColorGetRGBAComponents(CGColorRef color, CGFloat components[]) |
|
{ |
|
if (color) { |
|
const CGFloat *colors = CGColorGetComponents(color); |
|
size_t count = CGColorGetNumberOfComponents(color); |
|
|
|
if (4 == count) { |
|
// RGB colorspace |
|
components[0] = colors[0]; |
|
components[1] = colors[1]; |
|
components[2] = colors[2]; |
|
components[3] = colors[3]; |
|
} else if (2 == count) { |
|
// Grey colorspace |
|
components[0] = components[1] = components[2] = colors[0]; |
|
components[3] = colors[1]; |
|
} else { |
|
// Use CI to convert |
|
CIColor *ciColor = [CIColor colorWithCGColor:color]; |
|
components[0] = ciColor.red; |
|
components[1] = ciColor.green; |
|
components[2] = ciColor.blue; |
|
components[3] = ciColor.alpha; |
|
} |
|
} else { |
|
memset(components, 0, 4 * sizeof(components[0])); |
|
} |
|
} |
|
|
|
CGColorRef POPCGColorRGBACreate(const CGFloat components[]) |
|
{ |
|
#if TARGET_OS_IPHONE |
|
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); |
|
CGColorRef color = CGColorCreate(space, components); |
|
CGColorSpaceRelease(space); |
|
return color; |
|
#else |
|
return CGColorCreateGenericRGB(components[0], components[1], components[2], components[3]); |
|
#endif |
|
} |
|
|
|
CGColorRef POPCGColorWithColor(id color) |
|
{ |
|
if (CFGetTypeID((__bridge CFTypeRef)color) == CGColorGetTypeID()) { |
|
return ((__bridge CGColorRef)color); |
|
} |
|
#if TARGET_OS_IPHONE |
|
else if ([color isKindOfClass:[UIColor class]]) { |
|
return [color CGColor]; |
|
} |
|
#else |
|
else if ([color isKindOfClass:[NSColor class]]) { |
|
// -[NSColor CGColor] is only supported since OSX 10.8+ |
|
if ([color respondsToSelector:@selector(CGColor)]) { |
|
return [color CGColor]; |
|
} |
|
|
|
/* |
|
* Otherwise create a CGColorRef manually. |
|
* |
|
* The original accessor is (or would be) declared as: |
|
* @property(readonly) CGColorRef CGColor; |
|
* - (CGColorRef)CGColor NS_RETURNS_INNER_POINTER CF_RETURNS_NOT_RETAINED; |
|
* |
|
* (Please note that OSX' accessor is atomic, while iOS' isn't.) |
|
* |
|
* The access to the NSColor object must thus be synchronized |
|
* and the CGColorRef be stored as an associated object, |
|
* to return a reference which doesn't need to be released manually. |
|
*/ |
|
@synchronized(color) { |
|
static const void* key = &key; |
|
|
|
CGColorRef colorRef = (__bridge CGColorRef)objc_getAssociatedObject(color, key); |
|
|
|
if (!colorRef) { |
|
size_t numberOfComponents = [color numberOfComponents]; |
|
CGFloat components[numberOfComponents]; |
|
CGColorSpaceRef colorSpace = [[color colorSpace] CGColorSpace]; |
|
|
|
[color getComponents:components]; |
|
|
|
colorRef = CGColorCreate(colorSpace, components); |
|
|
|
objc_setAssociatedObject(color, key, (__bridge id)colorRef, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
|
CGColorRelease(colorRef); |
|
} |
|
|
|
return colorRef; |
|
} |
|
} |
|
#endif |
|
return nil; |
|
} |
|
|
|
#if TARGET_OS_IPHONE |
|
|
|
void POPUIColorGetRGBAComponents(UIColor *color, CGFloat components[]) |
|
{ |
|
return POPCGColorGetRGBAComponents(POPCGColorWithColor(color), components); |
|
} |
|
|
|
UIColor *POPUIColorRGBACreate(const CGFloat components[]) |
|
{ |
|
CGColorRef colorRef = POPCGColorRGBACreate(components); |
|
UIColor *color = [[UIColor alloc] initWithCGColor:colorRef]; |
|
CGColorRelease(colorRef); |
|
return color; |
|
} |
|
|
|
#else |
|
|
|
void POPNSColorGetRGBAComponents(NSColor *color, CGFloat components[]) |
|
{ |
|
return POPCGColorGetRGBAComponents(POPCGColorWithColor(color), components); |
|
} |
|
|
|
NSColor *POPNSColorRGBACreate(const CGFloat components[]) |
|
{ |
|
CGColorRef colorRef = POPCGColorRGBACreate(components); |
|
NSColor *color = nil; |
|
|
|
if (colorRef) { |
|
if ([NSColor respondsToSelector:@selector(colorWithCGColor:)]) { |
|
color = [NSColor colorWithCGColor:colorRef]; |
|
} else { |
|
color = [NSColor colorWithCIColor:[CIColor colorWithCGColor:colorRef]]; |
|
} |
|
|
|
CGColorRelease(colorRef); |
|
} |
|
|
|
return color; |
|
} |
|
|
|
#endif |
|
|
|
|