mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-10-07 01:23:26 +00:00
Implement historic NXColor decoding
This commit is contained in:
parent
04188e54ec
commit
01bfbf390a
@ -416,6 +416,7 @@ set(AppKit_sources
|
||||
|
||||
NSSharingService.m
|
||||
MacWorkspace.m
|
||||
NSCoder+AppKit.m
|
||||
)
|
||||
|
||||
set_source_files_properties(${AppKit_sources} LANGUAGE C)
|
||||
|
6
AppKit/NSCoder+AppKit.h
Normal file
6
AppKit/NSCoder+AppKit.h
Normal file
@ -0,0 +1,6 @@
|
||||
#import <Foundation/NSCoder.h>
|
||||
#import <AppKit/NSColor.h>
|
||||
|
||||
@interface NSCoder (AppKit)
|
||||
-(NSColor*) decodeNXColor;
|
||||
@end
|
126
AppKit/NSCoder+AppKit.m
Normal file
126
AppKit/NSCoder+AppKit.m
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright (C) 2020 Lubos Dolezel
|
||||
|
||||
// Support for decoding legacy NXColors
|
||||
|
||||
#import "NSCoder+AppKit.h"
|
||||
#import <Foundation/NSCoder.h>
|
||||
#import <Foundation/NSArchiver.h>
|
||||
|
||||
enum {
|
||||
kColorSingleChannel = 0x1,
|
||||
kColorHasNamedColor = 0x4,
|
||||
kColorTypeFlags = 0x1f,
|
||||
kColorIsRGB = 0x40,
|
||||
kColorOpaque = 0x80,
|
||||
};
|
||||
|
||||
@implementation NSCoder (AppKit)
|
||||
|
||||
-(NSColor*) decodeNXColor
|
||||
{
|
||||
uint8_t type;
|
||||
|
||||
[self decodeValuesOfObjCTypes: "c", &type];
|
||||
if ((type & kColorTypeFlags) == 2 || (type & 0x10))
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
// RGB or CMY components
|
||||
uint16_t component1, component2, component3;
|
||||
if ((type & kColorTypeFlags) == kColorSingleChannel)
|
||||
{
|
||||
[self decodeValuesOfObjCTypes: "s", &component1];
|
||||
component3 = component2 = component1;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self decodeValuesOfObjCTypes: "sss", &component1, &component2, &component3];
|
||||
}
|
||||
|
||||
uint16_t componentK = 0, componentAlpha;
|
||||
if (!(type & kColorIsRGB))
|
||||
[self decodeValuesOfObjCTypes: "s", &componentK];
|
||||
|
||||
if (!(type & kColorOpaque))
|
||||
[self decodeValuesOfObjCTypes: "s", &componentAlpha];
|
||||
else
|
||||
componentAlpha = 65534; // opaque
|
||||
|
||||
if (type & kColorHasNamedColor)
|
||||
{
|
||||
NSString* colorName = nil;
|
||||
|
||||
const char* atom;
|
||||
[self decodeValuesOfObjCTypes: "%", &atom];
|
||||
|
||||
const char* name = atom;
|
||||
while (*name)
|
||||
{
|
||||
name++;
|
||||
if (*name == '\x1B')
|
||||
break;
|
||||
}
|
||||
|
||||
if (*name)
|
||||
colorName = [NSString stringWithCString: name encoding: NSMacOSRomanStringEncoding];
|
||||
|
||||
NSString* catalogs[2] = { @"PANTONE", nil };
|
||||
NSString* palette = nil;
|
||||
|
||||
if (atom)
|
||||
{
|
||||
int i;
|
||||
char bufPalette[112];
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
if (atom[i] == '\0' || atom[i] == '\x1B')
|
||||
break;
|
||||
bufPalette[i] = atom[i];
|
||||
}
|
||||
bufPalette[i] = '\0';
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
if (i == 2 && bufPalette[0] == 0x7F)
|
||||
{
|
||||
// FIXME: This works differently in practice, but I don't know how
|
||||
palette = catalogs[0];
|
||||
}
|
||||
else
|
||||
palette = [NSString stringWithCString: bufPalette encoding: NSMacOSRomanStringEncoding];
|
||||
}
|
||||
}
|
||||
|
||||
if (colorName && palette)
|
||||
{
|
||||
NSColor* color = [NSColor colorWithCatalogName:palette colorName:colorName];
|
||||
if (color != nil)
|
||||
{
|
||||
if (componentAlpha != 0)
|
||||
{
|
||||
// TODO: Unless completely transparent, apply alpha
|
||||
}
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type & kColorIsRGB)
|
||||
{
|
||||
return [NSColor colorWithCalibratedRed: (component1 / 65534.0f)
|
||||
green: (component2 / 65534.0f)
|
||||
blue: (component3 / 65534.0f)
|
||||
alpha: (componentAlpha / 65534.0f)];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [NSColor colorWithDeviceCyan: (component1 / 65534.0f)
|
||||
magenta: (component2 / 65534.0f)
|
||||
yellow: (component3 / 65534.0f)
|
||||
black: (componentK / 65534.0f)
|
||||
alpha: (componentAlpha / 65534.0f)];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue
Block a user