Skip to content

Commit 8969ff8

Browse files
authored
Merge pull request #1558 from ychin/mmtabs-automatic-colors-tuning
Tabs: Tune automatic colors and use LAB for deriving colors
2 parents 8bac906 + 25b448f commit 8969ff8

File tree

1 file changed

+49
-27
lines changed

1 file changed

+49
-27
lines changed

src/MacVim/MMTabline/MMTabline.m

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,6 @@
2828
return button;
2929
}
3030

31-
static CGFloat calculateBrightness(NSColor *color) {
32-
if (color.colorSpace.colorSpaceModel == NSColorSpaceModelRGB) {
33-
// Calculate brightness according to a formula from
34-
// the W3C that gives brightness as the eye perceives it. Then lighten
35-
// or darken the default colors based on whether brightness is greater
36-
// than 50% to achieve good visual contrast.
37-
// www.w3.org/WAI/ER/WD-AERT/#color-contrast
38-
CGFloat r, g, b;
39-
[color getRed:&r green:&g blue:&b alpha:NULL];
40-
return r * 0.299 + g * 0.114 + b * 0.587;
41-
} else if (color.colorSpace.colorSpaceModel == NSColorSpaceModelGray) {
42-
return color.whiteComponent;
43-
}
44-
return 1;
45-
}
46-
4731
@implementation MMTabline
4832
{
4933
NSView *_tabsContainer;
@@ -299,7 +283,11 @@ - (NSColor *)tablineStrokeColor
299283

300284
// High-contrast modes. Should stroke to make it easier to read.
301285
NSColor *bgColor = self.tablineBgColor;
302-
CGFloat brightness = calculateBrightness(bgColor);
286+
CGFloat brightness = 1;
287+
if (bgColor.colorSpace.colorSpaceModel == NSColorSpaceModelRGB)
288+
brightness = bgColor.brightnessComponent;
289+
else if (bgColor.colorSpace.colorSpaceModel == NSColorSpaceModelGray)
290+
brightness = bgColor.whiteComponent;
303291
if (brightness > 0.5)
304292
return NSColor.blackColor;
305293
else
@@ -565,29 +553,63 @@ - (void)setAutoColorsSelBg:(NSColor *)back fg:(NSColor *)fore;
565553
{
566554
// Set the colors for the tabline based on the default background and
567555
// foreground colors.
568-
const CGFloat brightness = calculateBrightness(back);
569556

557+
// Calculate CIE Lab color. This is used for deriving other colors that are
558+
// brighter / darker versions of the background color. Using Lab gives better
559+
// results than simpy blending non-linearized RGB values.
560+
// Note: We don't use CGColorSpaceCreateWithName(kCGColorSpaceGenericLab)
561+
// because the API is only available on macOS 10.13+.
562+
const CGFloat whitePoint[3] = {0.95947,1,1.08883}; // D65 white point
563+
const CGFloat blackPoint[3] = {0,0,0};
564+
const CGFloat ranges[4] = {-127, 127, -127, 127};
565+
CGColorSpaceRef labRef = CGColorSpaceCreateLab(whitePoint, blackPoint, ranges);
566+
NSColorSpace *lab = [[NSColorSpace alloc] initWithCGColorSpace:labRef];
567+
NSColor *backLab = [back colorUsingColorSpace:lab];
568+
CGColorSpaceRelease(labRef);
569+
if (backLab.numberOfComponents > 4)
570+
backLab = nil; // don't know how this could happen, but just to be safe
571+
572+
CGFloat backComponents[4] = { 1, 0, 0, 1 }; // L*/a*/b*/alpha. L* is perceptual lightness from 0-100.
573+
[backLab getComponents:backComponents];
574+
CGFloat newComponents[4];
575+
memcpy(newComponents, backComponents, sizeof(newComponents));
576+
577+
// Contrast (different in lightness) for fill bg and tab bg colors relative to the background color
578+
// Note that this is not perceptively accurate to just add a fixed offset to the L* value but it's
579+
// good enough for our purpose.
580+
const CGFloat fillContrastDark = 17.0;
581+
const CGFloat bgContrastDark = fillContrastDark * 0.71;
582+
const CGFloat fillContrastLight = -19.0;
583+
const CGFloat bgContrastLight = fillContrastLight * 0.70;
584+
585+
const CGFloat fillContrast = backComponents[0] >= 40 ? fillContrastLight : fillContrastDark;
586+
const CGFloat bgContrast = backComponents[0] >= 40 ? bgContrastLight : bgContrastDark;
587+
588+
// Assign the colors
570589
_tablineSelBgColor = back;
571590

572-
_tablineSelFgColor = (brightness > 0.5)
573-
? [fore blendedColorWithFraction:0.6 ofColor:NSColor.blackColor]
574-
: [fore blendedColorWithFraction:0.6 ofColor:NSColor.whiteColor];
591+
_tablineSelFgColor = [fore blendedColorWithFraction:0.6
592+
ofColor:(backComponents[0] >= 50 ? NSColor.blackColor : NSColor.whiteColor)];
575593
_addTabButton.fgColor = _tablineSelFgColor;
576594
_backwardScrollButton.fgColor = _tablineSelFgColor;
577595
_forwardScrollButton.fgColor = _tablineSelFgColor;
578596

579-
_tablineBgColor = (brightness > 0.5)
580-
? [back blendedColorWithFraction:0.16 ofColor:NSColor.blackColor]
581-
: [back blendedColorWithFraction:0.13 ofColor:NSColor.whiteColor];
597+
newComponents[0] = backComponents[0] + bgContrast;
598+
_tablineBgColor = [[NSColor colorWithColorSpace:lab
599+
components:newComponents
600+
count:4]
601+
colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
582602

583603
_tablineFgColor = [_tablineSelFgColor blendedColorWithFraction:0.5 ofColor:_tablineBgColor];
584604

585605
_tablineUnfocusedFgColor = [_tablineFgColor blendedColorWithFraction:0.4 ofColor:_tablineBgColor];
586606
_tablineUnfocusedSelFgColor = [_tablineSelFgColor blendedColorWithFraction:0.38 ofColor:_tablineSelBgColor];
587607

588-
_tablineFillBgColor = (brightness > 0.5)
589-
? [back blendedColorWithFraction:0.25 ofColor:NSColor.blackColor]
590-
: [back blendedColorWithFraction:0.18 ofColor:NSColor.whiteColor];
608+
newComponents[0] = backComponents[0] + fillContrast;
609+
_tablineFillBgColor = [[NSColor colorWithColorSpace:lab
610+
components:newComponents
611+
count:4]
612+
colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
591613

592614
[self updateTabStates];
593615
self.needsDisplay = YES;

0 commit comments

Comments
 (0)