Skip to content

Commit

Permalink
Fix dropShadow not creating stacking context
Browse files Browse the repository at this point in the history
Summary:
Before `drop-shadow` was not creating a stacking context causing its children to get flattened and not receive the shadow effect.

This was due to incorrect parsing on C++. We didn't notice since we don't support `drop-shadow` on iOS and Android gets the parsed prop directly

Changelog: [Internal]

Reviewed By: NickGerleman, joevilches

Differential Revision: D61617699
  • Loading branch information
jorge-cab authored and facebook-github-bot committed Aug 22, 2024
1 parent 42dcfdd commit 1ac59ba
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -840,10 +840,12 @@ - (void)invalidateLayer
if (!_props->filter.empty()) {
float multiplicativeBrightness = 1;
for (const auto &primitive : _props->filter) {
if (primitive.type == FilterType::Brightness) {
multiplicativeBrightness *= primitive.amount;
} else if (primitive.type == FilterType::Opacity) {
self.layer.opacity *= primitive.amount;
if (std::holds_alternative<Float>(primitive.parameters)) {
if (primitive.type == FilterType::Brightness) {
multiplicativeBrightness *= std::get<Float>(primitive.parameters);
} else if (primitive.type == FilterType::Opacity) {
self.layer.opacity *= std::get<Float>(primitive.parameters);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ inline void fromRawValue(
result = boxShadows;
}
inline void fromRawValue(
const PropsParserContext& /*context*/,
const PropsParserContext& context,
const RawValue& value,
std::vector<FilterFunction>& result) {
react_native_expect(value.hasType<std::vector<RawValue>>());
Expand All @@ -1054,14 +1054,69 @@ inline void fromRawValue(
return;
}

auto rawFilterPrimitiveMap =
auto rawFilterFunction =
static_cast<std::unordered_map<std::string, RawValue>>(
rawFilterPrimitive);
FilterFunction filterFunction{};
try {
filterFunction.type =
filterTypeFromString(rawFilterPrimitiveMap.begin()->first);
filterFunction.amount = (float)rawFilterPrimitiveMap.begin()->second;
filterTypeFromString(rawFilterFunction.begin()->first);
if (filterFunction.type == FilterType::DropShadow) {
auto rawDropShadow =
static_cast<std::unordered_map<std::string, RawValue>>(
rawFilterFunction.begin()->second);
DropShadowParams dropShadowParams{};

auto offsetX = rawDropShadow.find("offsetX");
react_native_expect(offsetX != rawDropShadow.end());
if (offsetX == rawDropShadow.end()) {
result = {};
return;
}

react_native_expect(offsetX->second.hasType<Float>());
if (!offsetX->second.hasType<Float>()) {
result = {};
return;
}
dropShadowParams.offsetX = (Float)offsetX->second;

auto offsetY = rawDropShadow.find("offsetY");
react_native_expect(offsetY != rawDropShadow.end());
if (offsetY == rawDropShadow.end()) {
result = {};
return;
}
react_native_expect(offsetY->second.hasType<Float>());
if (!offsetY->second.hasType<Float>()) {
result = {};
return;
}
dropShadowParams.offsetY = (Float)offsetY->second;

auto standardDeviation = rawDropShadow.find("standardDeviation");
if (standardDeviation != rawDropShadow.end()) {
react_native_expect(standardDeviation->second.hasType<Float>());
if (!standardDeviation->second.hasType<Float>()) {
result = {};
return;
}
dropShadowParams.standardDeviation = (Float)standardDeviation->second;
}

auto color = rawDropShadow.find("color");
if (color != rawDropShadow.end()) {
fromRawValue(
context.contextContainer,
context.surfaceId,
color->second,
dropShadowParams.color);
}

filterFunction.parameters = dropShadowParams;
} else {
filterFunction.parameters = (float)rawFilterFunction.begin()->second;
}
filter.push_back(std::move(filterFunction));
} catch (const std::exception& e) {
LOG(ERROR) << "Could not parse FilterFunction: " << e.what();
Expand Down
15 changes: 13 additions & 2 deletions packages/react-native/ReactCommon/react/renderer/graphics/Filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

#pragma once

#include <react/renderer/graphics/Color.h>
#include <react/renderer/graphics/Float.h>

#include <string>
#include <string_view>
#include <variant>
#include <vector>

namespace facebook::react {
Expand All @@ -28,11 +30,20 @@ enum class FilterType {
DropShadow
};

struct DropShadowParams {
bool operator==(const DropShadowParams& other) const = default;

Float offsetX{};
Float offsetY{};
Float standardDeviation{};
SharedColor color{};
};

struct FilterFunction {
bool operator==(const FilterFunction& other) const = default;

FilterType type;
Float amount;
FilterType type{};
std::variant<Float, DropShadowParams> parameters{};
};

inline FilterType filterTypeFromString(std::string_view filterName) {
Expand Down

0 comments on commit 1ac59ba

Please sign in to comment.