6
6
*/
7
7
8
8
#import " HostPlatformColor.h"
9
+ #import " UIColor+Graphics.h"
9
10
10
11
#import < Foundation/Foundation.h>
11
12
#import < UIKit/UIKit.h>
13
+ #import < react/renderer/graphics/RCTPlatformColorUtils.h>
12
14
#import < react/utils/ManagedObjectWrapper.h>
13
15
#import < string>
14
16
19
21
namespace facebook ::react {
20
22
21
23
namespace {
24
+
25
+ bool UIColorIsP3ColorSpace (const std::shared_ptr<void > &uiColor)
26
+ {
27
+ UIColor *color = unwrapManagedObject (uiColor);
28
+ CGColorSpaceRef colorSpace = CGColorGetColorSpace (color.CGColor );
29
+
30
+ if (CGColorSpaceGetModel (colorSpace) == kCGColorSpaceModelRGB ) {
31
+ CFStringRef name = CGColorSpaceGetName (colorSpace);
32
+ if (name != NULL && CFEqual (name, kCGColorSpaceDisplayP3 )) {
33
+ return true ;
34
+ }
35
+ }
36
+ return false ;
37
+ }
38
+
22
39
UIColor *_Nullable UIColorFromInt32 (int32_t intColor)
23
40
{
24
41
CGFloat a = CGFloat ((intColor >> 24 ) & 0xFF ) / 255.0 ;
25
42
CGFloat r = CGFloat ((intColor >> 16 ) & 0xFF ) / 255.0 ;
26
43
CGFloat g = CGFloat ((intColor >> 8 ) & 0xFF ) / 255.0 ;
27
44
CGFloat b = CGFloat (intColor & 0xFF ) / 255.0 ;
28
- return [UIColor colorWithRed: r green: g blue: b alpha: a];
45
+
46
+ UIColor *color = [UIColor colorWithRed: r green: g blue: b alpha: a];
47
+ color.reactHash = facebook::react::hash_combine (intColor, 0 );
48
+ return color;
29
49
}
30
50
31
51
UIColor *_Nullable UIColorFromDynamicColor (const facebook::react::DynamicColor &dynamicColor)
56
76
}
57
77
}
58
78
}];
79
+ color.reactHash = facebook::react::hash_combine (dark, light, highContrastDark, highContrastLight, 0 );
59
80
return color;
60
81
} else {
61
82
return nil ;
64
85
return nil ;
65
86
}
66
87
67
- int32_t ColorFromUIColor (UIColor *color )
88
+ int32_t ColorFromColorComponents ( const facebook::react::ColorComponents &components )
68
89
{
69
90
float ratio = 255 ;
91
+ auto color = ((int32_t )round ((float )components.alpha * ratio) & 0xff ) << 24 |
92
+ ((int )round ((float )components.red * ratio) & 0xff ) << 16 |
93
+ ((int )round ((float )components.green * ratio) & 0xff ) << 8 | ((int )round ((float )components.blue * ratio) & 0xff );
94
+ return color;
95
+ }
96
+
97
+ int32_t ColorFromUIColor (UIColor *color)
98
+ {
70
99
CGFloat rgba[4 ];
71
100
[color getRed: &rgba[0 ] green: &rgba[1 ] blue: &rgba[2 ] alpha: &rgba[3 ]];
72
- return ((int32_t )round ((float )rgba[3 ] * ratio) & 0xff ) << 24 | ((int )round ((float )rgba[0 ] * ratio) & 0xff ) << 16 |
73
- ((int )round ((float )rgba[1 ] * ratio) & 0xff ) << 8 | ((int )round ((float )rgba[2 ] * ratio) & 0xff );
101
+ return ColorFromColorComponents ({(float )rgba[0 ], (float )rgba[1 ], (float )rgba[2 ], (float )rgba[3 ]});
74
102
}
75
103
76
- int32_t ColorFromUIColor (const std::shared_ptr<void > &uiColor)
104
+ int32_t ColorFromUIColorForSpecificTraitCollection (
105
+ const std::shared_ptr<void > &uiColor,
106
+ UITraitCollection *traitCollection)
77
107
{
78
108
UIColor *color = (UIColor *)unwrapManagedObject (uiColor);
79
109
if (color) {
80
- UITraitCollection *currentTraitCollection = [UITraitCollection currentTraitCollection ];
81
- color = [color resolvedColorWithTraitCollection: currentTraitCollection];
110
+ color = [color resolvedColorWithTraitCollection: traitCollection];
82
111
return ColorFromUIColor (color);
83
112
}
84
113
85
114
return 0 ;
86
115
}
87
116
117
+ int32_t ColorFromUIColor (const std::shared_ptr<void > &uiColor)
118
+ {
119
+ return ColorFromUIColorForSpecificTraitCollection (uiColor, [UITraitCollection currentTraitCollection ]);
120
+ }
121
+
88
122
UIColor *_Nullable UIColorFromComponentsColor (const facebook::react::ColorComponents &components)
89
123
{
124
+ UIColor *uiColor = nil ;
90
125
if (components.colorSpace == ColorSpace::DisplayP3) {
91
- return [UIColor colorWithDisplayP3Red: components.red
92
- green: components.green
93
- blue: components.blue
94
- alpha: components.alpha];
126
+ uiColor = [UIColor colorWithDisplayP3Red: components.red
127
+ green: components.green
128
+ blue: components.blue
129
+ alpha: components.alpha];
130
+ } else {
131
+ uiColor = [UIColor colorWithRed: components.red green: components.green blue: components.blue alpha: components.alpha];
132
+ }
133
+
134
+ auto color = ColorFromColorComponents (components);
135
+ uiColor.reactHash = facebook::react::hash_combine (color, components.colorSpace == ColorSpace::DisplayP3);
136
+
137
+ return uiColor;
138
+ }
139
+
140
+ int32_t hashFromUIColor (const std::shared_ptr<void > &uiColor)
141
+ {
142
+ if (uiColor == nullptr ) {
143
+ return 0 ;
95
144
}
96
- return [UIColor colorWithRed: components.red green: components.green blue: components.blue alpha: components.alpha];
145
+
146
+ static UITraitCollection *darkModeTraitCollection =
147
+ [UITraitCollection traitCollectionWithUserInterfaceStyle: UIUserInterfaceStyleDark];
148
+ auto darkColor = ColorFromUIColorForSpecificTraitCollection (uiColor, darkModeTraitCollection);
149
+
150
+ static UITraitCollection *lightModeTraitCollection =
151
+ [UITraitCollection traitCollectionWithUserInterfaceStyle: UIUserInterfaceStyleLight];
152
+ auto lightColor = ColorFromUIColorForSpecificTraitCollection (uiColor, lightModeTraitCollection);
153
+
154
+ static UITraitCollection *darkModeAccessibilityContrastTraitCollection =
155
+ [UITraitCollection traitCollectionWithTraitsFromCollections: @[
156
+ darkModeTraitCollection,
157
+ [UITraitCollection traitCollectionWithAccessibilityContrast: UIAccessibilityContrastHigh]
158
+ ]];
159
+ auto darkAccessibilityContrastColor =
160
+ ColorFromUIColorForSpecificTraitCollection (uiColor, darkModeAccessibilityContrastTraitCollection);
161
+
162
+ static UITraitCollection *lightModeAccessibilityContrastTraitCollection =
163
+ [UITraitCollection traitCollectionWithTraitsFromCollections: @[
164
+ lightModeTraitCollection,
165
+ [UITraitCollection traitCollectionWithAccessibilityContrast: UIAccessibilityContrastHigh]
166
+ ]];
167
+ auto lightAccessibilityContrastColor =
168
+ ColorFromUIColorForSpecificTraitCollection (uiColor, lightModeAccessibilityContrastTraitCollection);
169
+ return facebook::react::hash_combine (
170
+ darkColor,
171
+ lightColor,
172
+ darkAccessibilityContrastColor,
173
+ lightAccessibilityContrastColor,
174
+ UIColorIsP3ColorSpace (uiColor));
97
175
}
176
+
98
177
} // anonymous namespace
99
178
100
179
Color::Color (int32_t color)
@@ -114,14 +193,20 @@ int32_t ColorFromUIColor(const std::shared_ptr<void> &uiColor)
114
193
115
194
Color::Color (std::shared_ptr<void > uiColor)
116
195
{
196
+ UIColor *color = ((UIColor *)unwrapManagedObject (uiColor));
197
+ if (color && color.reactHash == 0 ) {
198
+ auto colorHash = hashFromUIColor (uiColor);
199
+ color.reactHash = colorHash;
200
+ }
117
201
uiColor_ = std::move (uiColor);
118
202
}
119
203
120
204
bool Color::operator ==(const Color &other) const
121
205
{
122
206
return (!uiColor_ && !other.uiColor_ ) ||
123
207
(uiColor_ && other.uiColor_ &&
124
- [unwrapManagedObject (getUIColor ()) isEqual: unwrapManagedObject (other.getUIColor ())]);
208
+ ((UIColor *)unwrapManagedObject (getUIColor ())).reactHash ==
209
+ ((UIColor *)unwrapManagedObject (other.getUIColor ())).reactHash );
125
210
}
126
211
127
212
bool Color::operator !=(const Color &other) const
@@ -142,6 +227,17 @@ int32_t ColorFromUIColor(const std::shared_ptr<void> &uiColor)
142
227
return static_cast <float >(rgba[channelId]);
143
228
}
144
229
230
+ int32_t Color::getUIColorHash () const
231
+ {
232
+ return [(UIColor *)unwrapManagedObject (uiColor_) reactHash ];
233
+ }
234
+
235
+ Color Color::createSemanticColor (std::vector<std::string> &semanticItems)
236
+ {
237
+ auto semanticColor = RCTPlatformColorFromSemanticItems (semanticItems);
238
+ return Color (wrapManagedObject (semanticColor));
239
+ }
240
+
145
241
} // namespace facebook::react
146
242
147
243
NS_ASSUME_NONNULL_END
0 commit comments