Skip to content

Commit 8ac02c6

Browse files
committed
Update CoreColor API
1 parent 1908a4f commit 8ac02c6

File tree

8 files changed

+164
-72
lines changed

8 files changed

+164
-72
lines changed

Package.resolved

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ if warningsAsErrorsCondition {
8686
sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"]))
8787
}
8888

89-
// NOTE: Mac Catalyst should use macOS-varient build of OpenSwiftUICore.framework and Mac Catalyst/UIKitForMac varient of OpenSwiftUI.framework
89+
// NOTE:
90+
// In macOS: Mac Catalyst App will use macOS-varient build of SwiftUI.framework in /System/Library/Framework and iOS varient of SwiftUI.framework in /System/iOSSupport/System/Library/Framework
9091
// Add `|| Mac Catalyst` check everywhere in `OpenSwiftUICore` and `OpenSwiftUI_SPI`.
9192
let openSwiftUICoreTarget = Target.target(
9293
name: "OpenSwiftUICore",
@@ -118,6 +119,7 @@ let OpenSwiftUI_SPITestTarget = Target.testTarget(
118119
"OpenSwiftUI_SPI",
119120
// For ProtocolDescriptor symbol linking
120121
"OpenSwiftUI",
122+
.product(name: "Numerics", package: "swift-numerics")
121123
],
122124
exclude: ["README.md"],
123125
swiftSettings: sharedSwiftSettings
@@ -157,6 +159,9 @@ let package = Package(
157159
// FIXME: This will block xcodebuild build(iOS CI) somehow
158160
// .library(name: "OpenSwiftUI_SPI", targets: ["OpenSwiftUI_SPI"]),
159161
],
162+
dependencies: [
163+
.package(url: "https://github.com/apple/swift-numerics.git", from: "1.0.2"),
164+
],
160165
targets: [
161166
// TODO: Add SwiftGTK as an backend alternative for UIKit/AppKit on Linux and macOS
162167
.systemLibrary(

Sources/OpenSwiftUICore/Graphic/Color/CoreColor+Extension.swift

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,60 +17,6 @@ extension OpenSwiftUICoreColor {
1717
package static func platformColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> NSObject? {
1818
OpenSwiftUICorePlatformColorForRGBA(isAppKitBased(), red, green, blue, alpha)
1919
}
20-
21-
#if os(iOS)
22-
static var systemRed: NSObject? {
23-
systemRedColor(withSystem: isAppKitBased())
24-
}
25-
26-
static var systemOrange: NSObject? {
27-
systemOrangeColor(withSystem: isAppKitBased())
28-
}
29-
30-
static var systemYellow: NSObject? {
31-
systemYellowColor(withSystem: isAppKitBased())
32-
}
33-
34-
static var systemGreen: NSObject? {
35-
systemGreenColor(withSystem: isAppKitBased())
36-
}
37-
38-
static var systemTeal: NSObject? {
39-
systemTealColor(withSystem: isAppKitBased())
40-
}
41-
42-
static var systemMint: NSObject? {
43-
systemMintColor(withSystem: isAppKitBased())
44-
}
45-
46-
static var systemCyan: NSObject? {
47-
systemCyanColor(withSystem: isAppKitBased())
48-
}
49-
50-
static var systemBlue: NSObject? {
51-
systemBlueColor(withSystem: isAppKitBased())
52-
}
53-
54-
static var systemIndigo: NSObject? {
55-
systemIndigoColor(withSystem: isAppKitBased())
56-
}
57-
58-
static var systemPurple: NSObject? {
59-
systemPurpleColor(withSystem: isAppKitBased())
60-
}
61-
62-
static var systemPink: NSObject? {
63-
systemPinkColor(withSystem: isAppKitBased())
64-
}
65-
66-
static var systemBrown: NSObject? {
67-
systemBrownColor(withSystem: isAppKitBased())
68-
}
69-
70-
static var systemGray: NSObject? {
71-
systemGrayColor(withSystem: isAppKitBased())
72-
}
73-
#endif
7420
}
7521

7622
#endif

Sources/OpenSwiftUICore/Util/Utils.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ func asOptional<Value>(_ value: Value) -> Value? {
1717

1818
#if canImport(Darwin)
1919

20-
// NOTE: use runtime check instead of #if targetEnvironment(macCatalyst) here
20+
// NOTE: use runtime check instead of #if targetEnvironment(macCatalyst)
21+
// Because Mac Catalyst will use macOS-varient build of OpenSwiftUICore.framework and Mac Catalyst/UIKitForMac varient of OpenSwiftUI.framework
2122
@inline(__always)
2223
package func isCatalyst() -> Bool {
2324
#if os(macOS) || targetEnvironment(macCatalyst)

Sources/OpenSwiftUI_SPI/Overlay/CoreGraphics/OpenSwiftUICoreColor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ OPENSWIFTUI_EXPORT
2727
NSObject * _Nullable OpenSwiftUICorePlatformColorForRGBA(BOOL system, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
2828

2929
OPENSWIFTUI_EXPORT
30-
Class OpenSwiftUICoreColorGetKitColorClass(BOOL system);
30+
Class _Nullable OpenSwiftUICoreColorGetKitColorClass(BOOL system);
3131

3232
@interface OpenSwiftUICoreColor : NSObject
3333

Sources/OpenSwiftUI_SPI/Overlay/CoreGraphics/OpenSwiftUICoreColor.m

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,19 @@
1010
#if OPENSWIFTUI_TARGET_OS_DARWIN
1111
#include "OpenSwiftUICoreGraphicsContext.h"
1212

13-
Class OpenSwiftUICoreColorClass(BOOL isAppKitBased);
13+
Class OpenSwiftUICoreColorClass(BOOL system);
1414

15-
#if OPENSWIFTUI_TARGET_OS_OSX || OPENSWIFTUI_TARGET_OS_MACCATALYST
15+
#if OPENSWIFTUI_TARGET_OS_OSX
1616
id NSColorSpaceForCGColorSpace(CGColorSpaceRef cgColorSpace);
1717
Class NSColorSpaceClass(void);
1818
#endif
1919

2020
BOOL OpenSwiftUICoreColorPlatformColorGetComponents(BOOL system, id color, CGFloat *red, CGFloat *green, CGFloat *blue, CGFloat *alpha) {
21-
if (!color) {
22-
return NO;
23-
}
2421
Class colorClass = OpenSwiftUICoreColorClass(system);
2522
if (!colorClass) {
2623
return NO;
2724
}
28-
#if OPENSWIFTUI_TARGET_OS_OSX || OPENSWIFTUI_TARGET_OS_MACCATALYST
25+
#if OPENSWIFTUI_TARGET_OS_OSX
2926
if (system) {
3027
id colorSpace = NSColorSpaceForCGColorSpace(CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB));
3128
NSColor *nameSpaceColor = [color colorUsingColorSpace:colorSpace];
@@ -35,36 +32,46 @@ BOOL OpenSwiftUICoreColorPlatformColorGetComponents(BOOL system, id color, CGFlo
3532
} else {
3633
return NO;
3734
}
35+
} else {
36+
// For OPENSWIFTUI_TARGET_OS_MACCATALYST
37+
typedef BOOL (*Func)(id, SEL, CGFloat *, CGFloat *, CGFloat *, CGFloat *);
38+
IMP imp = [color methodForSelector:@selector(getRed:green:blue:alpha:)];
39+
Func func = (Func)imp;
40+
return func(color, @selector(getRed:green:blue:alpha:), red, green, blue, alpha);
3841
}
42+
#else
43+
return [color getRed:red green:green blue:blue alpha:alpha];
3944
#endif
40-
// NOTE: Fix Mac Catalyst selector type issue
41-
return ((BOOL (*)(id, SEL))[color methodForSelector:@selector(getRed:green:blue:alpha:)])(color, @selector(getRed:green:blue:alpha:));
4245
}
4346

4447
NSObject *OpenSwiftUICorePlatformColorForRGBA(BOOL system, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) {
4548
Class colorClass = OpenSwiftUICoreColorClass(system);
4649
if (!colorClass) {
4750
return nil;
4851
}
49-
#if OPENSWIFTUI_TARGET_OS_OSX || OPENSWIFTUI_TARGET_OS_MACCATALYST
52+
#if OPENSWIFTUI_TARGET_OS_OSX
5053
if (system) {
5154
id colorSpace = NSColorSpaceForCGColorSpace(CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB));
5255
return [colorClass colorWithColorSpace:colorSpace components:(CGFloat[]){red, green, blue, alpha} count:4];
56+
} else {
57+
return [[colorClass alloc] initWithRed:red green:green blue:blue alpha:alpha];
5358
}
54-
#endif
59+
#else
5560
return [[colorClass alloc] initWithRed:red green:green blue:blue alpha:alpha];
61+
#endif
5662
}
5763

58-
Class OpenSwiftUICoreColorGetKitColorClass(BOOL system) {
64+
Class _Nullable OpenSwiftUICoreColorGetKitColorClass(BOOL system) {
5965
OpenSwiftUICoreColorClass(system);
6066
}
6167

62-
Class OpenSwiftUICoreColorClass(BOOL system) {
68+
Class _Nullable OpenSwiftUICoreColorClass(BOOL system) {
6369
static BOOL isValid = true;
70+
// FIXME: objc_autoreleaseReturnValue will crash
6471
static Class colorClass;
6572
static dispatch_once_t once;
6673
dispatch_once(&once, ^{
67-
#if OPENSWIFTUI_TARGET_OS_OSX || OPENSWIFTUI_TARGET_OS_MACCATALYST
74+
#if OPENSWIFTUI_TARGET_OS_OSX
6875
if (!system) {
6976
Class class = NSClassFromString(@"UIColor");
7077
colorClass = class;
@@ -88,7 +95,7 @@ Class OpenSwiftUICoreColorClass(BOOL system) {
8895
}
8996
}
9097

91-
#if OPENSWIFTUI_TARGET_OS_OSX || OPENSWIFTUI_TARGET_OS_MACCATALYST
98+
#if OPENSWIFTUI_TARGET_OS_OSX
9299
id NSColorSpaceForCGColorSpace(CGColorSpaceRef cgColorSpace) {
93100
Class colorSpaceClass = NSColorSpaceClass();
94101
if (colorSpaceClass) {
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//
2+
// CoreFoundationPrivateTests.swift
3+
// OpenSwiftUI_SPITests
4+
5+
import Numerics
6+
import OpenSwiftUI_SPI
7+
import OpenSwiftUICore
8+
import Testing
9+
10+
#if canImport(Darwin)
11+
12+
#if os(macOS)
13+
import AppKit
14+
#elseif os(iOS)
15+
import UIKit
16+
#endif
17+
18+
@MainActor
19+
struct OpenSwiftUICoreColorTests {
20+
@Test
21+
func platformColorGetComponents() {
22+
#if os(macOS)
23+
let blackColor = NSColor(colorSpace: .extendedSRGB, components: [0, 0, 0, 1], count: 4)
24+
let grayColor = NSColor(colorSpace: .extendedSRGB, components: [0.5, 0.5, 0.5, 1], count: 4)
25+
let whiteColor = NSColor(colorSpace: .extendedSRGB, components: [1, 1, 1, 1], count: 4)
26+
#elseif os(iOS)
27+
let blackColor = UIColor(white: 0, alpha: 1)
28+
let grayColor = UIColor(white: 0.5, alpha: 1)
29+
let whiteColor = UIColor(white: 1, alpha: 1)
30+
#endif
31+
32+
var r: CGFloat = 0
33+
var g: CGFloat = 0
34+
var b: CGFloat = 0
35+
var a: CGFloat = 0
36+
#expect(OpenSwiftUICoreColorPlatformColorGetComponents(isAppKitBased(), blackColor, &r, &g, &b, &a) == true)
37+
#expect(r.isApproximatelyEqual(to: 0))
38+
#expect(g.isApproximatelyEqual(to: 0))
39+
#expect(b.isApproximatelyEqual(to: 0))
40+
#expect(a.isApproximatelyEqual(to: 1))
41+
#expect(OpenSwiftUICoreColorPlatformColorGetComponents(isAppKitBased(), grayColor, &r, &g, &b, &a) == true)
42+
#expect(r.isApproximatelyEqual(to: 0.5))
43+
#expect(g.isApproximatelyEqual(to: 0.5))
44+
#expect(b.isApproximatelyEqual(to: 0.5))
45+
#expect(a.isApproximatelyEqual(to: 1))
46+
#expect(OpenSwiftUICoreColorPlatformColorGetComponents(isAppKitBased(), whiteColor, &r, &g, &b, &a) == true)
47+
#expect(r.isApproximatelyEqual(to: 1))
48+
#expect(g.isApproximatelyEqual(to: 1))
49+
#expect(b.isApproximatelyEqual(to: 1))
50+
#expect(a.isApproximatelyEqual(to: 1))
51+
}
52+
53+
@Test
54+
func platformColorForRGBA() throws {
55+
let blackColorObject = try #require(OpenSwiftUICorePlatformColorForRGBA(isAppKitBased(), 0, 0, 0, 1))
56+
let greyColorObject = try #require(OpenSwiftUICorePlatformColorForRGBA(isAppKitBased(), 0.5, 0.5, 0.5, 1))
57+
let whiteColorObject = try #require(OpenSwiftUICorePlatformColorForRGBA(isAppKitBased(), 1, 1, 1, 1))
58+
#if os(macOS)
59+
let blackColor = try #require((blackColorObject as? NSColor)?.usingColorSpace(.deviceRGB))
60+
let greyColor = try #require(greyColorObject as? NSColor)
61+
let whiteColor = try #require(whiteColorObject as? NSColor)
62+
var r: CGFloat = 0
63+
var g: CGFloat = 0
64+
var b: CGFloat = 0
65+
var a: CGFloat = 0
66+
blackColor.getRed(&r, green: &g, blue: &b, alpha: &a)
67+
#expect(r.isApproximatelyEqual(to: 0))
68+
#expect(g.isApproximatelyEqual(to: 0))
69+
#expect(b.isApproximatelyEqual(to: 0))
70+
#expect(a.isApproximatelyEqual(to: 1))
71+
greyColor.getRed(&r, green: &g, blue: &b, alpha: &a)
72+
#expect(r.isApproximatelyEqual(to: 0.5))
73+
#expect(g.isApproximatelyEqual(to: 0.5))
74+
#expect(b.isApproximatelyEqual(to: 0.5))
75+
#expect(a.isApproximatelyEqual(to: 1))
76+
whiteColor.getRed(&r, green: &g, blue: &b, alpha: &a)
77+
#expect(r.isApproximatelyEqual(to: 1))
78+
#expect(g.isApproximatelyEqual(to: 1))
79+
#expect(b.isApproximatelyEqual(to: 1))
80+
#expect(a.isApproximatelyEqual(to: 1))
81+
#elseif os(iOS)
82+
let blackColor = try #require(blackColorObject as? UIColor)
83+
let greyColor = try #require(greyColorObject as? UIColor)
84+
let whiteColor = try #require(whiteColorObject as? UIColor)
85+
var white: CGFloat = 0
86+
var alpha: CGFloat = 0
87+
blackColor.getWhite(&white, alpha: &alpha)
88+
#expect(white.isApproximatelyEqual(to: 0))
89+
#expect(alpha.isApproximatelyEqual(to: 1))
90+
greyColor.getWhite(&white, alpha: &alpha)
91+
#expect(white.isApproximatelyEqual(to: 0.5))
92+
#expect(alpha.isApproximatelyEqual(to: 1))
93+
whiteColor.getWhite(&white, alpha: &alpha)
94+
#expect(white.isApproximatelyEqual(to: 1.0000001192092896))
95+
#expect(alpha.isApproximatelyEqual(to: 1))
96+
#endif
97+
}
98+
99+
@Test
100+
func getKitColorClass() {
101+
let colorClass = OpenSwiftUICoreColorGetKitColorClass(isAppKitBased())
102+
print(colorClass)
103+
#if os(macOS)
104+
#expect(colorClass == NSColor.self)
105+
#elseif os(iOS)
106+
#expect(colorClass == UIColor.self)
107+
#endif
108+
}
109+
}
110+
#endif
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// OpenSwiftUICoreGraphicsContext.swift
3+
// OpenSwiftUI_SPITests
4+
5+
import OpenSwiftUI_SPI
6+
import Testing
7+
8+
#if canImport(Darwin)
9+
10+
struct OpenSwiftUICoreGraphicsContext {
11+
12+
}
13+
14+
#endif

0 commit comments

Comments
 (0)