From e1bcf5d6a4b813a63d42e6ccb37ca8054775d65b Mon Sep 17 00:00:00 2001 From: "thomasvl@gmail.com" Date: Thu, 5 Mar 2009 22:03:40 +0000 Subject: - Added GTMLuminance for working with colors in HSL space easily. - Added GTMTheme for doing product wide theme modifications. --- AppKit/GTMNSColor+Luminance.m | 153 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 AppKit/GTMNSColor+Luminance.m (limited to 'AppKit/GTMNSColor+Luminance.m') diff --git a/AppKit/GTMNSColor+Luminance.m b/AppKit/GTMNSColor+Luminance.m new file mode 100644 index 0000000..5b10dbe --- /dev/null +++ b/AppKit/GTMNSColor+Luminance.m @@ -0,0 +1,153 @@ +// +// GTMNSColor+Luminance.m +// +// Copyright 2009 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. +// + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + +#import "GTMNSColor+Luminance.h" + +static const CGFloat kGTMLuminanceDarkCutoff = 0.6; + +@implementation NSColorSpace (GTMNSColorSpaceLuminanceHelpers) + +// TODO(alcor): we may want to keep one of these around for performance reasons ++ (NSColorSpace *)gtm_labColorSpace { + // Observer= 2°, Illuminant= D65 + // TODO(alcor): these should come from ColorSync + CGFloat whitePoint[3] = {0.95047, 1.0, 1.08883}; + CGFloat blackPoint[3] = {0, 0, 0}; + CGFloat range[4] = {-127, 127, -127, 127}; + CGColorSpaceRef cs = CGColorSpaceCreateLab(whitePoint, blackPoint, range); + NSColorSpace *space = nil; + if (cs) { + space = [[[NSColorSpace alloc] initWithCGColorSpace:cs] autorelease]; + CGColorSpaceRelease(cs); + } + return space; +} +@end + +@implementation NSColor (GTMLuminance) + +- (NSColor *)labColor { + return [self colorUsingColorSpace:[NSColorSpace gtm_labColorSpace]]; +} + +- (CGFloat)gtm_luminance { + CGFloat lab[4]; + lab[0] = 0.0; + [[self labColor] getComponents:lab]; + return lab[0] / 100.0; +} + +- (NSColor *)gtm_colorByAdjustingLuminance:(CGFloat)luminance + saturation:(CGFloat)saturation { + CGFloat lab[4]; + [[self labColor] getComponents:lab]; + lab[0] *= 1.0 + luminance; + // If luminance is greater than 100, we desaturate it so that we don't get + // wild colors coming out of the forumula + if (lab[0] > 100) { + CGFloat clipping = lab[0] - 100; + CGFloat desaturation = (50.0 - clipping) / 50.0; + saturation = MIN(saturation, desaturation); + } + lab[1] *= saturation; + lab[2] *= saturation; + return [NSColor colorWithColorSpace:[NSColorSpace gtm_labColorSpace] + components:lab + count:sizeof(lab) / sizeof(lab[0])]; +} + +- (NSColor *)gtm_colorByAdjustingLuminance:(CGFloat)luminance { + return [self gtm_colorByAdjustingLuminance:luminance saturation:1.0]; +} + +// TODO(alcor): these constants are largely made up, come up with a consistent +// set of values or at least guidelines +- (NSColor *)gtm_colorAdjustedFor:(GTMColorationUse)use { + NSColor *color = nil; + switch (use) { + case GTMColorationBaseHighlight: + color = [self gtm_colorByAdjustingLuminance:0.15]; + break; + case GTMColorationBaseMidtone: + color = self; + break; + case GTMColorationBaseShadow: + color = [self gtm_colorByAdjustingLuminance:-0.15]; + break; + case GTMColorationBasePenumbra: + color = [self gtm_colorByAdjustingLuminance:-0.10]; + break; + case GTMColorationLightHighlight: + color = [self gtm_colorByAdjustingLuminance:0.25]; + color = [color blendedColorWithFraction:0.9 ofColor:[NSColor whiteColor]]; + break; + case GTMColorationLightMidtone: + color = [self blendedColorWithFraction:0.8 ofColor:[NSColor whiteColor]]; + break; + case GTMColorationLightShadow: + color = [self blendedColorWithFraction:0.7 ofColor:[NSColor whiteColor]]; + color = [color gtm_colorByAdjustingLuminance:-0.02]; + break; + case GTMColorationLightPenumbra: + color = [self blendedColorWithFraction:0.8 ofColor:[NSColor whiteColor]]; + color = [color gtm_colorByAdjustingLuminance:-0.01]; + break; + case GTMColorationDarkHighlight: + color = [self gtm_colorByAdjustingLuminance:-0.20]; + break; + case GTMColorationDarkMidtone: + color = [self gtm_colorByAdjustingLuminance:-0.25]; + break; + case GTMColorationDarkShadow: + color = [self gtm_colorByAdjustingLuminance:-0.30 saturation:1.4]; + break; + case GTMColorationDarkPenumbra: + color = [self gtm_colorByAdjustingLuminance:-0.25]; + break; + default: + _GTMDevLog(@"Invalid Coloration Use %d", use); + color = self; + break; + } + return color; +} +const CGFloat kDefaultFade = 0.3; + +- (NSColor *)gtm_colorAdjustedFor:(GTMColorationUse)use faded:(BOOL)fade { + NSColor *color = [self gtm_colorAdjustedFor:use]; + if (fade) { + CGFloat luminance = [color gtm_luminance]; + color = [color gtm_colorByAdjustingLuminance: + kDefaultFade * (1.0 - luminance) + saturation:kDefaultFade]; + } + return color; +} + +- (BOOL)gtm_isDarkColor { + return [self gtm_luminance] < kGTMLuminanceDarkCutoff; +} + +- (NSColor *)gtm_legibleTextColor { + return [self gtm_isDarkColor] ? [NSColor whiteColor] : [NSColor blackColor]; +} + +@end +#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 -- cgit v1.2.3