Skip to content

Commit

Permalink
Back out "Fabric: Fixes crash of dynamic color when light/dark mode c…
Browse files Browse the repository at this point in the history
…hanged" (#49054)

Summary:
Pull Request resolved: #49054

Original commit changeset: 01959845b742

Original Phabricator Diff: D68157559

Reviewed By: javache

Differential Revision: D68861984

fbshipit-source-id: c2e6fcf5d626447bd658b047adbb64947c2a5266
  • Loading branch information
Erica Klein authored and facebook-github-bot committed Jan 29, 2025
1 parent 2c406d8 commit 04afbd9
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@ struct Color {
Color(int32_t color);
Color(const DynamicColor& dynamicColor);
Color(const ColorComponents& components);
Color() : uiColor_(nullptr){};
Color(std::shared_ptr<void> uiColor);
int32_t getColor() const;
int32_t getUIColorHash() const;

static Color createSemanticColor(std::vector<std::string>& semanticItems);

std::shared_ptr<void> getUIColor() const {
return uiColor_;
}
Expand All @@ -52,7 +48,6 @@ struct Color {
}

private:
Color(std::shared_ptr<void> uiColor);
std::shared_ptr<void> uiColor_;
};

Expand All @@ -64,7 +59,7 @@ namespace HostPlatformColor {
#define NO_DESTROY
#endif

NO_DESTROY static const facebook::react::Color UndefinedColor = Color();
NO_DESTROY static const facebook::react::Color UndefinedColor = Color(nullptr);
} // namespace HostPlatformColor

inline Color
Expand Down Expand Up @@ -108,6 +103,8 @@ inline float blueFromHostPlatformColor(Color color) {
template <>
struct std::hash<facebook::react::Color> {
size_t operator()(const facebook::react::Color& color) const {
return color.getUIColorHash();
auto seed = size_t{0};
facebook::react::hash_combine(seed, color.getColor());
return seed;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
*/

#import "HostPlatformColor.h"
#import "UIColor+Graphics.h"

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <react/renderer/graphics/RCTPlatformColorUtils.h>
#import <react/utils/ManagedObjectWrapper.h>
#import <string>

Expand All @@ -21,31 +19,13 @@
namespace facebook::react {

namespace {

bool UIColorIsP3ColorSpace(const std::shared_ptr<void> &uiColor)
{
UIColor *color = unwrapManagedObject(uiColor);
CGColorSpaceRef colorSpace = CGColorGetColorSpace(color.CGColor);

if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelRGB) {
CFStringRef name = CGColorSpaceGetName(colorSpace);
if (name != NULL && CFEqual(name, kCGColorSpaceDisplayP3)) {
return true;
}
}
return false;
}

UIColor *_Nullable UIColorFromInt32(int32_t intColor)
{
CGFloat a = CGFloat((intColor >> 24) & 0xFF) / 255.0;
CGFloat r = CGFloat((intColor >> 16) & 0xFF) / 255.0;
CGFloat g = CGFloat((intColor >> 8) & 0xFF) / 255.0;
CGFloat b = CGFloat(intColor & 0xFF) / 255.0;

UIColor *color = [UIColor colorWithRed:r green:g blue:b alpha:a];
color.reactHash = facebook::react::hash_combine(intColor, 0);
return color;
return [UIColor colorWithRed:r green:g blue:b alpha:a];
}

UIColor *_Nullable UIColorFromDynamicColor(const facebook::react::DynamicColor &dynamicColor)
Expand Down Expand Up @@ -76,7 +56,6 @@ bool UIColorIsP3ColorSpace(const std::shared_ptr<void> &uiColor)
}
}
}];
color.reactHash = facebook::react::hash_combine(dark, light, highContrastDark, highContrastLight, 0);
return color;
} else {
return nil;
Expand All @@ -85,95 +64,37 @@ bool UIColorIsP3ColorSpace(const std::shared_ptr<void> &uiColor)
return nil;
}

int32_t ColorFromColorComponents(const facebook::react::ColorComponents &components)
{
float ratio = 255;
auto color = ((int32_t)round((float)components.alpha * ratio) & 0xff) << 24 |
((int)round((float)components.red * ratio) & 0xff) << 16 |
((int)round((float)components.green * ratio) & 0xff) << 8 | ((int)round((float)components.blue * ratio) & 0xff);
return color;
}

int32_t ColorFromUIColor(UIColor *color)
{
float ratio = 255;
CGFloat rgba[4];
[color getRed:&rgba[0] green:&rgba[1] blue:&rgba[2] alpha:&rgba[3]];
return ColorFromColorComponents({(float)rgba[0], (float)rgba[1], (float)rgba[2], (float)rgba[3]});
return ((int32_t)round((float)rgba[3] * ratio) & 0xff) << 24 | ((int)round((float)rgba[0] * ratio) & 0xff) << 16 |
((int)round((float)rgba[1] * ratio) & 0xff) << 8 | ((int)round((float)rgba[2] * ratio) & 0xff);
}

int32_t ColorFromUIColorForSpecificTraitCollection(
const std::shared_ptr<void> &uiColor,
UITraitCollection *traitCollection)
int32_t ColorFromUIColor(const std::shared_ptr<void> &uiColor)
{
UIColor *color = (UIColor *)unwrapManagedObject(uiColor);
if (color) {
color = [color resolvedColorWithTraitCollection:traitCollection];
UITraitCollection *currentTraitCollection = [UITraitCollection currentTraitCollection];
color = [color resolvedColorWithTraitCollection:currentTraitCollection];
return ColorFromUIColor(color);
}

return 0;
}

int32_t ColorFromUIColor(const std::shared_ptr<void> &uiColor)
{
return ColorFromUIColorForSpecificTraitCollection(uiColor, [UITraitCollection currentTraitCollection]);
}

UIColor *_Nullable UIColorFromComponentsColor(const facebook::react::ColorComponents &components)
{
UIColor *uiColor = nil;
if (components.colorSpace == ColorSpace::DisplayP3) {
uiColor = [UIColor colorWithDisplayP3Red:components.red
green:components.green
blue:components.blue
alpha:components.alpha];
} else {
uiColor = [UIColor colorWithRed:components.red green:components.green blue:components.blue alpha:components.alpha];
}

auto color = ColorFromColorComponents(components);
uiColor.reactHash = facebook::react::hash_combine(color, components.colorSpace == ColorSpace::DisplayP3);

return uiColor;
}

int32_t hashFromUIColor(const std::shared_ptr<void> &uiColor)
{
if (uiColor == nullptr) {
return 0;
return [UIColor colorWithDisplayP3Red:components.red
green:components.green
blue:components.blue
alpha:components.alpha];
}

static UITraitCollection *darkModeTraitCollection =
[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark];
auto darkColor = ColorFromUIColorForSpecificTraitCollection(uiColor, darkModeTraitCollection);

static UITraitCollection *lightModeTraitCollection =
[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight];
auto lightColor = ColorFromUIColorForSpecificTraitCollection(uiColor, lightModeTraitCollection);

static UITraitCollection *darkModeAccessibilityContrastTraitCollection =
[UITraitCollection traitCollectionWithTraitsFromCollections:@[
darkModeTraitCollection,
[UITraitCollection traitCollectionWithAccessibilityContrast:UIAccessibilityContrastHigh]
]];
auto darkAccessibilityContrastColor =
ColorFromUIColorForSpecificTraitCollection(uiColor, darkModeAccessibilityContrastTraitCollection);

static UITraitCollection *lightModeAccessibilityContrastTraitCollection =
[UITraitCollection traitCollectionWithTraitsFromCollections:@[
lightModeTraitCollection,
[UITraitCollection traitCollectionWithAccessibilityContrast:UIAccessibilityContrastHigh]
]];
auto lightAccessibilityContrastColor =
ColorFromUIColorForSpecificTraitCollection(uiColor, lightModeAccessibilityContrastTraitCollection);
return facebook::react::hash_combine(
darkColor,
lightColor,
darkAccessibilityContrastColor,
lightAccessibilityContrastColor,
UIColorIsP3ColorSpace(uiColor));
return [UIColor colorWithRed:components.red green:components.green blue:components.blue alpha:components.alpha];
}

} // anonymous namespace

Color::Color(int32_t color)
Expand All @@ -193,20 +114,14 @@ int32_t hashFromUIColor(const std::shared_ptr<void> &uiColor)

Color::Color(std::shared_ptr<void> uiColor)
{
UIColor *color = ((UIColor *)unwrapManagedObject(uiColor));
if (color && color.reactHash == 0) {
auto colorHash = hashFromUIColor(uiColor);
color.reactHash = colorHash;
}
uiColor_ = std::move(uiColor);
}

bool Color::operator==(const Color &other) const
{
return (!uiColor_ && !other.uiColor_) ||
(uiColor_ && other.uiColor_ &&
((UIColor *)unwrapManagedObject(getUIColor())).reactHash ==
((UIColor *)unwrapManagedObject(other.getUIColor())).reactHash);
[unwrapManagedObject(getUIColor()) isEqual:unwrapManagedObject(other.getUIColor())]);
}

bool Color::operator!=(const Color &other) const
Expand All @@ -227,17 +142,6 @@ int32_t hashFromUIColor(const std::shared_ptr<void> &uiColor)
return static_cast<float>(rgba[channelId]);
}

int32_t Color::getUIColorHash() const
{
return [(UIColor *)unwrapManagedObject(uiColor_) reactHash];
}

Color Color::createSemanticColor(std::vector<std::string> &semanticItems)
{
auto semanticColor = RCTPlatformColorFromSemanticItems(semanticItems);
return Color(wrapManagedObject(semanticColor));
}

} // namespace facebook::react

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ SharedColor parsePlatformColor(const ContextContainer &contextContainer, int32_t
auto items = (std::unordered_map<std::string, RawValue>)value;
if (items.find("semantic") != items.end() && items.at("semantic").hasType<std::vector<std::string>>()) {
auto semanticItems = (std::vector<std::string>)items.at("semantic");
return SharedColor(Color::createSemanticColor(semanticItems));
return {wrapManagedObject(RCTPlatformColorFromSemanticItems(semanticItems))};
} else if (
items.find("dynamic") != items.end() &&
items.at("dynamic").hasType<std::unordered_map<std::string, RawValue>>()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,9 @@
#pragma once

#import <UIKit/UIKit.h>
#import <react/renderer/graphics/HostPlatformColor.h>
#import <vector>

namespace facebook {
namespace react {
struct ColorComponents;
struct Color;
} // namespace react
} // namespace facebook

facebook::react::ColorComponents RCTPlatformColorComponentsFromSemanticItems(
std::vector<std::string>& semanticItems);
UIColor* RCTPlatformColorFromSemanticItems(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <react/renderer/graphics/HostPlatformColor.h>
#import <react/utils/ManagedObjectWrapper.h>

#include <string>
Expand Down

This file was deleted.

This file was deleted.

0 comments on commit 04afbd9

Please sign in to comment.