Skip to content

Commit

Permalink
Parse raw filter props (#44455)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #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
  • Loading branch information
joevilches authored and facebook-github-bot committed May 8, 2024
1 parent 00f3867 commit f340e6e
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -54,6 +55,9 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {

Cursor cursor{};

// Filter
std::vector<FilterPrimitive> filter{};

// Transform
Transform transform{};
TransformOrigin transformOrigin{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down
61 changes: 61 additions & 0 deletions packages/react-native/ReactCommon/react/renderer/graphics/Filter.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit f340e6e

Please sign in to comment.