From 05f729755c28a48652d397ccadfa55e69aa9cd7c Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 17 Sep 2024 03:39:36 +0800 Subject: [PATCH] Add Color.Resolved kitColor implementation --- .../Overlay/CoreGraphics/CoreColor.m | 70 ++++++++++-------- Sources/COpenSwiftUICore/README.md | 3 + Sources/COpenSwiftUICore/include/CoreColor.h | 35 +++++---- .../View/Graphic/Color/ColorResolved.swift | 9 +++ .../Graphic/Color/CoreColor+Extension.swift | 73 +++++++++++++++++++ .../Graphics/Color/ColorResolvedTests.swift | 19 +++++ 6 files changed, 162 insertions(+), 47 deletions(-) create mode 100644 Sources/COpenSwiftUICore/README.md create mode 100644 Sources/OpenSwiftUI/View/Graphic/Color/CoreColor+Extension.swift create mode 100644 Tests/OpenSwiftUITests/View/Graphics/Color/ColorResolvedTests.swift diff --git a/Sources/COpenSwiftUICore/Overlay/CoreGraphics/CoreColor.m b/Sources/COpenSwiftUICore/Overlay/CoreGraphics/CoreColor.m index 8aebc99c..325ed5d0 100644 --- a/Sources/COpenSwiftUICore/Overlay/CoreGraphics/CoreColor.m +++ b/Sources/COpenSwiftUICore/Overlay/CoreGraphics/CoreColor.m @@ -21,24 +21,32 @@ BOOL CoreColorPlatformColorGetComponents(BOOL system, id color, CGFloat *red, CG return NO; } Class colorClass = CoreColorClass(system); - if (colorClass) { - #if OPENSWIFTUI_TARGET_OS_OSX - if (system) { - id colorSpace = - NSColorSpaceForCGColorSpace(CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB)); - NSColor *nameSpaceColor = [color colorUsingColorSpace:colorSpace]; - if (nameSpaceColor) { - [nameSpaceColor getRed:red green:green blue: blue alpha: alpha]; - return YES; - } else { - return NO; - } - } - #endif - return ((BOOL (*)(id, SEL))[color methodForSelector:@selector(getRed:green:blue:alpha:)])(color, @selector(getRed:green:blue:alpha:)); - } else { + if (!colorClass) { return NO; } + #if OPENSWIFTUI_TARGET_OS_OSX + if (system) { + id colorSpace = + NSColorSpaceForCGColorSpace(CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB)); + NSColor *nameSpaceColor = [color colorUsingColorSpace:colorSpace]; + if (nameSpaceColor) { + [nameSpaceColor getRed:red green:green blue: blue alpha: alpha]; + return YES; + } else { + return NO; + } + } + #endif + // NOTE: Fix Mac Catalyst selector type issue + return ((BOOL (*)(id, SEL))[color methodForSelector:@selector(getRed:green:blue:alpha:)])(color, @selector(getRed:green:blue:alpha:)); +} + +NSObject *CorePlatformColorForRGBA(BOOL system, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) { + Class colorClass = CoreColorClass(system); + if (!colorClass) { + return nil; + } + return [[colorClass alloc] initWithRed:red green:green blue:blue alpha:alpha]; } Class CoreColorGetKitColorClass(BOOL system) { @@ -95,7 +103,7 @@ @interface CoreColor () { @implementation CoreColor -+ (id)colorWithSystem:(BOOL)system cgColor: (CGColorRef)cgColor { ++ (NSObject *)colorWithSystem:(BOOL)system cgColor: (CGColorRef)cgColor { Class colorClass = CoreColorClass(system); if (colorClass) { return [colorClass colorWithCGColor: cgColor]; @@ -104,72 +112,72 @@ + (id)colorWithSystem:(BOOL)system cgColor: (CGColorRef)cgColor { } } -+ (id)blackColorWithSystem:(BOOL)system { ++ (NSObject *)blackColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass blackColor]; } -+ (id)systemRedColorWithSystem:(BOOL)system { ++ (NSObject *)systemRedColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemRedColor]; } -+ (id)systemOrangeColorWithSystem:(BOOL)system { ++ (NSObject *)systemOrangeColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemOrangeColor]; } -+ (id)systemYellowColorWithSystem:(BOOL)system { ++ (NSObject *)systemYellowColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemYellowColor]; } -+ (id)systemGreenColorWithSystem:(BOOL)system { ++ (NSObject *)systemGreenColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemGreenColor]; } -+ (id)systemTealColorWithSystem:(BOOL)system { ++ (NSObject *)systemTealColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemTealColor]; } -+ (id)systemMintColorWithSystem:(BOOL)system { ++ (NSObject *)systemMintColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemMintColor]; } -+ (id)systemCyanColorWithSystem:(BOOL)system { ++ (NSObject *)systemCyanColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemCyanColor]; } -+ (id)systemBlueColorWithSystem:(BOOL)system { ++ (NSObject *)systemBlueColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemBlueColor]; } -+ (id)systemIndigoColorWithSystem:(BOOL)system { ++ (NSObject *)systemIndigoColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemIndigoColor]; } -+ (id)systemPurpleColorWithSystem:(BOOL)system { ++ (NSObject *)systemPurpleColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemPurpleColor]; } -+ (id)systemPinkColorWithSystem:(BOOL)system { ++ (NSObject *)systemPinkColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemPinkColor]; } -+ (id)systemBrownColorWithSystem:(BOOL)system { ++ (NSObject *)systemBrownColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemBrownColor]; } -+ (id)systemGrayColorWithSystem:(BOOL)system { ++ (NSObject *)systemGrayColorWithSystem:(BOOL)system { Class colorClass = CoreColorClass(system); return [colorClass systemGrayColor]; } diff --git a/Sources/COpenSwiftUICore/README.md b/Sources/COpenSwiftUICore/README.md new file mode 100644 index 00000000..44a57483 --- /dev/null +++ b/Sources/COpenSwiftUICore/README.md @@ -0,0 +1,3 @@ +## COpenSwiftUICore + +TODO: module name - OpenSwiftUI_SPI diff --git a/Sources/COpenSwiftUICore/include/CoreColor.h b/Sources/COpenSwiftUICore/include/CoreColor.h index dbc94fda..9a319ef3 100644 --- a/Sources/COpenSwiftUICore/include/CoreColor.h +++ b/Sources/COpenSwiftUICore/include/CoreColor.h @@ -23,25 +23,28 @@ OPENSWIFTUI_EXPORT BOOL CoreColorPlatformColorGetComponents(BOOL system, id color, CGFloat *red, CGFloat *green, CGFloat *blue, CGFloat *alpha); OPENSWIFTUI_EXPORT -Class CoreColorGetKitColorClass(BOOL isAppKitBased); +NSObject * _Nullable CorePlatformColorForRGBA(BOOL system, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha); + +OPENSWIFTUI_EXPORT +Class CoreColorGetKitColorClass(BOOL system); @interface CoreColor : NSObject -+ (id)colorWithSystem:(BOOL)system cgColor: (CGColorRef)cgColor; -+ (id)blackColorWithSystem:(BOOL)system; -+ (id)systemRedColorWithSystem:(BOOL)system; -+ (id)systemOrangeColorWithSystem:(BOOL)system; -+ (id)systemYellowColorWithSystem:(BOOL)system; -+ (id)systemGreenColorWithSystem:(BOOL)system; -+ (id)systemTealColorWithSystem:(BOOL)system; -+ (id)systemMintColorWithSystem:(BOOL)system; -+ (id)systemCyanColorWithSystem:(BOOL)system; -+ (id)systemBlueColorWithSystem:(BOOL)system; -+ (id)systemIndigoColorWithSystem:(BOOL)system; -+ (id)systemPurpleColorWithSystem:(BOOL)system; -+ (id)systemPinkColorWithSystem:(BOOL)system; -+ (id)systemBrownColorWithSystem:(BOOL)system; -+ (id)systemGrayColorWithSystem:(BOOL)system; ++ (nullable NSObject *)colorWithSystem:(BOOL)system cgColor: (CGColorRef)cgColor; ++ (nullable NSObject *)blackColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemRedColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemOrangeColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemYellowColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemGreenColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemTealColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemMintColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemCyanColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemBlueColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemIndigoColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemPurpleColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemPinkColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemBrownColorWithSystem:(BOOL)system; ++ (nullable NSObject *)systemGrayColorWithSystem:(BOOL)system; - (instancetype)initWithCGColor:(CGColorRef)cgColor; - (void)set; diff --git a/Sources/OpenSwiftUI/View/Graphic/Color/ColorResolved.swift b/Sources/OpenSwiftUI/View/Graphic/Color/ColorResolved.swift index b39d850f..f043bae6 100644 --- a/Sources/OpenSwiftUI/View/Graphic/Color/ColorResolved.swift +++ b/Sources/OpenSwiftUI/View/Graphic/Color/ColorResolved.swift @@ -309,5 +309,14 @@ extension Color.Resolved { return nil } } + + // ID: 4330A474F53D66045762501ED6F8A749 + private static let cache: ObjectCache = ObjectCache { resolved in + CoreColor.platformColor(resolvedColor: resolved)! + } + + package var kitColor: NSObject { + Self.cache[self] + } } #endif diff --git a/Sources/OpenSwiftUI/View/Graphic/Color/CoreColor+Extension.swift b/Sources/OpenSwiftUI/View/Graphic/Color/CoreColor+Extension.swift new file mode 100644 index 00000000..68d9b63e --- /dev/null +++ b/Sources/OpenSwiftUI/View/Graphic/Color/CoreColor+Extension.swift @@ -0,0 +1,73 @@ +// +// CoreColor+Extension.swift +// OpenSwiftUI +// +// Audited for RELEASE_2024 +// Status: WIP + +import COpenSwiftUICore + +extension CoreColor { + package static func platformColor(resolvedColor: Color.Resolved) -> NSObject? { + platformColor(red: CGFloat(resolvedColor.red), green: CGFloat(resolvedColor.green), blue: CGFloat(resolvedColor.blue), alpha: CGFloat(resolvedColor.opacity)) + } + + package static func platformColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> NSObject? { + CorePlatformColorForRGBA(isAppKitBased(), red, green, blue, alpha) + } + + #if os(iOS) + static var systemRed: NSObject? { + systemRedColor(withSystem: isAppKitBased()) + } + + static var systemOrange: NSObject? { + systemOrangeColor(withSystem: isAppKitBased()) + } + + static var systemYellow: NSObject? { + systemYellowColor(withSystem: isAppKitBased()) + } + + static var systemGreen: NSObject? { + systemGreenColor(withSystem: isAppKitBased()) + } + + static var systemTeal: NSObject? { + systemTealColor(withSystem: isAppKitBased()) + } + + static var systemMint: NSObject? { + systemMintColor(withSystem: isAppKitBased()) + } + + static var systemCyan: NSObject? { + systemCyanColor(withSystem: isAppKitBased()) + } + + static var systemBlue: NSObject? { + systemBlueColor(withSystem: isAppKitBased()) + } + + static var systemIndigo: NSObject? { + systemIndigoColor(withSystem: isAppKitBased()) + } + + static var systemPurple: NSObject? { + systemPurpleColor(withSystem: isAppKitBased()) + } + + static var systemPink: NSObject? { + systemPinkColor(withSystem: isAppKitBased()) + } + + static var systemBrown: NSObject? { + systemBrownColor(withSystem: isAppKitBased()) + } + + static var systemGray: NSObject? { + systemGrayColor(withSystem: isAppKitBased()) + } + #endif +} + diff --git a/Tests/OpenSwiftUITests/View/Graphics/Color/ColorResolvedTests.swift b/Tests/OpenSwiftUITests/View/Graphics/Color/ColorResolvedTests.swift new file mode 100644 index 00000000..f29ad47e --- /dev/null +++ b/Tests/OpenSwiftUITests/View/Graphics/Color/ColorResolvedTests.swift @@ -0,0 +1,19 @@ +// +// ColorResolvedTests.swift +// OpenSwiftUITests + +@testable import OpenSwiftUI +import Testing + +struct ColorResolvedTests { + @Test + func kitColor() { + let r1 = Color.Resolved(colorSpace: .sRGB, red: 1, green: 1, blue: 1, opacity: 1) + let r2 = Color.Resolved(colorSpace: .sRGBLinear, red: 1, green: 1, blue: 1, opacity: 1) + + #expect(r2.kitColor === r1.kitColor) + + let r3 = Color.Resolved(colorSpace: .sRGB, red: 0.3, green: 0.3, blue: 0.3, opacity: 0.3) + #expect(r3.kitColor !== r1.kitColor) + } +}