PageRenderTime 46ms CodeModel.GetById 14ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/google-toolbox-for-mac/AppKit/GTMNSColor+Luminance.m

http://macfuse.googlecode.com/
Objective C | 155 lines | 115 code | 16 blank | 24 comment | 4 complexity | 5026023d77b1afbf597f9f690ef05107 MD5 | raw file
  1//
  2//  GTMNSColor+Luminance.m
  3//
  4//  Copyright 2009 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9// 
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11// 
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18
 19#import "GTMDefines.h"
 20
 21#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
 22
 23#import "GTMNSColor+Luminance.h"
 24
 25static const CGFloat kGTMLuminanceDarkCutoff = 0.6;
 26
 27@implementation NSColorSpace (GTMNSColorSpaceLuminanceHelpers)
 28
 29// TODO(alcor): we may want to keep one of these around for performance reasons
 30+ (NSColorSpace *)gtm_labColorSpace {
 31  // Observer= 2?, Illuminant= D65
 32  // TODO(alcor): these should come from ColorSync
 33  CGFloat whitePoint[3] = {0.95047, 1.0, 1.08883};
 34  CGFloat blackPoint[3] = {0, 0, 0};
 35  CGFloat range[4] = {-127, 127, -127, 127};
 36  CGColorSpaceRef cs = CGColorSpaceCreateLab(whitePoint, blackPoint, range);
 37  NSColorSpace *space = nil;
 38  if (cs) {
 39    space = [[[NSColorSpace alloc] initWithCGColorSpace:cs] autorelease];
 40    CGColorSpaceRelease(cs);
 41  }
 42  return space;
 43}
 44@end
 45
 46@implementation NSColor (GTMLuminance)
 47
 48- (NSColor *)labColor {
 49  return [self colorUsingColorSpace:[NSColorSpace gtm_labColorSpace]];    
 50}
 51
 52- (CGFloat)gtm_luminance {
 53  CGFloat lab[4];
 54  lab[0] = 0.0;
 55  [[self labColor] getComponents:lab];
 56  return lab[0] / 100.0;
 57}
 58
 59- (NSColor *)gtm_colorByAdjustingLuminance:(CGFloat)luminance
 60                                saturation:(CGFloat)saturation {
 61  CGFloat lab[4];
 62  [[self labColor] getComponents:lab];
 63  lab[0] *= 1.0 + luminance;
 64  // If luminance is greater than 100, we desaturate it so that we don't get
 65  // wild colors coming out of the forumula
 66  if (lab[0] > 100) {
 67    CGFloat clipping = lab[0] - 100;
 68    CGFloat desaturation = (50.0 - clipping) / 50.0;
 69    saturation = MIN(saturation, desaturation);
 70  } 
 71  lab[1] *= saturation;
 72  lab[2] *= saturation;
 73  return [NSColor colorWithColorSpace:[NSColorSpace gtm_labColorSpace]
 74                           components:lab
 75                                count:sizeof(lab) / sizeof(lab[0])];
 76}
 77
 78- (NSColor *)gtm_colorByAdjustingLuminance:(CGFloat)luminance {
 79  return [self gtm_colorByAdjustingLuminance:luminance saturation:1.0];
 80}
 81
 82// TODO(alcor): these constants are largely made up, come up with a consistent
 83// set of values or at least guidelines
 84- (NSColor *)gtm_colorAdjustedFor:(GTMColorationUse)use {
 85  NSColor *color = nil;
 86  switch (use) {
 87    case GTMColorationBaseHighlight:
 88      color = [self gtm_colorByAdjustingLuminance:0.15];
 89      break;
 90    case GTMColorationBaseMidtone:
 91      color = self;
 92      break;
 93    case GTMColorationBaseShadow:
 94      color = [self gtm_colorByAdjustingLuminance:-0.15];
 95      break;
 96    case GTMColorationBasePenumbra:
 97      color = [self gtm_colorByAdjustingLuminance:-0.10];
 98      break;
 99    case GTMColorationLightHighlight:
100      color = [self gtm_colorByAdjustingLuminance:0.25];
101      color = [color blendedColorWithFraction:0.9 ofColor:[NSColor whiteColor]];
102      break;
103    case GTMColorationLightMidtone:
104      color = [self blendedColorWithFraction:0.8 ofColor:[NSColor whiteColor]];
105      break;
106    case GTMColorationLightShadow:
107      color = [self blendedColorWithFraction:0.7 ofColor:[NSColor whiteColor]];
108      color = [color gtm_colorByAdjustingLuminance:-0.02];
109      break;
110    case GTMColorationLightPenumbra:
111      color = [self blendedColorWithFraction:0.8 ofColor:[NSColor whiteColor]];
112      color = [color gtm_colorByAdjustingLuminance:-0.01];
113      break;
114    case GTMColorationDarkHighlight:
115      color = [self gtm_colorByAdjustingLuminance:-0.20];
116      break;
117    case GTMColorationDarkMidtone:
118      color = [self gtm_colorByAdjustingLuminance:-0.25];
119      break;
120    case GTMColorationDarkShadow:
121      color = [self gtm_colorByAdjustingLuminance:-0.30 saturation:1.4];
122      break;
123    case GTMColorationDarkPenumbra:
124      color = [self gtm_colorByAdjustingLuminance:-0.25];
125      break;
126    default:
127      _GTMDevLog(@"Invalid Coloration Use %lu", (unsigned long)use);
128      color = self;
129      break;
130  }
131  return color;
132}
133const CGFloat kDefaultFade = 0.3;
134
135- (NSColor *)gtm_colorAdjustedFor:(GTMColorationUse)use faded:(BOOL)fade {
136  NSColor *color = [self gtm_colorAdjustedFor:use];
137  if (fade) {
138    CGFloat luminance = [color gtm_luminance];
139    color = [color gtm_colorByAdjustingLuminance:
140               kDefaultFade * (1.0 - luminance) 
141                                      saturation:kDefaultFade];
142  }
143  return color;
144}
145
146- (BOOL)gtm_isDarkColor {
147  return [self gtm_luminance] < kGTMLuminanceDarkCutoff;
148}
149
150- (NSColor *)gtm_legibleTextColor {
151  return [self gtm_isDarkColor] ? [NSColor whiteColor] : [NSColor blackColor];
152}
153
154@end
155#endif // MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5