aboutsummaryrefslogtreecommitdiff
path: root/AppKit/GTMNSColor+Luminance.m
diff options
context:
space:
mode:
authorGravatar thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-05 22:03:40 +0000
committerGravatar thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-03-05 22:03:40 +0000
commite1bcf5d6a4b813a63d42e6ccb37ca8054775d65b (patch)
tree370ae297052052fb9576f0c14e0a9243f8a8bc86 /AppKit/GTMNSColor+Luminance.m
parentd4f38903d60f8b01c419f5056c2fb3cd4c6c6e60 (diff)
- Added GTMLuminance for working with colors in HSL space easily.
- Added GTMTheme for doing product wide theme modifications.
Diffstat (limited to 'AppKit/GTMNSColor+Luminance.m')
-rw-r--r--AppKit/GTMNSColor+Luminance.m153
1 files changed, 153 insertions, 0 deletions
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