diff --git a/ink/brush/internal/jni/BUILD.bazel b/ink/brush/internal/jni/BUILD.bazel index 1d3cfa4d..7e41e8a2 100644 --- a/ink/brush/internal/jni/BUILD.bazel +++ b/ink/brush/internal/jni/BUILD.bazel @@ -23,6 +23,7 @@ cc_library( tags = ["keep_dep"], deps = [ ":brush_behavior_jni", + ":brush_behavior_node_jni", ":brush_coat_jni", ":brush_family_jni", ":brush_jni", @@ -42,6 +43,7 @@ filegroup( cc_library( name = "cinterop", deps = [ + ":brush_behavior_node_native", ":easing_function_native", ], ) @@ -91,12 +93,46 @@ cc_library( alwayslink = 1, ) +cc_library( + name = "brush_behavior_node_jni", + srcs = ["brush_behavior_node_jni.cc"], + tags = ["keep_dep"], + deps = [ + ":brush_behavior_node_native", + ":brush_native_helper", + "//ink/brush", + "//ink/brush:brush_behavior", + "//ink/jni/internal:jni_defines", + "//ink/jni/internal:jni_string_util", + "//ink/jni/internal:status_jni_helper", + "//ink/types:duration", + "@com_google_absl//absl/log:absl_check", + "@com_google_absl//absl/status", + ] + select({ + "@platforms//os:android": [], + "//conditions:default": [ + "@rules_jni//jni", + ], + }), + alwayslink = 1, +) + +cc_library( + name = "brush_behavior_node_native", + srcs = ["brush_behavior_node_native.cc"], + hdrs = ["brush_behavior_node_native.h"], + deps = [ + ":brush_native_helper", + "//ink/brush:brush_behavior", + "@com_google_absl//absl/status", + ], +) + cc_library( name = "brush_tip_jni", srcs = ["brush_tip_jni.cc"], tags = ["keep_dep"], deps = [ - ":brush_behavior_jni", ":brush_native_helper", "//ink/brush", "//ink/brush:brush_behavior", @@ -178,7 +214,6 @@ cc_library( srcs = ["stock_brushes_jni.cc"], tags = ["keep_dep"], deps = [ - ":brush_coat_jni", ":brush_native_helper", "//ink/brush", "//ink/brush:brush_coat", diff --git a/ink/brush/internal/jni/brush_behavior_jni.cc b/ink/brush/internal/jni/brush_behavior_jni.cc index d1defa0b..55a9195c 100644 --- a/ink/brush/internal/jni/brush_behavior_jni.cc +++ b/ink/brush/internal/jni/brush_behavior_jni.cc @@ -14,7 +14,6 @@ #include -#include #include #include #include @@ -31,26 +30,15 @@ namespace { using ::ink::BrushBehavior; -using ::ink::brush_internal::ValidateBrushBehaviorNode; using ::ink::brush_internal::ValidateBrushBehaviorTopLevel; using ::ink::jni::JStringToStdString; using ::ink::jni::ThrowExceptionFromStatus; using ::ink::native::CastToBrushBehavior; using ::ink::native::CastToBrushBehaviorNode; -using ::ink::native::CastToEasingFunction; using ::ink::native::DeleteNativeBrushBehavior; -using ::ink::native::DeleteNativeBrushBehaviorNode; using ::ink::native::NewNativeBrushBehavior; using ::ink::native::NewNativeBrushBehaviorNode; -jlong ValidateAndHoistNodeOrThrow(BrushBehavior::Node node, JNIEnv* env) { - if (absl::Status status = ValidateBrushBehaviorNode(node); !status.ok()) { - ThrowExceptionFromStatus(env, status); - return 0; - } - return NewNativeBrushBehaviorNode(std::move(node)); -} - static constexpr int kSourceNode = 0; static constexpr int kConstantNode = 1; static constexpr int kNoiseNode = 2; @@ -105,153 +93,8 @@ JNI_METHOD(brush, BrushBehaviorNative, jint, getNodeCount) return CastToBrushBehavior(native_pointer).nodes.size(); } -JNI_METHOD(brush, BrushBehaviorNative, jstring, getDeveloperComment) -(JNIEnv* env, jobject object, jlong native_pointer) { - const BrushBehavior& brush_behavior = CastToBrushBehavior(native_pointer); - return env->NewStringUTF(brush_behavior.developer_comment.c_str()); -} - -JNI_METHOD(brush, BrushBehaviorNative, jlong, newCopyOfNode) +JNI_METHOD(brush, BrushBehaviorNative, jint, getNodeTypeInt) (JNIEnv* env, jobject thiz, jlong native_pointer, jint index) { - return NewNativeBrushBehaviorNode( - CastToBrushBehavior(native_pointer).nodes[index]); -} - -// Functions for dealing with BrushBehavior::Nodes. Note that on the C++ side, -// BrushBehavior::Node is a variant, so all of the native pointers are pointers -// to the same type (the variant BrushBehavior::Node). - -JNI_METHOD(brush_behavior, SourceNodeNative, jlong, createSource) -(JNIEnv* env, jobject thiz, jint source, jfloat source_value_start, - jfloat source_value_end, jint source_out_of_range_behavior) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::SourceNode{ - .source = static_cast(source), - .source_out_of_range_behavior = - static_cast( - source_out_of_range_behavior), - .source_value_range = {source_value_start, source_value_end}, - }, - env); -} - -JNI_METHOD(brush_behavior, ConstantNodeNative, jlong, createConstant) -(JNIEnv* env, jobject thiz, jfloat value) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::ConstantNode{.value = value}, env); -} - -JNI_METHOD(brush_behavior, NoiseNodeNative, jlong, createNoise) -(JNIEnv* env, jobject thiz, jint seed, jint vary_over, jfloat base_period) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::NoiseNode{ - .seed = static_cast(seed), - .vary_over = static_cast(vary_over), - .base_period = base_period, - }, - env); -} - -JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jlong, - createToolTypeFilter) -(JNIEnv* env, jobject thiz, jboolean mouse_enabled, jboolean touch_enabled, - jboolean stylus_enabled, jboolean unknown_enabled) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::ToolTypeFilterNode{ - .enabled_tool_types = {.unknown = unknown_enabled ? true : false, - .mouse = mouse_enabled ? true : false, - .touch = touch_enabled ? true : false, - .stylus = stylus_enabled ? true : false}, - }, - env); -} - -JNI_METHOD(brush_behavior, DampingNodeNative, jlong, createDamping) -(JNIEnv* env, jobject thiz, jint damping_source, jfloat damping_gap) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::DampingNode{ - .damping_source = - static_cast(damping_source), - .damping_gap = damping_gap, - }, - env); -} - -JNI_METHOD(brush_behavior, ResponseNodeNative, jlong, createResponse) -(JNIEnv* env, jobject thiz, jlong easing_function_native_pointer) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::ResponseNode{ - .response_curve = - CastToEasingFunction(easing_function_native_pointer), - }, - env); -} - -JNI_METHOD(brush_behavior, IntegralNodeNative, jlong, createIntegral) -(JNIEnv* env, jobject thiz, jint integrate_over, jfloat integral_value_start, - jfloat integral_value_end, jint integral_out_of_range_behavior) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::IntegralNode{ - .integrate_over = - static_cast(integrate_over), - .integral_out_of_range_behavior = - static_cast( - integral_out_of_range_behavior), - .integral_value_range = {integral_value_start, integral_value_end}, - }, - env); -} - -JNI_METHOD(brush_behavior, BinaryOpNodeNative, jlong, createBinaryOp) -(JNIEnv* env, jobject thiz, jint operation) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::BinaryOpNode{ - .operation = static_cast(operation), - }, - env); -} - -JNI_METHOD(brush_behavior, InterpolationNodeNative, jlong, createInterpolation) -(JNIEnv* env, jobject thiz, jint interpolation) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::InterpolationNode{ - .interpolation = - static_cast(interpolation), - }, - env); -} - -JNI_METHOD(brush_behavior, TargetNodeNative, jlong, createTarget) -(JNIEnv* env, jobject thiz, jint target, jfloat target_modifier_start, - jfloat target_modifier_end) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::TargetNode{ - .target = static_cast(target), - .target_modifier_range = {target_modifier_start, target_modifier_end}, - }, - env); -} - -JNI_METHOD(brush_behavior, PolarTargetNodeNative, jlong, createPolarTarget) -(JNIEnv* env, jobject thiz, jint polar_target, jfloat angle_range_start, - jfloat angle_range_end, jfloat magnitude_range_start, - jfloat magnitude_range_end) { - return ValidateAndHoistNodeOrThrow( - BrushBehavior::PolarTargetNode{ - .target = static_cast(polar_target), - .angle_range = {angle_range_start, angle_range_end}, - .magnitude_range = {magnitude_range_start, magnitude_range_end}, - }, - env); -} - -JNI_METHOD(brush_behavior, NodeNative, void, free) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - DeleteNativeBrushBehaviorNode(node_native_pointer); -} - -JNI_METHOD(brush_behavior, NodeNative, jint, getNodeType) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { constexpr auto visitor = absl::Overload{ [](const BrushBehavior::SourceNode&) { return kSourceNode; }, [](const BrushBehavior::ConstantNode&) { return kConstantNode; }, @@ -268,245 +111,19 @@ JNI_METHOD(brush_behavior, NodeNative, jint, getNodeType) }, [](const BrushBehavior::TargetNode&) { return kTargetNode; }, [](const BrushBehavior::PolarTargetNode&) { return kPolarTargetNode; }}; - return std::visit(visitor, CastToBrushBehaviorNode(node_native_pointer)); -} - -// SourceNode accessors: - -JNI_METHOD(brush_behavior, SourceNodeNative, jint, getSourceInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .source); -} - -JNI_METHOD(brush_behavior, SourceNodeNative, jfloat, getSourceValueRangeStart) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .source_value_range[0]; -} - -JNI_METHOD(brush_behavior, SourceNodeNative, jfloat, getSourceValueRangeEnd) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .source_value_range[1]; -} - -JNI_METHOD(brush_behavior, SourceNodeNative, jint, - getSourceOutOfRangeBehaviorInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .source_out_of_range_behavior); -} - -// ConstantNode accessors: - -JNI_METHOD(brush_behavior, ConstantNodeNative, jfloat, getConstantValue) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .value; -} - -// NoiseNode accessors: - -JNI_METHOD(brush_behavior, NoiseNodeNative, jint, getNoiseSeed) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .seed); -} - -JNI_METHOD(brush_behavior, NoiseNodeNative, jint, getNoiseVaryOverInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .vary_over); -} - -JNI_METHOD(brush_behavior, NoiseNodeNative, jfloat, getNoiseBasePeriod) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .base_period; -} - -// ToolTypeFilterNode accessors: - -JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, - getToolTypeFilterMouseEnabled) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .enabled_tool_types.mouse; -} - -JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, - getToolTypeFilterTouchEnabled) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .enabled_tool_types.touch; -} - -JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, - getToolTypeFilterStylusEnabled) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .enabled_tool_types.stylus; -} - -JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, - getToolTypeFilterUnknownEnabled) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .enabled_tool_types.unknown; -} - -// DampingNode accessors: - -JNI_METHOD(brush_behavior, DampingNodeNative, jint, getDampingSourceInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .damping_source); -} - -JNI_METHOD(brush_behavior, DampingNodeNative, jfloat, getDampingGap) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .damping_gap; -} - -// ResponseNode accessors: - -JNI_METHOD(brush_behavior, ResponseNodeNative, jlong, getResponseCurvePointer) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return reinterpret_cast( - &std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .response_curve); -} - -// IntegralNode accessors: - -JNI_METHOD(brush_behavior, IntegralNodeNative, jint, getIntegrateOverInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .integrate_over); -} - -JNI_METHOD(brush_behavior, IntegralNodeNative, jfloat, - getIntegralValueRangeStart) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .integral_value_range[0]; -} - -JNI_METHOD(brush_behavior, IntegralNodeNative, jfloat, getIntegralValueRangeEnd) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .integral_value_range[1]; -} - -JNI_METHOD(brush_behavior, IntegralNodeNative, jint, - getIntegralOutOfRangeBehaviorInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .integral_out_of_range_behavior); -} - -// BinaryOpNode accessors: - -JNI_METHOD(brush_behavior, BinaryOpNodeNative, jint, getBinaryOperationInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .operation); -} - -// InterpolationNode accessors: - -JNI_METHOD(brush_behavior, InterpolationNodeNative, jint, getInterpolationInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .interpolation); -} - -// TargetNode accessors: - -JNI_METHOD(brush_behavior, TargetNodeNative, jint, getTargetInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .target); -} - -JNI_METHOD(brush_behavior, TargetNodeNative, jfloat, - getTargetModifierRangeStart) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .target_modifier_range[0]; -} - -JNI_METHOD(brush_behavior, TargetNodeNative, jfloat, getTargetModifierRangeEnd) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .target_modifier_range[1]; + return std::visit(visitor, CastToBrushBehavior(native_pointer).nodes[index]); } -// PolarTargetNode accessors: - -JNI_METHOD(brush_behavior, PolarTargetNodeNative, jint, getPolarTargetInt) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return static_cast(std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .target); -} - -JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, - getPolarTargetAngleRangeStart) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .angle_range[0]; -} - -JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, - getPolarTargetAngleRangeEnd) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .angle_range[1]; -} - -JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, - getPolarTargetMagnitudeRangeStart) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .magnitude_range[0]; +JNI_METHOD(brush, BrushBehaviorNative, jstring, getDeveloperComment) +(JNIEnv* env, jobject object, jlong native_pointer) { + const BrushBehavior& brush_behavior = CastToBrushBehavior(native_pointer); + return env->NewStringUTF(brush_behavior.developer_comment.c_str()); } -JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, - getPolarTargetMagnitudeRangeEnd) -(JNIEnv* env, jobject thiz, jlong node_native_pointer) { - return std::get( - CastToBrushBehaviorNode(node_native_pointer)) - .magnitude_range[1]; +JNI_METHOD(brush, BrushBehaviorNative, jlong, newCopyOfNode) +(JNIEnv* env, jobject thiz, jlong native_pointer, jint index) { + return NewNativeBrushBehaviorNode( + CastToBrushBehavior(native_pointer).nodes[index]); } } // extern "C" diff --git a/ink/brush/internal/jni/brush_behavior_node_jni.cc b/ink/brush/internal/jni/brush_behavior_node_jni.cc new file mode 100644 index 00000000..09d02345 --- /dev/null +++ b/ink/brush/internal/jni/brush_behavior_node_jni.cc @@ -0,0 +1,281 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "ink/brush/internal/jni/brush_behavior_node_native.h" +#include "ink/jni/internal/jni_defines.h" +#include "ink/jni/internal/status_jni_helper.h" + +using ::ink::jni::ThrowExceptionFromStatusCallback; + +extern "C" { + +// Functions for dealing with BrushBehavior::Nodes. Note that on the C++ side, +// BrushBehavior::Node is a variant, so all of the native pointers are pointers +// to the same type (the variant BrushBehavior::Node). + +JNI_METHOD(brush_behavior, SourceNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint source, jfloat source_value_start, + jfloat source_value_end, jint source_out_of_range_behavior) { + return SourceNodeNative_create(env, source, source_value_start, + source_value_end, source_out_of_range_behavior, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, ConstantNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jfloat value) { + return ConstantNodeNative_create(env, value, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, NoiseNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint seed, jint vary_over, jfloat base_period) { + return NoiseNodeNative_create(env, seed, vary_over, base_period, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jboolean mouse_enabled, jboolean touch_enabled, + jboolean stylus_enabled, jboolean unknown_enabled) { + return ToolTypeFilterNodeNative_create(env, mouse_enabled, touch_enabled, + stylus_enabled, unknown_enabled, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, DampingNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint damping_source, jfloat damping_gap) { + return DampingNodeNative_create(env, damping_source, damping_gap, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, ResponseNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jlong easing_function_native_pointer) { + return ResponseNodeNative_create(env, easing_function_native_pointer, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, IntegralNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint integrate_over, jfloat integral_value_start, + jfloat integral_value_end, jint integral_out_of_range_behavior) { + return IntegralNodeNative_create( + env, integrate_over, integral_value_start, integral_value_end, + integral_out_of_range_behavior, &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, BinaryOpNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint operation) { + return BinaryOpNodeNative_create(env, operation, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, InterpolationNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint interpolation) { + return InterpolationNodeNative_create(env, interpolation, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, TargetNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint target, jfloat target_modifier_start, + jfloat target_modifier_end) { + return TargetNodeNative_create(env, target, target_modifier_start, + target_modifier_end, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, PolarTargetNodeNative, jlong, create) +(JNIEnv* env, jobject thiz, jint polar_target, jfloat angle_range_start, + jfloat angle_range_end, jfloat magnitude_range_start, + jfloat magnitude_range_end) { + return PolarTargetNodeNative_create(env, polar_target, angle_range_start, + angle_range_end, magnitude_range_start, + magnitude_range_end, + &ThrowExceptionFromStatusCallback); +} + +JNI_METHOD(brush_behavior, NodeNative, void, free) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + NodeNative_free(node_native_pointer); +} + +// SourceNode accessors: + +JNI_METHOD(brush_behavior, SourceNodeNative, jint, getSourceInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return SourceNodeNative_getSourceInt(node_native_pointer); +} + +JNI_METHOD(brush_behavior, SourceNodeNative, jfloat, getValueRangeStart) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return SourceNodeNative_getValueRangeStart(node_native_pointer); +} + +JNI_METHOD(brush_behavior, SourceNodeNative, jfloat, getValueRangeEnd) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return SourceNodeNative_getValueRangeEnd(node_native_pointer); +} + +JNI_METHOD(brush_behavior, SourceNodeNative, jint, getOutOfRangeBehaviorInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return SourceNodeNative_getOutOfRangeBehaviorInt(node_native_pointer); +} + +// ConstantNode accessors: + +JNI_METHOD(brush_behavior, ConstantNodeNative, jfloat, getValue) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return ConstantNodeNative_getValue(node_native_pointer); +} + +// NoiseNode accessors: + +JNI_METHOD(brush_behavior, NoiseNodeNative, jint, getSeed) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return NoiseNodeNative_getSeed(node_native_pointer); +} + +JNI_METHOD(brush_behavior, NoiseNodeNative, jint, getVaryOverInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return NoiseNodeNative_getVaryOverInt(node_native_pointer); +} + +JNI_METHOD(brush_behavior, NoiseNodeNative, jfloat, getBasePeriod) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return NoiseNodeNative_getBasePeriod(node_native_pointer); +} + +// ToolTypeFilterNode accessors: + +JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, getMouseEnabled) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return ToolTypeFilterNodeNative_getMouseEnabled(node_native_pointer); +} + +JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, getTouchEnabled) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return ToolTypeFilterNodeNative_getTouchEnabled(node_native_pointer); +} + +JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, getStylusEnabled) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return ToolTypeFilterNodeNative_getStylusEnabled(node_native_pointer); +} + +JNI_METHOD(brush_behavior, ToolTypeFilterNodeNative, jboolean, + getUnknownEnabled) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return ToolTypeFilterNodeNative_getUnknownEnabled(node_native_pointer); +} + +// DampingNode accessors: + +JNI_METHOD(brush_behavior, DampingNodeNative, jint, getDampingSourceInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return DampingNodeNative_getDampingSourceInt(node_native_pointer); +} + +JNI_METHOD(brush_behavior, DampingNodeNative, jfloat, getDampingGap) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return DampingNodeNative_getDampingGap(node_native_pointer); +} + +// ResponseNode accessors: + +JNI_METHOD(brush_behavior, ResponseNodeNative, jlong, getResponseCurvePointer) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return ResponseNodeNative_getResponseCurvePointer(node_native_pointer); +} + +// IntegralNode accessors: + +JNI_METHOD(brush_behavior, IntegralNodeNative, jint, getIntegrateOverInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return IntegralNodeNative_getIntegrateOverInt(node_native_pointer); +} + +JNI_METHOD(brush_behavior, IntegralNodeNative, jfloat, getValueRangeStart) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return IntegralNodeNative_getValueRangeStart(node_native_pointer); +} + +JNI_METHOD(brush_behavior, IntegralNodeNative, jfloat, getValueRangeEnd) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return IntegralNodeNative_getValueRangeEnd(node_native_pointer); +} + +JNI_METHOD(brush_behavior, IntegralNodeNative, jint, getOutOfRangeBehaviorInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return IntegralNodeNative_getOutOfRangeBehaviorInt(node_native_pointer); +} + +// BinaryOpNode accessors: + +JNI_METHOD(brush_behavior, BinaryOpNodeNative, jint, getOperationInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return BinaryOpNodeNative_getOperationInt(node_native_pointer); +} + +// InterpolationNode accessors: + +JNI_METHOD(brush_behavior, InterpolationNodeNative, jint, getInterpolationInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return InterpolationNodeNative_getInterpolationInt(node_native_pointer); +} + +// TargetNode accessors: + +JNI_METHOD(brush_behavior, TargetNodeNative, jint, getTargetInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return TargetNodeNative_getTargetInt(node_native_pointer); +} + +JNI_METHOD(brush_behavior, TargetNodeNative, jfloat, getModifierRangeStart) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return TargetNodeNative_getModifierRangeStart(node_native_pointer); +} + +JNI_METHOD(brush_behavior, TargetNodeNative, jfloat, getModifierRangeEnd) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return TargetNodeNative_getModifierRangeEnd(node_native_pointer); +} + +// PolarTargetNode accessors: + +JNI_METHOD(brush_behavior, PolarTargetNodeNative, jint, getTargetInt) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return PolarTargetNodeNative_getTargetInt(node_native_pointer); +} + +JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, getAngleRangeStart) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return PolarTargetNodeNative_getAngleRangeStart(node_native_pointer); +} + +JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, getAngleRangeEnd) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return PolarTargetNodeNative_getAngleRangeEnd(node_native_pointer); +} + +JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, + getMagnitudeRangeStart) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return PolarTargetNodeNative_getMagnitudeRangeStart(node_native_pointer); +} + +JNI_METHOD(brush_behavior, PolarTargetNodeNative, jfloat, getMagnitudeRangeEnd) +(JNIEnv* env, jobject thiz, jlong node_native_pointer) { + return PolarTargetNodeNative_getMagnitudeRangeEnd(node_native_pointer); +} + +} // extern "C" diff --git a/ink/brush/internal/jni/brush_behavior_node_native.cc b/ink/brush/internal/jni/brush_behavior_node_native.cc new file mode 100644 index 00000000..abf7d183 --- /dev/null +++ b/ink/brush/internal/jni/brush_behavior_node_native.cc @@ -0,0 +1,393 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "ink/brush/internal/jni/brush_behavior_node_native.h" + +#include +#include + +#include "absl/status/status.h" +#include "ink/brush/brush_behavior.h" +#include "ink/brush/internal/jni/brush_native_helper.h" + +namespace { + +using ::ink::BrushBehavior; +using ::ink::brush_internal::ValidateBrushBehaviorNode; +using ::ink::native::CastToBrushBehaviorNode; +using ::ink::native::CastToEasingFunction; +using ::ink::native::DeleteNativeBrushBehaviorNode; +using ::ink::native::NewNativeBrushBehaviorNode; + +int64_t ValidateAndHoistNode(void* jni_env_pass_through, + BrushBehavior::Node node, + void (*throw_from_status_callback)(void*, int, + const char*)) { + if (absl::Status status = ValidateBrushBehaviorNode(node); !status.ok()) { + throw_from_status_callback(jni_env_pass_through, + static_cast(status.code()), + status.message().data()); + return 0; + } + return NewNativeBrushBehaviorNode(std::move(node)); +} + +} // namespace + +extern "C" { + +int64_t SourceNodeNative_create( + void* jni_env_pass_through, int source, float source_value_start, + float source_value_end, int source_out_of_range_behavior, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::SourceNode{ + .source = static_cast(source), + .source_out_of_range_behavior = + static_cast( + source_out_of_range_behavior), + .source_value_range = {source_value_start, source_value_end}, + }, + throw_from_status_callback); +} + +int64_t ConstantNodeNative_create( + void* jni_env_pass_through, float value, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode(jni_env_pass_through, + BrushBehavior::ConstantNode{.value = value}, + throw_from_status_callback); +} + +int64_t NoiseNodeNative_create( + void* jni_env_pass_through, int seed, int vary_over, float base_period, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::NoiseNode{ + .seed = static_cast(seed), + .vary_over = static_cast(vary_over), + .base_period = base_period, + }, + throw_from_status_callback); +} + +int64_t ToolTypeFilterNodeNative_create( + void* jni_env_pass_through, bool mouse_enabled, bool touch_enabled, + bool stylus_enabled, bool unknown_enabled, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::ToolTypeFilterNode{ + .enabled_tool_types = {.unknown = unknown_enabled, + .mouse = mouse_enabled, + .touch = touch_enabled, + .stylus = stylus_enabled}, + }, + throw_from_status_callback); +} + +int64_t DampingNodeNative_create( + void* jni_env_pass_through, int damping_source, float damping_gap, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::DampingNode{ + .damping_source = + static_cast(damping_source), + .damping_gap = damping_gap, + }, + throw_from_status_callback); +} + +int64_t ResponseNodeNative_create( + void* jni_env_pass_through, int64_t easing_function_native_pointer, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode(jni_env_pass_through, + BrushBehavior::ResponseNode{ + .response_curve = CastToEasingFunction( + easing_function_native_pointer), + }, + throw_from_status_callback); +} + +int64_t IntegralNodeNative_create( + void* jni_env_pass_through, int integrate_over, float integral_value_start, + float integral_value_end, int integral_out_of_range_behavior, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::IntegralNode{ + .integrate_over = + static_cast(integrate_over), + .integral_out_of_range_behavior = + static_cast( + integral_out_of_range_behavior), + .integral_value_range = {integral_value_start, integral_value_end}, + }, + throw_from_status_callback); +} + +int64_t BinaryOpNodeNative_create( + void* jni_env_pass_through, int operation, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::BinaryOpNode{ + .operation = static_cast(operation), + }, + throw_from_status_callback); +} + +int64_t InterpolationNodeNative_create( + void* jni_env_pass_through, int interpolation, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::InterpolationNode{ + .interpolation = + static_cast(interpolation), + }, + throw_from_status_callback); +} + +int64_t TargetNodeNative_create( + void* jni_env_pass_through, int target, float target_modifier_start, + float target_modifier_end, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::TargetNode{ + .target = static_cast(target), + .target_modifier_range = {target_modifier_start, target_modifier_end}, + }, + throw_from_status_callback); +} + +int64_t PolarTargetNodeNative_create( + void* jni_env_pass_through, int polar_target, float angle_range_start, + float angle_range_end, float magnitude_range_start, + float magnitude_range_end, + void (*throw_from_status_callback)(void*, int, const char*)) { + return ValidateAndHoistNode( + jni_env_pass_through, + BrushBehavior::PolarTargetNode{ + .target = static_cast(polar_target), + .angle_range = {angle_range_start, angle_range_end}, + .magnitude_range = {magnitude_range_start, magnitude_range_end}, + }, + throw_from_status_callback); +} + +void NodeNative_free(int64_t native_ptr) { + DeleteNativeBrushBehaviorNode(native_ptr); +} + +// SourceNode accessors: + +int SourceNodeNative_getSourceInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .source); +} + +float SourceNodeNative_getValueRangeStart(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .source_value_range[0]; +} + +float SourceNodeNative_getValueRangeEnd(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .source_value_range[1]; +} + +int SourceNodeNative_getOutOfRangeBehaviorInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .source_out_of_range_behavior); +} + +// ConstantNode accessors: + +float ConstantNodeNative_getValue(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .value; +} + +// NoiseNode accessors: + +int NoiseNodeNative_getSeed(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .seed); +} + +int NoiseNodeNative_getVaryOverInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .vary_over); +} + +float NoiseNodeNative_getBasePeriod(int64_t native_ptr) { + return std::get(CastToBrushBehaviorNode(native_ptr)) + .base_period; +} + +// ToolTypeFilterNode accessors: + +bool ToolTypeFilterNodeNative_getMouseEnabled(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .enabled_tool_types.mouse; +} + +bool ToolTypeFilterNodeNative_getTouchEnabled(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .enabled_tool_types.touch; +} + +bool ToolTypeFilterNodeNative_getStylusEnabled(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .enabled_tool_types.stylus; +} + +bool ToolTypeFilterNodeNative_getUnknownEnabled(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .enabled_tool_types.unknown; +} + +// DampingNode accessors: + +int DampingNodeNative_getDampingSourceInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .damping_source); +} + +float DampingNodeNative_getDampingGap(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .damping_gap; +} + +// ResponseNode accessors: + +int64_t ResponseNodeNative_getResponseCurvePointer(int64_t native_ptr) { + return reinterpret_cast(&std::get( + CastToBrushBehaviorNode(native_ptr)) + .response_curve); +} + +// IntegralNode accessors: + +int IntegralNodeNative_getIntegrateOverInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .integrate_over); +} + +float IntegralNodeNative_getValueRangeStart(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .integral_value_range[0]; +} + +float IntegralNodeNative_getValueRangeEnd(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .integral_value_range[1]; +} + +int IntegralNodeNative_getOutOfRangeBehaviorInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .integral_out_of_range_behavior); +} + +// BinaryOpNode accessors: + +int BinaryOpNodeNative_getOperationInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .operation); +} + +// InterpolationNode accessors: + +int InterpolationNodeNative_getInterpolationInt(int64_t native_ptr) { + return static_cast(std::get( + CastToBrushBehaviorNode(native_ptr)) + .interpolation); +} + +// TargetNode accessors: + +int TargetNodeNative_getTargetInt(int64_t native_ptr) { + return static_cast( + std::get(CastToBrushBehaviorNode(native_ptr)) + .target); +} + +float TargetNodeNative_getModifierRangeStart(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .target_modifier_range[0]; +} + +float TargetNodeNative_getModifierRangeEnd(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .target_modifier_range[1]; +} + +// PolarTargetNode accessors: + +int PolarTargetNodeNative_getTargetInt(int64_t native_ptr) { + return static_cast(std::get( + CastToBrushBehaviorNode(native_ptr)) + .target); +} + +float PolarTargetNodeNative_getAngleRangeStart(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .angle_range[0]; +} + +float PolarTargetNodeNative_getAngleRangeEnd(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .angle_range[1]; +} + +float PolarTargetNodeNative_getMagnitudeRangeStart(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .magnitude_range[0]; +} + +float PolarTargetNodeNative_getMagnitudeRangeEnd(int64_t native_ptr) { + return std::get( + CastToBrushBehaviorNode(native_ptr)) + .magnitude_range[1]; +} + +} // extern "C" diff --git a/ink/brush/internal/jni/brush_behavior_node_native.h b/ink/brush/internal/jni/brush_behavior_node_native.h new file mode 100644 index 00000000..b11c6503 --- /dev/null +++ b/ink/brush/internal/jni/brush_behavior_node_native.h @@ -0,0 +1,139 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INK_BRUSH_INTERNAL_JNI_BRUSH_BEHAVIOR_NODE_NATIVE_H_ +#define INK_BRUSH_INTERNAL_JNI_BRUSH_BEHAVIOR_NODE_NATIVE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// The native_ptr parameter of these methods contains the raw pointer to a +// C++ BrushBehavior::Node object stored in Kotlin. + +// If validation fails for any create function, it calls +// throw_from_status_callback with the value passed as jni_env_pass_through, +// the error status code as an int, and the error status message. +int64_t SourceNodeNative_create( + void* jni_env_pass_through, int source, float source_value_start, + float source_value_end, int source_out_of_range_behavior, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t ConstantNodeNative_create( + void* jni_env_pass_through, float value, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t NoiseNodeNative_create(void* jni_env_pass_through, int seed, + int vary_over, float base_period, + void (*throw_from_status_callback)(void*, int, + const char*)); + +int64_t ToolTypeFilterNodeNative_create( + void* jni_env_pass_through, bool mouse_enabled, bool touch_enabled, + bool stylus_enabled, bool unknown_enabled, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t DampingNodeNative_create( + void* jni_env_pass_through, int damping_source, float damping_gap, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t ResponseNodeNative_create( + void* jni_env_pass_through, int64_t easing_function_native_pointer, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t IntegralNodeNative_create( + void* jni_env_pass_through, int integrate_over, float integral_value_start, + float integral_value_end, int integral_out_of_range_behavior, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t BinaryOpNodeNative_create( + void* jni_env_pass_through, int operation, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t InterpolationNodeNative_create( + void* jni_env_pass_through, int interpolation, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t TargetNodeNative_create( + void* jni_env_pass_through, int target, float target_modifier_start, + float target_modifier_end, + void (*throw_from_status_callback)(void*, int, const char*)); + +int64_t PolarTargetNodeNative_create( + void* jni_env_pass_through, int polar_target, float angle_range_start, + float angle_range_end, float magnitude_range_start, + float magnitude_range_end, + void (*throw_from_status_callback)(void*, int, const char*)); + +void NodeNative_free(int64_t native_ptr); + +// SourceNode accessors: +int SourceNodeNative_getSourceInt(int64_t native_ptr); +float SourceNodeNative_getValueRangeStart(int64_t native_ptr); +float SourceNodeNative_getValueRangeEnd(int64_t native_ptr); +int SourceNodeNative_getOutOfRangeBehaviorInt(int64_t native_ptr); + +// ConstantNode accessors: +float ConstantNodeNative_getValue(int64_t native_ptr); + +// NoiseNode accessors: +int NoiseNodeNative_getSeed(int64_t native_ptr); +int NoiseNodeNative_getVaryOverInt(int64_t native_ptr); +float NoiseNodeNative_getBasePeriod(int64_t native_ptr); + +// ToolTypeFilterNode accessors: +bool ToolTypeFilterNodeNative_getMouseEnabled(int64_t native_ptr); +bool ToolTypeFilterNodeNative_getTouchEnabled(int64_t native_ptr); +bool ToolTypeFilterNodeNative_getStylusEnabled(int64_t native_ptr); +bool ToolTypeFilterNodeNative_getUnknownEnabled(int64_t native_ptr); + +// DampingNode accessors: +int DampingNodeNative_getDampingSourceInt(int64_t native_ptr); +float DampingNodeNative_getDampingGap(int64_t native_ptr); + +// ResponseNode accessors: +int64_t ResponseNodeNative_getResponseCurvePointer(int64_t native_ptr); + +// IntegralNode accessors: +int IntegralNodeNative_getIntegrateOverInt(int64_t native_ptr); +float IntegralNodeNative_getValueRangeStart(int64_t native_ptr); +float IntegralNodeNative_getValueRangeEnd(int64_t native_ptr); +int IntegralNodeNative_getOutOfRangeBehaviorInt(int64_t native_ptr); + +// BinaryOpNode accessors: +int BinaryOpNodeNative_getOperationInt(int64_t native_ptr); + +// InterpolationNode accessors: +int InterpolationNodeNative_getInterpolationInt(int64_t native_ptr); + +// TargetNode accessors: +int TargetNodeNative_getTargetInt(int64_t native_ptr); +float TargetNodeNative_getModifierRangeStart(int64_t native_ptr); +float TargetNodeNative_getModifierRangeEnd(int64_t native_ptr); + +// PolarTargetNode accessors: +int PolarTargetNodeNative_getTargetInt(int64_t native_ptr); +float PolarTargetNodeNative_getAngleRangeStart(int64_t native_ptr); +float PolarTargetNodeNative_getAngleRangeEnd(int64_t native_ptr); +float PolarTargetNodeNative_getMagnitudeRangeStart(int64_t native_ptr); +float PolarTargetNodeNative_getMagnitudeRangeEnd(int64_t native_ptr); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // INK_BRUSH_INTERNAL_JNI_BRUSH_BEHAVIOR_NODE_NATIVE_H_