react-native-nitro-image-pipeline 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -6
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/HybridNitroImagePipeline.kt +34 -2
- package/android/src/main/java/com/margelo/nitro/nitroimagepipeline/transform/ResizeTransformation.kt +59 -0
- package/ios/HybridNitroImagePipeline.swift +23 -2
- package/ios/RoundedCornersProcessor.swift +121 -0
- package/lib/commonjs/index.js +25 -2
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +25 -2
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +18 -6
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts +46 -1
- package/lib/typescript/src/specs/nitro-image-toolkit.nitro.d.ts.map +1 -1
- package/nitrogen/generated/android/NitroImagePipeline+autolinking.cmake +1 -0
- package/nitrogen/generated/android/c++/JCornerRadii.hpp +69 -0
- package/nitrogen/generated/android/c++/JHybridNitroImagePipelineSpec.cpp +10 -0
- package/nitrogen/generated/android/c++/JOptions.hpp +15 -5
- package/nitrogen/generated/android/c++/JResizeOptions.hpp +61 -0
- package/nitrogen/generated/android/c++/JVariant_Double_CornerRadii.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_Double_CornerRadii.hpp +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/CornerRadii.kt +66 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/Options.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/ResizeOptions.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroimagepipeline/Variant_Double_CornerRadii.kt +62 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Bridge.hpp +66 -0
- package/nitrogen/generated/ios/NitroImagePipeline-Swift-Cxx-Umbrella.hpp +7 -0
- package/nitrogen/generated/ios/c++/HybridNitroImagePipelineSpecSwift.hpp +7 -0
- package/nitrogen/generated/ios/swift/CornerRadii.swift +96 -0
- package/nitrogen/generated/ios/swift/Options.swift +38 -8
- package/nitrogen/generated/ios/swift/ResizeOptions.swift +34 -0
- package/nitrogen/generated/ios/swift/Variant_Double_CornerRadii.swift +30 -0
- package/nitrogen/generated/shared/c++/CornerRadii.hpp +95 -0
- package/nitrogen/generated/shared/c++/Options.hpp +16 -5
- package/nitrogen/generated/shared/c++/ResizeOptions.hpp +87 -0
- package/package.json +1 -1
- package/src/index.ts +52 -6
- package/src/specs/nitro-image-toolkit.nitro.ts +49 -1
|
@@ -18,6 +18,10 @@ namespace margelo::nitro::image { class HybridImageSpec; }
|
|
|
18
18
|
namespace margelo::nitro::nitroimagepipeline { struct Options; }
|
|
19
19
|
// Forward declaration of `CacheOption` to properly resolve imports.
|
|
20
20
|
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
21
|
+
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
22
|
+
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
23
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
24
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
21
25
|
|
|
22
26
|
#include <memory>
|
|
23
27
|
#include <NitroImage/HybridImageSpec.hpp>
|
|
@@ -26,6 +30,9 @@ namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
|
26
30
|
#include "Options.hpp"
|
|
27
31
|
#include <optional>
|
|
28
32
|
#include "CacheOption.hpp"
|
|
33
|
+
#include "CornerRadii.hpp"
|
|
34
|
+
#include <variant>
|
|
35
|
+
#include "ResizeOptions.hpp"
|
|
29
36
|
#include <vector>
|
|
30
37
|
|
|
31
38
|
#include "NitroImagePipeline-Swift-Cxx-Umbrella.hpp"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// CornerRadii.swift
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
import NitroModules
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Represents an instance of `CornerRadii`, backed by a C++ struct.
|
|
12
|
+
*/
|
|
13
|
+
public typealias CornerRadii = margelo.nitro.nitroimagepipeline.CornerRadii
|
|
14
|
+
|
|
15
|
+
public extension CornerRadii {
|
|
16
|
+
private typealias bridge = margelo.nitro.nitroimagepipeline.bridge.swift
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a new instance of `CornerRadii`.
|
|
20
|
+
*/
|
|
21
|
+
init(topLeft: Double?, topRight: Double?, bottomLeft: Double?, bottomRight: Double?) {
|
|
22
|
+
self.init({ () -> bridge.std__optional_double_ in
|
|
23
|
+
if let __unwrappedValue = topLeft {
|
|
24
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
25
|
+
} else {
|
|
26
|
+
return .init()
|
|
27
|
+
}
|
|
28
|
+
}(), { () -> bridge.std__optional_double_ in
|
|
29
|
+
if let __unwrappedValue = topRight {
|
|
30
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
31
|
+
} else {
|
|
32
|
+
return .init()
|
|
33
|
+
}
|
|
34
|
+
}(), { () -> bridge.std__optional_double_ in
|
|
35
|
+
if let __unwrappedValue = bottomLeft {
|
|
36
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
37
|
+
} else {
|
|
38
|
+
return .init()
|
|
39
|
+
}
|
|
40
|
+
}(), { () -> bridge.std__optional_double_ in
|
|
41
|
+
if let __unwrappedValue = bottomRight {
|
|
42
|
+
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
43
|
+
} else {
|
|
44
|
+
return .init()
|
|
45
|
+
}
|
|
46
|
+
}())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@inline(__always)
|
|
50
|
+
var topLeft: Double? {
|
|
51
|
+
return { () -> Double? in
|
|
52
|
+
if bridge.has_value_std__optional_double_(self.__topLeft) {
|
|
53
|
+
let __unwrapped = bridge.get_std__optional_double_(self.__topLeft)
|
|
54
|
+
return __unwrapped
|
|
55
|
+
} else {
|
|
56
|
+
return nil
|
|
57
|
+
}
|
|
58
|
+
}()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@inline(__always)
|
|
62
|
+
var topRight: Double? {
|
|
63
|
+
return { () -> Double? in
|
|
64
|
+
if bridge.has_value_std__optional_double_(self.__topRight) {
|
|
65
|
+
let __unwrapped = bridge.get_std__optional_double_(self.__topRight)
|
|
66
|
+
return __unwrapped
|
|
67
|
+
} else {
|
|
68
|
+
return nil
|
|
69
|
+
}
|
|
70
|
+
}()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@inline(__always)
|
|
74
|
+
var bottomLeft: Double? {
|
|
75
|
+
return { () -> Double? in
|
|
76
|
+
if bridge.has_value_std__optional_double_(self.__bottomLeft) {
|
|
77
|
+
let __unwrapped = bridge.get_std__optional_double_(self.__bottomLeft)
|
|
78
|
+
return __unwrapped
|
|
79
|
+
} else {
|
|
80
|
+
return nil
|
|
81
|
+
}
|
|
82
|
+
}()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@inline(__always)
|
|
86
|
+
var bottomRight: Double? {
|
|
87
|
+
return { () -> Double? in
|
|
88
|
+
if bridge.has_value_std__optional_double_(self.__bottomRight) {
|
|
89
|
+
let __unwrapped = bridge.get_std__optional_double_(self.__bottomRight)
|
|
90
|
+
return __unwrapped
|
|
91
|
+
} else {
|
|
92
|
+
return nil
|
|
93
|
+
}
|
|
94
|
+
}()
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -18,7 +18,7 @@ public extension Options {
|
|
|
18
18
|
/**
|
|
19
19
|
* Create a new instance of `Options`.
|
|
20
20
|
*/
|
|
21
|
-
init(blur: Double?, cache: CacheOption?, cornerRadius:
|
|
21
|
+
init(blur: Double?, cache: CacheOption?, cornerRadius: Variant_Double_CornerRadii?, resize: ResizeOptions?) {
|
|
22
22
|
self.init({ () -> bridge.std__optional_double_ in
|
|
23
23
|
if let __unwrappedValue = blur {
|
|
24
24
|
return bridge.create_std__optional_double_(__unwrappedValue)
|
|
@@ -31,9 +31,22 @@ public extension Options {
|
|
|
31
31
|
} else {
|
|
32
32
|
return .init()
|
|
33
33
|
}
|
|
34
|
-
}(), { () -> bridge.
|
|
34
|
+
}(), { () -> bridge.std__optional_std__variant_double__CornerRadii__ in
|
|
35
35
|
if let __unwrappedValue = cornerRadius {
|
|
36
|
-
return bridge.
|
|
36
|
+
return bridge.create_std__optional_std__variant_double__CornerRadii__({ () -> bridge.std__variant_double__CornerRadii_ in
|
|
37
|
+
switch __unwrappedValue {
|
|
38
|
+
case .first(let __value):
|
|
39
|
+
return bridge.create_std__variant_double__CornerRadii_(__value)
|
|
40
|
+
case .second(let __value):
|
|
41
|
+
return bridge.create_std__variant_double__CornerRadii_(__value)
|
|
42
|
+
}
|
|
43
|
+
}().variant)
|
|
44
|
+
} else {
|
|
45
|
+
return .init()
|
|
46
|
+
}
|
|
47
|
+
}(), { () -> bridge.std__optional_ResizeOptions_ in
|
|
48
|
+
if let __unwrappedValue = resize {
|
|
49
|
+
return bridge.create_std__optional_ResizeOptions_(__unwrappedValue)
|
|
37
50
|
} else {
|
|
38
51
|
return .init()
|
|
39
52
|
}
|
|
@@ -58,14 +71,31 @@ public extension Options {
|
|
|
58
71
|
}
|
|
59
72
|
|
|
60
73
|
@inline(__always)
|
|
61
|
-
var cornerRadius:
|
|
62
|
-
return { () ->
|
|
63
|
-
if bridge.
|
|
64
|
-
let __unwrapped = bridge.
|
|
65
|
-
return
|
|
74
|
+
var cornerRadius: Variant_Double_CornerRadii? {
|
|
75
|
+
return { () -> Variant_Double_CornerRadii? in
|
|
76
|
+
if bridge.has_value_std__optional_std__variant_double__CornerRadii__(self.__cornerRadius) {
|
|
77
|
+
let __unwrapped = bridge.get_std__optional_std__variant_double__CornerRadii__(self.__cornerRadius)
|
|
78
|
+
return { () -> Variant_Double_CornerRadii in
|
|
79
|
+
let __variant = bridge.std__variant_double__CornerRadii_(__unwrapped)
|
|
80
|
+
switch __variant.index() {
|
|
81
|
+
case 0:
|
|
82
|
+
let __actual = __variant.get_0()
|
|
83
|
+
return .first(__actual)
|
|
84
|
+
case 1:
|
|
85
|
+
let __actual = __variant.get_1()
|
|
86
|
+
return .second(__actual)
|
|
87
|
+
default:
|
|
88
|
+
fatalError("Variant can never have index \(__variant.index())!")
|
|
89
|
+
}
|
|
90
|
+
}()
|
|
66
91
|
} else {
|
|
67
92
|
return nil
|
|
68
93
|
}
|
|
69
94
|
}()
|
|
70
95
|
}
|
|
96
|
+
|
|
97
|
+
@inline(__always)
|
|
98
|
+
var resize: ResizeOptions? {
|
|
99
|
+
return self.__resize.value
|
|
100
|
+
}
|
|
71
101
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ResizeOptions.swift
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
import NitroModules
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Represents an instance of `ResizeOptions`, backed by a C++ struct.
|
|
12
|
+
*/
|
|
13
|
+
public typealias ResizeOptions = margelo.nitro.nitroimagepipeline.ResizeOptions
|
|
14
|
+
|
|
15
|
+
public extension ResizeOptions {
|
|
16
|
+
private typealias bridge = margelo.nitro.nitroimagepipeline.bridge.swift
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create a new instance of `ResizeOptions`.
|
|
20
|
+
*/
|
|
21
|
+
init(width: Double, height: Double) {
|
|
22
|
+
self.init(width, height)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@inline(__always)
|
|
26
|
+
var width: Double {
|
|
27
|
+
return self.__width
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@inline(__always)
|
|
31
|
+
var height: Double {
|
|
32
|
+
return self.__height
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Variant_Double_CornerRadii.swift
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* An Swift enum with associated values representing a Variant/Union type.
|
|
12
|
+
* JS type: `number | struct`
|
|
13
|
+
*/
|
|
14
|
+
@frozen
|
|
15
|
+
public indirect enum Variant_Double_CornerRadii {
|
|
16
|
+
case first(Double)
|
|
17
|
+
case second(CornerRadii)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public extension Variant_Double_CornerRadii {
|
|
21
|
+
func asType<T>(_ type: T.Type = T.self) -> T? {
|
|
22
|
+
switch self {
|
|
23
|
+
case .first(let value): return value as? T
|
|
24
|
+
case .second(let value): return value as? T
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
func isType<T>(_ type: T.Type = T.self) -> Bool {
|
|
28
|
+
return self.asType(type) != nil
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// CornerRadii.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
#include <optional>
|
|
34
|
+
|
|
35
|
+
namespace margelo::nitro::nitroimagepipeline {
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A struct which can be represented as a JavaScript object (CornerRadii).
|
|
39
|
+
*/
|
|
40
|
+
struct CornerRadii final {
|
|
41
|
+
public:
|
|
42
|
+
std::optional<double> topLeft SWIFT_PRIVATE;
|
|
43
|
+
std::optional<double> topRight SWIFT_PRIVATE;
|
|
44
|
+
std::optional<double> bottomLeft SWIFT_PRIVATE;
|
|
45
|
+
std::optional<double> bottomRight SWIFT_PRIVATE;
|
|
46
|
+
|
|
47
|
+
public:
|
|
48
|
+
CornerRadii() = default;
|
|
49
|
+
explicit CornerRadii(std::optional<double> topLeft, std::optional<double> topRight, std::optional<double> bottomLeft, std::optional<double> bottomRight): topLeft(topLeft), topRight(topRight), bottomLeft(bottomLeft), bottomRight(bottomRight) {}
|
|
50
|
+
|
|
51
|
+
public:
|
|
52
|
+
friend bool operator==(const CornerRadii& lhs, const CornerRadii& rhs) = default;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
} // namespace margelo::nitro::nitroimagepipeline
|
|
56
|
+
|
|
57
|
+
namespace margelo::nitro {
|
|
58
|
+
|
|
59
|
+
// C++ CornerRadii <> JS CornerRadii (object)
|
|
60
|
+
template <>
|
|
61
|
+
struct JSIConverter<margelo::nitro::nitroimagepipeline::CornerRadii> final {
|
|
62
|
+
static inline margelo::nitro::nitroimagepipeline::CornerRadii fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
63
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
64
|
+
return margelo::nitro::nitroimagepipeline::CornerRadii(
|
|
65
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topLeft"))),
|
|
66
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topRight"))),
|
|
67
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomLeft"))),
|
|
68
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomRight")))
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::CornerRadii& arg) {
|
|
72
|
+
jsi::Object obj(runtime);
|
|
73
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "topLeft"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.topLeft));
|
|
74
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "topRight"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.topRight));
|
|
75
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "bottomLeft"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.bottomLeft));
|
|
76
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "bottomRight"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.bottomRight));
|
|
77
|
+
return obj;
|
|
78
|
+
}
|
|
79
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
80
|
+
if (!value.isObject()) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
jsi::Object obj = value.getObject(runtime);
|
|
84
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topLeft")))) return false;
|
|
88
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "topRight")))) return false;
|
|
89
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomLeft")))) return false;
|
|
90
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "bottomRight")))) return false;
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
} // namespace margelo::nitro
|
|
@@ -30,9 +30,16 @@
|
|
|
30
30
|
|
|
31
31
|
// Forward declaration of `CacheOption` to properly resolve imports.
|
|
32
32
|
namespace margelo::nitro::nitroimagepipeline { enum class CacheOption; }
|
|
33
|
+
// Forward declaration of `CornerRadii` to properly resolve imports.
|
|
34
|
+
namespace margelo::nitro::nitroimagepipeline { struct CornerRadii; }
|
|
35
|
+
// Forward declaration of `ResizeOptions` to properly resolve imports.
|
|
36
|
+
namespace margelo::nitro::nitroimagepipeline { struct ResizeOptions; }
|
|
33
37
|
|
|
34
38
|
#include <optional>
|
|
35
39
|
#include "CacheOption.hpp"
|
|
40
|
+
#include "CornerRadii.hpp"
|
|
41
|
+
#include <variant>
|
|
42
|
+
#include "ResizeOptions.hpp"
|
|
36
43
|
|
|
37
44
|
namespace margelo::nitro::nitroimagepipeline {
|
|
38
45
|
|
|
@@ -43,11 +50,12 @@ namespace margelo::nitro::nitroimagepipeline {
|
|
|
43
50
|
public:
|
|
44
51
|
std::optional<double> blur SWIFT_PRIVATE;
|
|
45
52
|
std::optional<CacheOption> cache SWIFT_PRIVATE;
|
|
46
|
-
std::optional<double
|
|
53
|
+
std::optional<std::variant<double, CornerRadii>> cornerRadius SWIFT_PRIVATE;
|
|
54
|
+
std::optional<ResizeOptions> resize SWIFT_PRIVATE;
|
|
47
55
|
|
|
48
56
|
public:
|
|
49
57
|
Options() = default;
|
|
50
|
-
explicit Options(std::optional<double> blur, std::optional<CacheOption> cache, std::optional<double>
|
|
58
|
+
explicit Options(std::optional<double> blur, std::optional<CacheOption> cache, std::optional<std::variant<double, CornerRadii>> cornerRadius, std::optional<ResizeOptions> resize): blur(blur), cache(cache), cornerRadius(cornerRadius), resize(resize) {}
|
|
51
59
|
|
|
52
60
|
public:
|
|
53
61
|
friend bool operator==(const Options& lhs, const Options& rhs) = default;
|
|
@@ -65,14 +73,16 @@ namespace margelo::nitro {
|
|
|
65
73
|
return margelo::nitro::nitroimagepipeline::Options(
|
|
66
74
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur"))),
|
|
67
75
|
JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache"))),
|
|
68
|
-
JSIConverter<std::optional<double
|
|
76
|
+
JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"))),
|
|
77
|
+
JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "resize")))
|
|
69
78
|
);
|
|
70
79
|
}
|
|
71
80
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::Options& arg) {
|
|
72
81
|
jsi::Object obj(runtime);
|
|
73
82
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "blur"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.blur));
|
|
74
83
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cache"), JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::toJSI(runtime, arg.cache));
|
|
75
|
-
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"), JSIConverter<std::optional<double
|
|
84
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius"), JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::toJSI(runtime, arg.cornerRadius));
|
|
85
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "resize"), JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::toJSI(runtime, arg.resize));
|
|
76
86
|
return obj;
|
|
77
87
|
}
|
|
78
88
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -85,7 +95,8 @@ namespace margelo::nitro {
|
|
|
85
95
|
}
|
|
86
96
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "blur")))) return false;
|
|
87
97
|
if (!JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::CacheOption>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cache")))) return false;
|
|
88
|
-
if (!JSIConverter<std::optional<double
|
|
98
|
+
if (!JSIConverter<std::optional<std::variant<double, margelo::nitro::nitroimagepipeline::CornerRadii>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "cornerRadius")))) return false;
|
|
99
|
+
if (!JSIConverter<std::optional<margelo::nitro::nitroimagepipeline::ResizeOptions>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "resize")))) return false;
|
|
89
100
|
return true;
|
|
90
101
|
}
|
|
91
102
|
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ResizeOptions.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
namespace margelo::nitro::nitroimagepipeline {
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A struct which can be represented as a JavaScript object (ResizeOptions).
|
|
39
|
+
*/
|
|
40
|
+
struct ResizeOptions final {
|
|
41
|
+
public:
|
|
42
|
+
double width SWIFT_PRIVATE;
|
|
43
|
+
double height SWIFT_PRIVATE;
|
|
44
|
+
|
|
45
|
+
public:
|
|
46
|
+
ResizeOptions() = default;
|
|
47
|
+
explicit ResizeOptions(double width, double height): width(width), height(height) {}
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
friend bool operator==(const ResizeOptions& lhs, const ResizeOptions& rhs) = default;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
} // namespace margelo::nitro::nitroimagepipeline
|
|
54
|
+
|
|
55
|
+
namespace margelo::nitro {
|
|
56
|
+
|
|
57
|
+
// C++ ResizeOptions <> JS ResizeOptions (object)
|
|
58
|
+
template <>
|
|
59
|
+
struct JSIConverter<margelo::nitro::nitroimagepipeline::ResizeOptions> final {
|
|
60
|
+
static inline margelo::nitro::nitroimagepipeline::ResizeOptions fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
61
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
62
|
+
return margelo::nitro::nitroimagepipeline::ResizeOptions(
|
|
63
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))),
|
|
64
|
+
JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroimagepipeline::ResizeOptions& arg) {
|
|
68
|
+
jsi::Object obj(runtime);
|
|
69
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter<double>::toJSI(runtime, arg.width));
|
|
70
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter<double>::toJSI(runtime, arg.height));
|
|
71
|
+
return obj;
|
|
72
|
+
}
|
|
73
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
74
|
+
if (!value.isObject()) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
jsi::Object obj = value.getObject(runtime);
|
|
78
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false;
|
|
82
|
+
if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false;
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-image-pipeline",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "High-performance image loading, caching, and processing for React Native, built with Nitro Modules",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/module/index.js",
|
package/src/index.ts
CHANGED
|
@@ -4,11 +4,13 @@ import { NitroModules } from 'react-native-nitro-modules';
|
|
|
4
4
|
|
|
5
5
|
import type {
|
|
6
6
|
CacheOption,
|
|
7
|
+
CornerRadii,
|
|
7
8
|
NitroImagePipeline as NitroImagePipelineSpec,
|
|
8
9
|
Options,
|
|
10
|
+
ResizeOptions,
|
|
9
11
|
} from './specs/nitro-image-toolkit.nitro';
|
|
10
12
|
|
|
11
|
-
export type { CacheOption, Options };
|
|
13
|
+
export type { CacheOption, CornerRadii, Options, ResizeOptions };
|
|
12
14
|
|
|
13
15
|
export const NitroImagePipeline =
|
|
14
16
|
NitroModules.createHybridObject<NitroImagePipelineSpec>('NitroImagePipeline');
|
|
@@ -42,16 +44,29 @@ export function useImage({
|
|
|
42
44
|
url,
|
|
43
45
|
blur = 0,
|
|
44
46
|
cornerRadius = 0,
|
|
47
|
+
resize,
|
|
45
48
|
cache,
|
|
46
49
|
}: {
|
|
47
50
|
url: string;
|
|
48
51
|
/**
|
|
49
52
|
* Gaussian blur strength, as the standard deviation (sigma) of the blur in
|
|
50
|
-
* source-image pixels
|
|
51
|
-
* React Native's `blurRadius`.
|
|
53
|
+
* source-image pixels (of the resized bitmap when `resize` is set). Matches
|
|
54
|
+
* across iOS and Android; roughly half of React Native's `blurRadius`.
|
|
52
55
|
*/
|
|
53
56
|
blur?: number;
|
|
54
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Corner radius in pixels of the loaded bitmap. Pass a single number for
|
|
59
|
+
* uniform rounding, or per-corner radii (inline object literals are fine —
|
|
60
|
+
* the hook compares the radii by value, not identity). Pair with `resize`
|
|
61
|
+
* so the radii apply at the size you display instead of the source size.
|
|
62
|
+
*/
|
|
63
|
+
cornerRadius?: number | CornerRadii;
|
|
64
|
+
/**
|
|
65
|
+
* Resize the bitmap to exactly this size in pixels (aspect-fill,
|
|
66
|
+
* center-crop) before blur/rounding. Typically your display size in points
|
|
67
|
+
* multiplied by `PixelRatio.get()`. Inline object literals are fine.
|
|
68
|
+
*/
|
|
69
|
+
resize?: ResizeOptions;
|
|
55
70
|
cache?: CacheOption;
|
|
56
71
|
}): Result {
|
|
57
72
|
const [image, setImage] = useState<Result>({
|
|
@@ -60,6 +75,19 @@ export function useImage({
|
|
|
60
75
|
});
|
|
61
76
|
const loadedUrlRef = useRef(url);
|
|
62
77
|
|
|
78
|
+
// Split the option into primitives so an inline `{ topLeft: 24, ... }`
|
|
79
|
+
// literal (new identity every render) doesn't re-trigger the effect.
|
|
80
|
+
const isUniformRadius = typeof cornerRadius === 'number';
|
|
81
|
+
const uniformRadius = isUniformRadius ? cornerRadius : 0;
|
|
82
|
+
const {
|
|
83
|
+
topLeft = 0,
|
|
84
|
+
topRight = 0,
|
|
85
|
+
bottomLeft = 0,
|
|
86
|
+
bottomRight = 0,
|
|
87
|
+
} = isUniformRadius ? {} : cornerRadius;
|
|
88
|
+
const resizeWidth = resize?.width ?? 0;
|
|
89
|
+
const resizeHeight = resize?.height ?? 0;
|
|
90
|
+
|
|
63
91
|
useEffect(() => {
|
|
64
92
|
let cancelled = false;
|
|
65
93
|
// Only reset to the loading state when the URL changes; for same-URL
|
|
@@ -74,7 +102,13 @@ export function useImage({
|
|
|
74
102
|
try {
|
|
75
103
|
const result = await NitroImagePipeline.loadImage(url, {
|
|
76
104
|
blur,
|
|
77
|
-
cornerRadius
|
|
105
|
+
cornerRadius: isUniformRadius
|
|
106
|
+
? uniformRadius
|
|
107
|
+
: { topLeft, topRight, bottomLeft, bottomRight },
|
|
108
|
+
resize:
|
|
109
|
+
resizeWidth > 0 && resizeHeight > 0
|
|
110
|
+
? { width: resizeWidth, height: resizeHeight }
|
|
111
|
+
: undefined,
|
|
78
112
|
cache,
|
|
79
113
|
});
|
|
80
114
|
|
|
@@ -92,7 +126,19 @@ export function useImage({
|
|
|
92
126
|
return () => {
|
|
93
127
|
cancelled = true;
|
|
94
128
|
};
|
|
95
|
-
}, [
|
|
129
|
+
}, [
|
|
130
|
+
url,
|
|
131
|
+
blur,
|
|
132
|
+
isUniformRadius,
|
|
133
|
+
uniformRadius,
|
|
134
|
+
topLeft,
|
|
135
|
+
topRight,
|
|
136
|
+
bottomLeft,
|
|
137
|
+
bottomRight,
|
|
138
|
+
resizeWidth,
|
|
139
|
+
resizeHeight,
|
|
140
|
+
cache,
|
|
141
|
+
]);
|
|
96
142
|
|
|
97
143
|
return image;
|
|
98
144
|
}
|
|
@@ -2,19 +2,67 @@ import type { Image } from 'react-native-nitro-image';
|
|
|
2
2
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
3
3
|
|
|
4
4
|
export type CacheOption = 'memory' | 'disk' | 'none';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Independent corner radii, in pixels of the loaded bitmap (see
|
|
8
|
+
* {@linkcode Options.cornerRadius}). Omitted corners stay square.
|
|
9
|
+
*/
|
|
10
|
+
export interface CornerRadii {
|
|
11
|
+
topLeft?: number;
|
|
12
|
+
topRight?: number;
|
|
13
|
+
bottomLeft?: number;
|
|
14
|
+
bottomRight?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Target bitmap size in pixels. The image is scaled to fill this size and
|
|
19
|
+
* center-cropped (like CSS `object-fit: cover`), upscaling if needed, so the
|
|
20
|
+
* result is exactly `width` × `height` pixels.
|
|
21
|
+
*/
|
|
22
|
+
export interface ResizeOptions {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
5
27
|
export type Options = {
|
|
6
28
|
/**
|
|
7
29
|
* Gaussian blur strength, given as the standard deviation (sigma) of the
|
|
8
30
|
* blur in **source-image pixels**. The same value on the same source image
|
|
9
31
|
* produces the same result on iOS and Android.
|
|
10
32
|
*
|
|
33
|
+
* When {@linkcode resize} is set, the blur runs after resizing, so sigma is
|
|
34
|
+
* in pixels of the resized bitmap instead.
|
|
35
|
+
*
|
|
11
36
|
* React Native's `<Image blurRadius={n} />` is roughly `blur: n / 2`.
|
|
12
37
|
*
|
|
13
38
|
* @default 0 (no blur)
|
|
14
39
|
*/
|
|
15
40
|
blur?: number;
|
|
16
41
|
cache?: CacheOption;
|
|
17
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Corner radius baked into the loaded bitmap, in **pixels of that bitmap**.
|
|
44
|
+
* Pass a single number to round all four corners uniformly, or a
|
|
45
|
+
* {@linkcode CornerRadii} object to round each corner independently (e.g. a
|
|
46
|
+
* "ticket" shape with larger bottom corners).
|
|
47
|
+
*
|
|
48
|
+
* Without {@linkcode resize} the radius applies to the full-resolution
|
|
49
|
+
* source image, so on a large photo displayed small the rounding shrinks
|
|
50
|
+
* along with it. To get corners sized for your layout, pass `resize` with
|
|
51
|
+
* your display size in pixels (points × screen scale) — the radii then
|
|
52
|
+
* apply to that final bitmap, 1:1 with what you see.
|
|
53
|
+
*
|
|
54
|
+
* @default 0 (square corners)
|
|
55
|
+
*/
|
|
56
|
+
cornerRadius?: number | CornerRadii;
|
|
57
|
+
/**
|
|
58
|
+
* Resize the image to exactly this size in pixels (aspect-fill,
|
|
59
|
+
* center-crop) before `blur` and `cornerRadius` are applied. Besides making
|
|
60
|
+
* `cornerRadius` predictable, this avoids decoding and processing
|
|
61
|
+
* full-resolution bitmaps you only display small.
|
|
62
|
+
*
|
|
63
|
+
* @default undefined (keep the source size)
|
|
64
|
+
*/
|
|
65
|
+
resize?: ResizeOptions;
|
|
18
66
|
};
|
|
19
67
|
|
|
20
68
|
export interface NitroImagePipeline extends HybridObject<{
|