Parse raw filter props (#44455)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44455

Title says it all. Right now this ignores drop-shadow as that will be implemented later. Some of this code will need to be adjusted as it is the one filter that takes multiple amounts. But I feel that can be amended later when we get there - after all the `amount` parsing code is just casting to a float at the moment, so we are not locking ourselves into anything.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D54640629

fbshipit-source-id: c8e1206ab46accab3c99614241b8bd9aa252e12c
This commit is contained in:
Joe Vilches
2024-05-08 13:39:09 -07:00
committed by Facebook GitHub Bot
parent 00f3867ac3
commit f340e6e575
4 changed files with 116 additions and 0 deletions
@@ -150,6 +150,14 @@ BaseViewProps::BaseViewProps(
"cursor",
sourceProps.cursor,
{})),
filter(
CoreFeatures::enablePropIteratorSetter ? sourceProps.filter
: convertRawProp(
context,
rawProps,
"experimental_filter",
sourceProps.filter,
{})),
transform(
CoreFeatures::enablePropIteratorSetter ? sourceProps.transform
: convertRawProp(
@@ -14,6 +14,7 @@
#include <react/renderer/core/Props.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/graphics/Color.h>
#include <react/renderer/graphics/Filter.h>
#include <react/renderer/graphics/Transform.h>
#include <optional>
@@ -54,6 +55,9 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {
Cursor cursor{};
// Filter
std::vector<FilterPrimitive> filter{};
// Transform
Transform transform{};
TransformOrigin transformOrigin{
@@ -15,6 +15,7 @@
#include <react/renderer/core/LayoutMetrics.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/RawProps.h>
#include <react/renderer/graphics/Filter.h>
#include <react/renderer/graphics/Transform.h>
#include <react/renderer/graphics/ValueUnit.h>
#include <stdlib.h>
@@ -761,6 +762,48 @@ inline void fromRawValue(
react_native_expect(false);
}
inline void fromRawValue(
const PropsParserContext& /*context*/,
const RawValue& value,
std::vector<FilterPrimitive>& result) {
react_native_expect(value.hasType<std::vector<RawValue>>());
if (!value.hasType<std::vector<RawValue>>()) {
result = {};
return;
}
std::vector<FilterPrimitive> filter{};
auto rawFilter = static_cast<std::vector<RawValue>>(value);
for (const auto& rawFilterPrimitive : rawFilter) {
bool isMap =
rawFilterPrimitive.hasType<std::unordered_map<std::string, RawValue>>();
react_native_expect(isMap);
if (!isMap) {
// If a filter is malformed then we should not apply any of them which
// is the web behavior.
result = {};
return;
}
auto rawFilterPrimitiveMap =
static_cast<std::unordered_map<std::string, RawValue>>(
rawFilterPrimitive);
FilterPrimitive filterPrimitive{};
try {
filterPrimitive.type =
filterTypeFromString(rawFilterPrimitiveMap.begin()->first);
filterPrimitive.amount = (float)rawFilterPrimitiveMap.begin()->second;
filter.push_back(filterPrimitive);
} catch (const std::exception& e) {
LOG(ERROR) << "Could not parse FilterPrimitive: " << e.what();
filter = {};
return;
}
}
result = filter;
}
template <size_t N>
inline std::string toString(const std::array<float, N> vec) {
std::string s;
@@ -0,0 +1,61 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/renderer/graphics/Float.h>
#include <string>
#include <string_view>
#include <vector>
namespace facebook::react {
enum class FilterType {
Blur,
Brightness,
Contrast,
Grayscale,
HueRotate,
Invert,
Opacity,
Saturate,
Sepia
};
struct FilterPrimitive {
bool operator==(const FilterPrimitive& other) const = default;
FilterType type;
Float amount;
};
inline FilterType filterTypeFromString(std::string_view filterName) {
if (filterName == "blur") {
return FilterType::Blur;
} else if (filterName == "brightness") {
return FilterType::Brightness;
} else if (filterName == "contrast") {
return FilterType::Contrast;
} else if (filterName == "grayscale") {
return FilterType::Grayscale;
} else if (filterName == "hueRotate") {
return FilterType::HueRotate;
} else if (filterName == "invert") {
return FilterType::Invert;
} else if (filterName == "opacity") {
return FilterType::Opacity;
} else if (filterName == "saturate") {
return FilterType::Saturate;
} else if (filterName == "sepia") {
return FilterType::Sepia;
} else {
throw std::invalid_argument(std::string(filterName));
}
}
} // namespace facebook::react