From 03d7c9c5872ac31007a8cdca9178069144c9f50d Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 20 Feb 2024 18:30:53 +0000 Subject: [PATCH 001/138] Updating harfbuzz to 8.3.0 [This thread](https://2dimensions.slack.com/archives/C067PQQL3EK/p1708104838351439) had me looking through the harfbuzz codebase to see if we could change the way some of the symbols were exported (our renames was getting clashing defines). That made me take a closer look at all the changes since 6.0.0 (the version we were pegged at). There are a ton of performance and stability changes since 6.0.0 that we really want (take a look at the [release page](https://github.com/harfbuzz/harfbuzz/releases) for a list). So I took this opportunity to update our renames script, pin us to a new harfbuzz and branch it with some changes to disable exporting certain symbols that are normally accessed via defines in C++ but are exported as a courtesy to wrapping language bindings. We don't need those so I added a way to compile them out for us. Diffs= 9d605a1fe Updating harfbuzz to 8.3.0 (#6652) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- .../gen_harfbuzz_renames/gen_header.dart | 58 +- dependencies/premake5_harfbuzz.lua | 13 +- dependencies/premake5_harfbuzz_v2.lua | 13 +- dependencies/rive_harfbuzz_renames.h | 981 ++++++++++++------ src/text/font_hb.cpp | 2 +- 6 files changed, 714 insertions(+), 355 deletions(-) diff --git a/.rive_head b/.rive_head index 28044705..a6def145 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -5cb42a9b0033a1b9d2360292b7ef14bf67e3d45e +9d605a1feb39dcad526ac9dda6b53b547921c58d diff --git a/dependencies/gen_harfbuzz_renames/gen_header.dart b/dependencies/gen_harfbuzz_renames/gen_header.dart index e0c6b4df..1acb016e 100644 --- a/dependencies/gen_harfbuzz_renames/gen_header.dart +++ b/dependencies/gen_harfbuzz_renames/gen_header.dart @@ -1,27 +1,79 @@ import 'dart:collection'; import 'dart:io'; -var skip = HashSet.from( +final skip = HashSet.from( [ 'hb_color_get_alpha', 'hb_color_get_green', 'hb_color_get_blue', 'hb_color_get_red', 'hb_glyph_info_get_glyph_flags', + 'hb_declval', + ], +); + +final extras = HashSet.from( + [ + 'lookup_standard_encoding_for_code', + 'lookup_expert_encoding_for_code', + 'lookup_expert_charset_for_sid', + 'lookup_expert_subset_charset_for_sid', + 'lookup_standard_encoding_for_sid', + 'accelerator_t', + 'get_seac_components', + 'data_destroy_arabic', ], ); void main() { + final uniqueNames = HashSet(); var header = StringBuffer(); header.writeln('// clang-format off'); + header.writeln('// hb_*'); var contents = File('harfbuzz_names.txt').readAsStringSync(); - RegExp exp = RegExp(r'\s_(hb_([a-zA-Z0-9_]*))$', multiLine: true); + RegExp exp = RegExp(r'\s(hb_([a-zA-Z0-9_]*))', multiLine: true); Iterable matches = exp.allMatches(contents); for (final m in matches) { var symbolName = m[1]; - if (skip.contains(symbolName)) { + if (symbolName == null || + skip.contains(symbolName) || + uniqueNames.contains(symbolName)) { continue; } + uniqueNames.add(symbolName); + header.writeln('#define $symbolName rive_$symbolName'); + } + header.writeln('// _hb_*'); + { + RegExp exp = RegExp(r'\s_(hb_([a-zA-Z0-9_]*))', multiLine: true); + Iterable matches = exp.allMatches(contents); + for (final m in matches) { + var symbolName = m[1]; + if (symbolName == null || + skip.contains(symbolName) || + uniqueNames.contains(symbolName)) { + continue; + } + uniqueNames.add(symbolName); + header.writeln('#define $symbolName rive_$symbolName'); + } + } + header.writeln('// __hb_*'); + { + RegExp exp = RegExp(r'\s_(_hb_([a-zA-Z0-9_]*))', multiLine: true); + Iterable matches = exp.allMatches(contents); + for (final m in matches) { + var symbolName = m[1]; + if (symbolName == null || + skip.contains(symbolName) || + uniqueNames.contains(symbolName)) { + continue; + } + uniqueNames.add(symbolName); + header.writeln('#define $symbolName rive_$symbolName'); + } + } + for (final symbolName in extras) { header.writeln('#define $symbolName rive_$symbolName'); } File('../rive_harfbuzz_renames.h').writeAsStringSync(header.toString()); diff --git a/dependencies/premake5_harfbuzz.lua b/dependencies/premake5_harfbuzz.lua index ed5cc1d6..de31b788 100644 --- a/dependencies/premake5_harfbuzz.lua +++ b/dependencies/premake5_harfbuzz.lua @@ -1,6 +1,6 @@ require('setup_compiler') local dependency = require('dependency') -harfbuzz = dependency.github('harfbuzz/harfbuzz', '6.0.0') +harfbuzz = dependency.github('rive-app/harfbuzz', 'rive_8.3.0') workspace('rive') configurations({ 'debug', 'release' }) @@ -218,11 +218,14 @@ do harfbuzz .. '/src/hb-vector.hh', harfbuzz .. '/src/hb.hh', harfbuzz .. '/src/graph/gsubgpos-context.cc', + harfbuzz .. '/src/hb-paint.cc', + harfbuzz .. '/src/hb-paint-extents.cc', + harfbuzz .. '/src/hb-outline.cc', }) warnings('Off') - defines({ 'HAVE_OT', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256' }) + defines({ 'HAVE_OT', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256', 'HB_NO_EXTERN_HELPERS' }) filter('system:emscripten') do @@ -238,6 +241,12 @@ do '-Werror=vla', }) end + filter('toolset:msc') + do + buildoptions({ + '/bigobj', + }) + end filter('configurations:debug') do diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua index 678f1a2d..f3449582 100644 --- a/dependencies/premake5_harfbuzz_v2.lua +++ b/dependencies/premake5_harfbuzz_v2.lua @@ -1,7 +1,7 @@ dofile('rive_build_config.lua') local dependency = require('dependency') -harfbuzz = dependency.github('harfbuzz/harfbuzz', '6.0.0') +harfbuzz = dependency.github('rive-app/harfbuzz', 'rive_8.3.0') newoption({ trigger = 'no-harfbuzz-renames', @@ -217,11 +217,14 @@ do harfbuzz .. '/src/hb-vector.hh', harfbuzz .. '/src/hb.hh', harfbuzz .. '/src/graph/gsubgpos-context.cc', + harfbuzz .. '/src/hb-paint.cc', + harfbuzz .. '/src/hb-paint-extents.cc', + harfbuzz .. '/src/hb-outline.cc', }) warnings('Off') - defines({ 'HAVE_OT', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256' }) + defines({ 'HAVE_OT', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256', 'HB_NO_EXTERN_HELPERS' }) filter('toolset:not msc') do @@ -232,6 +235,12 @@ do '-Werror=vla', }) end + filter('toolset:msc') + do + buildoptions({ + '/bigobj', + }) + end filter('options:config=release') do diff --git a/dependencies/rive_harfbuzz_renames.h b/dependencies/rive_harfbuzz_renames.h index 8e6e77ad..80b66c8b 100644 --- a/dependencies/rive_harfbuzz_renames.h +++ b/dependencies/rive_harfbuzz_renames.h @@ -1,4 +1,435 @@ // clang-format off +// hb_* +#define hb_vector_t rive_hb_vector_t +#define hb_hashmap_t rive_hb_hashmap_t +#define hb_serialize_context_t rive_hb_serialize_context_t +#define hb_array_t rive_hb_array_t +#define hb_array rive_hb_array +#define hb_barrier rive_hb_barrier +#define hb_identity rive_hb_identity +#define hb_ridentity rive_hb_ridentity +#define hb_bit_storage rive_hb_bit_storage +#define hb_object_fini rive_hb_object_fini +#define hb_object_init rive_hb_object_init +#define hb_unsigned_mul_overflows rive_hb_unsigned_mul_overflows +#define hb_user_data_array_t rive_hb_user_data_array_t +#define hb_get rive_hb_get +#define hb_has rive_hb_has +#define hb_map rive_hb_map +#define hb_max rive_hb_max +#define hb_hash rive_hb_hash +#define hb_iter rive_hb_iter +#define hb_swap rive_hb_swap +#define hb_deref rive_hb_deref +#define hb_concat rive_hb_concat +#define hb_filter rive_hb_filter +#define hb_invoke rive_hb_invoke +#define hb_memset rive_hb_memset +#define hb_mutex_t rive_hb_mutex_t +#define hb_priority rive_hb_priority +#define hb_map_iter_t rive_hb_map_iter_t +#define hb_atomic_int_t rive_hb_atomic_int_t +#define hb_atomic_ptr_t rive_hb_atomic_ptr_t +#define hb_concat_iter_t rive_hb_concat_iter_t +#define hb_filter_iter_t rive_hb_filter_iter_t +#define hb_lockable_set_t rive_hb_lockable_set_t +#define hb_object_header_t rive_hb_object_header_t +#define hb_reference_count_t rive_hb_reference_count_t +#define hb_reference_wrapper rive_hb_reference_wrapper +#define hb_map_iter_factory_t rive_hb_map_iter_factory_t +#define hb_filter_iter_factory_t rive_hb_filter_iter_factory_t +#define hb_iter_t rive_hb_iter_t +#define hb_iter_fallback_mixin_t rive_hb_iter_fallback_mixin_t +#define hb_match_reference rive_hb_match_reference +#define hb_sorted_array_t rive_hb_sorted_array_t +#define hb_sorted_array rive_hb_sorted_array +#define hb_aat_layout_track rive_hb_aat_layout_track +#define hb_font_t rive_hb_font_t +#define hb_buffer_t rive_hb_buffer_t +#define hb_aat_layout_position rive_hb_aat_layout_position +#define hb_aat_layout_substitute rive_hb_aat_layout_substitute +#define hb_feature_t rive_hb_feature_t +#define hb_aat_layout_compile_map rive_hb_aat_layout_compile_map +#define hb_aat_map_t rive_hb_aat_map_t +#define hb_aat_layout_find_feature_mapping rive_hb_aat_layout_find_feature_mapping +#define hb_aat_layout_remove_deleted_glyphs rive_hb_aat_layout_remove_deleted_glyphs +#define hb_aat_layout_zero_width_deleted_glyphs rive_hb_aat_layout_zero_width_deleted_glyphs +#define hb_aat_map_builder_t rive_hb_aat_map_builder_t +#define hb_aat_feature_mapping_t rive_hb_aat_feature_mapping_t +#define hb_bsearch_impl rive_hb_bsearch_impl +#define hb_aat_layout_feature_type_t rive_hb_aat_layout_feature_type_t +#define hb_glyph_info_t rive_hb_glyph_info_t +#define hb_set_digest_combiner_t rive_hb_set_digest_combiner_t +#define hb_set_digest_bits_pattern_t rive_hb_set_digest_bits_pattern_t +#define hb_aat_layout_feature_selector_info_t rive_hb_aat_layout_feature_selector_info_t +#define hb_min rive_hb_min +#define hb_none rive_hb_none +#define hb_sink rive_hb_sink +#define hb_clamp rive_hb_clamp +#define hb_match rive_hb_match +#define hb_memcpy rive_hb_memcpy +#define hb_cache_t rive_hb_cache_t +#define hb_blob_ptr_t rive_hb_blob_ptr_t +#define hb_no_trace_t rive_hb_no_trace_t +#define hb_lazy_loader_t rive_hb_lazy_loader_t +#define hb_face_lazy_loader_t rive_hb_face_lazy_loader_t +#define hb_face_t rive_hb_face_t +#define hb_table_lazy_loader_t rive_hb_table_lazy_loader_t +#define hb_blob_t rive_hb_blob_t +#define hb_nonnull_ptr_t rive_hb_nonnull_ptr_t +#define hb_atomic_short_t rive_hb_atomic_short_t +#define hb_segment_properties_t rive_hb_segment_properties_t +#define hb_dispatch_context_t rive_hb_dispatch_context_t +#define hb_sanitize_context_t rive_hb_sanitize_context_t +#define hb_sanitize_with_object_t rive_hb_sanitize_with_object_t +#define hb_direction_t rive_hb_direction_t +#define hb_sink_t rive_hb_sink_t +#define hb_data_wrapper_t rive_hb_data_wrapper_t +#define hb_not_found_t rive_hb_not_found_t +#define hb_glyph_position_t rive_hb_glyph_position_t +#define hb_buffer_flags_t rive_hb_buffer_flags_t +#define hb_buffer_scratch_flags_t rive_hb_buffer_scratch_flags_t +#define hb_glyph_flags_t rive_hb_glyph_flags_t +#define hb_unicode_props_flags_t rive_hb_unicode_props_flags_t +#define hb_equal rive_hb_equal +#define hb_qsort rive_hb_qsort +#define hb_object_trace rive_hb_object_trace +#define hb_object_create rive_hb_object_create +#define hb_object_destroy rive_hb_object_destroy +#define hb_object_is_valid rive_hb_object_is_valid +#define hb_object_reference rive_hb_object_reference +#define hb_object_is_immutable rive_hb_object_is_immutable +#define hb_object_get_user_data rive_hb_object_get_user_data +#define hb_user_data_key_t rive_hb_user_data_key_t +#define hb_object_set_user_data rive_hb_object_set_user_data +#define hb_object_make_immutable rive_hb_object_make_immutable +#define hb_parse_int rive_hb_parse_int +#define hb_parse_uint rive_hb_parse_uint +#define hb_buffer_serialize_format_t rive_hb_buffer_serialize_format_t +#define hb_buffer_serialize_flags_t rive_hb_buffer_serialize_flags_t +#define hb_in_range rive_hb_in_range +#define hb_stable_sort rive_hb_stable_sort +#define hb_buffer_add_utf rive_hb_buffer_add_utf +#define hb_latin1_t rive_hb_latin1_t +#define hb_utf16_xe_t rive_hb_utf16_xe_t +#define hb_utf32_xe_t rive_hb_utf32_xe_t +#define hb_utf8_t rive_hb_utf8_t +#define hb_unicode_funcs_t rive_hb_unicode_funcs_t +#define hb_buffer_diff_flags_t rive_hb_buffer_diff_flags_t +#define hb_parse_double rive_hb_parse_double +#define hb_variation_t rive_hb_variation_t +#define hb_language_item_t rive_hb_language_item_t +#define hb_language_impl_t rive_hb_language_impl_t +#define hb_language_get_default rive_hb_language_get_default +#define hb_draw_funcs_t rive_hb_draw_funcs_t +#define hb_draw_line_to_nil rive_hb_draw_line_to_nil +#define hb_draw_state_t rive_hb_draw_state_t +#define hb_draw_move_to_nil rive_hb_draw_move_to_nil +#define hb_draw_cubic_to_nil rive_hb_draw_cubic_to_nil +#define hb_draw_close_path_nil rive_hb_draw_close_path_nil +#define hb_draw_quadratic_to_nil rive_hb_draw_quadratic_to_nil +#define hb_fill rive_hb_fill +#define hb_bsearch rive_hb_bsearch +#define hb_bit_set_t rive_hb_bit_set_t +#define hb_bit_page_t rive_hb_bit_page_t +#define hb_ot_face_t rive_hb_ot_face_t +#define hb_sparseset_t rive_hb_sparseset_t +#define hb_shaper_lazy_loader_t rive_hb_shaper_lazy_loader_t +#define hb_ot_face_data_t rive_hb_ot_face_data_t +#define hb_vector_size_t rive_hb_vector_size_t +#define hb_bit_set_invertible_t rive_hb_bit_set_invertible_t +#define hb_shaper_object_dataset_t rive_hb_shaper_object_dataset_t +#define hb_set_t rive_hb_set_t +#define hb_map_t rive_hb_map_t +#define hb_font_funcs_t rive_hb_font_funcs_t +#define hb_trampoline_t rive_hb_trampoline_t +#define hb_codepoint_parse rive_hb_codepoint_parse +#define hb_font_draw_glyph_nil rive_hb_font_draw_glyph_nil +#define hb_draw_line_to_default rive_hb_draw_line_to_default +#define hb_draw_move_to_default rive_hb_draw_move_to_default +#define hb_font_paint_glyph_nil rive_hb_font_paint_glyph_nil +#define hb_paint_funcs_t rive_hb_paint_funcs_t +#define hb_draw_cubic_to_default rive_hb_draw_cubic_to_default +#define hb_draw_close_path_default rive_hb_draw_close_path_default +#define hb_font_draw_glyph_default rive_hb_font_draw_glyph_default +#define hb_font_get_glyph_name_nil rive_hb_font_get_glyph_name_nil +#define hb_font_paint_glyph_default rive_hb_font_paint_glyph_default +#define hb_draw_quadratic_to_default rive_hb_draw_quadratic_to_default +#define hb_font_get_glyph_extents_nil rive_hb_font_get_glyph_extents_nil +#define hb_glyph_extents_t rive_hb_glyph_extents_t +#define hb_font_get_nominal_glyph_nil rive_hb_font_get_nominal_glyph_nil +#define hb_font_get_font_h_extents_nil rive_hb_font_get_font_h_extents_nil +#define hb_font_extents_t rive_hb_font_extents_t +#define hb_font_get_font_v_extents_nil rive_hb_font_get_font_v_extents_nil +#define hb_font_get_glyph_h_origin_nil rive_hb_font_get_glyph_h_origin_nil +#define hb_font_get_glyph_name_default rive_hb_font_get_glyph_name_default +#define hb_font_get_glyph_v_origin_nil rive_hb_font_get_glyph_v_origin_nil +#define hb_font_get_glyph_from_name_nil rive_hb_font_get_glyph_from_name_nil +#define hb_font_get_glyph_h_advance_nil rive_hb_font_get_glyph_h_advance_nil +#define hb_font_get_glyph_h_kerning_nil rive_hb_font_get_glyph_h_kerning_nil +#define hb_font_get_glyph_v_advance_nil rive_hb_font_get_glyph_v_advance_nil +#define hb_font_get_glyph_v_kerning_nil rive_hb_font_get_glyph_v_kerning_nil +#define hb_font_get_variation_glyph_nil rive_hb_font_get_variation_glyph_nil +#define hb_font_get_glyph_extents_default rive_hb_font_get_glyph_extents_default +#define hb_font_get_nominal_glyph_default rive_hb_font_get_nominal_glyph_default +#define hb_font_get_font_h_extents_default rive_hb_font_get_font_h_extents_default +#define hb_font_get_font_v_extents_default rive_hb_font_get_font_v_extents_default +#define hb_font_get_glyph_h_origin_default rive_hb_font_get_glyph_h_origin_default +#define hb_font_get_glyph_v_origin_default rive_hb_font_get_glyph_v_origin_default +#define hb_font_get_nominal_glyphs_default rive_hb_font_get_nominal_glyphs_default +#define hb_font_get_glyph_contour_point_nil rive_hb_font_get_glyph_contour_point_nil +#define hb_font_get_glyph_from_name_default rive_hb_font_get_glyph_from_name_default +#define hb_font_get_glyph_h_advance_default rive_hb_font_get_glyph_h_advance_default +#define hb_font_get_glyph_h_kerning_default rive_hb_font_get_glyph_h_kerning_default +#define hb_font_get_glyph_v_advance_default rive_hb_font_get_glyph_v_advance_default +#define hb_font_get_glyph_v_kerning_default rive_hb_font_get_glyph_v_kerning_default +#define hb_font_get_variation_glyph_default rive_hb_font_get_variation_glyph_default +#define hb_font_get_glyph_h_advances_default rive_hb_font_get_glyph_h_advances_default +#define hb_font_get_glyph_v_advances_default rive_hb_font_get_glyph_v_advances_default +#define hb_font_get_nominal_glyph_trampoline rive_hb_font_get_nominal_glyph_trampoline +#define hb_font_get_variation_glyph_trampoline rive_hb_font_get_variation_glyph_trampoline +#define hb_font_get_glyph_contour_point_default rive_hb_font_get_glyph_contour_point_default +#define hb_ot_font_data_t rive_hb_ot_font_data_t +#define hb_copy rive_hb_copy +#define hb_reduce rive_hb_reduce +#define hb_reduce_t rive_hb_reduce_t +#define hb_pair_t rive_hb_pair_t +#define hb_draw_session_t rive_hb_draw_session_t +#define hb_ot_color_layer_t rive_hb_ot_color_layer_t +#define hb_paint_extents_get_funcs rive_hb_paint_extents_get_funcs +#define hb_ot_metrics_tag_t rive_hb_ot_metrics_tag_t +#define hb_outline_recording_pen_get_funcs rive_hb_outline_recording_pen_get_funcs +#define hb_ot_draw_glyph rive_hb_ot_draw_glyph +#define hb_ot_paint_glyph rive_hb_ot_paint_glyph +#define hb_ot_get_glyph_name rive_hb_ot_get_glyph_name +#define hb_ot_get_glyph_extents rive_hb_ot_get_glyph_extents +#define hb_ot_get_nominal_glyph rive_hb_ot_get_nominal_glyph +#define hb_ot_get_font_h_extents rive_hb_ot_get_font_h_extents +#define hb_ot_get_font_v_extents rive_hb_ot_get_font_v_extents +#define hb_ot_get_glyph_v_origin rive_hb_ot_get_glyph_v_origin +#define hb_ot_get_nominal_glyphs rive_hb_ot_get_nominal_glyphs +#define hb_ot_get_glyph_from_name rive_hb_ot_get_glyph_from_name +#define hb_ot_get_variation_glyph rive_hb_ot_get_variation_glyph +#define hb_ot_get_glyph_h_advances rive_hb_ot_get_glyph_h_advances +#define hb_ot_get_glyph_v_advances rive_hb_ot_get_glyph_v_advances +#define hb_ot_font_cmap_cache_user_data_key rive_hb_ot_font_cmap_cache_user_data_key +#define hb_bounds_t rive_hb_bounds_t +#define hb_transform_t rive_hb_transform_t +#define hb_memcmp rive_hb_memcmp +#define hb_extents_t rive_hb_extents_t +#define hb_outline_t rive_hb_outline_t +#define hb_empty_t rive_hb_empty_t +#define hb_ot_font_funcs_lazy_loader_t rive_hb_ot_font_funcs_lazy_loader_t +#define hb_color_line_t rive_hb_color_line_t +#define hb_paint_composite_mode_t rive_hb_paint_composite_mode_t +#define hb_paint_extents_context_t rive_hb_paint_extents_context_t +#define hb_font_funcs_lazy_loader_t rive_hb_font_funcs_lazy_loader_t +#define hb_color_stop_t rive_hb_color_stop_t +#define hb_partial rive_hb_partial +#define hb_ot_layout_kern rive_hb_ot_layout_kern +#define hb_ot_layout_has_kerning rive_hb_ot_layout_has_kerning +#define hb_ot_layout_position_start rive_hb_ot_layout_position_start +#define hb_ot_layout_substitute_start rive_hb_ot_layout_substitute_start +#define hb_ot_layout_has_cross_kerning rive_hb_ot_layout_has_cross_kerning +#define hb_ot_layout_substitute_lookup rive_hb_ot_layout_substitute_lookup +#define hb_ot_layout_table_find_feature rive_hb_ot_layout_table_find_feature +#define hb_ot_layout_has_machine_kerning rive_hb_ot_layout_has_machine_kerning +#define hb_ot_layout_position_finish_offsets rive_hb_ot_layout_position_finish_offsets +#define hb_ot_layout_position_finish_advances rive_hb_ot_layout_position_finish_advances +#define hb_popcount rive_hb_popcount +#define hb_enumerate rive_hb_enumerate +#define hb_bitwise_gt rive_hb_bitwise_gt +#define hb_bitwise_lt rive_hb_bitwise_lt +#define hb_bitwise_or rive_hb_bitwise_or +#define hb_bitwise_and rive_hb_bitwise_and +#define hb_bitwise_neg rive_hb_bitwise_neg +#define hb_unicode_general_category_t rive_hb_unicode_general_category_t +#define hb_add rive_hb_add +#define hb_all rive_hb_all +#define hb_any rive_hb_any +#define hb_ctz rive_hb_ctz +#define hb_zip rive_hb_zip +#define hb_iota rive_hb_iota +#define hb_apply rive_hb_apply +#define hb_first rive_hb_first +#define hb_range rive_hb_range +#define hb_second rive_hb_second +#define hb_apply_t rive_hb_apply_t +#define hb_partial_t rive_hb_partial_t +#define hb_range_iter_t rive_hb_range_iter_t +#define hb_zip_iter_t rive_hb_zip_iter_t +#define hb_iota_iter_t rive_hb_iota_iter_t +#define hb_collect_features_context_t rive_hb_collect_features_context_t +#define hb_position_single_dispatch_t rive_hb_position_single_dispatch_t +#define hb_get_glyph_alternates_dispatch_t rive_hb_get_glyph_alternates_dispatch_t +#define hb_ot_map_t rive_hb_ot_map_t +#define hb_ot_shape_plan_t rive_hb_ot_shape_plan_t +#define hb_ot_map_builder_t rive_hb_ot_map_builder_t +#define hb_ot_map_feature_flags_t rive_hb_ot_map_feature_flags_t +#define hb_ot_shape_plan_key_t rive_hb_ot_shape_plan_key_t +#define hb_ot_math_glyph_part_t rive_hb_ot_math_glyph_part_t +#define hb_ot_math_glyph_variant_t rive_hb_ot_math_glyph_variant_t +#define hb_ot_math_kern_t rive_hb_ot_math_kern_t +#define hb_ot_math_kern_entry_t rive_hb_ot_math_kern_entry_t +#define hb_ot_meta_tag_t rive_hb_ot_meta_tag_t +#define hb_ot_name_entry_t rive_hb_ot_name_entry_t +#define hb_ot_name_get_utf rive_hb_ot_name_get_utf +#define hb_ascii_t rive_hb_ascii_t +#define hb_ot_shape_fallback_kern_driver_t rive_hb_ot_shape_fallback_kern_driver_t +#define hb_in_ranges rive_hb_in_ranges +#define hb_ot_position rive_hb_ot_position +#define hb_form_clusters rive_hb_form_clusters +#define hb_vert_char_for rive_hb_vert_char_for +#define hb_ot_rotate_chars rive_hb_ot_rotate_chars +#define hb_propagate_flags rive_hb_propagate_flags +#define hb_ot_position_plan rive_hb_ot_position_plan +#define hb_ot_shape_internal rive_hb_ot_shape_internal +#define hb_ot_substitute_pre rive_hb_ot_substitute_pre +#define hb_set_unicode_props rive_hb_set_unicode_props +#define hb_ot_map_glyphs_fast rive_hb_ot_map_glyphs_fast +#define hb_ot_substitute_plan rive_hb_ot_substitute_plan +#define hb_ot_substitute_post rive_hb_ot_substitute_post +#define hb_ot_position_default rive_hb_ot_position_default +#define hb_insert_dotted_circle rive_hb_insert_dotted_circle +#define hb_ot_shape_setup_masks rive_hb_ot_shape_setup_masks +#define hb_ot_shaper_categorize rive_hb_ot_shaper_categorize +#define hb_ot_substitute_default rive_hb_ot_substitute_default +#define hb_ensure_native_direction rive_hb_ensure_native_direction +#define hb_synthesize_glyph_classes rive_hb_synthesize_glyph_classes +#define hb_ot_shape_collect_features rive_hb_ot_shape_collect_features +#define hb_ot_shape_initialize_masks rive_hb_ot_shape_initialize_masks +#define hb_ot_hide_default_ignorables rive_hb_ot_hide_default_ignorables +#define hb_ot_shape_setup_masks_fraction rive_hb_ot_shape_setup_masks_fraction +#define hb_ot_zero_width_default_ignorables rive_hb_ot_zero_width_default_ignorables +#define hb_shape_plan_key_t rive_hb_shape_plan_key_t +#define hb_ot_shape_planner_t rive_hb_ot_shape_planner_t +#define hb_script_t rive_hb_script_t +#define hb_map_retains_sorting rive_hb_map_retains_sorting +#define hb_pool_t rive_hb_pool_t +#define hb_len rive_hb_len +#define hb_serialize_error_t rive_hb_serialize_error_t +#define hb_indic_get_categories rive_hb_indic_get_categories +#define hb_syllabic_clear_var rive_hb_syllabic_clear_var +#define hb_syllabic_insert_dotted_circles rive_hb_syllabic_insert_dotted_circles +#define hb_options rive_hb_options +#define hb_indic_would_substitute_feature_t rive_hb_indic_would_substitute_feature_t +#define hb_ot_layout_glyph_props_flags_t rive_hb_ot_layout_glyph_props_flags_t +#define hb_use_u16 rive_hb_use_u16 +#define hb_use_get_category rive_hb_use_get_category +#define hb_use_b4 rive_hb_use_b4 +#define hb_use_u8 rive_hb_use_u8 +#define hb_ot_new_tag_to_script rive_hb_ot_new_tag_to_script +#define hb_ot_old_tag_to_script rive_hb_ot_old_tag_to_script +#define hb_ot_tags_from_language rive_hb_ot_tags_from_language +#define hb_ot_new_tag_from_script rive_hb_ot_new_tag_from_script +#define hb_ot_old_tag_from_script rive_hb_ot_old_tag_from_script +#define hb_ot_all_tags_from_script rive_hb_ot_all_tags_from_script +#define hb_ot_ambiguous_tag_to_language rive_hb_ot_ambiguous_tag_to_language +#define hb_ot_tags_from_complex_language rive_hb_ot_tags_from_complex_language +#define hb_ot_var_axis_info_t rive_hb_ot_var_axis_info_t +#define hb_ot_var_axis_t rive_hb_ot_var_axis_t +#define hb_outline_recording_pen_line_to rive_hb_outline_recording_pen_line_to +#define hb_outline_recording_pen_move_to rive_hb_outline_recording_pen_move_to +#define hb_outline_recording_pen_cubic_to rive_hb_outline_recording_pen_cubic_to +#define hb_outline_recording_pen_close_path rive_hb_outline_recording_pen_close_path +#define hb_outline_recording_pen_quadratic_to rive_hb_outline_recording_pen_quadratic_to +#define hb_outline_point_t rive_hb_outline_point_t +#define hb_outline_recording_pen_funcs_lazy_loader_t rive_hb_outline_recording_pen_funcs_lazy_loader_t +#define hb_outline_vector_t rive_hb_outline_vector_t +#define hb_draw_funcs_lazy_loader_t rive_hb_draw_funcs_lazy_loader_t +#define hb_draw_extents_line_to rive_hb_draw_extents_line_to +#define hb_draw_extents_move_to rive_hb_draw_extents_move_to +#define hb_draw_extents_cubic_to rive_hb_draw_extents_cubic_to +#define hb_draw_extents_get_funcs rive_hb_draw_extents_get_funcs +#define hb_paint_extents_pop_clip rive_hb_paint_extents_pop_clip +#define hb_paint_extents_pop_group rive_hb_paint_extents_pop_group +#define hb_paint_extents_push_group rive_hb_paint_extents_push_group +#define hb_draw_extents_quadratic_to rive_hb_draw_extents_quadratic_to +#define hb_paint_extents_paint_color rive_hb_paint_extents_paint_color +#define hb_paint_extents_paint_image rive_hb_paint_extents_paint_image +#define hb_paint_extents_pop_transform rive_hb_paint_extents_pop_transform +#define hb_paint_extents_push_transform rive_hb_paint_extents_push_transform +#define hb_paint_extents_push_clip_glyph rive_hb_paint_extents_push_clip_glyph +#define hb_paint_extents_push_clip_rectangle rive_hb_paint_extents_push_clip_rectangle +#define hb_paint_extents_paint_sweep_gradient rive_hb_paint_extents_paint_sweep_gradient +#define hb_paint_extents_paint_linear_gradient rive_hb_paint_extents_paint_linear_gradient +#define hb_paint_extents_paint_radial_gradient rive_hb_paint_extents_paint_radial_gradient +#define hb_draw_extents_funcs_lazy_loader_t rive_hb_draw_extents_funcs_lazy_loader_t +#define hb_paint_extents_funcs_lazy_loader_t rive_hb_paint_extents_funcs_lazy_loader_t +#define hb_paint_funcs_lazy_loader_t rive_hb_paint_funcs_lazy_loader_t +#define hb_paint_color_nil rive_hb_paint_color_nil +#define hb_paint_image_nil rive_hb_paint_image_nil +#define hb_paint_pop_clip_nil rive_hb_paint_pop_clip_nil +#define hb_paint_pop_group_nil rive_hb_paint_pop_group_nil +#define hb_paint_push_group_nil rive_hb_paint_push_group_nil +#define hb_paint_color_glyph_nil rive_hb_paint_color_glyph_nil +#define hb_paint_pop_transform_nil rive_hb_paint_pop_transform_nil +#define hb_paint_push_transform_nil rive_hb_paint_push_transform_nil +#define hb_paint_sweep_gradient_nil rive_hb_paint_sweep_gradient_nil +#define hb_paint_linear_gradient_nil rive_hb_paint_linear_gradient_nil +#define hb_paint_push_clip_glyph_nil rive_hb_paint_push_clip_glyph_nil +#define hb_paint_radial_gradient_nil rive_hb_paint_radial_gradient_nil +#define hb_paint_push_clip_rectangle_nil rive_hb_paint_push_clip_rectangle_nil +#define hb_paint_custom_palette_color_nil rive_hb_paint_custom_palette_color_nil +#define hb_bitwise_xor rive_hb_bitwise_xor +#define hb_shape_plan_t rive_hb_shape_plan_t +#define hb_shaper_list_lazy_loader_t rive_hb_shaper_list_lazy_loader_t +#define hb_shapers_lazy_loader_t rive_hb_shapers_lazy_loader_t +#define hb_shaper_entry_t rive_hb_shaper_entry_t +#define hb_ot_language_map_t rive_hb_ot_language_map_t +#define hb_serialize_cff_fdselect rive_hb_serialize_cff_fdselect +#define hb_plan_subset_cff_fdselect rive_hb_plan_subset_cff_fdselect +#define hb_inc_bimap_t rive_hb_inc_bimap_t +#define hb_subset_plan_t rive_hb_subset_plan_t +#define hb_subset_input_t rive_hb_subset_input_t +#define hb_subset_flags_t rive_hb_subset_flags_t +#define hb_bool rive_hb_bool +#define hb_pair rive_hb_pair +#define hb_multimap_t rive_hb_multimap_t +#define hb_subset_accelerator_t rive_hb_subset_accelerator_t +#define hb_lock_t rive_hb_lock_t +#define hb_repeat_iter_t rive_hb_repeat_iter_t +#define hb_resolve_overflows rive_hb_resolve_overflows +#define hb_resolve_graph_overflows rive_hb_resolve_graph_overflows +#define hb_subset_context_t rive_hb_subset_context_t +#define hb_ceil_to_4 rive_hb_ceil_to_4 +#define hb_take rive_hb_take +#define hb_drain rive_hb_drain +#define hb_repeat rive_hb_repeat +#define hb_priority_queue_t rive_hb_priority_queue_t +#define hb_ucd_script rive_hb_ucd_script +#define hb_ucd_compose rive_hb_ucd_compose +#define hb_ucd_decompose rive_hb_ucd_decompose +#define hb_ucd_mirroring rive_hb_ucd_mirroring +#define hb_ucd_combining_class rive_hb_ucd_combining_class +#define hb_ucd_general_category rive_hb_ucd_general_category +#define hb_ucd_unicode_funcs_lazy_loader_t rive_hb_ucd_unicode_funcs_lazy_loader_t +#define hb_unicode_funcs_lazy_loader_t rive_hb_unicode_funcs_lazy_loader_t +#define hb_unicode_script_nil rive_hb_unicode_script_nil +#define hb_unicode_compose_nil rive_hb_unicode_compose_nil +#define hb_unicode_decompose_nil rive_hb_unicode_decompose_nil +#define hb_unicode_mirroring_nil rive_hb_unicode_mirroring_nil +#define hb_unicode_combining_class_nil rive_hb_unicode_combining_class_nil +#define hb_unicode_eastasian_width_nil rive_hb_unicode_eastasian_width_nil +#define hb_unicode_general_category_nil rive_hb_unicode_general_category_nil +#define hb_unicode_decompose_compatibility_nil rive_hb_unicode_decompose_compatibility_nil +// _hb_* +#define hb_compiler_memory_r_barrier rive_hb_compiler_memory_r_barrier +#define hb_head_t rive_hb_head_t +#define hb_roundf rive_hb_roundf +#define hb_debug_msg rive_hb_debug_msg +#define hb_cmp_method rive_hb_cmp_method +#define hb_glyph_info_is_zwj rive_hb_glyph_info_is_zwj +#define hb_glyph_info_is_zwnj rive_hb_glyph_info_is_zwnj +#define hb_grapheme_group_func rive_hb_grapheme_group_func +#define hb_glyph_info_substituted rive_hb_glyph_info_substituted +#define hb_atomic_ptr_impl_cmplexch rive_hb_atomic_ptr_impl_cmplexch +#define hb_glyph_info_get_glyph_props rive_hb_glyph_info_get_glyph_props +#define hb_glyph_info_is_continuation rive_hb_glyph_info_is_continuation +#define hb_glyph_info_set_glyph_props rive_hb_glyph_info_set_glyph_props +#define hb_glyph_info_is_unicode_format rive_hb_glyph_info_is_unicode_format +#define hb_glyph_info_get_general_category rive_hb_glyph_info_get_general_category +#define hb_glyph_info_is_default_ignorable_and_not_hidden rive_hb_glyph_info_is_default_ignorable_and_not_hidden #define hb_aat_layout_feature_type_get_name_id rive_hb_aat_layout_feature_type_get_name_id #define hb_aat_layout_feature_type_get_selector_infos rive_hb_aat_layout_feature_type_get_selector_infos #define hb_aat_layout_get_feature_types rive_hb_aat_layout_get_feature_types @@ -14,30 +445,26 @@ #define hb_face_reference_table rive_hb_face_reference_table #define hb_language_from_string rive_hb_language_from_string #define hb_language_matches rive_hb_language_matches -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table #define hb_blob_copy_writable_or_fail rive_hb_blob_copy_writable_or_fail #define hb_blob_create rive_hb_blob_create #define hb_blob_create_from_file rive_hb_blob_create_from_file #define hb_blob_create_from_file_or_fail rive_hb_blob_create_from_file_or_fail #define hb_blob_create_or_fail rive_hb_blob_create_or_fail #define hb_blob_create_sub_blob rive_hb_blob_create_sub_blob -#define hb_blob_destroy rive_hb_blob_destroy #define hb_blob_get_data rive_hb_blob_get_data -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty #define hb_blob_get_length rive_hb_blob_get_length #define hb_blob_get_user_data rive_hb_blob_get_user_data #define hb_blob_is_immutable rive_hb_blob_is_immutable -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference #define hb_blob_set_user_data rive_hb_blob_set_user_data +#define hb_buffer_deserialize_json rive_hb_buffer_deserialize_json #define hb_buffer_serialize_formats rive_hb_buffer_serialize_formats +#define hb_buffer_serialize_invalid rive_hb_buffer_serialize_invalid +#define hb_buffer_serialize_glyphs_json rive_hb_buffer_serialize_glyphs_json +#define hb_buffer_serialize_glyphs_text rive_hb_buffer_serialize_glyphs_text +#define hb_buffer_serialize_unicode_json rive_hb_buffer_serialize_unicode_json +#define hb_buffer_serialize_unicode_text rive_hb_buffer_serialize_unicode_text +#define hb_buffer_deserialize_text_glyphs rive_hb_buffer_deserialize_text_glyphs +#define hb_buffer_deserialize_text_unicode rive_hb_buffer_deserialize_text_unicode #define hb_buffer_deserialize_glyphs rive_hb_buffer_deserialize_glyphs #define hb_buffer_deserialize_unicode rive_hb_buffer_deserialize_unicode #define hb_buffer_get_glyph_infos rive_hb_buffer_get_glyph_infos @@ -61,10 +488,8 @@ #define hb_buffer_diff rive_hb_buffer_diff #define hb_buffer_get_direction rive_hb_buffer_get_direction #define hb_buffer_get_flags rive_hb_buffer_get_flags -#define hb_buffer_get_glyph_infos rive_hb_buffer_get_glyph_infos #define hb_buffer_get_segment_properties rive_hb_buffer_get_segment_properties #define hb_buffer_reverse rive_hb_buffer_reverse -#define hb_buffer_serialize_unicode rive_hb_buffer_serialize_unicode #define hb_buffer_set_flags rive_hb_buffer_set_flags #define hb_buffer_set_length rive_hb_buffer_set_length #define hb_buffer_set_segment_properties rive_hb_buffer_set_segment_properties @@ -76,26 +501,16 @@ #define hb_buffer_add_utf32 rive_hb_buffer_add_utf32 #define hb_buffer_add_utf8 rive_hb_buffer_add_utf8 #define hb_buffer_allocation_successful rive_hb_buffer_allocation_successful -#define hb_buffer_append rive_hb_buffer_append -#define hb_buffer_clear_contents rive_hb_buffer_clear_contents #define hb_buffer_create rive_hb_buffer_create -#define hb_buffer_create_similar rive_hb_buffer_create_similar -#define hb_buffer_destroy rive_hb_buffer_destroy -#define hb_buffer_diff rive_hb_buffer_diff #define hb_buffer_get_cluster_level rive_hb_buffer_get_cluster_level #define hb_buffer_get_content_type rive_hb_buffer_get_content_type -#define hb_buffer_get_direction rive_hb_buffer_get_direction #define hb_buffer_get_empty rive_hb_buffer_get_empty -#define hb_buffer_get_flags rive_hb_buffer_get_flags -#define hb_buffer_get_glyph_infos rive_hb_buffer_get_glyph_infos -#define hb_buffer_get_glyph_positions rive_hb_buffer_get_glyph_positions #define hb_buffer_get_invisible_glyph rive_hb_buffer_get_invisible_glyph #define hb_buffer_get_language rive_hb_buffer_get_language #define hb_buffer_get_length rive_hb_buffer_get_length #define hb_buffer_get_not_found_glyph rive_hb_buffer_get_not_found_glyph #define hb_buffer_get_replacement_codepoint rive_hb_buffer_get_replacement_codepoint #define hb_buffer_get_script rive_hb_buffer_get_script -#define hb_buffer_get_segment_properties rive_hb_buffer_get_segment_properties #define hb_buffer_get_unicode_funcs rive_hb_buffer_get_unicode_funcs #define hb_buffer_get_user_data rive_hb_buffer_get_user_data #define hb_buffer_guess_segment_properties rive_hb_buffer_guess_segment_properties @@ -104,24 +519,18 @@ #define hb_buffer_pre_allocate rive_hb_buffer_pre_allocate #define hb_buffer_reference rive_hb_buffer_reference #define hb_buffer_reset rive_hb_buffer_reset -#define hb_buffer_reverse rive_hb_buffer_reverse #define hb_buffer_reverse_clusters rive_hb_buffer_reverse_clusters #define hb_buffer_reverse_range rive_hb_buffer_reverse_range #define hb_buffer_set_cluster_level rive_hb_buffer_set_cluster_level -#define hb_buffer_set_content_type rive_hb_buffer_set_content_type #define hb_buffer_set_direction rive_hb_buffer_set_direction -#define hb_buffer_set_flags rive_hb_buffer_set_flags #define hb_buffer_set_invisible_glyph rive_hb_buffer_set_invisible_glyph #define hb_buffer_set_language rive_hb_buffer_set_language -#define hb_buffer_set_length rive_hb_buffer_set_length #define hb_buffer_set_message_func rive_hb_buffer_set_message_func #define hb_buffer_set_not_found_glyph rive_hb_buffer_set_not_found_glyph #define hb_buffer_set_replacement_codepoint rive_hb_buffer_set_replacement_codepoint #define hb_buffer_set_script rive_hb_buffer_set_script -#define hb_buffer_set_segment_properties rive_hb_buffer_set_segment_properties #define hb_buffer_set_unicode_funcs rive_hb_buffer_set_unicode_funcs #define hb_buffer_set_user_data rive_hb_buffer_set_user_data -#define hb_language_get_default rive_hb_language_get_default #define hb_script_get_horizontal_direction rive_hb_script_get_horizontal_direction #define hb_segment_properties_equal rive_hb_segment_properties_equal #define hb_segment_properties_hash rive_hb_segment_properties_hash @@ -129,29 +538,29 @@ #define hb_unicode_funcs_destroy rive_hb_unicode_funcs_destroy #define hb_unicode_funcs_get_default rive_hb_unicode_funcs_get_default #define hb_unicode_funcs_reference rive_hb_unicode_funcs_reference +#define hb_options_init rive_hb_options_init #define hb_direction_from_string rive_hb_direction_from_string #define hb_direction_to_string rive_hb_direction_to_string #define hb_feature_from_string rive_hb_feature_from_string #define hb_feature_to_string rive_hb_feature_to_string -#define hb_language_from_string rive_hb_language_from_string -#define hb_language_get_default rive_hb_language_get_default -#define hb_language_matches rive_hb_language_matches #define hb_language_to_string rive_hb_language_to_string #define hb_script_from_iso15924_tag rive_hb_script_from_iso15924_tag #define hb_script_from_string rive_hb_script_from_string -#define hb_script_get_horizontal_direction rive_hb_script_get_horizontal_direction #define hb_script_to_iso15924_tag rive_hb_script_to_iso15924_tag -#define hb_tag_from_string rive_hb_tag_from_string #define hb_tag_to_string rive_hb_tag_to_string #define hb_variation_from_string rive_hb_variation_from_string #define hb_variation_to_string rive_hb_variation_to_string #define hb_version rive_hb_version #define hb_version_atleast rive_hb_version_atleast #define hb_version_string rive_hb_version_string +#define hb_draw_funcs_set_middle rive_hb_draw_funcs_set_middle +#define hb_draw_funcs_set_preamble rive_hb_draw_funcs_set_preamble #define hb_draw_close_path rive_hb_draw_close_path #define hb_draw_cubic_to rive_hb_draw_cubic_to #define hb_draw_funcs_create rive_hb_draw_funcs_create #define hb_draw_funcs_destroy rive_hb_draw_funcs_destroy +#define hb_draw_funcs_get_empty rive_hb_draw_funcs_get_empty +#define hb_draw_funcs_get_user_data rive_hb_draw_funcs_get_user_data #define hb_draw_funcs_is_immutable rive_hb_draw_funcs_is_immutable #define hb_draw_funcs_make_immutable rive_hb_draw_funcs_make_immutable #define hb_draw_funcs_reference rive_hb_draw_funcs_reference @@ -160,22 +569,20 @@ #define hb_draw_funcs_set_line_to_func rive_hb_draw_funcs_set_line_to_func #define hb_draw_funcs_set_move_to_func rive_hb_draw_funcs_set_move_to_func #define hb_draw_funcs_set_quadratic_to_func rive_hb_draw_funcs_set_quadratic_to_func +#define hb_draw_funcs_set_user_data rive_hb_draw_funcs_set_user_data #define hb_draw_line_to rive_hb_draw_line_to #define hb_draw_move_to rive_hb_draw_move_to #define hb_draw_quadratic_to rive_hb_draw_quadratic_to +#define hb_arabic_b2 rive_hb_arabic_b2 +#define hb_arabic_b4 rive_hb_arabic_b4 #define hb_arabic_u8 rive_hb_arabic_u8 #define hb_arabic_u16 rive_hb_arabic_u16 -#define hb_blob_create rive_hb_blob_create -#define hb_blob_create_sub_blob rive_hb_blob_create_sub_blob -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_get_length rive_hb_blob_get_length -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_builder_add_table rive_hb_face_builder_add_table -#define hb_face_builder_create rive_hb_face_builder_create -#define hb_face_builder_sort_tables rive_hb_face_builder_sort_tables +#define hb_arabic_pua_simp_map rive_hb_arabic_pua_simp_map +#define hb_arabic_pua_trad_map rive_hb_arabic_pua_trad_map +#define hb_face_for_data_closure_create rive_hb_face_for_data_closure_create +#define hb_face_for_data_closure_destroy rive_hb_face_for_data_closure_destroy +#define hb_face_for_data_reference_table rive_hb_face_for_data_reference_table +#define hb_face_collect_nominal_glyph_mapping rive_hb_face_collect_nominal_glyph_mapping #define hb_face_collect_unicodes rive_hb_face_collect_unicodes #define hb_face_collect_variation_selectors rive_hb_face_collect_variation_selectors #define hb_face_collect_variation_unicodes rive_hb_face_collect_variation_unicodes @@ -184,7 +591,6 @@ #define hb_face_create_for_tables rive_hb_face_create_for_tables #define hb_face_destroy rive_hb_face_destroy #define hb_face_get_empty rive_hb_face_get_empty -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count #define hb_face_get_index rive_hb_face_get_index #define hb_face_get_table_tags rive_hb_face_get_table_tags #define hb_face_get_upem rive_hb_face_get_upem @@ -193,30 +599,22 @@ #define hb_face_make_immutable rive_hb_face_make_immutable #define hb_face_reference rive_hb_face_reference #define hb_face_reference_blob rive_hb_face_reference_blob -#define hb_face_reference_table rive_hb_face_reference_table #define hb_face_set_glyph_count rive_hb_face_set_glyph_count #define hb_face_set_index rive_hb_face_set_index #define hb_face_set_upem rive_hb_face_set_upem #define hb_face_set_user_data rive_hb_face_set_user_data #define hb_shape_plan_destroy rive_hb_shape_plan_destroy +#define hb_font_create rive_hb_font_create #define hb_draw_funcs_default rive_hb_draw_funcs_default #define hb_font_funcs_default rive_hb_font_funcs_default -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_destroy rive_hb_face_destroy -#define hb_face_get_empty rive_hb_face_get_empty -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_make_immutable rive_hb_face_make_immutable -#define hb_face_reference rive_hb_face_reference -#define hb_face_reference_table rive_hb_face_reference_table +#define hb_font_adopt_var_coords rive_hb_font_adopt_var_coords +#define hb_font_funcs_set_middle rive_hb_font_funcs_set_middle +#define hb_font_funcs_set_preamble rive_hb_font_funcs_set_preamble #define hb_font_add_glyph_origin_for_direction rive_hb_font_add_glyph_origin_for_direction #define hb_font_changed rive_hb_font_changed -#define hb_font_create rive_hb_font_create #define hb_font_create_sub_font rive_hb_font_create_sub_font #define hb_font_destroy rive_hb_font_destroy +#define hb_font_draw_glyph rive_hb_font_draw_glyph #define hb_font_funcs_create rive_hb_font_funcs_create #define hb_font_funcs_destroy rive_hb_font_funcs_destroy #define hb_font_funcs_get_empty rive_hb_font_funcs_get_empty @@ -224,6 +622,7 @@ #define hb_font_funcs_is_immutable rive_hb_font_funcs_is_immutable #define hb_font_funcs_make_immutable rive_hb_font_funcs_make_immutable #define hb_font_funcs_reference rive_hb_font_funcs_reference +#define hb_font_funcs_set_draw_glyph_func rive_hb_font_funcs_set_draw_glyph_func #define hb_font_funcs_set_font_h_extents_func rive_hb_font_funcs_set_font_h_extents_func #define hb_font_funcs_set_font_v_extents_func rive_hb_font_funcs_set_font_v_extents_func #define hb_font_funcs_set_glyph_contour_point_func rive_hb_font_funcs_set_glyph_contour_point_func @@ -242,9 +641,9 @@ #define hb_font_funcs_set_glyph_v_origin_func rive_hb_font_funcs_set_glyph_v_origin_func #define hb_font_funcs_set_nominal_glyph_func rive_hb_font_funcs_set_nominal_glyph_func #define hb_font_funcs_set_nominal_glyphs_func rive_hb_font_funcs_set_nominal_glyphs_func +#define hb_font_funcs_set_paint_glyph_func rive_hb_font_funcs_set_paint_glyph_func #define hb_font_funcs_set_user_data rive_hb_font_funcs_set_user_data #define hb_font_funcs_set_variation_glyph_func rive_hb_font_funcs_set_variation_glyph_func -#define hb_font_get_empty rive_hb_font_get_empty #define hb_font_get_extents_for_direction rive_hb_font_get_extents_for_direction #define hb_font_get_face rive_hb_font_get_face #define hb_font_get_glyph rive_hb_font_get_glyph @@ -252,7 +651,6 @@ #define hb_font_get_glyph_advances_for_direction rive_hb_font_get_glyph_advances_for_direction #define hb_font_get_glyph_contour_point rive_hb_font_get_glyph_contour_point #define hb_font_get_glyph_contour_point_for_origin rive_hb_font_get_glyph_contour_point_for_origin -#define hb_font_get_glyph_extents rive_hb_font_get_glyph_extents #define hb_font_get_glyph_extents_for_origin rive_hb_font_get_glyph_extents_for_origin #define hb_font_get_glyph_from_name rive_hb_font_get_glyph_from_name #define hb_font_get_glyph_h_advance rive_hb_font_get_glyph_h_advance @@ -275,16 +673,17 @@ #define hb_font_get_ptem rive_hb_font_get_ptem #define hb_font_get_scale rive_hb_font_get_scale #define hb_font_get_serial rive_hb_font_get_serial +#define hb_font_get_synthetic_bold rive_hb_font_get_synthetic_bold #define hb_font_get_synthetic_slant rive_hb_font_get_synthetic_slant #define hb_font_get_user_data rive_hb_font_get_user_data #define hb_font_get_v_extents rive_hb_font_get_v_extents #define hb_font_get_var_coords_design rive_hb_font_get_var_coords_design #define hb_font_get_var_coords_normalized rive_hb_font_get_var_coords_normalized +#define hb_font_get_var_named_instance rive_hb_font_get_var_named_instance #define hb_font_get_variation_glyph rive_hb_font_get_variation_glyph -#define hb_font_glyph_from_string rive_hb_font_glyph_from_string -#define hb_font_glyph_to_string rive_hb_font_glyph_to_string #define hb_font_is_immutable rive_hb_font_is_immutable #define hb_font_make_immutable rive_hb_font_make_immutable +#define hb_font_paint_glyph rive_hb_font_paint_glyph #define hb_font_reference rive_hb_font_reference #define hb_font_set_face rive_hb_font_set_face #define hb_font_set_funcs rive_hb_font_set_funcs @@ -293,11 +692,13 @@ #define hb_font_set_ppem rive_hb_font_set_ppem #define hb_font_set_ptem rive_hb_font_set_ptem #define hb_font_set_scale rive_hb_font_set_scale +#define hb_font_set_synthetic_bold rive_hb_font_set_synthetic_bold #define hb_font_set_synthetic_slant rive_hb_font_set_synthetic_slant #define hb_font_set_user_data rive_hb_font_set_user_data #define hb_font_set_var_coords_design rive_hb_font_set_var_coords_design #define hb_font_set_var_coords_normalized rive_hb_font_set_var_coords_normalized #define hb_font_set_var_named_instance rive_hb_font_set_var_named_instance +#define hb_font_set_variation rive_hb_font_set_variation #define hb_font_set_variations rive_hb_font_set_variations #define hb_font_subtract_glyph_origin_for_direction rive_hb_font_subtract_glyph_origin_for_direction #define hb_ot_font_set_funcs rive_hb_ot_font_set_funcs @@ -317,22 +718,19 @@ #define hb_map_hash rive_hb_map_hash #define hb_map_is_empty rive_hb_map_is_empty #define hb_map_is_equal rive_hb_map_is_equal +#define hb_map_keys rive_hb_map_keys +#define hb_map_next rive_hb_map_next #define hb_map_reference rive_hb_map_reference #define hb_map_set rive_hb_map_set #define hb_map_set_user_data rive_hb_map_set_user_data -#define hb_blob_create_sub_blob rive_hb_blob_create_sub_blob -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_get_upem rive_hb_face_get_upem -#define hb_face_reference_table rive_hb_face_reference_table +#define hb_map_update rive_hb_map_update +#define hb_map_values rive_hb_map_values #define hb_ot_color_glyph_get_layers rive_hb_ot_color_glyph_get_layers +#define hb_ot_color_glyph_has_paint rive_hb_ot_color_glyph_has_paint #define hb_ot_color_glyph_reference_png rive_hb_ot_color_glyph_reference_png #define hb_ot_color_glyph_reference_svg rive_hb_ot_color_glyph_reference_svg #define hb_ot_color_has_layers rive_hb_ot_color_has_layers +#define hb_ot_color_has_paint rive_hb_ot_color_has_paint #define hb_ot_color_has_palettes rive_hb_ot_color_has_palettes #define hb_ot_color_has_png rive_hb_ot_color_has_png #define hb_ot_color_has_svg rive_hb_ot_color_has_svg @@ -341,49 +739,28 @@ #define hb_ot_color_palette_get_count rive_hb_ot_color_palette_get_count #define hb_ot_color_palette_get_flags rive_hb_ot_color_palette_get_flags #define hb_ot_color_palette_get_name_id rive_hb_ot_color_palette_get_name_id -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_arabic_u8 rive_hb_arabic_u8 -#define hb_arabic_u16 rive_hb_arabic_u16 -#define hb_blob_create_sub_blob rive_hb_blob_create_sub_blob -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_get_upem rive_hb_face_get_upem -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_font_funcs_create rive_hb_font_funcs_create -#define hb_font_funcs_destroy rive_hb_font_funcs_destroy -#define hb_font_funcs_get_empty rive_hb_font_funcs_get_empty -#define hb_font_funcs_make_immutable rive_hb_font_funcs_make_immutable -#define hb_font_funcs_set_font_h_extents_func rive_hb_font_funcs_set_font_h_extents_func -#define hb_font_funcs_set_font_v_extents_func rive_hb_font_funcs_set_font_v_extents_func -#define hb_font_funcs_set_glyph_extents_func rive_hb_font_funcs_set_glyph_extents_func -#define hb_font_funcs_set_glyph_from_name_func rive_hb_font_funcs_set_glyph_from_name_func -#define hb_font_funcs_set_glyph_h_advances_func rive_hb_font_funcs_set_glyph_h_advances_func -#define hb_font_funcs_set_glyph_name_func rive_hb_font_funcs_set_glyph_name_func -#define hb_font_funcs_set_glyph_shape_func rive_hb_font_funcs_set_glyph_shape_func -#define hb_font_funcs_set_glyph_v_advances_func rive_hb_font_funcs_set_glyph_v_advances_func -#define hb_font_funcs_set_glyph_v_origin_func rive_hb_font_funcs_set_glyph_v_origin_func -#define hb_font_funcs_set_nominal_glyph_func rive_hb_font_funcs_set_nominal_glyph_func -#define hb_font_funcs_set_nominal_glyphs_func rive_hb_font_funcs_set_nominal_glyphs_func -#define hb_font_funcs_set_variation_glyph_func rive_hb_font_funcs_set_variation_glyph_func -#define hb_font_set_funcs rive_hb_font_set_funcs -#define hb_ot_font_set_funcs rive_hb_ot_font_set_funcs -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_buffer_get_glyph_positions rive_hb_buffer_get_glyph_positions -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_font_get_extents_for_direction rive_hb_font_get_extents_for_direction -#define hb_font_get_glyph_extents rive_hb_font_get_glyph_extents -#define hb_font_get_nominal_glyph rive_hb_font_get_nominal_glyph +#define hb_ot_metrics_get_position_common rive_hb_ot_metrics_get_position_common +#define hb_ot_font_create rive_hb_ot_font_create +#define hb_ot_font_destroy rive_hb_ot_font_destroy +#define hb_ot_get_font_funcs rive_hb_ot_get_font_funcs +#define hb_allocate_lig_id rive_hb_allocate_lig_id +#define hb_glyph_info_is_mark rive_hb_glyph_info_is_mark +#define hb_glyph_info_get_lig_id rive_hb_glyph_info_get_lig_id +#define hb_glyph_info_multiplied rive_hb_glyph_info_multiplied +#define hb_glyph_info_is_ligature rive_hb_glyph_info_is_ligature +#define hb_glyph_info_get_lig_comp rive_hb_glyph_info_get_lig_comp +#define hb_glyph_info_is_base_glyph rive_hb_glyph_info_is_base_glyph +#define hb_ot_layout_set_glyph_props rive_hb_ot_layout_set_glyph_props +#define hb_glyph_info_clear_lig_props rive_hb_glyph_info_clear_lig_props +#define hb_buffer_assert_gsubgpos_vars rive_hb_buffer_assert_gsubgpos_vars +#define hb_glyph_info_ligated_internal rive_hb_glyph_info_ligated_internal +#define hb_glyph_info_get_lig_num_comps rive_hb_glyph_info_get_lig_num_comps +#define hb_glyph_info_set_general_category rive_hb_glyph_info_set_general_category +#define hb_glyph_info_set_lig_props_for_mark rive_hb_glyph_info_set_lig_props_for_mark +#define hb_glyph_info_set_lig_props_for_ligature rive_hb_glyph_info_set_lig_props_for_ligature +#define hb_glyph_info_set_lig_props_for_component rive_hb_glyph_info_set_lig_props_for_component #define hb_ot_layout_collect_features rive_hb_ot_layout_collect_features +#define hb_ot_layout_collect_features_map rive_hb_ot_layout_collect_features_map #define hb_ot_layout_collect_lookups rive_hb_ot_layout_collect_lookups #define hb_ot_layout_feature_get_characters rive_hb_ot_layout_feature_get_characters #define hb_ot_layout_feature_get_lookups rive_hb_ot_layout_feature_get_lookups @@ -391,7 +768,11 @@ #define hb_ot_layout_feature_with_variations_get_lookups rive_hb_ot_layout_feature_with_variations_get_lookups #define hb_ot_layout_get_attach_points rive_hb_ot_layout_get_attach_points #define hb_ot_layout_get_baseline rive_hb_ot_layout_get_baseline +#define hb_ot_layout_get_baseline2 rive_hb_ot_layout_get_baseline2 #define hb_ot_layout_get_baseline_with_fallback rive_hb_ot_layout_get_baseline_with_fallback +#define hb_ot_layout_get_baseline_with_fallback2 rive_hb_ot_layout_get_baseline_with_fallback2 +#define hb_ot_layout_get_font_extents rive_hb_ot_layout_get_font_extents +#define hb_ot_layout_get_font_extents2 rive_hb_ot_layout_get_font_extents2 #define hb_ot_layout_get_glyph_class rive_hb_ot_layout_get_glyph_class #define hb_ot_layout_get_glyphs_in_class rive_hb_ot_layout_get_glyphs_in_class #define hb_ot_layout_get_horizontal_baseline_tag_for_script rive_hb_ot_layout_get_horizontal_baseline_tag_for_script @@ -414,6 +795,7 @@ #define hb_ot_layout_script_find_language rive_hb_ot_layout_script_find_language #define hb_ot_layout_script_get_language_tags rive_hb_ot_layout_script_get_language_tags #define hb_ot_layout_script_select_language rive_hb_ot_layout_script_select_language +#define hb_ot_layout_script_select_language2 rive_hb_ot_layout_script_select_language2 #define hb_ot_layout_table_choose_script rive_hb_ot_layout_table_choose_script #define hb_ot_layout_table_find_feature_variations rive_hb_ot_layout_table_find_feature_variations #define hb_ot_layout_table_find_script rive_hb_ot_layout_table_find_script @@ -422,30 +804,14 @@ #define hb_ot_layout_table_get_script_tags rive_hb_ot_layout_table_get_script_tags #define hb_ot_layout_table_select_script rive_hb_ot_layout_table_select_script #define hb_ot_metrics_get_position_with_fallback rive_hb_ot_metrics_get_position_with_fallback +#define hb_ot_tags_from_script_and_language rive_hb_ot_tags_from_script_and_language #define hb_set_add_range rive_hb_set_add_range -#define hb_set_clear rive_hb_set_clear #define hb_set_create rive_hb_set_create #define hb_set_destroy rive_hb_set_destroy #define hb_set_get_empty rive_hb_set_get_empty #define hb_set_get_user_data rive_hb_set_get_user_data -#define hb_set_has rive_hb_set_has -#define hb_set_next rive_hb_set_next #define hb_set_reference rive_hb_set_reference #define hb_set_set_user_data rive_hb_set_set_user_data -#define hb_ot_layout_feature_with_variations_get_lookups rive_hb_ot_layout_feature_with_variations_get_lookups -#define hb_ot_layout_language_find_feature rive_hb_ot_layout_language_find_feature -#define hb_ot_layout_language_get_required_feature rive_hb_ot_layout_language_get_required_feature -#define hb_ot_layout_script_select_language rive_hb_ot_layout_script_select_language -#define hb_ot_layout_table_get_lookup_count rive_hb_ot_layout_table_get_lookup_count -#define hb_ot_layout_table_select_script rive_hb_ot_layout_table_select_script -#define hb_ot_tags_from_script_and_language rive_hb_ot_tags_from_script_and_language -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table #define hb_ot_math_get_constant rive_hb_ot_math_get_constant #define hb_ot_math_get_glyph_assembly rive_hb_ot_math_get_glyph_assembly #define hb_ot_math_get_glyph_italics_correction rive_hb_ot_math_get_glyph_italics_correction @@ -456,97 +822,58 @@ #define hb_ot_math_get_min_connector_overlap rive_hb_ot_math_get_min_connector_overlap #define hb_ot_math_has_data rive_hb_ot_math_has_data #define hb_ot_math_is_glyph_extended_shape rive_hb_ot_math_is_glyph_extended_shape -#define hb_blob_create_sub_blob rive_hb_blob_create_sub_blob -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table #define hb_ot_meta_get_entry_tags rive_hb_ot_meta_get_entry_tags #define hb_ot_meta_reference_entry rive_hb_ot_meta_reference_entry -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_font_get_extents_for_direction rive_hb_font_get_extents_for_direction -#define hb_font_get_glyph_extents rive_hb_font_get_glyph_extents -#define hb_font_get_nominal_glyph rive_hb_font_get_nominal_glyph #define hb_ot_metrics_get_position rive_hb_ot_metrics_get_position -#define hb_ot_metrics_get_position_with_fallback rive_hb_ot_metrics_get_position_with_fallback #define hb_ot_metrics_get_variation rive_hb_ot_metrics_get_variation #define hb_ot_metrics_get_x_variation rive_hb_ot_metrics_get_x_variation #define hb_ot_metrics_get_y_variation rive_hb_ot_metrics_get_y_variation -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_language_from_string rive_hb_language_from_string -#define hb_language_matches rive_hb_language_matches -#define hb_language_to_string rive_hb_language_to_string +#define hb_ot_name_language_for_ms_code rive_hb_ot_name_language_for_ms_code +#define hb_ot_name_language_for_mac_code rive_hb_ot_name_language_for_mac_code #define hb_ot_name_get_utf16 rive_hb_ot_name_get_utf16 #define hb_ot_name_get_utf32 rive_hb_ot_name_get_utf32 #define hb_ot_name_get_utf8 rive_hb_ot_name_get_utf8 #define hb_ot_name_list_names rive_hb_ot_name_list_names -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_script_get_horizontal_direction rive_hb_script_get_horizontal_direction -#define hb_aat_layout_has_positioning rive_hb_aat_layout_has_positioning -#define hb_aat_layout_has_substitution rive_hb_aat_layout_has_substitution -#define hb_aat_layout_has_tracking rive_hb_aat_layout_has_tracking -#define hb_buffer_reverse rive_hb_buffer_reverse -#define hb_ot_layout_has_glyph_classes rive_hb_ot_layout_has_glyph_classes -#define hb_ot_layout_has_positioning rive_hb_ot_layout_has_positioning -#define hb_ot_layout_has_substitution rive_hb_ot_layout_has_substitution -#define hb_ot_layout_lookups_substitute_closure rive_hb_ot_layout_lookups_substitute_closure +#define hb_ot_shape_fallback_kern rive_hb_ot_shape_fallback_kern +#define hb_ot_shape_fallback_spaces rive_hb_ot_shape_fallback_spaces +#define hb_ot_shape_fallback_mark_position rive_hb_ot_shape_fallback_mark_position +#define hb_ot_shape_fallback_mark_position_recategorize_marks rive_hb_ot_shape_fallback_mark_position_recategorize_marks +#define hb_glyph_info_ligated rive_hb_glyph_info_ligated +#define hb_glyph_info_is_unicode_mark rive_hb_glyph_info_is_unicode_mark +#define hb_glyph_info_is_unicode_space rive_hb_glyph_info_is_unicode_space +#define hb_glyph_info_get_modified_combining_class rive_hb_glyph_info_get_modified_combining_class +#define hb_glyph_info_set_modified_combining_class rive_hb_glyph_info_set_modified_combining_class +#define hb_glyph_info_get_unicode_space_fallback_type rive_hb_glyph_info_get_unicode_space_fallback_type +#define hb_ot_shape_normalize rive_hb_ot_shape_normalize +#define hb_glyph_info_unhide rive_hb_glyph_info_unhide +#define hb_buffer_assert_unicode_vars rive_hb_buffer_assert_unicode_vars +#define hb_glyph_info_set_unicode_props rive_hb_glyph_info_set_unicode_props +#define hb_glyph_info_set_unicode_space_fallback_type rive_hb_glyph_info_set_unicode_space_fallback_type +#define hb_unicode_is_emoji_Extended_Pictographic rive_hb_unicode_is_emoji_Extended_Pictographic +#define hb_apply_morx rive_hb_apply_morx +#define hb_glyph_info_set_continuation rive_hb_glyph_info_set_continuation +#define hb_ot_layout_reverse_graphemes rive_hb_ot_layout_reverse_graphemes +#define hb_buffer_allocate_unicode_vars rive_hb_buffer_allocate_unicode_vars +#define hb_buffer_allocate_gsubgpos_vars rive_hb_buffer_allocate_gsubgpos_vars +#define hb_buffer_deallocate_unicode_vars rive_hb_buffer_deallocate_unicode_vars +#define hb_buffer_deallocate_gsubgpos_vars rive_hb_buffer_deallocate_gsubgpos_vars +#define hb_codepoint_is_regional_indicator rive_hb_codepoint_is_regional_indicator +#define hb_glyph_info_is_default_ignorable rive_hb_glyph_info_is_default_ignorable #define hb_ot_shape_glyphs_closure rive_hb_ot_shape_glyphs_closure #define hb_ot_shape_plan_collect_lookups rive_hb_ot_shape_plan_collect_lookups -#define hb_script_get_horizontal_direction rive_hb_script_get_horizontal_direction -#define hb_set_create rive_hb_set_create -#define hb_set_destroy rive_hb_set_destroy #define hb_shape_plan_create_cached rive_hb_shape_plan_create_cached -#define hb_shape_plan_destroy rive_hb_shape_plan_destroy -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_font_get_glyph rive_hb_font_get_glyph -#define hb_font_get_glyph rive_hb_font_get_glyph -#define hb_font_get_glyph_h_advance rive_hb_font_get_glyph_h_advance -#define hb_ot_layout_lookup_would_substitute rive_hb_ot_layout_lookup_would_substitute -#define hb_font_get_glyph rive_hb_font_get_glyph -#define hb_language_from_string rive_hb_language_from_string -#define hb_language_to_string rive_hb_language_to_string +#define hb_preprocess_text_vowel_constraints rive_hb_preprocess_text_vowel_constraints +#define hb_next_syllable rive_hb_next_syllable +#define hb_glyph_info_ligated_and_didnt_multiply rive_hb_glyph_info_ligated_and_didnt_multiply +#define hb_glyph_info_clear_ligated_and_multiplied rive_hb_glyph_info_clear_ligated_and_multiplied +#define hb_clear_substitution_flags rive_hb_clear_substitution_flags +#define hb_glyph_info_clear_substituted rive_hb_glyph_info_clear_substituted +#define hb_glyph_info_reset_continuation rive_hb_glyph_info_reset_continuation #define hb_ot_tag_from_language rive_hb_ot_tag_from_language #define hb_ot_tag_to_language rive_hb_ot_tag_to_language #define hb_ot_tag_to_script rive_hb_ot_tag_to_script #define hb_ot_tags_from_script rive_hb_ot_tags_from_script -#define hb_ot_tags_from_script_and_language rive_hb_ot_tags_from_script_and_language #define hb_ot_tags_to_script_and_language rive_hb_ot_tags_to_script_and_language -#define hb_tag_from_string rive_hb_tag_from_string -#define hb_tag_to_string rive_hb_tag_to_string -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table #define hb_ot_var_find_axis rive_hb_ot_var_find_axis #define hb_ot_var_find_axis_info rive_hb_ot_var_find_axis_info #define hb_ot_var_get_axes rive_hb_ot_var_get_axes @@ -554,110 +881,100 @@ #define hb_ot_var_get_axis_infos rive_hb_ot_var_get_axis_infos #define hb_ot_var_get_named_instance_count rive_hb_ot_var_get_named_instance_count #define hb_ot_var_has_data rive_hb_ot_var_has_data -#define hb_ot_var_named_instance_get_design_coords rive_hb_ot_var_named_instance_get_design_coords #define hb_ot_var_named_instance_get_postscript_name_id rive_hb_ot_var_named_instance_get_postscript_name_id #define hb_ot_var_named_instance_get_subfamily_name_id rive_hb_ot_var_named_instance_get_subfamily_name_id -#define hb_ot_var_normalize_coords rive_hb_ot_var_normalize_coords #define hb_ot_var_normalize_variations rive_hb_ot_var_normalize_variations +#define hb_paint_funcs_create rive_hb_paint_funcs_create +#define hb_paint_funcs_destroy rive_hb_paint_funcs_destroy +#define hb_paint_funcs_get_empty rive_hb_paint_funcs_get_empty +#define hb_paint_funcs_make_immutable rive_hb_paint_funcs_make_immutable +#define hb_paint_funcs_set_color_func rive_hb_paint_funcs_set_color_func +#define hb_paint_funcs_set_image_func rive_hb_paint_funcs_set_image_func +#define hb_paint_funcs_set_linear_gradient_func rive_hb_paint_funcs_set_linear_gradient_func +#define hb_paint_funcs_set_pop_clip_func rive_hb_paint_funcs_set_pop_clip_func +#define hb_paint_funcs_set_pop_group_func rive_hb_paint_funcs_set_pop_group_func +#define hb_paint_funcs_set_pop_transform_func rive_hb_paint_funcs_set_pop_transform_func +#define hb_paint_funcs_set_push_clip_glyph_func rive_hb_paint_funcs_set_push_clip_glyph_func +#define hb_paint_funcs_set_push_clip_rectangle_func rive_hb_paint_funcs_set_push_clip_rectangle_func +#define hb_paint_funcs_set_push_group_func rive_hb_paint_funcs_set_push_group_func +#define hb_paint_funcs_set_push_transform_func rive_hb_paint_funcs_set_push_transform_func +#define hb_paint_funcs_set_radial_gradient_func rive_hb_paint_funcs_set_radial_gradient_func +#define hb_paint_funcs_set_sweep_gradient_func rive_hb_paint_funcs_set_sweep_gradient_func +#define hb_paint_funcs_set_middle rive_hb_paint_funcs_set_middle +#define hb_paint_funcs_set_preamble rive_hb_paint_funcs_set_preamble +#define hb_color_line_get_color_stops rive_hb_color_line_get_color_stops +#define hb_color_line_get_extend rive_hb_color_line_get_extend +#define hb_paint_color rive_hb_paint_color +#define hb_paint_color_glyph rive_hb_paint_color_glyph +#define hb_paint_custom_palette_color rive_hb_paint_custom_palette_color +#define hb_paint_funcs_get_user_data rive_hb_paint_funcs_get_user_data +#define hb_paint_funcs_is_immutable rive_hb_paint_funcs_is_immutable +#define hb_paint_funcs_reference rive_hb_paint_funcs_reference +#define hb_paint_funcs_set_color_glyph_func rive_hb_paint_funcs_set_color_glyph_func +#define hb_paint_funcs_set_custom_palette_color_func rive_hb_paint_funcs_set_custom_palette_color_func +#define hb_paint_funcs_set_user_data rive_hb_paint_funcs_set_user_data +#define hb_paint_image rive_hb_paint_image +#define hb_paint_linear_gradient rive_hb_paint_linear_gradient +#define hb_paint_pop_clip rive_hb_paint_pop_clip +#define hb_paint_pop_group rive_hb_paint_pop_group +#define hb_paint_pop_transform rive_hb_paint_pop_transform +#define hb_paint_push_clip_glyph rive_hb_paint_push_clip_glyph +#define hb_paint_push_clip_rectangle rive_hb_paint_push_clip_rectangle +#define hb_paint_push_group rive_hb_paint_push_group +#define hb_paint_push_transform rive_hb_paint_push_transform +#define hb_paint_radial_gradient rive_hb_paint_radial_gradient +#define hb_paint_sweep_gradient rive_hb_paint_sweep_gradient #define hb_set_add rive_hb_set_add -#define hb_set_add_range rive_hb_set_add_range #define hb_set_add_sorted_array rive_hb_set_add_sorted_array #define hb_set_allocation_successful rive_hb_set_allocation_successful #define hb_set_clear rive_hb_set_clear #define hb_set_copy rive_hb_set_copy -#define hb_set_create rive_hb_set_create #define hb_set_del rive_hb_set_del #define hb_set_del_range rive_hb_set_del_range -#define hb_set_destroy rive_hb_set_destroy -#define hb_set_get_empty rive_hb_set_get_empty #define hb_set_get_max rive_hb_set_get_max #define hb_set_get_min rive_hb_set_get_min #define hb_set_get_population rive_hb_set_get_population -#define hb_set_get_user_data rive_hb_set_get_user_data #define hb_set_has rive_hb_set_has #define hb_set_hash rive_hb_set_hash #define hb_set_intersect rive_hb_set_intersect #define hb_set_invert rive_hb_set_invert #define hb_set_is_empty rive_hb_set_is_empty #define hb_set_is_equal rive_hb_set_is_equal +#define hb_set_is_inverted rive_hb_set_is_inverted #define hb_set_is_subset rive_hb_set_is_subset #define hb_set_next rive_hb_set_next #define hb_set_next_many rive_hb_set_next_many #define hb_set_next_range rive_hb_set_next_range #define hb_set_previous rive_hb_set_previous #define hb_set_previous_range rive_hb_set_previous_range -#define hb_set_reference rive_hb_set_reference #define hb_set_set rive_hb_set_set -#define hb_set_set_user_data rive_hb_set_set_user_data #define hb_set_subtract rive_hb_set_subtract #define hb_set_symmetric_difference rive_hb_set_symmetric_difference #define hb_set_union rive_hb_set_union -#define hb_face_get_empty rive_hb_face_get_empty -#define hb_face_make_immutable rive_hb_face_make_immutable -#define hb_ot_layout_table_find_feature_variations rive_hb_ot_layout_table_find_feature_variations -#define hb_segment_properties_equal rive_hb_segment_properties_equal +#define hb_shapers_get rive_hb_shapers_get +#define hb_shape_plan_execute_internal rive_hb_shape_plan_execute_internal #define hb_shape_plan_create rive_hb_shape_plan_create #define hb_shape_plan_create2 rive_hb_shape_plan_create2 -#define hb_shape_plan_create_cached rive_hb_shape_plan_create_cached #define hb_shape_plan_create_cached2 rive_hb_shape_plan_create_cached2 -#define hb_shape_plan_destroy rive_hb_shape_plan_destroy #define hb_shape_plan_execute rive_hb_shape_plan_execute #define hb_shape_plan_get_empty rive_hb_shape_plan_get_empty #define hb_shape_plan_get_shaper rive_hb_shape_plan_get_shaper #define hb_shape_plan_get_user_data rive_hb_shape_plan_get_user_data #define hb_shape_plan_reference rive_hb_shape_plan_reference #define hb_shape_plan_set_user_data rive_hb_shape_plan_set_user_data -#define hb_buffer_append rive_hb_buffer_append -#define hb_buffer_create rive_hb_buffer_create -#define hb_buffer_destroy rive_hb_buffer_destroy #define hb_shape rive_hb_shape -#define hb_shape_full rive_hb_shape_full #define hb_shape_list_shapers rive_hb_shape_list_shapers -#define hb_shape_plan_create_cached2 rive_hb_shape_plan_create_cached2 -#define hb_shape_plan_destroy rive_hb_shape_plan_destroy -#define hb_shape_plan_execute rive_hb_shape_plan_execute #define hb_all_shapers rive_hb_all_shapers #define hb_ms_language_map rive_hb_ms_language_map #define hb_mac_language_map rive_hb_mac_language_map -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_language_from_string rive_hb_language_from_string -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_map_create rive_hb_map_create -#define hb_map_destroy rive_hb_map_destroy -#define hb_set_next rive_hb_set_next -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_map_destroy rive_hb_map_destroy -#define hb_set_next rive_hb_set_next -#define hb_ot_var_find_axis_info rive_hb_ot_var_find_axis_info -#define hb_set_add rive_hb_set_add -#define hb_set_add_range rive_hb_set_add_range -#define hb_set_clear rive_hb_set_clear -#define hb_set_create rive_hb_set_create -#define hb_set_destroy rive_hb_set_destroy -#define hb_set_invert rive_hb_set_invert +#define hb_ot_name_language_for rive_hb_ot_name_language_for #define hb_subset_input_create_or_fail rive_hb_subset_input_create_or_fail #define hb_subset_input_destroy rive_hb_subset_input_destroy #define hb_subset_input_get_flags rive_hb_subset_input_get_flags #define hb_subset_input_get_user_data rive_hb_subset_input_get_user_data #define hb_subset_input_glyph_set rive_hb_subset_input_glyph_set +#define hb_subset_input_keep_everything rive_hb_subset_input_keep_everything +#define hb_subset_input_old_to_new_glyph_mapping rive_hb_subset_input_old_to_new_glyph_mapping #define hb_subset_input_pin_axis_location rive_hb_subset_input_pin_axis_location #define hb_subset_input_pin_axis_to_default rive_hb_subset_input_pin_axis_to_default #define hb_subset_input_reference rive_hb_subset_input_reference @@ -667,45 +984,7 @@ #define hb_subset_input_unicode_set rive_hb_subset_input_unicode_set #define hb_subset_or_fail rive_hb_subset_or_fail #define hb_subset_preprocess rive_hb_subset_preprocess -#define hb_arabic_u8 rive_hb_arabic_u8 -#define hb_arabic_u16 rive_hb_arabic_u16 -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_get_user_data rive_hb_blob_get_user_data -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_blob_set_user_data rive_hb_blob_set_user_data #define hb_face_builder_create rive_hb_face_builder_create -#define hb_face_destroy rive_hb_face_destroy -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_get_upem rive_hb_face_get_upem -#define hb_face_get_user_data rive_hb_face_get_user_data -#define hb_face_reference rive_hb_face_reference -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_font_create rive_hb_font_create -#define hb_font_destroy rive_hb_font_destroy -#define hb_font_set_variations rive_hb_font_set_variations -#define hb_map_create rive_hb_map_create -#define hb_map_destroy rive_hb_map_destroy -#define hb_map_get_empty rive_hb_map_get_empty -#define hb_map_get_user_data rive_hb_map_get_user_data -#define hb_map_reference rive_hb_map_reference -#define hb_map_set_user_data rive_hb_map_set_user_data -#define hb_ot_layout_collect_features rive_hb_ot_layout_collect_features -#define hb_ot_layout_has_positioning rive_hb_ot_layout_has_positioning -#define hb_ot_layout_lookups_substitute_closure rive_hb_ot_layout_lookups_substitute_closure -#define hb_set_copy rive_hb_set_copy -#define hb_set_create rive_hb_set_create -#define hb_set_destroy rive_hb_set_destroy -#define hb_set_get_empty rive_hb_set_get_empty -#define hb_set_get_user_data rive_hb_set_get_user_data -#define hb_set_previous rive_hb_set_previous -#define hb_set_reference rive_hb_set_reference -#define hb_set_set rive_hb_set_set -#define hb_set_set_user_data rive_hb_set_set_user_data -#define hb_set_subtract rive_hb_set_subtract -#define hb_set_union rive_hb_set_union #define hb_subset_plan_create_or_fail rive_hb_subset_plan_create_or_fail #define hb_subset_plan_destroy rive_hb_subset_plan_destroy #define hb_subset_plan_get_user_data rive_hb_subset_plan_get_user_data @@ -714,42 +993,16 @@ #define hb_subset_plan_reference rive_hb_subset_plan_reference #define hb_subset_plan_set_user_data rive_hb_subset_plan_set_user_data #define hb_subset_plan_unicode_to_old_glyph_mapping rive_hb_subset_plan_unicode_to_old_glyph_mapping -#define hb_blob_copy_writable_or_fail rive_hb_blob_copy_writable_or_fail -#define hb_blob_create rive_hb_blob_create -#define hb_blob_destroy rive_hb_blob_destroy -#define hb_blob_get_data rive_hb_blob_get_data -#define hb_blob_get_data_writable rive_hb_blob_get_data_writable -#define hb_blob_get_empty rive_hb_blob_get_empty -#define hb_blob_get_user_data rive_hb_blob_get_user_data -#define hb_blob_make_immutable rive_hb_blob_make_immutable -#define hb_blob_reference rive_hb_blob_reference -#define hb_blob_set_user_data rive_hb_blob_set_user_data +#define hb_debug rive_hb_debug #define hb_face_builder_add_table rive_hb_face_builder_add_table -#define hb_face_get_empty rive_hb_face_get_empty -#define hb_face_get_glyph_count rive_hb_face_get_glyph_count -#define hb_face_get_table_tags rive_hb_face_get_table_tags -#define hb_face_get_upem rive_hb_face_get_upem -#define hb_face_reference rive_hb_face_reference -#define hb_face_reference_table rive_hb_face_reference_table -#define hb_face_set_user_data rive_hb_face_set_user_data -#define hb_font_create rive_hb_font_create -#define hb_font_destroy rive_hb_font_destroy -#define hb_font_get_empty rive_hb_font_get_empty -#define hb_font_set_variations rive_hb_font_set_variations -#define hb_set_create rive_hb_set_create -#define hb_set_destroy rive_hb_set_destroy -#define hb_set_get_empty rive_hb_set_get_empty -#define hb_set_get_user_data rive_hb_set_get_user_data -#define hb_set_next rive_hb_set_next -#define hb_set_reference rive_hb_set_reference -#define hb_set_set_user_data rive_hb_set_set_user_data -#define hb_set_subtract rive_hb_set_subtract -#define hb_set_union rive_hb_set_union -#define hb_subset_or_fail rive_hb_subset_or_fail -#define hb_subset_plan_create_or_fail rive_hb_subset_plan_create_or_fail -#define hb_subset_plan_destroy rive_hb_subset_plan_destroy #define hb_subset_plan_execute_or_fail rive_hb_subset_plan_execute_or_fail +#define hb_ucd_b4 rive_hb_ucd_b4 +#define hb_ucd_dm rive_hb_ucd_dm +#define hb_ucd_gc rive_hb_ucd_gc +#define hb_ucd_sc rive_hb_ucd_sc #define hb_ucd_u8 rive_hb_ucd_u8 +#define hb_ucd_bmg rive_hb_ucd_bmg +#define hb_ucd_ccc rive_hb_ucd_ccc #define hb_ucd_i16 rive_hb_ucd_i16 #define hb_ucd_u16 rive_hb_ucd_u16 #define hb_ucd_sc_map rive_hb_ucd_sc_map @@ -757,9 +1010,10 @@ #define hb_ucd_dm1_p2_map rive_hb_ucd_dm1_p2_map #define hb_ucd_dm2_u32_map rive_hb_ucd_dm2_u32_map #define hb_ucd_dm2_u64_map rive_hb_ucd_dm2_u64_map +#define hb_ucd_compose_hangul rive_hb_ucd_compose_hangul +#define hb_ucd_decompose_hangul rive_hb_ucd_decompose_hangul #define hb_ucd_get_unicode_funcs rive_hb_ucd_get_unicode_funcs #define hb_unicode_funcs_create rive_hb_unicode_funcs_create -#define hb_unicode_funcs_destroy rive_hb_unicode_funcs_destroy #define hb_unicode_funcs_get_empty rive_hb_unicode_funcs_get_empty #define hb_unicode_funcs_make_immutable rive_hb_unicode_funcs_make_immutable #define hb_unicode_funcs_set_combining_class_func rive_hb_unicode_funcs_set_combining_class_func @@ -768,31 +1022,66 @@ #define hb_unicode_funcs_set_general_category_func rive_hb_unicode_funcs_set_general_category_func #define hb_unicode_funcs_set_mirroring_func rive_hb_unicode_funcs_set_mirroring_func #define hb_unicode_funcs_set_script_func rive_hb_unicode_funcs_set_script_func +#define hb_emoji_b1 rive_hb_emoji_b1 +#define hb_emoji_b4 rive_hb_emoji_b4 #define hb_emoji_u8 rive_hb_emoji_u8 -#define hb_ucd_get_unicode_funcs rive_hb_ucd_get_unicode_funcs +#define hb_emoji_is_Extended_Pictographic rive_hb_emoji_is_Extended_Pictographic #define hb_unicode_combining_class rive_hb_unicode_combining_class #define hb_unicode_compose rive_hb_unicode_compose #define hb_unicode_decompose rive_hb_unicode_decompose #define hb_unicode_decompose_compatibility rive_hb_unicode_decompose_compatibility #define hb_unicode_eastasian_width rive_hb_unicode_eastasian_width -#define hb_unicode_funcs_create rive_hb_unicode_funcs_create -#define hb_unicode_funcs_destroy rive_hb_unicode_funcs_destroy -#define hb_unicode_funcs_get_default rive_hb_unicode_funcs_get_default -#define hb_unicode_funcs_get_empty rive_hb_unicode_funcs_get_empty #define hb_unicode_funcs_get_parent rive_hb_unicode_funcs_get_parent #define hb_unicode_funcs_get_user_data rive_hb_unicode_funcs_get_user_data #define hb_unicode_funcs_is_immutable rive_hb_unicode_funcs_is_immutable -#define hb_unicode_funcs_make_immutable rive_hb_unicode_funcs_make_immutable -#define hb_unicode_funcs_reference rive_hb_unicode_funcs_reference -#define hb_unicode_funcs_set_combining_class_func rive_hb_unicode_funcs_set_combining_class_func -#define hb_unicode_funcs_set_compose_func rive_hb_unicode_funcs_set_compose_func #define hb_unicode_funcs_set_decompose_compatibility_func rive_hb_unicode_funcs_set_decompose_compatibility_func -#define hb_unicode_funcs_set_decompose_func rive_hb_unicode_funcs_set_decompose_func #define hb_unicode_funcs_set_eastasian_width_func rive_hb_unicode_funcs_set_eastasian_width_func -#define hb_unicode_funcs_set_general_category_func rive_hb_unicode_funcs_set_general_category_func -#define hb_unicode_funcs_set_mirroring_func rive_hb_unicode_funcs_set_mirroring_func -#define hb_unicode_funcs_set_script_func rive_hb_unicode_funcs_set_script_func #define hb_unicode_funcs_set_user_data rive_hb_unicode_funcs_set_user_data #define hb_unicode_general_category rive_hb_unicode_general_category #define hb_unicode_mirroring rive_hb_unicode_mirroring #define hb_unicode_script rive_hb_unicode_script +// __hb_* +#define _hb_CrapPool rive__hb_CrapPool +#define _hb_NullPool rive__hb_NullPool +#define _hb_Null_AAT_Lookup rive__hb_Null_AAT_Lookup +#define _hb_Null_AAT_SettingName rive__hb_Null_AAT_SettingName +#define _hb_Null_OT_RangeRecord rive__hb_Null_OT_RangeRecord +#define _hb_Null_hb_buffer_t rive__hb_Null_hb_buffer_t +#define _hb_Null_hb_unicode_funcs_t rive__hb_Null_hb_unicode_funcs_t +#define _hb_options rive__hb_options +#define _hb_Null_hb_draw_funcs_t rive__hb_Null_hb_draw_funcs_t +#define _hb_Null_OT_CmapSubtableLongGroup rive__hb_Null_OT_CmapSubtableLongGroup +#define _hb_Null_hb_face_t rive__hb_Null_hb_face_t +#define _hb_ot_shaper_face_data_destroy rive__hb_ot_shaper_face_data_destroy +#define _hb_Null_hb_font_funcs_t rive__hb_Null_hb_font_funcs_t +#define _hb_Null_hb_font_t rive__hb_Null_hb_font_t +#define _hb_ot_shaper_font_data_destroy rive__hb_ot_shaper_font_data_destroy +#define _hb_Null_OT_Index rive__hb_Null_OT_Index +#define _hb_Null_OT_LangSys rive__hb_Null_OT_LangSys +#define _hb_modified_combining_class rive__hb_modified_combining_class +#define _hb_ot_shape rive__hb_ot_shape +#define _hb_ot_shaper_arabic rive__hb_ot_shaper_arabic +#define _hb_ot_shaper_default rive__hb_ot_shaper_default +#define _hb_ot_shaper_dumber rive__hb_ot_shaper_dumber +#define _hb_ot_shaper_face_data_create rive__hb_ot_shaper_face_data_create +#define _hb_ot_shaper_font_data_create rive__hb_ot_shaper_font_data_create +#define _hb_ot_shaper_hangul rive__hb_ot_shaper_hangul +#define _hb_ot_shaper_hebrew rive__hb_ot_shaper_hebrew +#define _hb_ot_shaper_indic rive__hb_ot_shaper_indic +#define _hb_ot_shaper_khmer rive__hb_ot_shaper_khmer +#define _hb_ot_shaper_myanmar rive__hb_ot_shaper_myanmar +#define _hb_ot_shaper_myanmar_zawgyi rive__hb_ot_shaper_myanmar_zawgyi +#define _hb_ot_shaper_thai rive__hb_ot_shaper_thai +#define _hb_ot_shaper_use rive__hb_ot_shaper_use +#define _hb_Null_hb_paint_funcs_t rive__hb_Null_hb_paint_funcs_t +#define _hb_Null_OT_ClipRecord rive__hb_Null_OT_ClipRecord +#define _hb_Null_OT_VarIdx rive__hb_Null_OT_VarIdx +#define _hb_subset_accelerator_user_data_key rive__hb_subset_accelerator_user_data_key +#define lookup_expert_subset_charset_for_sid rive_lookup_expert_subset_charset_for_sid +#define lookup_standard_encoding_for_sid rive_lookup_standard_encoding_for_sid +#define data_destroy_arabic rive_data_destroy_arabic +#define lookup_expert_charset_for_sid rive_lookup_expert_charset_for_sid +#define lookup_standard_encoding_for_code rive_lookup_standard_encoding_for_code +#define accelerator_t rive_accelerator_t +#define lookup_expert_encoding_for_code rive_lookup_expert_encoding_for_code +#define get_seac_components rive_get_seac_components diff --git a/src/text/font_hb.cpp b/src/text/font_hb.cpp index a1af534c..2bb77e6b 100644 --- a/src/text/font_hb.cpp +++ b/src/text/font_hb.cpp @@ -310,7 +310,7 @@ rive::rcp HBFont::withOptions(rive::Span coords, rive::RawPath HBFont::getPath(rive::GlyphID glyph) const { rive::RawPath rpath; - hb_font_get_glyph_shape(m_font, glyph, m_drawFuncs, &rpath); + hb_font_draw_glyph(m_font, glyph, m_drawFuncs, &rpath); return rpath; } From 71bf9e3105060884a42bd69e6bbec035e1b9c78d Mon Sep 17 00:00:00 2001 From: bodymovin Date: Wed, 21 Feb 2024 14:38:13 +0000 Subject: [PATCH 002/138] =?UTF-8?q?sort=20hit=20shapes=20when=20draw=20ord?= =?UTF-8?q?er=20changes=20and=20stop=20propagation=20on=20hit=20s=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sort hit shapes when draw order changes and stop propagation on hit success Diffs= 8bca56dca sort hit shapes when draw order changes and stop propagation on hit s… (#6624) Co-authored-by: hernan --- .rive_head | 2 +- dev/defs/artboard.json | 11 + .../rive/animation/nested_state_machine.hpp | 8 +- .../rive/animation/state_machine_instance.hpp | 20 +- include/rive/artboard.hpp | 3 + include/rive/drawable.hpp | 14 +- include/rive/drawable_flag.hpp | 26 ++ include/rive/hit_result.hpp | 13 + include/rive/scene.hpp | 8 +- src/animation/nested_state_machine.cpp | 25 +- src/animation/state_machine_instance.cpp | 247 +++++++++++++----- src/artboard.cpp | 2 + src/scene.cpp | 8 +- test/assets/opaque_hit_test.riv | Bin 0 -> 1008 bytes test/hittest_test.cpp | 123 +++++++++ 15 files changed, 410 insertions(+), 100 deletions(-) create mode 100644 include/rive/drawable_flag.hpp create mode 100644 include/rive/hit_result.hpp create mode 100644 test/assets/opaque_hit_test.riv diff --git a/.rive_head b/.rive_head index a6def145..cf570cd2 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -9d605a1feb39dcad526ac9dda6b53b547921c58d +8bca56dcaffd0f563a91f628b0ed432eca71acb5 diff --git a/dev/defs/artboard.json b/dev/defs/artboard.json index 628ce9be..8b1f39a0 100644 --- a/dev/defs/artboard.json +++ b/dev/defs/artboard.json @@ -123,6 +123,17 @@ "description": "List of selected animations", "runtime": false, "coop": false + }, + "viewModelId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 434, + "string": "viewmodelid" + }, + "description": "The view model attached to this artboard data context." } } } \ No newline at end of file diff --git a/include/rive/animation/nested_state_machine.hpp b/include/rive/animation/nested_state_machine.hpp index a320c854..fe0cded9 100644 --- a/include/rive/animation/nested_state_machine.hpp +++ b/include/rive/animation/nested_state_machine.hpp @@ -2,6 +2,7 @@ #define _RIVE_NESTED_STATE_MACHINE_HPP_ #include "rive/animation/state_machine_instance.hpp" #include "rive/generated/animation/nested_state_machine_base.hpp" +#include "rive/hit_result.hpp" #include "rive/math/vec2d.hpp" #include @@ -23,9 +24,10 @@ class NestedStateMachine : public NestedStateMachineBase void initializeAnimation(ArtboardInstance*) override; StateMachineInstance* stateMachineInstance(); - void pointerMove(Vec2D position); - void pointerDown(Vec2D position); - void pointerUp(Vec2D position); + HitResult pointerMove(Vec2D position); + HitResult pointerDown(Vec2D position); + HitResult pointerUp(Vec2D position); + HitResult pointerExit(Vec2D position); void addNestedInput(NestedInput* input); }; diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index a9c5ad52..67369e69 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -6,6 +6,7 @@ #include #include "rive/animation/linear_animation_instance.hpp" #include "rive/core/field_types/core_callback_type.hpp" +#include "rive/hit_result.hpp" #include "rive/listener_type.hpp" #include "rive/scene.hpp" @@ -20,7 +21,7 @@ class SMINumber; class SMITrigger; class Shape; class StateMachineLayerInstance; -class HitShape; +class HitComponent; class NestedArtboard; class Event; class KeyedProperty; @@ -41,23 +42,24 @@ class StateMachineInstance : public Scene { friend class SMIInput; friend class KeyedProperty; + friend class HitComponent; private: - void markNeedsAdvance(); - /// Provide a hitListener if you want to process a down or an up for the pointer position /// too. - void updateListeners(Vec2D position, ListenerType hitListener); + HitResult updateListeners(Vec2D position, ListenerType hitListener); template InstType* getNamedInput(const std::string& name) const; void notifyEventListeners(std::vector events, NestedArtboard* source); + void sortHitComponents(); public: StateMachineInstance(const StateMachine* machine, ArtboardInstance* instance); StateMachineInstance(StateMachineInstance const&) = delete; ~StateMachineInstance() override; + void markNeedsAdvance(); // Advance the state machine by the specified time. Returns true if the // state machine will continue to animate after this advance. bool advance(float seconds); @@ -88,9 +90,10 @@ class StateMachineInstance : public Scene bool advanceAndApply(float secs) override; std::string name() const override; - void pointerMove(Vec2D position) override; - void pointerDown(Vec2D position) override; - void pointerUp(Vec2D position) override; + HitResult pointerMove(Vec2D position) override; + HitResult pointerDown(Vec2D position) override; + HitResult pointerUp(Vec2D position) override; + HitResult pointerExit(Vec2D position) override; float durationSeconds() const override { return -1; } Loop loop() const override { return Loop::oneShot; } @@ -125,8 +128,7 @@ class StateMachineInstance : public Scene std::vector m_inputInstances; // we own each pointer size_t m_layerCount; StateMachineLayerInstance* m_layers; - std::vector> m_hitShapes; - std::vector m_hitNestedArtboards; + std::vector> m_hitComponents; StateMachineInstance* m_parentStateMachineInstance = nullptr; NestedArtboard* m_parentNestedArtboard = nullptr; }; diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index a110e0f7..8338a6d9 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -49,6 +49,7 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta std::vector m_NestedArtboards; std::vector m_Joysticks; bool m_JoysticksApplyBeforeUpdate = true; + bool m_HasChangedDrawOrderInLastUpdate = false; unsigned int m_DirtDepth = 0; rcp m_BackgroundPath; @@ -100,6 +101,8 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta void onDirty(ComponentDirt dirt) override; bool advance(double elapsedSeconds); + bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; }; + Drawable* firstDrawable() { return m_FirstDrawable; }; enum class DrawOption { diff --git a/include/rive/drawable.hpp b/include/rive/drawable.hpp index 0e4c494c..547d6b54 100644 --- a/include/rive/drawable.hpp +++ b/include/rive/drawable.hpp @@ -4,6 +4,7 @@ #include "rive/hit_info.hpp" #include "rive/renderer.hpp" #include "rive/clip_result.hpp" +#include "rive/drawable_flag.hpp" #include namespace rive @@ -15,6 +16,7 @@ class DrawRules; class Drawable : public DrawableBase { friend class Artboard; + friend class StateMachineInstance; private: std::vector m_ClippingShapes; @@ -34,9 +36,15 @@ class Drawable : public DrawableBase inline bool isHidden() const { - // For now we have a single drawable flag, when we have more we can - // make an actual enum for this. - return (drawableFlags() & 0x1) == 0x1 || hasDirt(ComponentDirt::Collapsed); + return (static_cast(drawableFlags()) & DrawableFlag::Hidden) == + DrawableFlag::Hidden || + hasDirt(ComponentDirt::Collapsed); + } + + inline bool isTargetOpaque() const + { + return (static_cast(drawableFlags()) & DrawableFlag::Opaque) == + DrawableFlag::Opaque; } }; } // namespace rive diff --git a/include/rive/drawable_flag.hpp b/include/rive/drawable_flag.hpp new file mode 100644 index 00000000..9f79a152 --- /dev/null +++ b/include/rive/drawable_flag.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_DRAWABLE_FLAGS_HPP_ +#define _RIVE_DRAWABLE_FLAGS_HPP_ + +#include "rive/enum_bitset.hpp" + +namespace rive +{ +enum class DrawableFlag : unsigned short +{ + None = 0, + + /// Whether the component should be drawn + Hidden = 1 << 0, + + /// Editor only + Locked = 1 << 1, + + /// Editor only + Disconnected = 1 << 2, + + /// Whether this Component lets hit events pass through to components behind it + Opaque = 1 << 3, +}; +RIVE_MAKE_ENUM_BITSET(DrawableFlag) +} // namespace rive +#endif diff --git a/include/rive/hit_result.hpp b/include/rive/hit_result.hpp new file mode 100644 index 00000000..ec0c7fd1 --- /dev/null +++ b/include/rive/hit_result.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_HIT_RESULT_HPP_ +#define _RIVE_HIT_RESULT_HPP_ + +namespace rive +{ +enum class HitResult : uint8_t +{ + none, + hit, + hitOpaque, +}; +} // namespace rive +#endif diff --git a/include/rive/scene.hpp b/include/rive/scene.hpp index 21cb6066..fd96d8e9 100644 --- a/include/rive/scene.hpp +++ b/include/rive/scene.hpp @@ -6,6 +6,7 @@ #include "rive/math/vec2d.hpp" #include "rive/animation/keyed_callback_reporter.hpp" #include "rive/core/field_types/core_callback_type.hpp" +#include "rive/hit_result.hpp" #include namespace rive @@ -46,9 +47,10 @@ class Scene : public KeyedCallbackReporter, public CallbackContext void draw(Renderer*); - virtual void pointerDown(Vec2D); - virtual void pointerMove(Vec2D); - virtual void pointerUp(Vec2D); + virtual HitResult pointerDown(Vec2D); + virtual HitResult pointerMove(Vec2D); + virtual HitResult pointerUp(Vec2D); + virtual HitResult pointerExit(Vec2D); virtual size_t inputCount() const; virtual SMIInput* input(size_t index) const; diff --git a/src/animation/nested_state_machine.cpp b/src/animation/nested_state_machine.cpp index a686f14b..a6b5210b 100644 --- a/src/animation/nested_state_machine.cpp +++ b/src/animation/nested_state_machine.cpp @@ -3,6 +3,7 @@ #include "rive/animation/nested_number.hpp" #include "rive/animation/nested_state_machine.hpp" #include "rive/animation/state_machine_instance.hpp" +#include "rive/hit_result.hpp" using namespace rive; @@ -37,28 +38,40 @@ StateMachineInstance* NestedStateMachine::stateMachineInstance() return m_StateMachineInstance.get(); } -void NestedStateMachine::pointerMove(Vec2D position) +HitResult NestedStateMachine::pointerMove(Vec2D position) { if (m_StateMachineInstance != nullptr) { - m_StateMachineInstance->pointerMove(position); + return m_StateMachineInstance->pointerMove(position); } + return HitResult::none; } -void NestedStateMachine::pointerDown(Vec2D position) +HitResult NestedStateMachine::pointerDown(Vec2D position) { if (m_StateMachineInstance != nullptr) { - m_StateMachineInstance->pointerDown(position); + return m_StateMachineInstance->pointerDown(position); } + return HitResult::none; } -void NestedStateMachine::pointerUp(Vec2D position) +HitResult NestedStateMachine::pointerUp(Vec2D position) { if (m_StateMachineInstance != nullptr) { - m_StateMachineInstance->pointerUp(position); + return m_StateMachineInstance->pointerUp(position); } + return HitResult::none; +} + +HitResult NestedStateMachine::pointerExit(Vec2D position) +{ + if (m_StateMachineInstance != nullptr) + { + return m_StateMachineInstance->pointerExit(position); + } + return HitResult::none; } void NestedStateMachine::addNestedInput(NestedInput* input) { m_nestedInputs.push_back(input); } \ No newline at end of file diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 3ba76eb3..fe7f27ab 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -17,6 +17,7 @@ #include "rive/animation/state_transition.hpp" #include "rive/animation/transition_condition.hpp" #include "rive/animation/state_machine_fire_event.hpp" +#include "rive/hit_result.hpp" #include "rive/math/aabb.hpp" #include "rive/math/hit_test.hpp" #include "rive/nested_animation.hpp" @@ -318,49 +319,48 @@ class StateMachineLayerInstance float m_holdTime = 0.0f; }; +class HitComponent +{ +public: + Component* component() const { return m_component; } + HitComponent(Component* component, StateMachineInstance* stateMachineInstance) : + m_component(component), m_stateMachineInstance(stateMachineInstance) + {} + virtual ~HitComponent(){}; + virtual HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) = 0; + +protected: + Component* m_component; + StateMachineInstance* m_stateMachineInstance; +}; + /// Representation of a Shape from the Artboard Instance and all the listeners it /// triggers. Allows tracking hover and performing hit detection only once on /// shapes that trigger multiple listeners. -class HitShape +class HitShape : public HitComponent { public: - Shape* shape() const { return m_shape; } - HitShape(Shape* shape) : m_shape(shape) {} + HitShape(Component* shape, StateMachineInstance* stateMachineInstance) : + HitComponent(shape, stateMachineInstance) + {} + ~HitShape() {} bool isHovered = false; + float hitRadius = 2; std::vector listeners; - -private: - Shape* m_shape; -}; -} // namespace rive - -void StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) -{ - if (m_artboardInstance->frameOrigin()) + HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override { - position -= Vec2D(m_artboardInstance->originX() * m_artboardInstance->width(), - m_artboardInstance->originY() * m_artboardInstance->height()); - } - - const float hitRadius = 2; - auto hitArea = AABB(position.x - hitRadius, - position.y - hitRadius, - position.x + hitRadius, - position.y + hitRadius) - .round(); - - for (const auto& hitShape : m_hitShapes) - { - - // TODO: quick reject. - - bool isOver = hitShape->shape()->hitTest(hitArea); - - bool hoverChange = hitShape->isHovered != isOver; - hitShape->isHovered = isOver; - - // iterate all listeners associated with this hit shape - for (auto listener : hitShape->listeners) + auto shape = m_component->as(); + auto hitArea = AABB(position.x - hitRadius, + position.y - hitRadius, + position.x + hitRadius, + position.y + hitRadius) + .round(); + bool isOver = canHit ? shape->hitTest(hitArea) : false; + bool hoverChange = isHovered != isOver; + isHovered = isOver; + + // // iterate all listeners associated with this hit shape + for (auto listener : listeners) { // Always update hover states regardless of which specific listener type // we're trying to trigger. @@ -368,38 +368,45 @@ void StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) { if (isOver && listener->listenerType() == ListenerType::enter) { - listener->performChanges(this, position); - markNeedsAdvance(); + listener->performChanges(m_stateMachineInstance, position); + m_stateMachineInstance->markNeedsAdvance(); } else if (!isOver && listener->listenerType() == ListenerType::exit) { - listener->performChanges(this, position); - markNeedsAdvance(); + listener->performChanges(m_stateMachineInstance, position); + m_stateMachineInstance->markNeedsAdvance(); } } if (isOver && hitType == listener->listenerType()) { - listener->performChanges(this, position); - markNeedsAdvance(); + listener->performChanges(m_stateMachineInstance, position); + m_stateMachineInstance->markNeedsAdvance(); } } + return isOver ? shape->isTargetOpaque() ? HitResult::hitOpaque : HitResult::hit + : HitResult::none; } - - // TODO: store a hittable abstraction for HitShape and NestedArtboard that - // can be sorted by drawOrder so they can be iterated in one loop and early - // out if any hit stops propagation (also require the ability to mark a hit - // as able to stop propagation) - for (auto nestedArtboard : m_hitNestedArtboards) +}; +class HitNestedArtboard : public HitComponent +{ +public: + HitNestedArtboard(Component* nestedArtboard, StateMachineInstance* stateMachineInstance) : + HitComponent(nestedArtboard, stateMachineInstance) + {} + ~HitNestedArtboard() {} + HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override { + auto nestedArtboard = m_component->as(); + HitResult hitResult = HitResult::none; if (nestedArtboard->isCollapsed()) { - continue; + return hitResult; } Vec2D nestedPosition; if (!nestedArtboard->worldToLocal(position, &nestedPosition)) { // Mounted artboard isn't ready or has a 0 scale transform. - continue; + return hitResult; } for (auto nestedAnimation : nestedArtboard->nestedAnimations()) @@ -407,38 +414,90 @@ void StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) if (nestedAnimation->is()) { auto nestedStateMachine = nestedAnimation->as(); - switch (hitType) + if (canHit) { - case ListenerType::down: - nestedStateMachine->pointerDown(nestedPosition); - break; - case ListenerType::up: - nestedStateMachine->pointerUp(nestedPosition); - break; - case ListenerType::move: - nestedStateMachine->pointerMove(nestedPosition); - break; - case ListenerType::enter: - case ListenerType::exit: - case ListenerType::event: - break; + switch (hitType) + { + case ListenerType::down: + hitResult = nestedStateMachine->pointerDown(nestedPosition); + break; + case ListenerType::up: + hitResult = nestedStateMachine->pointerUp(nestedPosition); + break; + case ListenerType::move: + hitResult = nestedStateMachine->pointerMove(nestedPosition); + break; + case ListenerType::enter: + case ListenerType::exit: + case ListenerType::event: + break; + } + } + else + { + switch (hitType) + { + case ListenerType::down: + case ListenerType::up: + case ListenerType::move: + nestedStateMachine->pointerExit(nestedPosition); + break; + case ListenerType::enter: + case ListenerType::exit: + case ListenerType::event: + break; + } } } } + return hitResult; + } +}; +} // namespace rive + +HitResult StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) +{ + if (m_artboardInstance->frameOrigin()) + { + position -= Vec2D(m_artboardInstance->originX() * m_artboardInstance->width(), + m_artboardInstance->originY() * m_artboardInstance->height()); + } + + bool hitSomething = false; + bool hitOpaque = false; + for (const auto& hitShape : m_hitComponents) + { + + // TODO: quick reject. + + HitResult hitResult = hitShape->processEvent(position, hitType, !hitOpaque); + if (hitResult != HitResult::none) + { + hitSomething = true; + if (hitResult == HitResult::hitOpaque) + { + hitOpaque = true; + } + } } + return hitSomething ? hitOpaque ? HitResult::hitOpaque : HitResult::hit : HitResult::none; } -void StateMachineInstance::pointerMove(Vec2D position) +HitResult StateMachineInstance::pointerMove(Vec2D position) +{ + return updateListeners(position, ListenerType::move); +} +HitResult StateMachineInstance::pointerDown(Vec2D position) { - updateListeners(position, ListenerType::move); + return updateListeners(position, ListenerType::down); } -void StateMachineInstance::pointerDown(Vec2D position) +HitResult StateMachineInstance::pointerUp(Vec2D position) { - updateListeners(position, ListenerType::down); + return updateListeners(position, ListenerType::up); } -void StateMachineInstance::pointerUp(Vec2D position) +HitResult StateMachineInstance::pointerExit(Vec2D position) { - updateListeners(position, ListenerType::up); + return updateListeners(position, ListenerType::exit); } StateMachineInstance::StateMachineInstance(const StateMachine* machine, @@ -497,9 +556,9 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, auto shape = m_artboardInstance->resolve(id); if (shape != nullptr && shape->is()) { - auto hs = rivestd::make_unique(shape->as()); + auto hs = rivestd::make_unique(shape->as(), this); hitShapeLookup[id] = hitShape = hs.get(); - m_hitShapes.push_back(std::move(hs)); + m_hitComponents.push_back(std::move(hs)); } else { @@ -519,7 +578,11 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, { if (nestedArtboard->hasNestedStateMachines()) { - m_hitNestedArtboards.push_back(nestedArtboard); + + auto hn = + rivestd::make_unique(nestedArtboard->as(), this); + m_hitComponents.push_back(std::move(hn)); + for (auto animation : nestedArtboard->nestedAnimations()) { if (animation->is()) @@ -534,6 +597,7 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, } } } + sortHitComponents(); } StateMachineInstance::~StateMachineInstance() @@ -545,8 +609,47 @@ StateMachineInstance::~StateMachineInstance() delete[] m_layers; } +void StateMachineInstance::sortHitComponents() +{ + Drawable* last = m_artboardInstance->firstDrawable(); + if (last) + { + // walk to the end, so we can visit in reverse-order + while (last->prev) + { + last = last->prev; + } + } + auto hitShapesCount = m_hitComponents.size(); + auto currentSortedIndex = 0; + for (auto drawable = last; drawable; drawable = drawable->next) + { + for (size_t i = currentSortedIndex; i < hitShapesCount; i++) + { + if (m_hitComponents[i]->component() == drawable) + { + if (currentSortedIndex != i) + { + std::iter_swap(m_hitComponents.begin() + currentSortedIndex, + m_hitComponents.begin() + i); + } + currentSortedIndex++; + break; + } + } + if (currentSortedIndex == hitShapesCount) + { + break; + } + } +} + bool StateMachineInstance::advance(float seconds) { + if (m_artboardInstance->hasChangedDrawOrderInLastUpdate()) + { + sortHitComponents(); + } this->notifyEventListeners(m_reportedEvents, nullptr); m_reportedEvents.clear(); m_needsAdvance = false; diff --git a/src/artboard.cpp b/src/artboard.cpp index 6f18718b..b386bf77 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -272,6 +272,7 @@ StatusCode Artboard::initialize() void Artboard::sortDrawOrder() { + m_HasChangedDrawOrderInLastUpdate = true; for (auto target : m_DrawTargets) { target->first = target->last = nullptr; @@ -486,6 +487,7 @@ bool Artboard::updateComponents() bool Artboard::advance(double elapsedSeconds) { + m_HasChangedDrawOrderInLastUpdate = false; if (m_JoysticksApplyBeforeUpdate) { for (auto joystick : m_Joysticks) diff --git a/src/scene.cpp b/src/scene.cpp index 2bf0a09a..a987dfec 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -1,4 +1,5 @@ #include "rive/artboard.hpp" +#include "rive/hit_result.hpp" #include "rive/scene.hpp" #include "rive/generated/core_registry.hpp" using namespace rive; @@ -14,9 +15,10 @@ float Scene::height() const { return m_artboardInstance->height(); } void Scene::draw(Renderer* renderer) { m_artboardInstance->draw(renderer); } -void Scene::pointerDown(Vec2D) {} -void Scene::pointerMove(Vec2D) {} -void Scene::pointerUp(Vec2D) {} +HitResult Scene::pointerDown(Vec2D) { return HitResult::none; } +HitResult Scene::pointerMove(Vec2D) { return HitResult::none; } +HitResult Scene::pointerUp(Vec2D) { return HitResult::none; } +HitResult Scene::pointerExit(Vec2D) { return HitResult::none; } size_t Scene::inputCount() const { return 0; } SMIInput* Scene::input(size_t index) const { return nullptr; } diff --git a/test/assets/opaque_hit_test.riv b/test/assets/opaque_hit_test.riv new file mode 100644 index 0000000000000000000000000000000000000000..65c0d81d17c552c08c12ecf901537555ab7303c1 GIT binary patch literal 1008 zcmaizO=}ZT6o%i^%=S#gA-eXNqYFK}6eTDvh8UE#g9uF}aL^e86O?L|3{@ z)sc=Xu|G{NU+*9l!Pu=!6bwN;CRF zr}UG46XuW0AWiGq?Vb+&vC`^v$}3V@&T;Kw*=~C6*S04G3|4LCfTMaIC|b}36@Z3y z37A+gM3yxxu58Uo;?+m>_mpOV77H3muwstKzR#+><4V~(N7t}IoxY&Uncw}f&l}{; zN~PkXAc%*?L+1h9sEJ@htZt-mrE0?5p=Z~Q;d3R$AGk0N9Q&x&3`L+k@VL`**KWRQ z_ayF&D5Dtc^&O`ZJnCM5SA8mOk4S%L52ahG;O<8vY-0NpQ`^G5@MiZ5(N~`5Sq?f2m=~j{ z)-FC#2uqJbggnI%voHJoPT8|vM|w$eA+m_x|LBmm95y)D*@QdWx~V$*ysbKWo`4{5 z$nakX4nOctEUEOL&34>;F$$atYS4U;> #include +#include +#include +#include +#include +#include "rive_file_reader.hpp" #include #include @@ -57,3 +62,121 @@ TEST_CASE("hittest-mesh", "[hittest]") }; REQUIRE(HitTester::testMesh(area, make_span(verts, 3), make_span(indices, 3))); } + +TEST_CASE("hit test on opaque target", "[hittest]") +{ + // This artboard has two rects of size 200 x 200, "red-activate" at [0, 0, 200, 200] + // and "green-activate" at [0, 100, 200, 300] + // "red-activate" is above "green-activate" in drawing order + // Both targets are set as opaque for its listeners + // "red-activate" sets "toGreen" to false + // "green-activate" sets "toGreen" to true + // There is also a "gray-activate" above the other 2 that is not opaque so events should + // traverse through the other targets + auto file = ReadRiveFile("../../test/assets/opaque_hit_test.riv"); + + auto artboard = file->artboard("main"); + auto artboardInstance = artboard->instance(); + auto stateMachine = artboard->stateMachine("main-state-machine"); + + REQUIRE(artboardInstance != nullptr); + REQUIRE(artboardInstance->stateMachineCount() == 1); + + REQUIRE(stateMachine != nullptr); + + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, artboardInstance.get()); + + stateMachineInstance->advance(0.0f); + artboardInstance->advance(0.0f); + REQUIRE(stateMachineInstance->needsAdvance() == true); + stateMachineInstance->advance(0.0f); + + auto toGreenToggle = stateMachineInstance->getBool("toGreen"); + REQUIRE(toGreenToggle != nullptr); + auto grayToggle = stateMachineInstance->getBool("grayToggle"); + REQUIRE(grayToggle != nullptr); + + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 50.0f)); + // "gray-activate" is clicked + REQUIRE(grayToggle->value() == true); + // Pointer only over "red-activate" + REQUIRE(toGreenToggle->value() == false); + + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 250.0f)); + // "gray-activate" is clicked + REQUIRE(grayToggle->value() == false); + // Pointer over "green-activate" + REQUIRE(toGreenToggle->value() == true); + + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 110.0f)); + // "gray-activate" is clicked + REQUIRE(grayToggle->value() == true); + // Pointer over "red-activate" and "green-activate", but "red-activate" is opaque and above + // so green activate does not trigger + REQUIRE(toGreenToggle->value() == false); + delete stateMachineInstance; +} + +TEST_CASE("hit test on opaque nested artboard", "[hittest]") +{ + // This artboard (300x300) has a main rect at [0, 0, 300, 300] + // this rect has a listener that toggles "second-gray-toggle" + // and a nested artboard at [0, 0, 150, 150] + // the nested artboard and the rect have opaque targets + auto file = ReadRiveFile("../../test/assets/opaque_hit_test.riv"); + + auto artboard = file->artboard("second"); + auto artboardInstance = artboard->instance(); + auto stateMachine = artboard->stateMachine("second-state-machine"); + + REQUIRE(artboardInstance != nullptr); + REQUIRE(artboardInstance->stateMachineCount() == 1); + + REQUIRE(stateMachine != nullptr); + + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, artboardInstance.get()); + + auto nestedArtboard = + stateMachineInstance->artboard()->find("second-nested"); + REQUIRE(nestedArtboard != nullptr); + auto nestedArtboardStateMachine = + nestedArtboard->nestedAnimations()[0]->as(); + REQUIRE(nestedArtboardStateMachine != nullptr); + auto nestedArtboardStateMachineInstance = nestedArtboardStateMachine->stateMachineInstance(); + + auto secondNestedBoolTarget = nestedArtboardStateMachineInstance->getBool("bool-target"); + REQUIRE(secondNestedBoolTarget != nullptr); + + artboardInstance->advance(0.0f); + stateMachineInstance->advanceAndApply(0.0f); + + REQUIRE(secondNestedBoolTarget->value() == false); + + auto secondGrayToggle = stateMachineInstance->getBool("second-gray-toggle"); + REQUIRE(secondGrayToggle != nullptr); + + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 250.0f)); + // toggle changes value because it is not under an opaque nested artboard + REQUIRE(secondGrayToggle->value() == true); + + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 50.0f)); + // toggle does not change because it is under an opaque nested artboard + REQUIRE(secondGrayToggle->value() == true); + + // nested toggle changes because it's on top of shape + REQUIRE(secondNestedBoolTarget->value() == true); + + // A timeline switches draw order and the nested artboard is now below the rect + stateMachineInstance->advanceAndApply(1.0f); + stateMachineInstance->advance(0.0f); + + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 50.0f)); + // So now the pointer down is captured by the rect + REQUIRE(secondGrayToggle->value() == false); + + // nested toggle does not change because it's below shape + REQUIRE(secondNestedBoolTarget->value() == true); + delete stateMachineInstance; +} \ No newline at end of file From d10993c2722479967c90e770719181ff1effb5a2 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 26 Feb 2024 03:05:59 +0000 Subject: [PATCH 003/138] add support for text feature in runtime add support for text feature in runtime Diffs= 20b585bea add support for text feature in runtime (#6674) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/text/text_style.hpp | 4 ++++ include/rive/text/text_style_feature.hpp | 1 + src/text/text_style.cpp | 12 ++++++++++-- src/text/text_style_feature.cpp | 20 ++++++++++++++++++++ 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 src/text/text_style_feature.cpp diff --git a/.rive_head b/.rive_head index cf570cd2..66dd24d1 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8bca56dcaffd0f563a91f628b0ed432eca71acb5 +20b585bea54a56631527f6379934dd0f4ec2d5af diff --git a/include/rive/text/text_style.hpp b/include/rive/text/text_style.hpp index 49efceaf..68bdf0b2 100644 --- a/include/rive/text/text_style.hpp +++ b/include/rive/text/text_style.hpp @@ -18,6 +18,7 @@ class RenderPaint; class TextVariationHelper; class TextStyleAxis; +class TextStyleFeature; class TextStyle : public TextStyleBase, public ShapePaintContainer, public FileAssetReferencer { private: @@ -38,6 +39,7 @@ class TextStyle : public TextStyleBase, public ShapePaintContainer, public FileA void draw(Renderer* renderer); Core* clone() const override; void addVariation(TextStyleAxis* axis); + void addFeature(TextStyleFeature* feature); void updateVariableFont(); StatusCode onAddedClean(CoreContext* context) override; void onDirty(ComponentDirt dirt) override; @@ -56,6 +58,8 @@ class TextStyle : public TextStyleBase, public ShapePaintContainer, public FileA std::vector m_coords; std::vector m_variations; std::vector> m_paintPool; + std::vector m_styleFeatures; + std::vector m_features; }; } // namespace rive diff --git a/include/rive/text/text_style_feature.hpp b/include/rive/text/text_style_feature.hpp index 73aee8c2..fd0bb75e 100644 --- a/include/rive/text/text_style_feature.hpp +++ b/include/rive/text/text_style_feature.hpp @@ -7,6 +7,7 @@ namespace rive class TextStyleFeature : public TextStyleFeatureBase { public: + StatusCode onAddedDirty(CoreContext* context) override; }; } // namespace rive diff --git a/src/text/text_style.cpp b/src/text/text_style.cpp index a43a1c85..e1b13434 100644 --- a/src/text/text_style.cpp +++ b/src/text/text_style.cpp @@ -1,5 +1,6 @@ #include "rive/text/text_style.hpp" #include "rive/text/text_style_axis.hpp" +#include "rive/text/text_style_feature.hpp" #include "rive/renderer.hpp" #include "rive/shapes/paint/shape_paint.hpp" #include "rive/backboard.hpp" @@ -36,6 +37,8 @@ TextStyle::TextStyle() {} void TextStyle::addVariation(TextStyleAxis* axis) { m_variations.push_back(axis); } +void TextStyle::addFeature(TextStyleFeature* feature) { m_styleFeatures.push_back(feature); } + void TextStyle::onDirty(ComponentDirt dirt) { if ((dirt & ComponentDirt::TextShape) == ComponentDirt::TextShape) @@ -94,14 +97,19 @@ void TextStyle::updateVariableFont() // Not ready yet. return; } - if (!m_variations.empty()) + if (!m_variations.empty() || !m_styleFeatures.empty()) { m_coords.clear(); for (TextStyleAxis* axis : m_variations) { m_coords.push_back({axis->tag(), axis->axisValue()}); } - m_variableFont = baseFont->makeAtCoords(m_coords); + m_features.clear(); + for (TextStyleFeature* styleFeature : m_styleFeatures) + { + m_features.push_back({styleFeature->tag(), styleFeature->featureValue()}); + } + m_variableFont = baseFont->withOptions(m_coords, m_features); } else { diff --git a/src/text/text_style_feature.cpp b/src/text/text_style_feature.cpp new file mode 100644 index 00000000..31410a5e --- /dev/null +++ b/src/text/text_style_feature.cpp @@ -0,0 +1,20 @@ +#include "rive/text/text_style_feature.hpp" +#include "rive/text/text_style.hpp" +#include "rive/container_component.hpp" + +using namespace rive; + +StatusCode TextStyleFeature::onAddedDirty(CoreContext* context) +{ + StatusCode code = Super::onAddedDirty(context); + if (code == StatusCode::Ok) + { + if (!parent()->is()) + { + return StatusCode::InvalidObject; + } + auto style = parent()->as(); + style->addFeature(this); + } + return code; +} \ No newline at end of file From 4341475de5177cff46796df7d9bd7c6e2d5d8c1a Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 26 Feb 2024 06:37:55 +0000 Subject: [PATCH 004/138] trigger change when text modifier updates Diffs= ffde4f5f6 trigger change when text modifier updates (#6675) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/text/text_modifier_group.hpp | 1 + include/rive/text/text_variation_modifier.hpp | 1 + src/text/text_modifier_group.cpp | 2 ++ src/text/text_variation_modifier.cpp | 6 ++++++ 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 66dd24d1..49a2247d 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -20b585bea54a56631527f6379934dd0f4ec2d5af +ffde4f5f66e868c3929de24bb0856db7d1d01e95 diff --git a/include/rive/text/text_modifier_group.hpp b/include/rive/text/text_modifier_group.hpp index 7c5d4171..99c021b1 100644 --- a/include/rive/text/text_modifier_group.hpp +++ b/include/rive/text/text_modifier_group.hpp @@ -23,6 +23,7 @@ class TextModifierGroup : public TextModifierGroupBase void addModifier(TextModifier* modifier); void rangeChanged(); void rangeTypeChanged(); + void shapeModifierChanged(); void clearRangeMaps(); void computeRangeMap(Span text, const rive::SimpleArray& shape, diff --git a/include/rive/text/text_variation_modifier.hpp b/include/rive/text/text_variation_modifier.hpp index e58bf811..f5bab27a 100644 --- a/include/rive/text/text_variation_modifier.hpp +++ b/include/rive/text/text_variation_modifier.hpp @@ -11,6 +11,7 @@ class TextVariationModifier : public TextVariationModifierBase std::unordered_map& variations, float fontSize, float strength) const override; + void axisValueChanged() override; }; } // namespace rive diff --git a/src/text/text_modifier_group.cpp b/src/text/text_modifier_group.cpp index 3569ca20..14778a55 100644 --- a/src/text/text_modifier_group.cpp +++ b/src/text/text_modifier_group.cpp @@ -43,6 +43,8 @@ void TextModifierGroup::rangeTypeChanged() addDirt(ComponentDirt::TextCoverage); } +void TextModifierGroup::shapeModifierChanged() { parent()->as()->markShapeDirty(); } + void TextModifierGroup::rangeChanged() { /// Marking shape dirty should only be done if this modifer group changes diff --git a/src/text/text_variation_modifier.cpp b/src/text/text_variation_modifier.cpp index fd4e9cf5..a0918c90 100644 --- a/src/text/text_variation_modifier.cpp +++ b/src/text/text_variation_modifier.cpp @@ -1,4 +1,5 @@ #include "rive/text/text_variation_modifier.hpp" +#include "rive/text/text_modifier_group.hpp" #include "rive/text_engine.hpp" using namespace rive; @@ -13,4 +14,9 @@ float TextVariationModifier::modify(Font* font, float fromValue = itr != variations.end() ? itr->second : font->getAxisValue(axisTag()); variations[axisTag()] = fromValue * (1 - strength) + axisValue() * strength; return fontSize; +} + +void TextVariationModifier::axisValueChanged() +{ + parent()->as()->shapeModifierChanged(); } \ No newline at end of file From 2416bfc48311294c66709c294056177b44904ee0 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Fri, 1 Mar 2024 01:05:20 +0000 Subject: [PATCH 005/138] Implement an MSAA fallback for PLS Add a new pls::InterlockMode called depthStencil, which obviously uses the depth and stencil buffers instead of PLS to do path rendering. When combined with MSAA, this can look decent. The coolest thing here is that we reverse-sort opaque draws front to back, and draw them first with Z culling. This gives some substantial perf wins. We should figure out how to use Z culling generally. For blend modes we use KHR_blend_equation_advanced_coherent. For now, only GL is supported. Still unfinished: - Implement clipping. - Implement advanced blend without extensions. Diffs= f2ecb3a22 Implement an MSAA fallback for PLS (#6680) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- include/rive/enum_bitset.hpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 49a2247d..5f8e24ba 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -ffde4f5f66e868c3929de24bb0856db7d1d01e95 +f2ecb3a22e9003dda6de911cc1a58b8547988ef4 diff --git a/include/rive/enum_bitset.hpp b/include/rive/enum_bitset.hpp index 6461bdd2..6ba86098 100644 --- a/include/rive/enum_bitset.hpp +++ b/include/rive/enum_bitset.hpp @@ -17,7 +17,8 @@ template class EnumBitset constexpr EnumBitset() = default; constexpr EnumBitset(T value) : m_bits(static_cast(value)) {} constexpr UnderlyingType bits() const { return m_bits; } - constexpr operator T() const { return static_cast(m_bits); } + constexpr T value() const { return static_cast(m_bits); } + constexpr operator T() const { return value(); } constexpr operator bool() const { return m_bits != 0; } private: From bd6e8861014aa5baceb64d6c57b5d2b3de4e80f0 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Sat, 2 Mar 2024 04:55:24 +0000 Subject: [PATCH 006/138] slim down harfbuzz Diffs= c36e16cb6 slim down harfbuzz (#6710) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- dependencies/premake5_harfbuzz.lua | 18 +++++++++++++++++- dependencies/premake5_harfbuzz_v2.lua | 18 +++++++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 5f8e24ba..5c7e86ab 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f2ecb3a22e9003dda6de911cc1a58b8547988ef4 +c36e16cb6a812a4b46c5ea8f133598367b664a17 diff --git a/dependencies/premake5_harfbuzz.lua b/dependencies/premake5_harfbuzz.lua index de31b788..1123265c 100644 --- a/dependencies/premake5_harfbuzz.lua +++ b/dependencies/premake5_harfbuzz.lua @@ -225,7 +225,23 @@ do warnings('Off') - defines({ 'HAVE_OT', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256', 'HB_NO_EXTERN_HELPERS' }) + defines({ + 'HAVE_OT', + 'HB_NO_FALLBACK_SHAPE', + 'HB_NO_WIN1256', + 'HB_NO_EXTERN_HELPERS', + 'HB_DISABLE_DEPRECATED', + 'HB_NO_COLOR', + 'HB_NO_BITMAP', + 'HB_NO_BUFFER_SERIALIZE', + 'HB_NO_SETLOCALE', + 'HB_NO_STYLE', + 'HB_NO_VERTICAL', + 'HB_NO_LAYOUT_COLLECT_GLYPHS', + 'HB_NO_LAYOUT_RARELY_USED', + 'HB_NO_LAYOUT_UNUSED', + 'HB_NO_OT_FONT_GLYPH_NAMES', + }) filter('system:emscripten') do diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua index f3449582..183c378d 100644 --- a/dependencies/premake5_harfbuzz_v2.lua +++ b/dependencies/premake5_harfbuzz_v2.lua @@ -224,7 +224,23 @@ do warnings('Off') - defines({ 'HAVE_OT', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256', 'HB_NO_EXTERN_HELPERS' }) + defines({ + 'HAVE_OT', + 'HB_NO_FALLBACK_SHAPE', + 'HB_NO_WIN1256', + 'HB_NO_EXTERN_HELPERS', + 'HB_DISABLE_DEPRECATED', + 'HB_NO_COLOR', + 'HB_NO_BITMAP', + 'HB_NO_BUFFER_SERIALIZE', + 'HB_NO_SETLOCALE', + 'HB_NO_STYLE', + 'HB_NO_VERTICAL', + 'HB_NO_LAYOUT_COLLECT_GLYPHS', + 'HB_NO_LAYOUT_RARELY_USED', + 'HB_NO_LAYOUT_UNUSED', + 'HB_NO_OT_FONT_GLYPH_NAMES', + }) filter('toolset:not msc') do From ce2c740e930d14e745d1828599a4f16efacccf61 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Fri, 8 Mar 2024 19:24:10 +0000 Subject: [PATCH 007/138] Upgrade rive_wasm to the new premake system Diffs= 7cb7eb812 Upgrade rive_wasm to the new premake system (#6789) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 5c7e86ab..534137d2 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -c36e16cb6a812a4b46c5ea8f133598367b664a17 +7cb7eb8122d3625aad2c6032615006cc8f5383e8 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 713af550..78d35ccc 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -74,6 +74,11 @@ newoption({ description = 'don\'t disable exceptions (nonstandard for Rive)', }) +newoption({ + trigger = 'wasm_single', + description = 'Embed wasm directly into the js, instead of side-loading it.', +}) + location(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT) targetdir(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT) objdir(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT .. '/obj') @@ -385,7 +390,7 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then system('emscripten') toolset('emsdk') - linkoptions({ '-sALLOW_MEMORY_GROWTH' }) + linkoptions({ '-sALLOW_MEMORY_GROWTH=1', '-sDYNAMIC_EXECUTION=0' }) filter('options:arch=wasm') do @@ -398,5 +403,10 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then linkoptions({ '-sWASM=0' }) end + filter('options:wasm_single') + do + linkoptions({ '-sSINGLE_FILE=1' }) + end + filter({}) end From 033a45243cb2656c5fd57a845fd6689b550263d9 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Sat, 9 Mar 2024 21:45:36 +0000 Subject: [PATCH 008/138] Always decode 3 or 4 channel PNG images. The bug @HayesGordon ran into with Unity was because we were trying to decode grayscale images to a single-channel image and then expanding those to 4 channels as the Rive Renderer expects RGBA. That was padding missing channel data with 255, which is why we were getting Cyan (R would be read, GBA were filled with 255). Instead, we make the Bitmap library only work with RGB and RGBA and we let libpng do the expansion for us. Glorious: CleanShot 2024-03-08 at 21 28 21@2x Diffs= 09feaccb0 Always decode 3 or 4 channel PNG images. (#6818) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- .../include/rive/decoders/bitmap_decoder.hpp | 1 - decoders/src/bitmap_decoder.cpp | 2 - decoders/src/decode_png.cpp | 55 ++++++++----------- 4 files changed, 24 insertions(+), 36 deletions(-) diff --git a/.rive_head b/.rive_head index 534137d2..9f56a91f 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -7cb7eb8122d3625aad2c6032615006cc8f5383e8 +09feaccb0c5bb3a2f88c23aca6c669d79eee4428 diff --git a/decoders/include/rive/decoders/bitmap_decoder.hpp b/decoders/include/rive/decoders/bitmap_decoder.hpp index 05e295dd..881028c5 100644 --- a/decoders/include/rive/decoders/bitmap_decoder.hpp +++ b/decoders/include/rive/decoders/bitmap_decoder.hpp @@ -13,7 +13,6 @@ class Bitmap public: enum class PixelFormat : uint8_t { - R, RGB, RGBA }; diff --git a/decoders/src/bitmap_decoder.cpp b/decoders/src/bitmap_decoder.cpp index 8d4c04e7..243ce29a 100644 --- a/decoders/src/bitmap_decoder.cpp +++ b/decoders/src/bitmap_decoder.cpp @@ -23,8 +23,6 @@ size_t Bitmap::bytesPerPixel(PixelFormat format) const { switch (format) { - case PixelFormat::R: - return 1; case PixelFormat::RGB: return 3; case PixelFormat::RGBA: diff --git a/decoders/src/decode_png.cpp b/decoders/src/decode_png.cpp index 157dfa2d..edfb1bba 100644 --- a/decoders/src/decode_png.cpp +++ b/decoders/src/decode_png.cpp @@ -73,48 +73,42 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount) NULL, NULL); - png_set_strip_16(png_ptr); - - int bitDepth = 0; - if (color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_RGB) + if (color_type == PNG_COLOR_TYPE_PALETTE || + (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)) { + // expand to 3 or 4 channels png_set_expand(png_ptr); - bitDepth = 24; - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - { - png_set_expand(png_ptr); - bitDepth += 8; - } } - else if (color_type == PNG_COLOR_TYPE_GRAY) + + png_bytep trns = 0; + int trnsCount = 0; + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_get_tRNS(png_ptr, info_ptr, &trns, &trnsCount, 0); png_set_expand(png_ptr); - bitDepth = 8; } - else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + + if (bit_depth == 16) { - png_set_expand(png_ptr); - png_set_gray_to_rgb(png_ptr); - bitDepth = 32; + png_set_strip_16(png_ptr); } - else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + + if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - png_set_expand(png_ptr); - bitDepth = 32; + png_set_gray_to_rgb(png_ptr); } - int pixelBytes = bitDepth / 8; - auto pixelBuffer = new uint8_t[width * height * pixelBytes]; + png_read_update_info(png_ptr, info_ptr); + uint8_t channels = png_get_channels(png_ptr, info_ptr); + + auto pixelBuffer = new uint8_t[width * height * channels]; png_bytep* row_pointers = new png_bytep[height]; for (unsigned row = 0; row < height; row++) { unsigned int rIndex = row; - // if (flipY) { - // rIndex = height - row - 1; - // } - row_pointers[rIndex] = pixelBuffer + (row * (width * pixelBytes)); + row_pointers[rIndex] = pixelBuffer + (row * (width * channels)); } png_read_image(png_ptr, row_pointers); png_read_end(png_ptr, info_ptr); @@ -124,18 +118,15 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount) delete[] row_pointers; Bitmap::PixelFormat pixelFormat; - assert(bitDepth == 32 || bitDepth == 24 || bitDepth == 8); - switch (bitDepth) + assert(channels == 3 || channels == 4); + switch (channels) { - case 32: + case 4: pixelFormat = Bitmap::PixelFormat::RGBA; break; - case 24: + case 3: pixelFormat = Bitmap::PixelFormat::RGB; break; - case 8: - pixelFormat = Bitmap::PixelFormat::R; - break; } return std::make_unique(width, height, pixelFormat, pixelBuffer); } From 9e000b07967aedbb4cb2d73e081c31f0c7b3d20b Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Sat, 9 Mar 2024 21:55:03 +0000 Subject: [PATCH 009/138] Unity webgl! Thread here: https://2dimensions.slack.com/archives/CHMAP278R/p1709934972246289 ![image](https://github.com/rive-app/rive/assets/454182/cc72ee80-4506-4e45-a65a-d994cae0a1a8) Uses PLS when draft extensions are enabled in Chrome! ![image](https://github.com/rive-app/rive/assets/454182/fadb112f-1bff-457f-98a1-6fe524224398) Details on how it works and how to patch Unity's emscripten here (part of this PR which will push downstream): https://github.com/rive-app/rive/blob/unity_webgl/packages/runtime_unity/public/WEBGL.md Diffs= bcf6451f4 Unity webgl! (#6816) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- dependencies/premake5_libpng.lua | 5 +- dependencies/premake5_libpng_v2.lua | 5 +- dependencies/rive_png_renames.h | 450 ++++++++++++++++++++++++++++ 4 files changed, 459 insertions(+), 3 deletions(-) create mode 100644 dependencies/rive_png_renames.h diff --git a/.rive_head b/.rive_head index 9f56a91f..2ab2502a 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -09feaccb0c5bb3a2f88c23aca6c669d79eee4428 +bcf6451f442d7d55ed423982b58204e93c1d8791 diff --git a/dependencies/premake5_libpng.lua b/dependencies/premake5_libpng.lua index 4d217a9d..fdf1c4ef 100644 --- a/dependencies/premake5_libpng.lua +++ b/dependencies/premake5_libpng.lua @@ -3,6 +3,9 @@ local dependency = require('dependency') libpng = dependency.github('glennrp/libpng', 'libpng16') zlib = dependency.github('madler/zlib', '04f42ceca40f73e2978b50e93806c2a18c1281fc') +includedirs({ './' }) +forceincludes({ 'rive_png_renames.h' }) + project('libpng') do kind('StaticLib') @@ -11,7 +14,7 @@ do targetdir('%{cfg.system}/cache/bin/%{cfg.buildcfg}/') objdir('%{cfg.system}/cache/obj/%{cfg.buildcfg}/') os.copyfile(libpng .. '/scripts/pnglibconf.h.prebuilt', libpng .. '/pnglibconf.h') - includedirs({ './', libpng, zlib }) + includedirs({ libpng, zlib }) files({ libpng .. '/png.c', libpng .. '/pngerror.c', diff --git a/dependencies/premake5_libpng_v2.lua b/dependencies/premake5_libpng_v2.lua index 2c44808d..ac653b79 100644 --- a/dependencies/premake5_libpng_v2.lua +++ b/dependencies/premake5_libpng_v2.lua @@ -4,11 +4,14 @@ local dependency = require('dependency') libpng = dependency.github('glennrp/libpng', 'libpng16') zlib = dependency.github('madler/zlib', '04f42ceca40f73e2978b50e93806c2a18c1281fc') +includedirs({ './' }) +forceincludes({ 'rive_png_renames.h' }) + project('libpng') do kind('StaticLib') os.copyfile(libpng .. '/scripts/pnglibconf.h.prebuilt', libpng .. '/pnglibconf.h') - includedirs({ './', libpng, zlib }) + includedirs({ libpng, zlib }) files({ libpng .. '/png.c', libpng .. '/pngerror.c', diff --git a/dependencies/rive_png_renames.h b/dependencies/rive_png_renames.h new file mode 100644 index 00000000..5a15fb01 --- /dev/null +++ b/dependencies/rive_png_renames.h @@ -0,0 +1,450 @@ +#ifndef RIVE_PNG_RENAMES_H +#define RIVE_PNG_RENAMES_H +#define PNGPREFIX_H +#define PNG_PREFIX rive_ +#define png_sRGB_table rive_png_sRGB_table +#define png_sRGB_base rive_png_sRGB_base +#define png_sRGB_delta rive_png_sRGB_delta +#define png_zstream_error rive_png_zstream_error +#define png_free_buffer_list rive_png_free_buffer_list +#define png_fixed rive_png_fixed +#define png_user_version_check rive_png_user_version_check +#define png_malloc_base rive_png_malloc_base +#define png_malloc_array rive_png_malloc_array +#define png_realloc_array rive_png_realloc_array +#define png_create_png_struct rive_png_create_png_struct +#define png_destroy_png_struct rive_png_destroy_png_struct +#define png_free_jmpbuf rive_png_free_jmpbuf +#define png_zalloc rive_png_zalloc +#define png_zfree rive_png_zfree +#define png_default_read_data rive_png_default_read_data +#define png_push_fill_buffer rive_png_push_fill_buffer +#define png_default_write_data rive_png_default_write_data +#define png_default_flush rive_png_default_flush +#define png_reset_crc rive_png_reset_crc +#define png_write_data rive_png_write_data +#define png_read_sig rive_png_read_sig +#define png_read_chunk_header rive_png_read_chunk_header +#define png_read_data rive_png_read_data +#define png_crc_read rive_png_crc_read +#define png_crc_finish rive_png_crc_finish +#define png_crc_error rive_png_crc_error +#define png_calculate_crc rive_png_calculate_crc +#define png_flush rive_png_flush +#define png_write_IHDR rive_png_write_IHDR +#define png_write_PLTE rive_png_write_PLTE +#define png_compress_IDAT rive_png_compress_IDAT +#define png_write_IEND rive_png_write_IEND +#define png_write_gAMA_fixed rive_png_write_gAMA_fixed +#define png_write_sBIT rive_png_write_sBIT +#define png_write_cHRM_fixed rive_png_write_cHRM_fixed +#define png_write_sRGB rive_png_write_sRGB +#define png_write_iCCP rive_png_write_iCCP +#define png_write_sPLT rive_png_write_sPLT +#define png_write_tRNS rive_png_write_tRNS +#define png_write_bKGD rive_png_write_bKGD +#define png_write_hIST rive_png_write_hIST +#define png_write_tEXt rive_png_write_tEXt +#define png_write_zTXt rive_png_write_zTXt +#define png_write_iTXt rive_png_write_iTXt +#define png_set_text_2 rive_png_set_text_2 +#define png_write_oFFs rive_png_write_oFFs +#define png_write_pCAL rive_png_write_pCAL +#define png_write_pHYs rive_png_write_pHYs +#define png_write_tIME rive_png_write_tIME +#define png_write_sCAL_s rive_png_write_sCAL_s +#define png_write_finish_row rive_png_write_finish_row +#define png_write_start_row rive_png_write_start_row +#define png_combine_row rive_png_combine_row +#define png_do_read_interlace rive_png_do_read_interlace +#define png_do_write_interlace rive_png_do_write_interlace +#define png_read_filter_row rive_png_read_filter_row +#define png_read_filter_row_up_neon rive_png_read_filter_row_up_neon +#define png_read_filter_row_sub3_neon rive_png_read_filter_row_sub3_neon +#define png_read_filter_row_sub4_neon rive_png_read_filter_row_sub4_neon +#define png_read_filter_row_avg3_neon rive_png_read_filter_row_avg3_neon +#define png_read_filter_row_avg4_neon rive_png_read_filter_row_avg4_neon +#define png_read_filter_row_paeth3_neon rive_png_read_filter_row_paeth3_neon +#define png_read_filter_row_paeth4_neon rive_png_read_filter_row_paeth4_neon +#define png_read_filter_row_sub3_sse2 rive_png_read_filter_row_sub3_sse2 +#define png_read_filter_row_sub4_sse2 rive_png_read_filter_row_sub4_sse2 +#define png_read_filter_row_avg3_sse2 rive_png_read_filter_row_avg3_sse2 +#define png_read_filter_row_avg4_sse2 rive_png_read_filter_row_avg4_sse2 +#define png_read_filter_row_paeth3_sse2 rive_png_read_filter_row_paeth3_sse2 +#define png_read_filter_row_paeth4_sse2 rive_png_read_filter_row_paeth4_sse2 +#define png_write_find_filter rive_png_write_find_filter +#define png_read_IDAT_data rive_png_read_IDAT_data +#define png_read_finish_IDAT rive_png_read_finish_IDAT +#define png_read_finish_row rive_png_read_finish_row +#define png_read_start_row rive_png_read_start_row +#define png_read_transform_info rive_png_read_transform_info +#define png_do_read_filler rive_png_do_read_filler +#define png_do_read_swap_alpha rive_png_do_read_swap_alpha +#define png_do_write_swap_alpha rive_png_do_write_swap_alpha +#define png_do_read_invert_alpha rive_png_do_read_invert_alpha +#define png_do_write_invert_alpha rive_png_do_write_invert_alpha +#define png_do_strip_channel rive_png_do_strip_channel +#define png_do_swap rive_png_do_swap +#define png_do_packswap rive_png_do_packswap +#define png_do_rgb_to_gray rive_png_do_rgb_to_gray +#define png_do_gray_to_rgb rive_png_do_gray_to_rgb +#define png_do_unpack rive_png_do_unpack +#define png_do_unshift rive_png_do_unshift +#define png_do_invert rive_png_do_invert +#define png_do_scale_16_to_8 rive_png_do_scale_16_to_8 +#define png_do_chop rive_png_do_chop +#define png_do_quantize rive_png_do_quantize +#define png_do_bgr rive_png_do_bgr +#define png_do_pack rive_png_do_pack +#define png_do_shift rive_png_do_shift +#define png_do_compose rive_png_do_compose +#define png_do_gamma rive_png_do_gamma +#define png_do_encode_alpha rive_png_do_encode_alpha +#define png_do_expand_palette rive_png_do_expand_palette +#define png_do_expand rive_png_do_expand +#define png_do_expand_16 rive_png_do_expand_16 +#define png_handle_IHDR rive_png_handle_IHDR +#define png_handle_PLTE rive_png_handle_PLTE +#define png_handle_IEND rive_png_handle_IEND +#define png_handle_bKGD rive_png_handle_bKGD +#define png_handle_cHRM rive_png_handle_cHRM +#define png_handle_gAMA rive_png_handle_gAMA +#define png_handle_hIST rive_png_handle_hIST +#define png_handle_iCCP rive_png_handle_iCCP +#define png_handle_iTXt rive_png_handle_iTXt +#define png_handle_oFFs rive_png_handle_oFFs +#define png_handle_pCAL rive_png_handle_pCAL +#define png_handle_pHYs rive_png_handle_pHYs +#define png_handle_sBIT rive_png_handle_sBIT +#define png_handle_sCAL rive_png_handle_sCAL +#define png_handle_sPLT rive_png_handle_sPLT +#define png_handle_sRGB rive_png_handle_sRGB +#define png_handle_tEXt rive_png_handle_tEXt +#define png_handle_tIME rive_png_handle_tIME +#define png_handle_tRNS rive_png_handle_tRNS +#define png_handle_zTXt rive_png_handle_zTXt +#define png_check_chunk_name rive_png_check_chunk_name +#define png_handle_unknown rive_png_handle_unknown +#define png_chunk_unknown_handling rive_png_chunk_unknown_handling +#define png_do_read_transformations rive_png_do_read_transformations +#define png_do_write_transformations rive_png_do_write_transformations +#define png_init_read_transformations rive_png_init_read_transformations +#define png_push_read_chunk rive_png_push_read_chunk +#define png_push_read_sig rive_png_push_read_sig +#define png_push_check_crc rive_png_push_check_crc +#define png_push_crc_skip rive_png_push_crc_skip +#define png_push_crc_finish rive_png_push_crc_finish +#define png_push_save_buffer rive_png_push_save_buffer +#define png_push_restore_buffer rive_png_push_restore_buffer +#define png_push_read_IDAT rive_png_push_read_IDAT +#define png_process_IDAT_data rive_png_process_IDAT_data +#define png_push_process_row rive_png_push_process_row +#define png_push_handle_unknown rive_png_push_handle_unknown +#define png_push_have_info rive_png_push_have_info +#define png_push_have_end rive_png_push_have_end +#define png_push_have_row rive_png_push_have_row +#define png_push_read_end rive_png_push_read_end +#define png_process_some_data rive_png_process_some_data +#define png_read_push_finish_row rive_png_read_push_finish_row +#define png_push_handle_tEXt rive_png_push_handle_tEXt +#define png_push_read_tEXt rive_png_push_read_tEXt +#define png_push_handle_zTXt rive_png_push_handle_zTXt +#define png_push_read_zTXt rive_png_push_read_zTXt +#define png_push_handle_iTXt rive_png_push_handle_iTXt +#define png_push_read_iTXt rive_png_push_read_iTXt +#define png_do_read_intrapixel rive_png_do_read_intrapixel +#define png_do_write_intrapixel rive_png_do_write_intrapixel +#define png_colorspace_set_gamma rive_png_colorspace_set_gamma +#define png_colorspace_sync_info rive_png_colorspace_sync_info +#define png_colorspace_sync rive_png_colorspace_sync +#define png_colorspace_set_chromaticities rive_png_colorspace_set_chromaticities +#define png_colorspace_set_endpoints rive_png_colorspace_set_endpoints +#define png_colorspace_set_sRGB rive_png_colorspace_set_sRGB +#define png_colorspace_set_ICC rive_png_colorspace_set_ICC +#define png_icc_check_length rive_png_icc_check_length +#define png_icc_check_header rive_png_icc_check_header +#define png_icc_check_tag_table rive_png_icc_check_tag_table +#define png_icc_set_sRGB rive_png_icc_set_sRGB +#define png_colorspace_set_rgb_coefficients rive_png_colorspace_set_rgb_coefficients +#define png_check_IHDR rive_png_check_IHDR +#define png_do_check_palette_indexes rive_png_do_check_palette_indexes +#define png_fixed_error rive_png_fixed_error +#define png_safecat rive_png_safecat +#define png_format_number rive_png_format_number +#define png_warning_parameter rive_png_warning_parameter +#define png_warning_parameter_unsigned rive_png_warning_parameter_unsigned +#define png_warning_parameter_signed rive_png_warning_parameter_signed +#define png_formatted_warning rive_png_formatted_warning +#define png_app_warning rive_png_app_warning +#define png_app_error rive_png_app_error +#define png_chunk_report rive_png_chunk_report +#define png_ascii_from_fp rive_png_ascii_from_fp +#define png_ascii_from_fixed rive_png_ascii_from_fixed +#define png_check_fp_number rive_png_check_fp_number +#define png_check_fp_string rive_png_check_fp_string +#define png_muldiv rive_png_muldiv +#define png_muldiv_warn rive_png_muldiv_warn +#define png_reciprocal rive_png_reciprocal +#define png_reciprocal2 rive_png_reciprocal2 +#define png_gamma_significant rive_png_gamma_significant +#define png_gamma_correct rive_png_gamma_correct +#define png_gamma_16bit_correct rive_png_gamma_16bit_correct +#define png_gamma_8bit_correct rive_png_gamma_8bit_correct +#define png_destroy_gamma_table rive_png_destroy_gamma_table +#define png_build_gamma_table rive_png_build_gamma_table +#define png_safe_error rive_png_safe_error +#define png_safe_warning rive_png_safe_warning +#define png_safe_execute rive_png_safe_execute +#define png_image_error rive_png_image_error +#define png_access_version_number rive_png_access_version_number +#define png_build_grayscale_palette rive_png_build_grayscale_palette +#define png_convert_to_rfc1123 rive_png_convert_to_rfc1123 +#define png_convert_to_rfc1123_buffer rive_png_convert_to_rfc1123_buffer +#define png_create_info_struct rive_png_create_info_struct +#define png_data_freer rive_png_data_freer +#define png_destroy_info_struct rive_png_destroy_info_struct +#define png_free_data rive_png_free_data +#define png_get_copyright rive_png_get_copyright +#define png_get_header_ver rive_png_get_header_ver +#define png_get_header_version rive_png_get_header_version +#define png_get_io_ptr rive_png_get_io_ptr +#define png_get_libpng_ver rive_png_get_libpng_ver +#define png_handle_as_unknown rive_png_handle_as_unknown +#define png_image_free rive_png_image_free +#define png_info_init_3 rive_png_info_init_3 +#define png_init_io rive_png_init_io +#define png_reset_zstream rive_png_reset_zstream +#define png_save_int_32 rive_png_save_int_32 +#define png_set_option rive_png_set_option +#define png_set_sig_bytes rive_png_set_sig_bytes +#define png_sig_cmp rive_png_sig_cmp +#define png_benign_error rive_png_benign_error +#define png_chunk_benign_error rive_png_chunk_benign_error +#define png_chunk_error rive_png_chunk_error +#define png_chunk_warning rive_png_chunk_warning +#define png_error rive_png_error +#define png_get_error_ptr rive_png_get_error_ptr +#define png_longjmp rive_png_longjmp +#define png_set_error_fn rive_png_set_error_fn +#define png_set_longjmp_fn rive_png_set_longjmp_fn +#define png_warning rive_png_warning +#define png_get_bit_depth rive_png_get_bit_depth +#define png_get_bKGD rive_png_get_bKGD +#define png_get_channels rive_png_get_channels +#define png_get_cHRM rive_png_get_cHRM +#define png_get_cHRM_fixed rive_png_get_cHRM_fixed +#define png_get_cHRM_XYZ rive_png_get_cHRM_XYZ +#define png_get_cHRM_XYZ_fixed rive_png_get_cHRM_XYZ_fixed +#define png_get_chunk_cache_max rive_png_get_chunk_cache_max +#define png_get_chunk_malloc_max rive_png_get_chunk_malloc_max +#define png_get_color_type rive_png_get_color_type +#define png_get_compression_buffer_size rive_png_get_compression_buffer_size +#define png_get_compression_type rive_png_get_compression_type +#define png_get_filter_type rive_png_get_filter_type +#define png_get_gAMA rive_png_get_gAMA +#define png_get_gAMA_fixed rive_png_get_gAMA_fixed +#define png_get_hIST rive_png_get_hIST +#define png_get_iCCP rive_png_get_iCCP +#define png_get_IHDR rive_png_get_IHDR +#define png_get_image_height rive_png_get_image_height +#define png_get_image_width rive_png_get_image_width +#define png_get_interlace_type rive_png_get_interlace_type +#define png_get_io_chunk_type rive_png_get_io_chunk_type +#define png_get_io_state rive_png_get_io_state +#define png_get_oFFs rive_png_get_oFFs +#define png_get_palette_max rive_png_get_palette_max +#define png_get_pCAL rive_png_get_pCAL +#define png_get_pHYs rive_png_get_pHYs +#define png_get_pHYs_dpi rive_png_get_pHYs_dpi +#define png_get_pixel_aspect_ratio rive_png_get_pixel_aspect_ratio +#define png_get_pixel_aspect_ratio_fixed rive_png_get_pixel_aspect_ratio_fixed +#define png_get_pixels_per_inch rive_png_get_pixels_per_inch +#define png_get_pixels_per_meter rive_png_get_pixels_per_meter +#define png_get_PLTE rive_png_get_PLTE +#define png_get_rgb_to_gray_status rive_png_get_rgb_to_gray_status +#define png_get_rowbytes rive_png_get_rowbytes +#define png_get_rows rive_png_get_rows +#define png_get_sBIT rive_png_get_sBIT +#define png_get_sCAL rive_png_get_sCAL +#define png_get_sCAL_fixed rive_png_get_sCAL_fixed +#define png_get_sCAL_s rive_png_get_sCAL_s +#define png_get_signature rive_png_get_signature +#define png_get_sPLT rive_png_get_sPLT +#define png_get_sRGB rive_png_get_sRGB +#define png_get_text rive_png_get_text +#define png_get_tIME rive_png_get_tIME +#define png_get_tRNS rive_png_get_tRNS +#define png_get_unknown_chunks rive_png_get_unknown_chunks +#define png_get_user_chunk_ptr rive_png_get_user_chunk_ptr +#define png_get_user_height_max rive_png_get_user_height_max +#define png_get_user_width_max rive_png_get_user_width_max +#define png_get_valid rive_png_get_valid +#define png_get_x_offset_inches rive_png_get_x_offset_inches +#define png_get_x_offset_inches_fixed rive_png_get_x_offset_inches_fixed +#define png_get_x_offset_microns rive_png_get_x_offset_microns +#define png_get_x_offset_pixels rive_png_get_x_offset_pixels +#define png_get_x_pixels_per_inch rive_png_get_x_pixels_per_inch +#define png_get_x_pixels_per_meter rive_png_get_x_pixels_per_meter +#define png_get_y_offset_inches rive_png_get_y_offset_inches +#define png_get_y_offset_inches_fixed rive_png_get_y_offset_inches_fixed +#define png_get_y_offset_microns rive_png_get_y_offset_microns +#define png_get_y_offset_pixels rive_png_get_y_offset_pixels +#define png_get_y_pixels_per_inch rive_png_get_y_pixels_per_inch +#define png_get_y_pixels_per_meter rive_png_get_y_pixels_per_meter +#define png_calloc rive_png_calloc +#define png_free rive_png_free +#define png_free_default rive_png_free_default +#define png_get_mem_ptr rive_png_get_mem_ptr +#define png_malloc rive_png_malloc +#define png_malloc_default rive_png_malloc_default +#define png_malloc_warn rive_png_malloc_warn +#define png_set_mem_fn rive_png_set_mem_fn +#define png_get_progressive_ptr rive_png_get_progressive_ptr +#define png_process_data rive_png_process_data +#define png_process_data_pause rive_png_process_data_pause +#define png_process_data_skip rive_png_process_data_skip +#define png_progressive_combine_row rive_png_progressive_combine_row +#define png_set_progressive_read_fn rive_png_set_progressive_read_fn +#define png_create_read_struct rive_png_create_read_struct +#define png_create_read_struct_2 rive_png_create_read_struct_2 +#define png_destroy_read_struct rive_png_destroy_read_struct +#define png_image_begin_read_from_file rive_png_image_begin_read_from_file +#define png_image_begin_read_from_memory rive_png_image_begin_read_from_memory +#define png_image_begin_read_from_stdio rive_png_image_begin_read_from_stdio +#define png_image_finish_read rive_png_image_finish_read +#define png_read_end rive_png_read_end +#define png_read_image rive_png_read_image +#define png_read_info rive_png_read_info +#define png_read_png rive_png_read_png +#define png_read_row rive_png_read_row +#define png_read_rows rive_png_read_rows +#define png_read_update_info rive_png_read_update_info +#define png_set_read_status_fn rive_png_set_read_status_fn +#define png_start_read_image rive_png_start_read_image +#define png_set_read_fn rive_png_set_read_fn +#define png_set_alpha_mode rive_png_set_alpha_mode +#define png_set_alpha_mode_fixed rive_png_set_alpha_mode_fixed +#define png_set_background rive_png_set_background +#define png_set_background_fixed rive_png_set_background_fixed +#define png_set_crc_action rive_png_set_crc_action +#define png_set_expand rive_png_set_expand +#define png_set_expand_16 rive_png_set_expand_16 +#define png_set_expand_gray_1_2_4_to_8 rive_png_set_expand_gray_1_2_4_to_8 +#define png_set_gamma rive_png_set_gamma +#define png_set_gamma_fixed rive_png_set_gamma_fixed +#define png_set_gray_to_rgb rive_png_set_gray_to_rgb +#define png_set_palette_to_rgb rive_png_set_palette_to_rgb +#define png_set_quantize rive_png_set_quantize +#define png_set_read_user_transform_fn rive_png_set_read_user_transform_fn +#define png_set_rgb_to_gray rive_png_set_rgb_to_gray +#define png_set_rgb_to_gray_fixed rive_png_set_rgb_to_gray_fixed +#define png_set_scale_16 rive_png_set_scale_16 +#define png_set_strip_16 rive_png_set_strip_16 +#define png_set_strip_alpha rive_png_set_strip_alpha +#define png_set_tRNS_to_alpha rive_png_set_tRNS_to_alpha +#define png_get_int_32 rive_png_get_int_32 +#define png_get_uint_16 rive_png_get_uint_16 +#define png_get_uint_31 rive_png_get_uint_31 +#define png_get_uint_32 rive_png_get_uint_32 +#define png_permit_mng_features rive_png_permit_mng_features +#define png_set_benign_errors rive_png_set_benign_errors +#define png_set_bKGD rive_png_set_bKGD +#define png_set_check_for_invalid_index rive_png_set_check_for_invalid_index +#define png_set_cHRM rive_png_set_cHRM +#define png_set_cHRM_fixed rive_png_set_cHRM_fixed +#define png_set_cHRM_XYZ rive_png_set_cHRM_XYZ +#define png_set_cHRM_XYZ_fixed rive_png_set_cHRM_XYZ_fixed +#define png_set_chunk_cache_max rive_png_set_chunk_cache_max +#define png_set_chunk_malloc_max rive_png_set_chunk_malloc_max +#define png_set_compression_buffer_size rive_png_set_compression_buffer_size +#define png_set_gAMA rive_png_set_gAMA +#define png_set_gAMA_fixed rive_png_set_gAMA_fixed +#define png_set_hIST rive_png_set_hIST +#define png_set_iCCP rive_png_set_iCCP +#define png_set_IHDR rive_png_set_IHDR +#define png_set_invalid rive_png_set_invalid +#define png_set_keep_unknown_chunks rive_png_set_keep_unknown_chunks +#define png_set_oFFs rive_png_set_oFFs +#define png_set_pCAL rive_png_set_pCAL +#define png_set_pHYs rive_png_set_pHYs +#define png_set_PLTE rive_png_set_PLTE +#define png_set_read_user_chunk_fn rive_png_set_read_user_chunk_fn +#define png_set_rows rive_png_set_rows +#define png_set_sBIT rive_png_set_sBIT +#define png_set_sCAL rive_png_set_sCAL +#define png_set_sCAL_fixed rive_png_set_sCAL_fixed +#define png_set_sCAL_s rive_png_set_sCAL_s +#define png_set_sPLT rive_png_set_sPLT +#define png_set_sRGB rive_png_set_sRGB +#define png_set_sRGB_gAMA_and_cHRM rive_png_set_sRGB_gAMA_and_cHRM +#define png_set_text rive_png_set_text +#define png_set_tIME rive_png_set_tIME +#define png_set_tRNS rive_png_set_tRNS +#define png_set_unknown_chunk_location rive_png_set_unknown_chunk_location +#define png_set_unknown_chunks rive_png_set_unknown_chunks +#define png_set_user_limits rive_png_set_user_limits +#define png_get_current_pass_number rive_png_get_current_pass_number +#define png_get_current_row_number rive_png_get_current_row_number +#define png_get_user_transform_ptr rive_png_get_user_transform_ptr +#define png_set_add_alpha rive_png_set_add_alpha +#define png_set_bgr rive_png_set_bgr +#define png_set_filler rive_png_set_filler +#define png_set_interlace_handling rive_png_set_interlace_handling +#define png_set_invert_alpha rive_png_set_invert_alpha +#define png_set_invert_mono rive_png_set_invert_mono +#define png_set_packing rive_png_set_packing +#define png_set_packswap rive_png_set_packswap +#define png_set_shift rive_png_set_shift +#define png_set_swap rive_png_set_swap +#define png_set_swap_alpha rive_png_set_swap_alpha +#define png_set_user_transform_info rive_png_set_user_transform_info +#define png_set_write_fn rive_png_set_write_fn +#define png_convert_from_struct_tm rive_png_convert_from_struct_tm +#define png_convert_from_time_t rive_png_convert_from_time_t +#define png_create_write_struct rive_png_create_write_struct +#define png_create_write_struct_2 rive_png_create_write_struct_2 +#define png_destroy_write_struct rive_png_destroy_write_struct +#define png_image_write_to_file rive_png_image_write_to_file +#define png_image_write_to_stdio rive_png_image_write_to_stdio +#define png_set_compression_level rive_png_set_compression_level +#define png_set_compression_mem_level rive_png_set_compression_mem_level +#define png_set_compression_method rive_png_set_compression_method +#define png_set_compression_strategy rive_png_set_compression_strategy +#define png_set_compression_window_bits rive_png_set_compression_window_bits +#define png_set_filter rive_png_set_filter +#define png_set_filter_heuristics rive_png_set_filter_heuristics +#define png_set_filter_heuristics_fixed rive_png_set_filter_heuristics_fixed +#define png_set_flush rive_png_set_flush +#define png_set_text_compression_level rive_png_set_text_compression_level +#define png_set_text_compression_mem_level rive_png_set_text_compression_mem_level +#define png_set_text_compression_method rive_png_set_text_compression_method +#define png_set_text_compression_strategy rive_png_set_text_compression_strategy +#define png_set_text_compression_window_bits rive_png_set_text_compression_window_bits +#define png_set_write_status_fn rive_png_set_write_status_fn +#define png_set_write_user_transform_fn rive_png_set_write_user_transform_fn +#define png_write_end rive_png_write_end +#define png_write_flush rive_png_write_flush +#define png_write_image rive_png_write_image +#define png_write_info rive_png_write_info +#define png_write_info_before_PLTE rive_png_write_info_before_PLTE +#define png_write_png rive_png_write_png +#define png_write_row rive_png_write_row +#define png_write_rows rive_png_write_rows +#define png_save_uint_16 rive_png_save_uint_16 +#define png_save_uint_32 rive_png_save_uint_32 +#define png_write_chunk rive_png_write_chunk +#define png_write_chunk_data rive_png_write_chunk_data +#define png_write_chunk_start rive_png_write_chunk_start +#define png_write_chunk_end rive_png_write_chunk_end +#define png_write_sig rive_png_write_sig +#define png_init_filter_functions_neon rive_png_init_filter_functions_neon +#define png_init_filter_functions_sse2 rive_png_init_filter_functions_sse2 +#define png_get_eXIf rive_png_get_eXIf +#define png_get_eXIf_1 rive_png_get_eXIf_1 +#define png_handle_eXIf rive_png_handle_eXIf +#define png_check_chunk_length rive_png_check_chunk_length +#define png_set_eXIf rive_png_set_eXIf +#define png_set_eXIf_1 rive_png_set_eXIf_1 +#define png_zlib_inflate rive_png_zlib_inflate +#define png_write_eXIf rive_png_write_eXIf +#endif // RIVE_PNGPREFIX_H \ No newline at end of file From 16d32220e76f40fe6492cbc575c80e9545707873 Mon Sep 17 00:00:00 2001 From: HayesGordon Date: Mon, 11 Mar 2024 19:00:52 +0000 Subject: [PATCH 010/138] chore: update README Mostly sentence case for headers and adding new info as needed + removing older things Diffs= e68c7b6de chore: update README (#6824) Co-authored-by: Gordon --- .rive_head | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index 2ab2502a..d951bd1d 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -bcf6451f442d7d55ed423982b58204e93c1d8791 +e68c7b6ded17c667fe344426e54710875fc58e94 diff --git a/README.md b/README.md index 783124a9..2ef3d1a3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The C++ runtime for Rive provides these runtime features: - Abstract Renderer for submitting high level vector path commands with retained path objects to optimize and minimize path re-computation (ultimately up to the concrete rendering implementation). - Example concrete renderer written in C++ with [Skia](https://skia.org/). Skia renderer code is in [skia/renderer/src/skia_factory.cpp](skia/renderer/src/skia_factory.cpp). -## Build System +## Build system We use [premake5](https://premake.github.io/). The Rive dev team primarily works on MacOS. There is some work done by the community to also support Windows and Linux. PRs welcomed for specific platforms you wish to support! We encourage you to use premake as it's highly extensible and configurable for a variety of platforms. ## Build @@ -52,10 +52,10 @@ The tests live in ```rive/test```. To add new tests, create a new ```xxx_test.cp There's a VSCode command provided to ```run tests``` from the Tasks: Run Task command palette. -## Code Formatting +## Code formatting rive-cpp uses clang-format, you can install it with brew on MacOS: ```brew install clang-format```. -## Memory Checks +## Memory checks Note that if you're on MacOS you'll want to install valgrind, which is somewhat complicated these days. This is the easiest solution (please PR a better one when it becomes available). ``` @@ -65,7 +65,7 @@ brew install --HEAD LouisBrunner/valgrind/valgrind You can now run the all the tests through valgrind by running ```test.sh memory```. -## Disassembly Explorer +## Disassembly explorer If you want to examine the generated assembly code per cpp file, install [Disassembly Explorer](https://marketplace.visualstudio.com/items?itemName=dseight.disasexpl) in VSCode. A ```disassemble``` task is provided to compile and preview the generated assembly. You can reach it via the Tasks: Run Task command palette or you can bind it to a shortcut by editing your VSCode keybindings.json: From f21904e92e76d205b4280e3c4822a0f50df7d487 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 15 Mar 2024 19:24:24 +0000 Subject: [PATCH 011/138] support for interrupting transitions on state change We are adding a flag to support interrupting transitions on state changes. Diffs= 337f9df1c support for interrupting transitions on state change (#6850) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/animation/state_transition.hpp | 7 +++++++ include/rive/animation/state_transition_flags.hpp | 5 ++++- src/animation/state_machine_instance.cpp | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.rive_head b/.rive_head index d951bd1d..6076c3e5 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e68c7b6ded17c667fe344426e54710875fc58e94 +337f9df1c04ace751fe16ed2b014477155d9cbfc diff --git a/include/rive/animation/state_transition.hpp b/include/rive/animation/state_transition.hpp index ff375274..412ac065 100644 --- a/include/rive/animation/state_transition.hpp +++ b/include/rive/animation/state_transition.hpp @@ -78,6 +78,13 @@ class StateTransition : public StateTransitionBase StateTransitionFlags::EnableExitTime; } + /// Whether the transition can be interrupted. + bool enableEarlyExit() const + { + return (transitionFlags() & StateTransitionFlags::EnableEarlyExit) == + StateTransitionFlags::EnableEarlyExit; + } + StatusCode import(ImportStack& importStack) override; size_t conditionCount() const { return m_Conditions.size(); } diff --git a/include/rive/animation/state_transition_flags.hpp b/include/rive/animation/state_transition_flags.hpp index 542c231f..87d718ec 100644 --- a/include/rive/animation/state_transition_flags.hpp +++ b/include/rive/animation/state_transition_flags.hpp @@ -23,7 +23,10 @@ enum class StateTransitionFlags : unsigned char /// Whether the animation is held at exit or if it keeps advancing /// during mixing. - PauseOnExit = 1 << 4 + PauseOnExit = 1 << 4, + + /// Whether the transition can exit before it is complete. + EnableEarlyExit = 1 << 5 }; diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index fe7f27ab..65fc3195 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -122,8 +122,8 @@ class StateMachineLayerInstance bool updateState(bool ignoreTriggers) { // Don't allow changing state while a transition is taking place - // (we're mixing one state onto another). - if (isTransitioning()) + // (we're mixing one state onto another) if enableEarlyExit is not true. + if (isTransitioning() && !m_transition->enableEarlyExit()) { return false; } From dcd45e122000e551b87d6f4e5d4a13e493443751 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Fri, 15 Mar 2024 19:36:31 +0000 Subject: [PATCH 012/138] Remove the Queue from Metal PLS Always require the client to supply and commit their own external command buffer. Diffs= e0e55a59e Remove the Queue from Metal PLS (#6852) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 6076c3e5..747fdb36 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -337f9df1c04ace751fe16ed2b014477155d9cbfc +e0e55a59eebeb44596d3dfdb669d85e7f656532d diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 78d35ccc..736a2654 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -157,6 +157,8 @@ end filter({ 'system:windows', 'options:toolset=msc' }) do + defines({ '_CRT_SECURE_NO_WARNINGS' }) + -- We currently suppress several warnings for the MSVC build, some serious. Once this build -- is fully integrated into GitHub actions, we will definitely want to address these. disablewarnings({ From 68ba1f9651741ffc6492b2082c15b41931ca3628 Mon Sep 17 00:00:00 2001 From: zplata Date: Mon, 18 Mar 2024 21:24:20 +0000 Subject: [PATCH 013/138] Add a @rive-app/webgl2 package that uses PLS Diffs= cae08a3c5 Add a @rive-app/webgl2 package that uses PLS (#6845) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 21 ++++++++++++++++++++- decoders/premake5_v2.lua | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 747fdb36..46970fa8 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e0e55a59eebeb44596d3dfdb669d85e7f656532d +cae08a3c5612afad5077dcd6008b73b33fa3c938 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 736a2654..1e97ca19 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -79,6 +79,11 @@ newoption({ description = 'Embed wasm directly into the js, instead of side-loading it.', }) +newoption({ + trigger = 'no-lto', + description = 'Don\'t build with link time optimizations.', +}) + location(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT) targetdir(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT) objdir(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT .. '/obj') @@ -108,9 +113,16 @@ do optimize('On') end -filter({ 'system:not windows', 'options:config=release' }) +filter({ 'options:config=release', 'options:not no-lto', 'not system:ios or windows' }) +do + flags({ 'LinkTimeOptimization' }) +end + +-- The 'LinkTimeOptimization' premake flag generates errors when building for ios. +filter({ 'options:config=release', 'options:not no-lto', 'system:ios' }) do buildoptions({ '-flto=full' }) + linkoptions({ '-flto=full' }) end filter('system:windows') @@ -410,5 +422,12 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then linkoptions({ '-sSINGLE_FILE=1' }) end + filter('options:config=release') + do + optimize('Size') + end + filter({}) end + +filter({}) diff --git a/decoders/premake5_v2.lua b/decoders/premake5_v2.lua index 7d35ee22..b85d38b4 100644 --- a/decoders/premake5_v2.lua +++ b/decoders/premake5_v2.lua @@ -1,4 +1,4 @@ -dofile('setup_compiler.lua') +dofile('rive_build_config.lua') rive = path.getabsolute('../') From 4f8e43deb12f0da2459d2192377142b26e3fb2db Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Wed, 20 Mar 2024 22:47:23 +0000 Subject: [PATCH 014/138] More LTO tweaks Don't use premake's "LinkTimeOptimization" flag on Mac either. This will attempt to use llvm-ar, which doesn't always exist on Mac. Enable premake's "LinkTimeOptimization" flag on Windows. Diffs= e2328daeb More LTO tweaks (#6904) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.rive_head b/.rive_head index 46970fa8..6f9ea6fc 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -cae08a3c5612afad5077dcd6008b73b33fa3c938 +e2328daeb02a92171cd3c0ab78c3c76695a9dd98 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 1e97ca19..25f9c3d9 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -113,14 +113,14 @@ do optimize('On') end -filter({ 'options:config=release', 'options:not no-lto', 'not system:ios or windows' }) +filter({ 'options:config=release', 'options:not no-lto', 'system:not macosx', 'system:not ios'}) do flags({ 'LinkTimeOptimization' }) end --- The 'LinkTimeOptimization' premake flag generates errors when building for ios. -filter({ 'options:config=release', 'options:not no-lto', 'system:ios' }) +filter({ 'options:config=release', 'options:not no-lto', 'system:macosx or ios' }) do + -- The 'LinkTimeOptimization' flag attempts to use llvm-ar, which doesn't always exist on macos. buildoptions({ '-flto=full' }) linkoptions({ '-flto=full' }) end From 8f9d5dd99cbef7e2107259bcacbde936035e33c8 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 26 Mar 2024 20:16:24 +0000 Subject: [PATCH 015/138] No simd canvas Basically disables simd for everything but our new webgl renderer runtime. Diffs= a0a40213f No simd canvas (#6926) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 6f9ea6fc..da4ec7bd 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e2328daeb02a92171cd3c0ab78c3c76695a9dd98 +a0a40213f0ea3490168fd71ad622e04ce364689b diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 25f9c3d9..f9543e7c 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -74,6 +74,11 @@ newoption({ description = 'don\'t disable exceptions (nonstandard for Rive)', }) +newoption({ + trigger = 'no-wasm-simd', + description = 'disable simd for wasm builds', +}) + newoption({ trigger = 'wasm_single', description = 'Embed wasm directly into the js, instead of side-loading it.', @@ -113,7 +118,7 @@ do optimize('On') end -filter({ 'options:config=release', 'options:not no-lto', 'system:not macosx', 'system:not ios'}) +filter({ 'options:config=release', 'options:not no-lto', 'system:not macosx', 'system:not ios' }) do flags({ 'LinkTimeOptimization' }) end @@ -408,10 +413,26 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then filter('options:arch=wasm') do - buildoptions({ '-msimd128' }) linkoptions({ '-sWASM=1' }) end + filter({ 'options:arch=wasm', 'options:not no-wasm-simd' }) + do + buildoptions({ '-msimd128' }) + end + + filter({ 'options:arch=wasm', 'options:config=debug' }) + do + buildoptions({ + '-fsanitize=address', + '-g2', + }) + linkoptions({ + '-fsanitize=address', + '-g2', + }) + end + filter('options:arch=js') do linkoptions({ '-sWASM=0' }) From b48fd9c382746778aea1fd59c7f12ed28d29f1ed Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Wed, 27 Mar 2024 18:56:25 +0000 Subject: [PATCH 016/138] Get wasm sizes back down. Turns out ```Optimize('Size')``` results in -Os and we get quite a bit more savings with -Oz. Diffs= f3739347c Get wasm sizes back down. (#6927) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index da4ec7bd..cc1de3ef 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a0a40213f0ea3490168fd71ad622e04ce364689b +f3739347cf81c6c35d445da3678f987626ce7df3 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index f9543e7c..93de5982 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -445,7 +445,7 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then filter('options:config=release') do - optimize('Size') + buildoptions({ '-Oz' }) end filter({}) From 1674c393ac097d1acc2564f3ea83ded5bc9bee2a Mon Sep 17 00:00:00 2001 From: bodymovin Date: Thu, 28 Mar 2024 00:08:10 +0000 Subject: [PATCH 017/138] propagate parent input change to nested input We have decided to add a new attribute to our code generator that will allow to overwrite the behavior of property setters for the c++ runtime. For the editor, the solution is more complex because we still need to reflect the nested artboard value in the inspector so users can follow changes both at the parent and the child level. Diffs= fee67f16d propagate parent input change to nested input (#6878) ff2c0cbf6 apply final update if it has not been applied before (#6930) Co-authored-by: hernan --- .rive_head | 2 +- dev/core_generator/lib/src/definition.dart | 28 +++++++++------- dev/core_generator/lib/src/property.dart | 5 +++ dev/defs/animation/nested_bool.json | 1 + dev/defs/animation/nested_number.json | 1 + include/rive/animation/nested_bool.hpp | 4 ++- include/rive/animation/nested_input.hpp | 2 +- include/rive/animation/nested_number.hpp | 3 +- .../generated/animation/nested_bool_base.hpp | 12 ++----- .../animation/nested_number_base.hpp | 12 ++----- src/animation/nested_bool.cpp | 33 +++++++++++++++++-- src/animation/nested_number.cpp | 33 +++++++++++++++++-- src/animation/state_machine_instance.cpp | 13 +------- 13 files changed, 96 insertions(+), 53 deletions(-) diff --git a/.rive_head b/.rive_head index cc1de3ef..292ff7c5 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f3739347cf81c6c35d445da3678f987626ce7df3 +fee67f16df7648b5c9bc100b6221c7ba5baca0af diff --git a/dev/core_generator/lib/src/definition.dart b/dev/core_generator/lib/src/definition.dart index 6515f77d..4e02bf62 100644 --- a/dev/core_generator/lib/src/definition.dart +++ b/dev/core_generator/lib/src/definition.dart @@ -220,20 +220,26 @@ class Definition { (property.isSetOverride ? 'override' : '') + '= 0;'); } else { - code.writeln((property.isVirtual ? 'virtual' : 'inline') + + code.writeln(((property.isVirtual || property.isPureVirtual) + ? 'virtual' + : 'inline') + ' ${property.type.cppGetterName} ${property.name}() const ' + (property.isGetOverride ? 'override' : '') + '{ return m_${property.capitalizedName}; }'); - - code.writeln( - 'void ${property.name}(${property.type.cppName} value) ' + - (property.isSetOverride ? 'override' : '') + - '{' - 'if(m_${property.capitalizedName} == value)' - '{return;}' - 'm_${property.capitalizedName} = value;' - '${property.name}Changed();' - '}'); + if (!property.isPureVirtual) { + code.writeln( + 'void ${property.name}(${property.type.cppName} value) ' + + (property.isSetOverride ? 'override' : '') + + '{' + 'if(m_${property.capitalizedName} == value)' + '{return;}' + 'm_${property.capitalizedName} = value;' + '${property.name}Changed();' + '}'); + } else { + code.writeln( + 'virtual void ${property.name}(${property.type.cppName} value) = 0;'); + } } code.writeln(); diff --git a/dev/core_generator/lib/src/property.dart b/dev/core_generator/lib/src/property.dart index e13ae67b..e147e81c 100644 --- a/dev/core_generator/lib/src/property.dart +++ b/dev/core_generator/lib/src/property.dart @@ -20,6 +20,7 @@ class Property { bool isSetOverride = false; bool isGetOverride = false; bool isEncoded = false; + bool isPureVirtual = false; FieldType? typeRuntime; static Property? make( @@ -93,6 +94,10 @@ class Property { if (rt is String) { typeRuntime = FieldType.find(rt); } + dynamic pv = data['pureVirtual']; + if (pv is bool) { + isPureVirtual = pv; + } key = Key.fromJSON(data['key']) ?? Key.forProperty(this); } diff --git a/dev/defs/animation/nested_bool.json b/dev/defs/animation/nested_bool.json index b55c59a2..31aa257f 100644 --- a/dev/defs/animation/nested_bool.json +++ b/dev/defs/animation/nested_bool.json @@ -10,6 +10,7 @@ "type": "bool", "initialValue": "false", "animates": true, + "pureVirtual": true, "key": { "int": 238, "string": "value" diff --git a/dev/defs/animation/nested_number.json b/dev/defs/animation/nested_number.json index 7315cf12..c845ea4e 100644 --- a/dev/defs/animation/nested_number.json +++ b/dev/defs/animation/nested_number.json @@ -10,6 +10,7 @@ "type": "double", "initialValue": "0", "animates": true, + "pureVirtual": true, "key": { "int": 239, "string": "nestedValue" diff --git a/include/rive/animation/nested_bool.hpp b/include/rive/animation/nested_bool.hpp index 813ece21..64210696 100644 --- a/include/rive/animation/nested_bool.hpp +++ b/include/rive/animation/nested_bool.hpp @@ -7,10 +7,12 @@ namespace rive class NestedBool : public NestedBoolBase { public: + void nestedValue(bool value) override; + bool nestedValue() const override; + void applyValue() override; protected: - void nestedValueChanged() override; }; } // namespace rive diff --git a/include/rive/animation/nested_input.hpp b/include/rive/animation/nested_input.hpp index 16d5bf99..0db46dfe 100644 --- a/include/rive/animation/nested_input.hpp +++ b/include/rive/animation/nested_input.hpp @@ -22,7 +22,7 @@ class NestedInput : public NestedInputBase virtual void applyValue() {} protected: - SMIInput* input() + SMIInput* input() const { auto parent = this->parent(); if (parent != nullptr && parent->is()) diff --git a/include/rive/animation/nested_number.hpp b/include/rive/animation/nested_number.hpp index b21dfc3c..f9651260 100644 --- a/include/rive/animation/nested_number.hpp +++ b/include/rive/animation/nested_number.hpp @@ -7,10 +7,11 @@ namespace rive class NestedNumber : public NestedNumberBase { public: + void nestedValue(float value) override; + float nestedValue() const override; void applyValue() override; protected: - void nestedValueChanged() override; }; } // namespace rive diff --git a/include/rive/generated/animation/nested_bool_base.hpp b/include/rive/generated/animation/nested_bool_base.hpp index d756d955..8c015f5a 100644 --- a/include/rive/generated/animation/nested_bool_base.hpp +++ b/include/rive/generated/animation/nested_bool_base.hpp @@ -35,16 +35,8 @@ class NestedBoolBase : public NestedInput bool m_NestedValue = false; public: - inline bool nestedValue() const { return m_NestedValue; } - void nestedValue(bool value) - { - if (m_NestedValue == value) - { - return; - } - m_NestedValue = value; - nestedValueChanged(); - } + virtual bool nestedValue() const { return m_NestedValue; } + virtual void nestedValue(bool value) = 0; Core* clone() const override; void copy(const NestedBoolBase& object) diff --git a/include/rive/generated/animation/nested_number_base.hpp b/include/rive/generated/animation/nested_number_base.hpp index e50ecacb..82bc0c94 100644 --- a/include/rive/generated/animation/nested_number_base.hpp +++ b/include/rive/generated/animation/nested_number_base.hpp @@ -35,16 +35,8 @@ class NestedNumberBase : public NestedInput float m_NestedValue = 0.0f; public: - inline float nestedValue() const { return m_NestedValue; } - void nestedValue(float value) - { - if (m_NestedValue == value) - { - return; - } - m_NestedValue = value; - nestedValueChanged(); - } + virtual float nestedValue() const { return m_NestedValue; } + virtual void nestedValue(float value) = 0; Core* clone() const override; void copy(const NestedNumberBase& object) diff --git a/src/animation/nested_bool.cpp b/src/animation/nested_bool.cpp index 29cd646d..e575022d 100644 --- a/src/animation/nested_bool.cpp +++ b/src/animation/nested_bool.cpp @@ -6,8 +6,8 @@ using namespace rive; class StateMachineInstance; -void NestedBool::nestedValueChanged() { this->applyValue(); } - +// Use the NestedBoolBase m_NestedValue on initialization but then it won't +// be used anymore and interface directly with the nested input value. void NestedBool::applyValue() { auto inputInstance = input(); @@ -16,7 +16,34 @@ void NestedBool::applyValue() auto boolInput = static_cast(inputInstance); if (boolInput != nullptr) { - boolInput->value(nestedValue()); + boolInput->value(NestedBoolBase::nestedValue()); + } + } +} + +void NestedBool::nestedValue(bool value) +{ + auto inputInstance = input(); + if (inputInstance != nullptr) + { + auto boolInput = static_cast(inputInstance); + if (boolInput != nullptr && boolInput->value() != value) + { + boolInput->value(value); + } + } +} + +bool NestedBool::nestedValue() const +{ + auto inputInstance = input(); + if (inputInstance != nullptr) + { + auto boolInput = static_cast(inputInstance); + if (boolInput != nullptr) + { + return boolInput->value(); } } + return false; } \ No newline at end of file diff --git a/src/animation/nested_number.cpp b/src/animation/nested_number.cpp index a81236fb..a3d88293 100644 --- a/src/animation/nested_number.cpp +++ b/src/animation/nested_number.cpp @@ -6,8 +6,8 @@ using namespace rive; class StateMachineInstance; -void NestedNumber::nestedValueChanged() { this->applyValue(); } - +// Use the NestedNumberBase m_NestedValue on initialization but then it won't +// be used anymore and interface directly with the nested input value. void NestedNumber::applyValue() { auto inputInstance = input(); @@ -16,7 +16,34 @@ void NestedNumber::applyValue() auto numInput = static_cast(inputInstance); if (numInput != nullptr) { - numInput->value(nestedValue()); + numInput->value(NestedNumberBase::nestedValue()); + } + } +} + +void NestedNumber::nestedValue(float value) +{ + auto inputInstance = input(); + if (inputInstance != nullptr) + { + auto numInput = static_cast(inputInstance); + if (numInput != nullptr && numInput->value() != value) + { + numInput->value(value); + } + } +} + +float NestedNumber::nestedValue() const +{ + auto inputInstance = input(); + if (inputInstance != nullptr) + { + auto numInput = static_cast(inputInstance); + if (numInput != nullptr) + { + return numInput->value(); } } + return 0.0; } \ No newline at end of file diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 65fc3195..0348c6e9 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -83,10 +83,7 @@ class StateMachineLayerInstance m_stateFrom->advance(seconds, m_stateMachineInstance); } - if (isTransitionEnded()) - { - apply(); - } + apply(); for (int i = 0; updateState(i != 0); i++) { @@ -99,8 +96,6 @@ class StateMachineLayerInstance } } - apply(); - m_currentState->clearSpilledTime(); return m_mix != 1.0f || m_waitingForExit || @@ -113,12 +108,6 @@ class StateMachineLayerInstance m_mix < 1.0f; } - bool isTransitionEnded() - { - return m_transition != nullptr && m_stateFrom != nullptr && m_transition->duration() != 0 && - m_mix == 1.0f; - } - bool updateState(bool ignoreTriggers) { // Don't allow changing state while a transition is taking place From fc1d270b4cbdea973c0ad04ff4470fcd2663c4f4 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Thu, 28 Mar 2024 23:41:31 +0000 Subject: [PATCH 018/138] Export audio clip Fixes an issue with the audio preview generator using the wrong sample rate when clipping the audio which is resulting in incorrect exported audio files. Allows referencing and playing back audio clips and now generalizes the behavior as AssetFile(s). Diffs= a69bfba11 Export audio clip (#6949) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- src/audio/audio_reader.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 292ff7c5..34c1fdde 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -fee67f16df7648b5c9bc100b6221c7ba5baca0af +a69bfba11ec4a116b8712af0b685aa27a5309e43 diff --git a/src/audio/audio_reader.cpp b/src/audio/audio_reader.cpp index bfc3d182..8451b3ca 100644 --- a/src/audio/audio_reader.cpp +++ b/src/audio/audio_reader.cpp @@ -12,7 +12,7 @@ AudioReader::AudioReader(rcp audioSource, uint32_t channels) : AudioReader::~AudioReader() { ma_decoder_uninit(&m_decoder); } uint32_t AudioReader::channels() const { return m_channels; } -uint32_t AudioReader::sampleRate() const { return m_source->sampleRate(); } +uint32_t AudioReader::sampleRate() const { return m_decoder.outputSampleRate; } ma_decoder* AudioReader::decoder() { return &m_decoder; } uint64_t AudioReader::lengthInFrames() From 820ce851d9abd1a844d4bf7360eead28f6a82369 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Fri, 29 Mar 2024 02:47:13 +0000 Subject: [PATCH 019/138] Export proxy and testing at runtime. Works in the viewer now with a trimmed audio clip. Diffs= 473dbcb5c Export proxy and testing at runtime. (#6950) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- viewer/src/viewer_content/scene_content.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 34c1fdde..ca285519 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a69bfba11ec4a116b8712af0b685aa27a5309e43 +473dbcb5ccba6d5cb077f762ac7094ca492d6319 diff --git a/viewer/src/viewer_content/scene_content.cpp b/viewer/src/viewer_content/scene_content.cpp index 392a6665..e847adb1 100644 --- a/viewer/src/viewer_content/scene_content.cpp +++ b/viewer/src/viewer_content/scene_content.cpp @@ -14,6 +14,8 @@ #include "rive/math/aabb.hpp" #include "rive/assets/image_asset.hpp" #include "viewer/viewer_content.hpp" +#include "rive/relative_local_asset_loader.hpp" + #ifdef RIVE_RENDERER_TESS #include "viewer/sample_tools/sample_atlas_packer.hpp" #endif @@ -382,7 +384,9 @@ class SceneContent : public ViewerContent std::unique_ptr ViewerContent::Scene(const char filename[]) { auto bytes = LoadFile(filename); - if (auto file = rive::File::import(bytes, RiveFactory())) + rive::RelativeLocalAssetLoader loader(filename); + rive::ImportResult result; + if (auto file = rive::File::import(bytes, RiveFactory(), &result, &loader)) { return rivestd::make_unique(filename, std::move(file)); } From 40cc4f81224ff80c4cf677c3930e6830b66d4f73 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Tue, 2 Apr 2024 22:42:06 +0000 Subject: [PATCH 020/138] treat cubic curve as quad when control point equals endpoint using a follow path with oriented mode on, if the target path's last two points were a cubic bezier and a straight line, we were not calculating correctly the tangent at distance 100%. That would cause the object with the follow path constraint to shift direction in the last position. This PR fixes the issue by changing how that edge case works and calculates the tangent as a quadratic bezier curve instead. fixes #6969 Diffs= 522a31bc2 treat cubic curve as quad when control point equals endpoint (#6919) Co-authored-by: hernan --- .rive_head | 2 +- src/math/contour_measure.cpp | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index ca285519..bd039cb0 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -473dbcb5ccba6d5cb077f762ac7094ca492d6319 +522a31bc24b4f8179b9a4f27d9a8154af385767a diff --git a/src/math/contour_measure.cpp b/src/math/contour_measure.cpp index 0aa804af..57c833c4 100644 --- a/src/math/contour_measure.cpp +++ b/src/math/contour_measure.cpp @@ -66,6 +66,27 @@ static ContourMeasure::PosTan eval_quad(const Vec2D pts[], float t) static ContourMeasure::PosTan eval_cubic(const Vec2D pts[], float t) { assert(t >= 0 && t <= 1); + // When t==0 and t==1, the most accurate way to find tangents is by differencing. + if (t == 0 || t == 1) + { + if (t == 0) + { + return {pts[0], + (pts[0] != pts[1] ? pts[1] + : pts[1] != pts[2] ? pts[2] + : pts[3]) - + pts[0] + + }; + } + else + { + return {pts[3], + pts[3] - (pts[3] != pts[2] ? pts[2] + : pts[2] != pts[1] ? pts[1] + : pts[0])}; + } + } const EvalCubic eval(pts); @@ -139,11 +160,9 @@ void ContourMeasure::Segment::extract(RawPath* dst, ContourMeasure::PosTan ContourMeasure::getPosTan(float distance) const { // specal-case end of the contour - if (distance >= m_length) + if (distance > m_length) { - size_t N = m_points.size(); - assert(N > 1); - return {m_points[N - 1], (m_points[N - 1] - m_points[N - 2]).normalized()}; + distance = m_length; } if (distance < 0) From a96799e64de0fe73336272c27ac2ce3bfe2f17a1 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Sun, 7 Apr 2024 15:12:39 +0000 Subject: [PATCH 021/138] Audio asset volume + VU This also fixes a bug where multiple sounds would play at the same time making clipping even worse... Some more details here: https://2dimensions.slack.com/archives/CHMAP278R/p1712443028936919 Diffs= f832e2617 Audio asset volume + VU (#6985) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 2 +- dev/core_generator/lib/src/definition.dart | 16 +- dev/defs/artboard.json | 11 -- dev/defs/assets/audio_asset.json | 54 +++++- dev/defs/assets/export_audio.json | 40 ++++ dev/test/premake5.lua | 1 + include/rive/assets/export_audio.hpp | 13 ++ include/rive/audio/audio_engine.hpp | 19 +- include/rive/audio/audio_sound.hpp | 19 +- .../generated/assets/audio_asset_base.hpp | 7 +- .../generated/assets/export_audio_base.hpp | 71 +++++++ include/rive/generated/core_registry.hpp | 7 + src/audio/audio_engine.cpp | 181 ++++++++++++++++-- src/audio/audio_sound.cpp | 40 +++- src/audio_event.cpp | 6 +- test/audio_test.cpp | 78 +++++++- 17 files changed, 506 insertions(+), 61 deletions(-) create mode 100644 dev/defs/assets/export_audio.json create mode 100644 include/rive/assets/export_audio.hpp create mode 100644 include/rive/generated/assets/export_audio_base.hpp diff --git a/.rive_head b/.rive_head index bd039cb0..29283048 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -522a31bc24b4f8179b9a4f27d9a8154af385767a +f832e26172cfbd11d52114ebb667e13418a5b1cd diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 93de5982..49fa644f 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -135,7 +135,7 @@ do staticruntime('on') -- Match Skia's /MT flag for link compatibility runtime('Release') -- Use /MT even in debug (/MTd is incompatible with Skia) architecture('x64') - defines({ '_USE_MATH_DEFINES' }) + defines({ '_USE_MATH_DEFINES', 'NOMINMAX' }) end filter({ 'system:windows', 'options:toolset=clang' }) diff --git a/dev/core_generator/lib/src/definition.dart b/dev/core_generator/lib/src/definition.dart index 4e02bf62..eeac8987 100644 --- a/dev/core_generator/lib/src/definition.dart +++ b/dev/core_generator/lib/src/definition.dart @@ -30,11 +30,24 @@ class Definition { properties.where((property) => property.getExportType().storesData); Definition? _extensionOf; + Definition? _rawExtensionOf; Key? _key; bool _isAbstract = false; bool _editorOnly = false; bool _forRuntime = true; bool get forRuntime => _forRuntime; + + Definition? getRuntimeExtensionOf(Definition? definition) { + var extensionOf = definition; + if (extensionOf != null) { + if (extensionOf._forRuntime) { + return extensionOf; + } + return getRuntimeExtensionOf(extensionOf._extensionOf); + } + return extensionOf; + } + static Definition? make(String filename) { var definition = definitions[filename]; if (definition != null) { @@ -61,7 +74,8 @@ class Definition { Definition.fromFilename(this._filename, Map data) { dynamic extendsFilename = data['extends']; if (extendsFilename is String) { - _extensionOf = Definition.make(extendsFilename); + _rawExtensionOf = Definition.make(extendsFilename); + _extensionOf = getRuntimeExtensionOf(_rawExtensionOf); } dynamic nameValue = data['name']; if (nameValue is String) { diff --git a/dev/defs/artboard.json b/dev/defs/artboard.json index 8b1f39a0..628ce9be 100644 --- a/dev/defs/artboard.json +++ b/dev/defs/artboard.json @@ -123,17 +123,6 @@ "description": "List of selected animations", "runtime": false, "coop": false - }, - "viewModelId": { - "type": "Id", - "typeRuntime": "uint", - "initialValue": "Core.missingId", - "initialValueRuntime": "-1", - "key": { - "int": 434, - "string": "viewmodelid" - }, - "description": "The view model attached to this artboard data context." } } } \ No newline at end of file diff --git a/dev/defs/assets/audio_asset.json b/dev/defs/assets/audio_asset.json index 667cf270..aed1f625 100644 --- a/dev/defs/assets/audio_asset.json +++ b/dev/defs/assets/audio_asset.json @@ -4,5 +4,57 @@ "int": 406, "string": "audioasset" }, - "extends": "assets/file_asset.json" + "extends": "assets/export_audio.json", + "properties": { + "sampleRate": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 473, + "string": "samplerate" + }, + "description": "Sample rate of the source audio file.", + "runtime": false + }, + "channels": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 474, + "string": "channels" + }, + "description": "Channel count of the source audio file.", + "runtime": false + }, + "durationSeconds": { + "type": "double", + "initialValue": "0", + "key": { + "int": 475, + "string": "durationseconds" + }, + "description": "Duration in seconds of the source audio file.", + "runtime": false + }, + "formatValue": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 476, + "string": "formatvalue" + }, + "description": "Container format value of the source audio file.", + "runtime": false + }, + "isCustom": { + "type": "bool", + "initialValue": "true", + "key": { + "int": 426, + "string": "iscustom" + }, + "description": "True if a custom asset, i.e the user has uploaded it", + "runtime": false + } + } } \ No newline at end of file diff --git a/dev/defs/assets/export_audio.json b/dev/defs/assets/export_audio.json new file mode 100644 index 00000000..37c747c6 --- /dev/null +++ b/dev/defs/assets/export_audio.json @@ -0,0 +1,40 @@ +{ + "name": "ExportAudio", + "key": { + "int": 422, + "string": "exportaudio" + }, + "abstract": true, + "extends": "assets/file_asset.json", + "properties": { + "exportFormatValue": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 527, + "string": "formatvalue" + }, + "description": "Start seconds of this clip", + "runtime": false + }, + "exportQualityValue": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 528, + "string": "qualityvalue" + }, + "description": "Start seconds of this clip", + "runtime": false + }, + "volume": { + "type": "double", + "initialValue": "1", + "key": { + "int": 530, + "string": "volume" + }, + "description": "Volume applied to all instances of this audio asset." + } + } +} \ No newline at end of file diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index b9079eb4..bef580b6 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -6,6 +6,7 @@ defines({ 'WITH_RIVE_TOOLS', 'WITH_RIVE_TEXT', 'WITH_RIVE_AUDIO', + 'WITH_RIVE_AUDIO_TOOLS', }) dofile(path.join(path.getabsolute('../../'), 'premake5_v2.lua')) diff --git a/include/rive/assets/export_audio.hpp b/include/rive/assets/export_audio.hpp new file mode 100644 index 00000000..7642863a --- /dev/null +++ b/include/rive/assets/export_audio.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_EXPORT_AUDIO_HPP_ +#define _RIVE_EXPORT_AUDIO_HPP_ +#include "rive/generated/assets/export_audio_base.hpp" +#include +namespace rive +{ +class ExportAudio : public ExportAudioBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/audio/audio_engine.hpp b/include/rive/audio/audio_engine.hpp index de7b21d4..e23f5393 100644 --- a/include/rive/audio/audio_engine.hpp +++ b/include/rive/audio/audio_engine.hpp @@ -11,16 +11,18 @@ typedef struct ma_engine ma_engine; typedef struct ma_sound ma_sound; typedef struct ma_device ma_device; +typedef struct ma_node_base ma_node_base; namespace rive { class AudioSound; class AudioSource; - +class LevelsNode; class AudioEngine : public RefCnt { friend class AudioSound; friend class AudioSource; + friend class LevelsNode; public: static const uint32_t defaultNumChannels = 2; @@ -48,17 +50,26 @@ class AudioEngine : public RefCnt bool sumAudioFrames(float* frames, uint64_t numFrames); #endif +#ifdef WITH_RIVE_AUDIO_TOOLS + void initLevelMonitor(); + void levels(Span levels); + float level(uint32_t channel); +#endif + private: AudioEngine(ma_engine* engine); ma_device* m_device; ma_engine* m_engine; std::vector> m_completedSounds; - - void completeSound(rcp sound); - void purgeCompletedSounds(); + rcp m_playingSoundsHead; static void SoundCompleted(void* pUserData, ma_sound* pSound); +#ifdef WITH_RIVE_AUDIO_TOOLS + void measureLevels(const float* frames, uint32_t frameCount); + std::vector m_levels; + LevelsNode* m_levelMonitor = nullptr; +#endif #ifdef EXTERNAL_RIVE_AUDIO_ENGINE std::vector m_readFrames; #endif diff --git a/include/rive/audio/audio_sound.hpp b/include/rive/audio/audio_sound.hpp index 2a409f62..783183ca 100644 --- a/include/rive/audio/audio_sound.hpp +++ b/include/rive/audio/audio_sound.hpp @@ -16,19 +16,26 @@ class AudioSound : public RefCnt bool seek(uint64_t timeInFrames); ~AudioSound(); void stop(uint64_t fadeTimeInFrames = 0); + float volume(); + void volume(float value); + bool completed() const; private: - AudioSound(rcp engine); - void complete(); + AudioSound(AudioEngine* engine); + ma_decoder* decoder() { return &m_decoder; } + ma_audio_buffer* buffer() { return &m_buffer; } + ma_sound* sound() { return &m_sound; } + void dispose(); - rcp m_engine; ma_decoder m_decoder; ma_audio_buffer m_buffer; ma_sound m_sound; - ma_decoder* decoder() { return &m_decoder; } - ma_audio_buffer* buffer() { return &m_buffer; } - ma_sound* sound() { return &m_sound; } + // This is storage used by the AudioEngine. + bool m_isDisposed; + rcp m_nextPlaying; + rcp m_prevPlaying; + AudioEngine* m_engine; }; } // namespace rive diff --git a/include/rive/generated/assets/audio_asset_base.hpp b/include/rive/generated/assets/audio_asset_base.hpp index 6af1e4e8..49f65788 100644 --- a/include/rive/generated/assets/audio_asset_base.hpp +++ b/include/rive/generated/assets/audio_asset_base.hpp @@ -1,12 +1,12 @@ #ifndef _RIVE_AUDIO_ASSET_BASE_HPP_ #define _RIVE_AUDIO_ASSET_BASE_HPP_ -#include "rive/assets/file_asset.hpp" +#include "rive/assets/export_audio.hpp" namespace rive { -class AudioAssetBase : public FileAsset +class AudioAssetBase : public ExportAudio { protected: - typedef FileAsset Super; + typedef ExportAudio Super; public: static const uint16_t typeKey = 406; @@ -18,6 +18,7 @@ class AudioAssetBase : public FileAsset switch (typeKey) { case AudioAssetBase::typeKey: + case ExportAudioBase::typeKey: case FileAssetBase::typeKey: case AssetBase::typeKey: return true; diff --git a/include/rive/generated/assets/export_audio_base.hpp b/include/rive/generated/assets/export_audio_base.hpp new file mode 100644 index 00000000..12cb58c4 --- /dev/null +++ b/include/rive/generated/assets/export_audio_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_EXPORT_AUDIO_BASE_HPP_ +#define _RIVE_EXPORT_AUDIO_BASE_HPP_ +#include "rive/assets/file_asset.hpp" +#include "rive/core/field_types/core_double_type.hpp" +namespace rive +{ +class ExportAudioBase : public FileAsset +{ +protected: + typedef FileAsset Super; + +public: + static const uint16_t typeKey = 422; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ExportAudioBase::typeKey: + case FileAssetBase::typeKey: + case AssetBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t volumePropertyKey = 530; + +private: + float m_Volume = 1.0f; + +public: + inline float volume() const { return m_Volume; } + void volume(float value) + { + if (m_Volume == value) + { + return; + } + m_Volume = value; + volumeChanged(); + } + + void copy(const ExportAudioBase& object) + { + m_Volume = object.m_Volume; + FileAsset::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case volumePropertyKey: + m_Volume = CoreDoubleType::deserialize(reader); + return true; + } + return FileAsset::deserialize(propertyKey, reader); + } + +protected: + virtual void volumeChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index e8fe1081..a911f8cf 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -66,6 +66,7 @@ #include "rive/assets/asset.hpp" #include "rive/assets/audio_asset.hpp" #include "rive/assets/drawable_asset.hpp" +#include "rive/assets/export_audio.hpp" #include "rive/assets/file_asset.hpp" #include "rive/assets/file_asset_contents.hpp" #include "rive/assets/folder.hpp" @@ -1086,6 +1087,9 @@ class CoreRegistry case DrawableAssetBase::widthPropertyKey: object->as()->width(value); break; + case ExportAudioBase::volumePropertyKey: + object->as()->volume(value); + break; } } static void setBool(Core* object, int propertyKey, bool value) @@ -1673,6 +1677,8 @@ class CoreRegistry return object->as()->height(); case DrawableAssetBase::widthPropertyKey: return object->as()->width(); + case ExportAudioBase::volumePropertyKey: + return object->as()->volume(); } return 0.0f; } @@ -1981,6 +1987,7 @@ class CoreRegistry case TextBase::paragraphSpacingPropertyKey: case DrawableAssetBase::heightPropertyKey: case DrawableAssetBase::widthPropertyKey: + case ExportAudioBase::volumePropertyKey: return CoreDoubleType::id; case TransformComponentConstraintBase::offsetPropertyKey: case TransformComponentConstraintBase::doesCopyPropertyKey: diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index c85eee17..268e22e8 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -18,14 +18,136 @@ #include "rive/audio/audio_sound.hpp" #include "rive/audio/audio_source.hpp" +#include + using namespace rive; void AudioEngine::SoundCompleted(void* pUserData, ma_sound* pSound) { AudioSound* audioSound = (AudioSound*)pUserData; - audioSound->complete(); + + auto next = audioSound->m_nextPlaying; + auto prev = audioSound->m_prevPlaying; + if (next != nullptr) + { + next->m_prevPlaying = prev; + } + if (prev != nullptr) + { + prev->m_nextPlaying = next; + } + + auto engine = audioSound->m_engine; + if (engine->m_playingSoundsHead.get() == audioSound) + { + engine->m_playingSoundsHead = next; + } + + // Unlink audio sound. + engine->m_completedSounds.push_back(ref_rcp(audioSound)); + audioSound->m_nextPlaying = nullptr; + audioSound->m_prevPlaying = nullptr; +} + +#ifdef WITH_RIVE_AUDIO_TOOLS +namespace rive +{ +class LevelsNode +{ +public: + ma_node_base base; + AudioEngine* engine; + static void measureLevels(ma_node* pNode, + const float** ppFramesIn, + ma_uint32* pFrameCountIn, + float** ppFramesOut, + ma_uint32* pFrameCountOut) + { + const float* frames = ppFramesIn[0]; + + ma_uint32 frameCount = pFrameCountIn[0]; + + static_cast(pNode)->engine->measureLevels(frames, (uint32_t)frameCount); + } +}; +} // namespace rive + +void AudioEngine::measureLevels(const float* frames, uint32_t frameCount) +{ + uint32_t channelCount = channels(); + + for (uint32_t i = 0; i < frameCount; i++) + { + for (uint32_t c = 0; c < channelCount; c++) + { + float sample = *frames++; + m_levels[c] = std::max(m_levels[c], sample); + } + } +} + +static ma_node_vtable measure_levels_vtable = {LevelsNode::measureLevels, + nullptr, + 1, + 1, + MA_NODE_FLAG_PASSTHROUGH}; + +void AudioEngine::initLevelMonitor() +{ + if (m_levelMonitor == nullptr) + { + m_levelMonitor = new LevelsNode(); + m_levelMonitor->engine = this; + + ma_node_config nodeConfig = ma_node_config_init(); + nodeConfig.vtable = &measure_levels_vtable; + uint32_t channelCount = channels(); + nodeConfig.pInputChannels = &channelCount; + nodeConfig.pOutputChannels = &channelCount; + m_levels.resize(channelCount); + + auto graph = ma_engine_get_node_graph(m_engine); + if (ma_node_init(graph, &nodeConfig, nullptr, &m_levelMonitor->base) != MA_SUCCESS) + { + delete m_levelMonitor; + m_levelMonitor = nullptr; + return; + } + if (ma_node_attach_output_bus(&m_levelMonitor->base, + 0, + ma_node_graph_get_endpoint(graph), + 0) != MA_SUCCESS) + { + ma_node_uninit(&m_levelMonitor->base, nullptr); + delete m_levelMonitor; + m_levelMonitor = nullptr; + return; + } + } } +void AudioEngine::levels(Span levels) +{ + int size = std::min((int)m_levels.size(), (int)levels.size()); + for (int i = 0; i < size; i++) + { + levels[i] = m_levels[i]; + m_levels[i] = 0.0f; + } +} + +float AudioEngine::level(uint32_t channel) +{ + if (channel < m_levels.size()) + { + float value = m_levels[channel]; + m_levels[channel] = 0.0f; + return value; + } + return 0.0f; +} +#endif + rcp AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate) { ma_engine_config engineConfig = ma_engine_config_init(); @@ -60,11 +182,15 @@ rcp AudioEngine::play(rcp source, uint64_t endTime, uint64_t soundStartTime) { - purgeCompletedSounds(); + // We have to dispose completed sounds out of the completed callback. So we + // do it on next play or at destruct. + for (auto sound : m_completedSounds) + { + sound->dispose(); + } + m_completedSounds.clear(); - rive::rcp rcEngine = rive::rcp(this); - rcEngine->ref(); - rcp audioSound = rcp(new AudioSound(rcEngine)); + rcp audioSound = rcp(new AudioSound(this)); if (source->isBuffered()) { rive::Span samples = source->bufferedSamples(); @@ -115,9 +241,6 @@ rcp AudioEngine::play(rcp source, audioSound->seek(soundStartTime); } - // one extra ref for sound as we're waiting for playback to complete. - audioSound->ref(); - ma_sound_set_end_callback(audioSound->sound(), SoundCompleted, audioSound.get()); if (startTime != 0) @@ -128,30 +251,58 @@ rcp AudioEngine::play(rcp source, { ma_sound_set_stop_time_in_pcm_frames(audioSound->sound(), endTime); } +#ifdef WITH_RIVE_AUDIO_TOOLS + if (m_levelMonitor != nullptr) + { + ma_node_attach_output_bus(audioSound->sound(), 0, m_levelMonitor, 0); + } +#endif if (ma_sound_start(audioSound->sound()) != MA_SUCCESS) { fprintf(stderr, "AudioSource::play - failed to start sound\n"); return nullptr; } + if (m_playingSoundsHead != nullptr) + { + m_playingSoundsHead->m_prevPlaying = audioSound; + } + audioSound->m_nextPlaying = m_playingSoundsHead; + m_playingSoundsHead = audioSound; + return audioSound; } -void AudioEngine::completeSound(rcp sound) { m_completedSounds.push_back(sound); } - -void AudioEngine::purgeCompletedSounds() +AudioEngine::~AudioEngine() { + auto sound = m_playingSoundsHead; + while (sound != nullptr) + { + sound->dispose(); + + auto next = sound->m_nextPlaying; + sound->m_nextPlaying = nullptr; + sound->m_prevPlaying = nullptr; + sound = next; + } + for (auto sound : m_completedSounds) { - sound->unref(); + sound->dispose(); } m_completedSounds.clear(); -} -AudioEngine::~AudioEngine() -{ ma_engine_uninit(m_engine); delete m_engine; + +#ifdef WITH_RIVE_AUDIO_TOOLS + if (m_levelMonitor != nullptr) + { + ma_node_uninit(&m_levelMonitor->base, nullptr); + delete m_levelMonitor; + } + +#endif } uint64_t AudioEngine::timeInFrames() diff --git a/src/audio/audio_sound.cpp b/src/audio/audio_sound.cpp index 21631f40..e355aadf 100644 --- a/src/audio/audio_sound.cpp +++ b/src/audio/audio_sound.cpp @@ -6,19 +6,42 @@ using namespace rive; -AudioSound::AudioSound(rcp engine) : - m_engine(std::move(engine)), m_decoder({}), m_buffer({}), m_sound({}) +AudioSound::AudioSound(AudioEngine* engine) : + m_decoder({}), m_buffer({}), m_sound({}), m_isDisposed(false), m_engine(engine) {} -AudioSound::~AudioSound() +void AudioSound::dispose() { + if (m_isDisposed) + { + return; + } + m_isDisposed = true; ma_sound_uninit(&m_sound); ma_decoder_uninit(&m_decoder); ma_audio_buffer_uninit(&m_buffer); } +float AudioSound::volume() { return ma_sound_get_volume(&m_sound); } +void AudioSound::volume(float value) { ma_sound_set_volume(&m_sound, value); } + +bool AudioSound::completed() const +{ + if (m_isDisposed) + { + return true; + } + return (bool)ma_sound_at_end(&m_sound); +} + +AudioSound::~AudioSound() { dispose(); } + void AudioSound::stop(uint64_t fadeTimeInFrames) { + if (m_isDisposed) + { + return; + } if (fadeTimeInFrames == 0) { ma_sound_stop(&m_sound); @@ -29,15 +52,12 @@ void AudioSound::stop(uint64_t fadeTimeInFrames) } } -void AudioSound::complete() -{ - auto sound = rcp(this); - sound->ref(); - m_engine->completeSound(sound); -} - bool AudioSound::seek(uint64_t timeInFrames) { + if (m_isDisposed) + { + return false; + } return ma_sound_seek_to_pcm_frame(&m_sound, (ma_uint64)timeInFrames) == MA_SUCCESS; } diff --git a/src/audio_event.cpp b/src/audio_event.cpp index 8ea32c67..1ba130b3 100644 --- a/src/audio_event.cpp +++ b/src/audio_event.cpp @@ -28,7 +28,11 @@ void AudioEvent::trigger(const CallbackData& value) #endif AudioEngine::RuntimeEngine(); - engine->play(audioSource, engine->timeInFrames(), 0, 0); + auto sound = engine->play(audioSource, engine->timeInFrames(), 0, 0); + if (audioAsset->volume() != 1.0f) + { + sound->volume(audioAsset->volume()); + } #endif } diff --git a/test/audio_test.cpp b/test/audio_test.cpp index f62e8446..06ffa307 100644 --- a/test/audio_test.cpp +++ b/test/audio_test.cpp @@ -1,5 +1,6 @@ #include "rive/audio/audio_engine.hpp" #include "rive/audio/audio_source.hpp" +#include "rive/audio/audio_sound.hpp" #include "rive/audio/audio_reader.hpp" #include "rive/audio_event.hpp" #include "rive/assets/audio_asset.hpp" @@ -36,26 +37,43 @@ TEST_CASE("audio source can be opened", "[audio]") REQUIRE(engine != nullptr); auto file = loadFile("../../test/assets/audio/what.wav"); auto span = Span(file); - AudioSource audioSource(span); - REQUIRE(audioSource.channels() == 2); - REQUIRE(audioSource.sampleRate() == 44100); + rcp audioSource = rcp(new AudioSource(span)); + REQUIRE(audioSource->channels() == 2); + REQUIRE(audioSource->sampleRate() == 44100); // Try some different sample rates. { - auto reader = audioSource.makeReader(2, 44100); + auto reader = audioSource->makeReader(2, 44100); REQUIRE(reader != nullptr); REQUIRE(reader->lengthInFrames() == 9688); } { - auto reader = audioSource.makeReader(1, 48000); + auto reader = audioSource->makeReader(1, 48000); REQUIRE(reader != nullptr); REQUIRE(reader->lengthInFrames() == 10544); } { - auto reader = audioSource.makeReader(2, 32000); + auto reader = audioSource->makeReader(2, 32000); REQUIRE(reader != nullptr); REQUIRE(reader->lengthInFrames() == 7029); } + + float channels[2] = {0, 0}; + engine->initLevelMonitor(); + engine->levels(Span(&channels[0], 2)); + REQUIRE(channels[0] == 0); + REQUIRE(channels[1] == 0); + + auto sound = engine->play(audioSource, 0, 0, 0); + float frames[512 * 2] = {}; + engine->readAudioFrames(frames, 512); + engine->levels(Span(&channels[0], 2)); + REQUIRE(channels[0] != 0); + REQUIRE(channels[1] != 0); + + engine->readAudioFrames(frames, 512); + REQUIRE(engine->level(0) != 0); + REQUIRE(engine->level(1) != 0); } TEST_CASE("file with audio loads correctly", "[text]") @@ -83,4 +101,50 @@ TEST_CASE("file with audio loads correctly", "[text]") // artboard->advance(0.0f); // rive::NoOpRenderer renderer; // artboard->draw(&renderer); -} \ No newline at end of file +} + +TEST_CASE("audio sound can outlive engine", "[audio]") +{ + rcp sound; + { + rcp engine = AudioEngine::Make(2, 44100); + REQUIRE(engine != nullptr); + auto file = loadFile("../../test/assets/audio/what.wav"); + auto span = Span(file); + rcp audioSource = rcp(new AudioSource(span)); + REQUIRE(audioSource->channels() == 2); + REQUIRE(audioSource->sampleRate() == 44100); + + sound = engine->play(audioSource, 0, 0, 0); + float frames[512 * 2] = {}; + engine->readAudioFrames(frames, 512); + } + sound->stop(); +} + +TEST_CASE("many audio sounds can outlive engine", "[audio]") +{ + std::vector> sounds; + { + rcp engine = AudioEngine::Make(2, 44100); + REQUIRE(engine != nullptr); + auto file = loadFile("../../test/assets/audio/what.wav"); + auto span = Span(file); + rcp audioSource = rcp(new AudioSource(span)); + REQUIRE(audioSource->channels() == 2); + REQUIRE(audioSource->sampleRate() == 44100); + + for (int i = 0; i < 20; i++) + { + sounds.emplace_back(engine->play(audioSource, 0, 0, 0)); + } + float frames[512 * 2] = {}; + engine->readAudioFrames(frames, 512); + } + for (auto sound : sounds) + { + sound->stop(); + } +} + +// TODO check if sound->stop calls completed callback!!! \ No newline at end of file From 097c1fee7b535502e7b40360bc20d9a158782ddd Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 8 Apr 2024 18:19:38 +0000 Subject: [PATCH 022/138] negative speed fix negative speed states wouldn't play the animation if it didn't have transition duration or exit time. this PR fixes it by taking into account the speed multiplier when evaluating if the animation still has frames to play. Diffs= 0bc446fad negative speed fix (#6982) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/animation/linear_animation_instance.hpp | 7 +++++++ src/animation/linear_animation_instance.cpp | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 29283048..ed40a47c 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f832e26172cfbd11d52114ebb667e13418a5b1cd +0bc446fad2a568a7088fdaa122af0de2de1dc940 diff --git a/include/rive/animation/linear_animation_instance.hpp b/include/rive/animation/linear_animation_instance.hpp index a7cb9f6f..4919bd7f 100644 --- a/include/rive/animation/linear_animation_instance.hpp +++ b/include/rive/animation/linear_animation_instance.hpp @@ -69,6 +69,13 @@ class LinearAnimationInstance : public Scene (directedSpeed() < 0 && m_time > m_animation->startSeconds()); } + bool keepGoing(float speedMultiplier) const + { + return this->loopValue() != static_cast(rive::Loop::oneShot) || + (directedSpeed() * speedMultiplier > 0 && m_time < m_animation->endSeconds()) || + (directedSpeed() * speedMultiplier < 0 && m_time > m_animation->startSeconds()); + } + float totalTime() const { return m_totalTime; } float lastTotalTime() const { return m_lastTotalTime; } float spilledTime() const { return m_spilledTime; } diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp index 7e132d46..ff7fe55a 100644 --- a/src/animation/linear_animation_instance.cpp +++ b/src/animation/linear_animation_instance.cpp @@ -58,7 +58,7 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte // NOTE: // do not track spilled time, if our one shot loop is already completed. // stop gap before we move spilled tracking into state machine logic. - bool killSpilledTime = !this->keepGoing(); + bool killSpilledTime = !this->keepGoing(elapsedSeconds); float lastTime = m_time; m_time += deltaSeconds; @@ -165,7 +165,7 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte } m_didLoop = didLoop; - return this->keepGoing(); + return this->keepGoing(elapsedSeconds); } void LinearAnimationInstance::time(float value) From 195548a36f496c140d3d88681d76078413206045 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 9 Apr 2024 19:20:25 +0000 Subject: [PATCH 023/138] Fixing audio runtimes. Race condition when completing in the audio completed callback thread! Want to add a test here but ran out of time! Diffs= 8ecc99130 Fixing audio runtimes. (#7007) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- .../rive/animation/state_machine_instance.hpp | 3 ++- include/rive/audio/audio_engine.hpp | 4 ++++ include/rive/audio_event.hpp | 1 + .../core/field_types/core_callback_type.hpp | 1 + include/rive/relative_local_asset_loader.hpp | 5 ++++ src/animation/state_machine_instance.cpp | 12 +++++++++- src/audio/audio_engine.cpp | 24 ++++++++++++------- src/audio_event.cpp | 14 ++++++++--- 9 files changed, 51 insertions(+), 15 deletions(-) diff --git a/.rive_head b/.rive_head index ed40a47c..406e3a5e 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -0bc446fad2a568a7088fdaa122af0de2de1dc940 +8ecc99130db737d49ce0889501c421bd53b58f9e diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 67369e69..98a56935 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -51,7 +51,7 @@ class StateMachineInstance : public Scene template InstType* getNamedInput(const std::string& name) const; - void notifyEventListeners(std::vector events, NestedArtboard* source); + void notifyEventListeners(const std::vector& events, NestedArtboard* source); void sortHitComponents(); public: @@ -120,6 +120,7 @@ class StateMachineInstance : public Scene /// Gets a reported event at an index < reportedEventCount(). const EventReport reportedEventAt(std::size_t index) const; + bool playsAudio() override { return true; } private: std::vector m_reportedEvents; diff --git a/include/rive/audio/audio_engine.hpp b/include/rive/audio/audio_engine.hpp index e23f5393..a49f6693 100644 --- a/include/rive/audio/audio_engine.hpp +++ b/include/rive/audio/audio_engine.hpp @@ -7,6 +7,7 @@ #include #include #include +#include typedef struct ma_engine ma_engine; typedef struct ma_sound ma_sound; @@ -60,6 +61,9 @@ class AudioEngine : public RefCnt AudioEngine(ma_engine* engine); ma_device* m_device; ma_engine* m_engine; + std::mutex m_mutex; + + void soundCompleted(rcp sound); std::vector> m_completedSounds; rcp m_playingSoundsHead; diff --git a/include/rive/audio_event.hpp b/include/rive/audio_event.hpp index cd67c6c5..2844e9c6 100644 --- a/include/rive/audio_event.hpp +++ b/include/rive/audio_event.hpp @@ -13,6 +13,7 @@ class AudioEvent : public AudioEventBase, public FileAssetReferencer void setAsset(FileAsset* asset) override; uint32_t assetId() override; void trigger(const CallbackData& value) override; + void play(); #ifdef TESTING AudioAsset* asset() const { return (AudioAsset*)m_fileAsset; } diff --git a/include/rive/core/field_types/core_callback_type.hpp b/include/rive/core/field_types/core_callback_type.hpp index 1c8ba627..a6bb93f4 100644 --- a/include/rive/core/field_types/core_callback_type.hpp +++ b/include/rive/core/field_types/core_callback_type.hpp @@ -9,6 +9,7 @@ class CallbackContext public: virtual ~CallbackContext() {} virtual void reportEvent(Event* event, float secondsDelay = 0.0f) {} + virtual bool playsAudio() { return false; } }; class CallbackData diff --git a/include/rive/relative_local_asset_loader.hpp b/include/rive/relative_local_asset_loader.hpp index 6056c9c9..c4dc317a 100644 --- a/include/rive/relative_local_asset_loader.hpp +++ b/include/rive/relative_local_asset_loader.hpp @@ -36,6 +36,11 @@ class RelativeLocalAssetLoader : public FileAssetLoader { std::string filename = m_Path + asset.uniqueFilename(); FILE* fp = fopen(filename.c_str(), "rb"); + if (fp == nullptr) + { + fprintf(stderr, "Failed to find file at %s\n", filename.c_str()); + return false; + } fseek(fp, 0, SEEK_END); const size_t length = ftell(fp); diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 0348c6e9..b75642a8 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -24,6 +24,7 @@ #include "rive/nested_artboard.hpp" #include "rive/shapes/shape.hpp" #include "rive/math/math_types.hpp" +#include "rive/audio_event.hpp" #include using namespace rive; @@ -782,7 +783,7 @@ const EventReport StateMachineInstance::reportedEventAt(std::size_t index) const return m_reportedEvents[index]; } -void StateMachineInstance::notifyEventListeners(std::vector events, +void StateMachineInstance::notifyEventListeners(const std::vector& events, NestedArtboard* source) { if (events.size() > 0) @@ -826,5 +827,14 @@ void StateMachineInstance::notifyEventListeners(std::vector events, { m_parentStateMachineInstance->notifyEventListeners(events, m_parentNestedArtboard); } + + for (auto report : events) + { + auto event = report.event(); + if (event->is()) + { + event->as()->play(); + } + } } } diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index 268e22e8..c63bb693 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -25,9 +25,17 @@ using namespace rive; void AudioEngine::SoundCompleted(void* pUserData, ma_sound* pSound) { AudioSound* audioSound = (AudioSound*)pUserData; + auto engine = audioSound->m_engine; + engine->soundCompleted(ref_rcp(audioSound)); +} - auto next = audioSound->m_nextPlaying; - auto prev = audioSound->m_prevPlaying; +void AudioEngine::soundCompleted(rcp sound) +{ + std::unique_lock lock(m_mutex); + m_completedSounds.push_back(sound); + + auto next = sound->m_nextPlaying; + auto prev = sound->m_prevPlaying; if (next != nullptr) { next->m_prevPlaying = prev; @@ -37,16 +45,13 @@ void AudioEngine::SoundCompleted(void* pUserData, ma_sound* pSound) prev->m_nextPlaying = next; } - auto engine = audioSound->m_engine; - if (engine->m_playingSoundsHead.get() == audioSound) + if (m_playingSoundsHead == sound) { - engine->m_playingSoundsHead = next; + m_playingSoundsHead = next; } - // Unlink audio sound. - engine->m_completedSounds.push_back(ref_rcp(audioSound)); - audioSound->m_nextPlaying = nullptr; - audioSound->m_prevPlaying = nullptr; + sound->m_nextPlaying = nullptr; + sound->m_prevPlaying = nullptr; } #ifdef WITH_RIVE_AUDIO_TOOLS @@ -182,6 +187,7 @@ rcp AudioEngine::play(rcp source, uint64_t endTime, uint64_t soundStartTime) { + std::unique_lock lock(m_mutex); // We have to dispose completed sounds out of the completed callback. So we // do it on next play or at destruct. for (auto sound : m_completedSounds) diff --git a/src/audio_event.cpp b/src/audio_event.cpp index 1ba130b3..d0d8098e 100644 --- a/src/audio_event.cpp +++ b/src/audio_event.cpp @@ -6,10 +6,8 @@ using namespace rive; -void AudioEvent::trigger(const CallbackData& value) +void AudioEvent::play() { - Super::trigger(value); - #ifdef WITH_RIVE_AUDIO auto audioAsset = (AudioAsset*)m_fileAsset; if (audioAsset == nullptr) @@ -36,6 +34,16 @@ void AudioEvent::trigger(const CallbackData& value) #endif } +void AudioEvent::trigger(const CallbackData& value) +{ + Super::trigger(value); + if (!value.context()->playsAudio()) + { + // Context won't play audio, we'll do it ourselves. + play(); + } +} + StatusCode AudioEvent::import(ImportStack& importStack) { auto result = registerReferencer(importStack); From 70dfed9a18f0fd000088eba8e60a209b6c0bebbb Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Wed, 10 Apr 2024 20:08:33 +0000 Subject: [PATCH 024/138] Exposing artboard volume Adds ```artboard->volume(0.9f);``` to C++ and artboard.volume getter/setter to JS! Needs to be exposed to the high level TS runtime so it can then be used by React for our community. Diffs= cb2ea5b2d Exposing artboard volume (#7022) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/artboard.hpp | 5 +++++ src/artboard.cpp | 3 +++ src/audio_event.cpp | 11 +++++++++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 406e3a5e..8d2c3c46 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8ecc99130db737d49ce0889501c421bd53b58f9e +cb2ea5b2d31eb6888a96cb25524392087bdf47c7 diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 8338a6d9..2365af92 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -260,10 +260,15 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta StatusCode import(ImportStack& importStack) override; + float volume() const; + void volume(float value); + #ifdef EXTERNAL_RIVE_AUDIO_ENGINE rcp audioEngine() const; void audioEngine(rcp audioEngine); #endif +private: + float m_volume = 1.0f; }; class ArtboardInstance : public Artboard diff --git a/src/artboard.cpp b/src/artboard.cpp index b386bf77..6021a076 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -796,6 +796,9 @@ StatusCode Artboard::import(ImportStack& importStack) return result; } +float Artboard::volume() const { return m_volume; } +void Artboard::volume(float value) { m_volume = value; } + ////////// ArtboardInstance #include "rive/animation/linear_animation_instance.hpp" diff --git a/src/audio_event.cpp b/src/audio_event.cpp index d0d8098e..9a9e043e 100644 --- a/src/audio_event.cpp +++ b/src/audio_event.cpp @@ -20,6 +20,12 @@ void AudioEvent::play() return; } + auto volume = audioAsset->volume() * artboard()->volume(); + if (volume <= 0.0f) + { + return; + } + auto engine = #ifdef EXTERNAL_RIVE_AUDIO_ENGINE artboard()->audioEngine() != nullptr ? artboard()->audioEngine() : @@ -27,9 +33,10 @@ void AudioEvent::play() AudioEngine::RuntimeEngine(); auto sound = engine->play(audioSource, engine->timeInFrames(), 0, 0); - if (audioAsset->volume() != 1.0f) + + if (volume != 1.0f) { - sound->volume(audioAsset->volume()); + sound->volume(volume); } #endif } From ae49ac70d0a7c5d2aa58aab6c1ef976b3bcc1f68 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 16 Apr 2024 21:25:33 +0000 Subject: [PATCH 025/138] Stop audio in iOS when backgrounded. - Fixes a crash when a sound is still playing and Artboard is de-allocated. Easy to cause with long sounds as sound resources would get nuked and the engine would keep trying to decode from a dead buffer. - Stops audio when going in background, resumes when coming to foreground. The way I did the backgrounding is on the RiveRendererView as I couldn't find a better general spot to do this but maybe @mjtalbot has an idea. This does not stop long sounds (like songs) when exiting a view, we can address that separately... Diffs= 4a9947630 Stop audio in iOS when backgrounded. (#7055) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/assets/audio_asset.hpp | 2 + include/rive/audio/audio_engine.hpp | 14 +++++- include/rive/audio/audio_sound.hpp | 6 ++- src/artboard.cpp | 13 ++++++ src/audio/audio_engine.cpp | 67 +++++++++++++++++++++++++---- src/audio/audio_sound.cpp | 10 ++++- src/audio_event.cpp | 2 +- test/audio_test.cpp | 38 ++++++++++++++++ 9 files changed, 138 insertions(+), 16 deletions(-) diff --git a/.rive_head b/.rive_head index 8d2c3c46..35589d3d 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -cb2ea5b2d31eb6888a96cb25524392087bdf47c7 +4a9947630d3848ff70813cf5e2d8718adb9a1b90 diff --git a/include/rive/assets/audio_asset.hpp b/include/rive/assets/audio_asset.hpp index 4e00ce54..c4f042fe 100644 --- a/include/rive/assets/audio_asset.hpp +++ b/include/rive/assets/audio_asset.hpp @@ -2,6 +2,7 @@ #define _RIVE_AUDIO_ASSET_HPP_ #include "rive/generated/assets/audio_asset_base.hpp" #include "rive/audio/audio_source.hpp" +#include "rive/audio/audio_engine.hpp" namespace rive { @@ -20,6 +21,7 @@ class AudioAsset : public AudioAssetBase rcp audioSource() { return m_audioSource; } void audioSource(rcp source) { m_audioSource = source; } + void stop(rcp engine); private: rcp m_audioSource; diff --git a/include/rive/audio/audio_engine.hpp b/include/rive/audio/audio_engine.hpp index a49f6693..8bdf33c4 100644 --- a/include/rive/audio/audio_engine.hpp +++ b/include/rive/audio/audio_engine.hpp @@ -19,6 +19,7 @@ namespace rive class AudioSound; class AudioSource; class LevelsNode; +class Artboard; class AudioEngine : public RefCnt { friend class AudioSound; @@ -42,9 +43,10 @@ class AudioEngine : public RefCnt rcp play(rcp source, uint64_t startTime, uint64_t endTime, - uint64_t soundStartTime); + uint64_t soundStartTime, + Artboard* artboard = nullptr); - static rcp RuntimeEngine(); + static rcp RuntimeEngine(bool makeWhenNecessary = true); #ifdef EXTERNAL_RIVE_AUDIO_ENGINE bool readAudioFrames(float* frames, uint64_t numFrames, uint64_t* framesRead = nullptr); @@ -57,6 +59,13 @@ class AudioEngine : public RefCnt float level(uint32_t channel); #endif + void start(); + void stop(); + void stop(Artboard* artboard); + +#ifdef TESTING + size_t playingSoundCount(); +#endif private: AudioEngine(ma_engine* engine); ma_device* m_device; @@ -64,6 +73,7 @@ class AudioEngine : public RefCnt std::mutex m_mutex; void soundCompleted(rcp sound); + void unlinkSound(rcp sound); std::vector> m_completedSounds; rcp m_playingSoundsHead; diff --git a/include/rive/audio/audio_sound.hpp b/include/rive/audio/audio_sound.hpp index 783183ca..5d34ca43 100644 --- a/include/rive/audio/audio_sound.hpp +++ b/include/rive/audio/audio_sound.hpp @@ -4,10 +4,12 @@ #include "miniaudio.h" #include "rive/refcnt.hpp" +#include "rive/audio/audio_source.hpp" namespace rive { class AudioEngine; +class Artboard; class AudioSound : public RefCnt { friend class AudioEngine; @@ -21,7 +23,7 @@ class AudioSound : public RefCnt bool completed() const; private: - AudioSound(AudioEngine* engine); + AudioSound(AudioEngine* engine, rcp source, Artboard* artboard); ma_decoder* decoder() { return &m_decoder; } ma_audio_buffer* buffer() { return &m_buffer; } ma_sound* sound() { return &m_sound; } @@ -30,12 +32,14 @@ class AudioSound : public RefCnt ma_decoder m_decoder; ma_audio_buffer m_buffer; ma_sound m_sound; + rcp m_source; // This is storage used by the AudioEngine. bool m_isDisposed; rcp m_nextPlaying; rcp m_prevPlaying; AudioEngine* m_engine; + Artboard* m_artboard; }; } // namespace rive diff --git a/src/artboard.cpp b/src/artboard.cpp index 6021a076..074e0cdc 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -18,6 +18,7 @@ #include "rive/shapes/shape.hpp" #include "rive/text/text_value_run.hpp" #include "rive/event.hpp" +#include "rive/assets/audio_asset.hpp" #include @@ -25,6 +26,18 @@ using namespace rive; Artboard::~Artboard() { +#ifdef WITH_RIVE_AUDIO +#ifdef EXTERNAL_RIVE_AUDIO_ENGINE + auto audioEngine = m_audioEngine; +#else + auto audioEngine = AudioEngine::RuntimeEngine(false); +#endif + if (audioEngine) + { + audioEngine->stop(this); + } +#endif + for (auto object : m_Objects) { // First object is artboard diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index c63bb693..076733d7 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -29,11 +29,8 @@ void AudioEngine::SoundCompleted(void* pUserData, ma_sound* pSound) engine->soundCompleted(ref_rcp(audioSound)); } -void AudioEngine::soundCompleted(rcp sound) +void AudioEngine::unlinkSound(rcp sound) { - std::unique_lock lock(m_mutex); - m_completedSounds.push_back(sound); - auto next = sound->m_nextPlaying; auto prev = sound->m_prevPlaying; if (next != nullptr) @@ -54,6 +51,13 @@ void AudioEngine::soundCompleted(rcp sound) sound->m_prevPlaying = nullptr; } +void AudioEngine::soundCompleted(rcp sound) +{ + std::unique_lock lock(m_mutex); + m_completedSounds.push_back(sound); + unlinkSound(sound); +} + #ifdef WITH_RIVE_AUDIO_TOOLS namespace rive { @@ -153,6 +157,9 @@ float AudioEngine::level(uint32_t channel) } #endif +void AudioEngine::start() { ma_engine_start(m_engine); } +void AudioEngine::stop() { ma_engine_stop(m_engine); } + rcp AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate) { ma_engine_config engineConfig = ma_engine_config_init(); @@ -185,7 +192,8 @@ AudioEngine::AudioEngine(ma_engine* engine) : rcp AudioEngine::play(rcp source, uint64_t startTime, uint64_t endTime, - uint64_t soundStartTime) + uint64_t soundStartTime, + Artboard* artboard) { std::unique_lock lock(m_mutex); // We have to dispose completed sounds out of the completed callback. So we @@ -196,7 +204,7 @@ rcp AudioEngine::play(rcp source, } m_completedSounds.clear(); - rcp audioSound = rcp(new AudioSound(this)); + rcp audioSound = rcp(new AudioSound(this, source, artboard)); if (source->isBuffered()) { rive::Span samples = source->bufferedSamples(); @@ -279,6 +287,39 @@ rcp AudioEngine::play(rcp source, return audioSound; } +#ifdef TESTING +size_t AudioEngine::playingSoundCount() +{ + std::unique_lock lock(m_mutex); + size_t count = 0; + auto sound = m_playingSoundsHead; + while (sound != nullptr) + { + count++; + sound = sound->m_nextPlaying; + } + + return count; +} +#endif + +void AudioEngine::stop(Artboard* artboard) +{ + std::unique_lock lock(m_mutex); + auto sound = m_playingSoundsHead; + while (sound != nullptr) + { + auto next = sound->m_nextPlaying; + if (sound->m_artboard == artboard) + { + sound->stop(); + m_completedSounds.push_back(sound); + unlinkSound(sound); + } + sound = next; + } +} + AudioEngine::~AudioEngine() { auto sound = m_playingSoundsHead; @@ -316,10 +357,18 @@ uint64_t AudioEngine::timeInFrames() return (uint64_t)ma_engine_get_time_in_pcm_frames(m_engine); } -rcp AudioEngine::RuntimeEngine() +static rcp m_runtimeAudioEngine; +rcp AudioEngine::RuntimeEngine(bool makeWhenNecessary) { - static rcp engine = AudioEngine::Make(defaultNumChannels, defaultSampleRate); - return engine; + if (!makeWhenNecessary) + { + return m_runtimeAudioEngine; + } + else if (m_runtimeAudioEngine == nullptr) + { + m_runtimeAudioEngine = AudioEngine::Make(defaultNumChannels, defaultSampleRate); + } + return m_runtimeAudioEngine; } #ifdef EXTERNAL_RIVE_AUDIO_ENGINE diff --git a/src/audio/audio_sound.cpp b/src/audio/audio_sound.cpp index e355aadf..6bc227d9 100644 --- a/src/audio/audio_sound.cpp +++ b/src/audio/audio_sound.cpp @@ -6,8 +6,14 @@ using namespace rive; -AudioSound::AudioSound(AudioEngine* engine) : - m_decoder({}), m_buffer({}), m_sound({}), m_isDisposed(false), m_engine(engine) +AudioSound::AudioSound(AudioEngine* engine, rcp source, Artboard* artboard) : + m_decoder({}), + m_buffer({}), + m_sound({}), + m_source(std::move(source)), + m_isDisposed(false), + m_engine(engine), + m_artboard(artboard) {} void AudioSound::dispose() diff --git a/src/audio_event.cpp b/src/audio_event.cpp index 9a9e043e..53c98123 100644 --- a/src/audio_event.cpp +++ b/src/audio_event.cpp @@ -32,7 +32,7 @@ void AudioEvent::play() #endif AudioEngine::RuntimeEngine(); - auto sound = engine->play(audioSource, engine->timeInFrames(), 0, 0); + auto sound = engine->play(audioSource, engine->timeInFrames(), 0, 0, artboard()); if (volume != 1.0f) { diff --git a/test/audio_test.cpp b/test/audio_test.cpp index 06ffa307..c96e4e0d 100644 --- a/test/audio_test.cpp +++ b/test/audio_test.cpp @@ -147,4 +147,42 @@ TEST_CASE("many audio sounds can outlive engine", "[audio]") } } +TEST_CASE("audio sounds from different artboards stop accordingly", "[audio]") +{ + rcp engine = AudioEngine::Make(2, 44100); + + auto file = ReadRiveFile("../../test/assets/sound.riv"); + auto artboard = file->artboardDefault(); + artboard->audioEngine(engine); + auto artboard2 = file->artboardDefault(); + artboard2->audioEngine(engine); + + REQUIRE(artboard != nullptr); + + auto audioEvents = artboard->find(); + REQUIRE(audioEvents.size() == 1); + + auto audioEvent = audioEvents[0]; + REQUIRE(audioEvent->asset() != nullptr); + REQUIRE(audioEvent->asset()->hasAudioSource()); + + audioEvent->play(); + audioEvent->play(); + REQUIRE(engine->playingSoundCount() == 2); + auto audioEvent2 = artboard2->find()[0]; + audioEvent2->play(); + REQUIRE(engine->playingSoundCount() == 3); + audioEvent->play(); + REQUIRE(engine->playingSoundCount() == 4); + + // The three playing sounds owned by the first artboard should now stop. + artboard = nullptr; + + REQUIRE(engine->playingSoundCount() == 1); + + // The last one belonging to artboard2 should now stop too. + artboard2 = nullptr; + REQUIRE(engine->playingSoundCount() == 0); +} + // TODO check if sound->stop calls completed callback!!! \ No newline at end of file From f8e84011cd77c47ef2affa2347a6af60315f4d68 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Wed, 17 Apr 2024 20:45:52 +0000 Subject: [PATCH 026/138] propagate volume to nested artboards propagate volume to nested artboards Diffs= 2828b7b01 propagate volume to nested artboards (#7067) Co-authored-by: hernan --- .rive_head | 2 +- src/artboard.cpp | 13 ++++++++++++- src/nested_artboard.cpp | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 35589d3d..929a5513 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -4a9947630d3848ff70813cf5e2d8718adb9a1b90 +2828b7b013811f1f4b0b0e2ee0f6d9b23c73878b diff --git a/src/artboard.cpp b/src/artboard.cpp index 074e0cdc..0b4778d4 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -810,7 +810,18 @@ StatusCode Artboard::import(ImportStack& importStack) } float Artboard::volume() const { return m_volume; } -void Artboard::volume(float value) { m_volume = value; } +void Artboard::volume(float value) +{ + m_volume = value; + for (auto nestedArtboard : m_NestedArtboards) + { + auto artboard = nestedArtboard->artboard(); + if (artboard != nullptr) + { + artboard->volume(value); + } + } +} ////////// ArtboardInstance diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 8b80df48..18ff0981 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -38,6 +38,7 @@ void NestedArtboard::nest(Artboard* artboard) } m_Artboard->frameOrigin(false); m_Artboard->opacity(renderOpacity()); + m_Artboard->volume(artboard->volume()); m_Instance = nullptr; if (artboard->isInstance()) { From 5e69b3d768a803e8fbad7b240716bcc5c39519a4 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 19 Apr 2024 21:46:42 +0000 Subject: [PATCH 027/138] support randomizing transitions First version of randomization to get in UAT for validation. Diffs= edac19b06 support randomizing transitions (#7082) Co-authored-by: hernan --- .rive_head | 2 +- dev/defs/animation/layer_state.json | 8 ++ dev/defs/animation/state_transition.json | 9 ++ include/rive/animation/layer_state_flags.hpp | 24 ++++ .../rive/animation/state_machine_instance.hpp | 2 + include/rive/animation/state_transition.hpp | 4 + .../generated/animation/layer_state_base.hpp | 36 +++++ .../animation/state_transition_base.hpp | 18 +++ include/rive/generated/core_registry.hpp | 12 ++ src/animation/state_machine_instance.cpp | 134 ++++++++++++------ 10 files changed, 201 insertions(+), 48 deletions(-) create mode 100644 include/rive/animation/layer_state_flags.hpp diff --git a/.rive_head b/.rive_head index 929a5513..58930e30 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -2828b7b013811f1f4b0b0e2ee0f6d9b23c73878b +edac19b0600a1ede64bb0b07e61556013a3e84fe diff --git a/dev/defs/animation/layer_state.json b/dev/defs/animation/layer_state.json index ce57d57b..b15b793b 100644 --- a/dev/defs/animation/layer_state.json +++ b/dev/defs/animation/layer_state.json @@ -34,6 +34,14 @@ "string": "y" }, "runtime": false + }, + "flags": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 536, + "string": "flags" + } } } } \ No newline at end of file diff --git a/dev/defs/animation/state_transition.json b/dev/defs/animation/state_transition.json index 072d10e0..3ac429eb 100644 --- a/dev/defs/animation/state_transition.json +++ b/dev/defs/animation/state_transition.json @@ -82,6 +82,15 @@ "string": "interpolatorid" }, "description": "The id of the custom interpolator used when interpolation is Cubic." + }, + "randomWeight": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 537, + "string": "randomweight" + }, + "description": "Weight of the transition in the overall random options" } } } \ No newline at end of file diff --git a/include/rive/animation/layer_state_flags.hpp b/include/rive/animation/layer_state_flags.hpp new file mode 100644 index 00000000..880bd35a --- /dev/null +++ b/include/rive/animation/layer_state_flags.hpp @@ -0,0 +1,24 @@ +#ifndef _RIVE_LAYER_STATE_FLAGS_HPP_ +#define _RIVE_LAYER_STATE_FLAGS_HPP_ + +#include + +namespace rive +{ +enum class LayerStateFlags : unsigned char +{ + None = 0, + + /// Whether the transition is disabled. + Random = 1 << 0, + +}; + +inline constexpr LayerStateFlags operator&(LayerStateFlags lhs, LayerStateFlags rhs) +{ + return static_cast( + static_cast::type>(lhs) & + static_cast::type>(rhs)); +} +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 98a56935..1232b113 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -43,6 +43,7 @@ class StateMachineInstance : public Scene friend class SMIInput; friend class KeyedProperty; friend class HitComponent; + friend class StateMachineLayerInstance; private: /// Provide a hitListener if you want to process a down or an up for the pointer position @@ -53,6 +54,7 @@ class StateMachineInstance : public Scene InstType* getNamedInput(const std::string& name) const; void notifyEventListeners(const std::vector& events, NestedArtboard* source); void sortHitComponents(); + double randomValue(); public: StateMachineInstance(const StateMachine* machine, ArtboardInstance* instance); diff --git a/include/rive/animation/state_transition.hpp b/include/rive/animation/state_transition.hpp index 412ac065..c021c2c5 100644 --- a/include/rive/animation/state_transition.hpp +++ b/include/rive/animation/state_transition.hpp @@ -35,6 +35,7 @@ class StateTransition : public StateTransitionBase return static_cast(flags()); } LayerState* m_StateTo = nullptr; + uint32_t m_EvaluatedRandomWeight = 1; CubicInterpolator* m_Interpolator = nullptr; std::vector m_Conditions; @@ -45,6 +46,9 @@ class StateTransition : public StateTransitionBase const LayerState* stateTo() const { return m_StateTo; } inline CubicInterpolator* interpolator() const { return m_Interpolator; } + inline uint32_t evaluatedRandomWeight() const { return m_EvaluatedRandomWeight; } + void evaluatedRandomWeight(uint32_t value) { m_EvaluatedRandomWeight = value; } + StatusCode onAddedDirty(CoreContext* context) override; StatusCode onAddedClean(CoreContext* context) override; diff --git a/include/rive/generated/animation/layer_state_base.hpp b/include/rive/generated/animation/layer_state_base.hpp index a14df6c0..f5611383 100644 --- a/include/rive/generated/animation/layer_state_base.hpp +++ b/include/rive/generated/animation/layer_state_base.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_LAYER_STATE_BASE_HPP_ #define _RIVE_LAYER_STATE_BASE_HPP_ #include "rive/animation/state_machine_layer_component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" namespace rive { class LayerStateBase : public StateMachineLayerComponent @@ -27,7 +28,42 @@ class LayerStateBase : public StateMachineLayerComponent uint16_t coreType() const override { return typeKey; } + static const uint16_t flagsPropertyKey = 535; + +private: + uint32_t m_Flags = 0; + +public: + inline uint32_t flags() const { return m_Flags; } + void flags(uint32_t value) + { + if (m_Flags == value) + { + return; + } + m_Flags = value; + flagsChanged(); + } + + void copy(const LayerStateBase& object) + { + m_Flags = object.m_Flags; + StateMachineLayerComponent::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case flagsPropertyKey: + m_Flags = CoreUintType::deserialize(reader); + return true; + } + return StateMachineLayerComponent::deserialize(propertyKey, reader); + } + protected: + virtual void flagsChanged() {} }; } // namespace rive diff --git a/include/rive/generated/animation/state_transition_base.hpp b/include/rive/generated/animation/state_transition_base.hpp index 9b526ac0..2deeb09e 100644 --- a/include/rive/generated/animation/state_transition_base.hpp +++ b/include/rive/generated/animation/state_transition_base.hpp @@ -34,6 +34,7 @@ class StateTransitionBase : public StateMachineLayerComponent static const uint16_t exitTimePropertyKey = 160; static const uint16_t interpolationTypePropertyKey = 349; static const uint16_t interpolatorIdPropertyKey = 350; + static const uint16_t randomWeightPropertyKey = 536; private: uint32_t m_StateToId = -1; @@ -42,6 +43,7 @@ class StateTransitionBase : public StateMachineLayerComponent uint32_t m_ExitTime = 0; uint32_t m_InterpolationType = 1; uint32_t m_InterpolatorId = -1; + uint32_t m_RandomWeight = 1; public: inline uint32_t stateToId() const { return m_StateToId; } @@ -110,6 +112,17 @@ class StateTransitionBase : public StateMachineLayerComponent interpolatorIdChanged(); } + inline uint32_t randomWeight() const { return m_RandomWeight; } + void randomWeight(uint32_t value) + { + if (m_RandomWeight == value) + { + return; + } + m_RandomWeight = value; + randomWeightChanged(); + } + Core* clone() const override; void copy(const StateTransitionBase& object) { @@ -119,6 +132,7 @@ class StateTransitionBase : public StateMachineLayerComponent m_ExitTime = object.m_ExitTime; m_InterpolationType = object.m_InterpolationType; m_InterpolatorId = object.m_InterpolatorId; + m_RandomWeight = object.m_RandomWeight; StateMachineLayerComponent::copy(object); } @@ -144,6 +158,9 @@ class StateTransitionBase : public StateMachineLayerComponent case interpolatorIdPropertyKey: m_InterpolatorId = CoreUintType::deserialize(reader); return true; + case randomWeightPropertyKey: + m_RandomWeight = CoreUintType::deserialize(reader); + return true; } return StateMachineLayerComponent::deserialize(propertyKey, reader); } @@ -155,6 +172,7 @@ class StateTransitionBase : public StateMachineLayerComponent virtual void exitTimeChanged() {} virtual void interpolationTypeChanged() {} virtual void interpolatorIdChanged() {} + virtual void randomWeightChanged() {} }; } // namespace rive diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index a911f8cf..0b077aaa 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -460,6 +460,9 @@ class CoreRegistry case ListenerFireEventBase::eventIdPropertyKey: object->as()->eventId(value); break; + case LayerStateBase::flagsPropertyKey: + object->as()->flags(value); + break; case ListenerInputChangeBase::inputIdPropertyKey: object->as()->inputId(value); break; @@ -538,6 +541,9 @@ class CoreRegistry case StateTransitionBase::interpolatorIdPropertyKey: object->as()->interpolatorId(value); break; + case StateTransitionBase::randomWeightPropertyKey: + object->as()->randomWeight(value); + break; case StateMachineFireEventBase::eventIdPropertyKey: object->as()->eventId(value); break; @@ -1256,6 +1262,8 @@ class CoreRegistry return object->as()->activeComponentId(); case ListenerFireEventBase::eventIdPropertyKey: return object->as()->eventId(); + case LayerStateBase::flagsPropertyKey: + return object->as()->flags(); case ListenerInputChangeBase::inputIdPropertyKey: return object->as()->inputId(); case ListenerInputChangeBase::nestedInputIdPropertyKey: @@ -1308,6 +1316,8 @@ class CoreRegistry return object->as()->interpolationType(); case StateTransitionBase::interpolatorIdPropertyKey: return object->as()->interpolatorId(); + case StateTransitionBase::randomWeightPropertyKey: + return object->as()->randomWeight(); case StateMachineFireEventBase::eventIdPropertyKey: return object->as()->eventId(); case StateMachineFireEventBase::occursValuePropertyKey: @@ -1779,6 +1789,7 @@ class CoreRegistry case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: case ListenerFireEventBase::eventIdPropertyKey: + case LayerStateBase::flagsPropertyKey: case ListenerInputChangeBase::inputIdPropertyKey: case ListenerInputChangeBase::nestedInputIdPropertyKey: case AnimationStateBase::animationIdPropertyKey: @@ -1805,6 +1816,7 @@ class CoreRegistry case StateTransitionBase::exitTimePropertyKey: case StateTransitionBase::interpolationTypePropertyKey: case StateTransitionBase::interpolatorIdPropertyKey: + case StateTransitionBase::randomWeightPropertyKey: case StateMachineFireEventBase::eventIdPropertyKey: case StateMachineFireEventBase::occursValuePropertyKey: case LinearAnimationBase::fpsPropertyKey: diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index b75642a8..3617c648 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -3,6 +3,7 @@ #include "rive/animation/any_state.hpp" #include "rive/animation/cubic_interpolator.hpp" #include "rive/animation/entry_state.hpp" +#include "rive/animation/layer_state_flags.hpp" #include "rive/animation/nested_state_machine.hpp" #include "rive/animation/state_instance.hpp" #include "rive/animation/state_machine_bool.hpp" @@ -140,6 +141,13 @@ class StateMachineLayerInstance } } + bool canChangeState(const LayerState* stateTo) + { + return !((m_currentState == nullptr ? nullptr : m_currentState->state()) == stateTo); + } + + double randomValue() { return ((double)rand() / (RAND_MAX)); } + bool changeState(const LayerState* stateTo) { if ((m_currentState == nullptr ? nullptr : m_currentState->state()) == stateTo) @@ -172,72 +180,104 @@ class StateMachineLayerInstance } auto stateFrom = stateFromInstance->state(); auto outState = m_currentState; + uint32_t totalWeight = 0; for (size_t i = 0, length = stateFrom->transitionCount(); i < length; i++) { auto transition = stateFrom->transition(i); auto allowed = transition->allowed(stateFromInstance, m_stateMachineInstance, ignoreTriggers); - if (allowed == AllowTransition::yes && changeState(transition->stateTo())) + if (allowed == AllowTransition::yes && canChangeState(transition->stateTo())) { - m_stateMachineChangedOnAdvance = true; - // state actually has changed - m_transition = transition; - fireEvents(StateMachineFireOccurance::atStart, transition->events()); - if (transition->duration() == 0) + transition->evaluatedRandomWeight(transition->randomWeight()); + totalWeight += transition->randomWeight(); + if ((static_cast(stateFromInstance->state()->flags()) & + LayerStateFlags::Random) != LayerStateFlags::Random) { - m_transitionCompleted = true; - fireEvents(StateMachineFireOccurance::atEnd, transition->events()); + break; } - else + } + else + { + transition->evaluatedRandomWeight(0); + if (allowed == AllowTransition::waitingForExit) { - m_transitionCompleted = false; + m_waitingForExit = true; } + } + } + if (totalWeight > 0) + { - if (m_stateFrom != m_anyStateInstance) + double randomWeight = randomValue() * totalWeight * 1.0; + float currentWeight = 0; + size_t index = 0; + StateTransition* transition; + while (index < stateFrom->transitionCount()) + { + transition = stateFrom->transition(index); + auto transitionWeight = transition->evaluatedRandomWeight(); + if (currentWeight + transitionWeight > randomWeight) { - // Old state from is done. - delete m_stateFrom; + break; } - m_stateFrom = outState; + currentWeight += transitionWeight; + index++; + } + changeState(transition->stateTo()); + m_stateMachineChangedOnAdvance = true; + // state actually has changed + m_transition = transition; + fireEvents(StateMachineFireOccurance::atStart, transition->events()); + if (transition->duration() == 0) + { + m_transitionCompleted = true; + fireEvents(StateMachineFireOccurance::atEnd, transition->events()); + } + else + { + m_transitionCompleted = false; + } - // If we had an exit time and wanted to pause on exit, make - // sure to hold the exit time. Delegate this to the - // transition by telling it that it was completed. - if (outState != nullptr && transition->applyExitCondition(outState)) - { - // Make sure we apply this state. This only returns true - // when it's an animation state instance. - auto instance = - static_cast(m_stateFrom)->animationInstance(); + if (m_stateFrom != m_anyStateInstance) + { + // Old state from is done. + delete m_stateFrom; + } + m_stateFrom = outState; - m_holdAnimation = instance->animation(); - m_holdTime = instance->time(); - } - m_mixFrom = m_mix; + // If we had an exit time and wanted to pause on exit, make + // sure to hold the exit time. Delegate this to the + // transition by telling it that it was completed. + if (outState != nullptr && transition->applyExitCondition(outState)) + { + // Make sure we apply this state. This only returns true + // when it's an animation state instance. + auto instance = + static_cast(m_stateFrom)->animationInstance(); - // Keep mixing last animation that was mixed in. - if (m_mix != 0.0f) - { - m_holdAnimationFrom = transition->pauseOnExit(); - } - if (m_stateFrom != nullptr && m_stateFrom->state()->is() && - m_currentState != nullptr) - { - auto instance = - static_cast(m_stateFrom)->animationInstance(); + m_holdAnimation = instance->animation(); + m_holdTime = instance->time(); + } + m_mixFrom = m_mix; - auto spilledTime = instance->spilledTime(); - m_currentState->advance(spilledTime, m_stateMachineInstance); - } - m_mix = 0.0f; - updateMix(0.0f); - m_waitingForExit = false; - return true; + // Keep mixing last animation that was mixed in. + if (m_mix != 0.0f) + { + m_holdAnimationFrom = transition->pauseOnExit(); } - else if (allowed == AllowTransition::waitingForExit) + if (m_stateFrom != nullptr && m_stateFrom->state()->is() && + m_currentState != nullptr) { - m_waitingForExit = true; + auto instance = + static_cast(m_stateFrom)->animationInstance(); + + auto spilledTime = instance->spilledTime(); + m_currentState->advance(spilledTime, m_stateMachineInstance); } + m_mix = 0.0f; + updateMix(0.0f); + m_waitingForExit = false; + return true; } return false; } @@ -837,4 +877,4 @@ void StateMachineInstance::notifyEventListeners(const std::vector& } } } -} +} \ No newline at end of file From 8a0f9271e9b7c46e33c147cd4af24a7ac0963c13 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 19 Apr 2024 22:30:23 +0000 Subject: [PATCH 028/138] Xxxx support random transitions update regenerated keys Diffs= a0004fa72 Xxxx support random transitions (#7094) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/generated/animation/layer_state_base.hpp | 2 +- include/rive/generated/animation/state_transition_base.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 58930e30..64395e4d 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -edac19b0600a1ede64bb0b07e61556013a3e84fe +a0004fa72b5b3c4f040b7807b186560703334dc4 diff --git a/include/rive/generated/animation/layer_state_base.hpp b/include/rive/generated/animation/layer_state_base.hpp index f5611383..3c4cfbe9 100644 --- a/include/rive/generated/animation/layer_state_base.hpp +++ b/include/rive/generated/animation/layer_state_base.hpp @@ -28,7 +28,7 @@ class LayerStateBase : public StateMachineLayerComponent uint16_t coreType() const override { return typeKey; } - static const uint16_t flagsPropertyKey = 535; + static const uint16_t flagsPropertyKey = 536; private: uint32_t m_Flags = 0; diff --git a/include/rive/generated/animation/state_transition_base.hpp b/include/rive/generated/animation/state_transition_base.hpp index 2deeb09e..7de3c369 100644 --- a/include/rive/generated/animation/state_transition_base.hpp +++ b/include/rive/generated/animation/state_transition_base.hpp @@ -34,7 +34,7 @@ class StateTransitionBase : public StateMachineLayerComponent static const uint16_t exitTimePropertyKey = 160; static const uint16_t interpolationTypePropertyKey = 349; static const uint16_t interpolatorIdPropertyKey = 350; - static const uint16_t randomWeightPropertyKey = 536; + static const uint16_t randomWeightPropertyKey = 537; private: uint32_t m_StateToId = -1; From 6fcc4fa7c936162a11c513aac192995c2a9a6d82 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Sat, 20 Apr 2024 00:43:05 +0000 Subject: [PATCH 029/138] Xxxx randomization updates part 2 Diffs= 99d28e1ac Xxxx randomization updates part 2 (#7097) Co-authored-by: Alex Gibson Co-authored-by: hernan --- .rive_head | 2 +- .../rive/animation/state_machine_instance.hpp | 4 ++ src/animation/state_machine_instance.cpp | 64 +++++++++++++++---- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/.rive_head b/.rive_head index 64395e4d..efc3ff2c 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a0004fa72b5b3c4f040b7807b186560703334dc4 +99d28e1ac65672076b08f3a044218ec60268c4ae diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 1232b113..4618a82f 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -5,6 +5,8 @@ #include #include #include "rive/animation/linear_animation_instance.hpp" +#include "rive/animation/state_instance.hpp" +#include "rive/animation/state_transition.hpp" #include "rive/core/field_types/core_callback_type.hpp" #include "rive/hit_result.hpp" #include "rive/listener_type.hpp" @@ -55,6 +57,8 @@ class StateMachineInstance : public Scene void notifyEventListeners(const std::vector& events, NestedArtboard* source); void sortHitComponents(); double randomValue(); + StateTransition* findRandomTransition(StateInstance* stateFromInstance, bool ignoreTriggers); + StateTransition* findAllowedTransition(StateInstance* stateFromInstance, bool ignoreTriggers); public: StateMachineInstance(const StateMachine* machine, ArtboardInstance* instance); diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 3617c648..9434dd45 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -172,15 +172,11 @@ class StateMachineLayerInstance return true; } - bool tryChangeState(StateInstance* stateFromInstance, bool ignoreTriggers) + StateTransition* findRandomTransition(StateInstance* stateFromInstance, bool ignoreTriggers) { - if (stateFromInstance == nullptr) - { - return false; - } - auto stateFrom = stateFromInstance->state(); - auto outState = m_currentState; uint32_t totalWeight = 0; + auto stateFrom = stateFromInstance->state(); + // printf("stateFrom->transitionCount(): %zu\n", stateFrom->transitionCount()); for (size_t i = 0, length = stateFrom->transitionCount(); i < length; i++) { auto transition = stateFrom->transition(i); @@ -190,11 +186,6 @@ class StateMachineLayerInstance { transition->evaluatedRandomWeight(transition->randomWeight()); totalWeight += transition->randomWeight(); - if ((static_cast(stateFromInstance->state()->flags()) & - LayerStateFlags::Random) != LayerStateFlags::Random) - { - break; - } } else { @@ -207,7 +198,6 @@ class StateMachineLayerInstance } if (totalWeight > 0) { - double randomWeight = randomValue() * totalWeight * 1.0; float currentWeight = 0; size_t index = 0; @@ -218,11 +208,57 @@ class StateMachineLayerInstance auto transitionWeight = transition->evaluatedRandomWeight(); if (currentWeight + transitionWeight > randomWeight) { - break; + return transition; } currentWeight += transitionWeight; index++; } + } + return nullptr; + } + + StateTransition* findAllowedTransition(StateInstance* stateFromInstance, bool ignoreTriggers) + { + auto stateFrom = stateFromInstance->state(); + // If it should randomize + if ((static_cast(stateFrom->flags()) & LayerStateFlags::Random) == + LayerStateFlags::Random) + { + return findRandomTransition(stateFromInstance, ignoreTriggers); + } + // Else search the first valid transition + for (size_t i = 0, length = stateFrom->transitionCount(); i < length; i++) + { + auto transition = stateFrom->transition(i); + auto allowed = + transition->allowed(stateFromInstance, m_stateMachineInstance, ignoreTriggers); + if (allowed == AllowTransition::yes && canChangeState(transition->stateTo())) + { + transition->evaluatedRandomWeight(transition->randomWeight()); + return transition; + } + else + { + transition->evaluatedRandomWeight(0); + if (allowed == AllowTransition::waitingForExit) + { + m_waitingForExit = true; + } + } + } + return nullptr; + } + + bool tryChangeState(StateInstance* stateFromInstance, bool ignoreTriggers) + { + if (stateFromInstance == nullptr) + { + return false; + } + auto outState = m_currentState; + auto transition = findAllowedTransition(stateFromInstance, ignoreTriggers); + if (transition != nullptr) + { changeState(transition->stateTo()); m_stateMachineChangedOnAdvance = true; // state actually has changed From 6276d83854045d0c26d65521037e82e3c01cf5e7 Mon Sep 17 00:00:00 2001 From: mjtalbot Date: Mon, 22 Apr 2024 13:31:59 +0000 Subject: [PATCH 030/138] add out of band audio support ios - abstracted audio! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow up to #7048! I nuked the custom defines and the miniaudio include. I think this fixes the need for miniaudio and the custom defines @mjtalbot! Give it a shot 🔫 Diffs= 89053041a add out of band audio support ios - abstracted audio! (#7079) Co-authored-by: Luigi Rosso Co-authored-by: Maxwell Talbot --- .rive_head | 2 +- cg_renderer/premake5.lua | 7 ------- include/rive/assets/audio_asset.hpp | 2 -- include/rive/assets/file_asset.hpp | 1 + include/rive/audio/audio_format.hpp | 2 -- include/rive/audio/audio_source.hpp | 24 ++++++++++++++++++++---- include/rive/factory.hpp | 3 +++ src/assets/file_asset.cpp | 12 +++++++----- src/audio/audio_source.cpp | 16 ++++++++++++++-- src/factory.cpp | 9 +++++++++ 10 files changed, 55 insertions(+), 23 deletions(-) diff --git a/.rive_head b/.rive_head index efc3ff2c..584b93d5 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -99d28e1ac65672076b08f3a044218ec60268c4ae +89053041aea1e6c8559afc4273c4e466e9ff547a diff --git a/cg_renderer/premake5.lua b/cg_renderer/premake5.lua index d54c7e52..a4a60627 100644 --- a/cg_renderer/premake5.lua +++ b/cg_renderer/premake5.lua @@ -43,11 +43,4 @@ do }) end end - - filter({ 'options:with_rive_text' }) - do - defines({ 'WITH_RIVE_TEXT' }) - end end - -newoption({ trigger = 'with_rive_text', description = 'Enables text experiments' }) diff --git a/include/rive/assets/audio_asset.hpp b/include/rive/assets/audio_asset.hpp index c4f042fe..bc8d89a5 100644 --- a/include/rive/assets/audio_asset.hpp +++ b/include/rive/assets/audio_asset.hpp @@ -14,7 +14,6 @@ class AudioAsset : public AudioAssetBase bool decode(SimpleArray&, Factory*) override; std::string fileExtension() const override; -#ifdef WITH_RIVE_AUDIO #ifdef TESTING bool hasAudioSource() { return m_audioSource != nullptr; } #endif @@ -25,7 +24,6 @@ class AudioAsset : public AudioAssetBase private: rcp m_audioSource; -#endif }; } // namespace rive diff --git a/include/rive/assets/file_asset.hpp b/include/rive/assets/file_asset.hpp index a8ed721e..22915f40 100644 --- a/include/rive/assets/file_asset.hpp +++ b/include/rive/assets/file_asset.hpp @@ -50,6 +50,7 @@ class FileAsset : public FileAssetBase } } + std::string uniqueName() const; std::string uniqueFilename() const; }; } // namespace rive diff --git a/include/rive/audio/audio_format.hpp b/include/rive/audio/audio_format.hpp index ab73fe54..330dffea 100644 --- a/include/rive/audio/audio_format.hpp +++ b/include/rive/audio/audio_format.hpp @@ -1,4 +1,3 @@ -#ifdef WITH_RIVE_AUDIO #ifndef _RIVE_AUDIO_FORMAT_HPP_ #define _RIVE_AUDIO_FORMAT_HPP_ namespace rive @@ -13,5 +12,4 @@ enum class AudioFormat : unsigned int buffered }; } -#endif #endif \ No newline at end of file diff --git a/include/rive/audio/audio_source.hpp b/include/rive/audio/audio_source.hpp index b38984b8..d6153a38 100644 --- a/include/rive/audio/audio_source.hpp +++ b/include/rive/audio/audio_source.hpp @@ -1,4 +1,3 @@ -#ifdef WITH_RIVE_AUDIO #ifndef _RIVE_AUDIO_SOURCE_HPP_ #define _RIVE_AUDIO_SOURCE_HPP_ @@ -26,24 +25,41 @@ class AudioSource : public RefCnt // the AudioSource deletes. AudioSource(rive::Span samples, uint32_t numChannels, uint32_t sampleRate); +#ifdef WITH_RIVE_AUDIO rcp makeReader(uint32_t numChannels, uint32_t sampleRate); +#endif uint32_t channels(); uint32_t sampleRate(); AudioFormat format() const; - const rive::Span bytes() const { return m_fileBytes; } + const rive::Span bytes() const + { +#ifdef WITH_RIVE_AUDIO + return m_fileBytes; +#else + return rive::Span(nullptr, 0); +#endif + } const rive::Span bufferedSamples() const; - bool isBuffered() const { return m_isBuffered; } + bool isBuffered() const + { +#ifdef WITH_RIVE_AUDIO + return m_isBuffered; +#else + return false; +#endif + } private: +#ifdef WITH_RIVE_AUDIO bool m_isBuffered; uint32_t m_channels; uint32_t m_sampleRate; rive::Span m_fileBytes; rive::SimpleArray m_ownedBytes; +#endif }; } // namespace rive -#endif #endif \ No newline at end of file diff --git a/include/rive/factory.hpp b/include/rive/factory.hpp index 1484c0fd..417d4efc 100644 --- a/include/rive/factory.hpp +++ b/include/rive/factory.hpp @@ -7,6 +7,7 @@ #include "rive/renderer.hpp" #include "rive/text_engine.hpp" +#include "rive/audio/audio_source.hpp" #include "rive/refcnt.hpp" #include "rive/span.hpp" #include "rive/math/aabb.hpp" @@ -58,6 +59,8 @@ class Factory virtual rcp decodeFont(Span); + virtual rcp decodeAudio(Span); + // Non-virtual helpers rcp makeRenderPath(const AABB&); diff --git a/src/assets/file_asset.cpp b/src/assets/file_asset.cpp index e6205ee5..03a87666 100644 --- a/src/assets/file_asset.cpp +++ b/src/assets/file_asset.cpp @@ -20,19 +20,21 @@ StatusCode FileAsset::import(ImportStack& importStack) return Super::import(importStack); } -std::string FileAsset::uniqueFilename() const +std::string FileAsset::uniqueName() const { // remove final extension - std::string uniqueFilename = name(); - std::size_t finalDot = uniqueFilename.rfind('.'); + std::string uniqueName = name(); + std::size_t finalDot = uniqueName.rfind('.'); if (finalDot != std::string::npos) { - uniqueFilename = uniqueFilename.substr(0, finalDot); + uniqueName = uniqueName.substr(0, finalDot); } - return uniqueFilename + "-" + std::to_string(assetId()) + "." + fileExtension(); + return uniqueName + "-" + std::to_string(assetId()); } +std::string FileAsset::uniqueFilename() const { return uniqueName() + "." + fileExtension(); } + void FileAsset::copyCdnUuid(const FileAssetBase& object) { // Should never be called. diff --git a/src/audio/audio_source.cpp b/src/audio/audio_source.cpp index 8cc5b78e..8701d9ce 100644 --- a/src/audio/audio_source.cpp +++ b/src/audio/audio_source.cpp @@ -1,12 +1,14 @@ -#ifdef WITH_RIVE_AUDIO #include "rive/audio/audio_source.hpp" +#ifdef WITH_RIVE_AUDIO #include "rive/audio/audio_engine.hpp" #include "rive/audio/audio_sound.hpp" #include "rive/audio/audio_reader.hpp" #include "rive/audio/audio_reader.hpp" +#endif using namespace rive; +#ifdef WITH_RIVE_AUDIO AudioSource::AudioSource(rive::Span samples, uint32_t numChannels, uint32_t sampleRate) : m_isBuffered(true), m_channels(numChannels), @@ -146,5 +148,15 @@ rcp AudioSource::makeReader(uint32_t numChannels, uint32_t sampleRa return reader; } - +#else +AudioSource::AudioSource(rive::Span fileBytes) {} +AudioSource::AudioSource(rive::SimpleArray fileBytes) {} +AudioSource::AudioSource(rive::Span samples, uint32_t numChannels, uint32_t sampleRate) {} +uint32_t AudioSource::channels() { return 0; } +uint32_t AudioSource::sampleRate() { return 0; } +AudioFormat AudioSource::format() const { return AudioFormat::unknown; } +const rive::Span AudioSource::bufferedSamples() const +{ + return rive::Span(nullptr, 0); +} #endif \ No newline at end of file diff --git a/src/factory.cpp b/src/factory.cpp index 00b89c1a..07e352ac 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -26,3 +26,12 @@ rcp Factory::decodeFont(Span span) return nullptr; #endif } + +rcp Factory::decodeAudio(Span span) +{ +#ifdef WITH_RIVE_AUDIO + return rcp(new AudioSource(SimpleArray(span.data(), span.size()))); +#else + return nullptr; +#endif +} From 2f5f3f21ca789dbffa4d2967350e599f997935a7 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 23 Apr 2024 03:47:15 +0000 Subject: [PATCH 031/138] Fix audio instances Fixes issue reported here: https://2dimensions.slack.com/archives/CSFM8K3CH/p1713795412798999 Part of the problem here was that the audio clips were never getting their "end" callback called as miniaudio doesn't call the "end" callback when an end time is provided that is not the end of the actual audio file. I modified the AudioEngine to create an appropriately sized PCM buffer for buffered sources and wrap the decoder in an audio source that only decodes the necessary PCM frames before marking the file is actually at its end (based on desired end frame). This is the cleanest way to make miniaudio call the callback without modifying the miniaudio source itself. Diffs= 2b2e92ca7 Fix audio instances (#7113) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/audio/audio_sound.hpp | 90 +++++++++++++++++++++++++++++- src/audio/audio_engine.cpp | 52 +++++++++++++---- src/audio/audio_sound.cpp | 2 +- 4 files changed, 130 insertions(+), 16 deletions(-) diff --git a/.rive_head b/.rive_head index 584b93d5..a5698263 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -89053041aea1e6c8559afc4273c4e466e9ff547a +2b2e92ca7ef815c7c60176c14bed4bd488d44d0c diff --git a/include/rive/audio/audio_sound.hpp b/include/rive/audio/audio_sound.hpp index 5d34ca43..96d63f39 100644 --- a/include/rive/audio/audio_sound.hpp +++ b/include/rive/audio/audio_sound.hpp @@ -10,6 +10,92 @@ namespace rive { class AudioEngine; class Artboard; + +struct ma_end_clipped_decoder +{ + ma_data_source_base base; + ma_decoder decoder; + ma_uint64 frameCursor; + ma_uint64 endFrame; +}; + +static ma_result ma_end_clipped_decoder_read(ma_data_source* pDataSource, + void* pFramesOut, + ma_uint64 frameCount, + ma_uint64* pFramesRead) +{ + ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource; + + ma_result result = + ma_decoder_read_pcm_frames(&clipped->decoder, pFramesOut, frameCount, pFramesRead); + + clipped->frameCursor += *pFramesRead; + if (clipped->frameCursor >= clipped->endFrame) + { + ma_uint64 overflow = clipped->frameCursor - clipped->endFrame; + if (*pFramesRead > overflow) + { + *pFramesRead -= overflow; + } + else + { + *pFramesRead = 0; + return MA_AT_END; + } + } + + return result; +} + +static ma_result ma_end_clipped_decoder_seek(ma_data_source* pDataSource, ma_uint64 frameIndex) +{ + ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource; + ma_result result = ma_decoder_seek_to_pcm_frame(&clipped->decoder, frameIndex); + if (result != MA_SUCCESS) + { + return result; + } + + clipped->frameCursor = frameIndex; + return result; +} + +static ma_result ma_end_clipped_decoder_get_data_format(ma_data_source* pDataSource, + ma_format* pFormat, + ma_uint32* pChannels, + ma_uint32* pSampleRate, + ma_channel* pChannelMap, + size_t channelMapCap) +{ + ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource; + return ma_decoder_get_data_format(&clipped->decoder, + pFormat, + pChannels, + pSampleRate, + pChannelMap, + channelMapCap); +} + +static ma_result ma_end_clipped_decoder_get_cursor(ma_data_source* pDataSource, ma_uint64* pCursor) +{ + ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource; + *pCursor = clipped->frameCursor; + return MA_SUCCESS; +} + +static ma_result ma_end_clipped_decoder_get_length(ma_data_source* pDataSource, ma_uint64* pLength) +{ + ma_end_clipped_decoder* clipped = (ma_end_clipped_decoder*)pDataSource; + return ma_decoder_get_length_in_pcm_frames(&clipped->decoder, pLength); +} + +static ma_data_source_vtable g_ma_end_clipped_decoder_vtable = { + ma_end_clipped_decoder_read, + ma_end_clipped_decoder_seek, + ma_end_clipped_decoder_get_data_format, + ma_end_clipped_decoder_get_cursor, + ma_end_clipped_decoder_get_length}; + class AudioSound : public RefCnt { friend class AudioEngine; @@ -24,12 +110,12 @@ class AudioSound : public RefCnt private: AudioSound(AudioEngine* engine, rcp source, Artboard* artboard); - ma_decoder* decoder() { return &m_decoder; } + ma_end_clipped_decoder* clippedDecoder() { return &m_decoder; } ma_audio_buffer* buffer() { return &m_buffer; } ma_sound* sound() { return &m_sound; } void dispose(); - ma_decoder m_decoder; + ma_end_clipped_decoder m_decoder; ma_audio_buffer m_buffer; ma_sound m_sound; rcp m_source; diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index 076733d7..8f957e84 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -19,6 +19,7 @@ #include "rive/audio/audio_source.hpp" #include +#include using namespace rive; @@ -195,6 +196,12 @@ rcp AudioEngine::play(rcp source, uint64_t soundStartTime, Artboard* artboard) { + if (endTime != 0 && startTime >= endTime) + { + // Requested to stop sound before start. + return nullptr; + } + std::unique_lock lock(m_mutex); // We have to dispose completed sounds out of the completed callback. So we // do it on next play or at destruct. @@ -208,12 +215,21 @@ rcp AudioEngine::play(rcp source, if (source->isBuffered()) { rive::Span samples = source->bufferedSamples(); - ma_audio_buffer_config config = - ma_audio_buffer_config_init(ma_format_f32, - source->channels(), - samples.size() / source->channels(), - (const void*)samples.data(), - nullptr); + ma_uint64 sizeInFrames = samples.size() / source->channels(); + if (endTime != 0) + { + float durationSeconds = (soundStartTime + endTime - startTime) / (float)sampleRate(); + ma_uint64 clippedFrames = (ma_uint64)std::round(durationSeconds * source->sampleRate()); + if (clippedFrames < sizeInFrames) + { + sizeInFrames = clippedFrames; + } + } + ma_audio_buffer_config config = ma_audio_buffer_config_init(ma_format_f32, + source->channels(), + sizeInFrames, + (const void*)samples.data(), + nullptr); if (ma_audio_buffer_init(&config, audioSound->buffer()) != MA_SUCCESS) { fprintf(stderr, "AudioSource::play - Failed to initialize audio buffer.\n"); @@ -230,18 +246,34 @@ rcp AudioEngine::play(rcp source, } else { + // We wrapped the miniaudio decoder with a custom data source "Clipped + // Decoder" which lets us ensure that the end callback for the sound is + // called when we reach the end of the clip. This won't happen when + // using ma_sound_set_stop_time_in_pcm_frames(audioSound->sound(), + // endTime); as this keeps the sound playing/ready to fade back in. + auto clip = audioSound->clippedDecoder(); ma_decoder_config config = ma_decoder_config_init(ma_format_f32, channels(), sampleRate()); auto sourceBytes = source->bytes(); if (ma_decoder_init_memory(sourceBytes.data(), sourceBytes.size(), &config, - audioSound->decoder()) != MA_SUCCESS) + &clip->decoder) != MA_SUCCESS) { fprintf(stderr, "AudioSource::play - Failed to initialize decoder.\n"); return nullptr; } + clip->frameCursor = 0; + clip->endFrame = endTime == 0 ? std::numeric_limits::max() + : soundStartTime + endTime - startTime; + ma_data_source_config baseConfig = ma_data_source_config_init(); + baseConfig.vtable = &g_ma_end_clipped_decoder_vtable; + if (ma_data_source_init(&baseConfig, &clip->base) != MA_SUCCESS) + { + return nullptr; + } + if (ma_sound_init_from_data_source(m_engine, - &audioSound->m_decoder, + audioSound->clippedDecoder(), MA_SOUND_FLAG_NO_PITCH | MA_SOUND_FLAG_NO_SPATIALIZATION, nullptr, audioSound->sound()) != MA_SUCCESS) @@ -261,10 +293,6 @@ rcp AudioEngine::play(rcp source, { ma_sound_set_start_time_in_pcm_frames(audioSound->sound(), startTime); } - if (endTime != 0) - { - ma_sound_set_stop_time_in_pcm_frames(audioSound->sound(), endTime); - } #ifdef WITH_RIVE_AUDIO_TOOLS if (m_levelMonitor != nullptr) { diff --git a/src/audio/audio_sound.cpp b/src/audio/audio_sound.cpp index 6bc227d9..052d1785 100644 --- a/src/audio/audio_sound.cpp +++ b/src/audio/audio_sound.cpp @@ -24,7 +24,7 @@ void AudioSound::dispose() } m_isDisposed = true; ma_sound_uninit(&m_sound); - ma_decoder_uninit(&m_decoder); + ma_decoder_uninit(&m_decoder.decoder); ma_audio_buffer_uninit(&m_buffer); } From f0fa7aa9d306417428fb49a5a2bfe1cbe81470f7 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Thu, 25 Apr 2024 22:50:02 +0000 Subject: [PATCH 032/138] initialize audio manager only if an instance needs it partially addressing [this request](https://rive.app/community/forums/bugs/fsLjspgTHYcR/new-web-runtime-is-trying-to-setup-audiocontext-before-user-interaction/ftnduzDdPGw9) from a user this improves how we handle audio in web. Now, instead of requesting an audio context for all cases, we reduce it to scenarios where an animation has an audio event. Diffs= 328d307df initialize audio manager only if an instance needs it (#7132) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/artboard.hpp | 1 + src/artboard.cpp | 20 +++++++++++++++++ test/assets/sound2.riv | Bin 0 -> 318949 bytes test/audio_test.cpp | 45 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/assets/sound2.riv diff --git a/.rive_head b/.rive_head index a5698263..3d7de347 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -2b2e92ca7ef815c7c60176c14bed4bd488d44d0c +328d307dfdfcc3c4a9d7c726f783b5325bfbef43 diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 2365af92..ba4ae11b 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -127,6 +127,7 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta bool isTranslucent() const; bool isTranslucent(const LinearAnimation*) const; bool isTranslucent(const LinearAnimationInstance*) const; + bool hasAudio() const; template T* find(const std::string& name) { diff --git a/src/artboard.cpp b/src/artboard.cpp index 0b4778d4..0ddaf7b8 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -4,6 +4,7 @@ #include "rive/dependency_sorter.hpp" #include "rive/draw_rules.hpp" #include "rive/draw_target.hpp" +#include "rive/audio_event.hpp" #include "rive/draw_target_placement.hpp" #include "rive/drawable.hpp" #include "rive/animation/keyed_object.hpp" @@ -648,6 +649,25 @@ bool Artboard::isTranslucent() const return true; } +bool Artboard::hasAudio() const +{ + for (auto object : m_Objects) + { + if (object != nullptr && object->coreType() == AudioEventBase::typeKey) + { + return true; + } + } + for (auto nestedArtboard : m_NestedArtboards) + { + if (nestedArtboard->artboard()->hasAudio()) + { + return true; + } + } + return false; +} + bool Artboard::isTranslucent(const LinearAnimation* anim) const { // For now we're conservative/lazy -- if we see that any of our paints are diff --git a/test/assets/sound2.riv b/test/assets/sound2.riv new file mode 100644 index 0000000000000000000000000000000000000000..4f7e9c5674aa523e351f8c0227ca8b44fa72a2b8 GIT binary patch literal 318949 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

a&Vb=@@=-|8RjtSqbVAxeKe^CvdldSkaZj_MWWk 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

={5gOly4fcs*?)Ear)_L2ygix3O#$QSBFuNQ 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%0DhM zeS|!&cx^Eoxp6%oSTAuo(X9~B581uAx3mU_P2rEn04p>vnC%!A5IutL zmGSfigV z2XOAG9{x$zX(^H0TRPU{d)Z0RMFM%E12vyt!O>>OqkL?`P*>aC{^6_d!JE~Bh5Hdd z@dR6nxRL{W+47q8Sep}vz{w;`8?Nf04y2G+nL!l3jVm|FMdU~7(2E}{mwj>gCpt5; zHT_a28g6yl!1V-7PQp)47WiEOBM>mB#5G+wI5@u@nalddh7h+{02iD+IrY=k}sRUSq!Ac-n72S`KF@0uBjnsGJXE1oR|m8S)Fo{g~apYi94D2}j7R8F*?07bW?0^wF1&12Gg^?g1i?VL7*a)PHJtGEsoZ$-I$SHYE$J>j1VE&>L=k@bep}Xx}-2Glw>MV}gWQt)GHxCP8+P}#Z5upkb@R=b_{n-&S?m;YvoogvKo7&3e z$zM&2TC`8|EnNYt4pUw%(2EiEe_qoB7|Wi)ydQAxQ@K_c5E$V+enSLl1*m3c90`g6 z@B)qz?W{if9q~ZdhcR4z$9#2)yfreK+Xt`0oFxmztnx@bVi2A@h>P1T>+%~2Jd-6U z=2wZR0{!-}whC2@efGnO3?fzs<{`hP02j(8D@RVN@Wu(!4zOE?iB*8%eE#Y4%Y@U) z8b)$(shgCdMuHJc&jo;pDJ>jG$ItSOqAc)cjSj@2sn>Y!eL{)+@MBIFGFwPLOziapU@YXp2NBge!j#4~h=_cB1e^wr^7?uU05ixo*1w44AmzIi ztnlcy6rxL`tyN`Z9w$VL1-2th7sq#u<1*;@!LatJ@Q4bxf%KxJ2`E2K{+6ntD_mrF z#RloF%pUTzhJwosC3lnzpH5E(xHJ1Mm#JEqv zAgLV0r}k?LhRp1IEvd6HsS9FDZ9ggJJtPS+(N{AAZ%OX^aj-ro+SRx)J@BD$E@5%x<)F+Xgxc|B1t@U@;@&AP0 zP&O0Fq-(5#8#UAA`*%16<3$OiHA-(ge;Sa09A>s3~uV5(0=mO`^Pn_Pr?1 zBT&lcz&)Ia*|M9qWr>A7WG-Y}s?y=-yCEl>Z>nCZZrLku6GZy|7b6vuS;>rq&QJ)P;wUO3 zIA$d)5bnaerIEDBbrO~SsIXaRT2Xm?dg;4a%ck;1arwrg2x~zSi@}P*P;`7uOE4s%;NR%PpMU@++X6= zOyjAUr7tOAvv)a*nJ(}|CBW8c@ z^?Wbi{p(YaoSRlL&ZCxD(QJ#~4a-QxdP>l6u(fKG`aqw!*{y8YozIsAdA2|PuBp}Z zm!J3xIa5-4?n*)n(YRD~O|E>uHs~DKLquq(tBP;ck4qX7xkf2$wm+v66Cee|zl?WM zUkgM*!xDU6?ZJyhqx-HrRLuKSf`GWhUj2)N+_>6yEsl2s)B28zIK~oD{T6DcikS~= zuslU~F>1fqM=3f{h=xke3g(mu4IM=-CX&d6CdP%Y4~La)WEBbYEJY#$8W?#PZ>VWM zE|7i4;rx=mIh%F&Q*V-}P+u##yrT*6*8_yPiTW4&_;tE&yHit>i^nql&$XxknRSUgfOao zHqR-2S&DuDywR;%$|GjZ4Xy3u)RqCTgrmx=LSVQ3hSo1P?)PHu!oS%GBnJe}X zVTU^v^xaVO^ol$h^Me)<6hf^?`5hYvNwk}`BDY1*a;v1X^ZhLN;OJ#{3E0}tg%HAy z!6O}#L<(}(MC$~@Nl&33L_ZZAo)X%ZAE;WPE2o=Po!LB%?&`SUnY0vd3YI0fsQaA< zKs*sn_KtgWi0$jXo{HxoBRpSapMv|+3&8$v;BOU{)pFdHIWm5Oa5Esvj+9yE5TW@M1AQ;N;W|)3f zqwZP5isoPOKyK-7wLh=tZ*`k%sO)sFzeqFIN4vIsM4nt$ta%^QEoy&~w%f3kkiLvcYNWw{btkoZ9JhY0srXLFlU0 z>E+5b2Eo#;lUi1qv2mgV#FvPJT1{TZo&ys>Ro4Ke0xIchzp=q03UdBi5@u>1nyOmq zULsyvdc42#mNxldeUz(511N+5+Pzq651RkXEFZ;f78x zmhE}$BmZRJSR|5TA)}6(9+c_l#VRcyF)0m14`;&_b=X+ zwCrt3+jtY?pi*gZ! zm2zgJBOxnx)#-9c)HUYsRwFn)qPk3A#YAXJw2xx}ZkK}*k~fk^#&ZbiR| zIR7aC+m(&ibsYHr{pRg%*mORadrl>G8Hm7>>Rwb`#)gTLRQ(YbFHxYs)Z*6gJZjRT zunmwh$+uFCZ!#F`q&HqtIJUo`9AtL3ZOCMSeN-|1`(5eQ?pwBs1+@Rpu*#KjFM%c4 zEe2fWX6Cb7S6i(|*_xor4aHUXGRMK}8i$Ge)wb{RO72E_58L+)&;8k(v`Y&-${Hs> z$YZEIkxZ6TTRapsi;1ZVaHC~;1O@TNQ2EqQrmTSK&-o=13QE7UluqgGNzp6MWTHMb zQ4NdSyBNE6j37uYC)q9DbkT}h&q;EUb}lqGjO|v7;6h1Rue}t601z6 zUHT>B<{U9LF5>_cxPerIV8qN4&x-8;lx`1@Vz3~T)>z(ia@B>MNt={b&P49P5hBB+ zYtP8U=M|6I8!?+^cfbgNvMEx*A|pvnY#b z;-Tr{+=wkOPP4i)62r7RP%jobYnbrm?q~2Mlo5VqgO9RUaTb!kb1x<00*#_dP*a3a z#(j_~(|fI@8fe1|a-}nThW>MGiMtoe03HKANmfZGgkBm*I+MMdqQd0u6eqI(R%jqK zQdT1c8fkAS2V@|1Y@H!;-v?qX`3-!o+1Z1HT8j4op$Yu2ww?iZxu*m~O`$Z8=E8@ju@ej->43VzoD&&srUgK0%H9D>fvWi4s^G z)mZr0S*Q!^tw*$T2G4m2>)KD>g})9f&3@IP4T?~OIbVt*qW5rBf1Dk35R@HZyu0Ys zT)tsj(QI_D6W9=t9`_jD2&JUG6mPigrXt4WCx2t z3~B&4)(Fuwa$AGtLd$!w2%~|4jLgcHM$aENkW;D>{k)$Tnf6Jf3kYc!`lcajap&=j zfB6wCEZFXBxwM_j0aOSW>#o~9z8WpOKu>aXx!77^6voNze5{Bkae^A#jHflN&Hv?+ zJ?zBxzG-W^tBywYZlNxHZbuah=AG8L5ldf7dwv+o2C}GgEUdzXjH4|c&}!hGx2B1C z;)u{~1w~v;5q3UBxTOw}`|P`7IJqS}D?wiADx+|4_AJmwLod2vq+UCvM9wGvVEPO%^z0 zrRAp)dR?S7*;c62p{YL-2>rLkkd0%o_|l(b1n5p$WbJi+N{S1G&w@E%AdCntq3Cpw zAN3Tr^njWQZ%Zkchc~F{KU^|?CGn{EEfBoE)3@RsPH>4=72l{dk#s&N*g5JLPHu37Lg*|PA4*lP_0W(@t4NH>4ktO@8CJIv@pmSK zhKvKOtjl zW>kXG(RKo~h^BTSDjd_%6O~xzSEFicW*sJRNFZ9iWMt#YEkh3G((e}^3H$mEI>5(n zn9@4TqNcVIfW5GKfIsE?tj|%CFp7uzEjko~o+t5DcGc-n8hLC(CVPPd;e;+NZc^!`*l$7LD;EKs`VO0Y zQ29Xa#0olPy0lKoWz_|(O;8t-lk+M0wtWTqk>Veo-BE%dzL|J{QaeOj1PeWRQcqRl zTFhANajm$%8_ZknFw={M2O1*Pu%a02H(;7#v*4pE%?6q~F(Qig;VQRbBx87|X(a^+ zw?$~bX3B3OE%!;s$>lp+ z4DVsNmjn*-S8C_0xJKym38+|7DgiEoA|mjxrcpFX3sP=JCghA!Ty?KGG=w^P4=YaZ zKfT7n=gC(t^M`n-r)wgPwIgCcOIyD~cyB0p{*71qTA z)_XOzX_mpN{R6G55Ivf*b08AV13 zTAV8-a8SHU74AB^B7cf=FV+1twaH!e*#s*7hNzJpLhtr9TKcPSv$L%S%1fj&FrZ}H zJAI{XnQ*2tV_Qo<5E5pJGePuBX`>d&CL78mSp;hR zUehn_4b%50#l|(zT-xSJYi)N6$IKSowqwS`{Lm1$D`L;1hsUkD zwpNYOnRO{M9UCG&gQiVORqt-Jkbw|yF&^KYnBbu0Uk3*NZ+W*X${HdUte)9I-vY&= zfvyRetXA--oEH_#VAZ%${D9q%Nq6nol+A7Ye zoRfFcz&a{z z$u((T4NjaqDfz zEY2}zMWQ%)=sEPHXKmHB5GOIkBqc`cwU{8YckNF9z;S8_`M|A|!saCmC+;yz51)c7 zscjxh-EAAYW^Xb4(QkPd^QUeMq)XFlmml0c!Dii^clN}Gl>ktJdP{7%i z5@IC*hmEml(a1?Axk1k~G72q6NuhxRD-NxkB1stL`>{yC^_a{dpTkN_I| zy}p`#Bt_{hNaKZVC^8l!EQ1QWbO8(uHPl0a$a+Vl557%pK30H2i`KaRwxgHWF;4%Fd`IWb5)ND6E=svRfxG?JaDov zQ68-pg4J#GWRl|#&@2}qeDP~UOLSKJWmdIIsJ|tYTy$KYeii zh8N{4NbXA0@3(H5UDR;8K?UFPXq>`tB+Y2Ez>D^=?6}lrj%5;H=F;4` zTM7+q?8U=YMxi{dUpK($qK~9IiYe~ljDZb`B*IQWlg84O!Z#n;B*d6e$1tzPKdR-T z8`|_o#D|-3wTy`yrzUIWoc-9Wr@XhH@+()T#7H~PAz={4Dg#JT z<`O3Dc|FL=>oqzPJ*d*qqEkt+=6z=n=lT@6FO;zpuEJ+oS+#?aB=Hen2S?gPS(&cy z(XyPi;jqVT4q=s_><4LEmJQVe6ZhHF|f5#(q9OfHf9=++{{VpR$OWB2o^ z{X~oJ_lwMbSKgp~)3^{lg@lYy8SRy_yh7sg6&z2Ua&T@dI>!)l0#p;cvxQm{KwS^s zp+6KD%i$;Qy<*10ej_o6NQllb1M__O?|DR9R!S?WNc7HS!I-n zft@{%t9TTC*>X~{Bv}=23{@n%yEkl7a8aA16n`}=MAe;SGN$~y&&VKgd&hi^NHGol z-oRFTBT%dvZWt0`HA*#D_Qj04f)Q~gDS{pn8B?nksd|*C5lkhc?CS%K!N)Y$I+;)c zPS4osK7ocaqIp>4Al#6jV0!y$h-^`vi@DS!fqk6*XJ^={_4C!d&3!yRupw^b&W|~26J*WZc_uE{oFgF%*1&5;&e;FqfUxK zRs<_3#W)F~TtwWYcc&kM#F*F=H?l8tLQsU2H)DeES6$iC2!yKnQ#yyW)?-G z7`asWBJIy*6+J^k65LFat?`9sDfLd7!wzU&2Uu>d!ZxGFS=FaOvckx*l!~M)7EVIgS&!pW@ zR!q_0!;?J%5G+rgNm4~>jS4O~P{m}aCIBakB&DZ6xG;7J`by8am(np&+Dy;XArv|ZDgC5HOH>HH zDja$Ii>d!B?6l98Ho;Jm7c7P<-4$1_xwJ^8{;7?)7n5U$#S%j51`MkCI#;cicg#X& zL22B9Z!WTLK)IwHnfNyb4Ii27y~30PQoHpVY~n_Tm^~Tw>v!KKWBt7HBiY~MHrKXn zsv)b6f|G$AcX(yJ7Pts7<`SPHJIx&?xV$Nc^}6_`RcP!Z7Av$QtD?$~;tPy@)|J{z zU4D`92v2z8og3aK&~MdeKex_{w&g3M8|7lI6(YQbSrl)cub{UHI_o|9U0-mB?RhF- z97&DYp0`b6*}9XnERa}WDQD}zUKS=gcaye*Qxas1i*mrgM{?_s}-4w-hZP}H}wZt*;5KRl@Nr5~8&q%7DRMX~#`3A@538oC&+2qfy{uhiC3S( z3RSJVC71|cL`B3v!fYU$OyWY6jH$+Ou1~Gz;KN4RkVj;w)H{SFk+J9BQB)9KCNgNE z92Ipv@k<0knn4idRGt>6eTX6MegaRSu+f&5J9tZ0>upToJhOyT9wLNUzyOyK5iF@>8CAO8sc7t> ziO~U_Q_pc1EXFVm=wPEXZLC}1BP+_2CVO*%3kn!K5g&d~*cjb>KwL8;fM=8kMwj$S zDVSerl0Ev%b1_&FH^E|tj3P1rZkBu22_6^~=ru0jUdCfceuSXeX5*I;9ups3DN-~5 z-&GFqb!KfyVBMRc(P zOimjwX4%h@^F8_$pw$58)r-C2Lu7@iIaF=-ZY}Ot`(U|kOtfU`FGg8+sMZyxi~yy) zheNhwO{woj3Y|4tpeC2FBPNmsW#`12c4C@A_4&4z*YrT>dMpGq{2;-&L~Ez(rDC+? z1XSuN0xM@sRF9JxKwfm0>Hfm>f z(2QCtBcJo;2*tapqLYqAh;0oHFA$>SMkgG)J4$n_O(opkQ^pXfD}|@cQ)Ij}bg8J0 zhH5=5qC)?%pJ$8EiDTe^M^-_7M_uxjc??_dvjI@fXYTFSj4j67c#h&^x6#t{_93w5$EuAp-5XN~ywWfZ-ZuandnGC_5;tT^J`A>HK|jk%9M6d`t z81TI$?KE^F7fYg-QL$vU+R1Tn>6?geWcfuEK`W!Rg@R_3<93)3E-SBTrXHSu5{|Zx7x9Lsx^8F((+A@Ksv8(qFF58Py(cEH{Cy7P>{Dmq!OQALyAo9oopNNh?Z4) zuSXM4QfmTqvpAbR;lpdk-1hQH>8`8M>Z2f-!td}xX%*WWC>m-fCDN;S226c{DqZZk z$1Kw1I7XNvC&qO=cuR6z;-s&QVY^(WcYK0%Ij(D4Ejy%%DDsv%BtXOnV@RJi@2O3+ zcQ$BZw@wB^*2r;1rOX>bkxQ>2pvt(j3JRUv@bzIp+3h^xSCTNWpVRB!(@pMulP(!9 zaG8>&X&WELfpL!jAru9kE*Ch!BScb-w8G6MMjlQl0;At1TvATXq5a$iGF)N~`%~zF zA;^QmFofdMOc0nwx5crBX99HSAfd%hAq-m*YgUaCw0XZyLuh>RZ`3RC!r^uSJSf!! z5NY9;9SjiSR|!R$Pn#>MR!N!>LTY3rd6ybkqvrHV#-0#aGh;kf^bQ5=&6`578xiMJ zLMyxrlwxY=KE<}I0=+45hOC#3ZCAv9I(SYe5gmnyErd@@qd)G_H>1RNtV<$l^il3&-tnXj-#(b{V9P_D~0^2=~*b)AsLr*kH{((QYb-OuM}EM%>w&xnx!(6 zL!v*+njC+AE4qt zt;b=^cbU6BP7vY1biirNnVWGEiQ$ErOyh+F=#sZRVNuy~OB@>|@L}5pQ8ZB{)%w7T z1T*GNi%{c;DFkWQ*+yJ&)XM(C;VXFa1OAqzvjj$vIx7x-1@r zs|H@v7r28w2(suuJ5>k5!@ATPMBs}PeMuVHFFM&@rWE&dh`4|X&}@@X-@`-)qr3-L zF;}x_>%|!)WfWBa^c&OU3E>|w2+lFdC;b~6aEXtLeC|BtyXf|ah`!^P*$epYS%zGS z2E;aXxpOHppt6v!z%?F$mM@#31B@r5+S%D&a8k&Sfs-0~_bE;M@)elUq~QW2sd*N% z3KQR+@%t%pwgnil%KZto-%2<@nnqTk5MjSsBpB`%bjD0KHbOxCnhw|H4uN-(8qdbm z8i=^H-;Kb3bdUL{2_%5-)jz*Rs*?SU{N}Bs22zx3=qdRN?u!aT3eAMNx?@JYO;A%H zWC~)5h9hSE>0JReJK^Ljk9j#v2CP`gaezu8O&M#T)7injDN2Bx6%0Y!6Z*f5O35pi zGG0xMstq1|(e|rZNly?%o{%NG;c*%P4J+*8sFMN)9HoiY66b(LO*sTQnOiCx1ncbv zchj02%-l^BMz9}jcL-sL7GtqU*y?ib3bHa#C@&BcTzXUz+fhMgfmWS-x#7bc2`-X~ zD!<45p?}Lgj;Wdfj~*831TIfKvlp3(I=t;$&cBWPyFa35Tsvhl%G4s^3(TYv$$Q&jw=fXJ#-qXzp#O)f3C}y9j{WR<@rb18R z#1U#z&)5iG#jv8L<)N%XMsoffLTEp$ysPhbQ5GUeX$rTwn$@mEPgx>1toa9>g4wqX z|9|{nAL9aQwhi9Avu8koYfSBQNe$3pTv(7}Na2{Bq-3bX^;#-onU>nJ1J z#8+57#RvohWF?+}{Lt)~-+Dl0@L&JX^GdkZ(p{=W*;V3}uVU78OQclH-op#96n(BZ z`PQfV%(6k*1iI@hg=AII;Zu`_Ms*MKTM;5_C5%PXH*V53uAtwmuVK(N{JX4G?@mGLW7jHx(gm3^Z=NMD9X6q#|E(yU1{qC)kk> zR3QHRl0G-Fm;ryvGbg8rwLlU;+%n!n(8Ft(yyp2NBUw z3guE{B5CY+q*UA?o3w}qfk_o|yriG9K>JW} zw@Pp*WX={+6WsiXgV#9aY2`Pv;C7e-KG0V2VO4CZ^KRAeLkM(`dK6Vr8uMT%*L;cD z-^0{|s&Xl@RY!L1BfF$yQl%~e6=7YeD#x&GZ9h?@)>wzG9M043 zaCw}zYp|tBDi7~*eH5PGsV0!2e64Czb@T|FTi;C?Gn`^+v=M8eb zsy%Oo3~{pOYI;66M=7f;QEx3TuH_9eEt$P0)<%2i_?2#P#kwuVX{G(aSXWxBgLaT#4_2jP)q*ag?xF6_OXc#ZBOODIrGkvx%)|1Nd*kJ zEqVptI8UKvbrZg6P{~>9c_Ng0Lc$%_;42;d@)^3jMI4gwY{wY+7*NtNbVA3m3u$~+ zkME&Fa25l-xpb4Ez%*$I?}(%PZV>7ftO=I|?RXI6h`Oo9%vi%jA&CW4p%qCU+ww+p+gtW@ke_=Bj*=!-fP#sNpvE&oeshA*DhVPbmx3m?*`XI4f@Fpo1x3QnD9h2k zCoo6M+kTpIC@R^06Xwj7)x_|q9YAgnr38pUdL&IpMiK(9GNHG5%P5-_gJT!-T$<>_ zvaIt$=VdL6Q_coigBtw{MPoPDA)dCk##kcNl0K5kYKIa~;No7;9 zh{FIQN+DA{xw{PI>8EirCuQUr0XoPVSD#jUO&o-HKw(X%0CCHel5c3llV zr}HcmMO$GdVY0QI9z5cWS(gNct?I5X2i3#98v#OCNJ>FnjgJS+NJA23R8XjhIeV$X zOGHI|5ytl`azJuP7n2T=?yyMqg_g3Cu*J;HDjGnc-)y5{qPp`E;_9~gaf<9^clgaL z6#$@J?ywY$H9nU>vk*ECaB7tS{5a2Yo8^NNi`I)uOq6hzVhopG_n84kuPeKT*?1^I zG%Uga?-r;_J9&kwE$k~UfD^1PL_QK97fDpW#~TgPEJ@6{o7R4jqHkq)#<6d1cvMw5 z#x9U71_jN5cIvza0HKZizQchLLP>FNay9{#F7%aTBk?4~}u1x;;@#k6n^E z2;{u;M`1KE%==ErV{4KVH%)S>mi_C37=w;WGWEE zxcEeYxbRPjh6Ym2E6=f#S&IYe+2A=jfWuF(TnR_MZFR>LRiK9~*(`p~-Y>gL^BkW~ zLjs%lw^ul)#r&9wbe_8W=gMJXa0(JhrcqKVmX+J)$Dqn`C3h(M)SW$celbedp&2*& z!iSrZ5*9yjFV_KB#L|!{J%@i!pq6CawG?+K)@n2nSjCvNJ$rM^DrO-j5{aueq&1gT zC!RuSZ7OSd)G2Kl=frMdC1Xct@1oTx_r<*=KHQgbjzm0(@kXpfZ7L~;uhwVM6LL(yJOu-6{73htb4;(?hxnQ_6zm5^{*K)} zdultr@9gyTS$)KiFqh?(YKo|+?_XW1ha!(NU~ZfU-A_+Iht(a|H$Yn@FK*2oz`dML zdpFBXl^5fvOEn6F_Q*Hiq_Dm41f#*hD*;-!!fdZkbEO1xthav*N9EYdbSH|c!?;G- zR1FCDp3H;2W*>>f*y+R^1e3994&0?e;TyLN5oIBT7jwIjc~Wnpl51db_U;GAlKl$rn5zYF!R zFO%eWP%=KWyeQTR!n1c4jQ?o@pvG#o7pmlU<8l+TJdqn>+E0}Ows_3whblgD(|8%g zwcF%=+)}g6XNNgttFRcn)KI7U-g%abeGUGFHMY9wS5Dz7t#E$|6?FtB)>msIz;Xv) z@H7!9BKV=xFc!)TK-fpbrr)vHr%7}LJqMnd5jBNxi3%^n?1NC#_ zperb;HAHKCS}Evd$jds|m$@M%;ZMt+EZ4bka%;fq!%zF(8I}~Smur4+_#z5yO~-~Y zDXs=QBR6acrTwmKDWU8l1tOx!{a=<1UmRguFHXhNEA`*3u8d@qRN-Qxp6QJQt8Fv@ zw_G8muJP3*osd#h%PDMBqr$$q6sKmEis5++wd+!F_62yO0#%=RJ*3R_3t5ubmK=D_6Hj43Q0mmv$CVaVCq_4hhIUfpE7iYA(``H7I$)l#JRwsKNIEl=18w3bo zrhA6oin`AQBu8q`5xJFJ(j`%cqrTPfEX_+m4dhgyq-dJ_8;GF;CWj7V!E9Ixz zEl2Arv*UbVkXgwb83NiIbIqO#t z#N1no-ytfk^`ZeS{#QS--_(!ZC;8Y7#sX>uLI6pDR5rA@AMc&`kU0imkNaO<^&q(L z;jTZ^+$NQP+in|%cK3G_qXY-iK{sxMNiel;>sCtm#K!9Fk}AamojE3`kfm^p#H|U% z%+kn3G8Zxo6jbUV$gGk0YBGmw17yl{b%4zF_Ja)(!t!$XD!$HzE+YcWbt5J0hJSd! zmHNqcg>IC{n60HH%x6gGXUOgo{*dR1g$Nzk8n1yXvTaL0sisICGK4~R^YnT3f3Kt0 zmrA+jDWU5>lY+jCp-JlCSZHJl^0S3d>C>z=m@6?wDgv9y{M+kFJK_e=maK3`k$Xt= zK#?*-vF0(&(IA;L#of{q))Fq_O|NDm(uiHFGeH2E;JNaud)bR25eyuY#>2a z0XySF6C07;d5mjIM#A&{;L{FZY8y7I%QJ}Wj?Yy?zR{y*hLM#)DymYyrl_50X{h5G zUseK7T5z|H)9J%Rx)847F%h~jN)3M%>+pfZ*VkiSqg1)uWP14ZLhHSt#BY?b#lsMF z&6~9!YRI_8IWAb`b4ZjV*=yy+qcJJ6MBE!pFn?ejI1nz-QQF#D9#9sxB=GeutYbO| zQ3kwKm3}E3_j~CpzgG{U!M#%wop!VX2n8w1YWSRFW}jLhJzpI*PVpwyjdyp5ip(a+ zr0-9X18vq`nQiohLsLGl^O7`o?U;#rRzQ)3XUj%{({bcEq#7wz|6U0=8*L_K#U+cs#OAu6+NIO?isqt{A-eszr z(64!efw~6oDZ<&W<=~1`P2qm%8KT+_tR(HAz~0Sxg_k?DV#lBLiL=nBRB%CGh>aE|~RRPpnnf{Yza5#~aS3O4wjxs1S)IZV@aY)0DaC5NArOoN+jd zJA+>x15hL&X-q?!eWHKXTu8{6_MI>8WQYr>nMmDzZhWRGZVm@)Rqw(UTL!Nre_MWV)QZ1C>o)TC~n*8Q%o%^tbSXM zj~-sgqdpZ?{_2Ir(WYLKt!_nHAXA@%?8Ss2Ya(nkv>EZNJN_bHw8fm~0%+pf#`+O( z*4l>S*ptY@g+**F^H`YZ!m0awF@vAvU!&%diXx>4K|-`^Wvr$p&sVN~9jbrHtFEwt zw$IEKRH&~ApOOBolcHG0*lJso7(9zU;}W`uA}|2sNuUDyv<3IRBan+ zMW{ebZZC;}WVBbCQGk|6*;M5NC8Dc;WBo>7_l^!eCR`Swm?^$AbB5I`vp+&aYJNB1OB?8l zXq#QF6Q~(lprWPdUp*@X%V4w-F&J`fV<}oIBZ=o^o0ClITj#n2gvQotGPY(Dwum~C z9?CR8C#=tkFU; z3;A4|y=|Oc1*j!)NHe(;2*&A0%8zKC1RF+#RA(}S{NJ-49o}|4EXk3jNwukiRg-3h z!FgGd#okL(;o?+5LiZE1QELd){hQGf_RBYhA7&Zm$jjMTT_y06DkCPEA0-D*F6>9oMQnEI_q8%n zbqT6%T?E||lqKCahH`kVM41}E@&mSN(2`@Wk)am_i&bJ@*ZBGwaxk<0pyD~A`tR4k z-d%8rjk2+G`cOVi?<{*iyIoQN6bFh? z;zNdP^0{cnC1biX9YV)0GISs?TP1K_f-PvR5L07UmY`-cuXWZ{*7v&6yPeBPwU#p! z1|6&8HI*-2s1xpM^t^egTUK0*RtV9Vg7;ZDFJ@H?W(4QCb8_A#)ri~svtunuqY3ow zU4Jp+ju2Q$(KwcIcGgSp@I2zs^|_?d`|LzjMPAA;43Wq|%2IGuknzdbqG+j6p_dMk zMLLw7kJ6bjCWZeY7;0M`oaG*nBR%ibTU0o-BOQgY(v8Le9=1r95Uj2w_O-O2w4N)j$IbN<&|f6|{~R`Tui38L5mLI9 z5qO{i*0Ti3HZ0(b@*skhOlJ2`+lU>Ayl!RS|a1@MoWN6%dciL*M zt*I)6Wgugx6&hzOh+{rw>jFbGWCDBQflVd~} zQ=%b8nFz=i@!%}|PuRD*cX7{5>p_@X|M5n<5UsSsVuw;bKUt}n){!hT$$aHzMeX8K zfI{Zc7bH0kM|{y-w_%74Y8xDvL&E6s^VJ4l=wtFTm}Nv*>!seYZml90t6$bjVPDRf02_|J-Ea^F}nFn9!oyUS6$N6{HkQCgYPiI z5!L%p7#`Z|Hd&=zZStJG$zt!?F0(xt*23T#8mD3xFs(aMoVVBAE&wKvM8I&`Ql%vf&;QzWjXECqMsNeE$VgNm#y?dqMD-Ugt#_DN2)6sFDU`M zy;ZOC2QnNk-kXt>hQ)l4cduLW~j*Hg6l{qKeE zLS(T)ZN+oMd^td0tN4~YLG{eoP_(~@?!if1{h@GF&V%MC5<)nA-b!uV($r`;OjSJ* znR$`cK{Bt;sA*;qxeRPxa%NdxU^E`AIZi2rzpl$Z*Ni3VOyB|%zOr328zHNtJ$RAi z8iNZ?_{V~9zT%PD9cxaq_5J9;(kG~ASdy@6{h?Ib&KW@+Bl`yxRk!Py=%o5m8JeezSy}n-d^>`>vR6C1&^ps(!F(m^45_GN45s zjr&-PZe|KNwIgnu>p*hudtzCDi#<0-DQN%T-WWjVEFjNCRx0CA5(Eyv7P_agW5AA5 z0pSK{Zo}h7VwSWPWei~5q2D%yo=&;h$bITv4(GV*FKMoRevIVIGc>aYho%g@P#mcO z!miP75uXm17wOK;`X{Tz5o&DI+G2(nPj%6M$mnCfa+JlPi~RsRjj%DImcF`4T9n98FK) zlUZDI{x5=^==N0xj+b0fN<_6sYG%X~R`6(*&mW=y3Czht!iCqv0 zLw{+mBydE*JjO+XgcdRSti}De72p_od~3+i^Z+NJSsDPMudOswttyOOxjzA=5kgM& z!m7iKLCS=T{h_b-JEe?Xggy{(n)A&#+CX&!d76a^JJlAIgwJ0aj74qBqex6rciE{z zwKESe6~(=iYKC`2+4`{N<(u|vdTtCMl0NfCDwJbcFi0le96r|V%3O%b5JLxxem^x$ zq>f)lB-N;e&Cuy%u64 zjXf#)aOVRmT@SD%LYGtT0*4PYShlN}C-^~l=_ z$$Z0|aJCkA^HM&LW~EQ*SgHa*vb=%(lA+Sf!cq4Tr_QEj<4sw5`=v{-gV*dL`=G*=q7( z{>l4HUuxI4NG7#z$uR(p|NEz;Riyhq66bKZnI0^g<@RAU=GjkzV`$N52;LC3Bh8$v zFtqN6j1{3IN%qaO$$;7t1h(QO1I=Au(%`NwSMH!Vo&0PWMO7=wDK0y_wgsHtWkk)a zr*&o|@qP>F!>xpR>&{29`|(L9he*PP81vyKl$fASKWGb^X<}&m+$@@^)Y_fGz7$i( z5bf7IZVyVkvI+$!%O&?=uF(_UJ$Z{s1dVl*mr0ZFs*_HLOkTfcVuh3d+Jo@!BP z_h9YVl&R@MIQkZNO-t+iWNh7Zlo-U$*Xke%d52oa-_CS(ya_PfaOK2_%vUFTB#8jN zxS2mt5Um!Ui29hga_@SOBh96Q!cb}mm7FrqZlrsRvASN7tN)9l6Z z^x`G!jal-p_8blNEKf=X#wq? z9dhM!_e(7aS@BJpX@djUBo2jnZ``K#dMut? zAES$rM<_9J&584d4c-h&w`x$9)vpuuqU0>}PW?hbu>8Mjws+ymG>QnI$uCAotkKm@ z`|g!JSnzinYn|69RsH%6dvU>jom#cX1*xfosE#J|k1OMrliP*&8%`W#CaSSHVa=w0 z5M60r?%*c)pGl%z^SBOCEGdLXAR>vq2l8cS@urROY3Yfsp^eJ{T}DJxddi&vZzkmi zfmJFL*3s<_|JAy-DF3zIu4Lusc*7`C7dqb>ZFsyBC+L-({LCVoZe;dBiPZES7?ymy zD?Nnu#>zyoWjmvKd&eEm?!41`_lUn5R z$R!!si$4W0rP!v;*lroo3|L;ne332rGWNb*Lz>o`ug{0N`9VLjaGc1gNh6j&gqO6n zSxYThB1i1jajq7H4E|$zKdOYEyB(3e9>1Dh(p^H=I))VYx&@eY%+9?%#4w-E&j1rj z@i;<${pN{dMqICnzQy+~SbS%H9K>5Pk-Ogu=08 z0;8x)spr3HRT7{1NEH%?#Jbr5J4siA>>F2bkFC&~S*f zVmxOCig(g(NoUDu*^@7-rYj|QS2<&dIss-Cf*M#7aGUQ?okd-l-%$WogE-Prr~!v8 zHnided&YJ(=|0cWD1s1rqXitTpXnbRa_A5laPPuL)aDZvNr2%wL%ZJ{}+8QlBG*aOn&H@%Y_0x^D5u1crdt=ZMhocOZDT)UtuilNHmG zIPE5Z9f`0tpr6SmpdF*ChvDStq6sUXxYa^2vet6;=izl)mkTZd7rChV^oK@{#WZEr z5S1kHCsjqHU2$kgQ9dXjf&LYe?;u0K-$Zw!h4>kFwpgHbz|)AFL<@*40E$t@dPVe* z=}S4yQ&drVyZvVTul~7*y;eps8?Q$+0#4-J$oOVi6|VQEACLP7k9fhHVhDt5 zASovf+^z&(VL7)HmU&D#PHY>n{(SiRa&ZC9l%GO_oFSq2R#k|Ib}IE84H$*Dd&GHq zhjI+`LUPwE?kY<`O(Gygfp6FGy>z-Diyr%S$ZS3q*1xjy%6KlGM4%XnqvD%NmBdR~ z*r)U;b=(vV>?;twLHb^WG(DJj(t|L4)lBz&8a^elsPj;Pa!4Q08{x&nJ)BQSRxjjp zs4JIldV@ig+NjWmZ=hCpP(p_O%zq&s^5UtPB1u%IZ3RBB1DaUjyM5sGn_&k-YBpla zEA1BoRh}ZRs%c~fEYxCRutKjo^cOB?4ZvU7)gNoBYRgNERA2S#WjDLx>T^@6*!m9> zrEWziT6$>AT#6)Vy&`Bgew&$zLaFIc1WBuJJ=zcyuj=jp+HFN7GbCc(;r{k4o*%ey ztC;N^Alr5oZAy>)w7eQXCGIXlHY7?NaNZ=kym0a)m?3m%jYNzaCOALI zR!L8#JKXrJiD`K_2sP#gN3@nZXI#M~m|ayy&}&wHop2{1^w+aGVNGGN4;_A~x#I>| zaFdNGM~Jaq2*m+`sM^3yI{Q$D$aOO#jh@Lx${!uj%NqOyhiT1aQVBcZ^%YIIlCZm6 zbDCsTKSYrk%~94%yumwei*heQC`q9^DrwKQPdq&yR{@W0VCj$VbkL}U9b?f?1N$1` zxgSPxqDDM!eTCO);}sz+se`9L2`pA`E9}UX6u|<-5>~*-HQT$*20Scwt$!M3t$qKxa1}3%9{qg z2~m79ciDe|7R*4#_N@5ys~3nub@{IunhB`csd#$NOjV5LWB6$VvO|c-ghtHLuPJa_ge!^#63@47Xl_8DGuaOl@00!=BeVuhDQ@p` zx3k<7S6JRAneHP=-{767TUoy3yOU{&m15MlB=1_Son51Yf>!!`6rkpu%(WZ;D4J#w zK18Rw!fS(;Ti2`fseTLOARqY_xTuIqa^Iv(@&)q|9^TakZVp(`#i&xt(iDm)(g_#sAw_nG*m@A@^n}_MIqTGH4KD|_DM<+xI;6r?Ngbyno38)#2(xI z^V}Zw#e9fIc52NhXDv?QA7DxS&R(av(9GeVA%B{%DY3N;U5GH+*xA8^3}^%AOylS zu*U|pbAr!E%-gIbpl^mqWxdNL4`AQa$vJrC<-A2z1RHcfzr= zIQh|WELKaC3uvKo;*~^2lNf3*`5cJAs>M{p$zxFyu@J5JYHJiH;|{JhP)SOG2-#Mf z#32l%nO$@Wc?BM$;D$hQM`Z!GyyW>!XyM4pwa^+yqBdIeuf!;l_~*sYqFThVkzNyGSEGGhGSRd( zA0o+wU^m{L%NWjSRcEVi9+FoiX4Y>=a^fn1iPdle!u&|EDzSSKD%bmBg4fk|QZgx+ z@)frpEE{s5lT0u*0$8&R(BfzpK6S!3hJQ}wp7puOFGVdQDhaX?&O&BWcLZsaeI+=a zEhg1%Vd*Oc)NCN1+FS5&4Xsu?IZr#W^c}>Aq>bl>dl*?}Y*1T@rY4Kl*sIuGZrpk)B-jc?z)P)hOy>jGg?REDF&)stJ!mol!(Y4cvGu0c= z_y$LuYj#-~d#Zy^B)K3oCt9ktprH(nC+F-JZ$*E(V?LLjl%odm}r- z*Ll21C2m#3W;k(#<#6h7EzxpB@#7d086G1Nsrj>II-m~WA)m^=efeXW zAP1?2UoLmSLhe-}mMLyqJ?>;s{@cg=2#Ad6ehBI+P4#rlObN0PRZ(kG(xEvWF0_M9Q|vgq@2@LJ@i=HWp=C4ouobD~)S zryy1_$7r*!g&j^hX*#+}n8F;Z4>SKTzPYH}k>zq;`*%Y3)xPBNyj?iYY=@=3*(lOP z!<@;Y6^S}p>jLOO7t9)01Q?}gkgY}7M8YT2)zf`Fs_qq;7c_0Sue%|Y=_M_@`IIM@ zkbWzomRG(v9V#eo-%v~btNldK z`MP39`G=!!&B*zxJXGD=^<*VqOe^bz?ISAJa4PW%X4zwqQn0~XdEOR5HgG4=VAZU= ziXzyv^DT`A#I_I;ZHixQA@vu@I1bnvTPSMFMR z=o?ZS*!0eKkA<{Rd#9)+zwY*~PVgY7K_nNt=D6k(vz9)A6ANn|bZTvVkOoS@Jeei8 zqttO~BIc}|Kl)W{<_s~>lnW>D(k{lq&%IwzoUO};!xl>sL=ulQ)-!b|QY3+L-O|=S zctn1V7jS%hH(|YBa$`_qgw*9Hdn}t|c9q(_Rxba@GA=Z`3p)6cqyj0p-@mVLJLkXEIgQ1EEztTJT^sqHMTPK_) z5TrZHhBB-)rswEAljEE~AR!8_584xiW6%cC0SaJ);M%IpANBJT1K^2Thls9+{F_aZ zeJcI)f{Z5(v7rz$Unvms8#;K4F=>CXRH^F)bN>3t|zSwtzDwkBW+7yz|mgq&-;Vj%kD@F36OV<$zsDI7i|mc) z2!x{*E_g@B(NCpdlhCo;s9&OhN!P}(|B|yE`AiL~$?xIYTRw8I(xy}iNe5YIl{EN~ zqm+C1mf4Y}1*M_JZs1MtYPP{7mb8ND)?;r_<7!ANyznv;rR2#@6na^w3dqCP-(W(FV#w@ESFXpuNoxKl-CyqskEH z#mWg|dhFzvH$aj#$2$K9utzLZRKWP%`^A7o=5174n1vLAB|+LPs1RwGy8BI6De#h~ zmzfw6Dn3eV<={eAJssvyRM0Flj}3#nvlwY{3htWJ z?V0PTV4JT6Em@m6jB5|mCfq7LDiBQ9K^g?5m12U<`t0;`L-5my=ToK^|h&7Zl5}(`*%$#0YZk zRdEMP(FV&!NOdsj&{zia$=uQ11FK(UYL5yuK1u`M{H=-%HPm*NJq)0Zl|R{qlCy{W zY|L~0+yT=-}QE^1SFGxDi%bRE=U5ke@jEaa*sHa1IHAy-!cqD3L3-8(9Y zIGoYm{TApeqUJ`+stKRXF)Swe z30rtA&LPy-LMP9~4)2AFolGXrdk(dn#|2bl42Yse20YUa8&){C?@jL?P8W zsT&D8pc{viYZ_1Ub}5A2GVF43L#Y^bPSPl*Mosr}>7w*)9D_o#kt-s$Yh+H&el6|D z`e@vb#ID-hKAIbv?dw^2Tqd;#Bm2w$!9!0;^F>cr`y|NZbFD&D zZ19iIxVz$Lat&hYeHvmT1D#A#?DhRIS-tXc9#q)6o`-sEJ<|1^37fo`b!=eA}80$a-7Z8KAgNKJHS>qM=X4VbiF44iyaz67o1lJ>H!3Z|H)fzr9mTQLnJY4?ba&t}jO)$mKE{3j+cKf_}ctD1)1jq`eLo zVi$anJpaI^PCa?@OeO`(L>Noryz81%P>H2C${CI(FlQE!2Gqbwy1{GYYd#yX=M|{x9Rn`80Fy1S)ksG%pe9X0yg2624r8y5 zi4GS8aibnx#mV2cWL9I`?~)4I;U!?`f4A$ak0j|@Q!dJ?-}m7<5YjF6RH#C@ zC=*~{xlVDA8bf71Fd=>3M=qYB#UA9G9`m0I{{ZUNQijz7hV0ZQb>D-iGNcT#igdlG zNE1vbcr^!kM#wW+n-;oZ3SOs?>9bh^OJ?)X33f0=KooytQ>nr3-%%5)>;LHbf|O;ZPwUuw_o)XdWMSrxiYk36 z7p{V8%7{fdZf1mC5X)nR@bZ8Z=rZ4E#0cU8bdg(K5URmA?9OnDTherW^ezq_Q$BqF zq>|y9z7_-!!7$MM&Fcgzyi5r}iuqe7MzV60?m5peYzQefX$D`)5|X03(?tyhd_<~M zYk^3Ank}U<{PyvIb~4x+;-}u_HZmFvdiQq%fV(5nR)|sl%XPYzGiZWOp-!VL`Ca8F zxmLOEWeZSTIvzx^Cxa5unjjA)RYooOq-J*_;mh!^Pay~YY3PgJh^;m6E4K)X*5do+ z8kiTPjIz}jM^>9f1~S6n$QRHJqzcu*6jF9Cnb1T!uQg?5)0yZ=_{3n(6{sKQ$FP8#Xu-NN#hcXB zbqghvE%i9dXFSTm89I+DP$95f2og`_A0~Mm;+!soQko3GuS{yVg)_>N!Sx%j1vYeY zjDHeg9opN+@IsuZQc<8nAgvZ%s7BUTcGKO`K#6#}ku~CpkLf3UHZ%Rya5fRgEt#x-#j;uTw?)qEm#{ zg>3p2VI-R*=lq1PZ-t{ExNeAkE~*WC|B_yJe7S+?D5A`}dZWBd!QB!lH+S|5FL@h# z7uQI>!Wd4@jt2myV}_qsmgV7ESHa(!$^@kP9xH`)BMr3-camqbD*CZAyb>LdsdwkL z>**G?Pt=r;f_sJPUSb}&B3+U|pk_4}C+~QjZ^B*qu?{VfhS5WjsYx%hwBcol># z5&W`FHS@_NL~RAvbCiXNV|oe^tDjjo`GPA(3`UJxAxSf*e_oGvWzqUA?9-Y=v)NWa z7nKG&>cd8$c%@2DX1MQu!$dma1^vTGo`^peNy zlG|66(}-pzVhc5=5NH2IhiedsYRns>nzahxP=Ewg+Al zBhdHxmBlS{$&l_4`svQvnb;#2>~{Z?A z?4?Ji5U{VbUX^LxTKaG8jR+oWMv)K3cdp0{fr_DxMNV< z1gI5--$HeVdaJ4a8N;@ai#d;I@XI(*os(N@xJetLO3#a&!b1mp96(2N-38CnfWfA* zKG1P6a%LzZkiWJ=ZR;b`M<5Dg#J}iN;WYs95 z=VTb=Ng@!WNT!;d?7^w1H+~UgSdNvs@)h-_v8t>{sQk0M=sK%&586A%kvT#yj>uvUD*8mp zjbMVbNHeQ%-{&SmAwMSgv+a0GOyImQ!t{H7Z%h2qDhxhHMa)wU-c$j}ivi-aVqM@$ ziOMaIe6i&Rzr0;Yh(qMLM7g0M{rrE}f&*~gSH4;e|8bSIRyoUX*d+knE}yQ%!OENk z21E-!ev}%jq~xDWo80t@;|B@v>$90sk=7yBK?FW})wUxik%uMht%a=wXE`BB%BX|n z?m8Hx0Yl0OS&74$SIY`>q`ND>*p~tdCIO$fx>+OOmI!h7+rZM~bY#|F9>Y(=XOnZ2 z&eR81y(Y*vIcyCsFtS7aGC-l3nts5Fehc=0CQ8>#VXYU#OSm%Hz%lp4BmhuAufGy? zqYtV}RU?h_A%Qn+)j>A!=uR-9F)hqN|}Z(;OSdFnQYFU$IXpxx@_V z+H47v@2!o-6z}8HKDosXNi?H&&3INJAy4HgLB~$TWqArk#)3z4yMMoAE)-Mb*FjYc z7ys!o>^HO_jw>pSWenJ(p_OEx<0j3d?hELS$2BQ4pWJ}#~%Ji?|)Qf&@0#htwP={vyG={3bv z!U|=6VQ7ME?y%oiw6WQ1AcJ@JUcf=(9^tDIvL8YW5lNrY$(-Csm~$f~@kFW1KawsC zb;9m4Lh9sEP-U`}JQ`5fchn^qUX^z-#Rxejb?{im}^?qP5B+G_9e z@UAWN8W(3MZb>9rySa~qFsk!Xv?!2Cb#{eUHIj7c*}ABYW`KlqHSSf1BUX2~wW`OY zC=!9QmNwvx(IDyD#n&iM%3UJZ>fb@pTA629RcRspovI1kf(w6$ox?XPDw9J>x=mJ5 zU$n=P#rC1(2|~v;5^G_lp&tZS56xNeq>NXhDFVp3KgOWZz;^%LM;4wNTG0O(sEjwrEM``&vsW#SsQ(n zqrM}wyw}=7+^ISG-qwRHwaPI103)swaM|RAC!ke?3PwRCn)a*Jdd`!=!@f2GY|_K5 zGF#EAQB3?*Zq^k4`y<|v!OFbkDQ1`OK~C&zR$1seOTl)Kty;sY0^ z&lc5XrSFhtr*CCR0&5ZDuoy|h?X!(Wa`mP1wx5{_1ActUb5jBZ0%5Ze08Hi*6NB=! zc1Bcj2wFT333x8Aurz!SSEdkKVjE+jPql2e7U@IVH;xD*OSK6H?;--wNu_(d6B&}~ zMApabh{k1SS@9oAM9g}}l4Z@F67CsjQ_Uv=p!C z*I&7IL!!P42IS)d2LID2MCQ0sC^+=y6BIk~id<*ckEaqlw!B%<44A_9R=lsjwTF=! zExDn~#K(N{3^RMD(t%vBVMxF19Tn{4;1|a(nQF*mx`7N%R0J)4m4lKHHg;BThY;+I zd|bcpwN*CXg9ALbt`H2%V!1IlcqagD&o@s}iQf|`mj#!bW({+1yG67ZWnE!Y(q5S` z4>=@>cz6PbFoGEt+W#gfh0++@Lmhv$%&w`mrykCUE2*M0qSIOak)S*9eDRyLrW0Pwadc;H*UyDT-*q zklZ1v%*aH&`5`#3rs$Xu=Y~}7M?0Ql_;<$n=~G`slsRtjbLG2y6D98#%iI2jk+qF zV)pAY*CvMJ#-;=uWX%l~yzV=*_SH$-P^SOokgKtZ!rU*ZWWoxNP2Q6mI71;%4`iSz z)Jy-T!g6Ey>?bb9L+StaVi(r-T?$cbvslsb+S)BhOt-BQYSOp3cQ#3!iB~7@A?=5nUR9oU|)* zdlrorpzV=Ro3!t<#t|6c*Z)1(?y7#`tR74NgQv8;MRtZrg*~4-{3ADeh2E*s+Y`1X z!#Zvu7PN2qQ`y*hI%xFS36zE8RjN)nDb@InvP%7=3Q*|OrXGkSYG)b0Vs~NA^y($F zzy(b4ni{3?A>n4;R(YKQe%Er9?NgETr8&T2 z?B=>Y@0MJtYwSVg!qXGHeq7?E#-ghTkCmQ-OrfhCAEN`R3*NyX*9&T~gCeDxvMkm; zgN|8IdZB-X4hxN-B_Gn?ly|@zO>B? z8BA(fwPTLsXWW;g|5G9Mr?1m`ky)=>`~Mv!#HY5siu>D(5?DoRL+2 zX^fGnd%#Q>2fIoMsOO>RB^%Bor;>6s0JF8eHxx^-C9E4(g!@qpNlFT~={YQbi3TYf z4Bzpw^~DHPBPFg}MEl3#)jW2|$9EZ9lWsQisz3Ldavqfc6SRMt<>;=`S4 zjJDyUv7stTkg*;Yh!D=GneeU^8|4c^AuTLJ*#3A_uo=31-0 zBTYN{uV0UFiBErH=jiP>@W~iRi1ZYXw1WK3{TNk_{B4NAO$!;glqZGN)f07xC?@8( z)X{|NbbUdEWQ8$}IQ0E(Z(K`L?k$*G3sQN#WvG{s#~5E2wmQN9T!ooejF8F}&EvX~ zf^Z@B0?bdgp-*~O>fjZ&EGmzfa9&+nf&)&~n2VRsfSRRP1#ae-r6o_WTr|X!)FOc* zUD9~oC5!_dliA!&^lB#`-Q>(Y3NM>{gB@0V)d$#eH~|bWf+*Wq1W4Qpj3>c7a0Z0R zuF*eS8+~vheJ79C`xdqSIFy}n8!F@P_v|F1CI$o=QB7Qf)LR90$`wOBMbgRgqB|iG z#)X~~$BE9>%K?nUD?~hZaN3)a+~Bydu~h`89vC;TYKQwKL@js{s54-MA@OA+3#in* z@^Z>|{;EZ4*vB}eI@4aBU4eGo#9-P#D)4#$RReLeu2u=Zm_w4cL`v|T7ZN`{QWwo$ z9+MHDM|h$8EhSuC0$A3h{4W}&m3_(s7nUycHDEOWHx&rR42H}|PjFY2qaIp{w@xob z&m6{T_Uche>kxW7^L1pcHxE~$eAS~oP6%0HqqbyWwxSoZDF$?MMMSK*XLMRxw<$5I zV?ak}5N`0U3)?#;NEv*_7mY_*x8is<4kBPD!Ys)V0@`)&MEh7=w^1d??MhT>h>@I7 zP~`7dZi>AxC3|4(Izo0NY67)CQs3ZLpJTz3aS@`RFU`{gO9ePu9&$pq>)i&s^0Fbx zI7&t=Dz$IxL2V98Ca@W7{z{f&$pRx6GoqI1nN6))ELXy)(st054>}lGApt!7V>B|y zLBCafsjMrX5R8^4GJRZ<7docR>n2%B3gK{1BGFXADLuuENLgpdE`!AYT~TkE0Cd5n z9ypzfcBrEb+PZqlDo@)2+dS&AL;yy;*U~hAWz--(U8qiwyJR0oda&{x_C`hGmD6G3 zsL>N{>idvLr)c9MHl>T^eiW&yUNYJ14 zUBhP5`eKzgEQP9qRYD_Mv($byI80<;-op<&^_Ck*XWLUL|2D4QyfML)55a0K&#<<| zMG{0w-0G_V5JFArC^Up9GS9n)M&3A14z$M`wxpip5h%2a){KZPrKzDeCd|<}Ofz+3 zO^_^mBSz`r0=1?uSVHwFwUpF_N`1!eF7f%uVuqr{Pw9Q&c1I1s<={x#)kiqsm%kal5(bzETJK#UgCmm}YCgv)urJ-8{frkNrJZs#e$0KQZGEKpY7Umg$Sr@m{g4fr=Zy7RXbFpRwc^9Z22vsJglBX ze2%HxjKi+=PS8{-u}5H7a_mTk`f=O|=lSZy&k8gosNM+rgiNt#pv0TkL&Bal9M#0f zmGUEX@~kNq|H$=p%K44t@m}PbK1m|9nP<>}`O%Gcb%D{3i*KC3Jw|a>kd{J8ADrLH zUB(Y~qOfU0a$}vcGv4Txy~DD=* z3V$u>$hK+>9gs!4_%8fg5RxLc)rvclh+yxjr0q8mLQMs-E2`RUi~b71x?>rsY!N*1 zk6H2YrKC(IVY6={_A7$3^>Ur3y6oFu^>X*u$0d&W7e~=;M$rr6La@d0#CXMIGRVbB z>aWj?hpAh-r4N>JuP-ou(%wbtO>Reig_xCnG9QE7r7}><3>uV0APK%k4DrGg{2 zDDK~hR?H=y84kdqad}$@xs+4+V@yhnH>oon&`#bGTtt_K9Mh6+bIPTq^2Y&mK&vZh z_bVvxiw~ji##=t-^n{*x`IdamM2{WGRkXsB0~EiSIg{4y5&WB93=ROGu%$;R;mZ7N z^5}yIu}nggB2jyI6y3c*5CC`L+~L7;~GNSCdg zt8zh9#4{3EX=tlL-EccyiEBu56;ZhLyaqTihKZmh{!a<4Vbc%7sz_lWwonMv=!C%% zi=2MOu9--(C@V@aB+V;<+I?*NL+#Pw)$A|ilctfO*44k2)(8P&cpp3!Cp+ul;)`{H zKu5oq-U8@2#?#bX{*^TbUSQBq{zit3nwY^S3IeDUq2ZjC+jW%1;@K`YLKuoVTjp8 zz44Gj2szpa5(M{#tVj*cl`K0;m%vS2uTZQB%eB59)0Kl5=AVk_uJf_vjL6-jeu*-@|gaEl<2a0fvdpVP2 zW;$2t3+QJ-upZ)p`=ViY=koQR#_iIX2r~<{vek{)71AKmL85pe)zJ~hyLo3h>`YlC ziAXq-9Mxcc{4!JM`PnyVsq@m8Z=&9w6{e&_X7kfO8>5Nt!BhF7G&m+=W20sjrgC!f zT))q2z8}r})D8~-%ct0a|HZ5E0{=l(h|kr z-gV;CUy-{wpY6jewp=Qv349K5G2r(TR3shgIfh1Ii9t(z zVtSwrwnSdedl8X;Cu-%(o#|(=xTSEQ5(+n)xv6$tZQ3w0tB-5nQ?5>jkv+oVNzEgR zeDSLik6ctoGJq`#!CoM1Aq26Kn;4=a=vz*PC9DdhVHh9R20=wS(htBvc_QuMOyB|{ zs8S?|vWhZoz$f54LvMQp1~FJCm=w;hX=cG>z%Q%>YRP0xy#Q^&{o+z`f+22* z>jKJ{8^67e^+rkT;Ym#?9aOHmP6T9ooRvyL5Mbw)h$A1)>_RzfTm`#Cl@q{>38#gO z#_y!DQ5iFUfIP-?a|-Eb!?$wjh+!Xuk+?ZKiUG8=8_2%Lk4S2ANZ(371E8|J)YCp- z5&|`#f}-=>1r%54>tIDz7 zn`eU1-fH_i6wO5Eqp5zEHdM4;V_B6c$v6{S$5wHCC7-UG!uuMKsSl&7h`Mgd0&w=! za^Cndhl_3lXHl-coJ-O=nA-3(oCKHR5(zl0P-k)ZZ0s+hl?h>!S}{uNjbwv}AR^+N zs1XC;-CUR}9dq#lK%{%XAc@j!g9fQZWG&d)=@LYulocTa^NK<>v2gL_=^(2$P@UB0^Te*6ZHx9nD)|(VM-6YthXR7Wq5y(U zz(FS(P@0LWfy||Qf5(>5>o`Luvw03C_qNts)f=3C?dGef(23oA?ywYT3GPM}vy4Fz z`T=m7X;`~kQNFSE0)AGostrYKpn{|Kwj=pJ866tfBY z-x7<@L^;>A%YZheZD$2Qn|;$c zf3cWAV)htC6=KLCZ_2u|n1{ZL@r0ch3U2>aAdVph1&4@bgn}Emu5i4P!0c67A*bPx zxPa#c^$YXu((h++VXQbBS@9i;79v>C>y>JLZ4t0IkT?j7P<5krD>l?RPh#>!;|1MK zbg;|O#(XIJ^-Sg&Pw$(=3A_`0tMUk3*(n`fdP3mqQiskjA-?sO{1SD_1GSLDeb*X9D(BUcI zSV<7Il$|4-j1JHp-QaP+cCM2qSaS%jgu}?puAJG4;8dYA@w~Q{Mi80!$Xxa=iOz>f z9072GxZ~m2EE*1K;TmbP!yNpio;=$`5$O{P44c_LTisU(oawyAdo2;TG?Y-Ba~4;T zpIEkXq1IQ#m~?((O-WBaYoPyxYBBMB&u3IF&KNP84vw`Y5b#&Vw>_d8n@iakwLa4` zH1t;#DoZ4lmhvHIl6f{1$N4rI|Gi}wR1QR)Y-bbOPcKU(B;;?#7t2b7RlDhTfeb%} z!dv;Gil9ectEczXHl69HNxDj269}fU)6>T>!Jz2srj91Hiqj*R=FFi@{xKfz-v%X0Pmj?42J)?~n(o^>|?x~=ye?qXZ{jec2 zAlWItE*}lm&rzyVgveE6Sf@m`Z%Y%D+aRIMy0c1of0_aZVk2dz;Xr%bxfuLNBWyv# z4{i!84Pb+|3`nNaDqk|~l9W`97GGhQG$bvO%3Gb=sgbCEM}hGvZ)`z!tkmI$1Crq} zb*P=zNvRj1C2Cs@c|9D+Fh)^hqmsdtrqfPRp?PO_>S|00-PhJdQm0JS4L;Hx4w|w{ z>Op@YQn)mg*VuDNYT#E^ZlIihMcwh|%ZH?*NBvwA9lHp(UzfbkNiL$x>4hmC{uw0O z5+X4dIyU^2ibGFXASc+}s-d|94OXlS$p~z`<~^&iIazSVviIQAKuprBIs>R|HyyLi z!F37NpQG6sMLAS}kh5mp73jw*YL&Ku#(VMlCw;V6cvx^bvnn9ZZpDjERHV29*Ua_F&xE3KlU4C)d5Ya(J+ zAf0iZ+S$+`g?Bo7OyARESWm3X-yECEeAdFJWKCt z{b55nxTr~Dca*Q!myefJ9Wjc$O^i(H{cS|{_W{G1T^SN@HqDr9%2xZ7>S@w`jlFI> z{Vxm-owP>iyGJL*45Q+XUR&<9;!{- zCj_K~`J1Qds;jM>mPXwHT~2V}d9dE*tj9S~P;6MP_HB5&Qt(#98T!XPi8E74Yp>AM zAv>5eD&UbfUG4j&S9LzhEk^% zMI}toiB~eQPkfT5c80`?mgJLdWgX&m_}|Kk=A}p2koHlK@t*{xgi7v|J`Giuf}-Gw z;q)lV7==MIiAQi)dIhHBg7ZWvNkds}7aCBx=YJ=1=159-a4K{czJ>sa#h4II2~Uk3 z6&5u>{7e3$bM#`5yPU2std(iNqps2H9x|xxDER?96BO~H9fzmI0F7NFGVUf+G7;o- zHwe|cmC?<4CJI1T+5pk#>^LI_VVap=rC3rCvHWnbuj>ToIW%BVU$>HI$dGPxV6-7U zRKw-?Fw9hD`bX|g~Ca#2nZA%dCoA~!tQR}sp=CCXU9IS;A<^=?c zWgFV1A%)sBbzvf&C^4B#?zSW(nF}+c6oKUcltNDKr)^^xldWju z8v4uPjzx0rKxzI}r5nzRu-eq;tmIy3uAWA*^QCMw1vZW!c`KDgSwU*by*Cqv% zNn4qu)j)7kBkQB2oT3nH4pawFs54?}o*TP4%?+X#>QFAV`h1od2p)4XFgG2p$XP55 z77rp4CJ)B`j|daGFih5^oSCO5exD-6L{$*19(KP3Os{a71hZ-K+C^Qy}QkfGFuVC{b zn$vMFWqb6l^PPy27(&Sz-#fldNoRSR10sTP&Lh$PLngyZO4KYO;6Z5oO z8GPFJwlsATM`ff&&D-)qYuvzLlDEZ&8Ij?E!+*}k08n6^vK>`%F(ZKzi)v20~T^V8hdza=x>b~D5Xh2t4?1W1k zG=&8QsA9CHgo*FPSrJ{z@fjWxO}*CMF}6hX(ErDDD0_E=6Pz%J*i&C!4$_ zuIXtAPgQocUnJ?7a4-^d_qbRn(oM;GQnNeKzu3Q$|DnITKf^!nZB0K;h-swcJKupi zJ^al;Dm+PoWsE>L^+jGX@aq{w{WCNsgnJ^;si&VN6y?xolpJ_Q3JvvR%hB9NZA_IF zr$r4K&Ou5sk6t5oA&sgs zsz}lJ|ASF{XZMcsmi?6vmcLYy;_&ZwCmuS;x6#Eav6*{WfQvqa)7k+NiXfMk_o73_ z_(u_97$sWWMTnC3PZDnYg(@8lUU?)HwQ9M|h=D{^@G9wpUH5VYUmKqMa3A4Cu-x|zBk3%5WvK~yoGn6zTvEkVq{z&ta`fzC9bJKEcYly zfij#SQi>RtktWzjy>L>{`Rgx5mJg+A@TGCx}Z(PWxg-)Cmbjm_HmxNFno!zoYC1) z6pelzs0L5)&8=DOQQE0%EnJZeo%ozi!6O5ZQA)K#8(`Af8`-VZ6kU1Jd0ABlBa8Irfkx} zt{NI*vulA$PnZSLUZT;Cu==S_(?d9FA(Cjv$YUVXEs+LtC!4~Et|EO@h2(Xg;D&-EB72hO@6e;Z^4ugkkei z*y6m@vNAhkA(hlaQ1U*Xb;-$pb_tkI)A2@Gv&*Xqv&PP4Sc`0Sm#Jm5l_wK)SJ|~> zeq}FM?X2AHSTvFmu`IpWOvk02Ogkv)T!)=ll%LyBFHl-5VsMj6&e*EnMrDkL;g@-x zO`_aZ(CMlVybQFi##1!7d*n9vXOo(ryY%FW8la1?W+{HPdqG&u|1m#|MPV3O3Y0P_m%&k*vB?CMoo->Q{0<>dF(Qa8;Z$rRkf(<{ zN42UW$TtKQ6vqpI^x?=!SRnY41Tkk;txr2d7) z(0n+PL1{_(VJ@I^HB1?{JqQF7p>>(5q|;GWBVTXBg4V*?AizzroA^ux zA2{4u1)J>zxXKb%8ZnB3GP>y4aZ55h5k552ipkB;be0NCp3w@b!c$<*-xX!ECC0+2 z)>GCw7?Tie{qE-SG&q=>1Pt%2e8y9qZHBI9F-o%0B$%AB{r#tFYGX1OzRFBvcGVgM zbp$&EaonL*{BXC!$8X9+XGp*D6>zJuGc%_ z_xb3)|Mfu}8R9%$SQxommBC>ZQV!FLf$y)PO@UBM#o;tc3ZEu1kecE3e6<`bnHduA zFC9qzjk6&|(Jwv`-6m;aWMnn9pWKwzgatQO{eo@^#b+7i(cm-9pu^xeuaB3>R0i*|w_z*}z>LIyXNl z6y7c}oS9$T#EU(j5PEy|$JU!t(!Df@-iwe7^#Xjv+CstcZTEvX+I#jW2C0jaGp@qw zw%0mSX_vfO0^MfdmZItQn==DpmhvWiu&milRTq=xej*mpYt|+CQG=Gjh~{&EfWa^F z5&}P0hE;8(v_pGq`zLIaZhG7Va*dIRCSiPi(0!(`T(8BPONpm6RPW{{7Yi}v68S&d zI|F+BGJ6qv8H#oM1`_j-z50EOJqncQkr_#NnD-%~YX z{tCIcm`Q~VkVO#%*&z_C9U`)`MXmEsO>zk)Q6qhkKj8xX>1zi+aEVv=QP4}aOrl}g z7KF7=n3S7Bw>ICV1gLJBaU?X!;%!~AA*@W?oocGqhxEm1sAffl(_dkFQV5%w1HI# zX-!%?A}kB2k5;E@NLQrT!ucIBIYC8%lALTR#tVIBuoS)}x4AYTm@bg#Lg1feje$jO zPsGAgb(C+l7&h}0PG=;tc8=<%@(E2b3M(?>iR+SbrwpHXCR~k6y3;EfSJz!BZ{$7{ zF!uDvd!@`BG7>55WLM5HN+sd>$4Gj7}O7g;Ilaai!wrFE6P%G;y z7Ta64L?x5w*S*asO3><#R&b~z@=VU0ryR%f#FTVi?x(D3!Dk^1vXvwkde?^ za8k#qx=W!jrHB6idC(y+AT-ml4~+Del5aj@LGLf5^_+Koync9Rg(cZYkGfGRv5y~5 z@tT)QKF2%NI8}9O+>_*)XrM_e5^cwuefp%2Wv1(Hd%?)v1X{){ul(sad)br;570 zv~o<=d|c_b*quD#)ZU0|yiSso%F|>?**j9V_$WoMp8T^fNT+t9nQq=?>28@G1#3#u zJD;I(WkP# z1M~gYJ0Uh0v07}ZY>*-{Y@kGWr({Vb@IuApJ}Tz}-(II-LQ&B7NsmKX!f%KOhJUBn z`69vUr$j6W4&{XzI$P~3ZOJ6#Q+A4CF4+^$&FBr>lZnQo_o$0mNn`xSL$8|x5ON9M zgc0IY<;$1cW>i)?|Idrv)0Q+C_%C$CMD~L!Udp>@yQjml4VY_mK3XN9H5S&u%6da=m!g>S@6dj!0A_K@C#_(7)lSnPS zX6b^i#Hfbce&t!*pkRkEh56H@iGx6yKy=jY>a1kw2*DolL|b6B`4Qrd1txZr!%HX9 zWx;rz7Q{8cUUFPv#L%&&`6Wtf6AmbcVX^|SpEX3ulPSLPnC56Sh6syHQ6i0GSDdTB zBGY)CDa7+6$3>MluCd9QrW#y|JVG;Z8G%Anrm^72EYQ^N!+DBMNPS3R;S#)aQc5(f zuRn@fy6#YjC}Fs6-9VvenbEtmVYVWbjS_l$K89#QQ&kYi?t#hL;DgMacPis76=t4< z1Ut`z78C1g`+_MlGBBd5S!vD;?N>s@?^E(APMBoiWFVc3w@s+LfrTcx*!g5AW zBxCh1EJl8WNoz;mmG4mSK{jcGlqZEMnM7x3*|N?ZVP;PKIq40v?QeI=iQ}UG#7+qW z#)63rW@@0=;DO}f=^LfD7kY$;cS(mULj({~OW8^Kv*pi6$5G~O;WJUn#Sx6#f@*&x zD$)XkQsdU>R*{BQBSt4RcTcH8@d=@Z_2-=!nwp8W|H3)ZMey9kBj~eZw^3)(`Zg;c zg0XA#ar1jk$~aZj{0q2=1nU!wh>14e2kO`p@$71@kW8v%3?xf&Ayq+CVff8I5sJiC z9L$FAt&LsS1wdGBKQNS$%=;Jb>g4^qaKQSiB<7VuZiI*yNrUvLR+rX#b584!4h6;) zl9bz@gj_o0?mtbP8c`7>Z%lt(v&G9qE7dZ^tQZ(ZLG@+c@R5rcuD8ZnX_}JN6UvL` z>(rcx@0#{c-q7!Y5hRPhqm z(8iQ{+Zx@LDo#NPsC76Umr7Piu+5W z!$?S8h%?j7ZZAoTct{nA?%8^B#G#2)Q3&#m+!k+#B`)b9#{I~R*c07!k2P3LbKW;s zsK_2WA8(m*&;Iv~{oE?=eN?5)rKV zJa4c{x^FTOymPA}iZ=Qrr2f*$Z+9ftEqpmyrb~{=v?nB$y7X+QAxWlRRYZyVN0wuA z4LEc^z7|p2emityv1iU1MnFKBD?N>OOV5NlPN_!PT&zoqyY-NjktJ|kw6i+qmMd6X zPc&&n$e1G~AZur-NjoTOl-nd@LzMDhNQb5A#Km0QQrk1FWI1@}rDKRuG+wozi$)9z zq>o$c%c!@yBAcegv3Jb+$A}86^EZxbeJVtq;mniYLb(z0i823v>3;K=iWj8zCezze ze2sF3+h2T-&oFw_qP938tLo&VY)T`ql6!K*g2HDvPRB=;&e=+=ZU40h=*e2bIqg|g zo!Q+On`niAMuQy0-9dKwD5Ft`mfpyj*BYOV^iX4&Sp8p1uxZ`%EGNYWYO_sC_S@eB z6NzI}HQKZ=PxmOfRGx`}zsbZYWNhHKcD1&43I|U zmC8wwQ=f+|CVM_D-=tWkES2BNcPRUWi=?hMN9!0P;kbs+X(EP}w9KLBo3?3&_xbB+ znYFG>JNuG5HpP`*=A>xtM^T|iT_3&3;uP^$WR#m~csu zCg9pAJn0Gfbjlx4aKUu>^i2`AEQxTl^OpuYx4JNsvABW?3O}?6y%A)Nz51D^l8M}< z!e|6M5!KXWdgSCFsU{>{B;A5Qs@dSdwJI!`GaKMTa+HGl65TX8UG(lE#N$wb~OTS@&S;y$?(Nx4TPqgGgCb)=ji zBc|FSB2bjDHyy=Sjv}zMUMifSE~2C?uyqxR*qh6dG2%ulmV$}gN{uEmDmh{bI}yq`CEW+saKv4km;F;68+4Bq7?Z%r{R@Vi(`5X}`bkMf+8<8A67W6@fT;Y*MLXHaLV8l?oP-LO)>%w!9R5 zsAbYIqV}whmKfEgF-gT~MMpV%93E zQWco;BGXWUo@#PTQ7&d1{hC91Y?VIKOmM>`cR2p|A*|IE7oBYz?d6t|6}cx&=HDXX zbwlmRRFbp$^6BW|KF;a&ZoOj^Bv1a@l-#q`nr1X-eI>+%p#@YS#INSL0}yg{Egm3Q zB0ORjMW`IGoIPbSN?9#07n;npw-TJ>SrsVcOTd*$xJ-o7EUoCA?!f_NZ^J~SQCP&L zW%3*|g(;C_>VQxaL}ak>jfT`sUk7+WNpc_*JSb` zuT6_LpEVeJ>1n|aRgcg`_hA{y8RfKVc_LJd^tAk%1X*VWaMj4SRJS(LdrRwSLYrND zb_zz>W?e>Nl#S}yDLSII>Ogs2c4@b-tGT& zms&+-W~c4mS_zOzh0ux;VF;Omo1`XBi`q`0uV|%8dE!PRI=@+SB&J6e!G|Xt=duxi zu(J|EmOg%`(uGT(O=+akn7_2;F@2qeFs%5xq;EoV&2vjd+iodB`<~Nd{`VxdGoSM4 zH&|Y9^WI!%EV!%7o5DqkIdrFcW>Hqk-pjdm=~b^q<@Ilxw!o%~I56Zf#%5ztJxG-bx?()#^)1#Zg6jp0o7+vgD{rDL6!wIjAKfaYcGX zENN7Uk@h0*qTQzm?Fp7bj-z?sUu21c==Y4KNJx{&608~t;PVe~9CL($c1Wx+I7n%0 zfuxpb@?<`IM-hkUAMVA7GF&Z2d~KyuGn zgnK3#r9oyaf>J%cU`smOy0##$8C0Tc99eZwE*@))xK1pr7FwW-OJvdRYY6#1hwzHP zvTbZ^vRq37JH|y8Le1eUYF7j^0}epOpfxih^#MezQARe57D4ViyJ*f+l2%ZE*m110 zK>3h{3*QtIC&Z#fTN)DVRJuTz7eNAPBq9nTG&ZPEkp#Fd2r;%xpjA1orzv2IISDfy zLY$n7D6}x4Qj^5>nYd%>kSsxdBH0OU5GSU;XN8_#o7#2@WPDUfIa&41Wf|x?;p*fb zt#GGhT*;7MILgeaAo0t*MKpmh7{ii^IEzITC8f2bt`B^ml-iW4NvOh&D3UfBVM<0L z4)t;nk_+P0r{@N9$?6lWWf|B}1_XSUYIA~tkgl<~6dcP;xjp)0j5TSspzqZXxgf%P zzek-vN4V3)`0ZxFs#~%l{$DhtL4<17vPP7*J25kEqpiw2#G1T@mrlJOEA#q78%L_h zq&8qiqId0HF{`3gRW_0I-G!wRm950Vt5Q;okxm$)lA_Vc)G3NW_`i5cTSe=N=f24? zA_La4pD0Zi1)R$Cr+@5!?SJS03!sG> zKQSUPhg^MoE#wksuu;o*2AT1HPBoPuX$aIgqsK&Wu-1=|mMJ>1W05%%nQD5Lt)Mq? zkowbfmJ-@UaS)doWu=lLg%Iws%W7>l8>%(-Zc;94Og~UxZIFnSwoGzFg)v6{zjHDc zk++l0QE2|ZXg5$vZxItJW+c7B(bK%7oq|_ck%?4j-+55MbA47y?2D38L~6K261Ds~ zNg~EB%NTxSA$-*v;eApFT2xk_XTu$r3qy#LGxp}}718usBmOm)vR^(VS|bj@`(LyD$9FNTjSF{3S%(9WB8 zt7WTSTFttST^Q4J@yxmWE7D^W-y0mAw$iPKrUY5qc}M4yf?g9=f$Ro^KGaolxx-Qw z7I_58Cf`M`Jw&eVPe>tZc`Qqk&w(TUoC0Ty*+D(*R=fK7^lA^=_7;39QNUU7<(KHHT2`zQ(H<`Ok+tr-jz=sD$#WY zhhHZ~G>HfwQ(0S2uEMoP?0~~3vJq+>P!4#q+iV=2d03L^`}Su{4M-b6+^rD=1jG$@ zD@PF&a0PKAwN%`-axGiG8XBM$n}}v3-LM@2DZJY6sp&7!%V3%>=Z?kbHVF0U5q81l>^0F{sg z?6sj>8rR+lm>x3m49YoJC<30|>SgE} z@YoOq_reU2i0_Wcc9!LhN_!lGS1;-6Iag08h&@%A{g9noI{H8^fG2sJ7oKb3-rsB9 zAJ*9Z6n1$?X(6j|4XnGN9F0g2CLS!KM$Rp@p!S=*{r7o2Y%8GH@qgaBv7oL08{ur} zx*+^q_{T%9(Ma{2?ZuQ)mHRQcY@>Mc|JuDPjElA)%jiJ8@v z$1F|X(_OLp3Nbr5r=6+o;4f0Y`rk*!OZBsBrMSvdyFIPgWbnP>C)#hrsjlz<8(S;A z^Rs^oe}CdDuUKw#x>hlhv_HvG3I@b9nvZQ>*W7Y>v!&^@H6V4y-VpU%W~Nc^`n|4~R*N5V^$gtnN1zA8OGnM$`{T#!43lXj zESgjf#;2%ZXEOlpPq!gce$QtN#XM8JX~7f5+9y?fnQi#p-MrRxe#+oT%V($l}p4_U8!Pig6 zjx8VpSIPv9m7&ew7uM*Mr2^+%O`BYeo;HfNXuNilb}dNn=%#k=LB-6K{Wx9_sd8@{ z{HkWxm)oXa=k@GV5+pzJe zw!d*7uSQ+tq}zHQ47|bsc-g+$*_|Krk=rtHd}EPYlZLHH{4cS@Uujzqe{jVRp*`DX zbQ-^q;ePbd0Ura?$ej$Wrv9w(IE1a@?U&t(+s1ed$Z%16AB#>Wf91CzCseT%D{0pJ zX+-N?+pA7rA3VEAiEKZyqa;dyV@%v1o@;lPnME5ecoF$g;&{00l)rIHO7@oDb%ubI z-XX589lhK~?Z}?pu!FvWi;TGhd$n{w^FTq2UTBXV()Y-p$W?7!lm%Ay zQ5sdWGwkfstMyGMg*u5R`Z-^YiP!SH8VrBRP9-_ElFwt>!=Sh#b7v zY4d$_rR<|jsND0dMKyxj3GVttw|J#H^<*S=eP=L5!}JeNeN4}@$*P+dyT3)&9_SBT z@UJerxbYTM_?CKCO=XL-UmhD5oLqhU3y-n^aa(&9@9-t->Ki|qFxs)1H%)?c0rr_y zyZ4)KJv0Cu=&AS^hX73oS*g%tMs*g`aFtcmlef~VJla-XR-`$qwyju7!Y9Q1(wwFZ3u^K4;rZS+B9I}#hS^Lf0vo)Cv`qJ z!QO-sZwg5^ei_}B*6nen`hewx7h^wtYsi;#FwHNIhj!gu=)d>O_5*3<`%yY zPoZO?R*=n&hevjo2(;eNdHJ^8J8sVRuKf*lFk}YDQ$C$_F>q7SzI%98h&a#R=KNo- zffTz>f5QmSAF_B@4>D| zDVcV6FGzpYYIKLb=lS1-J*-t>9b5s@7u#cjY3}cB-HPHZ%JA9|j^X(wM|FrT=zFjK zX>tBkfib_w@vHPrEZ5}hCDGWcR;O96=~s^L$oqKcdG&c^?aW6Wv9-XsKpuc7ihQcN z`;l(jm(RO9cUNo7JN$0Y0fYD*>eJqiY8f-i>O+vD&Ywy3A9ahST)UCcV2pa)gY7;=Bevr=TV8ffgqKF8_NbM#V-R8f zj9~LGH~UGatgEzEhJPsBZ98@#CQYN_a0wdyU}l z)A|^z7J$Ll&$Yved}(sA`vmH--(z#TCTiH({?p_+=?W_$Qb zLgWHHkW&%OrM-d+W*0$=|Jn^77-MBLZn1u{tfKi3`Gt8sYNjg3G_J9tTZ#j0I5XZW z_=mF}Ly^~SAH?}b6)mdxAW6fm8qMaz;#14Sp#o<`Evc)uJImn%d;vs zcYXECY{i)fEK%2L1(7g=;|N=_D@N5wm%|RVUO&;BAq?xeqY;h0OgzMKdTLwEb}u-2 z>4ISS{E5}Bi#I|~M$!+}Ra#P)zkf)>gkR3?KU8z;{ozj+skW_}_1#`j`k&nEn7WDX z$*zf3<@U(4jKH0Lx7~r}PL-o$HI&F%Sf^p!{g37U8Qi5@-1GVlzK0^g7FdGw3MMRF z_dEWdPp{qJ@pJCy^v~x%*V+{AH6?KZ_1K}h6Pl+UB`#>*1I}+dl6ehIRL}KOk8DYF zJ$>z`1Gnqs`E9go>D-q@GqGhwBqn;Vl%Qn{z}!AHm^;peCuBo ztB3OK(n^sDHnMPK2^+$>KiZ#*_^-pUIcja*U?0{x;eJ%jF;@lF%!z^b7{WZzDol92v!_N(G-G>Ow3RGn5yhi|mUziFrp!k=p%@?vsr#JmD95zn^j76ZgKKVG(mPnU0Wx`h=~M-S7otQx;~p=jdCPaLF$|tf zy)*~PjXpD({Fvx8LsKD)n8o(t4o zK^e6Dy3?2FVXot*O2%rLMQ%d_CmYT0Wj_Yd7F6!f zVN*h;Tff~fXuUX>VOf0yjyY%zAbcA4qB~XMQ4WUctoe7}ho-JKVlrs0|9miV<(yiX zJD)e5G#0~}1S!Uyw8q)gZmqsKq005AqK0;t)#Rw#E+!j$Yau6QnLnC?lwZ~^zJW^M z6&nZ=*z7WM9M{&9UNxLT0hU82n&I&3-Q#>egYSFW9zXc~+yiSaOdJ2(CDE2-1# zz$5xlcp79HTFeNz$>(-Hs?_K%_<)8yb5F2dYhcFB_rmKNkL&yHipYDGar8kEAynN$ ztoFN}^Fym=2dq8dThBTSa>Ou)Nj=Eus|)6EA6Tt%qW8LV#?*SddaRV0h+!6tDtZQDW$2&C@xXfSD(2m%y##ODY{hR0U z!X?l}Wt)*Yc3h|(l5BI$pb+3Qm=HwTvOmaN7hFq#a3QJ-7xG&g3vy3=sw@2&KihA7 zonvAycUN_G&oDTUT|UOR@(}Exbkoh4LSv!?QG4#$nj96}x|eDeK%N_rq}U*2&W3xa zmlo&q^$zv2!QHO(?GE=wA70@Qb+zhyu2}Hj67lUk4Cmegxo{f#Iso**sQ)+`-(k=e7V<<_6_&$# z1TQWe<`AOGXc3dp+f(sRzCP{_*bZLwCVsJ64A{zO0KR{Zkhl4J5sn5s%XBSsU(@IG zH!fKp@p~qM6Z?god@n)~dF+SYhIN`ZIJ4tLDhYN^gF zTOKig#m2nQD#N2XZXSBG^k~|VlDmB=wbZ$_@72&2xQdH8pYiN~6S*GRrPIF_f%l!P4rHJgh{+2DSGksCJf&Txb zHXNSg3#v{EiW7CQBl6ufshCpWcn`Rny!cm-S#-Xxt;s#UCwr{2 z>=WeCN)0bGbihHI*=3rC{gnVrS1tN$D5gLeFataemhm*`+i(Lr z(`}3%v@5JT&Epc!D*d~R%MYAW$HU6u>OTK|>-zLvI6Ldj+hFf7cr;k2HJYIfk(Tv8 znGTVRhF0s8KG-;{9Gv~Gc7|oST4wX?P-&z4=z~0~W5FHS6Q8Xp@Y<^ zYQ0Tby*`sAqmf2Dbi((xJW}{vi{+Vme?TS6Zp{B++qgC4Simt}3V7hZX`G-tMto8c z;vIb$FSlNh2aO)g6uve%9M)9uys`aLa4XVbdMiTK%czmZTO@Dd{|4$REHMJtBe zr(?&lmhKR{@AmzI6uT(vPH#C~C*3R61jgmO_NKNN=NZJFBr_L`W_n4QG7`A7^qBCl z(EE-0V%G4i&d_%5Koipx-SX7NapETrl^27aI+OGv{^SBEf3&rK>{%a}d)%b0e-&C* zb86$~#;NsF>yH_+54`^ABRZ@;{-pi$#FbYGdmh)F3IknUN_@;3C?tz%=G zJ}w4sCY))4Ru5>+=EA;tf5@wW^qsFN1}#p{j{D4eKl>!6-}nR`Ocx|SbYtEMBP3UE z&jz7z{}Qny0pgfM`l@!;f~Jx=bT$|lahD8W=@%#X5k7U$_6(yfLri+v(1v^U9QgT9 zLnM^{(Lmd*%aQASh1ff16&HeiF25sz6Fq!h$C`NhHL!jGKLq*%eU&88a`PH>^zL?d zSPF!2>*K!qp>_*()nplJD&k}9oma4Q-Nd!D&^L{~jQ5qdd+*w3Rca(F|9g}PX-ofA z!FbX4Ww`}4y*C#2`m7V}pGusMa=+i+ewzq>RN|fu&+>Fo+JSe)<;R)Dj|(c#A)A7R zN%Rlin9GVcq;$*S6UYACeFinAyyx(#G~np)eSFLTZEed5`-)3TjrKxF(yee<=bMKs zq!U;WHX}NC5<*vfuV5UDU~5!~U4l=JnzA)w0mAqo}Oc-KY95 zp1r$`w@=EtJA2shy7ljk+xO2F);|SY)PluD8ZiQ{Ii1!TT6Hw8G(7^auDMVW&A(jq z0~`ggos-xWi-QUgzGWDZPDmAWxju7ETOMkc3-yR7@TikzKY(<)?KN*M# zCO7N`S3mr%zf7|#aJcr3x~u#pJkSSxws)6mxZ5z%^}LVhdU^dB68YrzJt(tr95;F1 zvG4v_quLpHrK%X4It)1N|8>yAl2Cf~kjHk+J-T-ZAm7iejWd-S+TSqH`loPU`V^G% z!>aUKxz^3RaJLJ&0nY_w`{5)#+nCMQ>8J0lHnr*_qD%=NgD_F8*kCuKYMBno^GPeoXV?92(KPDz~HtB^}#8oWqJ2eeD?n%px(dT6RRyG!p(EmdG~hoZrcE2Z3_b|8}D86%vIJO zI-4kYcOq?^uBW9D=zHMQ*RHD%Jwey+Hr>KiGo04K1Q*j1cstyu?#E-=7}b$#5rr{> zal-+^^m~=VeQ~7W)6~2;le`^YJNeeOnbjNwCs)#Pc7XixglT`r0nA=33%71H$g=4V zwfF}XSgVH~*Sp-2#7F1?)#rIN6Vx^1!7RO^_j&I3O1NJXf31KjcT5A- zvD)*;M?l)8Yr}Ss8b^+%pZlP?cJ8GpZCKolG);SUozc`y%XP^LRoQalQe4#6<9W5d z$EOZv=_#P#(LFEH;`D8ED&VKsJ8t9D-p9q_jSElqL~C7!04BIGB*>LiV@}Mad+LTM zVxkESq9Led#m_-Cu{qY1T0^@eJ}rGI`NZfsU}~tr!uX~kOgyPE<8T!3>=%6`2CiO> zz`HvHM*hAlrr7~eA3_J8{c|fcwzrv7d%Y8$Fpqn3FkNloOLx^DJ3V;qn}VF^2|$w3 z=bEFzW>{6y1B1fK)@nrjDEQ4(lxgXnP!sMck5eIqF$h+IVGtF>c}L+sC_b-))!s?e zM;YQk)}&n#XRPazhGV>H!)KKAYIH1wlWcwLV??<-`sKp*fg|+>hmVL<^C7=7Rj~Vx zsYP7XNZ0l6eH?Qt-7^G0Y9u}MY+85hEVRE>8&+SG6~D$uj`7cZ$DAF;o=}~y8xn>_ z`X!m(k8JOKMR>Twte$&**?O(0B+ui~axJCXZg3onxKT8Qb2CJTdxUwV=?56j6icJ4 z>F1>9GIc)6wIBFVb1F?R>cr@|KJ7sn@s+relSGHD9DmKI|7ltz@ zGgjI>Dbw1(v%Rs=;AG7dJHOq%@QEWIvg{HoXH(B-70QE;PXH8&_gjG57C!87wlrlY zqdcmPpgV|W&U23!Lg04x`XiH{Wo_*-?<}}WEd+3s+4Azu5KGH{4z>w;6~`O;PZSsz z;|XQncr`;|5TGioDWF3^WH=xrFHF{HqV^E2zg?gjRCi(<%R2^`<4`V_4TtL$cQKAR z?~8r?Y)U3ELAoOoGQ(?WGhhOJyyYpH7qZdYg-nqpI zDrX$`UUCC`QfJ6GKim`Qm?I_0WdLbpI5)YlL(4cfir-&flI2~Xk7(M<+a77Bm&}>I z{j+%jw`h`>&n^erzxlW-4kJPTMaBl#T3g&KeEh=hKLcF#UszeiddCwzqHc9ds8);1 zr=40Qtl)fFl&z1nP|{fb{h6Yf=ih_)LQQy~^zyfE=b-DtWP3kYBYj+oOUs1Tm&Px@ zE{au+{zwj+5sK!n6!K2a$^tvn9#h#-*`+&Lf%i9K@3_MmK_SEFf|&mj@mP_wt;Kl$ zGi7n;&i=BaZ)OHux*c|pYI6c(^Cl@pWxmZQXL#~KZe3F`jr|W~_o4y6minmItk2}x zs|IE4`@+D25uc8;FZBO04~?Z}P@&UVoRkly{QquGEQZJp$i%4DKwl9RYq8EI%XsbY z8wdzvS$@HGR?I+nYDn49S#Zn(@OmSuNaIm$;v-y5puMw|DBT_23-FVV^gm2_OzF+E z;!(9;?AYi4mBN8tq{nNe_+_XNE`9T+em>CBzNy0&_v zarzv&{ogsX0PtAB-)Rx({f8iSBqpuVCje}EH=@A0;NZ9_2q>+%uUYM)N7G8ER(1Jk zan8Uk=P|SfB7!0fd%Ab+fTC1NedeA0Bi0Fm@ZHDWOT@glo0H0S0Ak-DNWg~76q2=&#_kJamg(#FXr`l|79KoU|d+jE)-p_;KrJ{0o5Gy zt0J<&;^^KCU^Z8{y;Gz1ysH)|{w&h=K}o-rb*}2~s^B0}bAGHf;T$-b>&>N&=_9D% zf;}ovT!$UO4Bu{WnE@WAWiQ|Y9_USr`jF4d;9B53H^dq3eCxscGkDi{&jrLH4N}pO zEjS_WN89&YVPE4+aDCKd!|8-%`wIiz@^)1>-<0S-+LC#aZ#(;pMczq!z^3X{)0d&A zwXAo#8h<2?f_a%+;>Rvr*lgj)$MB*upjtLga6wh#?#Em#NhhrEndiPdK%<5If+5E| z>37{jA4v8dk#E(Ys$iZ|g~KoWu6ur4w4G(OE%0BY1px@|@VE-Ij%Q98(;(RZ_Nc9! z)B852H8jCNmCGhOsYNIFbHyAvad80TaNVQ>wwE)lk}PP@6-kd=EK5!AA=&Gj!c~zh zRq=EJejcKEr5s6IFi~5{(XOYi{J{nm_8{YV7kEpdlwr28mO&6kY-3y~XUOslBEfFs zQc$5U1?W1Ii&@vTyv1G<a7zCIGJGiwLI4px+<6qyCbEWFm;};3 zs9n$1C4#R9aUVV*uJ??qYL@{qY(;j45M}{&wxmqvR*)8R5MeOuDFzhMh!*e(=3FFl zw?HdwEH+Gv1pDzq=?;jutcalS2{V96mll!`4z-Ri)vHq|rrO$oP-|TnZTBLK4<(EI zz-4~Yf~X6vgo!a8+W2&rl&DwbUBhX$_Kv#l18&tqN0Q`%3o>RMHl9a=Q8;Ycfm(%} zagGk-k|@0t!h~cO50{|BAHGu7s!dHQXb83UL7AVdmr7W*P)$fNLxr?%>*J|+naAnr zw&STb1inop@i`A$EprLo6P%tR?S`n%CU07$3KJpDD^Uhn>o2;C)qbr9D8;?imyn~^ zpm|!Ju+}53)yZ-NMC@{UA0DpD@TV&2AaW=YGT`5iCq^l!+Q|JEknCI8)^;fVHl%QZ zG^mA~rIPZxu|Rf$K*BQ&K%1%(U3sK-aLoY`(^!txT}aUhVL_3UyWW-_Bz_j3ozEvy zF8ET{fk{G8Y77}RnAl5ZF+_4Nkd|>t>r>`N%n=xhhlnw+nT(3WQd^}kE=wtR=s}I* zipI_hXR!$+3`r|Q!0I#K1^wg}Y8&h%DbWvKNY!ZrR22ko7o73-movS}EI9efjS!B+ zTxmfXxKgMkPe--7cmSh-ifTi<1eZkb>Uhylh-p^Eo9yhE#oULD@HD%FTo1W5@KR`j zZu9pQM1x|5!c;&HVPS9;u7T@+wL;AmCa1hxejZ z3wd;t*R^^Q_u#52@8Ek8r7j6=J*Fe$O$Qr`4KFcGwAzfl8wS@+0QM_!R7Q{=9jzc-%lMO~tKV9CmmX+~N5SGmM zLEw`I9;K3or4LD;G$wkf^E%_q((N667O{5_4bWX0Q6Ao($ETL|Vbznw8n)cVYhB_! z@94R<(MNAR@?`p6^hjK6P+VS;8-{$PDrR3KJRYzv?D`x#of%)|r@_OPr)j}m_7Wn> z5_T-yE%WG+4TtbjCeY1gXz0oEI&2iy3^n6!;9U}5Ovl_Pi^)Nd&ZA28PmPFt&^K}4 zJ=mhD!EbEa%61-Bfg-~B{z6e=EjUfRl=A?7dJ7;&6}f5sTW%pi z4T99@;{aNb`WGxA@AIs{)$=+t_*@Uzv*?z^UoVarMm$6eStwluC%is7aAql1THsp6 zC5=P!ROOS~jcSb$a^R(07?7*ImRn{Xi~sfLC7V(Y_H`xxPm*jAsMT|GfoQg60nX!a zv}Pba0G~F@X*L8+@*qJ$mc18@i5|8HQ}8b&gOa22sL>p?WNM3WA>~!d$mjebPeDh3 zrNjkzwyKy`Tf{IqO92D*?`Tr9whqys!S}iAbU@-+dBqv*n)F2SN*yE(eIvPtDUB{G`s_e|R zLj)m?-0d8KU(AI)b{tde(Vo@FkyMvMfcq!n8z`{Gj0pEncQ|R&vE&+gfy=bn6(4p&?s(arijloE|4Dy2$Xg5ZJk8d?u zWq_)dS0=f&fXeljs1V<8e95~L4*}|c5k<|i&NW|1ygwhXaC;NR(+0+ik(^;h{38g5 zvPLwcc|AJPiWBAu3KF!%V?v;ykhbS4g$73;UJ1O0Ewp^#Xy7m_Qk2@fMuT=Ifd>9c z+`Cj9E6aPHHxDn=rJ|Js+DDy& z0#Wis$!sTslz<>1!+R2onG9-ZqBWx^v4?BgFqrZ!g(UE+w(%?4FM=OJGDL^(nb3J! zbi_IwMe5|EDT=kzwFOJrpa#54#M!6f4r+e&y4#O^cd zz*PvziwP=t$WScwj7CS1QUvzkX?fY>lBj^oTEPh!Qn_`v&hX z4TIG}cVT(yXnMi{BSHL}5UtBWKocikc8)Z2>I?jjtzA@%Dfit%D!Uh#E)_RUl!;jQ zTX7Lsv}bR`R5x$JF6?}-GAqD>&uKCe-wrFrsc~q*!m=m@1CK|0(&#Ezu543HYkT zbX)ncB7HzD(G7s`Ktl5qkfUoPQr@(w5Md5QNji&7iV%3lHWAjl*&w1#BvHDKH^K4% z%;!x4vQc)tZwoy7Uo!5ZbT)V$F|D|z=FSu3TbG@V;_QX5RxR7?CV!fz)=q`vU|uE-4OF| z{nD7$gjbDZRarH=ogM>(exasVC!qK`Z(_7{ffi#l7YgYMj==zvwEQI{K8Y=uUmBt$ zW3Lx9fE!4HB$`d^=|=fb5pp+>-@9oc=vQQD+uMs$-9#m-8TJHPo z%Eq@&grN{U(xI>_Up$jUp|tUugAZ2Jdh>`pbA-VUb1`EfXo3f&>PT@(Ztdqv%!nX6bTu) zz(le^aS&ck%V@KsyLm-WE;Fx-_;3dCE&9&8ER4Sb!wu^U_+%HeA{Alyw7LXnP}iV* zo`e&T%mxQ7P0md*kh$3`mRsHNjf@XRz?`A6Fleh#XZ-Bs!pu z=6^{}gXZh!4ESL5yk)-eGzkh5z;-Rjr($9>N=!_g^im~?>PQeoNhOj%>Z<1%riSyX z0$Dt)(l{qSStV~$)f&5XFka1=gii3%a14dVa-f6W9{@S!+j_9r_vk|Epg%^dTEKgs ztLmz7cQr0Y(<-p4-BgV+(4X4&{y4TMXFl)B+yu4Nn0XCB8bcgvh%B`R{SF2AS7hW3 zO9=Ynu?c=H8zM*BJBy^$XGjV|Tuv`kvx-uiKah*#_q5Do4LjA*wXAInt}Q z8BRvf;6D9DU2qW;QT)9wRksm?EFi!A!6$-q*IMlA49w61VWxQysZNAWZ5 zQ|D1T1zaxazm9PnlEkfsVCpv&UpYEtGFc})@#Z?@rW?+=r1um|L6MLyKI|A_^i&fI z8tmE2+(6aCH;Ljz5Qv$LsASqJ(g4VhWsR$EU8&6{AVq%NvSsNFkb97f3d4=m|7BTwlxA zR?$(&>vU6f2SX$QOS-853R4aXTb#D|kD5klw}T|0g2IVS6U+eHez8Aaz^x;v;fk>c zKEy1o8543{gbCj@5iALWho?-0x*=&OSP*gL$;Sdk9->{eJRwCTz)HLthsL-CB8ogg zp3CLHaTY%Vv>F+VK@_wEul!h-gqKUHr_34uXKlrUW zOlISM;`)6<+It?;jK~2G zm=bkz^5<BJIU{UJC>$upc%zm$oQr>;F#q$%BjL!Vzxs5AJCI2b|DQia+Ni>;lY5O#Ka` zM*sinju!WgU#isG-w{e@d{q`g^>JZ81km zUAZI-B@Ym<<1bn=Z{r`T{#$~VP4To8v=CS)MHLQnuLlIxG9384@i%t=zFsvwd~7ZLjCNPP+lP(kxU zVqltpw*q1$o5(rd0(Wh7#iWPTiKveLgJ%$Kn%)(80-5_a4+fkT>YDq%O_%>u)p~sB z&rdM(p6jpn1R>xsu~~qoiil}j`hJXu2q2vKiz<)}Yyk|sr+Xkw@-*{fQL?8Ps>T(C zVo#g)Usf8@u!$=I35v!nIEq>%5ciQPJJg}w@tHaT$~saE7k4`>j=)tC!XaCszD7%H zSxt0^p1juyStx^IRk7Urjf#p3kpw7Pv^AfRPP8Y3*do``U2mwg9y0CmRN+I27cd6k z4F_uQHGQ;zNP!rAeB~4Y%?uIHaqa_qY;*6{&{g3;popqb;QpJbq`IF9Qp+J~jWpHh znlME&wgaWnDSGWHHWIp-8jTQTvuyw@YVlRVrM9}46jz=J$e<&vA(giw+Ho@;Nxr!F z_wY+$=tXsE{#HWCl7JhDrmAp`e?Bo<#up+!B#aWZmKsYrDc=z=GcKa5* zV5INLI26ss0yRW2(?M!T4szgbovB9mH^5gI5bGXwc_-~pe6+Tncu~YWz%?AypW;jVh^X<&)#7K&053Rpv4!4jH*t)a1<}c$?=DDr6Nl`1gNd4<38M zsrok>g?*K>BbsUhM`A6~OAmNn@0=a*zH3jKd3V#&37TeNXeeTU-Al1mUt-(8Yo+>d zM3mTPdDt!IyG6{pw1?6+6DvMtEN@h1&lO^@-F+gGzhoxzr&$d_~3&+In#-z)e zqm{Xg*!{4wA#k1GtLRy-PKwcFzr_&d&$~ z+m{-$JUe^z#|@Jfw)iL-OEoA_7TiPrSiupfMX+1s09p zKQTKG+RT<`SJ-TtHppsU|(&#6Cqi zOS)1wEH!K!_156PHAIXu^2&0M1rR#vl3n6`wG;z$PP<-qBQ;}_NSM3Tpmpxa(8eFu zAW>}9+a-|*N+hyt^$BT2QKrf57J2>jhq@)x-H2F*v+~h^^iE(%MB}A!jG`fPd3A1e zr1a{Zj{8L|`~ngWKm-$2006iO5WqzMxD;Y>Mmk*x`Lz$WIlRk88xmUC-#EbK^MB>p z-m1KH=O16?Nr|$Fb>e9Go$K}ejYDVOd0M@H08nxL-{f_p-EReYpZIvS-_-vH-uc`A zpgR`045JhSk-|rs{PH9T=CU5J5tklX9%UQZD?gkc zm)}^W7El^!)!(h@HuqU8 zZsI4k0k(cD(sQ)I+ZjSy)RK{p-06%_*nSHb>l5eG{bIzpwbjR-XC?#BG%s9ekUMT3 z(PP(YAN`8qm-yHeq#U&9=FFX{l3f^Sa@@Fip+3Q8M`NJB*Ux^d;dx>td0GvViPR85 z!^uUZdHF)Sy#~l(zW?F|cnLWwqwWllO-LmQrQm7Qpi)5!pF)Ztc&kAj=hk#FP%^<5 zYvfJvC3QVYQiBoy(7+zv!AKy&yLDxe-AW^t4rnyS2dcOKuBQn6c6RBIIGd0pyQm=z zb!2o)L=PrnUNab(0WU&#_s=N?4h_Nvq!LxK(G>v_5MVkis${h=^2GZ9AD5g8Z~NY} z8W^NSw&(r>?%e!u$qD!Gox1s0k(HIH%!|YoMtzt!#f0uPqd_kj%3;_vvF7klThPw| zP2e_K$csi~6P!S)C`fpP_Vox&2(FW{mGD7doHZ^W?I3Ei>`fL{%b3ln7KtYEkjo;X zFRUU&8GKKZTtC%Xz^U|P7X5i7c^@H-GdlJK(EZH&DjX?xNf70+i6w(!2V`lC!FYKO zvzqEO@yiNIJ?sD6p97C1>|K8CX*HU}dtkGhf~D_AcW!ZMp-jD9NTV=_;iB3ze@OL# ze@rl>>HDwi7w_o$rN&8l5E_(qIUlvJV3k@1? zUO%Oh@&`)NQ`gAo_yus^$YO|9^sB~A_Bv9xn0oU_jI&iRGz@EKh;ufQ{1*f7VvoiR zE_n}_vWX~byMv?BGNbB@#G|p^12%78m(Gtk8QS|&U8paTvTOfg2zXDO^{Jix)X@et zXuz=3tNt76Pq2)&VF{Yz^A<7_NyQ?0@_@`eN%X+)*twPV4hEq-Fr$<}fkJ=h2&!~x z?Ot`}yOpo4p=O)IL6dsts}iXHR{1IS2AuTU3w1o~_g@8C z(7vtOP)HaUU@D!gy3YWWH`BFQ2z}>U5NHx-G#h3e8F>k^YcaD`5={+I zdJ`h&Obc0ABoL_r7I1*uV;27{^^v3S(iDq~8y{onq{Prgfe6ap#d6UXzw&9s$ou{! ztI}a)n7|4EMjAuG9AhxRRYmo;92Gr^Adto+sek@K%cT#`e>{&Fp^n z%$3;|3eI}|KR-iKzB+0969X5h|7#soP^=YGFcAIud&M>K*50;mv{#vKW!XZ#-rW{W z@4uO0c-??vw&-0-i0xPZ*d42R!Nz@FWhWZHUDDl8da+^wCeXXuwcp34WR^gKuHFAP zl!>yaMh*Hb&W3$(sQp^|$T5)P&$(v%KGo&Xj+aT!LtI$#UpnRUC!$B6lms{qmESnj zEo-o-Zuo~aa(K!g@rt!vt-I@In-C?}Jj*e%`ixAqXC@k?GgA73iL(N-D z#2sJ!_VUPZIAZrcxn_6cxw!B*K1$cW z@)Clyrm^aq3?Mo|GN)vvbUqY^yv_Fb+^17Fsr=xBNIFU@Q8c*xW|{bZs#m{=_M6#n z_}|dKZT}7Mn_BzLD??k~>G7`_=4YkqfGeM)^UWj}C@xUe?5bmw^Oay1n3778o`hs~ z2n7!RK5|x1y!tCu3cWEWzO%Nlcl+#;)9N7pMQIJCtpX)d9CW@%+~%2v{m^D|;C*Sp2c7A=YHYi!}uao@;ONUM5XGw0!n_@ykvrve|lXvpkq?KE@!;plr>|7`av zYyNogKC&+a)7I?p0&Df=-o#<7#l-x9*Bg=Ia~sYn;>6=^jq3m(46YbhHwF^|*Nn|@iw zFDXTn+O-7{6qhb@!;RY`oWc$N{4W4>@)aovw<@2x7~Y)V_Ww9K z6L%=T|BXv%24#$0iWxIw-q2JE)6(dJkK$2xHkwD7I_*MgkFscPBUQ*UTwF=ipG0 z#mBW0_i0uqChS*>6!u)SX9o;R7_Y21&aUr{SKaKbJ@XtEF9yD&_Z}^6Nw4hM2@BW9>vElsKfNJQGy%+=IOC- z+6*SXb%RQHFLo)TzLp`KmZsN?Yex9e4O?lwt{k_mbB8Fhd2N-F=coHjuT11`*NQgu zGs-zO0M)2ukk%p2ht7|$yKv!B6Y@3D-39~|otb=Ut`Sd!4a6XtG)PcGm`XYtELFL| zt<08&9Xb)2TP zPI(yZKF0eS#kzot*%!Hz=73~5S1VMLa)}ZYGm>h&1;#c$7dEKK0e@+#jk2Yn{l$3P zF@4Oi3<;qg6c%5R1|XYHV}?mA&jJHVqNvR=$ zVGkY`+au7QV}NJzIC=l;(b3pU8zo?ck<4xGrMU#psuC&+#fgCx!O$pFntSfogyF86 zN9nphZar&>PP0Z?aj}DlO+gKm4rF^}W(E?fY1*E~ZOaiJJ?+FJ355K zr6&FclMAq$)jgud#m5j)sS}ATl2bgkjfM_@(x`ZhJ<;0bXMLJyon&TAcVcJhJL+sP zk4xCn)`nQkHW3Sk{(=Ti5=}RU&wWEjQan(0cz`G+-d0z}gN)Q&sC$94CH-1-p_uH+ z1;TL1($Y9E8CZ~MC$w(N0SKlN>s+LV%?;7PvqWuNW_$;MyHgCgk=1{$ZtKv}+$l+2 zose?^cZmF#pCq3IW?U6H#y~dWE^9Ol zeiCh$iS<{*v=nEeNX5`Z$yRbPRWkSA2v+*Qc?#!MECQgG>Pm}ZUBYo#C^dbKMpEJ# z6oHYz3D#M|rWr?-qLe}MaeV@w#vR5A<>lk(C&)hAlteJ(RKn!tx5_-I3S#1p078tc z0*hD>45lI=YEOh9M$~0l`_s<{QzY*!bQ~rryse8|^uu_Jk3^Yk_<+p)8jv>v5XePXe;5TtrZ8*c_Rb>X=@zPZUk>-v6;mVmEM4nV8w80pp+8^0)dwj5^P`=P#oRG ze}Dh|`giv4@ZU)*1SH3p_AkPVhG7*#Cs;Wmm*y*N&kbOgFI<)t zRl2!*2TovCq~`~(dZj3qDvMf;pPaD4UuhukJ{fkTciGWwhr1|3dUhYHrzpzNw|bEh z$~`jM$g3Nc0}W}33Pw&Wp6o2p+2C*>lGR)h*MV)584msE;b@62zg)!oieqGEyHY0>ry9H*Yi4jAr9%LAEagEk* z@GW$evCol?)cANSTZ6afwXKDyktwY!?*w+0QaS2+<)W2qM)LqEsD4=&ZTaO6{jVyy z7UmAVtyg)D@STGvqrLXEtgBYq8S9PBMb~H2wB>XEV#X9jzvjf38j`Hf&HpHnwpsG| zo`Orn5E8!8^5cbDSgkf)v}#ln(MPaK#^f|EGTKSbrOa74VQP*^V!Tuvk!2u zJF7?^&@sgWRY%i6$osBx5c%7-s15|iC9Up7lWb$jYb+ZizI74)lv_c1A*U`P7XPqb zSboE*mi8qH&=9W-AHkdLx?N^br#Z}Q*29>7a z0mmt2bz96apcJ7r3Ye3501ji8jn{{hD?{6{Y0ee;toaEwY09FoUiqSQ?u8D0_Z@<- zy_OJZKXZNqpKucjB*55_glCSXFvB*{Xz-D--xPx}0d<(cP1a63&nMQvAXc{M^R`JNArCFRP-rb7AElNJj?sYKK zuPdNwv_}+2JSHbpf>BVIJ1Pxqq~pR!EkEq~QJ4M#ob!k>=&p}-k{S@h^rHDV=LqvT zP#P4x1;Y_#S|C_cG*+Yy>M?w^%7#-Zu&Ltz{Dly#aLj~nA}qE*2rxM+ss*GX5zp|I@HdT zM1xmQ^!u^?Zb{fW#Z0O|H?kEH^j%%O7yc6uplTHMTvOsy%!D%>ROL<)CH9Wa9z(^_46G?5K;S(O{505N zN)^@$!`GjY#1@T_v+dAQG-nk=iM@hKHKUbI&(^0}C(ahvOCiU&X^BhFVQd)=D-NTe z-AQ=Ud>R&&9v;IiS~pwX!LemdlJc7Ev}i(QV(G2=K><-QG$CD9Li!LVP{C3QD;8-L zZ$)p|)&~J-$$J=sjVM0KIt`Fk@*?YbiwTlQ59SkcMLH6RtS7SBaes$ z;P2u~L2c)k{>4v#k(P@%jK@U@0OS~AQb9m!h=P+5vAke@4g!|mk0x}Df)Y`H$y|iP zj^3D*!wMi+Vhpci`UW3x6Y6L{!PtsooLOlIiW_7EFijP8jN;7AV3o$P%XVT3nIlL( z;1+%C1_mppC2B+hW@5pLTcTP37><(!q3~ij3&Q|rFbi{%I+5q1l} zK_7{QLD<+N|2Gox6ESo`|G%Jgg00X6yNhm4XS;*ekAPTZbP>slCY`;d#w)zM*9VYq#T_iqokpxT=^A zF;<&Mr8c2*#HuJHX^T>36Z%-pSK?tDyaH(RG^N7_e2{w_O3al~* z15ApQ{5Dy#QCB-z?Q6Zo(m{(sInc}lMsi^f!ooR=*`Z+WG$e8x`?vTEqqmyL%C0;!Pbe6kAAl^nQizumRNZ`>z_bQO z)@~oqP*qR`8{NPNKFhXGKwBsg#$DhciD+F56_3#6EL}kz5cbmed6+=2@y2L~FyoB# zH6gUc&9~C&|FCQpO^JJ<)ht$>@80XmzQ(_Bk3kgC9U1f^3(+T8>ZFE)*0T( zzc0H^3+V7w^#g#*aN4)|N$u@2a#QamRDOYe&WK_E!ll;?k#QAutj~xFz3n+Eyoc3Sf( z?1cM=bvDy^s zt{9Pp@KZ#-6)myI(dcSE1`VXv-FAf8LyX2i_pW>j>=6RtnEkXjHcfoo9ktP!^yWBw zioMoq(bV4~{m$FBDYWwzZ0i_x)>oA|=iVEeL4=li+vRIuZNrQD%%Erw4~E%SAW91#-X zBJhh))LvY7*m3KM2P1c!FtEBQ&zPB*FfJF=y1CK_TA;}82e*pCFOL=-zJr;_{QF0r%yT$bcMue)_X2$m{x^xl~ z??VX%_+Bjsmxvz>9Lfi98Xqc8QbOlzs=A%|u3uE>2w{G<_IVY}RJ}HUQ!gspFK#g~ z|LCz<{FG8Vt~Gkx0}crE=~u*L-JHd1GCf+^AYBxL8ja!ga3WXxY5lMDS&4B-dT%>% zVVI}!azdiS$I6&_x1OZ$!y6TdGO4`2R)hyZ!E>gUhhhx#tTdwC8;|!yY}7FMiz{h56}c3b^P(+Wk#dres?+U3C1&Ccw{} zwyJc2dETF19XwzaBScA*c=<9rgNwl8=zOWz>3*QPhrt%lB%l6!BX(r}d7% zwYHe;kEBz-3A<)mBX2qLG)Q3%lRNBapDOUw zBZ=K~*rk}4kgnMz-W<#6<6c_Js;M@e#$X~;Cgf9ecSy{L)^N0+Hgt`OtX{(Rw5MIz za;t~N8zm+@%lvPxUECSamC5HnEY68jl5oDaD^-H-550FW`2rO zD9JkQ`)*?*1Cko1r^b~WTCQr^*53Fqb*pj9VNp%0vL(PJbW0o)mz}s*kSG4aGo8>_ zm_1h|$ME1uSVNxeNJ}t8G>u7Ue4ZV`{r<*{G5mhk{($_1nfi}%hj-eQ@`oH#4J~OS zh7Fg|azaUn2C6m;2?vtK+1a^?Aj@KQkXMUy3_pR#ef+C3{BrIgyagJf(2i`OFM^#h3U^3r;$n__E zp&e)_SW7A99njT;H{k-z>4*0;?;UZsA7aQxG_dexN~63=lf^rKnfnp;EMsarfi5k> zo}=0edTy*)ndX@}k|gHH3xErt|6hO$baX%IKG40dm9g+WdigP=@6*$+P}3MXNC&_G zc`Y5~t!Q75<%%cgF_@D#;{OvGDZXNg=SU<{KvM=3Sy(PoKU*IHOOCk&+tjqVGtWD! zH9~v(Y7S@!7ohMXk)t${3W$w!G6RSNlf=bjP>IVP5}n(77E;`QbhBL1)2&|95-nx} zIAgG}%qE2$3MCKVAnfPW(qD4ZAB)0Mtw;FI1}?khzbZTMM%FrSu&H5bD0tVf)9s{ zXCjM{Vze{{R7n6zlT*_XAK!>mVq0F&SB}9@A;==L9T8PEQ%I$PJQ9oKfFVIKB31y` z8MqlNZ-ZIotvQTR{jGS5hf^dIi=~caj6fhj48{kep`wSufGGJQLku7BRmQCmGHvO1l8g zkep)C!QK^Cwhcusp4qx3zKBRI^q`(UUQTR8>u@Hh9KX{ici{@39m@)Q!1)_(w7x`! ztY4!A1q-Xr&U9g(lC3UE!>Vl?IeVWrHQ(TmeovTo*Gq_gQniex*y%8*D`=8rqJQ%? z1==*c%mu*E4=TP!bZET`nVaBv=zBlErFi^cy!@*1;#+2+QJOkYff0B0$!Z#ypAo>& zF1y}V`rwxj6Em~XQmcFVwK9A%>~1k%vQc^YysFtbt5OM0&Cs&CFCTSJ%>IcFh_lH; zV6sFv;IhK?a|lpR`(#_JzL%h-<{LA4OIr&=h^<1G9ez)`Rr@D`_miA zyfaCND+ku&;oAPkDBg0}S=m31d0$e?`4GiRj{0jxM2B)qw6yC~i%!$kTuS`!86$%F zFEeomwD@uB(et@`{(Kw8qyziDMYzQutgH54t7zbV9Mu9Qd>QMuuPWc1;iLr9suFvX9jEQ#L!= zH&l}hcwL)>WKVYj6#oWXWgB2mV}Rr95J5gi_bm~Yhn0>uxLI9+SIQ}T1<~xKSyzSm zpY|^d5wNpce@O9ew{*b?#`N9_T+>+;d+g=I+Iil$@Ov$Fn`z+32>mP8R_06gB=s+L zWkm7#0rqn78$#IT41eHxAW~)%&a1@TgVFz&T&qf|PFUJY8C`snjY9q?Q0j`$>CiDe zn=AKJo&p-a757x$SLRAI+$d4l-ont@uJiM||2PK2Z}3s`;=cS5RZ($7(qCd^0x+|J zX!#H3M&8Q)XoSzL{;AveiR={8a4+S(Rh1Upi^CTEvOCG8*8iB&@i02g!(L?BUsM-r z2{qXxWpPNqF)gaCE3$2dZ)+Wo|Ch}4G1+t2?l=71X?DqI$%FBPolo?v1-SIBEXCCI z_(0u90B$R-7>Qy6r)gt<3Mz|NF6w3QOY+o57Wgh}vd5U<9##}_%64V zEM(xSOw?wUCP!w#6oUwN13BNyV(4ELBT_r*)=iG;qgD2Y5(y5LqDn;-^De?UxWLv@ z!PCHlcm0pF=P@*JA3!oIKKz^8?-rFNulBk$>p;^PxylbEk|Mt%G#}rl>OBU%8>Su1 znQz*^zv%ni`VWyeAFNzOaJwqe4^TbpQk90Pw=QR_-5O|bHICfij-VY8;8wzUD6PNrfH$fD?K^-dlX^Qe9Mk??^y8o z4ncH`9V{-eH?i8=_*U~8*#O2u2F~WNw6>O=mQsy0Zw7e{)*lS9t3IHWR!_b+bSb-` zB~b6I`~ea#r9T*CoowM1Z)8*YKr(x60k?m|d0cwxg)WjywL;6=M(Tk@tuG~TZ#EJd z10^hC*-UWi%!3X=XMe%346gTx1wLwNcjeft?E$xa->Zp#1+_KLI*E?qJJvfY38m;~ zc-_839W(}3_zws>f9=3Ey*rCeYqn5b9GAo6nVkz(zGw*)%U5L(97U;4tgK?Vw*i1C zt~=Rd`6k~t(Sph{y5*rS3ZGT^gbIk;^Q4PU4-5692Hzv(RqCz(0MMc1IdcAQi43my z#Ij?BJ%;l(pxdZtP;52B*49xO z^TkY}x@xAtoBCCGB>!o<#aG#(y^gQRf~CV#yyPgvL1T8mJcKC6I_;`}%qoJffs&k< zl;@ZL3fMY`jKt!PAzk4P)(j{-?(Z*08MqZ+No}>~N4}hNXZUb3E5&`FwPoC5E`BOc zvGSY~EMIn<3v2rbe*;acf?MNQR+~+C^eI0l>&o}xTysw*5ko-# z;Qq&3ZH@Cty4cVdxcM`Awxe4HJjnIE%i;&3E=$6*b2r%`#U!BqyN9nz{W`j*0tq2$ z#c|OUAM(q^KXvxLldeI){-*?8ePaIaD;?uGEa2zAzvu5$I=X*r|9jHWwU&!6J-PIT zK4d%PdBtg=Zv5H}=9GBhP0}DETerlennq6duAy1fvZO?-EPj%WciH4Qt7rU4GFrOe z?3Juxk`S~EI#gb1XNPZX$j+;f94ruN-yNdmL=3q)iRY|sxi?-z*w8xkJrpC28fC&^ z3E(1Fs786b&^lIjHdhzu@LzSHg^EZphknLae9fRc0Bb-=)Zf7%9IE#OCEJ_3XaD0} zv90>_2dv57ifzU@K9Q))3h1b!DOdeVF>CL6jr|GLF8z5ACOt4~;e2m3K+~xH^51g3 z2@Cs6Mw$=30==BlO;?@e!nX%R@UTJ=G-z1pbi7jV~g{dIWkEdtP&O`!&` zL7LB}b;(KEIsL?%OUAWm*BRK_MYvYoonXA&IE7QK@@_}-nsJuUUm%NvKyO_YQx#E2 zCAnlHYve-{hPDe+(N=)>v{8&VvJdRM3$Xx?22f1z1$g>|7F7Sk~K`S{ZCS%|Q83{TYNU;!ZsUgUoB&?iw%#?dobk=^~jT zFGkYsGMVTNhU?}S+{Bxk%UnzqO^hi!Y>55+c+0{`5dS=lCt}o1#(He5#G>t~Q|Tv% zMm68L0WYG{bU`5VkF!6{{8lPG|85hG?sbnMq;-tk=5{zD7lUIMv*pGkBXM_L%)#_u zwV2r-uRVKXLqFo;{>#QTJ5{f$M|7hZ1Fs8c`kf;E3DscMQ_r$xapWo=#S*B&_=t{< zM#s`UEX}K8Uf38JSRBF3)FCmIt|8Q=b$C(n%|9?UBtV|=rMIkD5Oma^&h)mV_f3tC z;Qy3)3RzY&R@?9h-)MSPVW6d5W$C+|TXKqsCXpP_oT|5BJ3HhRo9oMG)l!O?Uo0Iv zLcP)&ZIUz{FAyw(L0m0dS>sW;%~7SRRHgE)l(sH34b&?(+O+SpT%W*W@2y znRjckBQ2W0g5KhhLQEB4KTk7(8%=U5$hWu8K0+^4NZ=4I1qroZ zjDJC%bA=Vu&rAoi@pfuDSoXOsru~=du~aDgX(vbFB6;J#SE4jOnTF5y%SskgpIW{! zd`_R=KL<%XZOS$3Z8WP`5eMNPHrpyn)&&Z9WB<8U-5KgIcYI_9K*`tSbH7MU{*_dK z?;ahFi{|gW-

5ay#fnQLOkQSq+7V@7kA`<8F(-YPJARp`Mseng%FL``ikDI_N{2 zN|BY?d|ycVSrt4h2k?L$wDYcXcE)^|@vGatgTcQxoS}T&A7fr$AA`m1 zDP{OO{Fg!)l~Kz2x}OUjI+f>1LUM%27^OXWhRiXEBCjC5&!`1~1KS@&jP)u_H?^}m zBE54w#&WNm@cnBksjqoh5CKp2iA>3~siTW2f~(fjOuh+a5Wytbw)%tTSM22;5~Ahg zr2mcy?W$Fz+|F~Yn?txmM73P>vXkC?yoob)T%_l712KP!1#WzFAtG9@u=ku;*}5Nj~z;{DaVeVCQ=@rMb`Rbz-y zdR2rbP)=}cf`tt@_vx8wS(c#wa8lP*7X)3!4`94pVX=RbhEN???g_mUzqZVWfduaC zQG?*BIJhoagjT`uEZI9ludFYRljFoRu%@m5{+Q+5(0^+0CZm|`0A08{g-4Q)Xa+dn zh=6jLl~9gasNp62lF_~D(`t(9?VjOSfM4`mrb{3>LZd=NOxoGFaSNEts+48#y5-sY ze!1C;nNKu^D<-Pm-St%RthsFM;nlZE+Mp>>f{Zn4y`(e}By!NtD{<-JfMa9P55^vz z!*{nJpwb6dJZGzQ>TAOCA4O%@OWt^lJK7j;sz+0YV_({8KK86X3HJbRrhEMQF{1_q zjqX^z*vWhbCPQ@c7n!WMq7ElNJeUP+l)pd8mZ)d#D~sK69{uxgH!57M*Um)7-9p6u zD^9i^0sAT=$rAiUj_0CP!-pInfFR$SIyLd1n5^)~hxJq*<0bM)2##wn_Qlwt+1wlh zqB~A~+^WbCiAQPPea;jtt5*PO)#^LHW7EE9w_=dYvqP-Oe9xN8xAWX_{DFrWtu8Ff zt90PcuavJfU&}^{|2tr~{Y#~DKc=v@G3jb{%==g8X-L8PnJY=_a!y^zzr8O!L=Vo~ z;OIa8D_wt80QoEDe%{KO!i`@QUUnv|m!hFPDu8*1@6p#ulS0B^-0c(lDYG+N zKBXU0)w4BJ?IaqocGnNwqdAew(^SkPfnPi`JZSFYz8qJ=WZbO&lyb>LLBB~{*Z#g? zcgKoSoZtNu-#0lFFwyPn8WWj%_`X!Y$rq=5%adJ}Eb~UI`&QxodU>AH>H#4qWxgEl zCzq7X3Ti!c!(YGkjXF{$NPRy-QSipsH^d`-l9GlyL!SxtK=lVdihQGe3M>q{$TGEn zRX=ZJ8`kHVTJcFKGfWH?9wc(;Uaz?KjG3>Xt7oLX-Il9f%3d^&D?p%@&nL6jau$i4 zt89}B52_E<6t|=<9Z|f4C+j}=jD^pcPA*T^vS>R0*A2(AXXh6#M=r(r+i5HXFJLu^ z@4CE%$4Zs_wBmO?B9pRTCpU#U1Pa2IGmTky;Ox3DNpim0!<=edsVC4UWeJee(Cfc{ z3N@W*DUVF7Gg}UW7ZK=c%V~>BArJfXLEp^cG*i$IzMI z>4_(#wWl*%iB|nL>~065w04Pq4(3YKM=x+2Ilc{eH^bb|)loTM3QA#;0@(R*F?s7s z(MP`yBRaQpaE5@Jq^=vmmr>BE-hq%fc8?gN-U=SVGCFTV1~Dr3l`|gtCNSuQ0}~ng zZessjQYcJF+#?lONnZShT0>t~q>_i`RAn)64~o_TuSo6AD3vOC9r={SddV}cBUt;L~AmuvqE zVV5;LH2skC(Uwo`y65EJ#7oS(2;N)2ZtL51>Dl@lb8^=FogaT9_tR<+X3}kX{JUU3Pt9r%yo#u@cKeyvu6 z+5FiwY?ZVTqBP)1i~6(~^l2)6vguLBaCZt+FlX0qw=skckRose*gL(TF>iGO4#=tay| zRQ|Famws6&Lo$^*M(M{(p9ooJ>jqSbDk@y_3)o9k?AO%-xA~2(T+OU`Q1SQvLI2iLk^-B59933xrFs|lv7E(5ui}>zQS*G; zMD24qldtOhd|gsNo0ih9O*s~_=J@rU#Fr|#&RlSW;KBXel|82kV>(qL`e^+3?$7*48-qbi^RX>7^6{Jk|Tuji_My@!#?@Up) z>=D+eJfD^1wbHWal}frSxPi;+_kVqYN;ecR5F0KRaeu2Qx`!TO$jNX~x+2PMX-YQI z$Nj$PMyY6iH|hEWlLE`vdE~@YnAM#tVnRFJ=C!uVK@4opIW^rqyaHbWFIByA^|EXz z*|>5}2(>)P_v^;b>)g4<*RAFsqZV`ggSEY=%XSIy{i=6<;Jw_}%TFz}eIH932Iu&K zwdsvTT(B&{WcN2Dr#7B?L1`_gR#6ikCm#_$;omas>+{p(_#A$KQ500#(w-@N;AXD0 zWOj*OOq8~I*pF_NTXxw_e?^Wi!N6mVFbFi)mHoG(&Cyr{prCfB@zPxdE52soHoRx~ z6~iv~yp=CE4U$SjIS9K(?)0cI?bqvbdT(`p49AzOgPP4i^?vmwac51f+XvQ+GM$xx ztDVbNrb;6j_Vb3pKf7%*LPY z{#s0VZ`PoN|9-p$8b5}=z2PsLf7ooH`SPh1I~;f=!7ORcqU_$bgat~B?&qI_M0FkOTxSrQKH1qEKuT@)0(D|OO9!A7gk}l zs0-n@)s7T3wAzyyKWX#ScSD;vbT{S>EaW#`o4)JFGO4*U-r%jObi_&${=#Jj*FTcC zN5*bwy?pyQOeWPWAy??`8dS!*!_=r?A;ix&p3!Z1`pT;|1(!Q!M~RIQg-zf?(Y;Cq zhMJ#6hQ{RS z(;kF2c6N&@D~j=}t)**h3O9dD4wFV}Bv0Ig)xcq!tS_85faZU)-!l*5q}U5YvW|7l zg9W{~vTBUOBT{0D27oKYp_15*#La*=%5?5>cRb%DRX+JLX!&REW9C2EgJ5~141h+X zra|4c<^N)--7bPR&_S(t^XBFB^Q&QEFyry{?-TdB8wBocj@2n5=F^Xzt)3(h)ht<~ zwcZPl3v=>QjiRL2rS!nx|9RNGZ%**gTr;(7RGMN?8U{Rn(M%QF|CE8zb77uLvEsUT zUCUdE8zpk;X7viC3lc(wV&sPZ6+evB5<29i=l5l7NU4+@=;1x%oin?3Gh2?#S*hqy zSWX*Tu09gFcj&iMp7foLPhfZpLJ%g{pbZV;-vx|BeAcoH-o5S{Siw;nw|lpE{f_Ke zsdAOXzM`b>WG3H4gG4mu<~@C+Jx;Kk0KYlLf_N(PU?&25mTRHpVgN*cE505!mCB$< zZiuvdUdH*`Go1T-5c}8R(R#JOC3fPaBMzxs*$X=AWy#K>*loa3KMC|xidEu%5K)L} z{NYoko-)at@-U%5B*BD5?&|xjOC34Lo}|m;^&G^Tbhfj;6$48}k|4*fJKNX#ZVlCy znd&b$p>&TN;iH%RdYN9n=o1sUJaRcmZu_Pw;dZ=Y-7fX7x0j-Y@N|q16c&;sBN3A*a%#z0O?n>7xysURfX0a0jj}vh1K{E#Ec^Uip|Q;;_eY(vq0lPZr^G(L|f>-mmo`j z=|0{_QAqeqje3lM`sH@`SzQxwvNhzFeU-mRo)B_?{dvgH@?ftb;6$kVnP(D4KMclG zhNPTGKZ)~JxKN&Qj{hyn8CnvFBaTx7xxa^n-va#9X8@F;2im`KT}7Ykh9A3xC8H-A z@@+G7jjGJKo+2mzh+lc@lRdH@YFx7KqOO3PSU4wJjD)cWU`n zE95n5D*wKD{j>2`d{xYm8xsovl(tVs*H!W&fI^fsBDPW8J(J(RuhLNrkz@V+^A~}Q z%SRrM9zM0~6acOm$6c2hvP>Sk|B1M`)DZ_u->KtSKy6^dx>e$=ZI{$6a~6;m(G-~^4h!cXN|7; z2w`QDeWjdHcf)L{Vu1&$D?!feykDC31^P-*Zo0?vvCr7|>@tLN7f-!o(jp-vMTy!79|7wsG(teFyn@u$c@h&CHo{ z8-rvk=^La3Lw5XH>Jf5_@@ChpZF_X*-igi8834$A@H2j;$UA3N9IlMd_FhQ{2G(2{ zehKiusC@m6Ny-u=zN0C4Z_l&qTNe5-w5;7X(1UxkAya4vbkLfU;cXSd{CBwt>qhDI zBzE52+xrf}1MZ{w?pfEW>2h1r+6J&Y0xSaY9LtL1o4MVLwUdRWq3w&{vb!VpDv2L{ zPP#GE0jlWn=fI`_U6~j=WTVHc|oWD z)5iJh%ynSH6`59dvER3j1)KcU(U+t?DJ>v8oVdBD4#m;*xmJGod`+>Rpv)WCxQ|ZH zGn^?B8t#!;@yd>ioqM+rhoUY}KTs}sZ(oV3j~tTKqjxml=~u9foA{&gPV)M^3 zsqk7SUS0KndWX0}=TqI%4yLRk=M%0Ag$i}eUqPo`UMeJZxTD~^~1Uz`K8Iakil*r$+wE z1F>Y{<0f(k2*{L;#%n3VY#3dEE529J zRi89Xi+?_Q@U3h{&^3)|y}zlF%^0ocP2A)NSPG2kv>&l@9UWVCEE4@5s@UKu`4QeX zCUqvi^6N`XqM1r>c(&2k2%YSG)V4!6xdZ(rUrzV5(-;-{aw#BggnRZkIaq<7Dy2CEB6htLm)j)DDb7;1e<`pyRva{Hw7%U!G;=GPrdItvxv!i!CR zcV#TO{xV2ezuf%W!rU&(phSsR?tAy_Xw7bYHZgI4VPPy|g8B2NcZc=aNgm0|_MLHf z?hjWNhv5rzsXp4xUi6t4k2HL1TKuW%XG(S6wYLvs-_%X{8_uZy8yVIL-V^rpX2-nb8D_!kNn5aM=z3Hn#W+2i_Ks^^s^ zlsUM?Q*m%Ag-{!_(s%nq8OyDd2iJg5%Z${6_s!v|fwwTfP*sN~FEWYU8w;q}hEjqD z8Y-`pk*}$!fMR_cqn0;V*XS#EH8KbI#+Auh`SG=dX@8HsR+QGf1!rh3r`D)D(fu;^0!HC;j`N3Q$UDfY*eTnk1trM9FTn=lPIqFC^Z2 zWp*rg=7W680qONd^Oca!dLsslmZ3jUVaJWd__u}eotuo|;ol@ioyYFTK8YB9cDSwg zk&$`{dSpOtHpxsF2B*W})OMUcpJly5+2D@gDYA+$nNWpFR68g_qkD`)3agUVEKf`< zN%*WU1I*ihcB||!33Y|)zZo~sC8j!f+lHSu24|KCcCNBJ_M|xlt`ORcH&jFx>Guey~vIzX|R z&gPrmW@V08&a=!#yZ1yPE3DhbfA3uvdPU27c9_a3?Rod7$ZqOFynCIFgMGgAqipKS z^!qi4Yw27oO+!R#C$6M;R1Q9MBu{x@DyT|#N-xwKi^fIaj&|9Gy?u9hABeZDSvI!Z zOS}#gV^%X#%^WUdgNFB9HmNiVn+Vv$yz4q?e&syH0YM3NRdfa(re~g9y({ZaB3ZX z$>qapwozIFN<8Aibd9&K8S@(;+ItT6Fcl*jzmk{~Wm|G4pw{*5Z(c&4Dqcz=MRxG*kIMCAw^qfu6&`45P zKmsz6-L3h_ca~P6K~PKQ{4BNV^slfZCf(B`*!MQ`ddfRq>tC%73Vx+apBbR#5YF4p zj0zC7$M&D(2m?8?1rmF7Z_)*@$=6}{(~jK^zo%EIdqE)=72|Vf)*fPqvPF)6WBP9m z{(T8jD=M;QUTIm#A98&8B}$4_Eq^1SlrR6RND|Z2`$H8DKaJnN0{o~i%Nn2|xr92{ z*6MqBIMu<&X-nBZw?)db|JQd5>3h+j_GYv@PrkHYF712YRxUg-R_p?FaNy@Q92>~_ z@J7Buwdm~5mKtC1&*Ho`@=RDrsjwni3@+5_Tt5I^skmY2YpLVNNAt@G6NN>L!k?y6 z-Ar0tRxBUyO;^99wVCF7-;Fhm8N|E4Xbk@Z{&JTbI@pzVH^ia)<1w#I`}g|T%jZEi z_m?{v;LEVriFd2f=_{x_Q@6tiP2DpI@F8DFz3AI#do^ngB)M zX-9&72^ML)p9}|{TvG~GBh(l`Xp-~wrQ232Qkph7N7n&Z?PBc-BgdxY_Vf1s4w=!&q{nLlVSyzF{Rr>R1|QkWBNq97nr9RKtAuf> z>H&*4#}4B8&G}R_146wgAa&wCQnSsa=lSj4`^t1Qv5AEuyHlAJ$@SjFTMZN!#GHUp zKcPRos$k}p!1Ih1-|&I*i9|m~hS!<52ScoPQZv%uziGXbHvfH%-$D_z_y(Uw{?hX7 zbro;vjhH;M0j+YhvnQU&+-~@v8Q@BvMfMSgay!Uc<^KRcK)=5!PN?Bev6)tPs>^nE zs)_TI@OBDnYHYVXP@^m5D5C-{r_%msE1a-bIh%^$zG-&^bJG~i!hW7BRm(m4rJBLU znidG43RFA($YAS>CD?jgI@THq!e1v@u3RpgmMlK-En<%i(Qp}k18BTnI-o}*_i@iA z$4F5IIlhD)5#o|rTNO3xSa4JlACF)wm5bmM_!KR0M=Ahz#(wPw7m7nyQ~(LfBM?y5 zZy5-e?;|%jrBtoTQK58-b%bYc1x}}8%W$PwHH1Fcd^Q>mlYGa7gf8q4jKTjg223Z0 zMW)^o*&0-W1#N9mlhlQ!s<3Kc$r0OOo-Ni{K?F|&)x+`vtJp~WYEo^WZhno|b%T2s zzEVN}WbO#1k*7F1s~@2%&FLOky%@t>;~#-=d!?_TubU6a3wl^Vm-^$$wAH!YB>`y&UG*{#4AID3T8)C`qL4q%V%xL9{y) z5#-_MlIbHkwxT%BNhC;B0-IiElbetW)O5W`Ql!P9tpYge=kML!7HT9(N)YXa-;B0@ zxhjb}J{~QD+S^jp%(o}s6TA*gDBxBFe2DMm64dHD`|Q$;kfIZt*$SY)qoWj(Z9F|r z^aV`elj0e;e>dQz1azLeSVdm?2>CbzPEy~~c6T%yjvu7$nPCi|n6LC?rv${mg={N% zW%Z@$ffx$Z-aO)vB9dMNKNQse8TlCLjNIM6e*4TkX;EaItRDK@|4tFUR$prB z`}_^Kn2|yQ4t}%Q4`mEbQ8kMCEN**ss0f(l=GSGSLbh_lC`7)MY&jmqB5A<-ghCM- zoa9+t?Lq4lVl9EtdAs@}iWf)~JkSkB@IVfYD84^G)pRHbsc_0V4h4&!UL2fUW6$cFK@*@>mF( zB?-b+7W9W+bACjNRxid#ejAR7TxH`;z^#%tV-^*mN7xrR&okn&?z**O=lnDtdl&WB ziU)KBtXyB@2%;44;bgKOYih;p>|H-LLq4af$O0h8m#q|#rL+_*&bh`$`dYJAlJ@Q* zhb;mMZX~f{dD_`x(Q>=uQ?fpRxK%4k2uZ2)^Op%{i7|c5WyB|#@g!HC8Jc8+y~DG6 zOGZC3#K~lso2N|FyHNAoGh9Q{I^`uyZ(=v`(~1GEpb`+_w{6;iK;){lQ^^9hH2kd0 zs!aS4w6HNWZj*h)Y+&NL+%+o6qh5rVxnSu8iBzzYL@LKWX5yPxi?LtDoPFs@Jl!et z9JnOua8_0&_fA-`1t_%uvKJ(Y{jh7^FR*PYFdhOiT)YuSA4eoL)4;-;k|;x#jo;v# zPWHSeQk4+t_nNcb~IsoA$g$y?Jw*d6SXU)Y`4nsiPw)=FcO&5GKD zU`}Yo6-9xFTpZ{N z4+F#wn9R!WsY|?mTAK?LvI8BM(I|YEijc*UpTQ$sSXdO`8NI zWa_|danJWN#pE*{fp7u@s2Dlve+Fj~I%J7R zcK25R$No=g0^MGg0;p-iGQ|#;Lg_V*wBl!)BUEEeCf)TqWUOZ0Tmwd}ewi+XrWa5e z;WQWA2YKj&nB&j&P0oxR!WPK4Dk|&t1z@-<$wOjq3&MnCIVsJXtksb4l88`(6m=7J z3FClvae2-*`KVx608a_gGL)=k8Mn5G;K4MRkS1hjq}1fZuiMQ|TvT9IXJlFfGK7c| z>`8q8GhzgJsc1wHrstvIqbVy?Adjf{u-t^rV1^(-w@$%GT$@pC-y=vdfFo18$&Hb; zkyxNxwoih9E2U(0VMx=0@JnBVza!4hF$m-nqU01MfSU+mgP6OA0SCjxlLt89)`G-A z-QKu`@zCxYZ5gj{q2W$TjKCCQ4USv0$GNC2snN8WR18}!YBD}jrtJ(23ioxz6e^R! z-$qX-S_5OmN><6yv~8iaCFPlx3>!k2BLSQ^0Rs?5)hEo+dWD$sE+i|8UXIY5w>W!P zUnh*nme?|66({584&lZk$O%k~uE;3}O|)7OPgR&nT6z$8IP7ol7Qs%GNt-fb(YgVk zS_M@qQ^|eEninEp%m)n#vLSY21;wz4#i(1@QXWgjm<8NmVqsIAxJKT8l54-rIE+3H z>Ge@_fVhsn^tTi)IZLO(#A+SGdhr|%{-7gjK#3eQ0n{91P}7VorpOxn2^7?p^;eM^ z2m=aX{sw4tJS0?9Nr^KG4K*=Hae`jy#%)K9O?rlSMlb(@s-9vPI5$C@2}2_r$B3R1 z5v@Ms4k{3GK0CyzjTeS_ta!&XOa>s*W63yLtv};1#M_cA+Ve~?ZxW>J!EY@i2sEy7T+EGz~41BPDR&RiW; z4icSOUMvC_(!b@@_$>rs#4AGebt}GL&#Q3qN@`bC;)Uhff#y>mCpcmSV58uWhSH?$ ziy}Y_=-;_q#rRp)yJQGlD8|KPF^N%!kiS9d?UPY_-YE&}lv;$cDY!eBT1uF^k|H04 zRiP%Q<+c#_oVuCP?uao7Qdn3-(=|+Og4okFihzti>)srLY=gJ|b-b=veJKC<$*3IJ zQva#|g#o?*(gDH&0|6WW@d1JXl(iwa2z+Mq>Pb{Y8Xi{_>@OjTTz%iV6 z#pZ4a%$3ZCD5&GaOks&^tulR8N>|6e={RL#G+Iy(#e~0-WW9rQ6Yr}R&RPh+M{5`! z6nYb@q%4T>$2N;g8ig%yW#3@fN-)bEeO3HIl#Oa*qaZUVDQtDkx)mx_=#V0`TUZ5= zyhdTMN2So6r{+p48%*EmL$hy{dkjtbv8tfR3=e?MkLa;8D(;GowTMNHl3of|U+C@~A{(pD+>x)(7Ft`fm+WOPcLXi_Pni zXM0ld0&M!X?1_=|BM#ab*41-&#E)r=`$X|yBG!{X5Ox~&7u9v!r={8qhpASt{YQMk zY4w$w(HF+b9Qjy7U!nQXQoPJ#uTilzNSut>{U6cBMDW)HEnBu zL#nN|IB9Ior0K6(7SJ<^YbRY|AoPjELTp7oBKE_Os`A>lUGbEuyQ|09B5>*6!6$}u zpvvtltxPL!^%0T$L-grutc@*xJmRe7Hy1GjSTzMpas;S9(S!S^u+1`#ROR2$J9W=W zZ1H_na+H8H5AiIXI^T=MoTykFgh{5Lh`ao_A?%~ZBrFp<|4^MT16EzjaTr4q$s*bv zdU=ec?}VtvX;y`@eCt&_fQM0W3xl_3;H+|s6xo_6C`Ik3e@~erS7){*A3}F{K|-iQ zK~k=4Hb~1C57#hrq!$hs-jsj1Lc7J9Cj@2#MMb;b97d-EBdEOhYB;OY$7gvzrP|;L zS3wx#+CVn$1@gSC6NBDLVcuxy{8^bgweTtT|jnRS}kCn)x_6gQ?)6qDAXq|8PMGli=VKEw9GUA89|<-Mmi=_tzL zG~DMA2e+8y!sJ>U)&&Zfel0}~3xe=gQZV7kC=m$MGC$6tl{j0=<3@(D@F$S@jj5EX zWD*3K6cCaDQov`}>&q97<}+bqaRy|KV48XqYP3hKe@cP%#^|kCr!foGu;A<|%JPAf zcj(+~1XsJwDtBQ2!#f!eW$xhv-fbdk{PhC;dx||#>^_h+kHnz@g;R7>#-iJLeG_DQEqK^o(@dE8Pa}7tU`DB3K4$9D`S+QCBQp}B z2F3e>3GJHGOp`t%o4mi+CHF^wfl$4v3%&kB>_DExgK&>YluI_>5jB$55Q!K1v3zEC z7pS!?V=S{$#>*%vK2dr;ND|a^7F+&A_rnZKQLQU@ptyFE>8I0mJY`!i%9U_{ohkm>uoGtw zNnvb2Tj zbIQ*7v>&Q(n$5pEknX@KCYXL?dbZo1!_cUZrR!l0%VXWDAc$7&`*EDK_3evb-$G9m z)9>k4ilRHTsVlr2^u35#zZis0$A z47&??@M3#)xV= z#jVz+@NA>u$@eVTzvYV0yzl<`F%YgRF%{RqsVx+$cTi6|UmeT6`O>iOC&G@+4u`jS z9+17sO06C`&G`SEod*$10<}det*7a*K*{V zgzCejcUH%<(Nvk3W6GDNTjy&73WakA9` zAqox98yf~7UZN*AAfwztS#mJoW1}=_6&)Vy=q8vnGiPF$jKy9s0h|({z@OFIA%jxA&daT|NAtVCHg(2Ad&A91u zZAjqI$E0@YD$|qKT5DPgHI0aa8bGGdGV`2kV$dk`)jT1GvTY9K+OO_uGFRfw`liLi zVkVq&u$-2f50`>B&g&cH$07E(9SDrAgg-Hou~Eodt3(z5}TlpzE0$FAV2qrVfRsY1Xy1_59b zTSP)EFLfZRIZnVes-v=D_B$$@a$pEo(@}Fd^r+1D_p!H+=)B&7FjY2#BGYY;hd4|Q zkFu<`T;ymf-`65W{T zF=P$UYBs6ydvS;lFge1Kq!;CMPE}}~6{x@lV5ZWGF%jG-B{AI=vY{!8NwhU++-td6 zDyqhm^Ao>REi@u%0V9JpM8+(jNdaya6-?k%-4|afAH!?^IGwLpdWgN;^`GxO@fytV zS^g-=>Z>}XTx7dg8olpN*WG`gLOENECxZ*pK z-0G5^+3qmb8x8{Inhf6fO&Jm_HfacuUU#%d;ni%>pxYIa+|MO(BqXIpn4nZD6i9X? zk*7l+WzybCnVwZ8N}*s~UrKabMkh`@RNO&#r!4z;ka8w~&wk6&2-(!^#Z)O_V3FHk zqD6a{loF9=q*J`s{3SX(CSs?wE_ zG~rz-qO@avU6tjn>#dJ~=aV>a!MvL<_0Gt9bcUpmIaB^k4Bs>>W6G#unRrrXO!t|E zxRFDmj>fnuwYEt44d{g&bxHMnD%fOh5{aOUM?r!hs7(GzZGsJko2Wq8Vet^9{jY+W zwnC|Zy+)+_7VZ4HqVk&=u5k^IB*5$ZN=e3ORd0*2@0|z+Dj}D4lKfIX&Pe~Fsd*~i z>n1%Rb?wy6yZnmJKWPQt&l~SIWQp)6{3oH>P2onc+w_s|ipxESTDGa&-_(thSqI&P zu#1pRC@jU)24TXnwAW0AzAd_{IaO5)OD60HUpFQW)i0pk!1$%uo@G{)d zD`MGrCdRvy9aFSd7bmt}hQNw{l&MrC6>^LqUIilXz(b{pv%p1!PAJ0dY412h=4njV zI7XrE?90Fj0@{S=Y^xV&zPQMjG+X~ z_c^OLs8N^~!ura*UNcx6 z8mpy_T7okh@J=sck;F^JBuodq#y_I8#Ue-+=9M{fqPzQ88#;UPgAKZXX%Z256|hy+ z#Qb5udyKTPpZ{dC_jqL0n$fsKXTE?#iYSU-RzJD0h``5Ymc9Yy>QoRcT6 zF634v{!q9;-Ar2gs1PN8tT-d+DN(K|CVN;vkP z`_CQzS;yu03^E|Vl(f?&jmA}R-tt(oK92f=GpH19x2_&lW}6-nhna~WG!x=cwI z#bM&ircYB5+))8XQ(pDNfJnv{+tV6a(;*Qem(psa2&_s2yDE8pnF+0!fVzDUx*Eeu z>i)7(93rWdwwcRiTI1c|%E;201QG?LK{W75N>mLIl{KIthI9BL$w%$EUVu{y?Wl3m zA{lMdMM{eJ%Z@q2xXMvJ99H>br|_~dfbH?29foj@$Y*&^+k2j_-tJ#|4vumNNdQY@ za@z$^T+qLI6GH;=GOA$v)H|10bFRQj?#3gzXzcrZ=rFaa?u7>01tPjhRCA4t@Khog zNU;1NG^{rW367-)E$jtKr7_f!DxTH#usdXZq*UXKz!0C@lqFqmI9E{!L*!!GcyF`& z&7MKggJY8`8zHf>L_%>IkV`J7#|56xOK3w>-$GMMtUeW>yS|lZiy|+NLPm_EWAVO* z&p0XKP(M$~tVG>}u4zeHrb#`*c0)X92&wTTYus+oR$>WOI%rbud)msOD2;&76}+vI z^8~1MbE;?KlRFZBQgGlBt!da|?A$-_2-z%_OKi2NsNAKW6P;3H((wTBs9cD?$3(}k zl_s)|mX#pLE=tpJslb3FC`CDJ`kRC5+D-T(TRp>Rw14k(Ivu=Y-$YwoAj>XlAHX5y zoc5om8h=$blfZ0pPi7|5hEWt-OMMOS?}$H zMJ>MY>_&Y_Ej&X=&DO$Flh3WAS_v=(uxs2MZ_vG z`)uof_P0Jb&`sKO0?U63$)3X|Q%EkbJ!Lpr!jwKU;m868ST6T5?kzCc*SSrnecu=j z-&t29eWyrFi+SivLmQz4sONr)suX{W=~hjgDiOaX16LQAH zCl)oS6o1$-v~4Ttn|7&R90@eS7D2Kq!x-<3`X zz%XkjC|Aja9iM=O4Xj)iaI6a(F7bDmmFWoA@ntkm*=c}U9KAN!sj$GvUNq=u`8>5mRC2ax7!v{JCpJiv-^=8 ziB?uv6!699857z-iw;7_P+@g%$#x2%OL*kFp+yBCQ`y5%)QB-55oOLv7;clI;(M5J zgTOy*kSXetP@-r8dcE#A1py3_%2)&kJ}Tn3})Xl5|O7qF5rL439r686p#jY#c)}q3`VwInEeR zZYp=aW_{B!sR=}Ngsqq$(cwsh8GE`XO?;9DUmSV{%(!a@%#e3c5({fif5F)0(8-S152Lj;AZuC=HI z=7`~yr=bN+$Y!s3GO4VKrB1qOOBXdFbhb#~RoRE?1L&7Y#`VQ}ia}3KtTFR98@VhIlg}S5FlLIZ4_c~lmb(O{u=JF zuOZ1wU`RJlV(gHzG`3#JHu8|QppOsx>q1Zk!Y>AM4V!+X20O@1Q9~gME4NK(nHJF# z(1v{KcP#Wfu!NP(ssb_4xT1F%PLr>p&`hq#4@*EtPE8dA#Su~}dhr z4aFBWgDg)I0v=KwJ9R78yn9QZ&TkO=jddA6FXASvL;prE3nE`0dg$d7i(JR@R1!CU zZEZcp78tZZw`$q|A@ph%gx>B_%*2AWBXboxazNT143CBGpfAFbRs_QPzv(e4HceXZs*k@Smd5>6|Cw=(nrYl2ZHz8lO z5_{(5KK|5Uht>6w&No1}f7=T@W=JQe{?>2F%jM;&;vsBc%opAJoNhIqns!;?} zce(-(a@%Sk$}7)KO82dr*+$#0iCen_@u$*6A2P1+T%jbVF`k5yM2U=(4^$*-TF}Yi zm@F9%ZcOdyws3jfwk1I9&75nhe?tjp=DL^WJ*c zDzIO=gDc1Bdo13qw(lr5rfFrHD=qfXbnk1m_K=N6<6mkisP-vw+E?c?3lWT{lJ?U# zH?t!SB4?^T1SbHJI&(#3pM?=vb&=GeAzob#h3twut*1h(z($B0_J(d5S{>ybl2Mg0 zZg91bnJGL+R(Af)zjB7)hEa;Ul)M-;iIU2$_0-wRMexQz$W$perCT$NzH(W4tDGl7 zT2V>^R2ZJL!fxO*tCG8&%3UGMB+TqaA2S8kZEKa3rges=-RwzR26ou2I@lskJhe&gLC|j#v zz5CnQdTTM&+0)~7d=$K)nwK_?8(h+omgGMvI0w~3p?$B+^X?u=vJN& z*jCD(SyDL>OjAeuSapR`HEE>mbX=0ua15tzBs+I7FBD`l7o0eRcp7~P@E@)JiP{S^ zOW9hMmP{cuSI(JS^_M*E0FvvaMvvU@=5MUu$Ek=%Wy`d%r1D-GuHgjbEVKCJ!##`G zr-TrFGCdR|Zik%%nFT?~Zrc=h$>|0 zJ8w8axX9p&V+APo_z*lIqI#3FvH8wj&U?olPK_ht?d;8*aNemb*_*eW zCjvxjxk@46Q*|WXDP3ZYhQ-=9ZW&_K(4OkYx z>ie`NAi8r4hN7^>&TbQ>vd6%lYDwt0oJusEfTpG6LvpyJFF>l|k93@IcEq$lCvksCS@?N}LzZb$Z( zOPO|xF_R^t)f9Cy5zc=bDdqOBw8C1vQemZ>bZ_r?o4d*1I}lyYmweZO7{CotIPOVy zf)Jqs=k;Jwq00v*@I=1!n!e){~fY}MB{yl4QJ0d%qKK>;-+-im$ z$q5Z1BQ0T4FcK6Bqqg&T;%*mmxheX{BeEkA6OcD!ab&>XN}9(FwP3wu?D*LDYtZTq z5xNB@N{4>@9UHid@j?JVI)uOqo#u(zVGNu)b&f>V1BWF}?D3fmCufc-4^(&Phb~-p z#H)+crO61bg-f;==$ffwG;6`ngn)IO2~;&LadX{1i6^Qf4=LE)7hCXunk?wA5@+sV zO`dCnlYTw})#aX3%Oobx$I)%o{?qz2SWs@w9ApZY4R;Z1WuI^JFG_L;`JaeIM7#*+I8v5VV_8v%6Wxgd;7PL z^R<)qD}KTu9w88dToZ6r5T=bRiq%o?YvJI!idew@UfCOg{Uji)E(bZ z0`MRA+SQssgIEGiIRlGx55iO~hJ2bF6f}h)dsUML8IfKZAu=!|f!-%`kU}3VL2Un_ z%N)^mEzo+wz=0!GyH0tgM@75}$b}Pt&*A|uf!P)ifv2H6;CbF4y&V}&-$rMF>a184NO+V)SkRpK}FwYU(7gAFBaOlXi#JOVQfQ3X&H8te@}d*l%X${#VhZd!1TQlJ@Q=l7KXiQv?3Fu z7rgar(ylfE0t3@&cbi{1XbE_r3YS7f6vwrDZzP?EGnHrA3w;P~46YP^>e9tOlQH>T z4Cj}I&e%oV$J!x-Bv=sMVZnXP8W@{N!fV$phhh3Pazbym-UejQ2-yMmmnVw}Q77hF z;y(kIEr*C{#?E3PBW*_Bm>S(>_?k1n822Se1X7joQJ2L4Xb$wkd}E0^)P>=WNnt)l zP3QRs#52^g1Wk7g`Vs6Y4AU-NF)6BDuQC0%q5VZ(h6! zks1j(Lrv4-+qxxm^4E0dthA!)8>U_(0^>$qW9=SC?+f%%nw3L%7tEyispxblRhefM zxKgoid$e-2St^G$&8=NCh#1Hg=S1%y2!13h72=HljbHcs`&qv4ulOT)8AdCDT4rj= zZMTCOfE`I`BQJ(;w|~b$T?2rKy^?5Anr2TYtiW9!DY3FO%E}~~@h^x9g97Mh9cpXd z-W5pyzm`$_21HmHu$Ar|bY;*=5X|U_r6S&lXoA>Uiz8EYQy^5F>^{mraKIj7cos+{jOi>k= zMJG^M!icrw)e^?Qm6CPG5&N;lEw|q}NW?~1l37IHSD8U>(|-x^Mk34yrS|hfOR6Ky zG&Y|UGo+8un#4=Gi=m&N#uX_wBuR0wil|0LOP`jLA$t>!ra|35BuCMKCHCl=5Xg)@ zn3g(ghwC2%v#W`c%1WK<$X~E?2L+#=+S2WxJso2`6BVzz*N`~yj35ZHR<=McjlxSN z&_{P@S#C7Kt4Zmq>RcY^Lg0uV?1B2?*DEomjcY1&(4~3YK2J4&BKBanb_C5iCD&++ zX33pv)T@+9+sR4#;3v;DwNv8Fs{XiaJmj;bN5@2K@i%QBLgQNJ#6mEV91F(et59ir zo^||G&iF>RRxc zwWNTETDK)hCGr02a)GI7QxtuxYAQF0ItbH?;r8-aW+93Y5OZlH%1?ccIYbD8{az75 z*{$vw+&Im#1hHWMLXfI9xyuUL0&4MBrbiN!l39YB*l>~aatsjDZVo{vR$pljbr2vC zj^mkFl|IPLR_E=JLf9za2+qQ09A-F_KVeTWNHiDMBj3ZmH9237Uxle>JW>TXLCGVi zwAmMqy7o|wB%KPRmpN$!K^=_%;Cz;&Dt$akv`8`3Q7cCN7*(MG0qW$N{C~p%ZA>S< zCs$W?(&eb>XpC-S%##gpN$H6XE!h`ZjPe@@Oz?*abb4ya7_~7%6=J-BWFCz&S>6ko;0vILhu0`~l z9+b1|q}Fb>&vcs*tMz{EEaE?b;VlNvrgJt6Ku$Ilw1^dItRv{dhu!)n{=`a@M6J1n zMZPO*sT!*!-@M8_Gw@8~#bpp1&MmhBaEa0@2KRGOrdAZCCFH84X|Kyie~JkYeiAq1 zVKj;^NCX#kO77YuxXVi_+{}Y(#DZ=!O}?Wkc7-qA;)at5fmf~V9TcU7t=&PokR&3j zbcC6p=(90nt;=d4vk=Qjbzy#t1q98aq_yN_JHl}$pe69jLY9^gXHlb$O;}Tb+|-$M zrP2g=MuaSRuL>EkPj9}lh%60f0!@VUNfBa3WJQ(ZMGW87{cxd6R331n-Q`&13vqNs zB(9x>({B8N&FUnp&Skuo({jsu(3Te{(tW^Eg!G@Z*r{3UXHk{uanBLO2%vOgq$+ zp%;OP+=A%%fHRFF6Y^x7XixG|%%lYpEd}0lvD9^Ts)WV6a&KkF3!phOF4S;Ff+|gB zy?I9opC9?pC9W-LI!^A_mOg(9qeW_!iNPW8s!Qco5)73y_hRwmaS043(7-O1dW(FqXEKSYsKbqO>nv?eRzN+1&nRP@PIN%LODveJP@TXuf? z;ikORZxUO2^!YZ_U;7&*Rh9wxY9|))-|Mo%)WyS-Gdm5O`p|vte^78(XyJj3){r0% z6V33q*SlIw=+wBDW>!-D#GW&&z)Y>{6D8B_>j!N8OV3}RB2VD(PTiG7efNWL0nIf( z+MGBdxt=Q}mNgYVF_F2xg30Z%Qvo1eAV@nC7N43Hytm5Y*Ci28t|BV#OU;zcdvGDJ7K_D6C$h{QWu0?BZQmm-yac8-dIv>i@F= zic=|%|9M^}cVqrVvpdmw5p$S^^R`xe^K7HD_kf?B34{NYB`e5{!bG0Aiqx$1p>_#p z+Vh1(_C;j;PEJ0%_w$+2Bi|=$s_|K)T40tYw$Di-`@EfN9Lm~I^_5VK+K6OdcH*!7 zW<4wsl{D3c%*iPU_?cOdmz>EhuO$0uU944#MOWVwLRIZg$PR8KZW)>{E|q1+zeePA z#CQA|A+Xh;L{7br6vhYZSAFDO)RsYYVmQV;sG?x6mr772vm$*Q8x;IES3Sg(4; zo1ulu=qE?wqwvg}{3|ObnCMh(lOaI?dwrA8GSn+QN5LHYA@z#$!IOTGRxZrbr;v21 z5hXO(jYs!M2*?Q~e0e!iQfAU2lI$lFg+da-blkkPVS9B;^Xxvd3AUGrD&URiq@P+?{D6-%dnoi%`EaD$+(R&kGCBAhzgHd zWh6Bd5R@=9)ujPNm==q3blIU;CkbdkVdibnkS&B(&C?a^125k(DnG#HSrPbY^SY{%0ub=We4LNONzqP3Q4o1#+i54{&nYy#7 zC`HRjBxw=&+`VeVja<_3EflD=tLKKF#f_;gH(IKISfH@>^Zu6aSuH_2;G>TV!)WH zy3~D5X&q>oK6s95oS21SD?nUnT6O-kT=gt&%X5KSzIpQN&(B6?e~Ez+1~X3Z4}c~Y z7%Jk;R^&DH^57JM)4jy><7pqV29gJVFbL^jw+!cBOBBqOkL4O8IU zVhT=L(U#mT=ELEzprS!QiD)7$u&Ut+n^Nyn!2Mbc7s$E6V4$0Cqx5zNSG6(x^&J9r z@|F@9;$3mj$UXz0ps7K&lSe~ z+k99^WZLRbmqm39+jz|ER&w++3;RVI6lnto1*${&aPV9gG?c$~Nffg^xJW_?#p~JB zfer~fs%F9?Crkxhp-j7CQxi6*4uT2Cc8CEGcx0RJm59Q1sR>ji9NtBE^cI%vyXNB7 zsf`Sbj}&`=pcMjOC;|t_IG`Jg{S%DFJSnW zLL%fRALyFTPC^tpDrEjFLxUOuODYDT>-SFRmd&=WUi8+UYnVM4vGFOg1L^oj`kMCO zzdS<{zJ%#b=;B=ev4EH>n1r%1-Kh!~NL3*$ z-1wZRKv!XXh1ywg#-g)SkQSd9b3!1jqib-IJ!uYsT$uwzef6Hy${{#MvDV9!5qP!IqI0f4?y7%*NXxO$8(eT749Q+bEf=; zsEwGwWS|a1Axqn^TJ$bq1aZZX%waiS>6224shAQm8Rj#VkWnP1pVd1hsS8ryZ}Mcv zBUMseB*Bo}=?p~rh=$YUpC(LuHBg0c1%*O00t0AZ`MCX1I&vK9dIqZAVGyP(UW-Y> zCjDm5;cpXe1!5Bv#pKcOL3z~JL9LCNN^TZA%xO(TQtTF93HhLS&~k6+Tb5$hin{9O zjF%nfP`l5Qn<5@DbRsja3IR=@Iyh5ENtIz#(?iHo$W6LsmulT?zdA=SsTt?adx%+v ziH0}ms80bD{Xzelu2o(9*%jx~d}W4JPYD{lC71fv+JpzIwekb|&`D8F|&*k4hZ zN5k4}?^Q81SUjbz5|nQ9Q49XK>QNU(&EuZelQb~;LyA?KH<{Z}gd5U!ytd5r;_1WQ z{`T+M^#ojgsR$X5?xdMfJ#50OxO}Hkc!J!bRDLYp!h_eVF3QG~> zTDu<$jW;Vc+>~@^iD4n9GZ^|I(YO3a?8(y7*@Zq)xG zuInwIM69Y(z>;euo3kAY9Y1)fb-N<}jJ{oy#JryjZMi~^?R0X9R7pFvyxMYl1|p6E zH}&-d?2-UYISbS2WqU^1Cj^@67T>NDy<11*ky)3RQ=rmGW^-h=(MrOi= z_`xnHpgmoi!TUG{{jrJi2uc^$2p+j!W!T49Fln)S2-i3Ul z^UCBhK4-stk%DexQQ?|MeF4cNiDH~~*=#d172TSf2)3v51k04zh}Xs=c8h3L^EEU2 zbQ#3cz)Wx;F|Ai(yy60{mH3D6nE;EN5L`rN>8$(Gm@f-EJYQDxDgiw$&DQ8B@?`BO?f<3L2SyJI{XnG^oZEWa={pqVW zkE{o`-f(x~FRm3~{GG&gk#UV}pRM<82p&f(Lvsj}4NfFcuAh_E=g89o+WgMGBL=QA zR7q$zngyc6<;$?bzvg4t!l5Npji{EUNROhTG6m;n4wRB3sk@6EA1&nKxFc$c&!zIe zq)mJ$wKMtKwN)+G?D2$m#r%li(1!b2XBEYiMQN{DlQg110VSMW$V|*=h)ez+#+0HT zMPULno6p()@`IQ#D$-6s(_4^KCs~}P(VpDsj94_@YJ+e+S5En|e8ZCvFFOiiik8$( zI|iq+TcQ&yE`9IlFUYZ80(NOzu$c%Y^ea6W;lt`T+0<@>cC!#ZxN zC`8=Jon|=u)IxGs`b5KNR=R|i)pbz?DcUduUd0Qe3olqgfh^Kt&=htgf#T+@TPR1* zXX#3TFb^jbE0wqI=I1;me5vfBs|U9R-TGT+EVl{b6<}U^=4@f^C?7;%sbDNbga3(U z`SxWrC}5fn??TiSQKRSNB!ym%?Gq-dLCy`MHCtkr?wxDBW9hP8f2i1bxde97xJAnU zp03%*Sx8csQ5fJ9fjuP{J|s?oQf0bpGPlUmXsMZ%yU3`f30EMV!p8!m)1;^;8KblC zpjL$|99DETHpS&G$W5f=nNWJ|;yctwh){85sv|myP%n^|)OX&B&@{EDOAT|QBqpbvca^7q}xnE<|WJ`F9seu z+k(2!3dJoD-V&l<-jMwat&b*DF$Viek4`Sm1dL6w`Gly%{|R~HvHP5cBlzO78&N9Q zv6BY(jW#9?Y0|=~v?O$M1yUPQ#XMz8mzFp4?0&gC`&yF9&KlM9?^J6pofNr^=ZJLa za_xrzGCz8V{#i8ILR}%CO)=05}j!zS@LyHns4PV$ou~G+zQ3|>7g|ju4!6NgpCv@^S!2wvO zDl;A%F7Bm%$sfJy%SLkW;^@?uK%3D3+~%pTI+YpsKB^(5okM=uR{K{ZMxs7pm-$cA z1xBN;?K$Lw=j*beIwjOIAIr1{ek^SD2VkN@2V6U(l=#>?cA)zw7|5Q^ZoA7x8??~l>=b%&+kvI7bMIqweaUt{7erclo(k$N4i6J<>*|ORVOsb+E-pl zQ(W<6W!ws%jo@N*#G8LTm!?hHQ+BRfJVcizSjlsS*TSe!%E)4z6TViKt*Rg*oz{03 zb2^$9WN>{WDDK!|)jv~loFWfr6qW8qa9Vk_Y6j?tRsPP6?Mg=Rq6pFfKr6t`m5Q337 zitJ~@XBZ{nGBD(7SW6viB7ZE8@uIUSX3F%WfUt+NcziMssn(>Y=e3&MeE|eCh2g4K zGFL3C3AbW)ZFhPoYxtZq9w592;1v)7)iM!!kuplgS_k^kEIPZ3=| zmDfBXO5_tiDLtYU1Hyq$gAJl~72b$I3ZMkNsbTn}W+)Pv^%j1fus?EPXecmAd@_QMsGnU&3lgV- zFi88FvI{XqdDe$cKvK-rcbTgBW`hMMT7blu*W?vO=1LL+gs>3}#rm&G!_|zG_{F54 zC+N9qu?DUuE!MmGv zY1~IU5;Gb~yJN_P)$=O7ZMVMQ6T`V6Ly*XopURoeW$C{LuCdp#oMw_q^qz$2qHdAU z$lO;dKF^S!NZUN4Z{k0?nvSU0)m&e799mT;(IY;eGxDHlZV@8;)qRvEeU=7NnfTHQ zgQfb@LOga1qNJsB+X_orPXtN7{6$0XF&fj8xb$Y@4kbXYqI&1DJ(%HNqo=f$xov3lmVR5w~$OCxiAE>5r~f;(14=OE;BT8(;z01dO5BNj@kQ` z$f>^sfOgZbkVqA~r1~GzaUzpS30eXxub|%?fX3>U{uygH{n&yD{p6*`{*$JAXTWVI zJJDL;PTNulAdjXURk}k1fGLsg z^dKqmi@DV+m>OPQZ&EK38p(xHP_@`nu+3(&!#-2VGi`5Z;DC=#tJFlM7Q(rqxVm0Y z7)OSpo85ZA$Ba~NqVP;#e7NjS-5Mv%`kh&!WxXbPZgI>t3m2E*r#K1&hH>Z&uo= z3ux@7D6dFZ@T7rx2??@q3$Pk|t1XN+MnIL!u-H>$QWFYD7I7fJPO3rOqQVM8PW&Y7 z0*Yj@-KbD)&MK2h`d+6nk5jjnu{?+8PlV1_Q*x0B8f-`PyP?$`zvZ`;6y+|3N;F%J zN8+;{HQsMb<%A_pUlIh$*7G9|Lb8CknAc62_>&~_^)$A#>rs6vAiUfl`$RFkyw035 z#4Dcrpvk8t9eks^7u)(%1gpi z%gj;ifqj+yS|=C~Q)-#_3Y~~^oVF5U&JJ~)n5OGuw|WNMi^=(F5*pM%>~i_#A-I2P zq$>i*W#*U~X>a0C#ny(&lnw{t;S%swMplomyU~+UL3-s0h6`j+%vMMcXLu^0coj;ISC21ZTN7MUlLIg4ZzSr1@zNX5)nLqDbDeMb+%PBdgPR| z1Ty(Hoim>}9AJ>U{Rnj$nGDlC^->m!9~xO?PB$_ZqUmdyC6TCztVarD`(vPVMz^lZ zdJIu$%$p&EU$5?ss1%PiXOUzf@A~i(hVatI>~VQmU{WO$1#q`rf~LapiVcboSM#|E z8Hx4x7@E$yO3YWkS0I$r9k7e&e2ru4`UG~q#pNP)Y9*8G=EUMh|1s1BL6ejtGl7l? z8I&O9N+mnMKGhTr#>9(y7a(PzL^mqDxFryT?$hO;HrKAJFR3r7 z_)@V1C<_v63<7f`)u_nmCHeM)=KO)^)7hl+v3a4Pi$d1uaUF zy_TIGhQM$vaV!x&BPM-yxJ4-3KskhP${f}LcJT*Yju$ezwAx5Dx48-%UT%>*=uj7{ zh)?P+6$c*0x|yg3h&TY#Iy=@%wI_*h{h}UZ9Q$Q>v%1&2`N;5mPn7XX!5KD(6j~O=MQW%fA@jOY{wZ%>@w$?S|Lz zOPsr1VSauInZ$&}_TK@yFgpQSYj~xXG zbk#YGGa2HHo2zCKEP@1tV#}Ovtb_`dC$$H-q0Cne2yHSutn|hU1!H`gage)NM00?D4+5m7Ffb=+^ zxd5oK!y*K5^|xwwjM%0q+a zr>mHY!KK1sIbJ(YZFEGS1qeVEatD=so(T8^-f7-)V20UJW)b+Js)U95+|B>!eA2&h z45A?^XR1AN^Q-Y|w%z10b?tFkFlRMr$VBio?X+cE)JAFDNp{b_f;lZ4ZcNykV4&7W z@atw#83}A1Gr?ac?u06SvhLLmNBl{s-OHjtk#X+Vf4okfByXO|No+i1w3Q#6Mn}Sa zYA@Bt)I=rwdTUbubl9**a!w(<%R~|{E6{80=Ua;3mj?-;fH~ee7gCgN*WBx-_G(lj zZF|X|fjs+t3z=*Rs);YIN>X*_zgd$ug9DPX!g1WXG)+225;CsVmphgygxfLU@Ws!(o7qAW0Y z7Y-%T304lG+qPqz?S;0~xOA+hefvsB2fm`aqa3voiWFVCHE&N@gDP$VA`(nXD{Mc7 zb?RWD#G=FPy{0<7bQs+Zp|rl2roahbbPHU~%6^mTnsnc<$~fg>qQ(0Vj2O8cOjCt5 zJx+xP0X#6y$5_wMR z=KpqZPhV{{>Bxdjio15ZerT``^p7ssbMO(dVuMR7C4m3mMWp~q~9uP%q`<$9E^ z-la7%PH)obM<=0rdrDK%z^U5xrpoGb`;<)cd9;Pn5zeNk(3%vEL7$&J+<~$@R#&`7 zO8-PH7i^Hg&*M(Z^)%h*)C^J8H;AqGoeHS#-Zf4Ht!&vCJ3&*vPb&R5H%%RyQlUat z*s@lODo_tU0ph&I@Z8|av6h9dvkBg9sGylmy)=wU19D3MKE4HfiZjgh`v z)YW1ob8f`ikCsRpz+Nde>|sKql7vEA0r!au*5qaE9`06Qq90E!O!*_giJBQ0VVkGr*5xFL^32!uXKe1@v^8LXn!{ElPQs9UMAiEjEaU5f>n>!ZOV_g4=i+ zaHh^&!&-^ve$7`-SR{78d?4}3JZEe=k&r#4KfZ{I+0DV~nI?$hZT{}=8-~L(yfXR@ zgEA{2kRLWO3&Q}*NkXY^B+oA1glu0*`1XF!#fh2A)S}_Ub|SPN4w^eb-(L%WOA#OR z<{{sYYWiv4gFl67uGJZ4(nVL3k$h_xDi=~LU2qO6xND=7FCNZ#Zj$Udj9BXn; zY+D-;(8cKVH%f9ZT0WySWTaj9INQjpUZP4mi$eLD)CmSC&q1WwKrc*|O?JCmy6BSl zEj`zYC0Fu4tA(9{o>I$VJaK8owxty3T~B9l*CYytB%bt{xKB13j2k)ZWoj{SyD+L$ zZ)a$2zFcNpE^4PuUs(NRarKslR0X=LwY8W~!CdYr$7RK`p@ZY_gFrMlqqttsa_`~7 zn?$5>#9>T8W~VSgswpnC)WPNG#Yj&5;`NcKAjE8Rj8)#9awC?Z=c)&%D6c6A>Uu7z z0@GaW&5PbQSxxf_@>8!|O(Uk!Wkj(HI$4RQcuCAzauGh?!*N0f38$9tpubrMqTwis5`o9&tv1ZIs6aR?j&|6#9%MAi!qdP8Lec+O*t)}S_`r~zjf=VKuOpWz}8ANbTn+c|kPgfm7K3zys<+?n11(~Q&*h*k; z^s#My_ow*E2DGh`S{#4Dnu*>6g9lkp^d z@mk7gQn7zHw$aEl{#@mAbrWw4CT>Z<&EG?&VFc_E_lI$rg(CRI+WOYZQiWbfr6ki^ z%vvbR`%K^z3C8AHdAVvmf7ViI^RUh@lI$ac5x2360+=eNYcg~^fs8s;%3iL0|4@QU zfM&GU3QZOm9rs6JmtlxAHs7U$WpyLSm%7gn2(5AOSa91L#dvQlcWhi?;?&CEuQk}l zWsY_v?VbYxS^TDh*;z3sceQMabG=2!UBYap-d@xyOaV8cqJlu``S*cFVt^%LvFgnR zL1rRRw9N!3ZVgc_@V^|(Lqb|^mr#~mQ)sH>o2~PQ)D-<&BjL|0=(MdH>kfkM-8@9f z#{LU;6l*4?Z33UfReYZ$u<-fRNJgTF^>R+%RQy=cLffy6Z7gHD^|3Fh&Vp(JNaG1( zeM3~cs`N4Cg{zd=fl90KWV+hyQp0IgCm1*#hsG%Mm0R4IGvac-*6Io~5|!uf^B4Sj zT0$u)cPl_^JMt0R!Ip299t)&J6p4sxgRHHyQNk6@va3JV($Np!nWfWMTXF$`DbJ)&jex#@BMw1sYo5rFeF@xEapP+shgPt2<3`)Bu| zyAcqk@WfEDd}Z*C-$qLTE9#o4eh+%P&x;8VcVOx=+tK!clONs-)Mtygw23173=?|vip8?WQ5?V@u27##=NzQmi<1qHEGvWw zeOKd@(s+l%1y;zgg3m@GBW02$#1J00%O+}EuPm_?w4SbZHDuD7=esvx!sVV-W4paE zpHYa*=F~VF@(6Q>@EP+3^ApPC7ypQJsj}kUAJnKuDH;Lw+|4YkBJPT<3>J3w6?GV{ z5%IzoEY6KsA9y(MRQhnUY7kPBs}@|X9&K-`UJ`ULFv>gD;p6s}-r^=RZZl5H(z*g2 zk35icA|+h3R)yZEDl5`Q_-s!_`DrdbzO%e{f$-iU?g&oCnx(82T|LI`I5^OZ>bKcw zp!+F>sybyD$B(xa9A;F#D7QV9hNsb!>uF(ibiJ?jL!)g)S| zg#N)iCd(`rUNS4o_z!Kanh~OY8dBz{#aRKByUQXzT&bJF4bSdMoCnh- zSIR!?LjvFn8xh!?(lJNSDW#!glvx6{vAmjoS}?eh9d6FGT`8tlGJsih@#$T5Su?!oQJn& zdpUr%sC6hxc@ppvfF$o3#}`n6pA%k%_Uv#5v7seP7l)tvnyhv&3XW4uIyIS~NEt0h zAu0(|R-n|UzLjO-YAhxXvKB7oO84f6oQX8*FNwTg$BtKhLVjupnjrN=7zn@Vo%$+Nj<(AbJ$u=Pz<0o5qI{l+buiECLGGLZAvFSW6u!+|AK9q5z2F3r; zIk*l26Rw$TW^wVRp-P3IhZye@s~=9 z)-f`6EL{vJbPz5a-0OBZkjd4x@QNl93SL$sGlMK$$$($Cb(m4qmoUBX>^ChyNI4RQ`%dP11PJznj@MStHTeN4-z$6da zge%KZX1@0>qQ=>`2u(Z+2jxc-KXfWe(@;jDxz!YV)pH)tK9t3##HK(r=v3PD@Po9< zl8x4(%mFEZKyg>34$I21Y5oZOs~s&oshTET^NVu>sQNA|8m@vRWEu0LoJ*}Ir)6sn z=gv7NL8Om7x!VF#C-Bz^L)pIgQC5Y=rpSO}Tl0<6nkbjnF&sF!m3Uf=UX*=Howg$i zV=q3LUC7CDN+X+b%;sXUX4Of9sx{%|>|N4(SFsV=!5@Z9!Cy#i2?)5R3mZ_#kQW6k zZaU!L;4`9GJ3P%%l2H9(&4uE^f#uOh;sha^3m?Hrjg+!%B^8|kOFivBCb$sjX7t-f zA--J!9{J*1lGTN|8(6m)aiwtH!a7+`(HS|v5_u2Ki|Tv3OeS@K1z52tsu-lG`^zzmFlq3#JkE zk}1CZyf%b-F+$@TW){ZnDg!B9!534)@oGI18B!CdK%QL40eX?jyzfvLy>cT`7A3f)@Fzl$t6O>*EBkuAjp1fKZz^x68ODn;WRuSJ^X zLUjI0kr1|xdzh6^<0{gBt%OWVVKGETc}sXWy6qJB0s;;3eN+~)CH4EL$*wgBH$Z(C zhh6PZhw8cPRn9LX(-bj9GZ|EG;MgidY7CU}Tq%B1Xkt7rTBgv4Ga4{>rQSa0B!8V; z!WBg})b~VBXWL6@f;SP{-zhdq0m=N;ejT1%NWXzUOeD}mD%}(XrPgC1`^w}WlJL{< zNHqY&6mn9vG|IC_OKy1{c#R$tdvt}CU8wFZI;X-gV8VuvGY1;`nTRI+l`)q5kkoQz z5Q(Cu^nn81E}J1r(5~LP%>$aUveu>9ehLZPiHLPScyy-+UpaL91>p7>&Wr=5u62a( zRe3(q2QsdzLpRG0d&97vliELwssYJb8#eCMmQ1z5Da z!F7A1Ao3S)vZmp~KhYFx4t+3$(oCRX9F&Bw-A;2rAw3$&yscGt5lwwAxjN)Hp$`>s zBGgK6N<1g4!p+&XT@Y@jd_c5yI<|_LK87I=>IevaqFtKt9w6(t0j=0y)vjQYB?xJZ zRuZYb+lhfOC|fqIYdJ3u6F)MfFM!K$*{e9vvs{Uvw0|HmTNk?a%Pam=8bvWNPzdco z5XHou8yvWQAb_rs(h0+Q z%Vksk^Md8f`GFWGNQ@9)t9+zt3IsG%y;=C%KcLIwKgC9!j8M523s(tG}Do=UL( zi%Y+9syZS`1;R1Nvsv6({HY0Y@c%x^ZTwR)gvNDAI(OWP^S1+3n&PFKL{9@$heI@1 zCYO~HJN!`Z9F*Sy(u-&>j5Phwh=BY6Xx@UiN@)+A%D!$i@e)X&i8s(IXpoBcRbxhS zK$wAdbG&;RyexL?mbb38D{v(EZvt7MJ!=A=2(fGyAjV1q3qGclCe3w_lF4c09Yxk< z2u9qWq+|WV^g-)2Z4=aeF(NS&#;$0=By_rntzi<5IO2<(fi7PkR*}2%P4oK>M%+>f zo*O57&4;+};^@QWH0y;S$f(czBjT` zE}=O_GZ8F+VT3mOTBfmPh&0-6KA3r0TY3oqMcA~NSTAH=;R$lZ z_aZU9pD@D{WsP#@?iS|}g=6>cR8lf?I%yEmhqdxq8*JyIKNZAI4ea=4$Vm6}swnNn z1|>&kST2lGd79CqUpr9 zct}08v@_o|qX-KsK@t!NW1C^Eij4i8thN-U86{HaS@_J;?<&y5F;J{ZeLhpkZBj0# zEK4FbZ$_uqU_5RANOe}v_jPa!gyh!p+D#Fp6{RNQe|AAjmW z3*H4ClF1HA4N6w(j1dlWLI}ge-*fR-%?8RTr%;;ba68Y~5y8-0%UbS> zxFMiho6PS!=NjoZ{bI>1;1xR7TTx$TB=7GQ(f~i=GdD)26Ue5h6_b_40yG3vgiQ^F z&kycV8p%8^8%lKo#xmfPU1Up#VE>8k#0M7q*=PMPv(BT*gWUG(Hh#o{^T@e^k!5@g zPoz~R*Sc|}s@lS3BON5X?j4-8YQQ$4jS3P4ogh=v+ zSi*(W&{l6)N9-9Tul{KuHOo69ejU9dW$OkpdK;TzHX^m6j6j?9Fkd!yzDS)OU*#@x z`|_-4oKb}CfvXIM&d2W|nYG6s`>5KjVlBD=#&$MTnan0IbTH`x;Z#>w8YC{TWfr9h z3S1$5#ZDMh&-n?MU&Nq4Ra{i$?vyxpb9ETBOMrh7^?^Wch5NtUc=m2|mXy}koApm! z9YR^nMDLcBs+InW1IqT`SS5o4-byOyy|(>z2+9ljqx7{ws%5@F3Xls9k6$@hR9|@p zk`%j?)FQ`9_O9;8*gKNc=zMX6&7M_ng>p-E_2?yZIJ$7W1gGV#CV=IV_Z-?(#fI&p zJ53IDyx<+`A!=1n0#3Msga<3YaVgMS8I=D}{nUpiKvbcFtc>vCE64Jck)!rL$S_Hu zqIVGpMJZ5HpKLG|-JViCVGJqtSF+`*;%?d@O*ogt!zwIhzYy(okcdY%()IiOWJ*G% zk(OhGqTw`jstpPs(&a=5kBk8beI!JQD1d^ndBIonQ+c~!Ic^NmVU)rlNY)cb8>^2N z2j)RcXD~^Q7`9w}GvVizqLfl3#HS5(N_!B|P3HnB%s$CJoO$?CaH^WL>K8K#C1Snr zazLc9fL*^pey(_;c*xP$WD`d;iVXx9>eGMPrO=w&ex%x~HQZM55n`})Xsp8!S4?hI z45O_B$BzU7=N`>fvC`ohgaq2GQ3@&%&ZD>oA}B@awGHNBeYz)`ZR|s@@L%$&Q^swv zTQ8M^kDw5Xh0Ye62M)3-u!`xAHu-zcwY2#f>0g+o*&iR>PB!@CUfr2@4Arps%6pkb zEC$x3B(6Pv%!Ru+dP)hTY#x-U`BMsylhUfZ!llLR*8wEepDV3au(Vg_S*8r_pi{jX zP0Tk?hDs?@c^8{ZopOj6jLW$McZ7A4zm6YS$mt7olN#CoXJT!24DXQr#iI!2K7Jd~4T8Lsn1Z4A`UZ2?<1W!t}F?Mx~cWxaa5 zRYrwDY3UK|?W_9Hgp$-&_#nr$%G|_mca)TSs@p~s2sg0Ii#BrGX;^qDzt{fH(sc*vbjrUgcfXbOv?-1oR39}O{4Y&#ltjrcYu90{FjO|cY@pgM1X1&2Jqua})o_!Q&4LAvz*6aZp8YPwo5JRsf4|Z}?>EVO1@CF{L|w z8kqiuF=rD|)OtO1oH_$91jHQ^*LD69F0z^yuSE3 z9K;J@6jPLjIuT}F+?))Um77V#I-G7m)>z89RAVA|V48dung)piKw@!vaz8w&`VPmT z6|3PBc4=A-+4HM?rEc`(5v=SL>D9-2>*JKxMq6T`1D7}B!1DNWg>=+iy3D{ zqxcJ`ypYo6g*kMFFRJK+edYp6Ij%_8H{H&K*i?@6|J|t6nHmIg4wOL_-RIisc2x|s zMCW$a^d=e(&^PG524js<&-cr}?i-Y*;lSzz(QoU3)b?A0gMqgRG84q%>havF^e z{!s5WrOd*gap#;|nTSE@M_8p|LnQsfCYD9Gur^#OzQx@-bT8l>wikk97YFDvH*9!c z79yANW&VzKXXbdD?TXDJ6*OlDdwh!lR)JWeZ!o+p(sf9V?UHSuI+;&Me+?)(lK0^k z@OF;f(62L7TWF}Np*lp6Sv3Wk<54N1VyJg4I>dp=Yh6D4TMbK?QFr$txlL>e(-zRy zek)?#85IZpCWjE@16M6ex+v6kf&06n;-NNjFMR><_rWr#M?+{3N74Gp$?OrNO@gJ5 zjFO+z+n2Rs6*i9);dQ!p#?=gevo)0Vhl#00&QXbaz;cbbJ;a&1ER)GMx$9VBc_*Z1 z_>j4)y&i|X*4ZRwmCTQ1KI2NhcTORzXSE8=EjXJXwu{0~ky@@NvNKypH3)vtayID@ zLdHp4Y-hTkD|9Ciwxa0^s&9WCs(Pe4h07`x*MYKp(UEob#2peepvc|3Cju^LKi7CMg6_R zU+_ax6RsaEUU1DqKul}GXLGW8PZ35Z@u(Q!$_ryCTtu4w?UG#(y%3_B-WFwlHHwi4 z(;wDY*@(XOI)$cU1`-j|MCRV<60oP4{#Uspe>uvVAlmYt>Fv)(HHz0SwLB?FV|AFK znr*G*%y)j?P$2n+O44OP^aPF_G)=d87^lMf)o_?Q%DDPKrxd5b8o5lf*mX>np=gyh zW$XC}%eU(iu-_|B8~J~9ik7j^OJyq|RaYBcb)Rn2+{nhzck@XMD6wtcCfca$37P7j zf^Vy!M1`Z+i>jYV6CP{eiYo^BjPyFOCe$iYk{&4aEw#BSc-P_TZ0`x~PQ{#IH+S!&a`2UHw^Q}(xsVJ1H;^(ca-Xyc0tTy=YpBMcvrqN)g}dZ3L4 zccmiU^ClhLEb92H(se70KjE5yliR2+$~Y~>Ga;yAcTNpJ2^ntBORQ0c#$z-wf(Jrq z7{p$a3WexuB58@HgwS~Dw6(igJuQA23uB%C6|{u7y{62LLAw;aXbXi1c0_QJ`tDfI zyFI*NpW|hTgzsViFe0!7}o3hosr%lWte0$mnEUMD-M6WuBJ>n-ne?jWU(K#sj6TOqg>U5|ULCo)&Fot6;#I z$J$yZ#1n8O0Kdn)XTzcl#KKo$@{Hg9)7hSiK_VJbFu*)@k&O%y&@~X9O7+(Swh>rv z#(-4B&|N~tq`3vi++;2d*u)D-S@=kWo`Bwf4tx|iT&+VasxrVUo9?k*%-CK54`8j1 zNE|HgmgfX386WG?PAk_C%IM#yu4J)_-rI}b5`JpTeDE3H*_qYz7Ym-K_DD}IweJsg69<_NXJTIljccCdY{45+ z9T+WiPio{Nzv&!o!yeWeEJtvky-k~TK4?VR*wIiR-vqzS@+)B>kusi%A~0(rjhEeyX^iK*b) z5~w8_NwAN4GzaLM`jkN>08IH)2YCN+7eR91WP{See#YA^Ee416bM7+N+9tsGfa;h- z+QR=x4E8NygZW_@{&$cZnjLsM;C1OlK$BMO7`vAh)>5F5P=n`C=es!*%xxexu6MTM z6JXRR=to>r7OqP)bAQ-ffnD*H$)yQ485wSPC+2VIRQv-RarwBIXd)aUyr+VJ*Sux) zw#S^VuhA)Dd-*UmC|((;%fpB(=8>-@H%ucWVq`*54Z2kRD&PPR#L=Cki za&i@W|VJ6FzsjxR?HrflM{|#C3dIX@hvnCzUJAQlfBQ@!hV8 zR?*%_h({0}D=WX4tQkPWh%p-YC=B=qBmU@$q77_`$Q$-e52ceVa-dm0@{Sx+-EHC8 zw=04n77c6%IFq=^XC=(CGB;`5cXhK|b1-N+#H0bitJ$-_o7&b%ov2kGjzF-2R8hAK0G6?2axAMKVAp04YR77Mh_&_0TL!M|i4Q}~Tom_AUN)_!D^D*SJEx*(@ zYh-lDjY`#1VkgGJR&Z*sj(y2oRX*~=gg$eN6|3X+-9_%zsfI{_qJ4d%nI3d$)E}>5-6y$q!WJt1y$)UQ`fq>wH{5~ zCf28O$m(^LC?+6^PmhE+kbBkaa$bs$8%KY0hS=D+YV=+F3T*9Vzf61m$5z~S5ZP}D zJkYRo!?X|J35vHoHl+gaZh;BC#r<8ABbGv1S^|G<2qf;ssl`Qt9(wN+6_GVP` z#Q{S^&6Bu8oJ{sa(T(R`uFEi<1&GsLAo_UOH+Q;di&MS7+8wzAqi^7;gpfBG$ z1BS`$R)UL_`MizK=F*21$YkY@B(U#=sdysbLVK1>t-KR7c?{02`EHDOit z0J%D&zK6``XwTpL!l=`24kfQ#pzBJ1`07MlKVg@&Q_|m&K2IgTMs(L<{SLC5^*eXO z{&mHEc!iZB*if-h*(>LnJXRxuPklWMJbs13>|`4g8VYBTmYwfQNAZJPA{6F04w8b% zfvJ$}QCXEiWwh%j)s}w}=73Yd_=YAj%%pDJ=pyr41sQGhVWKdfF2Ob$cso3T$zQS; zFB(2k3sxJX8w|09)7sadO?mJ{_cg&+mfm>-z=d!4L2Vlf5Ffg3rMZk@l zM`Jq4J_$EoJzQ*Gqy9*MpWC3U`(wb1VSkd)y4O#VE^jk15{ne(r)+n!ehTpBMWV7w z7Dm%u-q{iJE)>ZTv~LNIT?#@ld8qcrT5l~qO;}wPR*rgrQ^|Ee&HAxy_2gUp0-b182`gPQmpPMge$4U3&D_ykphxXp+jyo$aVE6 z4ztbO{$elH{e(i0nJQfLi1LCK5tvZLaK_h#1`Z=i3GkcVCwH~Sw8)e%C`ZiP6JiEe zV&=D+AFRY?4NgLc$^&GNL22;W4D6CYig28hFqZkE0K&mp+eQ|lP0YOBz7{W+m_hyu zlJjZ;g7oI=yDDU)+_jR#0FUbO9F4+>~GdoWKo+~ z_QIBBe#wZDX`xg<5JtiV1oGOkUUIJ9%r@AGDJMB?Ykt{tZ^?8aHGUoUY(>lJIK=)S zw9#snG2Zx1AufxXl>cwODRzd%z>5_LUI-)|*yDl>LmAq&^g$;_ZNK$*%WZZz%v#^N zfPivfqb#7aa>I9R3UZbtx@qWbup67dmS`>48p?vAVRtYl-G9q?4 ze)???)B-G1VdUW#oTbYl?N-}h9XrO2JPO1V+_vvdLoeAB-jrw0ea8~IH@d!1Nf*e= zK`bIt=G09(l9A;7tCmdP5u_E68LDeQlZ#!r{0&*Zx`& z2$*c5`;WqzhPfdlcU!La2#zkH9aiXco6vdy>Av=}VCDl47*yf@QE`&qw6Ehe=&Gc$ zY?`L)%YbP{A684|x9F=lv@sJVHCIRYiXo?e(Y0N@Ov2qfys)2B5 zpS8QSV@C+B?~6+XTax>nA9c6y=DGM$UvH_hCEf)B2}#5S*ogpcmN&djmneP0n2nW| zZJSPKogsM*Z^%0sU;y|W1<7eTTZQpuh0bVKviPd~@jkb+Jg>H^%Q>p=Pd6VpFxagR zP}6%N<P)l*mm{FW*E|K%ID{kJfp5ezee+crBE1x*d6Lz$9!yZ< z>A=QE4P5d!Fkbvf-V}UcE5{Uqx)ByHiC*HL83vQgB0wzFHn>PeDB!eo@oZE8LO~$5 zO;xT>-{YwAL$tN3@l@4JETK9A=maLlX|ey2kgP-vbUx@r@<;tJuI|+d5$m2*)E@Sd zfWg&Vsb%U!{_1!Qxq;Y(s=A>_U-iU_jAQrFZ{1!WMJfbeI=;;iBk-)uI2CZYO(lA@ zaMLOmOg`)=Oj8kN5Up2KH@NfSc{QM1>kvbtq+>=`-D>~Rpi@Jre;?|yS~fDq@F`i& zJaK@t0`!PHSgBOxMbnUedwcTD&_VOUMw1T7(R$QQ>)nZs@aidM5~}m4$xM1W2Xp&S zCOzvn4;!RD3N~q@5=NSwX}21!b%brl2xxoGIPSI5>SP{OHnKzR)Y>4iSdS!u%7DO-G0V-%m*M%r*UF;?Cj2i5D`CQOb!=_)JuPqK}ld z0b89gWJP9B4la)meA}jrqtGIPFZa^Mj;7gqVe07mUG99)CF>BUN}dj7yaZAdmQ6aae2;b8JkU_YjBb}C)!CXYlIPaj46Iixs~)uW zEMI(@3iIaU2Pl-$MGl}vJ4_%k@RUSGb5b9%x3>ZSXe#Ac@0NR*v}-6Y@eRM1W#UHu zT&rJ6z5^aJcfouT3gnh>q@6ws*w28eMO<0Py?f>=CHK$tii%1?l1QCxHPnp^RQ#&q zv61aM_5+ti0<-{0K(@csHUJizA27<6KSa1|cICr9MUnkYi`aeV&81RXTnP~7^VUw0 zN*l4AEC2eh_qoOxM#6f&Opq7cO2n$Cp6QdZ7Q&cyngpB2XtUkDmM}SX{r=6^+2K&4 z2mOhn208MeUldin2iBVxH*v- zh^sibd}p@JcgPzvewWI%Vk(o~5dEJ%oemj5JlTxdB0Mf@S$J?r|}`Zf@>KaeTiEO2qKct8hd04-oQ zxl7{cX&`U2mmCrL$cGRWoD&6A(UIqXMSC#uU8O+zg>+QC1{5(`Yg9hWKvP_L1eR`4 z6AQo`hO5LLqMud`CxAUTuAL2*q*gVZW9=!fY}O>=1+oFrWgl@Mno$souir2BqMu50 z%sMdps^!nVxo$9UAl560PtIQq7RT#nws7qrD$Uu?4YP z=V25BBu0TweCZk*#)cX(4yqd%fy z$@5EU4omJe)h@UZZv(|p=vvXYHj;TZp{Ac|7x0R8&bmWT#LfT4MKb0$x!YW{-9_8n zc{(V@=q!HWxM={mpAxrp^fC%baPqT@WTFmP2L#q1e!Qz&DAjBe z-@b!om%5|wagY+^)pTg%U+6IiR)<|5mQR6#|Bxx7F{*n6SpuBah|DcWNOdY!(@>{y zuSUW95%i@+O-6IeB(hPCkubyq=DMDOD!=a4A=6a72Z-NJr_6cB^}v!Xvbm_aBT?|i z1R}1B5vP(yyOrRINiKrdDf)E*qCZ`wOEX|;rJ5wdBa0JlU2)Kp{cAoMGU&}@|Ft>0 zA2!GALwh3lhsOXAD_@a|!*waD)}C>mb-N;b{Vx~9g(QrVX~~)3VKeenc2+4Oun>%V zB_!_6d-V zO0xmxY4XT-5*t=om}4Hr%h!z89|ECcD_HiBAjBO-7ubFAB~lWedX9SXHAE`^@Gga= z;}%OvYfH60A5?+7#-zgNfy5&M0##^tpxZIU9A0Mcm0}u5(3c=4aw-`QXOp>i5+8ID zfymXE$qNm5*y(~e=#ngsHgdLI+?+VLr?Ax0g;(-~+#lQ*y*>;S`OqnrL;@yYs_DL9 z&{%%5NybTrR4Ax9H_kNrJ?x+FUm?fELw4yJ2)!Nv%;_7sn7!)5Pce>PPm&`}tc02U%hki=Nq?d6s7AL#JM^IXtif}bgn|N~IvS|P zHnV1}Pa>W!GRq2)jE|}_wwlIqLy$(c$2N-|WVCM>1xN9_F~@BRi1bNx0mI55&bh17 zvzFOq;uob?O3bD6e^807u>*@30j+YoU7a#EoCxE*Xlo65@`$mu5uw(~#*#E)p{nhQ z5R*<@Ji4NchkX@N_nW?ilz&)O{g%Zjs}YrAInAVk!KnQMGK97o8V+ShH-gLQm{w%u zc7e(#ln_aF6ZoW3LeAMMYZ=JJMz+|U+6Ae38bIQWsNfW7d0sS)A~x{3d8-u-OwHxA zlx|3}nlEl$wNl~MP#Z}jLXTJ4k#>~wjL@7b#YW!ZGqT6R&>(_X-*#ZD=H%#t4YZsc zK!`kHHj^3hGh*0`@)idhEyT8a6Pc6B1?-{LE!ZREHp_8XG^UC++RfR4u;qFA z5?!0_F>3Tkkmgb-8x7ekz^rm!{Ey)H-hPtKA`JMZ}DByA;0#svQV4g$zvvoNI7H zgx~Ujuf4=&q5T%lkHplx+qg z6#0V6-&{YM=*;t3ejsHF?%_y1huF@DX=NMpSZ@#vAoqL;cfc*_$95~C@cw_VxauS| z5E8(1bAzd;(9M(!h*wYVwU1#BKdp77uFmSVz@ArsmTD;GO*D%$m2L$wx`g*SUY+&8 zh%TIs$-(&N!gq9eq+#Er3!@0DO$}1#(<<$7q1CQyNrJ+0FaB`W$8yDu5mT7$sB9B$ zp2i(0Q}=HW{)TNET5;#Uc>K){?69mmx$;cSo3aGdF10oP*!F@|8_qnjvE-Ju04phX z&MZWB(;UFcPT`{A;Hv5>k$ns^wzJ8UmVCOH4;xbppzXugWz*facZq21^iah&hXEfZ z$So{v#K%pFZ292EP(o<;(AC?U&Z7#21eQMUwU3}074ONR#~r8Y>LoKB1q>IEw8GvW zz^l(k7X==gD(sb5i4Il-V;v6vasN6#D?57dJ{@5^ z@KMK`W}+)MSQU-JRqFcU8qhi`h+21jHRPgGnPp)I__lC9FR85R6NO6WhfF6*jSLQ4 zxK^+&D36K3h2*v-7J2DOq04qV_uHBlppr4X3szo<^3W!GUh#bngFB55sG zZ<18}&oyjF+a~U>pHN1=n;_bzTT?BV*oJp75;{q~DR(4a@>Yu`kT>j7xbOMqyY%VE z*3kv^cb)w8Q_co-D+riIVym05!OSqk#mi5Sz4NMc5LKqA#{Fq3YM zc)m_-dLx>N)HS&1JmOsH-4r7l6fBl+UT3COIsA|kSr??1O899*2Jt?-R6}Me*+(?x ze4cw}kF>R2g)b`7FJ>-F&8*3Rgd0BC|Hj}Man(%1k2wM$%9?$$oLql%kfrF}px!>g znKBjI($wF8Z7pj~c@Cr-_6&F-H`bSyk8iQF@9p;=YB14&6jYkF8tNZZpn_`KOK~|j zN`(ftGN34CZwYuJ!;E{@%^}L~k8uoCpmCLbC971jXlA4UJC|O3G7T_r4iJfuxBBBo zo&8-p7`-7oGYB)EzXWY3N+Li7Sr$B$s(Y@xniLp4M@=5c$Tks#E?Pkb+c#+1d<>=I zckP0fi0&?#q4O^&*cRZ9b0UwUt(V7r@8i5O_ONNX%xd2A6=d*%iJiGGW_ed?b!RG( zJ^!)ZNKmI zdgh%8atDBHgyUkz#ZV*j8mSt#(pb09vd#qEOMTIYDj~vAaJ4hE&VQv5co}iU9~#y^ z#YRlz%tGr3e8KyUVJiB36>a(`Wk9UhMelOa4}Tm{d*>lo)+IUkmMTG_ko=0|ZgX0` zi2}WHiW0;l!Y|e@cGShIa*)@o2h`D)(D2%H5QEAgy^+!kdVIB*`fs9c9{EnpPHKfxp1wtlzc&TKYYLyh`*(q4hT0+6dE zW*T@FbuENoWSZx4japeSzz*6Ab`6vSDFvYRrE!$)Bx_B`<7(Dg!uSLmXfmjD?0A=` zmLq%fA`&niye4TPpkTTJf$Lg1Ay^DjVq?O~qs#4Po7SVXWRYC)zV9evbjg%H&LtFp ztd>v7MemTrk|R73p&aleV;0P^NFjf!v#VBOmyqK??=|B1k%q<`$m`_jvxr_s|2jSK zGt`ODRdP1;l$5XsiH6YW1!F`K=T*(2m+dH`wlA}=hc{7m_9A%(3K;~sxd(gKT-tKm zi_*!}Dl@h)2nuS+E`bV=Pe_5IZ#?6`Xt7W5t6AQ{XqrXbG=8q`ofifZUe>H4ja*GF zAmNncZXg<&zrLTr}A^8RF?nB(E)aCgoQ`wZByW3g0qX|#YS?^ zD8FBSm|~M<_`8P$D%5LZ`u^H0Q#r+|aU_eiLJvO1C`1@d2;iiLaH>c^F?RfgNnT-_ zNz;J^r2AX_HL!DfMUPBvWovB4Ed#T7)UM3ZMc?z; zCZFG4O!^N@Zk)u5fSkx_L3M(2<;3LpKDT6}Ejz(9DfO7mu_9ajcxrVl3nC{CE@c=M z4S*GDGx$2du^B#uwEfPWEkEV^V%Z!qE5U&iNAF!oxnZKMPL>%vc!Go|#T$6qTd`r` z(hSHfwzf|8`Mmy0cfJR*=YUP4B1KmchYcBT2T!Pp*81-nY}q9W0MG-zNgdX>cU6@Er(k(Cux@7POgRf4SvDBy|Q)M3$` z-7#{IC{iaqO~pEp6hE=eU)PAud-qma^}w5)y?I0%pCJr{RT3T1R(^eEz#>L%q^YwR z8(G0~1SYUL8_-aNyjPQ28uk-WMLT^VFqBSAq$TS&?I#^(xmXH6o+O1Eo)>4HoeSYH zMaU`$uzaTi%wL2FqpGSdbSkPjig61rOxOm+f@>W$s31gbwS=InrldXGL`CYkg^{cl z-#JzYtB_5P$#fRA-vf)mP0 zq+Dc4FGxqyCoop&!4P(9oKJv)U&pEnQb1;AI{(4D971(bs?Vn67;sj8>Djd87)>et z6XzSbN+tv-A4Yg-leah+@u^b=|G2EMo6r7+bY+@=&_Hm-s?SK1I2p0Fd}uomU138I zd2~4vxpKK_&cFkoPo{@{1?0#VRd8Uz+ObMp?LPFsOrfzZQn0f7)Y@4eyE?lkP~uA* z(%ML>?h({99)^HpiX8$NGH{y@M2B9Qdoo=;x;ct<0z`#+tMcHL9cgHYcq(Fu=HV;1 zIXJ#o{Yo%zX0_cTYa&7Rx-9mSa)rzx6SWm!y$P|U96>x3T54b8jUWR%uBHr4Lsc%B zWYOGlpc*Bpl3B-dBOSS)?Qw~cJTmzevOF(XV%?Jf*@Qnf&G+iubYv{{NKr+eAja6p ztji?mJ(S4oZXOK*t*@VEK};?RG)tGe8qp}C4`^i(6K(2{DX#5E8NQ2E?IRtba1Plh zP+mIzEv;l+l}bfw{YkOfQHiR~i14Le_+^UA%`%eq`jLijHiBVo&{KV7#cHGLnXyPi z_EmE~DCof4y~#k366bc=)^^To$(XI*sR6V~O*t@!SkkLHeEmNJ1q~-djPFR~fkZ}0 zXUPL!hl`4S*^o(&2}qj?A{#q`cT8(TP$sO0We}KIQcPfoS?a%NpI$U^%RqKapN zQxxp7hf_kqYQ9NT-R4@V35_agdIin-a*OdUCAgEt@D+RSTXM`UM~QoSpVMwpyV&1j za7tD5RSM0iGN)hWp~oH{1juAOp#`x?9WE5Zk8kR$h}2UJLj2&LG9~#1kdRj13mcVV z&q#19X~dPD;6ak>ijoTVMRwf$c#yIUxw+YEHU>>LinQYh(SUpJ(|USI`pkjHSqaIV z4G4swbVKH>@4c(R>0!T04LTIE>OGa-Ep3ex(bnN$BlhD>`EL>qT>AAS)*olDl9IY< zs`l^lzB`oU$%t-Nw{Kpn8X!k1NcQJJoBURMxfuGTsY<@@3VQ31YT@5Xbnxm3nySn; zrahN435>AO|6daO-m~e0KE#Be^j@-1_O(5GKu%K3bqQ_c_(h8??Vhb(SL11RKdx8t z*^w0m;7Gnze*q3Z+AqjxNIA;*$`-yy^NPsE^G7(V!>`BeEle`tR+<#im|gh`Jp5xl z^~J){u)#`{TSlxHZ<3O&n&WO{m{`AKEK7?xKv+&epBz(@5}eIYZ62tBd|ISQRnIvD zFx(ef2gn34+9<)_GC>X+Yq;DFHy|(vxQ&(M7_uI5gCkf(WkhybFo2-n)J)9;Xd%Yn z2a&6DLc%0Nez6GKHa?=tauV*iEkRU}It8T}-;fk^AoJCv(fJ$^%Rxo#6j2OBPcV^% zSzi?F5{P%jGnI&}8W(Wz)WZx3^3vc4`Z8d^k{gBW_6PYEmz8omC_qKCv>jCaac$ZX zi93Lm-ZCm=ptkKmO$$_5@zzsvdeE!Nk!i9Tkwr>*Avv}oK|Wol#)R*@YdUZziy5_^ z8xx_+@ha{`8^2lpk#n9P>KT-M$K_`kH+^*~%%nVU3lvSL!lGDq%#dR&%zwNH2svks z*Ye>P48Rw>v7lzqIYBQ4bR#9LV*;BdJ4BFdb7Tt0{US#ut<4j}F_RJD1X{%g#wKA| z#pXZYlpJIQF~vg|L4a+ORXLm{IOg$g5J!oK#s=(LcN?)5Lxw79fuaQC4UU|j9ut=T z5dUb6GB?-K=#CSAkVg^Uk`hvn!vS(m98N+!V(gvOw@bQAB>#--0IUa?%~=O7bSnj^ zo8}UBR?vLiiu2h#l0aO@_Vkcpmpy8S+EWfO0WJd+VG*>g?QHP^1pNp#;-$My-Q;=) zQAoBO+)}``_KW4y2w@dWaDc- z-~VN~wXV`dK4R}Ol`0}T`QaR0C6jqDdeH;E#S)s;t57>-6nMhC(-e0N!{1B934mYR z5Tz>Yg^rcEmFD$AqG*w0;Wt8hKQ`~EgWXcK`Wj6Z*oyXWABDGl!zILJ?QzlKVB;Qd zMRMihG~qa5*nb-6c?bgSUz?Nwxi2y2y=-rOeX6sTKn-x)er2dYL&wIR(05aetNoj^ zOp*Zt+#pRVxXO(Tp=y@3CS_yol->^_7^-<8F}X1A94@l~dOTOoTF&07@*@Y>&|mGH!Zm$N$UoV-@?O(TCW8)y}}whB(D#cPB8_O zDa;w4yAn!LADfgG>Mox94v8REq6$TJQYc{nH6sQmqQkGaoH9;;&{0y#SYfEPsAR-# zixm`1vcltrN$Jd1afn<>%n22d9n+?#D*0dfrMp^RIyz*w zT2i+WBF>aFMbiCXT@6C>$+Uh5MtdF*6i%p_qQX4F3{oM#L+17^+MZz4oE`u9_i4^q zW!#~$PJ+I-pc52G(l(IOm7wnBm#uc3i{u%!#Y1eF=QF0oOuBbVW?nYK&`$q(D1k*L zI#i*{;$%nwsS;{o`jq~((W%Wcv?hLd7n!j{wRY22(OT5OV7gi35Lsr^we%xGFvosd zwka%+GnhCmAn;0PZ2|h1(Iott|>3d{aiyldxI{o^RIDj!oRZuX-k| zH$r%_Zy^hh&UKsalN0pNWR{=#QDekk6U|F58eDXV66_|L2*n7xOrj5-M_o~umq6oG zb$FQHOqD(gH;&%pzpK~K$S48<=ITBseBI4xZbA}4(mHCvSDbmElU}5g2EIoOIXa85+*FFy&K$LQtz5BRi^c`D!}xVIWqGWKW@-M}{%FiAX%VeUj#@ z*6@(qO_rYkYa60Is33w>s_v{REYb&Ev&=~q!R3qlD4e9*6?0I2NJYz>Bat$z#^i5k zc3RC2gUN;LmqykruG=gpoYBs6d3kd;I*=k0>Ow`xV+_QR9NOWRA57nXw1^9?@}%N| z!QO6=?DAZcSPjw*4$xe&6NQYUt3OwD?UGWK#na_yP3_90heqNj2vC%eQ?{bipjPG! zQ93sI5l%Z z5cw0w7{is5FGbp_PnsBoM^r&8j7!BQH6+p&K>Vjbfs!#xzzK5oN+l>d!>uYP6G;jI zH35y4MR`y)-K@X2@QFTQ(aSjN#~M>obYvu&eIoM_bt2FjA?=5$moQO2h~Ig-mq9hZ z5Shh+uc@SjHYFNB4V&iqB0!OBQ*s*x5WeD+|9S#yUo)$xE$?Lp{_)3* zGeEX)*KlTq1J)Ngxdmd5le2F{<}6%Tl$dVA2^S;IK8^6(ihr3Bp-&dh;+%Ph6834P z#3i@u)VtxA`YR;F^Qse_rXJFmplrv|vB?Z2LB8MlDRes2Lv<0NOvI$D9+7!+B3oV} zB_KD6_a~nUcG5FhDx%=+GMuZ_Q4Fc@!{tWS!IAMOF7^R=Mppf+nV9xh*`)d5^v>kW zkL=!?mi!vdl8ISm$_k>FONX9+>ks*{mjk~yZu=osS|qY1n&6wiXp`oW`90?FmxK<8 z9RAp|NX4z+5pxQIMC6vYSuRlZC{(WKt~-#mTxSFKG{*Fw*18Tv z=z_5HvOW6`=bOA7M~1l-@7=OuTN*XGGN#(CE=g3QG#6n$7W%9V%3Km26Cf zU>MgFxa*i+o=?rr+%!9Vbl^FsXJNe<+4&64%CdM3(Ki&0q7G0!>FRy)T|TQw zDoQttBFwpW^umix3gC%D0P00TU~%)L^T@eVztb%7mupOpl*+s01M!3zB4e*9N(ot8 zR`i5}u;W%z406JolCe=uZA7_gQiQTyzIZh@ga2a_WWZXiL=RZ3GzG%c>@`UUr!EK*nrHO__Ww-{j{z0A2@?_K8hpOAH?J_RY&C)w6cKO1*$K7$ za~8Y0Yrkz7t1{!EAl0}wb>j?zxwrnLw05wx?w>UHt_+^R;Aq0gtKndXumq!Qj0xhd z+@>(oArp(bC#6bR-Qj_G>1;=S+iTRIiMkvndgk!xq%;NpYqN?O@;XK}W{}_z6<{gE zXrK!}-=2h3umyliCmznv4EQ<}Qn`#1i1?r~NJ9T`euG%K6FOZ)u5zJBqY^oH#d&yc zB5ba^br-XUo08X0>46Uq|=Glg+(=!mOz>u>yD;H5yB zdOkb0y-IhFBS6E{SSWEPL9^YegVHJH4QDtc%u*LCN@IkSwnfgn~bk>xPu&s(ZkcWvcuGvp^@__P7{uj8jy}6GN+OXr%k0^ zX=w|D!Jg3z#x2mwTze4gCF%-u+a!nT{C_nIs-p$}mwIE&N^ioDDDIm3w5g=3)iniB z2d@1g|0TgeKlG>iED+E6m;+tf(&(H(1KPre+d=p&ITTBW%KCREUk?dal2wH|3BNA$ zzl7P8)y+4u^|32L`pO=?#w6uuQYL@I(ST*M1jvaAq91lVv>tGB2u_RH7(U1_EjSiq zbKoR64&Ot8U5Gm^ybK}&>p=6UG6`2g2!?>05l@WbU7hxYX%)L4bL?_>tKnbhy>}F_ zbdkau()e)}%MVLSbynSD>jpYs+aX{1s^NFycEU6nZQHD^c+ILV- zZ`!wkwyJ7QEg})!>7u$;=H){H^ejyT{;*Wrj(JrQZU=*^nd#|9yg!M2Bdv%#G1?(q znjt~4d5^PBXcDOCRNfmCK3v5x93ot-i{&Utp^m>6k@(tkhitgJ^rhb^mlG`GO4tPNE(2P%szCeODez(hep)4el&bn=`*tNAhnZpRC}$H z1h$?Mp|wQ&(hxT`x10AU$X~BAEF`afbyj;}{*9!M9&|lFao6`5l}H+W5*O%ntq@3* zjdhdrmuHy~63=;@?Cwt7|NTlWs8=EU>G_@PDy@_1>x5!y;Nh;prwfaOS*%De!%dgk z{1sHZ-}YdU#?BK(CrzGj0_%<3l;UO#EoI8&arez3mZRf`3SJlBOZQbem%^6G_9tQ* zkOdvHPfIZJcBHsQ4(BoPEVVN%|9T-JYe6sq3D_m>I$J7WQ3b_P{cd`ZLr>Y;)ryJt z;~$C;F>%+hQ(>+b7ogg>sHdV6i1InyUd4?}Z@eL{7#IRQF1e334j8yzlw{-^YGCA~A|m$u!NBlz@kz(4!d3}Sp(^r; zR==X$L?MKp=PCW=zF*SSC+FtaBdiu5^4n#g>l9`F6vAQUD-0D#<0!xf8%eIb&<@3B zl=$th1S5NWsj#+c{xN`q+Pcuz7CDsvSAAT&8DNULFme6dx}Je(Nj?1hDG z?-z=q-j%{5WTN$mEyL%%wmtqL8fV&i_OdW9~M z)mm-xaZTdj^QYTKow&Wz)tR8a%31`Vkep9MNUm6>im8d(abth|)|BeF)hOfhY`d!A zmB~(}FR>@6BbzUF!wRJk;90@C2-@r#7Mi1xAJ}uYmL-|RTY5o(6tOz6)GR_oX=cS^ zCj50y}Uj_WV0>Udu|B?9@} z)O=#RS^~o2^nu3H5)Dh_F^L}tAv!ly1Zv$}H+>~XS)*8jir{Vk1TyYUL_{ate*WOq zci(8V;hk})nqPWZJ)Jn8$}S)h6~JC{dL;^C@c_7@k6E6m!TGE3tQ{zH;TWu<|YeD)kaRE~7CAXh6O>EF!IrNtC z+ZN~WjFM=lu4i`PH9dgCu(WsOC}uqj*CH2zLJ`ZIC_00rhwCqCMY&M^U>Ag}BJC74 zD90~`ie_a;ZE}QHq^dlYs>MXqzQXEqP6xcQb$Ba&aEYu-R$jnaBuNZxS6Dt5?-RwP zur}f5%SBNrZsSS?03UyyNyh+iav492QsdzrBjW#?;DzzGd^}_YT6>_8X__rd z)ToonlSG?IOKx9<=^o3^3J#rFxoLXI`5+_N8QBC&S z?Xx4rr8m+r{J{&dImhEG9Y{)AK-ngY7UrTTDzjnS9QlOH5;4<=So_=bleP4uQCUw7 z7)}U6bUy6ju2DtJL6SkVkksaNC1J0sb{~kCb*M5Rg<=G|w)`b&2PG}+v&qKz0ru`v za+Mt}`mP!fezGD0AGchaK|sX)8DbHFPYBo-lM^)B%+r23cjnGD6k|JYDB{}as;5L0 zP?J9wR;`Or}(lZkO$IwMhaOLO9*bv(5x=ds`hr5En?WA|4gyzoDcEr{d zWACyBdKb|fl#&W`^q8ejc+AHU9tfa2(%sp?T_l{)#V`X5F5ahf=Yz>2{NUdwBOAXK zA-ywoq>|9!NM>*sO6?(W5|>xHWT1i2fTmgvUozwvntll}Fd3oLjkJjtciQcdX1ZbD zDGf@^D2FR#76zk*Y2f^c@Vik4-k!D*xuN@C3nbb$d32)sp7r73q}7tLx6qAHr~H2o z{qwH{;UtItBaAYP6*|l?{x(`%>u6nkP%$TD>|A*T1TY>2@uPB*;bq zy=Q~cTnG@0d`SqLp3IcL%^}VUfI%zIJz$a&jL;fY!RphgAQJJDDaJbL8G&3X3uiQx z9mPZ|n3-j)z>4;CO~fTTh?3)UChc49DrZ7;EcJHQdvWEwwXjmxrsUhvE6R8ilxlsW zmKB;}i#|SK^K$F^dYZ|b97ddxBM4?D??(Ajy$rQ{3Kjp)T5~^8@&$tPoUbAS4=1Y*p zntL}G{|>=e|72SaS|N&tX6QBYv^FiVxDj|n1faM&ZzRN4W%$x#R*DRf;w6TM70n0$ zK=*zG2~+5oJB8NL2Ka$g>MnAqT_5LYRO!T?tH*Htj53Jd1m(C(Vre}hdL<;*xzeFi z^OBgSHgUEd;=z$txjh+pR)HCYF{7R_o{#nl5{x2SvbvBR2=~OhuKoCt+WuEyyOEgv zOTP8aXsZmHpHs~#vt2sbT(B$-uq8Ao=VT|TnVkYUat(28Bj_1Ll(2{vG!#n18eXY+ zZWqZJDJ9kz9mH~r*iWQdYjlm$79gj#E+NAayxZOpVJ|&+MABCu-?=pPKF>2|f6iG& zwouCQ;E8$njp-39*%Z6b))RcJ?8~ffg@mA3!~>aw3)DV|@;HsOT3Z zO`tnJj7L?;OV6;uggwYIJn~c-V3zwVH;MDiZl7ouewM{Wme6;JHuU~aMEJ?DNswww zno(k?KHsL3LZR=Rv}1533518}?cLv|?XR*)9|!+@i4JR6>~MdDyx2Tdk-{eeH)}&h za2+@H`%_U6YE`r)vZ5`Va|m>j6jL{Di5 zi-!CoZQ*PQF=Wrcz?| z5xI;mqo1DHk8+y+hO9ec0dzElBVg!J>ZNeyTYjmB;DG{h|5iGQX6bC8vcD37#Pqr3 z;Nk5wXMmz38oniqHB_>c&KVjLcDh=3JaCkxx)A3_J|HC;9@=RsrT~{LRlH;<@9Pmu zAF3A;?jY61lf~|TwyYZVq76-Ul&;9l)I`};S@W2#4Kq=N2=ZyTS zDkEoVe1j|S9faTDh}jJZL0-X1o1sXW<3wwkRxwp!Wj>x-iIbhVBl2Q)B`@)AD4+V0 zE_>$UhoPVCBSW4*f|VwDN8KjjmQwHP;dIPo$Cc6 z9uEI4a>y>`_T`)QKx>Mz<7*Q)kH`yys!Fr8D6TiM!;-Eq zFvutY!BS~LG@U4-)xP~`Y|t0q*6=dYM4(?5aWXU%7cF|rh=;z`Yt^az{Tr}sB(hzb zSgQIMXtu3+ktHM+e(C(*vUk&!z>oCQA92HwA&Bx=Y@%Co83O=(PfiN@#=L+?GoNhRPS?i;Kd@P{keP#(T|`wIxG= zm+_=1HjTPrxttMX57|mb{Y!TEC*PAau%9K~o7le_1ZTFdRPnthCR=`t7{Bi|81t@k z4>LHWC7I2Bv`}t=3|LNTiNbSQ?`24;hDmPq45@%1hxBkAKa(y_90gf|o_X1qL64n4_t z*ebo$xqIC7!eZ(gEOl`-B7_=xVsxzKs2avY?ijPWN(_Fgs4Gt9NltxjAV93uViYq6 z$M*jpweg`QMe-AdZ2DeZdXuSx#+j{TH#wjD{|>7kX7Obz*4_}kwVi79+LgrD*Rrg! zCX&Wv|NAmvL{<9`UeGTU<4FCL6>2D|+J!KS>^XITw0kLR|@qZ(fPttz<8_QM> zs$E)ot@2IJ0nA`BdR$rw?kCYITuC)g@SOuuBa>;0b~;!2z+{(`^sdpB(YS`(s)XRJ zBpT+DK_sWp{A+Ecsoch`OflyJU-ek)CuXg8`}}_x9b5m*D=4QXqzb~(1HR%U+uI;X zn-X_Oa^;}`Tc4EgXP_8IBug3vF(x{eZN! zhqIR)>}d|R?^|bQx?w`4qSVwmc&605;;lGVYl~o#8m$)xe6zN@>(&d*ul5+ zMe3&-NK!H+-RHbWP^ALaD#$Kl7_AtUOym%_93P>jrFb@&sK49}jvn2m0s`(n9uPr{ z;$uuO5JRTLBQIlVhPgo@IYrQ2B{sCA;tz;-a^meMichy%OKUr=Co(A-1pCL?cHqg+ zf<5?}IC&@Ze_6=+bRp6@r5x&AV>xhQSa!~EOPS$4XE{_Xpu}p{yd$A}M)0YD>^p>_W6=t?yBl|3ZY6J>GN!_K z-MmfR50lgOuORF^;5(P1w@+sy8Qg^n{x`s>h)%PUo!%yYc<_#jW+?XjXk75ktMZc4 zL}tzEB;p~SbGHZl&mtakUqzYP!Yr6SB$eqRRHkvxhG*k z(taJdbMLE6Nq0R|*&^V>yl@3#kyK}<=d97_`dfVYe^1$;AK z*h=?k>DI&%p#V-N)l~U8V_}|9D;13p5rC#(gMS&IR#Pp~rOAa3z2p(3BtrA$)rqYe z{mP%C0kH|t78h4PgnDSyukj>H4$zpN6a6H3Fz~JQ=C}o(2^hz4mivkkdo@Cl{()+8 zX^6p#JeJ+txO?6c4>;aju{jyUjS}f&9H|!e&ksOZ<`qYV$McVCJF8O>TCp{l0967`i7MGZ+ zBLL5)#5XF7SwIhO`%>50aiwB6$9(keQa+4)bnWF0P4b`k-3Qy4r`STlE`u_F7>OqA zhM{!ww>Am8^3QOS>Va|^HB_Y$Wd4Y>3`Tmx7STv@wEFgt(^)HSTeFy%NF{UtqU#vdwQnU;a zA;(qCoR!8Ufd3ddKuLNLiwnviQr&mK#*srOM`$@yY1h&5m@SB-csSc~gNy%#I(571 z+hzCQb}~wlyVBtbtq)~l!8j@&B+uZbZZcxA_S{_+3S0Gd7zlggeLejl2yjv7o|B z-Gs%MAgRX+z53e41TMLIl0v=%oZc2NfO#^RX8RqG;#qYktZ?B z`uOU%7hdv~L6BPdGN8>aipvC3!X$M>84FuI|3otOtDD6%utYUfJnBD^gvhlP=~X1l z{hC*JKL&`L7q{1LbWjuXljKX^AvPrf4rcx2qm)B@`?g3-cArYP-Ggli-Z5Mn1=M>Y(B;&JH>b8`KRhkYmWD&!H5d;=$#^m2yhuC@b|7C ze&31PkzgCDYs7JGp12wjTgG!Ws#S^hcabfZa$E}(B6f7+=%NHNKGeML%29+DfaN9y z!r);Oct1&-z2ZRE0)PoHlyt{r3LnQ^g44x!)ryV?Qh1~H7-jMl%wXe5+lZ$O1U&WO z;-j5oibjf@%`K)25J4O)=3&B`3z3#Udh;h5X#|-HHG;JM&3=YNQ7#cja4~%(i(afX zFrpQt5^T+M3proaPB-4dXCz3w0sCL?eL4yIz?o73R&^lY^q>mb- zaWEQX(_GTQIcP9)?lz|>(%hzD3*@vk#?k~uHD8Vu^9LdpyXfLaZg?DO1fj@Lva#nQ&jDtf^f+QrpH-pCMBZ=kZ{Th&9s+ zm$z8*P2PC3I|<>C^8)B^hoG}IkKGw&hiI@o+>f0IMey^sk8ydwC&v+!@Y_F)u^_p~ zHxT88P{lGEZd-$dk{%d9Pgh?n_jk1~g+$2%Z#;Fa_M;Ef{O&@Ip&G^(8ew4&| z5@br8%-skm*!71}bGC<0)kn*(aS6eB;nT&6qsCQH&fjihS&S_gMU7APB=5nfm6hi6 z%7x@n^SYh&mYYYLT@iH}5|a%V~Ub{UcEPx%|0G(VRcdXK(F9Hj78%p5Vzl|f1GM#JK8 zlTTZf(cudtp;YcSS{h{tmUlx~2CgbLc%Pn^CWuWW#b`7{TpU)A!u6qJ39N>y)eR9; zto*Q*^b-#6gpjv?e;}4B8X1Xa z@1;?WgJs?2kcbdnZ8p%3!T3>N>dZ=TA)SaAxV5pgt+8)KUM9usvBT89pD;y~+KSOO zd0-|r&wwR1(-Ovy=!GpIMvf&av-j~5RtX82TV%EC5@xCzC!&62hQx$JvYH|qhBRVb zxsfZqXCY2ND`BoeF9h>t8h6rJxKzI`Np3}U_@v`uOhs`XXUiF4-ErbHr3++!7Z{RY ze-_NAGIOuCMINQqkuBJUED2V{5=N4Nyii9KjkD34pG^2${GXLd`rR0nLZjsL2+>O> z630I0FJ!?L6~5UB9EB43^tx9rMIxPT5r;gK%DZiri$Cpqgx1Zy1#{V_hAzXid*)J> zk7TSQybGd208JXPZ4yb@uRwMso(+Xmm+~Uz4gyMc0!n&HozSNRF>zJ9vOeX~V7u@`FDgPSqq{Jc_1Y|m zlFTz1U&RcksV{^uuCpmQHMO+N!nQ}~x+|Eys_@gcVsE`>#QIbe5?1D!m>1NW(fAev zLz%Gs16Q_F3}f)sd!a(n2w*#V0>ZDgBw-YELh`?Z{-=xU&HL?`H2Gv^2zFSDc46g^JwRi|xJ9H2%SYVYgPZn3w;) z)OQZpL_H-hC-!JnSFEWk-SfFZBJ5wLd@Cv%-q@rfa^($_m7|Ic6xSG;ONcQr_kmG6 zQG4vE)g0ucDV90O%9i~mw*Kh}@%405#%aMciHzNsN}~)@@yS~(r42Y^c{JNt5g_KI zUaNZuiTq7af$mNkQ#a(s%bwFD%%uNBLMortCt77>DO99dJP@s^u0Yf3zG>E^dQ^1# z&R!;-1tv@|`;l2M6;>A-poICC-5VJMwO`WIxN83elR0$fwi-iX3rq*DAN-)%NHAlo zHe$kg4RuJHcLHk2gvOONLJGp{_L<8xcqR`jl6_|cNDZ#;#3Z1NDo~+aGHX_2_ZnG< zDmuWCD~GLuaE+FQnIG0OUsdsXM(9M>6Cpurm#Pzm@wJ9Hn9F{nL5_mzXbk;X(wT{k zS+@4OcyJLi0BPf6@@0Z3pG<6Ah%Fb5Uc9&}E*C7EkyuupZTE-?)Ygz{EsQ!GUTybO z-{GNDf7rk(SWgWN9n~Yw%o`4kdomiB)}pG;w~KkPtzrMeCiP~dHvp+q@P>d^)|p9% zfz$U~(BT-y&uZB@XsC3wk!It2<}|%B28Ad}`@A?EHXH?kC+hraa;>!j5z0iQibP{T z(2=~rQd{9>Vnp4Vctbz`G$yV=DNf|$;%Vt8OnDL*k~A&D+)6nK3R0QMp=N3Jl7o~f9M+SE0Qus1l!MBX!w7?L?3(dlNN#y6cv%?Eyst=B`ghdEowVuqDmF+3F;wg&gpt4$y(XS z?>kveG$lDeI6mIw))$yO#k&q#lE_wiX^hUaBQYuw1 zrZy^T45SGJ(-6z$c3-I7BbgHSS!M$TNxYTbMpI2jMTG%$Xx%RMMwwj9(1b^mnatf# zVGTL8E=YgRmJydAy%A+aesf&xPmmfFF}%Uas=19-#nvuZPhf>Q_Qq6@FGNXoGIVfd z!BitSlYTFF=&4(}Obytx8gRxs{9Ce1yHwOT88V6zB4K~q)O6B7@NDUu|0QBuXq?R~?~5;{vX zNKsmZ$ioedj~P|cKd@{Q39m3JLKG1q#eVZwJ7pIZMAHJas4d+SM-2?wk~(IFSUy47 z3~??n)h-@ed9%`Vc+*KGh^@OL&F$(^-}LEu%y2eGCvvsFjN)u0iq$0~W@zxgej-jRQat`1yYRDS2UM)2_7Qq6Nw6y98esKO2(YdsYEF|ESYg9l+Z*(e017^P5+Md5L#aumk9B-=M^!teigvZQfQU; zKbMfVr6D0RYot*UEpb&&c&GUTrI$S%{<6vF&7Ubv@so(QZie>k)0ry0Via9xd~g3y zu|$eh|FwjK?a??Yg5@8{q82wNr<1Rk+Z^>^r;nK@0QbP0z-y2rhz=M7lmP1g=-Qhq z+)6i~0*~~9htorpv^jo?G@+{B9*$q7xxFc(fhI%wV#W$ELzQa}eBJo^jSX8kp=z@Z z^T+lL1bD~FNR`8DEG_L3CKLx#F4ZNcU$xREzr^4$5sv~r5fx%@3I}8%@@mq|aVXRZ z%_S@pe2i4`87bj^x#7Rt*~B{)UWjayH>v7tNV#&XA==o)jpU|_PXm_*DkcHMgsrr= zOYvc=MK)G}rGnxfI9r59B#)O{rKbbU2>?W=I7WZ=bwxfG%t!ez)c5PZozhICRG0L_ zD^FU@n<390WX?*vnVc;VR$Ko;xS%ACSVG|ps6%wZ)qszKp6x;-l7y977@~!ZQ)RLi0snH7D7~iEpJ+!>un3*~esk=NM!ucUb zT0o4=vN4~~`^~85%35XQl&8Fw{^`nI(wa*KYotlLVn|cVhWqm1T04;qh~c`CaOFt> zZk$s?a7AxvVKHKJ;4Dp3t*mDZ7j)wA@176PmcFMy+`BY1OFN=3h`rBwn8Z`c0{wA^ zkLyLs`nyUo3p$#AjJ|q9b$440?<#dhipsli5te*ygb1O z_B6*P_}ap^)c^Eh^EM!tn?G>AUln$;ip?}i{AJ}HM_%fzn_$ORmdd0)hp)>?5f!|k znoBxv!{u2*{e!vH&Di@KCYZ~ZR>O)eYS*-^O73!-&EqM z_^(DBcGz^G&k_4mr0+R%0P0jn$(br z4F$&!VnV*7g{{ukcYH|ec++5CE7cNnHBZ%J9wEXDVPd;kt@db5i5Z;cAKcLsMvg5> z6%+wcKg9>$rN4XnX=`JPE@7BJs;p)&e>>uxEX{fVBh{7$0A5levT7Q9EM0X(iYVxJ zIZtLOLiR*s|DFP%*sIC?lgi_>h%G&qQg;{5r0j^Bu4Tln2`?m_r+zmDj-l9XuuOG6hfX4vBXj!pExmm>zN$BZdpW@I@89lB17%MTGgNKZz%=CcO30W2fR7-Sx` zIMJ+7rNT;an$a$7;Rqh<8vy7jmcIE8fq1ePt7gh*lAEOl3aLTSY7}kNdAIqtkFKB) z%c2+I6`pfUlp{Ue`%<=ptVPT0m4AiSo%M4QCwkZmx0d}&UQ}lZ!#lnqq`rqZKqLM6z zuizr*RkmhR-BK}9=woX_dAeYi9q;!3eVsmSQ;dT+6l&TA+#TnhQGTngrxaZ8%<`FV z)fvw%(&PN#MC8o*w2Wdsa3~Yj<*8NJx`<@ziPG2@<*8;xBy6h2u*D=vR<|-bz@Wx& zuuGN_+=eRCg;u{=Ir^Zw5q5(wE&1PTXMQE^Hu9Nof6c) z74bqDUvxZK(uf*KC>JSio2+@T#0%r=wwL=aaSxFDLd{S*=A%ut3!}?R=N=6JsQaG zBMUNmWRifS`t6R5JFc>wdK(L0G*a-8H9~NkXKk{p61i)N9Yp)*dr?@j(@s9d9H(Yd zLX8)T>&P6dF6q)F;Kh;zjLZM1*~LSfWGc9S_&<$NSo*e*bCTIQDD?M?ZT#ZrStzIW zsWdt{9h(P2PDavsk;!RimS8G)EE0sFDaY@`u28fG8OLzT&#*AXXSMQKerZA~O3gh= z_AL6fmh;XpMrnq?2xUrDr4C&gh*Fg3hi)i;#Pm^lBp}^~^YDj4yBt zpDE2~iB*nlh5(=3aIM_TBZp|W9RcHxfg%2t$}zQ0zh#H8wK0MXdxs+sTb1 zsZ)q(7VA09PJom|ubC62V$%vYccxD$iegf`7&pndGT8@lu80UlBOpI_6A>(dtX=JL zt~bRT=W7r-uA}CPPd9_3#98`sk!rBP{#zYSe0{z0uRR$Eig znZ40x-p9l!vCB_C)EUnT*i&E#{Vaz6qJ_5!0ehzCPO>#z3FI7~>QLi1keR|fNFp$v z8RUB~T`3zI4Bt~pGw-UN_KsJeukPqugz~d-u373(V|msvTu5|Q<-G)=l>L@W?28>E8>Ui#ag^DzD{z43{<&uP%F+tkFn#Dhd8%tFDp{!(`-VyJn{ z&nbMBsTgQPvMyvUpS#U=K`bb9Qh9DXEPkKj0gpi0=)uvXPdN}9_)0$;^*NTZZcHDO zOZ8%{$ofG#ASkbp4g@uYN9uDMdv76m!<5gXenb+Jj!@O#X~Za6B9r|D7LZaLa(i)q z@_!0JEPFc%>SZ;_BBaiI`%=gu;aIRDHUPR!PoPuY&Ws#*1mR&q8iGM-&K46OX2!%m zt}`2d6m9x5=riqH+N#L=kc4$D6L*&WsT0uu1`|@^cwBZTo><$}B&M!P*pjp?Dv<|Z zD|0iAhaOlGz5=IU^!@;Xf(rHxGtA~Vz zCi?^u34&$zV|_L%WTw%y(!?MUk;xu?F9CEfNVrdFE#<5goOBtcCo!>sr zdIWbfPRYIUtkhl+RA$QBx`DXi!8=8k$lc#3E}g>pj^Zr3Du1*Ih^Y)YgaYCF+l|w&B6ki zK?szb_||kty3&Mou1*97W1ya)`Tk|MGK%7$OK)|`QGk{#qLv5>>jq{fMQgJO1b{_4 zpgu1{O`^`Lvlg#=P`&ey)O@GMxm_M?E7!gYqM@*YE6b9F%lEY z!q4i2q4l6z)|U^uJpp*r1~(CGswFnq3EKl{S)u`HuWgE8B}tN@iG2m^xKufnkagQ` zG$6+#T?`K4{QmkOFov?tNi2c_4^?0i3>%KFPca1TBH8g=W-7g@^$Q!ydZ`L#K6X}D z&<-JH?@Ss8fm0O`9PNJdvIMRovj4N{G*g4gaff|2!%UX_=psC zMF>LbS~is3r&p0ZAM{eukT;y7NKz?xL^hxktk7}Hq$66X;MJWNB?5Q8XRnc+5ZaBM zhXG%!$RcR6WUIbfx<@hJ%C7|TTep-)nB9EL43Q_fb@mSSeHh)$sJ!0RdONvt7FDrG z6dsx|_i}Md8j(yTu;omz_=b*!qa$Ewvc`T9vBSdJWheq+1Av#!)P&y3eJzTd8P#|t zU=X{muRMvf7efb>Wg-y7l9hntgn*5e6kppnL<^%bpSpw!gNdNQtC9hRh}&bsks$=5 za&OL&OaiF9ClyXU;Cn-;a}1)3L51~ZaLuZ34T5HiWBI`|8=Qw$-?%p{t11-8gkN#N z2$&n(hk<|KY99<*Z^XIhYH6OV10P^iYE0oYrpRV8lPW47+wz@V6pxnM8?1>>iK=w; zL73jKMP)0K%;xGYs;L~Rd)8UjkVr=x($<#MR-r&lA(Ab(RP83~J+H5d3|$+ONuQ3A z&A0OXm09_QB1RHpw-Uv@a7!YHJCWW9EGf*1OXciHRdRBGSu!r?8Lcb^2f{T@UIiMg z1mNKHV=Bk&`~hQtkhWzZ>1Qu0)Z6I#TdUnY@go|#JhBZ&aF3=eFOQ~@jPlU?E>xak zj1x7L92f_ba$yLf_22u@sftY(FIpkzWl;&sLCaYd~Du$oQL2vgL@)?zh?;JJMalzV6l)mE|^fmEVX} zgQ4?AGs*+EWeWBB2gE@bF8)!>w zDyWAo4o5^Rg=H+{ds~)vpKGDr#fv+`PJ?!WwY1W68z(f5OvQxUG-zx;B^O!BX}(>x zcVT$Ej)plhAH0sIGCP401rnSob5N_#bmSuo9%?|`wFJ2mx>2Fj*3W#F?$|I^U1z$Y zjgeRXJxx!W|MhM*ARsd->Xz34q+-T@3~IF~Np+t8lg4e(4EMb==C|`6p!XJyfy{v_@kGI!sYH0nUw9sLyjAe5ydo*RgxG!7}m-w z{ACCN2``+9`qE{>&5dYWQ1k0Nx1_{lq!~_KRWTRR5MHvr5hw<8RTOj&CxQ1 zQP(a4&bnx+)bc|6ScgRv_Yk-;2!s0RBP@xGqjJKYytIg`OaxNHE zb2rO+RU~y!U17O-38~L?h0i_&R1?$J>gw^cOs$zyLI5NH5&!G|#s7Z)P5(~+fd8Jfq&2ge zmhKDpa);-VflxyFP%MI%D13pgfffsdO$$arULq~=01`XUBv^{W$u)INQLdUy^L9`p z;y`H73hPUwH`o`ySy8;qR(O4~c9Y6{upxQyQf@Ks4+Bq!g z0H{-mP*rj&s-U>nDA1WXmjnx)B4kLa#LsCEL5=pxixvrd8$)mqL{NC^!?F={mku77 z>ra+&#>JKjT0^1R5Og*DN&2z{ZIs?NU}dFW_YLgkHTEiPQ{^9f=1&I zLwXxLSTZ6(;)q;9eV9LK>qXQY^Gam8S7BVzAVRP~3qa!dP6TEX6l_Io@`Ot3t0BS) zw}7IKlw{gI9iow&f&|%z9YnEn3BO1AV)Fq#pLDRxhNzImOzdb`zr5U;BP*7Si{8Xd zh$KLxGIP9D!YZRsQ9DAKjalIIByBU;DUx+rtS1=+6T>AU5PaGts%<+O7o^>DApxDG z_JWN|B=jc8Rzlgn#pQKHDz`9ETeUI-e95)X8Pft}1Ti#xkSv0Pjjt`bAlQotbI9pe zVQU9b%SB#|QxV|_Z}3uTlx-mrsO2+0x`y^(PNJrywB@~u^)wGk{>HM{$uvUfM+hSI zMr3h%5fr0MCV8^*6CN$KP za!3*W+d`QpQLc%Vd$AL`59O6U#6G@vGD@k7q?af?Lr!KPFw|Rpc-TVeDDxSj?4a`3 zd-y1>O>uN6IgRq~KEl~-g&D`j3=xxWx5PG{K_aD%C8COC@o_bp#Th&7tQtaYGSb8+ zeK_7r+q;q&wW>Uwlk$7{2d2A57k`dFL6AV>jtt4N;vT1in~h`2AMJw=5Y>#)0yo-& zO`Uc&;Vc)t;pa;P40W`c=!1ddSf9N=OYv&Wi6%O*V&9eUN#s3yu{YguH2nLSDzhhM z7SHZT?q*L{QcK5hB}`@dlOR}-!ig(}WW-W-beM|!_SV0Ss8w%u1hitU%Wp5NjuT)M*iMAc4NnuXjbt;-qMgxTR*TGgU6?JMVj%_r!=|QC%G}NhXvx8ykgbKQKoH z9&LdGS|`HzRgqR3d~Z8yHL;cHB_8O)4joTYi!&H+(SECYlfy!J!!pzgaazG55pC#o zK5&PXOKz4`l;x6k*+>_4#Ae4Q;~XG>SJ6nS%S%b7LcfeC$NPoN^rU)I(0f^>VT&&^ zgb9-5uU*E-755U|iD;Tn7C{)nhKVfcH>stGlGPJvqlWd!;Ju1FE20(b^s@AiN-IEghe2tR-+4LY~Y72 z)FG8D%(NwP(5V&E`Zr625ZcgJJfc)b)-71GIY%C8m|n>w8}46Lr`Sj9GhY2&=@F?_B?Ul)eZlU_$PH=XVh}7tgx!W%Ean5O4oSqUz@C$_tTszSLyd8Q8n7s< z@Nn=Ylwstaz(~PrBEu9Qa8wH)8l{LNI14Z)0!0Dm0<=upSZ$C*n8OUKV{8e};DRi| zB*KJ)8!E-A=8P=xU6SVu?NSRE_!>GSA<&<09C9>4iLtczc$=r;lJ|PfptQt6JsMym zSSzb_6eWp-ndw4!p`q&L4iTaz8c?M}M2HYcwr8j~l-e-8wIYYGX=J#DAr}J#D1!na zD|&(xCbQg0pfqEelc#e^;R*hDqak82p)f4M1`dFG7)W2!&CK1>Tq(hh<{M`Up^hcc zWwci&7P>fs%9^txnh$Bq7h~X9P;tel7EmSL@qqFZ0T@B4TSirBbXKU5LeMBkHqUYE z<%OLGh-1wgZ)rwQrw5!`LV{41{3da3XcRP{O=yQ$U~73VP6ZMui1Byl3nvU* z({NdUonI)PgBFK7G0Zs#p>Seck%X+bI{dLuT}H?dLn>d7{cbB@NSa)=i4ZixAj5jR zG#Eh?%T1VALa7R3;!wf@0SF|(B!rJfW@BOzlS1Ho7BH@NM5_j(LyLx_li?$_O4M+p z0#D!49Ocq&^htq6a}2fdsW{U5%HGC&QYHZP}zNkv>e`Cx}u>6A!cm$JLdBaf<4uw&CTv9d@==>+{naT%@5G zHf+TqZEr}`%}St(La9Y0LfSP3?>VOPBY1_wvVtpcwSv_oNTmMyg^0x`&*B>;p~)-P z=D*}2j=RSkbo&W&ui!-{IJIpvb_r4&dfYpWl9+JB@R}=LlGu@&qp?NFL&5s!DQXI*)E{s7Yp%29!M(ekX zROt(=N1&Hpq0y*NrkA8+QsG7>{+ShlPN7VWxTrLrRiowSl>%}K)?E?Ak($9eoEOh)umQyfLqGJmBT3mej(i=X6k;*3EIe-bF-7L&q6 z=#*tbNzv2qFW!nd+fiv+2qVT7k+^xj_nt%~ToW`_uuMw`RdU&7BC%O8_U=!r5`>~U zP>86R_4A5Fr7jp}USgB9&fH5!yp^hpCiNQ3XKIlP;RB2(tjf5F`zLi-Qii>qinkJ7 zoewh;j2+gRmD8g3bt2o#tVHkja#Rr|AkL`7Z}}q9XHu{Oi~-&Np#Thj`Tzg`03ZQ) z0ptMk0672aT2ac?4-Zy`Z^uI)%RvkqJxCM5U43bCAZCu;$EQ-6v{ooyZm9HLkqT14 zW=M?ifKVVXtdJO-G%OYo-9j_)vO-;EuDTp3LsF)K-kzZ5GhO+8AjB(3F%=gXRP)??dB_)ug4EXLXy7G zTKm^y`4bU=VR;YE-yM@I7zo8F4T$j0tM}Il2?~W$mHk55EgwEo(sG*{*YOmH3{FHn zna>3E7X&p6&W_L4<_KK+QfK=R=uFJa~WhZZzfb&!*{;?<xHD#G-~7x{?;}PicFlG zE0;%x1ko1aL6lz?w1ze*^uV~RO~7Pp=XJUg`egZ(Z*fX~NQEZvxP@Y~ZQFkSvGcZQ z-M}0b2L-ZybJ2pCy@KgOO(jTQyRp|3CHKrt$%y98}q#-0tS91ux zE!e+(QjSW*Q|0GPFgh*NLA_{5R|-fS9un-xQKEWlZ~C=_hH&GOs^tyVd|VOiT0Uql zOo@7Ch+`NkOZ{ysJJcs6X5|u7_J$#H)=3c8PXs}UW|azDm!daX@tS4F7Y!a7r(1r zDF<*&yv8$cV)K>UqimV*fNC5^#))QqLzfrQQKl=VkXH51gx0s%K>PFc<3n2hMD=)6 z$}0@r%*-~$HfqYOWo(%gxhO&3?oCur$Av8lVlaZ4%bO=FR_4OZ`M~uSrplH=Xmw1) z2xg63tC1~NgrO89m5BsdYZnpe*~9__Y4cWH5qd2xBOFV2D+rmADJx)=xw#LN?>oEy zON5I1od!GhW&K)^l;X|8)j{%AiuQuWhZ(lMsWswh6?j0whj@I38}ujenf7=rB*Ap# zr0r83=T5;J(Q|fpcu`ZU8MwElS{A3CJ*5hju=1v*qK6$ZeR3J8$EklZcQv?Jm!D1= zAiCo*bd{Rnl(fH{9c9T9^KBLqUz*RiploinLJYs+-z3#HU-l_+M`glIt&Na%3Rf-iV$};rLq#-AsQ&+0d4>my25GrJ+i==QxC^ zRsu5n9Il>E8G452IB5M#$ zNQdpp8s)?4^7%OF;)E&w)`d=?T8!(44%YDUM?bG4U!EptOEQ@wh7%})UlA8BTK|KD zAMq&3G9EaTfuc$sa+y z<0xJ$O6CzPs8A+QRmR>Sjy6pY@>PN^vroJCpOGWQGUoUo!YU;Hlyb`~ro4#tWpI<+ zSrA!^;zk8enIVdNYogy{T}@@vM5YKNUFsFGDvJIsOO(1S`R_Kd)apO8DOyo-UlYT5 z3OaP%d~z(g0`_SqjZq|0+~Q;FkbQet%{Ai8C+Nnxv$RPfowNSe&gG{|7c^3?NiWfh zc&(>>hzHIK-e*&fkw=0Eq?)8P$P=mEv~kGR2GGuvXl__h4g>WRhZUT9aw%7Bh5+;P zza0#X_+~-SFu2p(2!xJwAdj*Z20{Y{zA_T&ArYgac7{Yk{0*F|i(nvJ=5?@__7qIV z&3tO}qvnl6sS{Y<3t&7SZ^Kj@wZ{&mI!u0{p}CVCNkI?jKB_qDrjZB`7?;i)?K`m70E zOKO>~J1rKF)<#qCP15BKs98u?gRB(v{L&7Wi%5y1SLyGeaTzEei=uEQu{eXnMJ-U+ z_=5zi5GZP75GX)k$70a>X~mSK`h*M3PsJA^^Y?(OWRS3t0ruh~B*43@IQxVqvL-v3 zy5Wl=>HEiKT%nVaPw!}8=go*X5?S;O2&RatW!HITB0+{Ao+VNQuK=tF#9wcq!*Z`DfWfT71nas zb1aY&(%Q>JDl~>wB9kM+V(Up9ND9n(q7*w75i4-KF5+}8&l2DYOGmwNR4!FiX#6!Y< zs`=A&=`1nYB#^k-vNgGH=!c=rxS>>6iSMGPu*kwtoVzm&I5|-X>LWGxnqcpUFEFgj zU84#T>v2_)0wYLP zJDy6wtdXjax*x?58YEd^%EpjR594VgP88jW+;m1kJu*ayk8fc#?cA}-l10?nm6!jl zp&C3vBpOPEJ)0U`*zN3LT2z`uRix5o<7PElY{)-~}2 zHd-cyq*T1?S`imyZ#Vn~h#35QFC&Bw_)k7qgB1A zL7`!UvP}KNA-hb4J!!1+aNX^T=<2Pzy%@5|C$3tEcG{e^@%kA=woYOv&^;ViF!nX) zR^jM*{!UX_230FOCaQWYtBIa8fnsRN&!DHd&+p=}<&g6dx|}tFiWEnvaKio~sst3B zBx!;-FulnC5ORfeNzQW-n=3RB>`C((+GKM4i}*&*3@mc9fH>iwrey zC`0j1(cvqQwV_p2Q|%q2GmWTCU)J2~D)v&Q-CV(9o>}6_Lt4c-ZKYwP6?SZl)&S;@*Cr#ZlyRSDgDdi;&Q0E(Nh?YUCo?&4#bz@gQV66XQbHb| zB-Ds8LL%jm^+jRjF*N|i36?`H7NU(cW+|p9_0{*NWG+iK(52!eqqcbxcQ(&(t`zDd zoHe;;AD;3CSwN(lL6c+=MJ!Fnw%Da{yL?g1>8@+aGnmPbES@IdJfZDj1t_5=JHxH8)Jf*eNaW01%gGcWdWOG9BaH&phLsLj!vpm zS7}_igsYjYl`n&w_t0gU=xT+*nzhmrq;y0-RkT3C$$1iyg%@aw=*$&DMVM8HNo4dz zB&IEuLzjOdsL4}BTk4Qm5z;W?lAB4;EtbUec}G%tOK4RuD%7>v46@RKlc0f57P^#* zMlZ+|?zVBgD`R9sQV=QSxdfyb5lEqC+o|$(iL;jD6Gl1MV-V8$LHCHqh&g>ZZD1=N z>mFd{#U&&Zwx~$77?iwGR3)k2V6jIG4(ibk62lT=5+;WvY@J0G7sD|kT;pv-3pSj> zbTCy>o0wBXz(OUnWIHv4;-;+yX_uuH4aO2uUU5Zo{MW3!b;+x6sc~E=shHV~8k|_% z3?p1Xm!Uz5Xq_DxqOYY&zBINL9?>M*9vTn?Z3Yx2Iey1Zrk4uG5wKjSQEE{H3s^e@ zrdesUI_2n8(CABN7wquX6q_lR2}}{AV*HvA$K;qDV&WETl|{0DM3=5pP2rJDIcDLX zjYyHiX?usQYcPgYHcnw_%Od96rZQy(G24=59M6jqTWwJp&2pFd;;u~bwyjrx{J~L` z=_PhyffeVaMnwuh-~1^;b^n}~)7?$gw#O;Ve{h13qs?{7r|s)xLmGo5PaOgwk&NQyOzV<_<(?kR`c^M-dryzvcn1U7O!e6^&xWdicC?FJsazy`k2&#M6Cl!Mf zxWyw>%k6wBq0}Zp7?KLFF~exgUfnJx^VE%09$2L(uNBI3&EP)y?KjxrH2q1V8p?>HhFl4G_3BB$gG6A9dC|A^}(hGMYRL_`k-ZaBHp zo)5L_CY0>BqVdC)gFOX5(mqQ`;6Q~@oWwH%#%xs%(rn2(M#+=uI|1wTUA4C zIJ%++8~a}Bcs#0B(rIoaw(olcZ+<1_`9;ubSAet)zBI_nBL>)L??Iurflvp4EihJ7U)Egv%=(+V6EDON#IF+E@HxbY4H!DFzOFX z(D?(3(YppPT!J$H%vjFKvqr}b~4*iecvQFTzxnD<&kds$@K=6yOer7LB~ zqrWqIPdJKYiiQf5*wI$WHpe!w$WRp=Y?EULe3m7$)jlu_nlfOFTD|f6MMYAwRmaf3 z^noQ;EdRgxRfX+JT$aj~I>h#XsDrBQ4bpJO-I8hzg^rd*P5C)S-(lTZsKItWHtk(e z%|ytm^(uxS@4XNkhYb`SWE!H$f<%>+Nbpl|vI>Yst;8}@>)%0a-9^_084IjYtl7Y} zsJ*=5^kJ?%LK2ZnYhoJhwetLk;vkh2N?53-?8$hWO5wNFpk+W3|6P4)HxoMPL|HuE?~G#rc%mwT9#x|aT?70E0vEhwOu0@ zzi?DTl?1JV1aXK){9ytdxAEA*1SvGZfgfQ3RynHi1gmBYVhkW}1O%7z!H}d%g@A&f z5r=5iEy*#&-Pp!~7Bj%WfTgVp-Bi`Oao0GCs_xjvShq3|OouHo{RKT7GbbQHln{=E zVL!JOi5M@3aW7`4#6*I8aFx5#idzEG_8le+ehs*+!V|y{2%WZ46(frl22viNnMpgL z4UjQym?KIOJSR>{{8NQreizPaOe05fB}8cyVG+Th;HrEjbJr=Em#}9>F`D8vz04z4 zFsbq>L~RAsjZ{?Jm%U|U5Rs|Q!egxr#}B^h_nN*S#dUF}rhmlZ$f(9rBC(Cg)QHrk zPPh<R^-B@I^xfnzwh3xW!ljd6w9wqd;rGE(J!aC-N zAVgFlnK2xQMg$;2nPC*%G!JvRfu55i({L7*P(M zk&4Dj!+jLj6=7^u<}wb-idG|a?9)3^HDrBbI~k(*#7|@xpOR?_>Jve^u%<>P-F#b< znV?KC+8s$nWf3}TCWc2w{*=E_iwfN}WET;RhYOM?YHS*D?s%vK_V5 z(NilFBkkHvsx~ibx0_m=mA1uVD^`w*#4Mu6qc>tjYhyL(ktVZ3Gg_%Kxu26kGfaq? zDigsO8SZrZC(X&p6o!~WG-Z=!K`plC8JLZ}449f4BDNu6K4TRzmS%~IqX?vlZ1P(z zDj6V(k0;GiNiImJ*K=*A)gQiOskDvE@rd%x@PyRRm9Y^&iI-^;!csO;PMYPH+CwJo zcP7&QOKW)KT!gfVp3*CN>r*Va*v!e%ArdcR)S6aBZ$7AGWFqws`k(x-{=fi`0uTbQ z0ssO~1WQUKXNW=sSJHqeG7?}OH zU)!1Ht*|MYH;z)d_myr{t_Y^MqGMF0aGxQsXQ&7WSbPJT9{~n$Qj9@nwGdX`lGiJ9 zA<93*GRP=2)d(?}yz2?pc|4A+&mo2&kv@;xFola!kM&s>n@s7pDyz#u8HkeS;zS2& zX~mdfNGMi`O%dK-n2F^rLaXGb64yuZZ*i4|3N5@{l$j{1U70t6J*5|-qi9Js=NGsT zWclI*5yk!Qt&B0}!=Qs29)lXb97ZshQi<@#JtbLe%*j11n~W!1N2gKb40g+hN$Y-& zwy<{kTH8RR$!rXvDLET#x;cVZ;I4|yv3`LVPPo{zQog=(3B$009UgFs7h2-a{&l^Vl$-PKuXF~mu!@!td?4BG-YL=Dw_yb^e2+|C-Vw0i~Mp&$q!po zf)4Tdl^0ow8Z1JlWpfA`*ZesxZzlBcv?+5h~H&BiEA!;?clDCwR}$7S95u|~AQ)vm~5 zBb@EtU#lv&1dplL)tr&XzG0v1!J|%|#o50tALCl}d7L5aD4MBtxcgYY?IEfaUsSWS zE38gty<56nrvLYc#cLu1^_HL0TjtjV*c+{U%&@rd>tS2R9qYDn4$ah(dg(xOdqaU; z`S<~}I~qv|JS)@9Jh!xWz21l+)sCsRk=t|$;m9_`w=e22v9{WFa8b_7leJ?%Q+WdZ zhHcNaP=5PXAHy2@vO}1!jTiMgei57Q@tkmPXzX&A@$7sq#<#llzw{Dy1uZiC(CAaZ zy_mN45uQG|)vpCvtw`-Pi&!J(EH-zbQ? za!?rYs)>^#{msP^WB3bctocbq5xNKzDPs$zsr%g8VP;?s>>tUiu)S^1jibp>@J z8yyj-t=Hv~@XWObFr;}YZvNI>Tc4`CYl98{hTiR0K6CFw!uCG782*MdUvJP$AhTdx@58BNg%QKibPMjp30DzEn z1hZmWEG;2878iE8W=!?kH##73;}Xx4_jWDA1}%R2_7H71e*E6hv7O~yyYh@% z+kS&_a&Ee03 z(Yae~U-Q$CcsWUSEO|^;TzZ(i*;`tSTcKxVZLQC>e`5CJ#;C>nRarc&-;YI8b-@NN z<4Y6CS-S4kvHQg>dxdXyz`Jr+#ZW&qj1(uHc<^L5x6mOsXYk0_1{YlGWh#g{KUIB1 zzIx}0Vuj^gk=2v1 zWfNE1)vJ(smPsmm`UCtc?=8lxyoU-4Z;KoPORehNQsOMjxqrM9mAm3o(d#4zbys7iu)@u7C=xRM1{|0wpXiP7d zeu=+vE8TWLzm);*7^htO5TlWbr>-PRPHX73u&3)x$o|iOg z+S&34jp2d&hiALqy2Qr^y{&FJ*oNU6o4E>@cLKX{%d~^`DzHS$_`YUxL>aazV`clU zM*P<8xaX^}GBU$`QB~ZAaNe(GWuE97KH8%^o~e5p{LmY=|Mb33DRp)JmwC(c=6v=Q z<>8iYk}PiqV(Iu?s%7S{+M+Hr-lX1;&((8zV8o(x?~Ce7^t^}dSBV5At4!*{GO^v( zTMrsmpP1^dr+ZDPwq^b$t*(s0 zpy{{e7A*yHy5YNZ2i#>7-eO}ji`=&8(}j0RPp4Y@$FEYv5Qw{KE?^(Mc-htMX(>sv z99-_b7o@&`H=$wBbxg!Bj+ztGLp(ej*Q5yu!Q)ON-NV~X=C3VR$Tg2f1{rkrZ@h;8{$)Fk1L65^25elPYNSxuAoh44P{ z9g&Dc=;8D~O9LK@zoQ^Se1t!g{1A)^e=ci_!FH7+ zi^?4fwbwYI3rj*SU5zT(Bkr#!O`Cz(#>syCAGfNHybjwx@pBB_q9F(uTj_d$d)UTt z-~OR@!cU{)oY$W{9UGs`G~7F1F6y2X*#Q;LXsLR>; zez^qIK0MV`9c|MoCW{<>E}DtM;u7b<6sq#6Q|4ux`okF<|bCUU(R1Wy?UAA~0?1gVQtd zuNorua8fn zTgOJgZ@bwHFerMF0%MbpT2>k)(N5qN^gD6uADsejrn@e3JGd+}QUpj`+=9Ggju>?| zvhP(27$BUFT1O3}Z$#-&W)howEOvXm)-MSg6_~ z=sK%kM-M*`udJ~%?f!`0r|Ldok%BCLCcvB2AnojXY<3tHt@qrbW>i+W)t<*QqL~?H z)egx@e^efmP>Rj>C=ag>=K+Dn5okfirZLpRA#xxUBYo2uSIFR!b14Cyl$Oo?QSQ2x zFZPuOkR_s$u(oB++dVNUW=8;p0V)ES=_?G|OaM;R_v{EJn%d_pcbYJp!;5zU3L;%k z^^-|5(~rxr4aqG($SIeR#rC@R{mcta_u5hg#`s}mO%N$WVpk*ed+z+;mrU$=b92eC z?Ta@yJFqebvt68g(@s$kVT|?0Qyll<^n9+}uA;XuW(~dGrAM~xayXsX4|3Q zO1q|tDloaxDQKJYx={G4D)k9Z!J%yvJ$KE?ek2LGyRLyH<(^d* zzh;;C5PzsKJxDZgu#=^R{}N(=AK=VRZa&LfhwT3La#)Z1utCvn~OY4K-&%$bRoylwF`LU`E7XGrGAr zU$V4>0U+J3Kkv2i^JwaC%@Hyp84MXt&09f~$@DR%`im(zKR}t$p7bO#h-8VfBLhi< zTLfw%Fu~eF00UGc7As+dF9Lbe&T?N7DREJnnkG~Bf{XY>ZBe(owT!REq18BkPmqH- zw?9Y<`VefkwD2lWI5s~^-+~8j!HPOmNT!QlqEc}*t&C5y;3-vL%4HvhA0v`4p^+FF zXeu9!VMKI?mhmM{93mcADT{Ktmj-eu1X;uwKozJ7bUIE+1?07%-KKORZu05KcK($S zelHl&6WS}0U(v_p7=p4+ebX@rWMsH05-mwA0LO|9RjCOd+AEXTmRW`%;Imd)#+MO> zI0{LB?*y<`LI7D@K;uj3`?5SqCXcXob(K&#U!tfCUIr^s0Oq(tCL7hGRDXN~$WdEA zj?5V!Ns`J)7!Ju}^5lqzp@hz6ZXD`W>jUMH?Ku@rPMUFzq?e!u`MnUx1A&QB%Ek}1 zytTJbv|Of~(<_s!Ml~F@3}mq_Vc&evghr4ML~4TC2%y5JfP~tUrtX#bQhNK|OO@)L zBvQJJARCiIMB0o~i?lMzRVCf{B}hUa0gO0fQ}o`oYB+ZQDIKD+xEyHAwG8%3kl@;7 z1d-AXiW=?nb<&*t!tF_~j7);&MkxO6d`$=R5R z?}*O*t{`R^QzEoyc<*#KCLbcM4v%TE7o+7O0aBoF!fQ3>OqRJu|ej6Jg-hx zzN09Eu==#ZJb{=X@N2=m&NXq#PtihQL<~&Sxe2t73trdW5YQ#{v6-MC*GEA+KOICU zj6q7caSY4PmniN;tG$0`73Mp}3?@7U-3zmZS1EN(*Q+B>G>RjtNJ+*1zCWHG#`oLY-?977U1pM+kt#F+e9BbkEYVpu6b6cNUKE%;6lf}wu=1p! z?I&FoDv*Cld?y372}exBxMMC0gSLYXNYAG71kf)W-S!7lvK-@nfRA&DscVk2>CA1$ z(d~X44h&ETTBNmP>1;lJp4Dcb&s8#5SuVq+mpyR@aj0Zz2-}kc>W_FDe-HXpvTxF* zYi9VtS6ZYYZTVtzPfR{((6cocZwj#3pF%jKat5abJW3}{QAi->Z8(+dXj==k_Y2L% zbtoT@)ljunsmvwR*OvIbwYymVsqV0tbKbQ2DJ57zfSJtVV#&?CG+@VVY-wx#MKM_} zG;Q;{TIZ>Z)}LXs283BHnU^g}t*j}2p<8Siy4|531x_8HsQ{V55Ex$XVR71!?OBF* zrld4nH$k>DL7HJbVl1R4w3`^-ys04wUIn}q2q>@dKZ0fybz$tNpjg!)b92a!iK+F~ z2auJ|uW2)w?R+7+oP=R~Aje>RRVRi78c7RNxzR=-RZ2UF$dg%);DETG(ezaVEEmFo0P{QslEkYL9kP!1VcC~PamMdw7QHY zof7h2MWR*kvw7VPfTqD^b2)fsA3<(7rI0@E2@2)ur+72=$msRVh*c6_m))jdIs}9x8$)OFy7sm`;O#DXns? zl(x@ySXTxpXY8JEp4*dQws_jRhOmLB*$9D&9MSD`%J}H$s7u-`=t1HIeNe#+AX3Pr z%3+tFaaD~q6|km{PaNfgQT>8mkO6@HG9hIi=;)i3fB?)LvmG##$p{k4+oe9VK8oZd zbUTP6Um*Gvl3&z0ng-;&N&z{4aHSI*O_rhBa0mo&f(}A|WQA;Mbj-iEPY%t?{L=kh zsUC*6V}Qy%0kui~RDfzpgMH)HcF<^4i6)x?My6BdrQ~!7f)osslV4Kd?|Dn2(+N|Q zF-_kbMKu!TI$t?7DuEfzP%WXutSTcVPxfZBxcokU2-^IW*=X#b`N%XiA&Zc0swO3? z{7LC!z7)u5a+Ef!mP63|0)K)qrP8Q8k(#u?tgw;~lO+d&jte<=(N!eV*Qf?`3QocX5&y-SCt=hGo*29kf%%n#4PQo02eHr+iK9A7S z)!Q2#6U$$WKz#8)E*#$JEFRZFAb!@;MIK0qh_^qK7^{c)tc8hAPEJU2S+gc8COP_0 zxWnE9afnhKT|Ljk5%I}-h%y}nLPrm=1ku~fFhWGUWgr&o>6jt{Y8hsTy^B2%7(FE1 zP((*ZM+l*WMqu|a`d$lRNz*|rU$+#oim8QI<jhY__vi`k{61>1H0 ziGK0_2mRMPehmNtCwDWP(*FYVHL1tqVdTfI!V5?Xg}5$e!bu%!Ur6fLa%1##{^|Vx T)cjv%?W;>|*x^?IZis&XjG;9{ literal 0 HcmV?d00001 diff --git a/test/audio_test.cpp b/test/audio_test.cpp index c96e4e0d..734262ae 100644 --- a/test/audio_test.cpp +++ b/test/audio_test.cpp @@ -185,4 +185,49 @@ TEST_CASE("audio sounds from different artboards stop accordingly", "[audio]") REQUIRE(engine->playingSoundCount() == 0); } +TEST_CASE("Artboard has audio", "[audio]") +{ + rcp engine = AudioEngine::Make(2, 44100); + + auto file = ReadRiveFile("../../test/assets/sound2.riv"); + auto artboard = file->artboardNamed("child"); + artboard->audioEngine(engine); + + REQUIRE(artboard != nullptr); + + auto audioEvents = artboard->find(); + REQUIRE(audioEvents.size() == 1); + REQUIRE(artboard->hasAudio() == true); +} + +TEST_CASE("Artboard has audio in nested artboard", "[audio]") +{ + rcp engine = AudioEngine::Make(2, 44100); + + auto file = ReadRiveFile("../../test/assets/sound2.riv"); + auto artboard = file->artboardNamed("grand-parent"); + artboard->audioEngine(engine); + + REQUIRE(artboard != nullptr); + + auto audioEvents = artboard->find(); + REQUIRE(audioEvents.size() == 0); + REQUIRE(artboard->hasAudio() == true); +} + +TEST_CASE("Artboard does not have audio", "[audio]") +{ + rcp engine = AudioEngine::Make(2, 44100); + + auto file = ReadRiveFile("../../test/assets/sound2.riv"); + auto artboard = file->artboardNamed("no-audio"); + artboard->audioEngine(engine); + + REQUIRE(artboard != nullptr); + + auto audioEvents = artboard->find(); + REQUIRE(audioEvents.size() == 0); + REQUIRE(artboard->hasAudio() == false); +} + // TODO check if sound->stop calls completed callback!!! \ No newline at end of file From d32253e0b40e79a62f02f6df336d98fb143bdfa4 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 29 Apr 2024 13:20:09 +0000 Subject: [PATCH 033/138] fix follow path not working with path as target and shape with 0 opacity fixes #7155 We have to also check all paths belonging to a shape before deferring the path update Diffs= 1c7e61b8a fix follow path not working with path as target and shape with 0 opacity (#7156) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/shapes/path.hpp | 1 + src/shapes/path.cpp | 6 ++++++ src/shapes/shape.cpp | 16 ++++++++++++++-- test/assets/follow_path_path_0_opacity.riv | Bin 0 -> 255 bytes test/follow_path_constraint_test.cpp | 20 ++++++++++++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 test/assets/follow_path_path_0_opacity.riv diff --git a/.rive_head b/.rive_head index 3d7de347..1b876f8f 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -328d307dfdfcc3c4a9d7c726f783b5325bfbef43 +1c7e61b8a075b2eaacbcce4f5438d6072b30e420 diff --git a/include/rive/shapes/path.hpp b/include/rive/shapes/path.hpp index b92428a0..5732cfbe 100644 --- a/include/rive/shapes/path.hpp +++ b/include/rive/shapes/path.hpp @@ -52,6 +52,7 @@ class Path : public PathBase void update(ComponentDirt value) override; void addDefaultPathSpace(PathSpace space); + bool canDeferPathUpdate(); void addVertex(PathVertex* vertex); virtual void markPathDirty(); diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp index 71371f3e..53545809 100644 --- a/src/shapes/path.cpp +++ b/src/shapes/path.cpp @@ -60,6 +60,12 @@ void Path::addVertex(PathVertex* vertex) { m_Vertices.push_back(vertex); } void Path::addDefaultPathSpace(PathSpace space) { m_DefaultPathSpace |= space; } +bool Path::canDeferPathUpdate() +{ + return ((m_DefaultPathSpace & PathSpace::Clipping) != PathSpace::Clipping) && + ((m_DefaultPathSpace & PathSpace::FollowPath) != PathSpace::FollowPath); +} + const Mat2D& Path::pathTransform() const { return worldTransform(); } void Path::buildPath(CommandPath& commandPath) const diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index 820b5b1f..420b82df 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -23,8 +23,20 @@ void Shape::addPath(Path* path) bool Shape::canDeferPathUpdate() { - return renderOpacity() == 0 && (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping && - (pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath; + auto canDefer = renderOpacity() == 0 && + (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping && + (pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath; + if (canDefer) + { + for (auto path : m_Paths) + { + if (!path->canDeferPathUpdate()) + { + return false; + } + } + } + return canDefer; } void Shape::update(ComponentDirt value) diff --git a/test/assets/follow_path_path_0_opacity.riv b/test/assets/follow_path_path_0_opacity.riv new file mode 100644 index 0000000000000000000000000000000000000000..ce4f0fbaa7d9a459e529aaf029394db1f1bbaed7 GIT binary patch literal 255 zcmWIY40B~?nBU0whVdQqT1EyC5NBXyVaZL*%wuO@_~pz2BHl6cz5z-yv#^yU7Nw__ zurdgNRPr*oggf&w^f)*(2(U6Tu(C3NumnSkqq8K#hF&Kmo=k=_h$qP)((240#L5RW zi=`+v8E6tOgVQ1>J_eU|CkA#_4iN^2G$&CI0aV4$u#}ONV=W^SkS(BUXlVGKVF@!U z1A_?AG7(k|AZB2YH|Gk;%uUV7%u7`;WH2@74=zb8NmcMoOwND^S#~k9`y^JT76GO0 T7#tYv862lGGBemt1$qboyaq3R literal 0 HcmV?d00001 diff --git a/test/follow_path_constraint_test.cpp b/test/follow_path_constraint_test.cpp index 20901867..faff9ec8 100644 --- a/test/follow_path_constraint_test.cpp +++ b/test/follow_path_constraint_test.cpp @@ -46,3 +46,23 @@ TEST_CASE("follow path with 0 opacity constraint updates world transform", "[fil REQUIRE(targetComponents.x() == rectComponents.x()); REQUIRE(targetComponents.y() == rectComponents.y()); } + +TEST_CASE("follow path constraint with path at 0 opacity updates world transform", "[file]") +{ + auto file = ReadRiveFile("../../test/assets/follow_path_path_0_opacity.riv"); + + auto artboard = file->artboard(); + + REQUIRE(artboard->find("target") != nullptr); + auto target = artboard->find("target"); + + REQUIRE(artboard->find("rect") != nullptr); + auto rectangle = artboard->find("rect"); + + artboard->advance(0.0f); + + auto targetComponents = target->worldTransform().decompose(); + auto rectComponents = rectangle->worldTransform().decompose(); + REQUIRE(targetComponents.x() == rectComponents.x()); + REQUIRE(targetComponents.y() == rectComponents.y()); +} From aaacf51f5fc6fd188b0410c6fe17f81586554f32 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 30 Apr 2024 00:03:43 +0000 Subject: [PATCH 034/138] GameKit on Windows GameKit updated for Windows and Mac with latest Rive Renderer. - [x] Cleanup Windows includes - [ ] Add image decoding from Flutter so procedural rendering can draw images. I want to do the first one before submitting the PR and push the image decoding to a new PR. We can even start integrating it into the editor without that right now. Diffs= e96739328 GameKit on Windows (#7150) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 28 +++++++++++++++++++++++- include/rive/artboard.hpp | 4 ++-- src/animation/state_machine_instance.cpp | 5 ++--- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/.rive_head b/.rive_head index 1b876f8f..6f489144 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -1c7e61b8a075b2eaacbcce4f5438d6072b30e420 +e96739328b7eb82870c5a642f6e3213c7b423d51 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 49fa644f..84993ee1 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -130,10 +130,36 @@ do linkoptions({ '-flto=full' }) end -filter('system:windows') +newoption({ + trigger = 'use_default_runtime', + description = 'Don\'t set windows static runtime and runtime values.', +}) + +newoption({ + trigger = 'runtime', + description = 'Choose whether to use staticruntime on/off/default', + allowed = { + { 'default', 'Use default runtime' }, + { 'static', 'Use static runtime' }, + { 'dynamic', 'Use dynamic runtime' }, + }, + default = 'static', +}) + +filter({ 'system:windows', 'options:runtime=static' }) do staticruntime('on') -- Match Skia's /MT flag for link compatibility runtime('Release') -- Use /MT even in debug (/MTd is incompatible with Skia) +end + +filter({ 'system:windows', 'options:runtime=dynamic' }) +do + staticruntime('off') + runtime('Release') +end + +filter('system:windows') +do architecture('x64') defines({ '_USE_MATH_DEFINES', 'NOMINMAX' }) end diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index ba4ae11b..69a339de 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -101,8 +101,8 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta void onDirty(ComponentDirt dirt) override; bool advance(double elapsedSeconds); - bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; }; - Drawable* firstDrawable() { return m_FirstDrawable; }; + bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; } + Drawable* firstDrawable() { return m_FirstDrawable; } enum class DrawOption { diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 9434dd45..1719bbe6 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -392,7 +392,7 @@ class HitComponent HitComponent(Component* component, StateMachineInstance* stateMachineInstance) : m_component(component), m_stateMachineInstance(stateMachineInstance) {} - virtual ~HitComponent(){}; + virtual ~HitComponent() {} virtual HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) = 0; protected: @@ -409,7 +409,6 @@ class HitShape : public HitComponent HitShape(Component* shape, StateMachineInstance* stateMachineInstance) : HitComponent(shape, stateMachineInstance) {} - ~HitShape() {} bool isHovered = false; float hitRadius = 2; std::vector listeners; @@ -459,7 +458,7 @@ class HitNestedArtboard : public HitComponent HitNestedArtboard(Component* nestedArtboard, StateMachineInstance* stateMachineInstance) : HitComponent(nestedArtboard, stateMachineInstance) {} - ~HitNestedArtboard() {} + ~HitNestedArtboard() override {} HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override { auto nestedArtboard = m_component->as(); From c5c6a96655fba4ed46f21dc62d545cecd13da428 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Wed, 1 May 2024 20:19:53 +0000 Subject: [PATCH 035/138] Handle NaN in PLS paths and transforms Remove an assertion from Mat2D::mapBoundingBox() and instead make it explicitly return {0} when the points are empty or all NaN. Introduce a "clipIsEmpty" boolean to the render stack so we can bail from draws early when the clip has NaN or empty paths. In the future we can take further advantage of this feature by marking the clip stack empty when its elements have an empty intersection. Diffs= 7d0125c92 Handle NaN in PLS paths and transforms (#7176) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- include/rive/math/aabb.hpp | 6 ++++++ include/rive/math/mat2d.hpp | 3 ++- src/math/mat2d.cpp | 19 ++++++++++--------- test/aabb_test.cpp | 20 ++++++++++++++++++++ test/mat2d_test.cpp | 12 ++++++++++++ 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/.rive_head b/.rive_head index 6f489144..8e331601 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e96739328b7eb82870c5a642f6e3213c7b423d51 +7d0125c9256d329a11844184e6cd1244f3496012 diff --git a/include/rive/math/aabb.hpp b/include/rive/math/aabb.hpp index 4c79aedb..2eabd8c5 100644 --- a/include/rive/math/aabb.hpp +++ b/include/rive/math/aabb.hpp @@ -75,6 +75,12 @@ class AABB Vec2D size() const { return {width(), height()}; } Vec2D center() const { return {(minX + maxX) * 0.5f, (minY + maxY) * 0.5f}; } + bool isEmptyOrNaN() const + { + // Use "inverse" logic so we return true if either of the comparisons fail due to a NaN. + return !(width() > 0 && height() > 0); + } + AABB inset(float dx, float dy) const { AABB r = {minX + dx, minY + dy, maxX - dx, maxY - dy}; diff --git a/include/rive/math/mat2d.hpp b/include/rive/math/mat2d.hpp index 8576cd1e..dd1414b3 100644 --- a/include/rive/math/mat2d.hpp +++ b/include/rive/math/mat2d.hpp @@ -46,7 +46,8 @@ class Mat2D void mapPoints(Vec2D dst[], const Vec2D pts[], size_t n) const; // Computes a bounding box that would tightly contain the given points if they were to all be - // transformed by this matrix. + // transformed by this matrix, ignoring NaN values. + // Returns {0, 0, 0, 0} if the given points are empty or all NaN. AABB mapBoundingBox(const Vec2D pts[], size_t n) const; AABB mapBoundingBox(const AABB&) const; diff --git a/src/math/mat2d.cpp b/src/math/mat2d.cpp index 223e1b69..d88edbfe 100644 --- a/src/math/mat2d.cpp +++ b/src/math/mat2d.cpp @@ -90,11 +90,6 @@ void Mat2D::mapPoints(Vec2D dst[], const Vec2D pts[], size_t n) const AABB Mat2D::mapBoundingBox(const Vec2D pts[], size_t n) const { - if (n == 0) - { - return {0, 0, 0, 0}; - } - size_t i = 0; float4 scale = float2{m_buffer[0], m_buffer[3]}.xyxy; float4 skew = simd::load2f(&m_buffer[1]).yxyx; @@ -140,10 +135,16 @@ AABB Mat2D::mapBoundingBox(const Vec2D pts[], size_t n) const } float4 bbox = simd::join(simd::min(mins.xy, mins.zw), simd::max(maxes.xy, maxes.zw)); - assert(simd::all(bbox.xy <= bbox.zw)); - - float4 trans = simd::load2f(&m_buffer[4]).xyxy; - bbox += trans; + if (!simd::all(bbox.xy <= bbox.zw)) + { + // The given points were NaN or empty. + bbox = float4(0); + } + else + { + float4 trans = simd::load2f(&m_buffer[4]).xyxy; + bbox += trans; + } return math::bit_cast(bbox); } diff --git a/test/aabb_test.cpp b/test/aabb_test.cpp index 4adafea3..0f06abe7 100644 --- a/test/aabb_test.cpp +++ b/test/aabb_test.cpp @@ -29,4 +29,24 @@ TEST_CASE("IAABB_empty", "[IAABB]") std::numeric_limits::min()} .empty()); } + +TEST_CASE("isEmptyOrNaN", "[AABB]") +{ + auto inf = std::numeric_limits::infinity(); + auto nan = std::numeric_limits::quiet_NaN(); + CHECK(!AABB{0, 0, 1, 1}.isEmptyOrNaN()); + CHECK(!AABB{-inf, -inf, inf, inf}.isEmptyOrNaN()); + CHECK(AABB{0, 0, 0, 0}.isEmptyOrNaN()); + CHECK(AABB{0, 0, -1, -2}.isEmptyOrNaN()); + CHECK(AABB{inf, inf, -inf, -inf}.isEmptyOrNaN()); + CHECK(AABB{inf, -inf, -inf, inf}.isEmptyOrNaN()); + CHECK(AABB{-inf, inf, inf, -inf}.isEmptyOrNaN()); + CHECK(AABB{nan, 0, 10, 10}.isEmptyOrNaN()); + CHECK(AABB{0, nan, 10, 10}.isEmptyOrNaN()); + CHECK(AABB{0, 0, nan, 10}.isEmptyOrNaN()); + CHECK(AABB{0, 0, 10, nan}.isEmptyOrNaN()); + CHECK(AABB{nan, nan, 10, 10}.isEmptyOrNaN()); + CHECK(AABB{nan, nan, nan, 10}.isEmptyOrNaN()); + CHECK(AABB{nan, nan, nan, nan}.isEmptyOrNaN()); +} } // namespace rive diff --git a/test/mat2d_test.cpp b/test/mat2d_test.cpp index aa904ead..af1c559f 100644 --- a/test/mat2d_test.cpp +++ b/test/mat2d_test.cpp @@ -233,5 +233,17 @@ TEST_CASE("mapBoundingBox", "[Mat2D]") checkMatrix(Mat2D(-12, -13, -14, -15, -16, -17)); checkMatrix(Mat2D(18, 19, 20, 21, 22, 23)); checkMatrix(Mat2D(-25, 26, 27, -28, 29, -30)); + + // Mapping empty or NaN points returns 0. + CHECK(Mat2D().mapBoundingBox(nullptr, 0) == AABB()); + auto nan = std::numeric_limits::quiet_NaN(); + CHECK(Mat2D().mapBoundingBox(AABB{nan, nan, nan, nan}) == AABB()); + + // NaN values are otherwise ignored. + CHECK(Mat2D().mapBoundingBox(AABB{-1, -1, 1, 1}) == AABB{-1, -1, 1, 1}); + CHECK(Mat2D().mapBoundingBox(AABB{nan, -1, 1, 1}) == AABB{1, -1, 1, 1}); + CHECK(Mat2D().mapBoundingBox(AABB{-1, nan, 1, 1}) == AABB{-1, 1, 1, 1}); + CHECK(Mat2D().mapBoundingBox(AABB{-1, -1, nan, 1}) == AABB{-1, -1, -1, 1}); + CHECK(Mat2D().mapBoundingBox(AABB{-1, -1, 1, nan}) == AABB{-1, -1, 1, -1}); } } // namespace rive From 331c05ab77d786db6f9d969bee0928dc17952a2b Mon Sep 17 00:00:00 2001 From: bodymovin Date: Wed, 1 May 2024 23:42:44 +0000 Subject: [PATCH 036/138] Xxxx support target align from position A lot of files changed, but they're mostly boilerplate code and changes to the API of the actions. This PR adds support for using Align Target without moving the aligned target to the pointer position. Instead, it moves the element from its starting point following the mouse position. It adds a new boolean property to enable the feature. In order to achieve this, it's necessary to provide to all actions the current position and the previous position so the action can calculate the delta. Diffs= a55f1ffb6 Xxxx support target align from position (#7154) Co-authored-by: hernan --- .rive_head | 2 +- dev/defs/animation/listener_align_target.json | 9 ++ include/rive/animation/listener_action.hpp | 4 +- .../rive/animation/listener_align_target.hpp | 4 +- .../rive/animation/listener_bool_change.hpp | 4 +- .../rive/animation/listener_fire_event.hpp | 4 +- .../rive/animation/listener_number_change.hpp | 4 +- .../animation/listener_trigger_change.hpp | 4 +- .../rive/animation/state_machine_listener.hpp | 4 +- .../animation/listener_align_target_base.hpp | 19 ++++ include/rive/generated/core_registry.hpp | 6 ++ src/animation/listener_align_target.cpp | 20 ++++- src/animation/listener_bool_change.cpp | 4 +- src/animation/listener_fire_event.cpp | 4 +- src/animation/listener_number_change.cpp | 4 +- src/animation/listener_trigger_change.cpp | 3 +- src/animation/state_machine_instance.cpp | 16 +++- src/animation/state_machine_listener.cpp | 5 +- test/assets/align_target.riv | Bin 0 -> 806368 bytes test/listener_align_target_test.cpp | 82 ++++++++++++++++++ 20 files changed, 180 insertions(+), 22 deletions(-) create mode 100644 test/assets/align_target.riv create mode 100644 test/listener_align_target_test.cpp diff --git a/.rive_head b/.rive_head index 8e331601..ca0ca4d5 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -7d0125c9256d329a11844184e6cd1244f3496012 +a55f1ffb6cabe9b918fa0b8fd1ad11b4d656ae1c diff --git a/dev/defs/animation/listener_align_target.json b/dev/defs/animation/listener_align_target.json index b34168f1..699b1605 100644 --- a/dev/defs/animation/listener_align_target.json +++ b/dev/defs/animation/listener_align_target.json @@ -16,6 +16,15 @@ "string": "targetid" }, "description": "Identifier used to track the object use as a target fo this listener action." + }, + "preserveOffset": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 541, + "string": "preserveoffset" + }, + "description": "Whether to preserve offset between mouse position and target position." } } } \ No newline at end of file diff --git a/include/rive/animation/listener_action.hpp b/include/rive/animation/listener_action.hpp index 370a5cc1..691ab0fd 100644 --- a/include/rive/animation/listener_action.hpp +++ b/include/rive/animation/listener_action.hpp @@ -10,7 +10,9 @@ class ListenerAction : public ListenerActionBase { public: StatusCode import(ImportStack& importStack) override; - virtual void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const = 0; + virtual void perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const = 0; }; } // namespace rive diff --git a/include/rive/animation/listener_align_target.hpp b/include/rive/animation/listener_align_target.hpp index dd711082..2a150d6b 100644 --- a/include/rive/animation/listener_align_target.hpp +++ b/include/rive/animation/listener_align_target.hpp @@ -7,7 +7,9 @@ namespace rive class ListenerAlignTarget : public ListenerAlignTargetBase { public: - void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; + void perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const override; }; } // namespace rive diff --git a/include/rive/animation/listener_bool_change.hpp b/include/rive/animation/listener_bool_change.hpp index df0b7627..a6f25c24 100644 --- a/include/rive/animation/listener_bool_change.hpp +++ b/include/rive/animation/listener_bool_change.hpp @@ -10,7 +10,9 @@ class ListenerBoolChange : public ListenerBoolChangeBase public: bool validateInputType(const StateMachineInput* input) const override; bool validateNestedInputType(const NestedInput* input) const override; - void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; + void perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const override; }; } // namespace rive diff --git a/include/rive/animation/listener_fire_event.hpp b/include/rive/animation/listener_fire_event.hpp index 66c48500..4e4a7d23 100644 --- a/include/rive/animation/listener_fire_event.hpp +++ b/include/rive/animation/listener_fire_event.hpp @@ -7,7 +7,9 @@ namespace rive class ListenerFireEvent : public ListenerFireEventBase { public: - void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; + void perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const override; }; } // namespace rive diff --git a/include/rive/animation/listener_number_change.hpp b/include/rive/animation/listener_number_change.hpp index d76cc0e5..613d7d3c 100644 --- a/include/rive/animation/listener_number_change.hpp +++ b/include/rive/animation/listener_number_change.hpp @@ -10,7 +10,9 @@ class ListenerNumberChange : public ListenerNumberChangeBase public: bool validateInputType(const StateMachineInput* input) const override; bool validateNestedInputType(const NestedInput* input) const override; - void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; + void perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const override; }; } // namespace rive diff --git a/include/rive/animation/listener_trigger_change.hpp b/include/rive/animation/listener_trigger_change.hpp index 7a9c5954..005f4727 100644 --- a/include/rive/animation/listener_trigger_change.hpp +++ b/include/rive/animation/listener_trigger_change.hpp @@ -10,7 +10,9 @@ class ListenerTriggerChange : public ListenerTriggerChangeBase public: bool validateInputType(const StateMachineInput* input) const override; bool validateNestedInputType(const NestedInput* input) const override; - void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; + void perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const override; }; } // namespace rive diff --git a/include/rive/animation/state_machine_listener.hpp b/include/rive/animation/state_machine_listener.hpp index 88be3c07..244eb276 100644 --- a/include/rive/animation/state_machine_listener.hpp +++ b/include/rive/animation/state_machine_listener.hpp @@ -31,7 +31,9 @@ class StateMachineListener : public StateMachineListenerBase StatusCode onAddedClean(CoreContext* context) override; const std::vector& hitShapeIds() const { return m_HitShapesIds; } - void performChanges(StateMachineInstance* stateMachineInstance, Vec2D position) const; + void performChanges(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const; }; } // namespace rive diff --git a/include/rive/generated/animation/listener_align_target_base.hpp b/include/rive/generated/animation/listener_align_target_base.hpp index 79c0cfc4..b7e5800f 100644 --- a/include/rive/generated/animation/listener_align_target_base.hpp +++ b/include/rive/generated/animation/listener_align_target_base.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_LISTENER_ALIGN_TARGET_BASE_HPP_ #define _RIVE_LISTENER_ALIGN_TARGET_BASE_HPP_ #include "rive/animation/listener_action.hpp" +#include "rive/core/field_types/core_bool_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { @@ -29,9 +30,11 @@ class ListenerAlignTargetBase : public ListenerAction uint16_t coreType() const override { return typeKey; } static const uint16_t targetIdPropertyKey = 240; + static const uint16_t preserveOffsetPropertyKey = 541; private: uint32_t m_TargetId = 0; + bool m_PreserveOffset = false; public: inline uint32_t targetId() const { return m_TargetId; } @@ -45,10 +48,22 @@ class ListenerAlignTargetBase : public ListenerAction targetIdChanged(); } + inline bool preserveOffset() const { return m_PreserveOffset; } + void preserveOffset(bool value) + { + if (m_PreserveOffset == value) + { + return; + } + m_PreserveOffset = value; + preserveOffsetChanged(); + } + Core* clone() const override; void copy(const ListenerAlignTargetBase& object) { m_TargetId = object.m_TargetId; + m_PreserveOffset = object.m_PreserveOffset; ListenerAction::copy(object); } @@ -59,12 +74,16 @@ class ListenerAlignTargetBase : public ListenerAction case targetIdPropertyKey: m_TargetId = CoreUintType::deserialize(reader); return true; + case preserveOffsetPropertyKey: + m_PreserveOffset = CoreBoolType::deserialize(reader); + return true; } return ListenerAction::deserialize(propertyKey, reader); } protected: virtual void targetIdChanged() {} + virtual void preserveOffsetChanged() {} }; } // namespace rive diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 0b077aaa..a0c8df9a 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -1138,6 +1138,9 @@ class CoreRegistry case KeyFrameBoolBase::valuePropertyKey: object->as()->value(value); break; + case ListenerAlignTargetBase::preserveOffsetPropertyKey: + object->as()->preserveOffset(value); + break; case NestedBoolBase::nestedValuePropertyKey: object->as()->nestedValue(value); break; @@ -1720,6 +1723,8 @@ class CoreRegistry return object->as()->isPlaying(); case KeyFrameBoolBase::valuePropertyKey: return object->as()->value(); + case ListenerAlignTargetBase::preserveOffsetPropertyKey: + return object->as()->preserveOffset(); case NestedBoolBase::nestedValuePropertyKey: return object->as()->nestedValue(); case LinearAnimationBase::enableWorkAreaPropertyKey: @@ -2013,6 +2018,7 @@ class CoreRegistry case FollowPathConstraintBase::offsetPropertyKey: case NestedSimpleAnimationBase::isPlayingPropertyKey: case KeyFrameBoolBase::valuePropertyKey: + case ListenerAlignTargetBase::preserveOffsetPropertyKey: case NestedBoolBase::nestedValuePropertyKey: case LinearAnimationBase::enableWorkAreaPropertyKey: case LinearAnimationBase::quantizePropertyKey: diff --git a/src/animation/listener_align_target.cpp b/src/animation/listener_align_target.cpp index c0a573a5..415321e6 100644 --- a/src/animation/listener_align_target.cpp +++ b/src/animation/listener_align_target.cpp @@ -5,7 +5,9 @@ using namespace rive; -void ListenerAlignTarget::perform(StateMachineInstance* stateMachineInstance, Vec2D position) const +void ListenerAlignTarget::perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const { auto coreTarget = stateMachineInstance->artboard()->resolve(targetId()); if (coreTarget == nullptr || !coreTarget->is()) @@ -19,8 +21,18 @@ void ListenerAlignTarget::perform(StateMachineInstance* stateMachineInstance, Ve { return; } + if (preserveOffset()) + { - auto localPosition = inverse * position; - target->x(localPosition.x); - target->y(localPosition.y); + auto localPosition = inverse * position; + auto prevLocalPosition = inverse * previousPosition; + target->x(target->x() + localPosition.x - prevLocalPosition.x); + target->y(target->y() + localPosition.y - prevLocalPosition.y); + } + else + { + auto localPosition = inverse * position; + target->x(localPosition.x); + target->y(localPosition.y); + } } diff --git a/src/animation/listener_bool_change.cpp b/src/animation/listener_bool_change.cpp index b86e0f86..e84808c8 100644 --- a/src/animation/listener_bool_change.cpp +++ b/src/animation/listener_bool_change.cpp @@ -23,7 +23,9 @@ bool ListenerBoolChange::validateNestedInputType(const NestedInput* input) const return input == nullptr || input->is(); } -void ListenerBoolChange::perform(StateMachineInstance* stateMachineInstance, Vec2D position) const +void ListenerBoolChange::perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const { if (nestedInputId() != Core::emptyId) { diff --git a/src/animation/listener_fire_event.cpp b/src/animation/listener_fire_event.cpp index 41e8dc63..bd6d0744 100644 --- a/src/animation/listener_fire_event.cpp +++ b/src/animation/listener_fire_event.cpp @@ -4,7 +4,9 @@ using namespace rive; -void ListenerFireEvent::perform(StateMachineInstance* stateMachineInstance, Vec2D position) const +void ListenerFireEvent::perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const { auto coreEvent = stateMachineInstance->artboard()->resolve(eventId()); if (coreEvent == nullptr || !coreEvent->is()) diff --git a/src/animation/listener_number_change.cpp b/src/animation/listener_number_change.cpp index ca1d5c25..61cac0c9 100644 --- a/src/animation/listener_number_change.cpp +++ b/src/animation/listener_number_change.cpp @@ -24,7 +24,9 @@ bool ListenerNumberChange::validateNestedInputType(const NestedInput* input) con return input == nullptr || input->is(); } -void ListenerNumberChange::perform(StateMachineInstance* stateMachineInstance, Vec2D position) const +void ListenerNumberChange::perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const { if (nestedInputId() != Core::emptyId) { diff --git a/src/animation/listener_trigger_change.cpp b/src/animation/listener_trigger_change.cpp index a7b05794..2832ff81 100644 --- a/src/animation/listener_trigger_change.cpp +++ b/src/animation/listener_trigger_change.cpp @@ -26,7 +26,8 @@ bool ListenerTriggerChange::validateNestedInputType(const NestedInput* input) co } void ListenerTriggerChange::perform(StateMachineInstance* stateMachineInstance, - Vec2D position) const + Vec2D position, + Vec2D previousPosition) const { if (nestedInputId() != Core::emptyId) { diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 1719bbe6..c0f5f586 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -411,6 +411,7 @@ class HitShape : public HitComponent {} bool isHovered = false; float hitRadius = 2; + Vec2D previousPosition; std::vector listeners; HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override { @@ -423,6 +424,11 @@ class HitShape : public HitComponent bool isOver = canHit ? shape->hitTest(hitArea) : false; bool hoverChange = isHovered != isOver; isHovered = isOver; + if (hoverChange && isHovered) + { + previousPosition.x = position.x; + previousPosition.y = position.y; + } // // iterate all listeners associated with this hit shape for (auto listener : listeners) @@ -433,21 +439,23 @@ class HitShape : public HitComponent { if (isOver && listener->listenerType() == ListenerType::enter) { - listener->performChanges(m_stateMachineInstance, position); + listener->performChanges(m_stateMachineInstance, position, previousPosition); m_stateMachineInstance->markNeedsAdvance(); } else if (!isOver && listener->listenerType() == ListenerType::exit) { - listener->performChanges(m_stateMachineInstance, position); + listener->performChanges(m_stateMachineInstance, position, previousPosition); m_stateMachineInstance->markNeedsAdvance(); } } if (isOver && hitType == listener->listenerType()) { - listener->performChanges(m_stateMachineInstance, position); + listener->performChanges(m_stateMachineInstance, position, previousPosition); m_stateMachineInstance->markNeedsAdvance(); } } + previousPosition.x = position.x; + previousPosition.y = position.y; return isOver ? shape->isTargetOpaque() ? HitResult::hitOpaque : HitResult::hit : HitResult::none; } @@ -891,7 +899,7 @@ void StateMachineInstance::notifyEventListeners(const std::vector& auto listenerEvent = sourceArtboard->resolve(listener->eventId()); if (listenerEvent == event.event()) { - listener->performChanges(this, Vec2D()); + listener->performChanges(this, Vec2D(), Vec2D()); break; } } diff --git a/src/animation/state_machine_listener.cpp b/src/animation/state_machine_listener.cpp index 3e51892c..f943f828 100644 --- a/src/animation/state_machine_listener.cpp +++ b/src/animation/state_machine_listener.cpp @@ -75,10 +75,11 @@ StatusCode StateMachineListener::onAddedClean(CoreContext* context) } void StateMachineListener::performChanges(StateMachineInstance* stateMachineInstance, - Vec2D position) const + Vec2D position, + Vec2D previousPosition) const { for (auto& action : m_Actions) { - action->perform(stateMachineInstance, position); + action->perform(stateMachineInstance, position, previousPosition); } } \ No newline at end of file diff --git a/test/assets/align_target.riv b/test/assets/align_target.riv new file mode 100644 index 0000000000000000000000000000000000000000..38492393ce69d467624dba419d33c068419c43c3 GIT binary patch literal 806368 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

#iJct!idDPD5Y|+L2?+l+q)=YNKex>ppj{Bh&cX zBl&%yY>?;0W%>S^i2N%&Q$(*2VZF%PSg%rVK2}t|JSsO@{B#>F)0;nF3Zm6vjnvmo zPtU`l9#MUVHcGvs*ZqjDox^kvqbCBHKp}ane3kg0V1aA1m9no3V;ce7Wsl zBt_)0{t|NK)>xw;>PHca8pc^YQLm&mt1J~S)G1IhBKD^>H_I!Gs}K-zy~y=eMDkqk z##5%H9&IkrbWf@MZa&r;HAm@m+tHsd+wmyn#NXYHLXHLUjRQNpr|I{!r4UQ+J@d?a zmoB~Mj5F?8y0Ex-A@FPmBt{pUZA%_()w<&QSTb)uHdNaphA zt5a1R@j~Z`m@C{t<6XpD{}mfOW~519b`qnwl&1Wyp?+VZk-?**kZ-KQ!}$mYx!bq& zs3LCm6K5vR#2QQn4Gz;dETq+qG&&yra_s0>K7~d{W9J6Z2ED^$f*w0Oq9z7u>{=o+ z%+X`Oo?#L0ZK#+(uy{c?@Yg#d{wd@Z8JS}#)-`V2m}G2jr8xmDsv7!?M4x2i*$f@Rx1O6~3Y5%#_&G+(DGk*S6D?BPz9GNk6|gi@DA` zZ(%xdv{|E;z-BZpk;U>|xp6Mtvqa=k?XSZRlgV;1&Z3LB>8<~Yu4sA-9mCPTSiU!i zf{i`Kd<;;sOUWa-wD63Cwx?#MCyzxp!hjU%R>A(Hy-s^{?aN}?efQa)wADVIzgLRB zw0%wOYlTZ*TU*m!U@77FX%{bf*{=U_(7yeZC715guPKk%zut0(7}dC5_-?z=4&zin z3l|NQ4kwqwan+zkz1&r4f_(lPVPOpM!&FL79IlkFEL6OsTD^U-dUc2UhADM4zzs>V*Y*#6EJ^sgq{uJ#@v5&dEx=2gs{mPsCbF z+f&IxMuqoLYP;H_=N6CMHjo|B{%j=b8`602_I%mSv|)+%jL55vK}SB%E61%AH*GIV#q(&a9O975$}G!y$TT27bU(e$vG)45*g_a*i3{Y?F}@0_>lo$5tv zi^laQ-C+-Mm(uu+Hx4wy*)$~sWz*Z- z|c9!p#WU26K{}7Q2qo3_yjemdw&d6&m)!n94UIS$x!@`AtfQ#A;*{A%0V);;MpvqutL-oe@joJ zV&RP|4(&grFgtnL=)I2)mF;4!6KJ*>W;n!5}@@JO$;9vV^(9OrC5uJ>_b=Hd{Wwiy+`jqI{U0cdvkK_1v^=u zZSTS2%xGFtS2WA?Z#L9PC*^J}6RBcAREAQAui02BJ(fIkZ5pkc-9ISflp23&&b$DYqqQ$>>=`s)O4V@8S`Paf@5iq01!1 zd*G+ENhlxU&YGG@PrqaedB^9RqMtfzN@QUCt@hUk`d1yBlXvvtIp^(XSJjER`Tt#c z@25+iEMNERLVJ3w-a9OOMXnvcblIs#9=^~YKW9I?vR-6kIec$%Kqp?^gHXK@0lfy)hV4VWed(Q4`ZV=PveFGiL^{B9kxZoGL@JV%SpE*WEi|uf@&LF8tUT zdnNSi@p`!Z4Ux3wUi+g>t3Td&ep2rq=QfvI-nQ)Qx7K#3Ryb>WL*Z-GzqzmP(7|n` zDHM!fZwK#dv46fXYt_@0xmO%l^3<||r_b+FH;23Fp3yTNQTy5pJQG2tGZC1+2bB+T zu9lZ!U08-qjU8Hd9vRRUeQv+_FwOU|_xk_ry1~8IPkmJ^>F*b3zv;Pw|NK(V4ZJf% zcF|)g=oN?UZrQ@~%txB%^KR&5rw$J>?ovxLb$CqCSxI)mS2Q`W$E+lOE1u#mC#!a8 zJa;|0D;qisjxM=CDZp5R8^&ID84{J!a;4rKp?qC(SwyMva4EebEs_f@+*!WDUH)K! zj+#c~D`Vu@5jjR!XJl;h!IL8L3uq@el0Pl4IRDa^avLJ@a$lP#eQ88qVO$#t@OkrJ zjT_HM{(icFmHAs|BHrqR0(@O@5k0NbeA$kkoiTb|Yvi#UGlVz)8=V(E((*HE2U-TA zT-YySk73tU(~BS7ddnMkuJ>iweQvu$}osbjVBBco5#IsGqplQ zjxa}s8|IiG!yKIYCuKt<6wxKa95QcnaGnfvkcN?#r%(!79yN&3R4!a`m8}-z(7akFmIMhH#NAitn(}TkIZbvl4e$k|LUk_fTu@)Fxw@{AG+?@ACvYvuuc^PUR@9MDs|-0LUP}#y$#-x_ZX8mB$POvx z9NXmd&Z3j$k(jPbPeU2YBN0ZD`=_~ba~mT5e8(J{euXER4bCaH9MP4@0!~_b1K%_{lr^ujqgN{?ezwx?fT+={w&VHibTD5Dm(z$?J|;F?2qkrL=FoiiMVf^juBymCy{qnnBLkS4WA+0VhyV!mF+yDjQ0=bmFd|d)miF+ z9VOJTPI~qqQNtbl8qX`!UeXSBZS_X*&OY4g?@gNB{Yd?Hm-n|eu6k^#p~OV(!YQEw zLm4>#hD+_Cb~5^tZ!T^{x9WlssPII@y$%`42)nC~z9H5m3BRqL*E&YyZm3E-Z@vB+ z>1${$84q@BBF|UIL-dIVh+-N+OUjL^F^TwyC$qX@Jx~v>`SzOr{A&)m_@m1HHoGP2 zjh)gLuL>2UTq*YYtf8T~CA(V$MN?;|of>}7{*FA}hQ}L@$IEBG<)Y&RtCL2`L0eHMnU&Z@xvdQC-R~b$UV*?ka$6*nw44tZwH{Y}AfG(c; zar2gasci3~GbpOk+JtUIWqi_nXaD6D`N`9K*$9|W043Z(Szo2q|JtU_D676$h)rrv zS)PvzGaFDCLUCd*|X)?VPlm0sAEI^n0h7HaiaRixqOAXM&BIGZtguk(bZpi`09Y;TtKYQ{Uys%3EXerewub;LiAUdr(d z6w=4YG4N|vG(GlUx`uKoJqF2kx%TArXN5y@io!6e_Iu=oHc~qJC~_+0^zZ{IhxN4# zIo+^)h4ZW^u2Kg)@|7fqr}l@NM7Ol>1aG?xdvv?2zjgRS*<`_R(+Ce+%Pi5Q>%!rE9?GRU_LSHX$hsYpR^7ew|m+2Mq_5zO*lY=2W zH$=5wL;2w78swgakaGN78s66-9V-C?2QB_EKupH5{{t!7)75|GE4A?x;^ULzi!r}! zty$A~Zuh0#1&Ptjv=}C!&XdKpwNl!RK5Fi>=2}hb%6C;>=agm8f`Sa8BNo zKksw$as9IjZ~k+CxDDrI&b|NCo_`!Z?a!Il94-dzX(!!zagLfzUWH1car9Ja&UP|0 zqM2E;^7Y|1H6*=WnjfPd_rl@wQb$gW3?sl;ugL3%{Y~ox$9V5kIgatLe!wWW#e(zV zCnEMh188(`JYAqpX=08L&H4KQe){5`b=8UqP9ZM(PxD7ar}HUe!HhXoTBD6g){J)yzcNqb&EEg z4)uqvMvdOt3WYELQkHT(jD;`R5dw9H`ci}Z%EXs=D-&g}HiQ?6j((rAaY)&y%cO9e zwaCDbW{?ev{`sMj4f)HEuR|77)%WwEtoZ^2XdSo{21VR`VWm&cG?4>G77O%FokYWq9F=XG_j}qWp}T3upD` zF5KrYnTvANCcCR&oBNM@&&5HqgO}ZSGJXdm<%q@m{&k;ud0M|?iw1aX63R)ZcbQPP zmVHhxq-aw^zLH!XW0UJ0szI0BvN-+t{3{Q)`>32Y6K701eP$EZMq6u2PEl3AZ?k`NOC!0Vb0xhXLAv4a>&Yd%y?MCK8Iu#dv2JJ( zivX(AS7b?A1V}F}fP9`u{=yIfQ}EO5p+U#FaE~BjoQqCL&`MUmX9YbE4&kZM&Kxb= z?^V<5bJ#VCxZE(c$#jkbNVTI50K>2Yu-tWkXTy2&{iR$@I6#JU0OZ0Bz?F9$04q{Y zYI1-M&)pTcIjwAn2=UN@-3=7@K`Md9So;c zq;pF;Uf!81iReGlywN-VFD{P3z!Hjg>7IQd&wJKUY)ZP~k_fw?(mZrB>X zbB(-rq>Z~&kGe-c)Wc7(!%DPQFM9@Fv5(~utl^F~?g!k^SuL{gTQ^H{yk&2VF~>I7 zAb2oow61RtJ$O@lt=6}_7Y2ExL~Dx}ga&>J6eP~v6I0`^i#50O?z~(K>)D72X78$W z9=xm;x%?cEUR9`~i$&zw=%OrNrSUKYFQw*-$g9zhp|+gp>)=Ih$Y_MnM*FZ>28D5U z2wrf}2wr5Nh+mPl43x8(jCK@2aUFjC);m?vtm1l(Crst5qx)!_RFJo{;R(YuXv94< z9ZH~kSj@sBsKW*OsAdT?37CJc+Gv!na$ zd}4BkV}LoG_G^zmDh}%G6bC)}sQp^!otqag-h8M0H+7RJ_Q zVXa#y;u;(6U)HU&gX`tv1Sk$_P;v6*e7h{t6KcTJ9QiG4?YC69e0V@&*SZ-Cb_`e0 zX+mg=u|mVr7)@BLRDtR2`vw>-2cIJE;ftPd8rgKByiT7{7q0&e11>BwvWm7TyEY>! z&|}oXqb$7q2Ll#8RWBc^-<1}=mhRWK7MwXLT=N@x7^S`TVAF}UTi@QLD(EI`BXkRC zBe?S*4e+s2>MR?i8?qdo!m;RbrNbjvBJve@_#~Q7RK7Asjz{I4e3ps=B_UF7H2+e{ zpIQtLzPWCWo84V`9pAtY3)B3j%iT0Qg0pLv3k{AC-(gK@VWnXmObfA?8oPEjjdJG| zx0&X&fxavo@8 zxpZIR$e;IFp7bpdIil6k{AokoNq;8f?xwR67bzDT>baZ`ZphJMZhC}Jt33JRTah#9Fb$IyT&bb8f|qusee*hJ=VdAeksR^{sqofH^u?i zt7xm6yb6nGk508THE5%x-0SU8xwmiBQjE<>?X5wr9BnukIoeRmz!K=}k@V40F$&32 z<8~;OEN4(1A}w3t)XB8ocHX(op0m-F`>#Fdz-6MsE-cXWgcNUOCU)R#4!^ zA=Su{*Mm>~M?fCgP8AzOB~EFlZfhRFx=rYO^lRJfz8pb}1U<1iD_{GC_kHniJ)#D} z{o!8c{g-Bu_pUPGc>DQx+U%G6F1h#{arjH`iN72>Azby9NV?=I`#&GNVE?K{zp1ED@Ew27gued}^SohR=F)z5eTb%#RS7LR~hj#V%w!NlzN~V**9o zJi(d&hq?EGi?Z0_hj*Um**_TB${(d7gG5CynF%NrC0D5^$*9Q4$VgF9QPEII(Kf{- zMI|LgB}GLfMJ1&oqvRSI85tQBx3=zPT%+#Z;(Eze*d5;QnP+!d5by2&e(&e~yx9Uf z&pc<&oH=vm%$ak}xGx58YBmlxuf1WSpZDXpWgMBV)3hwyAW5zAwNLL&vqz|#SMfd# zS8qe*-j#J-HZG-g^YQ2L-P=%I`b*qqU@4|Yt7PAULIg~rW$PP?_-8`S2+jkE7+UN{f_ z{x`;->fVH-j1qL!)XbhIAw*wqNb1=la<;&lLdW?&BCntIgpiH?^=}<{XSm7ekHDpcLJ9lFQ)d1AX&8MMy>(8l7%>87-Mp9Z4Po z21{i$(Tt0|NFp zT?3DD8hFtKoyWkVoCaPk_ZWDOHp$T4HSj@V;HiEu1Mm5kd*BN?E!qf7ui@YV{Rl+b z&`H360TiJiB)L0R;*g<(Dd`DK9Yq_^==V_0%=Pb@a+}Yd*~%{-`v%DxXW zGCMV&pW58Hr(n)6NaPjsYC%HsJE?9Y*%F4+?T8UC(TD5eJ@UJd_`yo2&ETtgA zbRlI_7+tk9owbv?)y`rW9<_;;2{s-5m8s>h{dq#q(~az^FSgR6z8*TfFn)+uy_#Hb z^gp}G367X5R3EHQa6H>lnH*afdd@U?_#TGg3kAEWDILJ=dTrNb10vfjn0*Wm!-UaT zr!R|QO7ou1&9#l4n&uDoy;6CzWf=d&dX)cb>&Krozx=|x>$h*dSt%<4ORwDZ`Kai~ zz0=lbXGhi6XEo&P{$y0tEi;m)y_lDP)@_gHU#df+pP{3KU32&V>swTr|H0(~-d1U8p1UjQ%eN{`(>Eua*tg>oZQDWHYLm6($giXP zeEDx*0$X!ZQR>dKmYMsK^XuN(-0n@yBReW3m#57KolkWIBq7}{Qthht`K}bHhopUYfntOZ+OE^_h+RgWX;MfoHJ==;+&){8)`K0LGQH6`M6A= zA8?{WA~FA+(x`EO+cnq9-x=it-BYk@XFO|DZ@dzBR zyP~bCkv!9BkjDkJx{@nfMlT%2f(ZX7z4+bUlOh(S5xuxYD6Xz^H|Oz($W^6=ppgcM zpt?wwZ%t1aKRrHe=(L>5rG@1ezcigZeMfrXGjzr;McAA58JBU&pOA3(Q@5udeX*$O z?{m&Xh(m+w!cXy~hia8KSfZNig}Zd@1tz_By)7Q8dhIksWTo;IbX zZhPXXqG#89ys+1J?mOmAyl329i;^B+_ZVZ()NDdWGI+jR2Js*UA{=g3vRiQ-Dpbe* z{&{j>4{oZf<8Z6-90l-_n=kd0`I6HA_H)st8;d8&fmg7M99LB(Rb9a-5a3CUGPz!# z0Wr8ph`Gf~6`RytodG#V)N=i0b{ZE(Q2iugELS<~iEw|Sazf9G#Ig!!fhJ7^eI`M* z^sJw!%~tF4XvNqC$1u%Rj-zsGSGjJjHks-p?PquRvv?N5bHpLBHV>PS{`dlw+{2^S z$*7~1Vyo3Sy7_Rv#bkYNbJE+(rA#@mUBi?`dtYFzmb`__>LwpYADWPPNH|c+utGsE znSXIS~dqdStKhkSeO3kzo zXQ=dZm68Dnds25fE&EiPg5fGX$~EqCS28XYPFJ}r*ODmrN^#d;$W#ua@^V9hyL<*q z5DPy=L6nf+q_f>6GFGo%@NuP*6Y%@E>$_8!spZ8kIEFsDcyiBG`|H*0F89_U9?D&A zahLaXmRAa{bHl+|g*u}Ie4)#$^f5V;mC+$5INk+Ew?Su7@$XUoimpH{$04U@{k6Kp zuKtQM2?5{mp3>G;?p5T1Z+HfH(kVdCcJpv1;ij9g(5ra5lC1%MTmwn{S|i5SW86K; zVdu9vq3DeQidwrn6q)nssdMGX9F|^)duD;=#%bp8alOnCJX7cd^$6Gly@PzK!!G~(ue5ahLfkS z>Z&iMtO|djR3kc;h2hHr-EgGiB?XJyAn=prvJCt);_jJN-pcdwua&j%0Ay#+lQJC| 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

uMkXT`Cz;@BlYHT1wy<9@0l7fB|Xyg5!~ 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 +#include +#include +#include +#include +#include +#include "rive_file_reader.hpp" + +#include +#include + +using namespace rive; + +TEST_CASE("align target with preserve offset off test", "[listener_align]") +{ + // The circle starts at coords 100, 100 + // Once the pointer move has acted, the new coords should be 100, 51 + auto file = ReadRiveFile("../../test/assets/align_target.riv"); + + auto artboard = file->artboard("preserve-inactive"); + auto artboardInstance = artboard->instance(); + auto stateMachine = artboard->stateMachine("align-state-machine"); + + REQUIRE(artboardInstance != nullptr); + REQUIRE(artboardInstance->stateMachineCount() == 1); + + REQUIRE(stateMachine != nullptr); + + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, artboardInstance.get()); + + artboardInstance->advance(0.0f); + stateMachineInstance->advanceAndApply(0.0f); + REQUIRE(stateMachineInstance->needsAdvance() == true); + stateMachineInstance->advance(0.0f); + auto circle = stateMachineInstance->artboard()->find("circle"); + REQUIRE(circle != nullptr); + stateMachineInstance->pointerMove(rive::Vec2D(100.0f, 50.0f)); + stateMachineInstance->pointerMove(rive::Vec2D(100.0f, 51.0f)); + stateMachineInstance->advanceAndApply(1.0f); + stateMachineInstance->advance(0.0f); + REQUIRE(circle->x() == 100.0f); + REQUIRE(circle->y() == 51.0f); + delete stateMachineInstance; +} + +TEST_CASE("align target preserve offset test", "[listener_align]") +{ + // The circle starts at coords 100, 100 + // Once the pointer move has acted, the new coords should be 100, 101 + auto file = ReadRiveFile("../../test/assets/align_target.riv"); + + auto artboard = file->artboard("preserve-active"); + auto artboardInstance = artboard->instance(); + auto stateMachine = artboard->stateMachine("align-state-machine"); + + REQUIRE(artboardInstance != nullptr); + REQUIRE(artboardInstance->stateMachineCount() == 1); + + REQUIRE(stateMachine != nullptr); + + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, artboardInstance.get()); + + artboardInstance->advance(0.0f); + stateMachineInstance->advanceAndApply(0.0f); + REQUIRE(stateMachineInstance->needsAdvance() == true); + stateMachineInstance->advance(0.0f); + auto circle = stateMachineInstance->artboard()->find("circle"); + REQUIRE(circle != nullptr); + stateMachineInstance->pointerMove(rive::Vec2D(100.0f, 50.0f)); + stateMachineInstance->pointerMove(rive::Vec2D(100.0f, 51.0f)); + stateMachineInstance->advanceAndApply(1.0f); + stateMachineInstance->advance(0.0f); + REQUIRE(circle->x() == 100.0f); + REQUIRE(circle->y() == 101.0f); + delete stateMachineInstance; +} \ No newline at end of file From efe038211e583aba2ab03cec538eae40b448ef45 Mon Sep 17 00:00:00 2001 From: mjtalbot Date: Thu, 2 May 2024 16:14:44 +0000 Subject: [PATCH 037/138] fix state machine advanceAndApply this almost fixes the issue with ios. but somehow this ends up returning false sometimes still... it seem to stop in a similar position each time, a little nudge being enough to get it moving again for a longer while also ``` - (bool)advanceBy:(double)elapsedSeconds { return instance->advanceAndApply(elapsedSeconds); } ``` note the intervals at which we call this function are somewhat laughable, ![CleanShot 2024-05-01 at 16 07 05](https://github.com/rive-app/rive/assets/1216025/694e61bf-8d0c-465e-9676-af221d6be174) Diffs= 8db7cac50 fix state machine advanceAndApply (#7183) Co-authored-by: Maxwell Talbot --- .rive_head | 2 +- .../rive/animation/nested_remap_animation.hpp | 2 +- .../animation/nested_simple_animation.hpp | 2 +- .../rive/animation/nested_state_machine.hpp | 2 +- include/rive/nested_animation.hpp | 2 +- src/animation/nested_remap_animation.cpp | 5 +++- src/animation/nested_simple_animation.cpp | 6 ++-- src/animation/nested_state_machine.cpp | 6 ++-- src/animation/state_machine_instance.cpp | 6 ++-- src/nested_artboard.cpp | 7 +++-- test/assets/ball_test.riv | Bin 0 -> 995 bytes test/nested_artboard.cpp | 26 ++++++++++++++++++ 12 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 test/assets/ball_test.riv diff --git a/.rive_head b/.rive_head index ca0ca4d5..ceeb57a8 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a55f1ffb6cabe9b918fa0b8fd1ad11b4d656ae1c +8db7cac50c53ab10838da0cd80c869917c51c72a diff --git a/include/rive/animation/nested_remap_animation.hpp b/include/rive/animation/nested_remap_animation.hpp index c83002c9..3b304fd9 100644 --- a/include/rive/animation/nested_remap_animation.hpp +++ b/include/rive/animation/nested_remap_animation.hpp @@ -8,7 +8,7 @@ class NestedRemapAnimation : public NestedRemapAnimationBase { public: void timeChanged() override; - void advance(float elapsedSeconds) override; + bool advance(float elapsedSeconds) override; void initializeAnimation(ArtboardInstance*) override; }; } // namespace rive diff --git a/include/rive/animation/nested_simple_animation.hpp b/include/rive/animation/nested_simple_animation.hpp index 41bc958c..ce04aa44 100644 --- a/include/rive/animation/nested_simple_animation.hpp +++ b/include/rive/animation/nested_simple_animation.hpp @@ -7,7 +7,7 @@ namespace rive class NestedSimpleAnimation : public NestedSimpleAnimationBase { public: - void advance(float elapsedSeconds) override; + bool advance(float elapsedSeconds) override; }; } // namespace rive diff --git a/include/rive/animation/nested_state_machine.hpp b/include/rive/animation/nested_state_machine.hpp index fe0cded9..489d631c 100644 --- a/include/rive/animation/nested_state_machine.hpp +++ b/include/rive/animation/nested_state_machine.hpp @@ -20,7 +20,7 @@ class NestedStateMachine : public NestedStateMachineBase public: NestedStateMachine(); ~NestedStateMachine() override; - void advance(float elapsedSeconds) override; + bool advance(float elapsedSeconds) override; void initializeAnimation(ArtboardInstance*) override; StateMachineInstance* stateMachineInstance(); diff --git a/include/rive/nested_animation.hpp b/include/rive/nested_animation.hpp index dae78774..843739e8 100644 --- a/include/rive/nested_animation.hpp +++ b/include/rive/nested_animation.hpp @@ -12,7 +12,7 @@ class NestedAnimation : public NestedAnimationBase StatusCode onAddedDirty(CoreContext* context) override; // Advance animations and apply them to the artboard. - virtual void advance(float elapsedSeconds) = 0; + virtual bool advance(float elapsedSeconds) = 0; // Initialize the animation (make instances as necessary) from the // source artboard. diff --git a/src/animation/nested_remap_animation.cpp b/src/animation/nested_remap_animation.cpp index 92b94653..4edc815f 100644 --- a/src/animation/nested_remap_animation.cpp +++ b/src/animation/nested_remap_animation.cpp @@ -18,10 +18,13 @@ void NestedRemapAnimation::initializeAnimation(ArtboardInstance* artboard) timeChanged(); } -void NestedRemapAnimation::advance(float elapsedSeconds) +bool NestedRemapAnimation::advance(float elapsedSeconds) { + bool keepGoing = false; if (m_AnimationInstance != nullptr && mix() != 0.0f) { m_AnimationInstance->apply(mix()); + keepGoing = true; } + return keepGoing; } \ No newline at end of file diff --git a/src/animation/nested_simple_animation.cpp b/src/animation/nested_simple_animation.cpp index 89ff29f8..dd6bb6e2 100644 --- a/src/animation/nested_simple_animation.cpp +++ b/src/animation/nested_simple_animation.cpp @@ -3,17 +3,19 @@ using namespace rive; -void NestedSimpleAnimation::advance(float elapsedSeconds) +bool NestedSimpleAnimation::advance(float elapsedSeconds) { + bool keepGoing = false; if (m_AnimationInstance != nullptr) { if (isPlaying()) { - m_AnimationInstance->advance(elapsedSeconds * speed()); + keepGoing = m_AnimationInstance->advance(elapsedSeconds * speed()); } if (mix() != 0.0f) { m_AnimationInstance->apply(mix()); } } + return keepGoing; } \ No newline at end of file diff --git a/src/animation/nested_state_machine.cpp b/src/animation/nested_state_machine.cpp index a6b5210b..f04477f2 100644 --- a/src/animation/nested_state_machine.cpp +++ b/src/animation/nested_state_machine.cpp @@ -10,12 +10,14 @@ using namespace rive; NestedStateMachine::NestedStateMachine() {} NestedStateMachine::~NestedStateMachine() {} -void NestedStateMachine::advance(float elapsedSeconds) +bool NestedStateMachine::advance(float elapsedSeconds) { + bool keepGoing = false; if (m_StateMachineInstance != nullptr) { - m_StateMachineInstance->advance(elapsedSeconds); + keepGoing = m_StateMachineInstance->advance(elapsedSeconds); } + return keepGoing; } void NestedStateMachine::initializeAnimation(ArtboardInstance* artboard) diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index c0f5f586..e5e387da 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -744,9 +744,9 @@ bool StateMachineInstance::advance(float seconds) bool StateMachineInstance::advanceAndApply(float seconds) { - bool more = this->advance(seconds); - m_artboardInstance->advance(seconds); - return more; + bool keepGoing = this->advance(seconds); + keepGoing = m_artboardInstance->advance(seconds) || keepGoing; + return keepGoing; } void StateMachineInstance::markNeedsAdvance() { m_needsAdvance = true; } diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 18ff0981..fdd40b8d 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -129,15 +129,16 @@ StatusCode NestedArtboard::onAddedClean(CoreContext* context) bool NestedArtboard::advance(float elapsedSeconds) { + bool keepGoing = false; if (m_Artboard == nullptr || isCollapsed()) { - return false; + return keepGoing; } for (auto animation : m_NestedAnimations) { - animation->advance(elapsedSeconds); + keepGoing = keepGoing || animation->advance(elapsedSeconds); } - return m_Artboard->advance(elapsedSeconds); + return m_Artboard->advance(elapsedSeconds) || keepGoing; } void NestedArtboard::update(ComponentDirt value) diff --git a/test/assets/ball_test.riv b/test/assets/ball_test.riv new file mode 100644 index 0000000000000000000000000000000000000000..e0e618daaf663d412b75d3c3ce2a842d99661e8d GIT binary patch literal 995 zcmcJNJxjwt7{{L{$+buE_avv|L&KZoQpf*?f_rJ5*~^VSjK03 z#1j$hrvp%OMRWSnMmo3b1bF2xqj?b}8DR6~83FcDV(}d{jLog~QsoL+omr_4 z4d>B0mEP5I^m*)*_812RA`m^NZZ40FKYl>r5!s1|a7EFOaCnBXfGx_P_NP!wmVlIpEc$5qW_CiF4E44219 zX!l}V**osx>cpGOA&-jjj2{CqTq)$#99vzRG_q!HRjAdGJKp8pw$b<-A=UjZ4xpFpUm_XQHe pAyXz3iafind(); auto greenRect = greenMovingShapes.at(0); REQUIRE(greenRect->x() == 50); +} + +TEST_CASE("nested artboards with looping animations will keep main advanceAndApply advancing", + "[nested]") +{ + auto file = ReadRiveFile("../../test/assets/ball_test.riv"); + auto artboard = file->artboard("Artboard")->instance(); + artboard->advance(0.0f); + auto stateMachine = artboard->stateMachineAt(0); + REQUIRE(stateMachine->advanceAndApply(0.0f) == true); + REQUIRE(stateMachine->advanceAndApply(1.0f) == true); + REQUIRE(stateMachine->advanceAndApply(1.0f) == true); +} +TEST_CASE("nested artboards with one shot animations will not main advanceAndApply advancing", + "[nested]") +{ + + auto file = ReadRiveFile("../../test/assets/ball_test.riv"); + auto artboard = file->artboard("Artboard 2")->instance(); + artboard->advance(0.0f); + auto stateMachine = artboard->stateMachineAt(0); + REQUIRE(stateMachine->advanceAndApply(0.0f) == true); + REQUIRE(stateMachine->advanceAndApply(0.9f) == true); + REQUIRE(stateMachine->advanceAndApply(0.1f) == true); + // nested artboards animation is 1s long + REQUIRE(stateMachine->advanceAndApply(0.1f) == false); } \ No newline at end of file From 0a88f0e6661072777ec13739ccd586da88fb5a96 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Thu, 2 May 2024 17:35:32 +0000 Subject: [PATCH 038/138] Add static/dynamic runtime config based on actual target config. Based on chat with Matt from geotech. Diffs= 335a30588 Add static/dynamic runtime config based on actual target config. (#7184) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 31 ++++++++++++++++++--------- dependencies/premake5_harfbuzz_v2.lua | 3 ++- dependencies/rive_png_renames.h | 2 ++ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/.rive_head b/.rive_head index ceeb57a8..2ffd0ca9 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8db7cac50c53ab10838da0cd80c869917c51c72a +335a30588e5052375d6245e65c3c0a64864d486e diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 84993ee1..dfeaab4c 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -131,30 +131,41 @@ do end newoption({ - trigger = 'use_default_runtime', - description = 'Don\'t set windows static runtime and runtime values.', -}) - -newoption({ - trigger = 'runtime', + trigger = 'windows_runtime', description = 'Choose whether to use staticruntime on/off/default', allowed = { { 'default', 'Use default runtime' }, { 'static', 'Use static runtime' }, { 'dynamic', 'Use dynamic runtime' }, }, - default = 'static', + default = 'default', }) -filter({ 'system:windows', 'options:runtime=static' }) +-- This is just to match our old windows config. Gamekit specifically sets +-- static/dynamic and maybe we should do the same elsewhere. +filter({ 'system:windows', 'options:windows_runtime=default' }) +do + staticruntime('on') -- Match Skia's /MT flag for link compatibility + runtime('Release') +end + +filter({ 'system:windows', 'options:windows_runtime=static' }) do staticruntime('on') -- Match Skia's /MT flag for link compatibility - runtime('Release') -- Use /MT even in debug (/MTd is incompatible with Skia) end -filter({ 'system:windows', 'options:runtime=dynamic' }) +filter({ 'system:windows', 'options:windows_runtime=dynamic' }) do staticruntime('off') +end + +filter({ 'system:windows', 'options:not windows_runtime=default', 'options:config=debug' }) +do + runtime('Debug') +end + +filter({ 'system:windows', 'options:not windows_runtime=default', 'options:config=release' }) +do runtime('Release') end diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua index 183c378d..2114f7c1 100644 --- a/dependencies/premake5_harfbuzz_v2.lua +++ b/dependencies/premake5_harfbuzz_v2.lua @@ -1,7 +1,7 @@ dofile('rive_build_config.lua') local dependency = require('dependency') -harfbuzz = dependency.github('rive-app/harfbuzz', 'rive_8.3.0') +harfbuzz = dependency.github('rive-app/harfbuzz', 'rive_8.4.0') newoption({ trigger = 'no-harfbuzz-renames', @@ -225,6 +225,7 @@ do warnings('Off') defines({ + 'HB_ONLY_ONE_SHAPER', -- added this for Geotech Mac multi-module issue: https://github.com/rive-app/rive-cpp/issues/369 'HAVE_OT', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256', diff --git a/dependencies/rive_png_renames.h b/dependencies/rive_png_renames.h index 5a15fb01..5122b8c5 100644 --- a/dependencies/rive_png_renames.h +++ b/dependencies/rive_png_renames.h @@ -2,6 +2,8 @@ #define RIVE_PNG_RENAMES_H #define PNGPREFIX_H #define PNG_PREFIX rive_ +#define png_image_write_to_memory rive_png_image_write_to_memory +#define png_check_keyword rive_png_check_keyword #define png_sRGB_table rive_png_sRGB_table #define png_sRGB_base rive_png_sRGB_base #define png_sRGB_delta rive_png_sRGB_delta From 785bee1ff7a6d5f5a484f2158342061a4e31f536 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Fri, 3 May 2024 21:22:01 +0000 Subject: [PATCH 039/138] Fix ios analyzer Trying to disable some unused features that might be biting us.. Diffs= 0d03a416b Fix ios analyzer (#7198) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/premake5.lua | 11 ++++++++--- dependencies/premake5_harfbuzz_v2.lua | 6 ++++++ dependencies/premake5_miniaudio.lua | 2 +- dependencies/premake5_miniaudio_v2.lua | 2 +- premake5_v2.lua | 12 +++++++++--- 6 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.rive_head b/.rive_head index 2ffd0ca9..cb09d2ac 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -335a30588e5052375d6245e65c3c0a64864d486e +0d03a416b584cdd95aa4b496df105c14cdd2c05c diff --git a/build/premake5.lua b/build/premake5.lua index 4c34b540..dfe2dd1c 100644 --- a/build/premake5.lua +++ b/build/premake5.lua @@ -11,14 +11,19 @@ filter({ 'options:with_rive_text' }) do defines({ 'WITH_RIVE_TEXT' }) end -filter({}) filter({ 'options:with_rive_audio=system' }) do - defines({ 'WITH_RIVE_AUDIO' }) + defines({ 'WITH_RIVE_AUDIO', 'MA_NO_RESOURCE_MANAGER' }) end + filter({ 'options:with_rive_audio=external' }) do - defines({ 'WITH_RIVE_AUDIO', 'EXTERNAL_RIVE_AUDIO_ENGINE', 'MA_NO_DEVICE_IO' }) + defines({ + 'WITH_RIVE_AUDIO', + 'EXTERNAL_RIVE_AUDIO_ENGINE', + 'MA_NO_DEVICE_IO', + 'MA_NO_RESOURCE_MANAGER', + }) end filter({}) diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua index 2114f7c1..6ebdf0be 100644 --- a/dependencies/premake5_harfbuzz_v2.lua +++ b/dependencies/premake5_harfbuzz_v2.lua @@ -227,6 +227,7 @@ do defines({ 'HB_ONLY_ONE_SHAPER', -- added this for Geotech Mac multi-module issue: https://github.com/rive-app/rive-cpp/issues/369 'HAVE_OT', + 'HB_NO_CFF', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256', 'HB_NO_EXTERN_HELPERS', @@ -234,6 +235,8 @@ do 'HB_NO_COLOR', 'HB_NO_BITMAP', 'HB_NO_BUFFER_SERIALIZE', + 'HB_NO_BUFFER_VERIFY', + 'HB_NO_BUFFER_MESSAGE', 'HB_NO_SETLOCALE', 'HB_NO_STYLE', 'HB_NO_VERTICAL', @@ -241,6 +244,9 @@ do 'HB_NO_LAYOUT_RARELY_USED', 'HB_NO_LAYOUT_UNUSED', 'HB_NO_OT_FONT_GLYPH_NAMES', + 'HB_NO_PAINT', + 'HB_NO_MMAP', + 'HB_NO_META', }) filter('toolset:not msc') diff --git a/dependencies/premake5_miniaudio.lua b/dependencies/premake5_miniaudio.lua index a83cc41a..6779bba6 100644 --- a/dependencies/premake5_miniaudio.lua +++ b/dependencies/premake5_miniaudio.lua @@ -1,2 +1,2 @@ local dependency = require('dependency') -miniaudio = dependency.github('rive-app/miniaudio', 'rive_changes') +miniaudio = dependency.github('rive-app/miniaudio', 'rive_changes_4') diff --git a/dependencies/premake5_miniaudio_v2.lua b/dependencies/premake5_miniaudio_v2.lua index b193cb87..c2098b4f 100644 --- a/dependencies/premake5_miniaudio_v2.lua +++ b/dependencies/premake5_miniaudio_v2.lua @@ -1,3 +1,3 @@ dofile('rive_build_config.lua') local dependency = require('dependency') -miniaudio = dependency.github('rive-app/miniaudio', 'rive_changes') +miniaudio = dependency.github('rive-app/miniaudio', 'rive_changes_4') diff --git a/premake5_v2.lua b/premake5_v2.lua index 0787eddc..5311fb73 100644 --- a/premake5_v2.lua +++ b/premake5_v2.lua @@ -8,14 +8,19 @@ filter({ 'options:with_rive_text' }) do defines({ 'WITH_RIVE_TEXT' }) end -filter({}) filter({ 'options:with_rive_audio=system' }) do - defines({ 'WITH_RIVE_AUDIO' }) + defines({ 'WITH_RIVE_AUDIO', 'MA_NO_RESOURCE_MANAGER' }) end + filter({ 'options:with_rive_audio=external' }) do - defines({ 'WITH_RIVE_AUDIO', 'EXTERNAL_RIVE_AUDIO_ENGINE', 'MA_NO_DEVICE_IO' }) + defines({ + 'WITH_RIVE_AUDIO', + 'EXTERNAL_RIVE_AUDIO_ENGINE', + 'MA_NO_DEVICE_IO', + 'MA_NO_RESOURCE_MANAGER', + }) end filter({}) @@ -89,6 +94,7 @@ do '-Wno-implicit-fallthrough', '-Wno-implicit-int-conversion', '-Wno-undef', + '-Wno-unused-function', }) end From 1fadc01a78f67f0599e98d91d36b1472b8b7f2c1 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Tue, 7 May 2024 01:41:51 +0000 Subject: [PATCH 040/138] Add a "path_fuzz" mode to the PLS fuzzer Merge all fuzzers into a single application named "fuzz". Add another fuzzer that generates random paths. Fix some bugs it found. Diffs= 1d0d2b6ac Add a "path_fuzz" mode to the PLS fuzzer (#7211) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- src/math/mat2d.cpp | 11 ++++++++--- test/mat2d_test.cpp | 9 +++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.rive_head b/.rive_head index cb09d2ac..2b396c27 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -0d03a416b584cdd95aa4b496df105c14cdd2c05c +1d0d2b6acd58a8541bf0fa01a9ac0b5bb761e65a diff --git a/src/math/mat2d.cpp b/src/math/mat2d.cpp index d88edbfe..0980c8f4 100644 --- a/src/math/mat2d.cpp +++ b/src/math/mat2d.cpp @@ -135,9 +135,11 @@ AABB Mat2D::mapBoundingBox(const Vec2D pts[], size_t n) const } float4 bbox = simd::join(simd::min(mins.xy, mins.zw), simd::max(maxes.xy, maxes.zw)); - if (!simd::all(bbox.xy <= bbox.zw)) + // Use logic that takes the "nonfinite" branch when bbox has NaN values. + // Use "b - a >= 0" instead of "a >= b" because it fails when b == a == inf. + if (!simd::all(bbox.zw - bbox.xy >= 0)) { - // The given points were NaN or empty. + // The given points were NaN or empty, or infinite. bbox = float4(0); } else @@ -146,7 +148,10 @@ AABB Mat2D::mapBoundingBox(const Vec2D pts[], size_t n) const bbox += trans; } - return math::bit_cast(bbox); + auto aabb = math::bit_cast(bbox); + assert(aabb.width() >= 0); + assert(aabb.height() >= 0); + return aabb; } AABB Mat2D::mapBoundingBox(const AABB& aabb) const diff --git a/test/mat2d_test.cpp b/test/mat2d_test.cpp index af1c559f..cc807131 100644 --- a/test/mat2d_test.cpp +++ b/test/mat2d_test.cpp @@ -245,5 +245,14 @@ TEST_CASE("mapBoundingBox", "[Mat2D]") CHECK(Mat2D().mapBoundingBox(AABB{-1, nan, 1, 1}) == AABB{-1, 1, 1, 1}); CHECK(Mat2D().mapBoundingBox(AABB{-1, -1, nan, 1}) == AABB{-1, -1, -1, 1}); CHECK(Mat2D().mapBoundingBox(AABB{-1, -1, 1, nan}) == AABB{-1, -1, 1, -1}); + + // When AABB::height() inf - inf, the result is nan. + auto inf = std::numeric_limits::infinity(); + CHECK(Mat2D().mapBoundingBox(AABB{0, inf, 0, nan}).height() == 0); + CHECK(Mat2D().mapBoundingBox(AABB{0, -inf, 0, nan}).height() == 0); + CHECK(Mat2D().mapBoundingBox(AABB{inf, 0, nan, 0}).width() == 0); + CHECK(Mat2D().mapBoundingBox(AABB{-inf, 0, nan, 0}).width() == 0); + CHECK(Mat2D().mapBoundingBox(AABB{inf, 0, inf, 0}).width() == 0); + CHECK(Mat2D().mapBoundingBox(AABB{0, -inf, 0, -inf}).height() == 0); } } // namespace rive From 448cda297d1c21e3fc0a9ce63a8db1e4eca04af7 Mon Sep 17 00:00:00 2001 From: mjtalbot Date: Wed, 8 May 2024 15:09:23 +0000 Subject: [PATCH 041/138] Wasm fallback and min safari version ### This PR - fixes WASM not loading on older Apple devices/browsers - adds a fallback mechanism #### Fix for older devices The addition of `MIN_SAFARI_VERSION` is the only flag that resolved the issue on the affected devices (see discussion: https://2dimensions.slack.com/archives/CLLCU09T6/p1714494911457529) #### Fallback This PR is meant to showcase a way to introduce a fallback mechanism quickly. Can it be merged? Yes. But we need to consider the impact and alternatives (see below). _Also note that this PR makes an assumption about the best way to handle our single packages, which needs to be discussed before merging (see below)._ #### Problem with this fallback We'll increase the NPM package size by having two WASM files: `rive.wasm` and `rive_fallback.wasm`. To alleviate any concern, this can be resolved with proper documentation. The packages that load the WASM remotely do so through `unpkg` or `jsdelvr` (or overridden manually). It would not have an impact on the actual end client (to my knowledge), but maybe the perception of the "increased" NPM package size is something we want to avoid. #### Benefit of this approach Quick, with minimal change. We continue to use `unpkg` and `jsdelvr` to host. #### TODO Adaptive Loading: Implement more sophisticated loading strategies, such as loading different WASM modules based on the user's browser capabilities or preferences. This draft PR only loads the fallback if the current one failed. This does not need to be part of this PR and can be a future enhancement. ### Single vs Non-Single versions **This fallback mechanism will only work for the non-single packages where we load the WASM bundle separately**. Not the **-single versions, where WASM is bundled with the JS. In my testing during the call to `loadRuntime` the callback for `locateFile` will not be called if Emscripten is built with `-sSINGLE_FILE=1`. At the time of making the draft PR I've not come up with a solution for this. It might not be possible. TODO: This needs to be investigated more. Or we should reach out to Emscripten. #### What this means If we can't create a fallback for these, then we should make a decision around our single libraries: - Should they prefer to support older architecture and we recommend that people use the non-single packages to benefit from the fallback mechanism. - Or the alternative and we still recommend using the non-single packages to benefit from a fallback. **There are other benefits to using the non-single:** - Streaming Compilation: Newer browsers can start compiling the WASM file as soon as it starts downloading, which could lead to faster execution start times. - Better Cache Control: JavaScript and WASM can be cached separately. If you update one, users may not need to re-download the other. With the single version, I can see how people may end up using it in a way where any update to their site might then be bundling everything again. ### Alternative One _Most of the above still apply._ Instead of adding `rive_fallback.wasm` to the current packages, we create another NPM package called `rive_fallback` or something. And all this package is responsible for is to distribute the fallback WASM files, for example, `rive_canvas_fallback.wasm` and `rive_webgl_fallback.wasm`. **Benefit** We do not increase the perceived NPM package size for our published packages. And we can continue to use `unpkg` and `jsdelivr` for hosting. ### Alternative Two _Most of the above still apply._ We build our own hosting with versioning, etc. Diffs= 4342a3f04 Wasm fallback and min safari version (#7214) Co-authored-by: Gordon Co-authored-by: Maxwell Talbot --- .rive_head | 2 +- build/rive_build_config.lua | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 2b396c27..7af1aa16 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -1d0d2b6acd58a8541bf0fa01a9ac0b5bb761e65a +4342a3f049632b640b5522c1fabf7aef781423af diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index dfeaab4c..973f748c 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -458,6 +458,11 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then buildoptions({ '-msimd128' }) end + filter({ 'options:arch=wasm', 'options:no-wasm-simd' }) + do + linkoptions({ '-s MIN_SAFARI_VERSION=120000' }) + end + filter({ 'options:arch=wasm', 'options:config=debug' }) do buildoptions({ From 49a9ac541a9be88733f5d0ed492ed5cffe3f2384 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Wed, 8 May 2024 19:31:48 +0000 Subject: [PATCH 042/138] Add strokes, gradients, and blend modes to path_fuzz Diffs= 7d03c3faf Add strokes, gradients, and blend modes to path_fuzz (#7230) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- test/simd_test.cpp | 56 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/.rive_head b/.rive_head index 7af1aa16..9faac266 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -4342a3f049632b640b5522c1fabf7aef781423af +7d03c3fafeefd05513c4a418f320322ecd1c1e4e diff --git a/test/simd_test.cpp b/test/simd_test.cpp index e86aa7d9..7838c36c 100644 --- a/test/simd_test.cpp +++ b/test/simd_test.cpp @@ -31,6 +31,8 @@ namespace rive { constexpr float kInf = std::numeric_limits::infinity(); constexpr float kNaN = std::numeric_limits::quiet_NaN(); +constexpr double kInf_double = std::numeric_limits::infinity(); +constexpr double kNaN_double = std::numeric_limits::quiet_NaN(); // Check simd::any. TEST_CASE("any", "[simd]") @@ -295,21 +297,47 @@ TEST_CASE("min-max", "[simd]") CHECK_ALL((f4.xyz == vec<3>{1, 1, 2})); CHECK(std::isnan(f4.w)); + // fminf/fmaxf behaves the same as simd::min/max. // simd::min/max differs from std::min/max when the first argument is NaN. - CHECK(simd::min(kNaN, 1).x == 1); - CHECK(std::isnan(std::min(kNaN, 1))); - CHECK(simd::max(kNaN, 1).x == 1); - CHECK(std::isnan(std::max(kNaN, 1))); - CHECK(simd::min(kNaN, 1).x == 1); - CHECK(std::isnan(std::min(kNaN, 1))); - CHECK(simd::max(kNaN, 1).x == 1); - CHECK(std::isnan(std::max(kNaN, 1))); - - // simd::min/max is equivalent std::min/max when the second argument is NaN. - CHECK(simd::min(1, kNaN).x == std::min(1, kNaN)); - CHECK(simd::max(1, kNaN).x == std::max(1, kNaN)); - CHECK(simd::min(1, kNaN).x == std::min(1, kNaN)); - CHECK(simd::max(1, kNaN).x == std::max(1, kNaN)); + for (float f : {-2.f, -kInf, kInf}) + { + CHECK(simd::min(kNaN, f).x == f); + CHECK(fminf(kNaN, f) == f); + CHECK(std::isnan(std::min(kNaN, f))); + CHECK(simd::max(kNaN, f).x == f); + CHECK(fmaxf(kNaN, f) == f); + CHECK(std::isnan(std::max(kNaN, f))); + } + for (double d : {-1.0, -kInf_double, kInf_double}) + { + CHECK(simd::min(kNaN_double, d).x == d); + CHECK(fmin(kNaN_double, d) == d); + CHECK(std::isnan(std::min(kNaN_double, d))); + CHECK(simd::max(kNaN_double, d).x == d); + CHECK(fmax(kNaN_double, d) == d); + CHECK(std::isnan(std::max(kNaN_double, d))); + } + + // fminf/fmaxf/std::min/std::max/simd::min/stmd::max all behave the same when the second + // argument is NaN. + for (float f : {1.f, -kInf, kInf}) + { + CHECK(simd::min(f, kNaN).x == f); + CHECK(fminf(f, kNaN) == f); + CHECK(std::min(f, kNaN) == f); + CHECK(simd::max(f, kNaN).x == f); + CHECK(fmaxf(f, kNaN) == f); + CHECK(std::max(f, kNaN) == f); + } + for (double d : {2.0, -kInf_double, kInf_double}) + { + CHECK(simd::min(d, kNaN_double).x == d); + CHECK(fmin(d, kNaN_double) == d); + CHECK(std::min(d, kNaN_double) == d); + CHECK(simd::max(d, kNaN_double).x == d); + CHECK(fmax(d, kNaN_double) == d); + CHECK(std::max(d, kNaN_double) == d); + } // check non-32-bit types. CHECK_ALL((simd::max(simd::gvec{3, 4}, simd::gvec{4, 3}) == From 8e68ab77876153a04d8e53a9b11f30c2582418ae Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Wed, 8 May 2024 21:55:43 +0000 Subject: [PATCH 043/138] Fix an assert in contour_measure.cpp Since fp32 has finite precision, a segment may reasonably become degenerate with length 0, and we need to be robust enough to handle this. Asserting that the distance is non-negative is still a good test. Fixes #7210. Diffs= 806ae1fae Fix an assert in contour_measure.cpp (#7232) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- src/math/contour_measure.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 9faac266..42e70600 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -7d03c3fafeefd05513c4a418f320322ecd1c1e4e +806ae1faea4cc10452c76a4ce2b35f2ca12aa469 diff --git a/src/math/contour_measure.cpp b/src/math/contour_measure.cpp index 57c833c4..247f9082 100644 --- a/src/math/contour_measure.cpp +++ b/src/math/contour_measure.cpp @@ -34,7 +34,7 @@ ContourMeasure::ContourMeasure(std::vector&& segs, // or the last segment if distance == m_distance size_t ContourMeasure::findSegment(float distance) const { - assert(m_segments.front().m_distance > 0); + assert(m_segments.front().m_distance >= 0); assert(m_segments.back().m_distance == m_length); assert(distance >= 0 && distance <= m_length); From f8e8391390ae89629fa5ff0211dc75f23e5c1079 Mon Sep 17 00:00:00 2001 From: philter Date: Wed, 8 May 2024 22:06:48 +0000 Subject: [PATCH 044/138] Don't defer path update if Shape has a dependent skin Fixes an issue where shapes set to 0% opacity and also having bound bones were not updating, causing problems with hit detection on those shapes. Diffs= e0c4d9a20 Don't defer path update if Shape has a dependent skin (#7231) Co-authored-by: Philip Chung --- .rive_head | 2 +- src/shapes/points_path.cpp | 2 +- src/shapes/shape.cpp | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 42e70600..f5a3b4ce 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -806ae1faea4cc10452c76a4ce2b35f2ca12aa469 +e0c4d9a20df66b8bc43d7d2528caf432aa053ebb diff --git a/src/shapes/points_path.cpp b/src/shapes/points_path.cpp index a6d70d6c..a23b0ca3 100644 --- a/src/shapes/points_path.cpp +++ b/src/shapes/points_path.cpp @@ -28,7 +28,7 @@ const Mat2D& PointsPath::pathTransform() const void PointsPath::update(ComponentDirt value) { - if (hasDirt(value, ComponentDirt::Path) && skin() != nullptr && !m_Shape->canDeferPathUpdate()) + if (hasDirt(value, ComponentDirt::Path) && skin() != nullptr) { // Path tracks re-adding ComponentDirt::Path if we deferred due to to // shape being invisible. diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index 420b82df..e37b4749 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -1,6 +1,7 @@ #include "rive/constraints/constraint.hpp" #include "rive/hittest_command_path.hpp" #include "rive/shapes/path.hpp" +#include "rive/shapes/points_path.hpp" #include "rive/shapes/shape.hpp" #include "rive/shapes/clipping_shape.hpp" #include "rive/shapes/paint/blend_mode.hpp" @@ -28,6 +29,14 @@ bool Shape::canDeferPathUpdate() (pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath; if (canDefer) { + // If we have a dependent Skin, don't defer the update + for (auto d : dependents()) + { + if (d->is() && d->as()->skin() != nullptr) + { + return false; + } + } for (auto path : m_Paths) { if (!path->canDeferPathUpdate()) From 657354303be0cc13dd8926f6863489964dc62f5c Mon Sep 17 00:00:00 2001 From: bodymovin Date: Wed, 8 May 2024 22:59:09 +0000 Subject: [PATCH 045/138] remove harfbuzz flag Diffs= 8700c7365 remove harfbuzz flag (#7233) Co-authored-by: hernan --- .rive_head | 2 +- dependencies/premake5_harfbuzz_v2.lua | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index f5a3b4ce..17e01661 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e0c4d9a20df66b8bc43d7d2528caf432aa053ebb +8700c736576bf50e591a4ba61c005907c398a908 diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua index 6ebdf0be..428aa156 100644 --- a/dependencies/premake5_harfbuzz_v2.lua +++ b/dependencies/premake5_harfbuzz_v2.lua @@ -227,7 +227,6 @@ do defines({ 'HB_ONLY_ONE_SHAPER', -- added this for Geotech Mac multi-module issue: https://github.com/rive-app/rive-cpp/issues/369 'HAVE_OT', - 'HB_NO_CFF', 'HB_NO_FALLBACK_SHAPE', 'HB_NO_WIN1256', 'HB_NO_EXTERN_HELPERS', From 4aeeaddf4aa621fdcdd48a85bb287d5c24ab9f27 Mon Sep 17 00:00:00 2001 From: mjtalbot Date: Fri, 10 May 2024 08:18:40 +0000 Subject: [PATCH 046/138] fix advancing nested animations flipping the order of conditions to guarantee that all nested animations advance Diffs= 5ccc21fa3 fix advancing nested animations (#7246) Co-authored-by: hernan --- .rive_head | 2 +- src/nested_artboard.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 17e01661..231082d4 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8700c736576bf50e591a4ba61c005907c398a908 +5ccc21fa3a5f726827da601f04cf234138b379df diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index fdd40b8d..901661c0 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -136,7 +136,7 @@ bool NestedArtboard::advance(float elapsedSeconds) } for (auto animation : m_NestedAnimations) { - keepGoing = keepGoing || animation->advance(elapsedSeconds); + keepGoing = animation->advance(elapsedSeconds) || keepGoing; } return m_Artboard->advance(elapsedSeconds) || keepGoing; } From 6ecd5882959edd42d0e78785800216ec4c7588e2 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Thu, 16 May 2024 23:46:24 +0000 Subject: [PATCH 047/138] Simple libjpeg Original libjpeg (turbo was forked from an older version of this). Note C api is still the same. Diffs= 45b998e68 Simple libjpeg (#7277) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- decoders/premake5_v2.lua | 5 +- decoders/src/bitmap_decoder.cpp | 2 +- decoders/src/decode_jpeg.cpp | 117 +++++++++++++++++++++++++++ dependencies/jconfig.h | 11 +++ dependencies/premake5_libjpeg_v2.lua | 64 +++++++++++++++ dev/test/premake5.lua | 12 ++- test/assets/open_source.jpg | Bin 0 -> 8880 bytes test/assets/placeholder.png | Bin 0 -> 1096 bytes test/image_decoders_test.cpp | 29 +++++++ test/rive_file_reader.hpp | 25 +++--- viewer/build/premake5_viewer.lua | 2 +- 12 files changed, 254 insertions(+), 15 deletions(-) create mode 100644 decoders/src/decode_jpeg.cpp create mode 100644 dependencies/jconfig.h create mode 100644 dependencies/premake5_libjpeg_v2.lua create mode 100644 test/assets/open_source.jpg create mode 100644 test/assets/placeholder.png create mode 100644 test/image_decoders_test.cpp diff --git a/.rive_head b/.rive_head index 231082d4..10705429 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -5ccc21fa3a5f726827da601f04cf234138b379df +45b998e68b849e0c8741bf254a2193e31844c405 diff --git a/decoders/premake5_v2.lua b/decoders/premake5_v2.lua index b85d38b4..bf0a1156 100644 --- a/decoders/premake5_v2.lua +++ b/decoders/premake5_v2.lua @@ -3,14 +3,15 @@ dofile('rive_build_config.lua') rive = path.getabsolute('../') dofile(rive .. '/dependencies/premake5_libpng_v2.lua') +dofile(rive .. '/dependencies/premake5_libjpeg_v2.lua') project('rive_decoders') do - dependson('libpng') + dependson('libpng', 'zlib', 'libjpeg') kind('StaticLib') flags({ 'FatalWarnings' }) - includedirs({ 'include', '../include', libpng }) + includedirs({ 'include', '../include', libpng, libjpeg }) files({ 'src/**.cpp' }) end diff --git a/decoders/src/bitmap_decoder.cpp b/decoders/src/bitmap_decoder.cpp index 243ce29a..e497a6ea 100644 --- a/decoders/src/bitmap_decoder.cpp +++ b/decoders/src/bitmap_decoder.cpp @@ -39,7 +39,7 @@ size_t Bitmap::byteSize(PixelFormat format) const size_t Bitmap::byteSize() const { return byteSize(m_PixelFormat); } std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount); -std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount) { return nullptr; } +std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount); std::unique_ptr DecodeWebP(const uint8_t bytes[], size_t byteCount) { return nullptr; } using BitmapDecoder = std::unique_ptr (*)(const uint8_t bytes[], size_t byteCount); diff --git a/decoders/src/decode_jpeg.cpp b/decoders/src/decode_jpeg.cpp new file mode 100644 index 00000000..0eab5c78 --- /dev/null +++ b/decoders/src/decode_jpeg.cpp @@ -0,0 +1,117 @@ +// Adapted from libjpeg-turbo's example: +// https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/example.c +#include "rive/decoders/bitmap_decoder.hpp" + +#include "jpeglib.h" +#include "jerror.h" + +#include +#include +#include +#include + +struct my_error_mgr +{ + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +typedef struct my_error_mgr* my_error_ptr; + +void my_error_exit(j_common_ptr cinfo) +{ + // cinfo.err really points to a my_error_mgr struct, so coerce pointer + my_error_ptr myerr = (my_error_ptr)cinfo->err; + + // Always display the message. + // We could postpone this until after returning, if we chose. + (*cinfo->err->output_message)(cinfo); + + // Return control to the setjmp point + longjmp(myerr->setjmp_buffer, 1); +} + +std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount) +{ + struct jpeg_decompress_struct cinfo; + struct my_error_mgr jerr; + + JSAMPARRAY buffer = nullptr; + std::unique_ptr pixelBuffer; + int row_stride; + + // Step 1: allocate and initialize JPEG decompression object. + + // We set up the normal JPEG error routines, then override error_exit. + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + // Establish the setjmp return context for my_error_exit to use. + if (setjmp(jerr.setjmp_buffer)) + { + // If we get here, the JPEG code has signaled an error. + // We need to clean up the JPEG object, close the input file, and return. + jpeg_destroy_decompress(&cinfo); + return nullptr; + } + + // Now we can initialize the JPEG decompression object. + jpeg_create_decompress(&cinfo); + + // Step 2: specify data source + jpeg_mem_src(&cinfo, bytes, byteCount); + + // Step 3: read file parameters with jpeg_read_header() + + jpeg_read_header(&cinfo, TRUE); + + // Step 4: set parameters for decompression + + // always want 8 bit RGB + cinfo.data_precision = 8; + cinfo.out_color_space = JCS_RGB; + + // Step 5: Start decompressor + jpeg_start_decompress(&cinfo); + + /// Api worked as expected and gave us correct format even for jpeg 12 or 16 + assert(cinfo.data_precision == 8); + assert(cinfo.output_components == 3); + + pixelBuffer = std::make_unique(cinfo.output_width * cinfo.output_height * + cinfo.output_components); + + uint8_t* pixelWriteBuffer = (uint8_t*)pixelBuffer.get(); + + // Samples per row in output buffer + row_stride = cinfo.output_width * cinfo.output_components; + // Make a one-row-high sample array that will go away when done with image + buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); + + // Step 6: while (scan lines remain to be read) + // jpeg_read_scanlines(...); + + // Here we use the library's state variable cinfo->output_scanline as the + // loop counter, so that we don't have to keep track ourselves. + // + while (cinfo.output_scanline < cinfo.output_height) + { + // jpeg_read_scanlines expects an array of pointers to scanlines. + // Here the array is only one element long, but you could ask for + // more than one scanline at a time if that's more convenient. + jpeg_read_scanlines(&cinfo, buffer, 1); + + memcpy(pixelWriteBuffer, buffer[0], row_stride); + pixelWriteBuffer += row_stride; + } + + // Step 7: Finish decompression + jpeg_finish_decompress(&cinfo); + + // Step 8: Release JPEG decompression object + jpeg_destroy_decompress(&cinfo); + + return std::make_unique(cinfo.output_width, + cinfo.output_height, + Bitmap::PixelFormat::RGB, + std::move(pixelBuffer)); +} \ No newline at end of file diff --git a/dependencies/jconfig.h b/dependencies/jconfig.h new file mode 100644 index 00000000..b0daaa1a --- /dev/null +++ b/dependencies/jconfig.h @@ -0,0 +1,11 @@ +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +#undef INCOMPLETE_TYPES_BROKEN \ No newline at end of file diff --git a/dependencies/premake5_libjpeg_v2.lua b/dependencies/premake5_libjpeg_v2.lua new file mode 100644 index 00000000..30be9665 --- /dev/null +++ b/dependencies/premake5_libjpeg_v2.lua @@ -0,0 +1,64 @@ +dofile('rive_build_config.lua') + +if _OPTIONS['no-rive-decoders'] then + return +end + +local dependency = require('dependency') +libjpeg = dependency.github('rive-app/libjpeg', 'v9f') + +project('libjpeg') +do + kind('StaticLib') + + includedirs({ libjpeg }) + + files({ + libjpeg .. '/jaricom.c', + libjpeg .. '/jcapimin.c', + libjpeg .. '/jcapistd.c', + libjpeg .. '/jcarith.c', + libjpeg .. '/jccoefct.c', + libjpeg .. '/jccolor.c', + libjpeg .. '/jcdctmgr.c', + libjpeg .. '/jchuff.c', + libjpeg .. '/jcinit.c', + libjpeg .. '/jcmainct.c', + libjpeg .. '/jcmarker.c', + libjpeg .. '/jcmaster.c', + libjpeg .. '/jcomapi.c', + libjpeg .. '/jcparam.c', + libjpeg .. '/jcprepct.c', + libjpeg .. '/jcsample.c', + libjpeg .. '/jctrans.c', + libjpeg .. '/jdapimin.c', + libjpeg .. '/jdapistd.c', + libjpeg .. '/jdarith.c', + libjpeg .. '/jdatadst.c', + libjpeg .. '/jdatasrc.c', + libjpeg .. '/jdcoefct.c', + libjpeg .. '/jdcolor.c', + libjpeg .. '/jddctmgr.c', + libjpeg .. '/jdhuff.c', + libjpeg .. '/jdinput.c', + libjpeg .. '/jdmainct.c', + libjpeg .. '/jdmarker.c', + libjpeg .. '/jdmaster.c', + libjpeg .. '/jdmerge.c', + libjpeg .. '/jdpostct.c', + libjpeg .. '/jdsample.c', + libjpeg .. '/jdtrans.c', + libjpeg .. '/jerror.c', + libjpeg .. '/jfdctflt.c', + libjpeg .. '/jfdctfst.c', + libjpeg .. '/jfdctint.c', + libjpeg .. '/jidctflt.c', + libjpeg .. '/jidctfst.c', + libjpeg .. '/jidctint.c', + libjpeg .. '/jquant1.c', + libjpeg .. '/jquant2.c', + libjpeg .. '/jutils.c', + libjpeg .. '/jmemmgr.c', + libjpeg .. '/jmemansi.c', + }) +end diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index bef580b6..7fe5e83d 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -10,6 +10,7 @@ defines({ }) dofile(path.join(path.getabsolute('../../'), 'premake5_v2.lua')) +dofile(path.join(path.getabsolute('../../decoders/'), 'premake5_v2.lua')) project('tests') do @@ -19,10 +20,19 @@ do includedirs({ './include', '../../include', + '../../decoders/include', miniaudio, }) - links({ 'rive', 'rive_harfbuzz', 'rive_sheenbidi' }) + links({ + 'rive', + 'rive_harfbuzz', + 'rive_sheenbidi', + 'rive_decoders', + 'libpng', + 'zlib', + 'libjpeg', + }) files({ '../../test/**.cpp', -- the tests diff --git a/test/assets/open_source.jpg b/test/assets/open_source.jpg new file mode 100644 index 0000000000000000000000000000000000000000..710a4cf6116d2f0a6b2bd7a301dd90a06034b131 GIT binary patch literal 8880 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

Q?SZxhm5ou~z9%mYwW2qjE!albxympG7 z&6Rcvj=R3mZHtg|-VBA+zk@-YK#_wmO;1K!GHI%Zq6my3z(dMSmVQ55?}8-f1TIJ1 zJA0wvBhxx)?dzK?(#aC96ZD7EeM6`AS~4r&X*R3FHClbE3p*U_{k`i41@15JNZ>i; zg1TzE;_i-0mkQ6hrnCrDxUY`_u{DHde$AX&VFmwAkm)~#85HErpIV;4u! zZ6vsGRCaN+V1q~tfycwenwr;*jEh8%A-o&qGK$;ex4~UGrGUW{^=JJ&CBCTH z({O8+{*9@LURLpdF=>}eJ^lx;gHi59KrhX|i4553-~R1EYn+zJF215wH5QTc%=Lm* zfOFw&FEsNt>7AO%ky?u4(F9=^QAnSV`?g4&e7JfMZse(h4AN|S@3mF0u_5QcdPW#; zYwu8ZBi|!`Y;f}wRwFleCWa&e%Q!1`sw1J&H|95>vvfnA8`%5hB{!_m4FH&$Q%bEIAOdYvrfWjjQO9j1=HSQk(@Ik;M!Q+`=Ht$S`Y;1W=H% zILO_JVcj{Imp~3nx}&cn1H;CC?mvmF3=GV7JzX3_Dj471<@UQ{Akud6Lt5aQdhb0m zUnwnJw94aB`&;>%K9j7aL5*y+$;UekLW#2xR78ZW|w`%`n*N)zh7Jq;L(-~hCH`EF2*|%@s|47BS*jU}^)9e0f z`uIw(oM;f*8YwUI{rmU#@)AAjN8H@}-1~n?JPH3%x!+jPtf=l^>AhQBA09qTtgNn% zmT>Oqt=al`eb>j29|L=uEu!*McsKSPbo2ZD?@9G~!+ZDcMMb{#>EI3RS?qqSYqi_X zD8sea<7T`z3GJ!n{5bn}#lH<#vfka(i2WZHAH3Y+#bLuoDO&547vFuM`8B7-VqsT- z{;|@KCH#thtCaTa+Y?Fh-t@M8Q~s8m{GmnbfO2rq;zWC=IY)L)e)MAQ@obZl znj8HBhu40e`SZ5-*(}#BarK}6XRDNmf7rL@_Q5_M#sAx-Sl6##FaB#&gm6}EgRj4P z-a+Q7x@GGA8IF+a>Y@@sm4)}ys|MMYN~uk26H`gQiIZ_D?0 zFXsL!c^t{{akjP5qHABSwbj^!9k1Cwz%qi}cY&r4p z^!*I?jy<<`|H;iRHvI1gWJd4U*t}m?@l&v`zrFSL7bgR9IVZ+nnY+(^-I8_PmU#wO yrwidth() == 226); + REQUIRE(bitmap->height() == 128); +} + +TEST_CASE("jpeg file decodes correctly", "[image-decoder]") +{ + auto file = ReadFile("../../test/assets/open_source.jpg"); + REQUIRE(file.size() == 8880); + + auto bitmap = Bitmap::decode(file.data(), file.size()); + + REQUIRE(bitmap != nullptr); + + REQUIRE(bitmap->width() == 350); + REQUIRE(bitmap->height() == 200); +} diff --git a/test/rive_file_reader.hpp b/test/rive_file_reader.hpp index 6ba4c949..19001f03 100644 --- a/test/rive_file_reader.hpp +++ b/test/rive_file_reader.hpp @@ -8,16 +8,8 @@ static rive::NoOpFactory gNoOpFactory; -static inline std::unique_ptr ReadRiveFile(const char path[], - rive::Factory* factory = nullptr, - rive::FileAssetLoader* loader = nullptr, - bool loadInBandAssets = true) +static inline std::vector ReadFile(const char path[]) { - if (!factory) - { - factory = &gNoOpFactory; - } - FILE* fp = fopen(path, "rb"); REQUIRE(fp != nullptr); @@ -28,6 +20,21 @@ static inline std::unique_ptr ReadRiveFile(const char path[], REQUIRE(fread(bytes.data(), 1, length, fp) == length); fclose(fp); + return bytes; +} + +static inline std::unique_ptr ReadRiveFile(const char path[], + rive::Factory* factory = nullptr, + rive::FileAssetLoader* loader = nullptr, + bool loadInBandAssets = true) +{ + if (!factory) + { + factory = &gNoOpFactory; + } + + std::vector bytes = ReadFile(path); + rive::ImportResult result; auto file = rive::File::import(bytes, factory, &result, loader); REQUIRE(result == rive::ImportResult::success); diff --git a/viewer/build/premake5_viewer.lua b/viewer/build/premake5_viewer.lua index 1f7b2d93..741c4976 100644 --- a/viewer/build/premake5_viewer.lua +++ b/viewer/build/premake5_viewer.lua @@ -78,7 +78,7 @@ do do includedirs({ rive_tess .. '/include', rive .. '/decoders/include' }) defines({ 'RIVE_RENDERER_TESS' }) - links({ 'rive_tess_renderer', 'rive_decoders', 'libpng', 'zlib' }) + links({ 'rive_tess_renderer', 'rive_decoders', 'libpng', 'zlib', 'libjpeg' }) libdirs({ rive_tess .. '/build/%{cfg.system}/bin/%{cfg.buildcfg}' }) end From e682a6fbd34e72a01f2a86fca619858dd2bf4c3a Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 17 May 2024 01:57:43 +0000 Subject: [PATCH 048/138] initialize seed with chrono using rand without seeding it was generating the same sequence of results on every iteration. This PR initializes it with a new seed on every state machine instance. Diffs= 3734d9bac initialize seed with chrono (#7285) Co-authored-by: hernan --- .rive_head | 2 +- src/animation/state_machine_instance.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 10705429..036d2883 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -45b998e68b849e0c8741bf254a2193e31844c405 +3734d9bac071052acbcfdbec576ba9532bc84e3b diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index e5e387da..2400ced4 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -27,6 +27,7 @@ #include "rive/math/math_types.hpp" #include "rive/audio_event.hpp" #include +#include using namespace rive; namespace rive @@ -51,6 +52,10 @@ class StateMachineLayerInstance m_anyStateInstance = layer->anyState()->makeInstance(instance).release(); m_layer = layer; changeState(m_layer->entryState()); + auto now = std::chrono::high_resolution_clock::now(); + auto nanos = + std::chrono::duration_cast(now.time_since_epoch()).count(); + srand(nanos); } void updateMix(float seconds) From 2c45ce80234671ff07236baf8e4f3aef3e7cd8ba Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 17 May 2024 16:02:41 +0000 Subject: [PATCH 049/138] use world bounds for coarse grained collision test fixes #7286 I'm creating this PR mostly to align the way both runtimes behave, although the performance gain is a plus probably. Duo and others have reported that this difference of two pixels between runtime and editor are critical to how they build their projects. Diffs= 405b8ef90 use world bounds for coarse grained collision test (#7287) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/drawable_flag.hpp | 4 ++++ include/rive/math/aabb.hpp | 2 ++ include/rive/shapes/shape.hpp | 14 ++++++++++++++ src/animation/state_machine_instance.cpp | 17 +++++++++++++++-- src/math/aabb.cpp | 5 +++++ src/shapes/shape.cpp | 1 + test/aabb_test.cpp | 15 +++++++++++++++ test/hittest_test.cpp | 5 +++++ 9 files changed, 62 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 036d2883..618f3804 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -3734d9bac071052acbcfdbec576ba9532bc84e3b +405b8ef907d29cf480422b94d4717fdcdfad0824 diff --git a/include/rive/drawable_flag.hpp b/include/rive/drawable_flag.hpp index 9f79a152..c21604db 100644 --- a/include/rive/drawable_flag.hpp +++ b/include/rive/drawable_flag.hpp @@ -20,6 +20,10 @@ enum class DrawableFlag : unsigned short /// Whether this Component lets hit events pass through to components behind it Opaque = 1 << 3, + + /// Whether the computed world bounds for a shape need to be recalculated + /// Using Clean instead of dirty so it doesn't need to be initialized to 1 + WorldBoundsClean = 1 << 4, }; RIVE_MAKE_ENUM_BITSET(DrawableFlag) } // namespace rive diff --git a/include/rive/math/aabb.hpp b/include/rive/math/aabb.hpp index 2eabd8c5..6dda2ab4 100644 --- a/include/rive/math/aabb.hpp +++ b/include/rive/math/aabb.hpp @@ -121,6 +121,8 @@ class AABB return Vec2D(width() == 0.0f ? 0.0f : (point.x - left()) * 2.0f / width() - 1.0f, (height() == 0.0f ? 0.0f : point.y - top()) * 2.0f / height() - 1.0f); } + + bool contains(Vec2D position) const; }; } // namespace rive diff --git a/include/rive/shapes/shape.hpp b/include/rive/shapes/shape.hpp index 3f2c6869..830e8779 100644 --- a/include/rive/shapes/shape.hpp +++ b/include/rive/shapes/shape.hpp @@ -5,6 +5,7 @@ #include "rive/generated/shapes/shape_base.hpp" #include "rive/shapes/path_composer.hpp" #include "rive/shapes/shape_paint_container.hpp" +#include "rive/drawable_flag.hpp" #include namespace rive @@ -17,6 +18,7 @@ class Shape : public ShapeBase, public ShapePaintContainer private: PathComposer m_PathComposer; std::vector m_Paths; + AABB m_WorldBounds; bool m_WantDifferencePath = false; @@ -47,6 +49,18 @@ class Shape : public ShapeBase, public ShapePaintContainer bool isEmpty(); void pathCollapseChanged(); + AABB worldBounds() + { + if ((static_cast(drawableFlags()) & DrawableFlag::WorldBoundsClean) != + DrawableFlag::WorldBoundsClean) + { + drawableFlags(drawableFlags() | + static_cast(DrawableFlag::WorldBoundsClean)); + m_WorldBounds = computeWorldBounds(); + } + return m_WorldBounds; + } + AABB computeWorldBounds(const Mat2D* xform = nullptr) const; AABB computeLocalBounds() const; }; diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 2400ced4..dd3f7858 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -418,15 +418,28 @@ class HitShape : public HitComponent float hitRadius = 2; Vec2D previousPosition; std::vector listeners; - HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override + + bool hitTest(Vec2D position) const { + auto shape = m_component->as(); + auto worldBounds = shape->worldBounds(); + if (!worldBounds.contains(position)) + { + return false; + } auto hitArea = AABB(position.x - hitRadius, position.y - hitRadius, position.x + hitRadius, position.y + hitRadius) .round(); - bool isOver = canHit ? shape->hitTest(hitArea) : false; + return shape->hitTest(hitArea); + } + + HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override + { + auto shape = m_component->as(); + bool isOver = canHit ? hitTest(position) : false; bool hoverChange = isHovered != isOver; isHovered = isOver; if (hoverChange && isHovered) diff --git a/src/math/aabb.cpp b/src/math/aabb.cpp index 23688fcc..c6fa11aa 100644 --- a/src/math/aabb.cpp +++ b/src/math/aabb.cpp @@ -80,3 +80,8 @@ void AABB::join(AABB& out, const AABB& a, const AABB& b) out.maxX = std::max(a.maxX, b.maxX); out.maxY = std::max(a.maxY, b.maxY); } + +bool AABB::contains(Vec2D point) const +{ + return point.x >= left() && point.x <= right() && point.y >= top() && point.y <= bottom(); +} diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index e37b4749..157e378f 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -70,6 +70,7 @@ bool Shape::collapse(bool value) void Shape::pathChanged() { + drawableFlags(drawableFlags() & ~static_cast(DrawableFlag::WorldBoundsClean)); m_PathComposer.addDirt(ComponentDirt::Path, true); for (auto constraint : constraints()) { diff --git a/test/aabb_test.cpp b/test/aabb_test.cpp index 0f06abe7..2e380b3b 100644 --- a/test/aabb_test.cpp +++ b/test/aabb_test.cpp @@ -49,4 +49,19 @@ TEST_CASE("isEmptyOrNaN", "[AABB]") CHECK(AABB{nan, nan, nan, 10}.isEmptyOrNaN()); CHECK(AABB{nan, nan, nan, nan}.isEmptyOrNaN()); } + +TEST_CASE("AABB contains", "[AABB]") +{ + CHECK(AABB{0, 0, 100, 100}.contains(Vec2D(20, 20))); + CHECK(AABB{0, 0, 100, 100}.contains(Vec2D(0, 0))); + CHECK(AABB{0, 0, 100, 100}.contains(Vec2D(100, 100))); + CHECK(!AABB{0, 0, 100, 100}.contains(Vec2D(200, 200))); + CHECK(!AABB{0, 0, 100, 100}.contains(Vec2D(-200, -200))); + auto leftBoundary = 0.f; + auto rightBoundary = 100.f; + CHECK(!AABB{leftBoundary, 0, rightBoundary, 100.0}.contains( + Vec2D(leftBoundary - std::numeric_limits::epsilon(), 50))); + CHECK(!AABB{leftBoundary, 0, rightBoundary, 100.0}.contains( + Vec2D(rightBoundary + rightBoundary * std::numeric_limits::epsilon(), 50))); +} } // namespace rive diff --git a/test/hittest_test.cpp b/test/hittest_test.cpp index cb4f8f8c..87b14296 100644 --- a/test/hittest_test.cpp +++ b/test/hittest_test.cpp @@ -161,6 +161,11 @@ TEST_CASE("hit test on opaque nested artboard", "[hittest]") // toggle changes value because it is not under an opaque nested artboard REQUIRE(secondGrayToggle->value() == true); + stateMachineInstance->pointerDown(rive::Vec2D(301.0f, 50.0f)); + // toggle does not change because it is beyond the area of the square by 1 pixel + // And the 2px padding is unly used after the coarse grained test passes + REQUIRE(secondGrayToggle->value() == true); + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 50.0f)); // toggle does not change because it is under an opaque nested artboard REQUIRE(secondGrayToggle->value() == true); From 61d6fbb5cfd89aff9ab20ad8a21e58bf8753b807 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Tue, 21 May 2024 21:13:37 +0000 Subject: [PATCH 050/138] Make ContourMeasure more robust Make assertions and operations inside ContourMeasure more robust with degenerate data and NaN. Add a rive::math::clamp() method with better behavior surrounding NaN. Change the ContourMeasureIter constructor to accept a "const RawPath*". (The former definition with "const RawPath&" accepted r-values, which was unsafe since the iterator stored raw pointers directly to objects owned by the RawPath.) Delete RawPath operator*(). The way this operator was defined, the matrix had to go on the wrong side of the path relative to how it operated on the data. Diffs= cd6210f42 Make ContourMeasure more robust (#7294) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- include/rive/math/contour_measure.hpp | 4 +- include/rive/math/math_types.hpp | 11 ++++++ include/rive/math/raw_path.hpp | 1 - src/constraints/follow_path_constraint.cpp | 2 +- src/math/contour_measure.cpp | 29 +++++++++------ src/shapes/metrics_path.cpp | 3 +- test/contour_measure_test.cpp | 37 ++++++++++++++++--- test/metrics_path_test.cpp | 28 +++++++++++++- test/simd_test.cpp | 12 ++++++ .../src/viewer_content/textpath_content.cpp | 2 +- .../src/viewer_content/trimpath_content.cpp | 2 +- 12 files changed, 107 insertions(+), 26 deletions(-) diff --git a/.rive_head b/.rive_head index 618f3804..29b2afd9 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -405b8ef907d29cf480422b94d4717fdcdfad0824 +cd6210f42d644de3cc1c83fa65b3d4e1f790cece diff --git a/include/rive/math/contour_measure.hpp b/include/rive/math/contour_measure.hpp index 8077ee68..93eea52c 100644 --- a/include/rive/math/contour_measure.hpp +++ b/include/rive/math/contour_measure.hpp @@ -97,12 +97,12 @@ class ContourMeasureIter // approximation for the curves actual length. static constexpr float kDefaultTolerance = 0.5f; - ContourMeasureIter(const RawPath& path, float tol = kDefaultTolerance) + ContourMeasureIter(const RawPath* path, float tol = kDefaultTolerance) { this->rewind(path, tol); } - void rewind(const RawPath&, float = kDefaultTolerance); + void rewind(const RawPath*, float = kDefaultTolerance); // Returns a measure object for each contour in the path // (contours with zero-length are skipped over) diff --git a/include/rive/math/math_types.hpp b/include/rive/math/math_types.hpp index 481c9b54..17dfaeab 100644 --- a/include/rive/math/math_types.hpp +++ b/include/rive/math/math_types.hpp @@ -112,6 +112,17 @@ template RIVE_ALWAYS_INLINE constexpr size_t round_up_to_multiple_of( "math::round_up_to_multiple_of<> only supports powers of 2."); return (x + (N - 1)) & ~(N - 1); } + +// Behaves better with NaN than std::clamp(). (Matching simd::clamp().) +// +// Returns lo if x == NaN (but std::clamp() returns NaN). +// Returns hi if hi <= lo. +// Ignores hi and/or lo if they are NaN. +// +RIVE_ALWAYS_INLINE static float clamp(float x, float lo, float hi) +{ + return fminf(fmaxf(lo, x), hi); +} } // namespace math template T lerp(const T& a, const T& b, float t) { return a + (b - a) * t; } diff --git a/include/rive/math/raw_path.hpp b/include/rive/math/raw_path.hpp index 7f277f84..df502450 100644 --- a/include/rive/math/raw_path.hpp +++ b/include/rive/math/raw_path.hpp @@ -49,7 +49,6 @@ class RawPath RawPath transform(const Mat2D&) const; void transformInPlace(const Mat2D&); - RawPath operator*(const Mat2D& mat) const { return this->transform(mat); } Span points() const { return m_Points; } Span points() { return m_Points; } diff --git a/src/constraints/follow_path_constraint.cpp b/src/constraints/follow_path_constraint.cpp index fa3bb212..0b8096f6 100644 --- a/src/constraints/follow_path_constraint.cpp +++ b/src/constraints/follow_path_constraint.cpp @@ -154,7 +154,7 @@ void FollowPathConstraint::update(ComponentDirt value) commandPath->addToRawPath(m_rawPath, path->pathTransform()); } - auto measure = ContourMeasureIter(m_rawPath); + auto measure = ContourMeasureIter(&m_rawPath); for (auto contour = measure.next(); contour != nullptr; contour = measure.next()) { m_contours.push_back(contour); diff --git a/src/math/contour_measure.cpp b/src/math/contour_measure.cpp index 247f9082..89c1e425 100644 --- a/src/math/contour_measure.cpp +++ b/src/math/contour_measure.cpp @@ -247,9 +247,12 @@ static float compute_t(Span segs, size_t index, f } } - assert(prevDist < seg.m_distance); + assert(prevDist <= seg.m_distance); const auto ratio = (distance - prevDist) / (seg.m_distance - prevDist); - return lerp(prevT, seg.getT(), ratio); + float t = lerp(prevT, seg.getT(), ratio); + t = math::clamp(t, prevT, seg.getT()); + assert(prevT <= t && t <= seg.getT()); + return t; } void ContourMeasure::getSegment(float startDist, @@ -366,16 +369,16 @@ float ContourMeasureIter::addCubicSegs(ContourMeasure::Segment* segs, return distance; } -void ContourMeasureIter::rewind(const RawPath& path, float tolerance) +void ContourMeasureIter::rewind(const RawPath* path, float tolerance) { - m_iter = path.begin(); - m_end = path.end(); - m_srcPoints = path.points().data(); + m_iter = path->begin(); + m_end = path->end(); + m_srcPoints = path->points().data(); constexpr float kMinTolerance = 1.0f / 16; m_invTolerance = 1.0f / std::max(tolerance, kMinTolerance); - m_segmentCounts.resize(path.verbs().count()); + m_segmentCounts.resize(path->verbs().count()); } // Can return null if either it encountered an empty contour (length == 0) @@ -515,12 +518,15 @@ rcp ContourMeasureIter::tryNext() m_iter = endOfContour; - if (distance == 0 || pts.size() < 2) + if (distance > 0 && pts.size() >= 2) { - return nullptr; + assert(!std::isnan(distance)); + return rcp( + new ContourMeasure(std::move(segs), std::move(pts), distance, isClosed)); } - return rcp( - new ContourMeasure(std::move(segs), std::move(pts), distance, isClosed)); + + assert(distance == 0 || std::isnan(distance)); + return nullptr; } rcp ContourMeasureIter::next() @@ -537,5 +543,6 @@ rcp ContourMeasureIter::next() break; } } + assert(!cm || !std::isnan(cm->length())); return cm; } diff --git a/src/shapes/metrics_path.cpp b/src/shapes/metrics_path.cpp index 46fea411..f66aa5e4 100644 --- a/src/shapes/metrics_path.cpp +++ b/src/shapes/metrics_path.cpp @@ -63,7 +63,8 @@ float MetricsPath::computeLength(const Mat2D& transform) if (!m_Contour || transform != m_ComputedLengthTransform) { m_ComputedLengthTransform = transform; - m_Contour = ContourMeasureIter(m_RawPath * transform).next(); + RawPath transformedPath = m_RawPath.transform(transform); + m_Contour = ContourMeasureIter(&transformedPath).next(); m_ComputedLength = m_Contour ? m_Contour->length() : 0; } return m_ComputedLength; diff --git a/test/contour_measure_test.cpp b/test/contour_measure_test.cpp index a52f1b6c..c9164d68 100644 --- a/test/contour_measure_test.cpp +++ b/test/contour_measure_test.cpp @@ -39,15 +39,15 @@ TEST_CASE("contour-basics", "[contourmeasure]") const float tol = 0.000001f; RawPath path; - ContourMeasureIter iter(path, false); + ContourMeasureIter iter(&path); REQUIRE(iter.next() == nullptr); path.moveTo(1, 2); - iter.rewind(path, false); + iter.rewind(&path); REQUIRE(iter.next() == nullptr); path.lineTo(4, 6); - iter.rewind(path, false); + iter.rewind(&path); auto cm = iter.next(); REQUIRE(cm); REQUIRE(nearly_eq(cm->length(), 5, tol)); @@ -58,7 +58,7 @@ TEST_CASE("contour-basics", "[contourmeasure]") path = RawPath(); const float w = 4, h = 6; path.addRect({0, 0, w, h}, PathDirection::cw); - iter.rewind(path, false); + iter.rewind(&path); cm = iter.next(); REQUIRE(cm); REQUIRE(nearly_eq(cm->length(), 2 * (w + h), tol)); @@ -118,7 +118,7 @@ TEST_CASE("multi-contours", "[contourmeasure]") path.addPoly(span, false); // len == 7 - ContourMeasureIter iter(path, false); + ContourMeasureIter iter(&path); auto cm = iter.next(); REQUIRE(cm->length() == 7); cm = iter.next(); @@ -136,7 +136,7 @@ TEST_CASE("contour-oval", "[contourmeasure]") const float r = 10; RawPath path; path.addOval({-r, -r, r, r}, PathDirection::cw); - ContourMeasureIter iter(path, false); + ContourMeasureIter iter(&path, tol); auto cm = iter.next(); REQUIRE(nearly_eq(cm->length(), 2 * r * math::PI, tol)); @@ -152,3 +152,28 @@ TEST_CASE("bad contour", "[contourmeasure]") auto machine = artboard->defaultStateMachine(); machine->advanceAndApply(0.0f); } + +// NaN paths don't return contours. +TEST_CASE("nan-path", "[contourmeasure]") +{ + RawPath path; + path.lineTo(1, 2); + path.cubicTo(3, 4, 5, 6, 7, 8); + path.cubicTo(9, 10, 11, 12, 13, 14); + path.cubicTo(15, 16, 17, 18, 19, 20); + + { + ContourMeasureIter iter(&path); + auto cm = iter.next(); + CHECK(cm != nullptr); + CHECK(std::isfinite(cm->length())); + CHECK(iter.next() == nullptr); + } + + { + auto nan = std::numeric_limits::quiet_NaN(); + RawPath path_ = path.transform(Mat2D(nan, nan, nan, nan, nan, nan)); + ContourMeasureIter iter(&path_); + CHECK(iter.next() == nullptr); + } +} diff --git a/test/metrics_path_test.cpp b/test/metrics_path_test.cpp index 44efab79..cde47276 100644 --- a/test/metrics_path_test.cpp +++ b/test/metrics_path_test.cpp @@ -1,5 +1,11 @@ #include +#include #include +#include +#include +#include + +using namespace rive; TEST_CASE("path metrics compute correctly", "[bezier]") { @@ -25,4 +31,24 @@ TEST_CASE("path metrics compute correctly", "[bezier]") // float cubicLength = cubicPath.computeLength(identity); // REQUIRE(cubicLength == 238.38698f); -} \ No newline at end of file +} + +// Regression test for a crash found by fuzzing. +TEST_CASE("fuzz_issue_7295", "[MetricsPath]") +{ + NoOpFactory factory; + + OnlyMetricsPath innerPath; + innerPath.moveTo(.0f, -20.5f); + innerPath.cubicTo(11.3218384f, -20.5f, 20.5f, -11.3218384f, 20.5f, .0f); + innerPath.cubicTo(20.5f, 11.3218384f, 11.3218384f, 20.5f, .0f, 20.5f); + innerPath.cubicTo(-11.3218384f, 20.5f, -20.5f, 11.3218384f, -20.5f, .0f); + innerPath.cubicTo(-20.5f, -11.3218384f, -11.3218384f, -20.5f, .0f, -20.5f); + + OnlyMetricsPath outerPath; + outerPath.addPath(&innerPath, Mat2D(1.f, .0f, .0f, 1.f, -134217728.f, -134217728.f)); + + RawPath result; + outerPath.paths()[0]->trim(.0f, 168.389008f, true, &result); + CHECK(math::nearly_equal(outerPath.paths()[0]->length(), 168.389008f)); +} diff --git a/test/simd_test.cpp b/test/simd_test.cpp index 7838c36c..2192f120 100644 --- a/test/simd_test.cpp +++ b/test/simd_test.cpp @@ -369,11 +369,17 @@ TEST_CASE("clamp", "[simd]") // Returns lo if x == NaN, but std::clamp() returns NaN. CHECK(simd::clamp(kNaN, 1, 2).x == 1); + // Matches math::clamp(). + CHECK(simd::clamp(kNaN, 1, 2).x == math::clamp(kNaN, 1, 2)); // Returns hi if hi <= lo. CHECK(simd::clamp(3, 2, 1).x == 1); CHECK(simd::clamp(kNaN, 2, 1).x == 1); CHECK(simd::clamp(kNaN, kNaN, 1).x == 1); + // Matches math::clamp(). + CHECK(simd::clamp(3, 2, 1).x == math::clamp(3, 2, 1)); + CHECK(simd::clamp(kNaN, 2, 1).x == math::clamp(kNaN, 2, 1)); + CHECK(simd::clamp(kNaN, kNaN, 1).x == math::clamp(kNaN, kNaN, 1)); // Ignores hi and/or lo if they are NaN. CHECK(simd::clamp(3, 4, kNaN).x == 4); @@ -381,6 +387,12 @@ TEST_CASE("clamp", "[simd]") CHECK(simd::clamp(3, kNaN, 2).x == 2); CHECK(simd::clamp(3, kNaN, 4).x == 3); CHECK(simd::clamp(3, kNaN, kNaN).x == 3); + // Matches math::clamp(). + CHECK(simd::clamp(3, 4, kNaN).x == math::clamp(3, 4, kNaN)); + CHECK(simd::clamp(3, 2, kNaN).x == math::clamp(3, 2, kNaN)); + CHECK(simd::clamp(3, kNaN, 2).x == math::clamp(3, kNaN, 2)); + CHECK(simd::clamp(3, kNaN, 4).x == math::clamp(3, kNaN, 4)); + CHECK(simd::clamp(3, kNaN, kNaN).x == math::clamp(3, kNaN, kNaN)); } // Check simd::abs. diff --git a/viewer/src/viewer_content/textpath_content.cpp b/viewer/src/viewer_content/textpath_content.cpp index 69fe3fd0..9b05375c 100644 --- a/viewer/src/viewer_content/textpath_content.cpp +++ b/viewer/src/viewer_content/textpath_content.cpp @@ -241,7 +241,7 @@ class TextPathContent : public ViewerContent RawPath warp = make_quad_path(m_pathpts); this->draw_warp(renderer, warp); - auto meas = ContourMeasureIter(warp).next(); + auto meas = ContourMeasureIter(&warp).next(); const float warpLength = meas->length(); const float textLength = gruns.back().xpos.back(); diff --git a/viewer/src/viewer_content/trimpath_content.cpp b/viewer/src/viewer_content/trimpath_content.cpp index af28c42e..d4ffb3d1 100644 --- a/viewer/src/viewer_content/trimpath_content.cpp +++ b/viewer/src/viewer_content/trimpath_content.cpp @@ -114,7 +114,7 @@ class TrimPathContent : public ViewerContent { renderer->save(); - auto cm = ContourMeasureIter(*p, false).next(); + auto cm = ContourMeasureIter(p, false).next(); auto p1 = trim(cm.get(), m_trimFrom, m_trimTo); stroke_path(renderer, p1, 20, 0xFFFF0000); From 35f22ae75d7720d64f1bdf72259b370bc6834fa6 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Wed, 22 May 2024 19:50:10 +0000 Subject: [PATCH 051/138] validating core objects property keys on load this should fix fuzz crashes caught from bad animation keys Diffs= 8a538c243 validating core objects property keys on load (#7298) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- dev/core_generator/lib/src/definition.dart | 16 + include/rive/generated/core_registry.hpp | 535 +++++++++++++++++++++ src/animation/keyed_object.cpp | 8 +- 4 files changed, 559 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 29b2afd9..dd5879ce 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -cd6210f42d644de3cc1c83fa65b3d4e1f790cece +8a538c243fcc5b72159388a7e63669f1e6998dda diff --git a/dev/core_generator/lib/src/definition.dart b/dev/core_generator/lib/src/definition.dart index eeac8987..5a04630f 100644 --- a/dev/core_generator/lib/src/definition.dart +++ b/dev/core_generator/lib/src/definition.dart @@ -557,6 +557,22 @@ class Definition { ctxCode.writeln('default:return false;'); ctxCode.writeln('}}'); + // static bool objectSupportsProperty(Core* object, uint32_t propertyKey) { return true; } + ctxCode.writeln(''' + static bool objectSupportsProperty(Core* object, uint32_t propertyKey) { + switch(propertyKey) {'''); + for (final fieldType in usedFieldTypes.keys) { + var properties = getSetFieldTypes[fieldType]; + if (properties != null) { + for (final property in properties) { + ctxCode.writeln('case ${property.definition.name}Base' + '::${property.name}PropertyKey:'); + ctxCode + .writeln('return object->is<${property.definition.name}Base>();'); + } + } + } + ctxCode.writeln('}return false;}'); ctxCode.writeln('};}'); var output = generatedHppPath; diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index a0c8df9a..c306c1fe 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -2055,6 +2055,541 @@ class CoreRegistry return false; } } + static bool objectSupportsProperty(Core* object, uint32_t propertyKey) + { + switch (propertyKey) + { + case ComponentBase::namePropertyKey: + return object->is(); + case AnimationBase::namePropertyKey: + return object->is(); + case StateMachineComponentBase::namePropertyKey: + return object->is(); + case KeyFrameStringBase::valuePropertyKey: + return object->is(); + case OpenUrlEventBase::urlPropertyKey: + return object->is(); + case TextValueRunBase::textPropertyKey: + return object->is(); + case CustomPropertyStringBase::propertyValuePropertyKey: + return object->is(); + case AssetBase::namePropertyKey: + return object->is(); + case FileAssetBase::cdnBaseUrlPropertyKey: + return object->is(); + case ComponentBase::parentIdPropertyKey: + return object->is(); + case DrawTargetBase::drawableIdPropertyKey: + return object->is(); + case DrawTargetBase::placementValuePropertyKey: + return object->is(); + case TargetedConstraintBase::targetIdPropertyKey: + return object->is(); + case DistanceConstraintBase::modeValuePropertyKey: + return object->is(); + case TransformSpaceConstraintBase::sourceSpaceValuePropertyKey: + return object->is(); + case TransformSpaceConstraintBase::destSpaceValuePropertyKey: + return object->is(); + case TransformComponentConstraintBase::minMaxSpaceValuePropertyKey: + return object->is(); + case IKConstraintBase::parentBoneCountPropertyKey: + return object->is(); + case DrawableBase::blendModeValuePropertyKey: + return object->is(); + case DrawableBase::drawableFlagsPropertyKey: + return object->is(); + case NestedArtboardBase::artboardIdPropertyKey: + return object->is(); + case NestedAnimationBase::animationIdPropertyKey: + return object->is(); + case SoloBase::activeComponentIdPropertyKey: + return object->is(); + case ListenerFireEventBase::eventIdPropertyKey: + return object->is(); + case LayerStateBase::flagsPropertyKey: + return object->is(); + case ListenerInputChangeBase::inputIdPropertyKey: + return object->is(); + case ListenerInputChangeBase::nestedInputIdPropertyKey: + return object->is(); + case AnimationStateBase::animationIdPropertyKey: + return object->is(); + case NestedInputBase::inputIdPropertyKey: + return object->is(); + case KeyedObjectBase::objectIdPropertyKey: + return object->is(); + case BlendAnimationBase::animationIdPropertyKey: + return object->is(); + case BlendAnimationDirectBase::inputIdPropertyKey: + return object->is(); + case BlendAnimationDirectBase::blendSourcePropertyKey: + return object->is(); + case TransitionConditionBase::inputIdPropertyKey: + return object->is(); + case KeyedPropertyBase::propertyKeyPropertyKey: + return object->is(); + case StateMachineListenerBase::targetIdPropertyKey: + return object->is(); + case StateMachineListenerBase::listenerTypeValuePropertyKey: + return object->is(); + case StateMachineListenerBase::eventIdPropertyKey: + return object->is(); + case KeyFrameBase::framePropertyKey: + return object->is(); + case InterpolatingKeyFrameBase::interpolationTypePropertyKey: + return object->is(); + case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: + return object->is(); + case KeyFrameIdBase::valuePropertyKey: + return object->is(); + case ListenerBoolChangeBase::valuePropertyKey: + return object->is(); + case ListenerAlignTargetBase::targetIdPropertyKey: + return object->is(); + case TransitionValueConditionBase::opValuePropertyKey: + return object->is(); + case StateTransitionBase::stateToIdPropertyKey: + return object->is(); + case StateTransitionBase::flagsPropertyKey: + return object->is(); + case StateTransitionBase::durationPropertyKey: + return object->is(); + case StateTransitionBase::exitTimePropertyKey: + return object->is(); + case StateTransitionBase::interpolationTypePropertyKey: + return object->is(); + case StateTransitionBase::interpolatorIdPropertyKey: + return object->is(); + case StateTransitionBase::randomWeightPropertyKey: + return object->is(); + case StateMachineFireEventBase::eventIdPropertyKey: + return object->is(); + case StateMachineFireEventBase::occursValuePropertyKey: + return object->is(); + case LinearAnimationBase::fpsPropertyKey: + return object->is(); + case LinearAnimationBase::durationPropertyKey: + return object->is(); + case LinearAnimationBase::loopValuePropertyKey: + return object->is(); + case LinearAnimationBase::workStartPropertyKey: + return object->is(); + case LinearAnimationBase::workEndPropertyKey: + return object->is(); + case ElasticInterpolatorBase::easingValuePropertyKey: + return object->is(); + case BlendState1DBase::inputIdPropertyKey: + return object->is(); + case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: + return object->is(); + case StrokeBase::capPropertyKey: + return object->is(); + case StrokeBase::joinPropertyKey: + return object->is(); + case TrimPathBase::modeValuePropertyKey: + return object->is(); + case FillBase::fillRulePropertyKey: + return object->is(); + case PathBase::pathFlagsPropertyKey: + return object->is(); + case ClippingShapeBase::sourceIdPropertyKey: + return object->is(); + case ClippingShapeBase::fillRulePropertyKey: + return object->is(); + case PolygonBase::pointsPropertyKey: + return object->is(); + case ImageBase::assetIdPropertyKey: + return object->is(); + case DrawRulesBase::drawTargetIdPropertyKey: + return object->is(); + case ArtboardBase::defaultStateMachineIdPropertyKey: + return object->is(); + case JoystickBase::xIdPropertyKey: + return object->is(); + case JoystickBase::yIdPropertyKey: + return object->is(); + case JoystickBase::joystickFlagsPropertyKey: + return object->is(); + case JoystickBase::handleSourceIdPropertyKey: + return object->is(); + case OpenUrlEventBase::targetValuePropertyKey: + return object->is(); + case WeightBase::valuesPropertyKey: + return object->is(); + case WeightBase::indicesPropertyKey: + return object->is(); + case TendonBase::boneIdPropertyKey: + return object->is(); + case CubicWeightBase::inValuesPropertyKey: + return object->is(); + case CubicWeightBase::inIndicesPropertyKey: + return object->is(); + case CubicWeightBase::outValuesPropertyKey: + return object->is(); + case CubicWeightBase::outIndicesPropertyKey: + return object->is(); + case TextModifierRangeBase::unitsValuePropertyKey: + return object->is(); + case TextModifierRangeBase::typeValuePropertyKey: + return object->is(); + case TextModifierRangeBase::modeValuePropertyKey: + return object->is(); + case TextModifierRangeBase::runIdPropertyKey: + return object->is(); + case TextStyleFeatureBase::tagPropertyKey: + return object->is(); + case TextStyleFeatureBase::featureValuePropertyKey: + return object->is(); + case TextVariationModifierBase::axisTagPropertyKey: + return object->is(); + case TextModifierGroupBase::modifierFlagsPropertyKey: + return object->is(); + case TextStyleBase::fontAssetIdPropertyKey: + return object->is(); + case TextStyleAxisBase::tagPropertyKey: + return object->is(); + case TextBase::alignValuePropertyKey: + return object->is(); + case TextBase::sizingValuePropertyKey: + return object->is(); + case TextBase::overflowValuePropertyKey: + return object->is(); + case TextBase::originValuePropertyKey: + return object->is(); + case TextValueRunBase::styleIdPropertyKey: + return object->is(); + case FileAssetBase::assetIdPropertyKey: + return object->is(); + case AudioEventBase::assetIdPropertyKey: + return object->is(); + case CustomPropertyNumberBase::propertyValuePropertyKey: + return object->is(); + case ConstraintBase::strengthPropertyKey: + return object->is(); + case DistanceConstraintBase::distancePropertyKey: + return object->is(); + case TransformComponentConstraintBase::copyFactorPropertyKey: + return object->is(); + case TransformComponentConstraintBase::minValuePropertyKey: + return object->is(); + case TransformComponentConstraintBase::maxValuePropertyKey: + return object->is(); + case TransformComponentConstraintYBase::copyFactorYPropertyKey: + return object->is(); + case TransformComponentConstraintYBase::minValueYPropertyKey: + return object->is(); + case TransformComponentConstraintYBase::maxValueYPropertyKey: + return object->is(); + case FollowPathConstraintBase::distancePropertyKey: + return object->is(); + case TransformConstraintBase::originXPropertyKey: + return object->is(); + case TransformConstraintBase::originYPropertyKey: + return object->is(); + case WorldTransformComponentBase::opacityPropertyKey: + return object->is(); + case TransformComponentBase::rotationPropertyKey: + return object->is(); + case TransformComponentBase::scaleXPropertyKey: + return object->is(); + case TransformComponentBase::scaleYPropertyKey: + return object->is(); + case NodeBase::xPropertyKey: + return object->is(); + case NodeBase::yPropertyKey: + return object->is(); + case NestedLinearAnimationBase::mixPropertyKey: + return object->is(); + case NestedSimpleAnimationBase::speedPropertyKey: + return object->is(); + case AdvanceableStateBase::speedPropertyKey: + return object->is(); + case BlendAnimationDirectBase::mixValuePropertyKey: + return object->is(); + case StateMachineNumberBase::valuePropertyKey: + return object->is(); + case CubicInterpolatorBase::x1PropertyKey: + return object->is(); + case CubicInterpolatorBase::y1PropertyKey: + return object->is(); + case CubicInterpolatorBase::x2PropertyKey: + return object->is(); + case CubicInterpolatorBase::y2PropertyKey: + return object->is(); + case TransitionNumberConditionBase::valuePropertyKey: + return object->is(); + case CubicInterpolatorComponentBase::x1PropertyKey: + return object->is(); + case CubicInterpolatorComponentBase::y1PropertyKey: + return object->is(); + case CubicInterpolatorComponentBase::x2PropertyKey: + return object->is(); + case CubicInterpolatorComponentBase::y2PropertyKey: + return object->is(); + case ListenerNumberChangeBase::valuePropertyKey: + return object->is(); + case KeyFrameDoubleBase::valuePropertyKey: + return object->is(); + case LinearAnimationBase::speedPropertyKey: + return object->is(); + case ElasticInterpolatorBase::amplitudePropertyKey: + return object->is(); + case ElasticInterpolatorBase::periodPropertyKey: + return object->is(); + case NestedNumberBase::nestedValuePropertyKey: + return object->is(); + case NestedRemapAnimationBase::timePropertyKey: + return object->is(); + case BlendAnimation1DBase::valuePropertyKey: + return object->is(); + case LinearGradientBase::startXPropertyKey: + return object->is(); + case LinearGradientBase::startYPropertyKey: + return object->is(); + case LinearGradientBase::endXPropertyKey: + return object->is(); + case LinearGradientBase::endYPropertyKey: + return object->is(); + case LinearGradientBase::opacityPropertyKey: + return object->is(); + case StrokeBase::thicknessPropertyKey: + return object->is(); + case GradientStopBase::positionPropertyKey: + return object->is(); + case TrimPathBase::startPropertyKey: + return object->is(); + case TrimPathBase::endPropertyKey: + return object->is(); + case TrimPathBase::offsetPropertyKey: + return object->is(); + case VertexBase::xPropertyKey: + return object->is(); + case VertexBase::yPropertyKey: + return object->is(); + case MeshVertexBase::uPropertyKey: + return object->is(); + case MeshVertexBase::vPropertyKey: + return object->is(); + case StraightVertexBase::radiusPropertyKey: + return object->is(); + case CubicAsymmetricVertexBase::rotationPropertyKey: + return object->is(); + case CubicAsymmetricVertexBase::inDistancePropertyKey: + return object->is(); + case CubicAsymmetricVertexBase::outDistancePropertyKey: + return object->is(); + case ParametricPathBase::widthPropertyKey: + return object->is(); + case ParametricPathBase::heightPropertyKey: + return object->is(); + case ParametricPathBase::originXPropertyKey: + return object->is(); + case ParametricPathBase::originYPropertyKey: + return object->is(); + case RectangleBase::cornerRadiusTLPropertyKey: + return object->is(); + case RectangleBase::cornerRadiusTRPropertyKey: + return object->is(); + case RectangleBase::cornerRadiusBLPropertyKey: + return object->is(); + case RectangleBase::cornerRadiusBRPropertyKey: + return object->is(); + case CubicMirroredVertexBase::rotationPropertyKey: + return object->is(); + case CubicMirroredVertexBase::distancePropertyKey: + return object->is(); + case PolygonBase::cornerRadiusPropertyKey: + return object->is(); + case StarBase::innerRadiusPropertyKey: + return object->is(); + case ImageBase::originXPropertyKey: + return object->is(); + case ImageBase::originYPropertyKey: + return object->is(); + case CubicDetachedVertexBase::inRotationPropertyKey: + return object->is(); + case CubicDetachedVertexBase::inDistancePropertyKey: + return object->is(); + case CubicDetachedVertexBase::outRotationPropertyKey: + return object->is(); + case CubicDetachedVertexBase::outDistancePropertyKey: + return object->is(); + case ArtboardBase::widthPropertyKey: + return object->is(); + case ArtboardBase::heightPropertyKey: + return object->is(); + case ArtboardBase::xPropertyKey: + return object->is(); + case ArtboardBase::yPropertyKey: + return object->is(); + case ArtboardBase::originXPropertyKey: + return object->is(); + case ArtboardBase::originYPropertyKey: + return object->is(); + case JoystickBase::xPropertyKey: + return object->is(); + case JoystickBase::yPropertyKey: + return object->is(); + case JoystickBase::posXPropertyKey: + return object->is(); + case JoystickBase::posYPropertyKey: + return object->is(); + case JoystickBase::originXPropertyKey: + return object->is(); + case JoystickBase::originYPropertyKey: + return object->is(); + case JoystickBase::widthPropertyKey: + return object->is(); + case JoystickBase::heightPropertyKey: + return object->is(); + case BoneBase::lengthPropertyKey: + return object->is(); + case RootBoneBase::xPropertyKey: + return object->is(); + case RootBoneBase::yPropertyKey: + return object->is(); + case SkinBase::xxPropertyKey: + return object->is(); + case SkinBase::yxPropertyKey: + return object->is(); + case SkinBase::xyPropertyKey: + return object->is(); + case SkinBase::yyPropertyKey: + return object->is(); + case SkinBase::txPropertyKey: + return object->is(); + case SkinBase::tyPropertyKey: + return object->is(); + case TendonBase::xxPropertyKey: + return object->is(); + case TendonBase::yxPropertyKey: + return object->is(); + case TendonBase::xyPropertyKey: + return object->is(); + case TendonBase::yyPropertyKey: + return object->is(); + case TendonBase::txPropertyKey: + return object->is(); + case TendonBase::tyPropertyKey: + return object->is(); + case TextModifierRangeBase::modifyFromPropertyKey: + return object->is(); + case TextModifierRangeBase::modifyToPropertyKey: + return object->is(); + case TextModifierRangeBase::strengthPropertyKey: + return object->is(); + case TextModifierRangeBase::falloffFromPropertyKey: + return object->is(); + case TextModifierRangeBase::falloffToPropertyKey: + return object->is(); + case TextModifierRangeBase::offsetPropertyKey: + return object->is(); + case TextVariationModifierBase::axisValuePropertyKey: + return object->is(); + case TextModifierGroupBase::originXPropertyKey: + return object->is(); + case TextModifierGroupBase::originYPropertyKey: + return object->is(); + case TextModifierGroupBase::opacityPropertyKey: + return object->is(); + case TextModifierGroupBase::xPropertyKey: + return object->is(); + case TextModifierGroupBase::yPropertyKey: + return object->is(); + case TextModifierGroupBase::rotationPropertyKey: + return object->is(); + case TextModifierGroupBase::scaleXPropertyKey: + return object->is(); + case TextModifierGroupBase::scaleYPropertyKey: + return object->is(); + case TextStyleBase::fontSizePropertyKey: + return object->is(); + case TextStyleBase::lineHeightPropertyKey: + return object->is(); + case TextStyleBase::letterSpacingPropertyKey: + return object->is(); + case TextStyleAxisBase::axisValuePropertyKey: + return object->is(); + case TextBase::widthPropertyKey: + return object->is(); + case TextBase::heightPropertyKey: + return object->is(); + case TextBase::originXPropertyKey: + return object->is(); + case TextBase::originYPropertyKey: + return object->is(); + case TextBase::paragraphSpacingPropertyKey: + return object->is(); + case DrawableAssetBase::heightPropertyKey: + return object->is(); + case DrawableAssetBase::widthPropertyKey: + return object->is(); + case ExportAudioBase::volumePropertyKey: + return object->is(); + case TransformComponentConstraintBase::offsetPropertyKey: + return object->is(); + case TransformComponentConstraintBase::doesCopyPropertyKey: + return object->is(); + case TransformComponentConstraintBase::minPropertyKey: + return object->is(); + case TransformComponentConstraintBase::maxPropertyKey: + return object->is(); + case TransformComponentConstraintYBase::doesCopyYPropertyKey: + return object->is(); + case TransformComponentConstraintYBase::minYPropertyKey: + return object->is(); + case TransformComponentConstraintYBase::maxYPropertyKey: + return object->is(); + case IKConstraintBase::invertDirectionPropertyKey: + return object->is(); + case FollowPathConstraintBase::orientPropertyKey: + return object->is(); + case FollowPathConstraintBase::offsetPropertyKey: + return object->is(); + case NestedSimpleAnimationBase::isPlayingPropertyKey: + return object->is(); + case KeyFrameBoolBase::valuePropertyKey: + return object->is(); + case ListenerAlignTargetBase::preserveOffsetPropertyKey: + return object->is(); + case NestedBoolBase::nestedValuePropertyKey: + return object->is(); + case LinearAnimationBase::enableWorkAreaPropertyKey: + return object->is(); + case LinearAnimationBase::quantizePropertyKey: + return object->is(); + case StateMachineBoolBase::valuePropertyKey: + return object->is(); + case ShapePaintBase::isVisiblePropertyKey: + return object->is(); + case StrokeBase::transformAffectsStrokePropertyKey: + return object->is(); + case PointsPathBase::isClosedPropertyKey: + return object->is(); + case RectangleBase::linkCornerRadiusPropertyKey: + return object->is(); + case ClippingShapeBase::isVisiblePropertyKey: + return object->is(); + case CustomPropertyBooleanBase::propertyValuePropertyKey: + return object->is(); + case ArtboardBase::clipPropertyKey: + return object->is(); + case TextModifierRangeBase::clampPropertyKey: + return object->is(); + case NestedTriggerBase::firePropertyKey: + return object->is(); + case EventBase::triggerPropertyKey: + return object->is(); + case KeyFrameColorBase::valuePropertyKey: + return object->is(); + case SolidColorBase::colorValuePropertyKey: + return object->is(); + case GradientStopBase::colorValuePropertyKey: + return object->is(); + } + return false; + } }; } // namespace rive diff --git a/src/animation/keyed_object.cpp b/src/animation/keyed_object.cpp index 3666199f..bb54f886 100644 --- a/src/animation/keyed_object.cpp +++ b/src/animation/keyed_object.cpp @@ -18,13 +18,19 @@ void KeyedObject::addKeyedProperty(std::unique_ptr property) StatusCode KeyedObject::onAddedDirty(CoreContext* context) { // Make sure we're keying a valid object. - if (context->resolve(objectId()) == nullptr) + Core* coreObject = context->resolve(objectId()); + if (coreObject == nullptr) { return StatusCode::MissingObject; } for (auto& property : m_keyedProperties) { + // Validate coreObject supports propertyKey + if (!CoreRegistry::objectSupportsProperty(coreObject, property->propertyKey())) + { + return StatusCode::InvalidObject; + } StatusCode code; if ((code = property->onAddedDirty(context)) != StatusCode::Ok) { From 78672988b26d793c93e3f7c31329e715b956c680 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Wed, 22 May 2024 21:40:09 +0000 Subject: [PATCH 052/138] fix for unexpected triggered events fixes #7226 This PR fixes reports of events when animations are playing backward. It considers both the timeline speed and the state machine state speed to determine direction. It also handles not reporting an event twice if it comes from a "ping pong" loop. It also adds a small performance improvement, skipping the binary search if possible. Diffs= 265c00985 fix for unexpected triggered events (#7227) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/animation/keyed_object.hpp | 2 +- include/rive/animation/keyed_property.hpp | 2 +- include/rive/animation/linear_animation.hpp | 5 ++- .../animation/linear_animation_instance.hpp | 1 + src/animation/keyed_object.cpp | 4 +- src/animation/keyed_property.cpp | 37 ++++++++++++++++--- src/animation/linear_animation.cpp | 22 +++++++---- src/animation/linear_animation_instance.cpp | 20 ++++++++-- 9 files changed, 71 insertions(+), 24 deletions(-) diff --git a/.rive_head b/.rive_head index dd5879ce..a329f6d8 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8a538c243fcc5b72159388a7e63669f1e6998dda +265c009852e86492deb69277ad18aa2c394c93e5 diff --git a/include/rive/animation/keyed_object.hpp b/include/rive/animation/keyed_object.hpp index e11306c7..860e11fc 100644 --- a/include/rive/animation/keyed_object.hpp +++ b/include/rive/animation/keyed_object.hpp @@ -19,7 +19,7 @@ class KeyedObject : public KeyedObjectBase void reportKeyedCallbacks(KeyedCallbackReporter* reporter, float secondsFrom, float secondsTo, - int secondsFromExactOffset) const; + bool isAtStartFrame) const; void apply(Artboard* coreContext, float time, float mix); StatusCode import(ImportStack& importStack) override; diff --git a/include/rive/animation/keyed_property.hpp b/include/rive/animation/keyed_property.hpp index c45f3bd1..1ef73ce5 100644 --- a/include/rive/animation/keyed_property.hpp +++ b/include/rive/animation/keyed_property.hpp @@ -20,7 +20,7 @@ class KeyedProperty : public KeyedPropertyBase uint32_t objectId, float secondsFrom, float secondsTo, - int secondsFromExactOffset) const; + bool isAtStartFrame) const; /// Apply interpolating key frames. void apply(Core* object, float time, float mix); diff --git a/include/rive/animation/linear_animation.hpp b/include/rive/animation/linear_animation.hpp index 2efcfeb7..f7aa60ea 100644 --- a/include/rive/animation/linear_animation.hpp +++ b/include/rive/animation/linear_animation.hpp @@ -35,6 +35,7 @@ class LinearAnimation : public LinearAnimationBase /// Returns the start time/ end time of the animation in seconds, considering speed float startTime() const; + float startTime(float multiplier) const; float endTime() const; /// Convert a global clock to local seconds (takes into consideration @@ -49,7 +50,9 @@ class LinearAnimation : public LinearAnimationBase void reportKeyedCallbacks(KeyedCallbackReporter* reporter, float secondsFrom, - float secondsTo) const; + float secondsTo, + float speedDirection, + bool fromPong) const; }; } // namespace rive diff --git a/include/rive/animation/linear_animation_instance.hpp b/include/rive/animation/linear_animation_instance.hpp index 4919bd7f..316b0c7c 100644 --- a/include/rive/animation/linear_animation_instance.hpp +++ b/include/rive/animation/linear_animation_instance.hpp @@ -101,6 +101,7 @@ class LinearAnimationInstance : public Scene private: const LinearAnimation* m_animation = nullptr; float m_time; + float m_speedDirection; float m_totalTime; float m_lastTotalTime; float m_spilledTime; diff --git a/src/animation/keyed_object.cpp b/src/animation/keyed_object.cpp index bb54f886..0bb8e63a 100644 --- a/src/animation/keyed_object.cpp +++ b/src/animation/keyed_object.cpp @@ -52,7 +52,7 @@ StatusCode KeyedObject::onAddedClean(CoreContext* context) void KeyedObject::reportKeyedCallbacks(KeyedCallbackReporter* reporter, float secondsFrom, float secondsTo, - int secondsFromExactOffset) const + bool isAtStartFrame) const { for (const std::unique_ptr& property : m_keyedProperties) { @@ -64,7 +64,7 @@ void KeyedObject::reportKeyedCallbacks(KeyedCallbackReporter* reporter, objectId(), secondsFrom, secondsTo, - secondsFromExactOffset); + isAtStartFrame); } } diff --git a/src/animation/keyed_property.cpp b/src/animation/keyed_property.cpp index 750e976d..7156fb89 100644 --- a/src/animation/keyed_property.cpp +++ b/src/animation/keyed_property.cpp @@ -18,13 +18,18 @@ void KeyedProperty::addKeyFrame(std::unique_ptr keyframe) int KeyedProperty::closestFrameIndex(float seconds, int exactOffset) const { - int idx = 0; int mid = 0; float closestSeconds = 0; int start = 0; auto numKeyFrames = static_cast(m_keyFrames.size()); int end = numKeyFrames - 1; + // If it's the last keyframe, we skip the binary search + if (seconds > m_keyFrames[end]->seconds()) + { + return end + 1; + } + while (start <= end) { mid = (start + end) >> 1; @@ -41,19 +46,39 @@ int KeyedProperty::closestFrameIndex(float seconds, int exactOffset) const { return mid + exactOffset; } - idx = start; } - return idx; + return start; } void KeyedProperty::reportKeyedCallbacks(KeyedCallbackReporter* reporter, uint32_t objectId, float secondsFrom, float secondsTo, - int secondsFromExactOffset) const + bool isAtStartFrame) const { - int idx = closestFrameIndex(secondsFrom, secondsFromExactOffset); - int idxTo = closestFrameIndex(secondsTo, 1); + if (secondsFrom == secondsTo) + { + return; + } + bool isForward = secondsFrom <= secondsTo; + int fromExactOffset = 0; + int toExactOffset = isForward ? 1 : 0; + if (isForward) + { + if (!isAtStartFrame) + { + fromExactOffset = 1; + } + } + else + { + if (isAtStartFrame) + { + fromExactOffset = 1; + } + } + int idx = closestFrameIndex(secondsFrom, fromExactOffset); + int idxTo = closestFrameIndex(secondsTo, toExactOffset); if (idxTo < idx) { diff --git a/src/animation/linear_animation.cpp b/src/animation/linear_animation.cpp index c2ade3b5..21d795d9 100644 --- a/src/animation/linear_animation.cpp +++ b/src/animation/linear_animation.cpp @@ -86,6 +86,10 @@ float LinearAnimation::endSeconds() const } float LinearAnimation::startTime() const { return (speed() >= 0) ? startSeconds() : endSeconds(); } +float LinearAnimation::startTime(float multiplier) const +{ + return ((speed() * multiplier) >= 0) ? startSeconds() : endSeconds(); +} float LinearAnimation::endTime() const { return (speed() >= 0) ? endSeconds() : startSeconds(); } float LinearAnimation::durationSeconds() const { return std::abs(endSeconds() - startSeconds()); } @@ -119,16 +123,18 @@ float LinearAnimation::globalToLocalSeconds(float seconds) const void LinearAnimation::reportKeyedCallbacks(KeyedCallbackReporter* reporter, float secondsFrom, - float secondsTo) const + float secondsTo, + float speedDirection, + bool fromPong) const { - int secondsFromExactOffset = - startTime() == secondsFrom && - (speed() >= 0 ? secondsFrom < secondsTo : secondsFrom < secondsTo) - ? 0 - : 1; + float startingTime = startTime(speedDirection); + bool isAtStartFrame = startingTime == secondsFrom; - for (const auto& object : m_KeyedObjects) + if (!isAtStartFrame || !fromPong) { - object->reportKeyedCallbacks(reporter, secondsFrom, secondsTo, secondsFromExactOffset); + for (const auto& object : m_KeyedObjects) + { + object->reportKeyedCallbacks(reporter, secondsFrom, secondsTo, isAtStartFrame); + } } } \ No newline at end of file diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp index ff7fe55a..f40f8afe 100644 --- a/src/animation/linear_animation_instance.cpp +++ b/src/animation/linear_animation_instance.cpp @@ -13,6 +13,7 @@ LinearAnimationInstance::LinearAnimationInstance(const LinearAnimation* animatio Scene(instance), m_animation((assert(animation != nullptr), animation)), m_time((speedMultiplier >= 0) ? animation->startTime() : animation->endTime()), + m_speedDirection((speedMultiplier >= 0) ? 1 : -1), m_totalTime(0.0f), m_lastTotalTime(0.0f), m_spilledTime(0.0f), @@ -23,6 +24,7 @@ LinearAnimationInstance::LinearAnimationInstance(LinearAnimationInstance const& Scene(lhs), m_animation(lhs.m_animation), m_time(lhs.m_time), + m_speedDirection(lhs.m_speedDirection), m_totalTime(lhs.m_totalTime), m_lastTotalTime(lhs.m_lastTotalTime), m_spilledTime(lhs.m_spilledTime), @@ -64,7 +66,7 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte m_time += deltaSeconds; if (reporter != nullptr) { - animation.reportKeyedCallbacks(reporter, lastTime, m_time); + animation.reportKeyedCallbacks(reporter, lastTime, m_time, m_speedDirection, false); } int fps = animation.fps(); @@ -107,7 +109,7 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte didLoop = true; if (reporter != nullptr) { - animation.reportKeyedCallbacks(reporter, 0.0f, m_time); + animation.reportKeyedCallbacks(reporter, 0.0f, m_time, m_speedDirection, false); } } else if (direction == -1 && frames <= start) @@ -119,11 +121,16 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte didLoop = true; if (reporter != nullptr) { - animation.reportKeyedCallbacks(reporter, end / (float)fps, m_time); + animation.reportKeyedCallbacks(reporter, + end / (float)fps, + m_time, + m_speedDirection, + false); } } break; case Loop::pingPong: + bool fromPong = true; while (true) { if (direction == 1 && frames >= end) @@ -153,8 +160,13 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte didLoop = true; if (reporter != nullptr) { - animation.reportKeyedCallbacks(reporter, lastTime, m_time); + animation.reportKeyedCallbacks(reporter, + lastTime, + m_time, + m_speedDirection, + fromPong); } + fromPong = !fromPong; } break; } From 526edf1896b9dd612726794664560629e5d0b02c Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Wed, 22 May 2024 23:17:39 +0000 Subject: [PATCH 053/138] Fix warnings about invalid toolsets Add our custom android_ndk/emsdk toolsets to "valid_tools" for the gmake2 action. These errors were confusing even for people familiar with our build system. Diffs= 973ff2276 Fix warnings about invalid toolsets (#7300) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index a329f6d8..1563e51d 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -265c009852e86492deb69277ad18aa2c394c93e5 +973ff2276f928634e964fafb2d74f11a1cb9d29c diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 973f748c..f6ff5103 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -295,6 +295,8 @@ if _OPTIONS['os'] == 'android' then return android_ndk_tools[tool] end + valid_cc_tools = premake.action._list['gmake2'].valid_tools['cc'] + valid_cc_tools[#valid_cc_tools + 1] = 'android_ndk' toolset('android_ndk') buildoptions({ @@ -444,6 +446,9 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then end system('emscripten') + + valid_cc_tools = premake.action._list['gmake2'].valid_tools['cc'] + valid_cc_tools[#valid_cc_tools + 1] = 'emsdk' toolset('emsdk') linkoptions({ '-sALLOW_MEMORY_GROWTH=1', '-sDYNAMIC_EXECUTION=0' }) @@ -461,7 +466,7 @@ if _OPTIONS['arch'] == 'wasm' or _OPTIONS['arch'] == 'js' then filter({ 'options:arch=wasm', 'options:no-wasm-simd' }) do linkoptions({ '-s MIN_SAFARI_VERSION=120000' }) - end + end filter({ 'options:arch=wasm', 'options:config=debug' }) do From eb046e6c5cd8fbcda87b15e5b8130ae3c57a2f89 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Thu, 23 May 2024 20:32:01 +0000 Subject: [PATCH 054/138] Fail early with bad blend modes. Diffs= 5ad13845d Fail early with bad blend modes. (#7302) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/drawable.hpp | 2 ++ include/rive/importers/import_stack.hpp | 17 ++++++++++--- src/drawable.cpp | 31 ++++++++++++++++++++++++ src/file.cpp | 8 +++--- test/assets/solar-system.riv | Bin 0 -> 1858 bytes test/file_test.cpp | 9 +++++++ 7 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 test/assets/solar-system.riv diff --git a/.rive_head b/.rive_head index 1563e51d..8e964350 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -973ff2276f928634e964fafb2d74f11a1cb9d29c +5ad13845d3ca1a130b61fb16e6c3627356e31f79 diff --git a/include/rive/drawable.hpp b/include/rive/drawable.hpp index 547d6b54..ca5e9966 100644 --- a/include/rive/drawable.hpp +++ b/include/rive/drawable.hpp @@ -46,6 +46,8 @@ class Drawable : public DrawableBase return (static_cast(drawableFlags()) & DrawableFlag::Opaque) == DrawableFlag::Opaque; } + + StatusCode onAddedDirty(CoreContext* context) override; }; } // namespace rive diff --git a/include/rive/importers/import_stack.hpp b/include/rive/importers/import_stack.hpp index c80986b4..ae03495f 100644 --- a/include/rive/importers/import_stack.hpp +++ b/include/rive/importers/import_stack.hpp @@ -72,18 +72,29 @@ class ImportStack StatusCode resolve() { + StatusCode returnCode = StatusCode::Ok; + + // Reverse iterate the last added import stack objects and resolve them. + // If any don't resolve, capture the return code and stop resolving. for (auto itr = m_LastAdded.rbegin(); itr != m_LastAdded.rend(); itr++) { StatusCode code = (*itr)->resolve(); - delete *itr; if (code != StatusCode::Ok) { - return code; + returnCode = code; + break; } } + + // Clean the import stack before returning the resolve code. + for (ImportStackObject* stackObject : m_LastAdded) + { + delete stackObject; + } m_Latests.clear(); m_LastAdded.clear(); - return StatusCode::Ok; + + return returnCode; } ~ImportStack() diff --git a/src/drawable.cpp b/src/drawable.cpp index 5f41d68f..2f01c79d 100644 --- a/src/drawable.cpp +++ b/src/drawable.cpp @@ -7,6 +7,37 @@ using namespace rive; +StatusCode Drawable::onAddedDirty(CoreContext* context) +{ + auto code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + auto blendMode = static_cast(blendModeValue()); + switch (blendMode) + { + case rive::BlendMode::srcOver: + case rive::BlendMode::screen: + case rive::BlendMode::overlay: + case rive::BlendMode::darken: + case rive::BlendMode::lighten: + case rive::BlendMode::colorDodge: + case rive::BlendMode::colorBurn: + case rive::BlendMode::hardLight: + case rive::BlendMode::softLight: + case rive::BlendMode::difference: + case rive::BlendMode::exclusion: + case rive::BlendMode::multiply: + case rive::BlendMode::hue: + case rive::BlendMode::saturation: + case rive::BlendMode::color: + case rive::BlendMode::luminosity: + return StatusCode::Ok; + } + return StatusCode::InvalidObject; +} + void Drawable::addClippingShape(ClippingShape* shape) { m_ClippingShapes.push_back(shape); } ClipResult Drawable::clip(Renderer* renderer) const diff --git a/src/file.cpp b/src/file.cpp index 183aa504..83edfc6c 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -174,13 +174,13 @@ std::unique_ptr File::import(Span bytes, auto file = std::unique_ptr(new File(factory, assetLoader)); auto readResult = file->read(reader, header); - if (readResult != ImportResult::success) + if (result) { - file.reset(nullptr); + *result = readResult; } - if (result) + if (readResult != ImportResult::success) { - *result = ImportResult::success; + file.reset(nullptr); } return file; } diff --git a/test/assets/solar-system.riv b/test/assets/solar-system.riv new file mode 100644 index 0000000000000000000000000000000000000000..acb0b98067d5aebb9f21c43ae6e095923c9dabee GIT binary patch literal 1858 zcma)6OKcle6ulGAv)#mYoWyNBA;dpCPTU}>T5c&#J!6mUBod!0^(Uc zBLotPw~&NJ0cBGmQ6OEQN=R%#6|Eh*3BoLpDn4S<1qcbLe55WAAcp(Kb;o9k#AbBw znLB6Bz3<#NHJM46;O{Fe^aI11qowkkoGUGu04i}afEYgj@OrEh;AIIqSo4|HqWfui zAy2>#__l{WtoVrA0BW?NGm$Hm7aKJU7}%~x{!D3ZsZ2WTTay(5Sk{tQUS7Jel6RlZ zl^2P@0l-TK=>vL6%wMn91sGuuOv!TD9g~ZB(gDLwW;Hj??2qlnke;aY#Dp5I#B5Ja zgnT-7GqSs*$nK6J`xE{`p`c(O(cdUYVZfdU(@!u|+dFeXE)xq9Rs?M7cCFtD_J0Ys zx*0ICom9O0w7gU-6Ppt@uZtYK^JO*lUH7DzuJnB?W^gc&t#B7bUA6e(bd(bvw`!^I zBhFg-(4*(X%;oTNLiWz^qP`knGs>Z$NJ=*UT1~GNiI^$;^sbQIy%Eq=W8vFkivBwN z>YO#2p>nb`(un}r*~4mgEj9V#FG8BUwIXH?zPVn_9UV3Y%R;Z1 zp6+sp8Ru_YHM^1A6mg&@{jYrXm!ccLg^oW)#~;I@F~9V|?{wqmu}{x6TM^W;7a=06kmk)l9y)y3+J&o8er~!dBmnvvBU(b!xpvp=v$%jG~OI z)>A>^>E8KjobJFx4DGUWO()-r@`3sfsQ)7VqhJ3){TKJc?mnGFSA)EOD{c8{Yabo`=zS>;LM*&7u9dN$3PA@JFxsm2csyVBBF!} zJ!hf0LCNL@S({oKJ&fpjID!Nlw1*Aa!#M4McHSAw&A)KIB(D}12;ciOvLPb4q+`)j_no7J0mx?%nVF;EMHc^3mp zK)HB`9(tG`qM3T=y(H?Not;&{!4gScmP^E}h1Lartboard("One") != nullptr); } +TEST_CASE("file with bad blend mode fails to load", "[file]") +{ + std::vector bytes = ReadFile("../../test/assets/solar-system.riv"); + + rive::ImportResult result; + auto file = rive::File::import(bytes, &gNoOpFactory, &result, nullptr); + CHECK(result == rive::ImportResult::malformed); +} + TEST_CASE("file with animation can be read", "[file]") { auto file = ReadRiveFile("../../test/assets/juice.riv"); From 3f9e940167cd5fd9173c34f2a79fdaad0df19f11 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Fri, 24 May 2024 21:30:48 +0000 Subject: [PATCH 055/138] Use unique_ptr in import stack. Diffs= 01d20e026 Use unique_ptr in import stack. (#7307) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/importers/import_stack.hpp | 59 ++++++++++--------------- src/file.cpp | 41 ++++++++++------- 3 files changed, 48 insertions(+), 54 deletions(-) diff --git a/.rive_head b/.rive_head index 8e964350..ee9abc18 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -5ad13845d3ca1a130b61fb16e6c3627356e31f79 +01d20e02661309cd2f8a0702f9de102107c1a0f1 diff --git a/include/rive/importers/import_stack.hpp b/include/rive/importers/import_stack.hpp index ae03495f..5e0436f8 100644 --- a/include/rive/importers/import_stack.hpp +++ b/include/rive/importers/import_stack.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace rive { @@ -18,41 +19,36 @@ class ImportStackObject class ImportStack { -private: - std::unordered_map m_Latests; - std::vector m_LastAdded; - public: template T* latest(uint16_t coreType) { - auto itr = m_Latests.find(coreType); - if (itr == m_Latests.end()) + auto itr = m_latests.find(coreType); + if (itr == m_latests.end()) { return nullptr; } - return static_cast(itr->second); + return static_cast(itr->second.get()); } - StatusCode makeLatest(uint16_t coreType, ImportStackObject* object) + StatusCode makeLatest(uint16_t coreType, std::unique_ptr object) { // Clean up the old object in the stack. - auto itr = m_Latests.find(coreType); - if (itr != m_Latests.end()) + auto itr = m_latests.find(coreType); + if (itr != m_latests.end()) { - auto stackObject = itr->second; + auto stackObject = itr->second.get(); // Remove it from latests. - auto lastAddedItr = std::find(m_LastAdded.begin(), m_LastAdded.end(), stackObject); - if (lastAddedItr != m_LastAdded.end()) + auto lastAddedItr = std::find(m_lastAdded.begin(), m_lastAdded.end(), stackObject); + if (lastAddedItr != m_lastAdded.end()) { - m_LastAdded.erase(lastAddedItr); + m_lastAdded.erase(lastAddedItr); } StatusCode code = stackObject->resolve(); - delete stackObject; if (code != StatusCode::Ok) { - m_Latests.erase(coreType); + m_latests.erase(coreType); return code; } } @@ -60,12 +56,12 @@ class ImportStack // Set the new one. if (object == nullptr) { - m_Latests.erase(coreType); + m_latests.erase(coreType); } else { - m_Latests[coreType] = object; - m_LastAdded.push_back(object); + m_lastAdded.push_back(object.get()); + m_latests[coreType] = std::move(object); } return StatusCode::Ok; } @@ -76,7 +72,7 @@ class ImportStack // Reverse iterate the last added import stack objects and resolve them. // If any don't resolve, capture the return code and stop resolving. - for (auto itr = m_LastAdded.rbegin(); itr != m_LastAdded.rend(); itr++) + for (auto itr = m_lastAdded.rbegin(); itr != m_lastAdded.rend(); itr++) { StatusCode code = (*itr)->resolve(); if (code != StatusCode::Ok) @@ -86,28 +82,15 @@ class ImportStack } } - // Clean the import stack before returning the resolve code. - for (ImportStackObject* stackObject : m_LastAdded) - { - delete stackObject; - } - m_Latests.clear(); - m_LastAdded.clear(); + m_latests.clear(); + m_lastAdded.clear(); return returnCode; } - ~ImportStack() - { - for (auto& pair : m_Latests) - { - delete pair.second; - } - } - bool readNullObject() { - for (auto itr = m_LastAdded.rbegin(); itr != m_LastAdded.rend(); itr++) + for (auto itr = m_lastAdded.rbegin(); itr != m_lastAdded.rend(); itr++) { if ((*itr)->readNullObject()) { @@ -116,6 +99,10 @@ class ImportStack } return false; } + +private: + std::unordered_map> m_latests; + std::vector m_lastAdded; }; } // namespace rive #endif diff --git a/src/file.cpp b/src/file.cpp index 83edfc6c..1fc3fbb4 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -171,7 +171,7 @@ std::unique_ptr File::import(Span bytes, } return nullptr; } - auto file = std::unique_ptr(new File(factory, assetLoader)); + auto file = rivestd::make_unique(factory, assetLoader); auto readResult = file->read(reader, header); if (result) @@ -226,22 +226,23 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) delete object; continue; } - ImportStackObject* stackObject = nullptr; + std::unique_ptr stackObject = nullptr; auto stackType = object->coreType(); switch (stackType) { case Backboard::typeKey: - stackObject = new BackboardImporter(object->as()); + stackObject = rivestd::make_unique(object->as()); break; case Artboard::typeKey: - stackObject = new ArtboardImporter(object->as()); + stackObject = rivestd::make_unique(object->as()); break; case LinearAnimation::typeKey: - stackObject = new LinearAnimationImporter(object->as()); + stackObject = + rivestd::make_unique(object->as()); break; case KeyedObject::typeKey: - stackObject = new KeyedObjectImporter(object->as()); + stackObject = rivestd::make_unique(object->as()); break; case KeyedProperty::typeKey: { @@ -252,11 +253,13 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) return ImportResult::malformed; } stackObject = - new KeyedPropertyImporter(importer->animation(), object->as()); + rivestd::make_unique(importer->animation(), + object->as()); break; } case StateMachine::typeKey: - stackObject = new StateMachineImporter(object->as()); + stackObject = + rivestd::make_unique(object->as()); break; case StateMachineLayer::typeKey: { @@ -266,8 +269,9 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) return ImportResult::malformed; } - stackObject = new StateMachineLayerImporter(object->as(), - artboardImporter->artboard()); + stackObject = + rivestd::make_unique(object->as(), + artboardImporter->artboard()); break; } @@ -277,33 +281,36 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) case AnimationState::typeKey: case BlendState1D::typeKey: case BlendStateDirect::typeKey: - stackObject = new LayerStateImporter(object->as()); + stackObject = rivestd::make_unique(object->as()); stackType = LayerState::typeKey; break; case StateTransition::typeKey: case BlendStateTransition::typeKey: - stackObject = new StateTransitionImporter(object->as()); + stackObject = + rivestd::make_unique(object->as()); stackType = StateTransition::typeKey; break; case StateMachineListener::typeKey: - stackObject = new StateMachineListenerImporter(object->as()); + stackObject = rivestd::make_unique( + object->as()); break; case ImageAsset::typeKey: case FontAsset::typeKey: case AudioAsset::typeKey: - stackObject = - new FileAssetImporter(object->as(), m_assetLoader, m_factory); + stackObject = rivestd::make_unique(object->as(), + m_assetLoader, + m_factory); stackType = FileAsset::typeKey; break; } - if (importStack.makeLatest(stackType, stackObject) != StatusCode::Ok) + if (importStack.makeLatest(stackType, std::move(stackObject)) != StatusCode::Ok) { // Some previous stack item didn't resolve. return ImportResult::malformed; } if (object->is() && importStack.makeLatest(StateMachineLayerComponent::typeKey, - new StateMachineLayerComponentImporter( + rivestd::make_unique( object->as())) != StatusCode::Ok) { return ImportResult::malformed; From 41a69324a0cad36ea35ca5cbcc6510a28fe815e1 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Fri, 31 May 2024 23:31:05 +0000 Subject: [PATCH 056/138] Fix libjpg on Mac Sonoma Diffs= dde676085 Fix libjpg on Mac Sonoma (#7329) e0a786c90 Runtime API for Nested Inputs (#7316) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> Co-authored-by: Gordon Hayes Co-authored-by: Philip Chung --- .rive_head | 2 +- dependencies/jconfig.h | 4 +- include/rive/animation/nested_input.hpp | 12 +- .../rive/animation/nested_state_machine.hpp | 3 + include/rive/artboard.hpp | 13 ++ include/rive/nested_artboard.hpp | 7 + src/animation/nested_state_machine.cpp | 22 ++- src/artboard.cpp | 82 +++++++++++ src/nested_artboard.cpp | 50 +++++++ test/assets/runtime_nested_inputs.riv | Bin 0 -> 947 bytes test/nested_input_test.cpp | 139 ++++++++++++++++++ 11 files changed, 330 insertions(+), 4 deletions(-) create mode 100644 test/assets/runtime_nested_inputs.riv create mode 100644 test/nested_input_test.cpp diff --git a/.rive_head b/.rive_head index ee9abc18..30ea12c2 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -01d20e02661309cd2f8a0702f9de102107c1a0f1 +dde676085908d492af545660cbbb19ee0d10d91d diff --git a/dependencies/jconfig.h b/dependencies/jconfig.h index b0daaa1a..84c05fc1 100644 --- a/dependencies/jconfig.h +++ b/dependencies/jconfig.h @@ -1,3 +1,5 @@ +#include // Required on Mac -- libjpg expects FILE to be already defined. + #define HAVE_PROTOTYPES #define HAVE_UNSIGNED_CHAR #define HAVE_UNSIGNED_SHORT @@ -8,4 +10,4 @@ #undef NEED_SYS_TYPES_H #undef NEED_FAR_POINTERS #undef NEED_SHORT_EXTERNAL_NAMES -#undef INCOMPLETE_TYPES_BROKEN \ No newline at end of file +#undef INCOMPLETE_TYPES_BROKEN diff --git a/include/rive/animation/nested_input.hpp b/include/rive/animation/nested_input.hpp index 0db46dfe..fe75467c 100644 --- a/include/rive/animation/nested_input.hpp +++ b/include/rive/animation/nested_input.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_NESTED_INPUT_HPP_ #define _RIVE_NESTED_INPUT_HPP_ #include "rive/animation/nested_state_machine.hpp" +#include "rive/animation/state_machine_input_instance.hpp" #include "rive/generated/animation/nested_input_base.hpp" #include namespace rive @@ -21,7 +22,6 @@ class NestedInput : public NestedInputBase virtual void applyValue() {} -protected: SMIInput* input() const { auto parent = this->parent(); @@ -34,6 +34,16 @@ class NestedInput : public NestedInputBase } return nullptr; } + + const std::string name() const + { + auto smi = input(); + if (smi != nullptr) + { + return smi->name(); + } + return std::string(); + } }; } // namespace rive diff --git a/include/rive/animation/nested_state_machine.hpp b/include/rive/animation/nested_state_machine.hpp index 489d631c..c76729aa 100644 --- a/include/rive/animation/nested_state_machine.hpp +++ b/include/rive/animation/nested_state_machine.hpp @@ -30,6 +30,9 @@ class NestedStateMachine : public NestedStateMachineBase HitResult pointerExit(Vec2D position); void addNestedInput(NestedInput* input); + size_t inputCount() { return m_nestedInputs.size(); } + NestedInput* input(size_t index); + NestedInput* input(std::string name); }; } // namespace rive diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 69a339de..b8fdea35 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -32,6 +32,10 @@ class StateMachineInstance; class Joystick; class TextValueRun; class Event; +class SMIBool; +class SMIInput; +class SMINumber; +class SMITrigger; class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer { @@ -120,6 +124,8 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta const std::vector& objects() const { return m_Objects; } const std::vector nestedArtboards() const { return m_NestedArtboards; } + NestedArtboard* nestedArtboard(const std::string& name) const; + NestedArtboard* nestedArtboardAtPath(const std::string& path) const; AABB bounds() const; @@ -295,6 +301,13 @@ class ArtboardInstance : public Artboard // 3. first animation instance // 4. nullptr std::unique_ptr defaultScene(); + + SMIInput* input(const std::string& name, const std::string& path); + template + InstType* getNamedInput(const std::string& name, const std::string& path); + SMIBool* getBool(const std::string& name, const std::string& path); + SMINumber* getNumber(const std::string& name, const std::string& path); + SMITrigger* getTrigger(const std::string& name, const std::string& path); }; } // namespace rive diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index e075c863..14bd7c13 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp @@ -10,6 +10,9 @@ namespace rive { class ArtboardInstance; class NestedAnimation; +class NestedInput; +class NestedStateMachine; +class StateMachineInstance; class NestedArtboard : public NestedArtboardBase { @@ -37,6 +40,10 @@ class NestedArtboard : public NestedArtboardBase bool hasNestedStateMachines() const; Span nestedAnimations(); + NestedArtboard* nestedArtboard(std::string name) const; + NestedStateMachine* stateMachine(std::string name) const; + NestedInput* input(std::string name) const; + NestedInput* input(std::string name, std::string stateMachineName) const; /// Convert a world space (relative to the artboard that this /// NestedArtboard is a child of) to the local space of the Artboard diff --git a/src/animation/nested_state_machine.cpp b/src/animation/nested_state_machine.cpp index f04477f2..f9734299 100644 --- a/src/animation/nested_state_machine.cpp +++ b/src/animation/nested_state_machine.cpp @@ -32,7 +32,6 @@ void NestedStateMachine::initializeAnimation(ArtboardInstance* artboard) nestedInput->applyValue(); } } - m_nestedInputs.clear(); } StateMachineInstance* NestedStateMachine::stateMachineInstance() @@ -76,4 +75,25 @@ HitResult NestedStateMachine::pointerExit(Vec2D position) return HitResult::none; } +NestedInput* NestedStateMachine::input(size_t index) +{ + if (index < m_nestedInputs.size()) + { + return m_nestedInputs[index]; + } + return nullptr; +} + +NestedInput* NestedStateMachine::input(std::string name) +{ + for (auto input : m_nestedInputs) + { + if (input->name() == name) + { + return input; + } + } + return nullptr; +} + void NestedStateMachine::addNestedInput(NestedInput* input) { m_nestedInputs.push_back(input); } \ No newline at end of file diff --git a/src/artboard.cpp b/src/artboard.cpp index 0ddaf7b8..4458ecf5 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -15,6 +15,10 @@ #include "rive/importers/backboard_importer.hpp" #include "rive/nested_artboard.hpp" #include "rive/joystick.hpp" +#include "rive/animation/nested_bool.hpp" +#include "rive/animation/nested_number.hpp" +#include "rive/animation/nested_trigger.hpp" +#include "rive/animation/state_machine_input_instance.hpp" #include "rive/animation/state_machine_instance.hpp" #include "rive/shapes/shape.hpp" #include "rive/text/text_value_run.hpp" @@ -758,6 +762,47 @@ int Artboard::defaultStateMachineIndex() const return index; } +NestedArtboard* Artboard::nestedArtboard(const std::string& name) const +{ + for (auto nested : m_NestedArtboards) + { + if (nested->name() == name) + { + return nested; + } + } + return nullptr; +} + +NestedArtboard* Artboard::nestedArtboardAtPath(const std::string& path) const +{ + // name parameter can be a name or a path to recursively find a nested artboard + std::string delimiter = "/"; + size_t firstDelim = path.find(delimiter); + std::string artboardName = firstDelim == std::string::npos ? path : path.substr(0, firstDelim); + std::string restOfPath = + firstDelim == std::string::npos ? "" : path.substr(firstDelim + 1, path.size()); + + // Find the nested artboard at this level + if (!artboardName.empty()) + { + auto nested = nestedArtboard(artboardName); + if (nested != nullptr) + { + if (restOfPath.empty()) + { + return nested; + } + else + { + auto artboard = nested->artboard(); + return artboard->nestedArtboardAtPath(restOfPath); + } + } + } + return nullptr; +} + // std::unique_ptr Artboard::instance() const // { // std::unique_ptr artboardClone(new ArtboardInstance); @@ -896,6 +941,43 @@ std::unique_ptr ArtboardInstance::defaultScene() return scene; } +SMIInput* ArtboardInstance::input(const std::string& name, const std::string& path) +{ + return getNamedInput(name, path); +} + +template +InstType* ArtboardInstance::getNamedInput(const std::string& name, const std::string& path) +{ + if (!path.empty()) + { + auto nestedArtboard = nestedArtboardAtPath(path); + if (nestedArtboard != nullptr) + { + auto input = nestedArtboard->input(name); + if (input != nullptr && input->input() != nullptr) + { + return static_cast(input->input()); + } + } + } + return nullptr; +} + +SMIBool* ArtboardInstance::getBool(const std::string& name, const std::string& path) +{ + return getNamedInput(name, path); +} + +SMINumber* ArtboardInstance::getNumber(const std::string& name, const std::string& path) +{ + return getNamedInput(name, path); +} +SMITrigger* ArtboardInstance::getTrigger(const std::string& name, const std::string& path) +{ + return getNamedInput(name, path); +} + #ifdef EXTERNAL_RIVE_AUDIO_ENGINE rcp Artboard::audioEngine() const { return m_audioEngine; } void Artboard::audioEngine(rcp audioEngine) diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 901661c0..1c580409 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -164,6 +164,56 @@ bool NestedArtboard::hasNestedStateMachines() const Span NestedArtboard::nestedAnimations() { return m_NestedAnimations; } +NestedArtboard* NestedArtboard::nestedArtboard(std::string name) const +{ + if (m_Instance != nullptr) + { + return m_Instance->nestedArtboard(name); + } + return nullptr; +} + +NestedStateMachine* NestedArtboard::stateMachine(std::string name) const +{ + for (auto animation : m_NestedAnimations) + { + if (animation->is() && animation->name() == name) + { + return animation->as(); + } + } + return nullptr; +} + +NestedInput* NestedArtboard::input(std::string name) const { return input(name, ""); } + +NestedInput* NestedArtboard::input(std::string name, std::string stateMachineName) const +{ + if (!stateMachineName.empty()) + { + auto nestedSM = stateMachine(stateMachineName); + if (nestedSM != nullptr) + { + return nestedSM->input(name); + } + } + else + { + for (auto animation : m_NestedAnimations) + { + if (animation->is()) + { + auto input = animation->as()->input(name); + if (input != nullptr) + { + return input; + } + } + } + } + return nullptr; +} + bool NestedArtboard::worldToLocal(Vec2D world, Vec2D* local) { assert(local != nullptr); diff --git a/test/assets/runtime_nested_inputs.riv b/test/assets/runtime_nested_inputs.riv new file mode 100644 index 0000000000000000000000000000000000000000..04c2395c9713e1bc4dfcd3501950506d9c69e236 GIT binary patch literal 947 zcmZXSJ8u&~6ot>-hwYe`iHs3Y#En~|4T{1;5PO#hM)@kX!yiqPR@_4*NCWyq zCv-%ogxTjR$T`0mM(u`7wmYGGlLwkXL6xDMJK@8xoO3}WcVh9hn+WOR0?=<uhdX`NH60XXCq_m8RH~LMr`W-zIfI&lT9`n+dA2kUbvn+VW~huDO}T218P~fLu3DYv ts^xjEI(j;7W1utv3eI0WB`Z0v>v0^tdoK + +TEST_CASE("validate nested boolean get/set", "[nestedInput]") +{ + auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv"); + + auto artboard = file->artboard("MainArtboard")->instance(); + REQUIRE(artboard != nullptr); + REQUIRE(artboard->stateMachineCount() == 1); + + // Test getting/setting boolean SMIInput via nested artboard path + auto boolInput = artboard->getBool("CircleOuterState", "CircleOuter"); + auto smiInput = artboard->input("CircleOuterState", "CircleOuter"); + auto smiBoolInput = static_cast(smiInput); + auto nestedArtboard = artboard->nestedArtboard("CircleOuter"); + auto nestedInput = nestedArtboard->input("CircleOuterState")->as(); + REQUIRE(boolInput->value() == false); + REQUIRE(smiBoolInput->value() == false); + REQUIRE(nestedInput->nestedValue() == false); + + boolInput->value(true); + REQUIRE(boolInput->value() == true); + REQUIRE(smiBoolInput->value() == true); + REQUIRE(nestedInput->nestedValue() == true); + + smiBoolInput->value(false); + REQUIRE(boolInput->value() == false); + REQUIRE(smiBoolInput->value() == false); + REQUIRE(nestedInput->nestedValue() == false); + + nestedInput->nestedValue(true); + REQUIRE(boolInput->value() == true); + REQUIRE(smiBoolInput->value() == true); + REQUIRE(nestedInput->nestedValue() == true); +} + +TEST_CASE("validate nested number get/set", "[nestedInput]") +{ + auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv"); + + auto artboard = file->artboard("MainArtboard")->instance(); + REQUIRE(artboard != nullptr); + REQUIRE(artboard->stateMachineCount() == 1); + + // Test getting/setting number SMIInput via nested artboard path + auto numInput = artboard->getNumber("CircleOuterNumber", "CircleOuter"); + auto smiInput = artboard->input("CircleOuterNumber", "CircleOuter"); + auto smiNumInput = static_cast(smiInput); + auto nestedArtboard = artboard->nestedArtboardAtPath("CircleOuter"); + auto nestedInput = nestedArtboard->input("CircleOuterNumber")->as(); + REQUIRE(numInput->value() == 0); + REQUIRE(smiNumInput->value() == 0); + REQUIRE(nestedInput->nestedValue() == 0); + + numInput->value(10); + REQUIRE(numInput->value() == 10); + REQUIRE(smiNumInput->value() == 10); + REQUIRE(nestedInput->nestedValue() == 10); + + smiNumInput->value(5); + REQUIRE(numInput->value() == 5); + REQUIRE(smiNumInput->value() == 5); + REQUIRE(nestedInput->nestedValue() == 5); + + nestedInput->nestedValue(99); + REQUIRE(numInput->value() == 99); + REQUIRE(smiNumInput->value() == 99); + REQUIRE(nestedInput->nestedValue() == 99); +} + +TEST_CASE("validate nested trigger fire", "[nestedInput]") +{ + auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv"); + + auto artboard = file->artboard("MainArtboard")->instance(); + REQUIRE(artboard != nullptr); + REQUIRE(artboard->stateMachineCount() == 1); + + // Test getting/setting number SMIInput via nested artboard path + auto tInput = artboard->getTrigger("CircleOuterTrigger", "CircleOuter"); + auto smiInput = artboard->input("CircleOuterTrigger", "CircleOuter"); + auto smiTInput = static_cast(smiInput); + auto nestedArtboard = artboard->nestedArtboardAtPath("CircleOuter"); + auto nestedInput = nestedArtboard->input("CircleOuterTrigger")->as(); + auto nestedSMI = static_cast(nestedInput->input()); + REQUIRE(tInput->didFire() == false); + REQUIRE(smiTInput->didFire() == false); + REQUIRE(nestedSMI->didFire() == false); + + tInput->fire(); + REQUIRE(tInput->didFire() == true); + REQUIRE(smiTInput->didFire() == true); + REQUIRE(nestedSMI->didFire() == true); +} + +TEST_CASE("validate nested boolean get/set multiple nested artboards deep", "[nestedInput]") +{ + auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv"); + + auto artboard = file->artboard("MainArtboard")->instance(); + REQUIRE(artboard != nullptr); + REQUIRE(artboard->stateMachineCount() == 1); + + // Test getting/setting boolean SMIInput via nested artboard path + auto boolInput = artboard->getBool("CircleInnerState", "CircleOuter/CircleInner"); + auto smiInput = artboard->input("CircleInnerState", "CircleOuter/CircleInner"); + auto smiBoolInput = static_cast(smiInput); + auto nestedArtboard = artboard->nestedArtboardAtPath("CircleOuter/CircleInner"); + auto nestedInput = nestedArtboard->input("CircleInnerState")->as(); + REQUIRE(boolInput->value() == false); + REQUIRE(smiBoolInput->value() == false); + REQUIRE(nestedInput->nestedValue() == false); + + boolInput->value(true); + REQUIRE(boolInput->value() == true); + REQUIRE(smiBoolInput->value() == true); + REQUIRE(nestedInput->nestedValue() == true); + + smiBoolInput->value(false); + REQUIRE(boolInput->value() == false); + REQUIRE(smiBoolInput->value() == false); + REQUIRE(nestedInput->nestedValue() == false); + + nestedInput->nestedValue(true); + REQUIRE(boolInput->value() == true); + REQUIRE(smiBoolInput->value() == true); + REQUIRE(nestedInput->nestedValue() == true); +} \ No newline at end of file From dd5cc310886c2a615608aab843d929677ecb81fb Mon Sep 17 00:00:00 2001 From: bodymovin Date: Thu, 6 Jun 2024 23:12:40 +0000 Subject: [PATCH 057/138] fix bounds calculation ahead of time this PR handles marking a shape bounds as dirty after it has updated. This is needed because pointer events can trigger before a new draw update, which would consume the change flag before the shape has properly updated. Diffs= 085f5bd2d fix bounds calculation ahead of time (#7380) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/shapes/shape.hpp | 5 +++++ src/shapes/path_composer.cpp | 1 + src/shapes/shape.cpp | 1 - 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 30ea12c2..6e06eb9b 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -dde676085908d492af545660cbbb19ee0d10d91d +085f5bd2dce2d25561b00eebc5f7118a2c8769eb diff --git a/include/rive/shapes/shape.hpp b/include/rive/shapes/shape.hpp index 830e8779..587d4aa3 100644 --- a/include/rive/shapes/shape.hpp +++ b/include/rive/shapes/shape.hpp @@ -60,6 +60,11 @@ class Shape : public ShapeBase, public ShapePaintContainer } return m_WorldBounds; } + void markBoundsDirty() + { + drawableFlags(drawableFlags() & + ~static_cast(DrawableFlag::WorldBoundsClean)); + } AABB computeWorldBounds(const Mat2D* xform = nullptr) const; AABB computeLocalBounds() const; diff --git a/src/shapes/path_composer.cpp b/src/shapes/path_composer.cpp index adaef9cf..e0bf032c 100644 --- a/src/shapes/path_composer.cpp +++ b/src/shapes/path_composer.cpp @@ -87,6 +87,7 @@ void PathComposer::update(ComponentDirt value) } } } + m_Shape->markBoundsDirty(); } } diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index 157e378f..e37b4749 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -70,7 +70,6 @@ bool Shape::collapse(bool value) void Shape::pathChanged() { - drawableFlags(drawableFlags() & ~static_cast(DrawableFlag::WorldBoundsClean)); m_PathComposer.addDirt(ComponentDirt::Path, true); for (auto constraint : constraints()) { From fa6e59865cd1de99a3dfe06b5681f8aae266317e Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Fri, 7 Jun 2024 00:44:49 +0000 Subject: [PATCH 058/138] Get rid of MetricsPath. This lets us trim a raw path directly which means all the trim path logic from the editor can now be pushed down to the C++ runtime, even for the case where the rendering is still happening via Skia/Impeller, all our path operations can be done in C++ (without using RenderPath/MetricsPath/RenderMetricsPath/OnlyMetricsPath/etc). Basically, I needed to do this now to not have as many edge cases in the editor for the difference between using our runtime to render with PLS vs Flutter. It also quite greatly simplifies the code! More lines removed than added! Some tests will fail as I think we're using the MetricsPath in some other parts of the code, but that can be refactored following the patterns used here... It also means that most of our runtime now speaks RawPath which means we can optimize/reserve memory ahead of time in a lot of cases (not doing that yet). Diffs= 8486c3445 Get rid of MetricsPath. (#7371) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/artboard.hpp | 2 + .../constraints/follow_path_constraint.hpp | 4 +- include/rive/shapes/metrics_path.hpp | 79 ---------- include/rive/shapes/paint/fill.hpp | 5 +- include/rive/shapes/paint/shape_paint.hpp | 16 +- include/rive/shapes/paint/stroke.hpp | 5 +- include/rive/shapes/paint/stroke_effect.hpp | 4 +- include/rive/shapes/paint/trim_path.hpp | 30 +++- include/rive/shapes/path.hpp | 8 +- include/rive/shapes/path_composer.hpp | 24 ++- include/rive/shapes/shape_paint_container.hpp | 2 - src/artboard.cpp | 7 +- src/constraints/follow_path_constraint.cpp | 4 +- src/shapes/metrics_path.cpp | 131 ---------------- src/shapes/paint/fill.cpp | 2 +- src/shapes/paint/stroke.cpp | 7 +- src/shapes/paint/trim_path.cpp | 141 +++++++++++------- src/shapes/path.cpp | 54 +++---- src/shapes/path_composer.cpp | 51 ++++--- src/shapes/shape.cpp | 26 ++-- src/shapes/shape_paint_container.cpp | 48 ------ src/text/text_style.cpp | 2 +- tess/test/triangulation_test.cpp | 2 +- test/contour_measure_test.cpp | 22 +++ test/metrics_path_test.cpp | 54 ------- test/path_test.cpp | 129 ++++++++-------- 27 files changed, 322 insertions(+), 539 deletions(-) delete mode 100644 include/rive/shapes/metrics_path.hpp delete mode 100644 src/shapes/metrics_path.cpp delete mode 100644 test/metrics_path_test.cpp diff --git a/.rive_head b/.rive_head index 6e06eb9b..8bafa524 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -085f5bd2dce2d25561b00eebc5f7118a2c8769eb +8486c344528d5f7f84de1984510064a7d0788e73 diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index b8fdea35..d93d91de 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -12,6 +12,7 @@ #include "rive/text/text_value_run.hpp" #include "rive/event.hpp" #include "rive/audio/audio_engine.hpp" +#include "rive/math/raw_path.hpp" #include #include @@ -56,6 +57,7 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta bool m_HasChangedDrawOrderInLastUpdate = false; unsigned int m_DirtDepth = 0; + RawPath m_backgroundRawPath; rcp m_BackgroundPath; rcp m_ClipPath; Factory* m_Factory = nullptr; diff --git a/include/rive/constraints/follow_path_constraint.hpp b/include/rive/constraints/follow_path_constraint.hpp index 604e5782..a59b0f67 100644 --- a/include/rive/constraints/follow_path_constraint.hpp +++ b/include/rive/constraints/follow_path_constraint.hpp @@ -2,13 +2,11 @@ #define _RIVE_FOLLOW_PATH_CONSTRAINT_HPP_ #include "rive/generated/constraints/follow_path_constraint_base.hpp" #include "rive/math/transform_components.hpp" -#include "rive/shapes/metrics_path.hpp" -#include +#include "rive/math/contour_measure.hpp" namespace rive { class FollowPathConstraint : public FollowPathConstraintBase { - public: void distanceChanged() override; void orientChanged() override; diff --git a/include/rive/shapes/metrics_path.hpp b/include/rive/shapes/metrics_path.hpp deleted file mode 100644 index 7311b9cd..00000000 --- a/include/rive/shapes/metrics_path.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _RIVE_METRICS_PATH_HPP_ -#define _RIVE_METRICS_PATH_HPP_ - -#include "rive/command_path.hpp" -#include "rive/math/contour_measure.hpp" -#include "rive/math/vec2d.hpp" -#include -#include - -namespace rive -{ - -class MetricsPath : public CommandPath -{ -private: - RawPath m_RawPath; // temporary, until we build m_Contour - rcp m_Contour; - std::vector m_Paths; - Mat2D m_ComputedLengthTransform; - float m_ComputedLength = 0; - -public: - const std::vector& paths() const { return m_Paths; } - rcp contourMeasure() const { return m_Contour; } - - void addPath(CommandPath* path, const Mat2D& transform) override; - void rewind() override; - void moveTo(float x, float y) override; - void lineTo(float x, float y) override; - void cubicTo(float ox, float oy, float ix, float iy, float x, float y) override; - void close() override; - - float length() const { return m_ComputedLength; } - - /// Add commands to the result RenderPath that will draw the segment - /// from startLength to endLength of this MetricsPath. Requires - /// computeLength be called prior to trimming. - void trim(float startLength, float endLength, bool moveTo, RawPath* result); - - /// Add this MetricsPath to a raw path with a transform. - RawPath::Iter addToRawPath(RawPath& rawPath, const Mat2D& transform) const; - ~MetricsPath() override; - -private: - float computeLength(const Mat2D& transform); -}; - -class OnlyMetricsPath : public MetricsPath -{ -public: - void fillRule(FillRule value) override {} - - RenderPath* renderPath() override - { - // Should never be used for actual rendering. - assert(false); - return nullptr; - } -}; - -class RenderMetricsPath : public MetricsPath -{ -private: - rcp m_RenderPath; - -public: - RenderMetricsPath(rcp); - RenderPath* renderPath() override { return m_RenderPath.get(); } - void addPath(CommandPath* path, const Mat2D& transform) override; - - void fillRule(FillRule value) override; - void rewind() override; - void moveTo(float x, float y) override; - void lineTo(float x, float y) override; - void cubicTo(float ox, float oy, float ix, float iy, float x, float y) override; - void close() override; -}; -} // namespace rive -#endif diff --git a/include/rive/shapes/paint/fill.hpp b/include/rive/shapes/paint/fill.hpp index 9e8df0b5..97291e61 100644 --- a/include/rive/shapes/paint/fill.hpp +++ b/include/rive/shapes/paint/fill.hpp @@ -9,7 +9,10 @@ class Fill : public FillBase public: RenderPaint* initRenderPaint(ShapePaintMutator* mutator) override; PathSpace pathSpace() const override; - void draw(Renderer* renderer, CommandPath* path, RenderPaint* paint) override; + void draw(Renderer* renderer, + CommandPath* path, + const RawPath* rawPath, + RenderPaint* paint) override; void applyTo(RenderPaint* renderPaint, float opacityModifier) const override; }; } // namespace rive diff --git a/include/rive/shapes/paint/shape_paint.hpp b/include/rive/shapes/paint/shape_paint.hpp index 36735807..388fb134 100644 --- a/include/rive/shapes/paint/shape_paint.hpp +++ b/include/rive/shapes/paint/shape_paint.hpp @@ -5,6 +5,8 @@ #include "rive/shapes/paint/blend_mode.hpp" #include "rive/shapes/paint/shape_paint_mutator.hpp" #include "rive/shapes/path_space.hpp" +#include "rive/math/raw_path.hpp" + namespace rive { class RenderPaint; @@ -30,9 +32,17 @@ class ShapePaint : public ShapePaintBase virtual PathSpace pathSpace() const = 0; - void draw(Renderer* renderer, CommandPath* path) { draw(renderer, path, renderPaint()); } - - virtual void draw(Renderer* renderer, CommandPath* path, RenderPaint* paint) = 0; + void draw(Renderer* renderer, CommandPath* path, const RawPath* rawPath = nullptr) + { + draw(renderer, path, rawPath, renderPaint()); + } + + virtual void draw(Renderer* renderer, + CommandPath* path, + // When every CommandPath stores a RawPath we can get rid + // of this argument. + const RawPath* rawPath, + RenderPaint* paint) = 0; RenderPaint* renderPaint() { return m_RenderPaint.get(); } diff --git a/include/rive/shapes/paint/stroke.hpp b/include/rive/shapes/paint/stroke.hpp index 592eb8ff..7663669b 100644 --- a/include/rive/shapes/paint/stroke.hpp +++ b/include/rive/shapes/paint/stroke.hpp @@ -13,7 +13,10 @@ class Stroke : public StrokeBase public: RenderPaint* initRenderPaint(ShapePaintMutator* mutator) override; PathSpace pathSpace() const override; - void draw(Renderer* renderer, CommandPath* path, RenderPaint* paint) override; + void draw(Renderer* renderer, + CommandPath* path, + const RawPath* rawPath, + RenderPaint* paint) override; void addStrokeEffect(StrokeEffect* effect); bool hasStrokeEffect() { return m_Effect != nullptr; } void invalidateEffects(); diff --git a/include/rive/shapes/paint/stroke_effect.hpp b/include/rive/shapes/paint/stroke_effect.hpp index 2276d947..72ed7165 100644 --- a/include/rive/shapes/paint/stroke_effect.hpp +++ b/include/rive/shapes/paint/stroke_effect.hpp @@ -7,13 +7,13 @@ namespace rive { class Factory; class RenderPath; -class MetricsPath; +class RawPath; class StrokeEffect { public: virtual ~StrokeEffect() {} - virtual RenderPath* effectPath(MetricsPath* source, Factory*) = 0; + virtual RenderPath* effectPath(const RawPath& source, Factory*) = 0; virtual void invalidateEffect() = 0; }; } // namespace rive diff --git a/include/rive/shapes/paint/trim_path.hpp b/include/rive/shapes/paint/trim_path.hpp index 3c55ffb9..d9374819 100644 --- a/include/rive/shapes/paint/trim_path.hpp +++ b/include/rive/shapes/paint/trim_path.hpp @@ -3,24 +3,44 @@ #include "rive/generated/shapes/paint/trim_path_base.hpp" #include "rive/shapes/paint/stroke_effect.hpp" #include "rive/renderer.hpp" +#include "rive/math/raw_path.hpp" +#include "rive/math/contour_measure.hpp" namespace rive { -class TrimPath : public TrimPathBase, public StrokeEffect +enum class TrimPathMode : unsigned char { -private: - rcp m_TrimmedPath; - RenderPath* m_RenderPath = nullptr; + sequential = 1, + synchronized = 2 + +}; +class ContourMeasure; +class TrimPath : public TrimPathBase, public StrokeEffect +{ public: StatusCode onAddedClean(CoreContext* context) override; - RenderPath* effectPath(MetricsPath* source, Factory*) override; + RenderPath* effectPath(const RawPath& source, Factory*) override; void invalidateEffect() override; void startChanged() override; void endChanged() override; void offsetChanged() override; void modeValueChanged() override; + + TrimPathMode mode() const { return (TrimPathMode)modeValue(); } + + StatusCode onAddedDirty(CoreContext* context) override; + + const RawPath& rawPath() const { return m_rawPath; } + +private: + void invalidateTrim(); + void trimRawPath(const RawPath& source); + RawPath m_rawPath; + std::vector> m_contours; + rcp m_trimmedPath; + RenderPath* m_renderPath = nullptr; }; } // namespace rive diff --git a/include/rive/shapes/path.hpp b/include/rive/shapes/path.hpp index 5732cfbe..d5ba979d 100644 --- a/include/rive/shapes/path.hpp +++ b/include/rive/shapes/path.hpp @@ -3,6 +3,7 @@ #include "rive/command_path.hpp" #include "rive/generated/shapes/path_base.hpp" #include "rive/math/mat2d.hpp" +#include "rive/math/raw_path.hpp" #include "rive/shapes/shape_paint_container.hpp" #include @@ -37,10 +38,10 @@ class Path : public PathBase { protected: Shape* m_Shape = nullptr; - rcp m_CommandPath; std::vector m_Vertices; bool m_deferredPathDirt = false; PathSpace m_DefaultPathSpace = PathSpace::Neither; + RawPath m_rawPath; public: Shape* shape() const { return m_Shape; } @@ -48,7 +49,7 @@ class Path : public PathBase void buildDependencies() override; virtual const Mat2D& pathTransform() const; bool collapse(bool value) override; - CommandPath* commandPath() const { return m_CommandPath.get(); } + const RawPath& rawPath() const { return m_rawPath; } void update(ComponentDirt value) override; void addDefaultPathSpace(PathSpace space); @@ -67,8 +68,7 @@ class Path : public PathBase std::vector& vertices() { return m_Vertices; } #endif - // pour ourselves into a command-path - void buildPath(CommandPath&) const; + void buildPath(RawPath&) const; }; } // namespace rive diff --git a/include/rive/shapes/path_composer.hpp b/include/rive/shapes/path_composer.hpp index aa6ccbc8..b9b3c8fd 100644 --- a/include/rive/shapes/path_composer.hpp +++ b/include/rive/shapes/path_composer.hpp @@ -2,6 +2,8 @@ #define _RIVE_PATH_COMPOSER_HPP_ #include "rive/component.hpp" #include "rive/refcnt.hpp" +#include "rive/math/raw_path.hpp" + namespace rive { class Shape; @@ -9,23 +11,29 @@ class CommandPath; class RenderPath; class PathComposer : public Component { -private: - Shape* m_Shape; - rcp m_LocalPath; - rcp m_WorldPath; - bool m_deferredPathDirt; public: PathComposer(Shape* shape); - Shape* shape() const { return m_Shape; } + Shape* shape() const { return m_shape; } void buildDependencies() override; void onDirty(ComponentDirt dirt) override; void update(ComponentDirt value) override; - CommandPath* localPath() const { return m_LocalPath.get(); } - CommandPath* worldPath() const { return m_WorldPath.get(); } + CommandPath* localPath() const { return m_localPath.get(); } + CommandPath* worldPath() const { return m_worldPath.get(); } + + const RawPath& localRawPath() const { return m_localRawPath; } + const RawPath& worldRawPath() const { return m_worldRawPath; } void pathCollapseChanged(); + +private: + Shape* m_shape; + RawPath m_localRawPath; + RawPath m_worldRawPath; + rcp m_localPath; + rcp m_worldPath; + bool m_deferredPathDirt; }; } // namespace rive #endif diff --git a/include/rive/shapes/shape_paint_container.hpp b/include/rive/shapes/shape_paint_container.hpp index 690cccae..7ba4d766 100644 --- a/include/rive/shapes/shape_paint_container.hpp +++ b/include/rive/shapes/shape_paint_container.hpp @@ -35,8 +35,6 @@ class ShapePaintContainer void invalidateStrokeEffects(); - rcp makeCommandPath(PathSpace space); - void propagateOpacity(float opacity); #ifdef TESTING diff --git a/src/artboard.cpp b/src/artboard.cpp index 4458ecf5..6fb08e7a 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -454,7 +454,10 @@ void Artboard::update(ComponentDirt value) clip = bg; } m_ClipPath = factory()->makeRenderPath(clip); - m_BackgroundPath = factory()->makeRenderPath(bg); + + m_backgroundRawPath.addRect(bg); + m_BackgroundPath->rewind(); + m_backgroundRawPath.addTo(m_BackgroundPath.get()); } if (hasDirt(value, ComponentDirt::RenderOpacity)) { @@ -602,7 +605,7 @@ void Artboard::draw(Renderer* renderer, DrawOption option) { for (auto shapePaint : m_ShapePaints) { - shapePaint->draw(renderer, m_BackgroundPath.get()); + shapePaint->draw(renderer, m_BackgroundPath.get(), &m_backgroundRawPath); } } diff --git a/src/constraints/follow_path_constraint.cpp b/src/constraints/follow_path_constraint.cpp index 0b8096f6..199a0db4 100644 --- a/src/constraints/follow_path_constraint.cpp +++ b/src/constraints/follow_path_constraint.cpp @@ -5,7 +5,6 @@ #include "rive/math/contour_measure.hpp" #include "rive/math/mat2d.hpp" #include "rive/math/math_types.hpp" -#include "rive/shapes/metrics_path.hpp" #include "rive/shapes/path.hpp" #include "rive/shapes/shape.hpp" #include "rive/transform_component.hpp" @@ -150,8 +149,7 @@ void FollowPathConstraint::update(ComponentDirt value) m_contours.clear(); for (auto path : paths) { - auto commandPath = static_cast(path->commandPath()); - commandPath->addToRawPath(m_rawPath, path->pathTransform()); + m_rawPath.addPath(path->rawPath(), &path->pathTransform()); } auto measure = ContourMeasureIter(&m_rawPath); diff --git a/src/shapes/metrics_path.cpp b/src/shapes/metrics_path.cpp deleted file mode 100644 index f66aa5e4..00000000 --- a/src/shapes/metrics_path.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "rive/shapes/metrics_path.hpp" -#include "rive/renderer.hpp" -#include "rive/math/raw_path.hpp" -#include "rive/math/contour_measure.hpp" -#include - -using namespace rive; - -void MetricsPath::rewind() -{ - for (auto ptr : m_Paths) - { - delete ptr; - } - m_Paths.clear(); - m_Contour.reset(nullptr); - m_RawPath.rewind(); - m_ComputedLengthTransform = Mat2D(); - m_ComputedLength = 0; -} - -MetricsPath::~MetricsPath() { rewind(); } - -void MetricsPath::addPath(CommandPath* path, const Mat2D& transform) -{ - MetricsPath* metricsPath = static_cast(path); - m_ComputedLength += metricsPath->computeLength(transform); - // We need to copy the data to avoid contention between multiple uses of the same path - // for example when the same path is added as localPath and worldPath - auto metricsPathCopy = new OnlyMetricsPath(); - metricsPathCopy->m_Contour = metricsPath->m_Contour; - metricsPathCopy->m_RawPath = metricsPath->m_RawPath; - metricsPathCopy->m_ComputedLength = metricsPath->m_ComputedLength; - m_Paths.emplace_back(metricsPathCopy); -} - -RawPath::Iter MetricsPath::addToRawPath(RawPath& rawPath, const Mat2D& transform) const -{ - return rawPath.addPath(m_RawPath, &transform); -} - -void MetricsPath::moveTo(float x, float y) -{ - assert(m_RawPath.points().size() == 0); - m_RawPath.move({x, y}); -} - -void MetricsPath::lineTo(float x, float y) { m_RawPath.line({x, y}); } - -void MetricsPath::cubicTo(float ox, float oy, float ix, float iy, float x, float y) -{ - m_RawPath.cubic({ox, oy}, {ix, iy}, {x, y}); -} - -void MetricsPath::close() -{ - // Should we pass the close() to our m_RawPath ??? -} - -float MetricsPath::computeLength(const Mat2D& transform) -{ - // Only compute if our pre-computed length is not valid - if (!m_Contour || transform != m_ComputedLengthTransform) - { - m_ComputedLengthTransform = transform; - RawPath transformedPath = m_RawPath.transform(transform); - m_Contour = ContourMeasureIter(&transformedPath).next(); - m_ComputedLength = m_Contour ? m_Contour->length() : 0; - } - return m_ComputedLength; -} - -void MetricsPath::trim(float startLength, float endLength, bool moveTo, RawPath* result) -{ - assert(endLength >= startLength); - if (!m_Paths.empty()) - { - m_Paths.front()->trim(startLength, endLength, moveTo, result); - return; - } - if (!m_Contour) - { - // All the contours were 0 length, so there's nothing to segment. - return; - } - // TODO: if we can change the signature of MetricsPath and/or trim() to speak native - // rawpaths, we wouldn't need this temporary copy (since ContourMeasure speaks - // native rawpaths). - RawPath tmp; - m_Contour->getSegment(startLength, endLength, result, moveTo); -} - -RenderMetricsPath::RenderMetricsPath(rcp path) : m_RenderPath(std::move(path)) {} - -void RenderMetricsPath::addPath(CommandPath* path, const Mat2D& transform) -{ - MetricsPath::addPath(path, transform); - m_RenderPath->addPath(path->renderPath(), transform); -} - -void RenderMetricsPath::rewind() -{ - MetricsPath::rewind(); - m_RenderPath->rewind(); -} - -void RenderMetricsPath::moveTo(float x, float y) -{ - MetricsPath::moveTo(x, y); - m_RenderPath->moveTo(x, y); -} - -void RenderMetricsPath::lineTo(float x, float y) -{ - MetricsPath::lineTo(x, y); - m_RenderPath->lineTo(x, y); -} - -void RenderMetricsPath::cubicTo(float ox, float oy, float ix, float iy, float x, float y) -{ - MetricsPath::cubicTo(ox, oy, ix, iy, x, y); - m_RenderPath->cubicTo(ox, oy, ix, iy, x, y); -} - -void RenderMetricsPath::close() -{ - MetricsPath::close(); - m_RenderPath->close(); -} - -void RenderMetricsPath::fillRule(FillRule value) { m_RenderPath->fillRule(value); } diff --git a/src/shapes/paint/fill.cpp b/src/shapes/paint/fill.cpp index 60c39d88..466b61a7 100644 --- a/src/shapes/paint/fill.cpp +++ b/src/shapes/paint/fill.cpp @@ -18,7 +18,7 @@ void Fill::applyTo(RenderPaint* renderPaint, float opacityModifier) const m_PaintMutator->applyTo(renderPaint, opacityModifier); } -void Fill::draw(Renderer* renderer, CommandPath* path, RenderPaint* paint) +void Fill::draw(Renderer* renderer, CommandPath* path, const RawPath* rawPath, RenderPaint* paint) { if (!isVisible()) { diff --git a/src/shapes/paint/stroke.cpp b/src/shapes/paint/stroke.cpp index a32b7b38..b0d7348b 100644 --- a/src/shapes/paint/stroke.cpp +++ b/src/shapes/paint/stroke.cpp @@ -33,18 +33,17 @@ void Stroke::applyTo(RenderPaint* renderPaint, float opacityModifier) const bool Stroke::isVisible() const { return Super::isVisible() && thickness() > 0.0f; } -void Stroke::draw(Renderer* renderer, CommandPath* path, RenderPaint* paint) +void Stroke::draw(Renderer* renderer, CommandPath* path, const RawPath* rawPath, RenderPaint* paint) { if (!isVisible()) { return; } - if (m_Effect != nullptr) + if (m_Effect != nullptr && rawPath != nullptr) { - /// We're guaranteed to get a metrics path here if we have an effect. auto factory = artboard()->factory(); - path = m_Effect->effectPath(reinterpret_cast(path), factory); + path = m_Effect->effectPath(*rawPath, factory); } renderer->drawPath(path->renderPath(), paint); diff --git a/src/shapes/paint/trim_path.cpp b/src/shapes/paint/trim_path.cpp index 7fad5424..6b0e334f 100644 --- a/src/shapes/paint/trim_path.cpp +++ b/src/shapes/paint/trim_path.cpp @@ -1,5 +1,4 @@ #include "rive/shapes/paint/trim_path.hpp" -#include "rive/shapes/metrics_path.hpp" #include "rive/shapes/paint/stroke.hpp" #include "rive/factory.hpp" @@ -17,33 +16,29 @@ StatusCode TrimPath::onAddedClean(CoreContext* context) return StatusCode::Ok; } -RenderPath* TrimPath::effectPath(MetricsPath* source, Factory* factory) +void TrimPath::trimRawPath(const RawPath& source) { - if (m_RenderPath != nullptr) - { - return m_RenderPath; - } - - // Source is always a containing (shape) path. - const std::vector& subPaths = source->paths(); - - RawPath rawTrimmed; + m_rawPath.rewind(); + auto renderOffset = std::fmod(std::fmod(offset(), 1.0f) + 1.0f, 1.0f); - if (!m_TrimmedPath) + // Build up contours if they're empty. + if (m_contours.empty()) { - m_TrimmedPath = factory->makeEmptyRenderPath(); - } - else - { - m_TrimmedPath->rewind(); + ContourMeasureIter iter(&source); + while (auto meas = iter.next()) + { + m_contours.push_back(meas); + } } - - auto renderOffset = std::fmod(std::fmod(offset(), 1.0f) + 1.0f, 1.0f); - switch (modeValue()) + switch (mode()) { - case 1: + case TrimPathMode::sequential: { - float totalLength = source->length(); + float totalLength = 0.0f; + for (auto contour : m_contours) + { + totalLength += contour->length(); + } auto startLength = totalLength * (start() + renderOffset); auto endLength = totalLength * (end() + renderOffset); @@ -60,35 +55,35 @@ RenderPath* TrimPath::effectPath(MetricsPath* source, Factory* factory) endLength -= totalLength; } - int i = 0, subPathCount = (int)subPaths.size(); + int i = 0, subPathCount = (int)m_contours.size(); while (endLength > 0) { - auto path = subPaths[i % subPathCount]; - auto pathLength = path->length(); + auto contour = m_contours[i % subPathCount]; + auto contourLength = contour->length(); - if (startLength < pathLength) + if (startLength < contourLength) { - path->trim(startLength, endLength, true, &rawTrimmed); - endLength -= pathLength; + contour->getSegment(startLength, endLength, &m_rawPath, true); + endLength -= contourLength; startLength = 0; } else { - startLength -= pathLength; - endLength -= pathLength; + startLength -= contourLength; + endLength -= contourLength; } i++; } } break; - case 2: + case TrimPathMode::synchronized: { - for (auto path : subPaths) + for (auto contour : m_contours) { - auto pathLength = path->length(); - auto startLength = pathLength * (start() + renderOffset); - auto endLength = pathLength * (end() + renderOffset); + auto contourLength = contour->length(); + auto startLength = contourLength * (start() + renderOffset); + auto endLength = contourLength * (end() + renderOffset); if (endLength < startLength) { auto length = startLength; @@ -96,37 +91,83 @@ RenderPath* TrimPath::effectPath(MetricsPath* source, Factory* factory) endLength = length; } - if (startLength > pathLength) + if (startLength > contourLength) { - startLength -= pathLength; - endLength -= pathLength; + startLength -= contourLength; + endLength -= contourLength; } - path->trim(startLength, endLength, true, &rawTrimmed); - while (endLength > pathLength) + contour->getSegment(startLength, endLength, &m_rawPath, true); + while (endLength > contourLength) { startLength = 0; - endLength -= pathLength; - path->trim(startLength, endLength, true, &rawTrimmed); + endLength -= contourLength; + contour->getSegment(startLength, endLength, &m_rawPath, true); } } } break; + default: + RIVE_UNREACHABLE(); } +} - m_RenderPath = m_TrimmedPath.get(); - rawTrimmed.addTo(m_RenderPath); - return m_RenderPath; +RenderPath* TrimPath::effectPath(const RawPath& source, Factory* factory) +{ + if (m_renderPath != nullptr) + { + // Previous result hasn't been invalidated, it's still good. + return m_renderPath; + } + + trimRawPath(source); + + if (!m_trimmedPath) + { + m_trimmedPath = factory->makeEmptyRenderPath(); + } + else + { + m_trimmedPath->rewind(); + } + + m_renderPath = m_trimmedPath.get(); + m_rawPath.addTo(m_renderPath); + return m_renderPath; } void TrimPath::invalidateEffect() { - m_RenderPath = nullptr; + invalidateTrim(); + // This is usually sent when the path is changed so we need to also + // invalidate the contours, not just the trim effect. + m_contours.clear(); +} + +void TrimPath::invalidateTrim() +{ + m_renderPath = nullptr; auto stroke = parent()->as(); stroke->parent()->addDirt(ComponentDirt::Paint); stroke->invalidateRendering(); } -void TrimPath::startChanged() { invalidateEffect(); } -void TrimPath::endChanged() { invalidateEffect(); } -void TrimPath::offsetChanged() { invalidateEffect(); } -void TrimPath::modeValueChanged() { invalidateEffect(); } +void TrimPath::startChanged() { invalidateTrim(); } +void TrimPath::endChanged() { invalidateTrim(); } +void TrimPath::offsetChanged() { invalidateTrim(); } +void TrimPath::modeValueChanged() { invalidateTrim(); } + +StatusCode TrimPath::onAddedDirty(CoreContext* context) +{ + auto code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + switch (mode()) + { + case TrimPathMode::sequential: + case TrimPathMode::synchronized: + return StatusCode::Ok; + } + return StatusCode::InvalidObject; +} \ No newline at end of file diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp index 53545809..cdf45aa2 100644 --- a/src/shapes/path.cpp +++ b/src/shapes/path.cpp @@ -47,14 +47,7 @@ StatusCode Path::onAddedClean(CoreContext* context) return StatusCode::MissingObject; } -void Path::buildDependencies() -{ - Super::buildDependencies(); - // Make sure this is called once the shape has all of the paints added - // (paints get added during the added cycle so buildDependencies is a good - // time to do this.) - m_CommandPath = m_Shape->makeCommandPath(m_DefaultPathSpace); -} +void Path::buildDependencies() { Super::buildDependencies(); } void Path::addVertex(PathVertex* vertex) { m_Vertices.push_back(vertex); } @@ -62,13 +55,20 @@ void Path::addDefaultPathSpace(PathSpace space) { m_DefaultPathSpace |= space; } bool Path::canDeferPathUpdate() { - return ((m_DefaultPathSpace & PathSpace::Clipping) != PathSpace::Clipping) && + // A path cannot defer its update if the shapes requires an update. Note the + // nuance here where we track that the shape may be marked for follow path + // (meaning all child paths need to follow path). This doesn't mean the + // Shape is necessarily forced to update put the paths are, which is why we + // explicitly also check the shape's path space. + return m_Shape->canDeferPathUpdate() && + (m_Shape->pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath && + ((m_DefaultPathSpace & PathSpace::Clipping) != PathSpace::Clipping) && ((m_DefaultPathSpace & PathSpace::FollowPath) != PathSpace::FollowPath); } const Mat2D& Path::pathTransform() const { return worldTransform(); } -void Path::buildPath(CommandPath& commandPath) const +void Path::buildPath(RawPath& rawPath) const { const bool isClosed = isPathClosed(); const std::vector& vertices = m_Vertices; @@ -94,7 +94,7 @@ void Path::buildPath(CommandPath& commandPath) const startIn = cubic->renderIn(); out = cubic->renderOut(); start = cubic->renderTranslation(); - commandPath.move(start); + rawPath.move(start); } else { @@ -125,18 +125,18 @@ void Path::buildPath(CommandPath& commandPath) const float idealDistance = computeIdealControlPointDistance(toPrev, toNext, renderRadius); startIn = start = Vec2D::scaleAndAdd(pos, toPrev, renderRadius); - commandPath.move(startIn); + rawPath.move(startIn); Vec2D outPoint = Vec2D::scaleAndAdd(pos, toPrev, renderRadius - idealDistance); Vec2D inPoint = Vec2D::scaleAndAdd(pos, toNext, renderRadius - idealDistance); out = Vec2D::scaleAndAdd(pos, toNext, renderRadius); - commandPath.cubic(outPoint, inPoint, out); + rawPath.cubic(outPoint, inPoint, out); prevIsCubic = false; } else { startIn = start = out = point.renderTranslation(); - commandPath.move(out); + rawPath.move(out); } } @@ -150,7 +150,7 @@ void Path::buildPath(CommandPath& commandPath) const auto inPoint = cubic->renderIn(); auto translation = cubic->renderTranslation(); - commandPath.cubic(out, inPoint, translation); + rawPath.cubic(out, inPoint, translation); prevIsCubic = true; out = cubic->renderOut(); @@ -183,22 +183,22 @@ void Path::buildPath(CommandPath& commandPath) const Vec2D translation = Vec2D::scaleAndAdd(pos, toPrev, renderRadius); if (prevIsCubic) { - commandPath.cubic(out, translation, translation); + rawPath.cubic(out, translation, translation); } else { - commandPath.line(translation); + rawPath.line(translation); } Vec2D outPoint = Vec2D::scaleAndAdd(pos, toPrev, renderRadius - idealDistance); Vec2D inPoint = Vec2D::scaleAndAdd(pos, toNext, renderRadius - idealDistance); out = Vec2D::scaleAndAdd(pos, toNext, renderRadius); - commandPath.cubic(outPoint, inPoint, out); + rawPath.cubic(outPoint, inPoint, out); prevIsCubic = false; } else if (prevIsCubic) { - commandPath.cubic(out, pos, pos); + rawPath.cubic(out, pos, pos); prevIsCubic = false; out = pos; @@ -206,7 +206,7 @@ void Path::buildPath(CommandPath& commandPath) const else { out = pos; - commandPath.line(out); + rawPath.line(out); } } } @@ -214,13 +214,13 @@ void Path::buildPath(CommandPath& commandPath) const { if (prevIsCubic || startIsCubic) { - commandPath.cubic(out, startIn, start); + rawPath.cubic(out, startIn, start); } else { - commandPath.line(start); + rawPath.line(start); } - commandPath.close(); + rawPath.close(); } } @@ -249,9 +249,9 @@ void Path::update(ComponentDirt value) { Super::update(value); - if (m_CommandPath != nullptr && hasDirt(value, ComponentDirt::Path)) + if (hasDirt(value, ComponentDirt::Path)) { - if (m_Shape->canDeferPathUpdate()) + if (canDeferPathUpdate()) { m_deferredPathDirt = true; return; @@ -260,8 +260,8 @@ void Path::update(ComponentDirt value) // Build path doesn't explicitly rewind because we use it to concatenate // multiple built paths into a single command path (like the hit // tester). - m_CommandPath->rewind(); - buildPath(*m_CommandPath); + m_rawPath.rewind(); + buildPath(m_rawPath); } // if (hasDirt(value, ComponentDirt::WorldTransform) && m_Shape != nullptr) // { diff --git a/src/shapes/path_composer.cpp b/src/shapes/path_composer.cpp index e0bf032c..71a4c00e 100644 --- a/src/shapes/path_composer.cpp +++ b/src/shapes/path_composer.cpp @@ -3,16 +3,17 @@ #include "rive/renderer.hpp" #include "rive/shapes/path.hpp" #include "rive/shapes/shape.hpp" +#include "rive/factory.hpp" using namespace rive; -PathComposer::PathComposer(Shape* shape) : m_Shape(shape), m_deferredPathDirt(false) {} +PathComposer::PathComposer(Shape* shape) : m_shape(shape), m_deferredPathDirt(false) {} void PathComposer::buildDependencies() { - assert(m_Shape != nullptr); - m_Shape->addDependent(this); - for (auto path : m_Shape->paths()) + assert(m_shape != nullptr); + m_shape->addDependent(this); + for (auto path : m_shape->paths()) { path->addDependent(this); } @@ -25,7 +26,7 @@ void PathComposer::onDirty(ComponentDirt dirt) // We'd deferred the update, let's make sure the rest of our // dependencies update too. Constraints need to update too, stroke // effects, etc. - m_Shape->pathChanged(); + m_shape->pathChanged(); } } @@ -33,61 +34,63 @@ void PathComposer::update(ComponentDirt value) { if (hasDirt(value, ComponentDirt::Path)) { - if (m_Shape->canDeferPathUpdate()) + if (m_shape->canDeferPathUpdate()) { m_deferredPathDirt = true; return; } m_deferredPathDirt = false; - auto space = m_Shape->pathSpace(); - bool hasConstraint = (space & PathSpace::FollowPath) == PathSpace::FollowPath; + auto space = m_shape->pathSpace(); if ((space & PathSpace::Local) == PathSpace::Local) { - if (m_LocalPath == nullptr) + if (m_localPath == nullptr) { - PathSpace localSpace = - (hasConstraint) ? PathSpace::Local & PathSpace::FollowPath : PathSpace::Local; - m_LocalPath = m_Shape->makeCommandPath(localSpace); + m_localPath = artboard()->factory()->makeEmptyRenderPath(); } else { - m_LocalPath->rewind(); + m_localPath->rewind(); + m_localRawPath.rewind(); } - auto world = m_Shape->worldTransform(); + auto world = m_shape->worldTransform(); Mat2D inverseWorld = world.invertOrIdentity(); // Get all the paths into local shape space. - for (auto path : m_Shape->paths()) + for (auto path : m_shape->paths()) { if (!path->isHidden() && !path->isCollapsed()) { const auto localTransform = inverseWorld * path->pathTransform(); - m_LocalPath->addPath(path->commandPath(), localTransform); + m_localRawPath.addPath(path->rawPath(), &localTransform); } } + + // TODO: add a CommandPath::copy(RawPath) + m_localRawPath.addTo(m_localPath.get()); } if ((space & PathSpace::World) == PathSpace::World) { - if (m_WorldPath == nullptr) + if (m_worldPath == nullptr) { - PathSpace worldSpace = - (hasConstraint) ? PathSpace::World & PathSpace::FollowPath : PathSpace::World; - m_WorldPath = m_Shape->makeCommandPath(worldSpace); + m_worldPath = artboard()->factory()->makeEmptyRenderPath(); } else { - m_WorldPath->rewind(); + m_worldPath->rewind(); + m_worldRawPath.rewind(); } - for (auto path : m_Shape->paths()) + for (auto path : m_shape->paths()) { if (!path->isHidden() && !path->isCollapsed()) { const Mat2D& transform = path->pathTransform(); - m_WorldPath->addPath(path->commandPath(), transform); + m_worldRawPath.addPath(path->rawPath(), &transform); } } + // TODO: add a CommandPath::copy(RawPath) + m_worldRawPath.addTo(m_worldPath.get()); } - m_Shape->markBoundsDirty(); + m_shape->markBoundsDirty(); } } diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index e37b4749..01310ed4 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -24,9 +24,8 @@ void Shape::addPath(Path* path) bool Shape::canDeferPathUpdate() { - auto canDefer = renderOpacity() == 0 && - (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping && - (pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath; + auto canDefer = + renderOpacity() == 0 && (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping; if (canDefer) { // If we have a dependent Skin, don't defer the update @@ -37,13 +36,6 @@ bool Shape::canDeferPathUpdate() return false; } } - for (auto path : m_Paths) - { - if (!path->canDeferPathUpdate()) - { - return false; - } - } } return canDefer; } @@ -113,9 +105,10 @@ void Shape::draw(Renderer* renderer) { renderer->transform(worldTransform()); } - shapePaint->draw(renderer, - paintsInLocal ? m_PathComposer.localPath() - : m_PathComposer.worldPath()); + shapePaint->draw( + renderer, + paintsInLocal ? m_PathComposer.localPath() : m_PathComposer.worldPath(), + paintsInLocal ? &m_PathComposer.localRawPath() : &m_PathComposer.worldRawPath()); renderer->restore(); } } @@ -135,7 +128,7 @@ bool Shape::hitTest(const IAABB& area) const if (!path->isCollapsed()) { tester.setXform(path->pathTransform()); - path->buildPath(tester); + path->rawPath().addTo(&tester); } } return tester.wasHit(); @@ -184,7 +177,7 @@ Core* Shape::hitTest(HitInfo* hinfo, const Mat2D& xform) { tester.setXform(mx * path->pathTransform()); } - path->buildPath(tester); + path->rawPath().addTo(&tester); } if (tester.wasHit()) { @@ -284,8 +277,7 @@ AABB Shape::computeWorldBounds(const Mat2D* xform) const { continue; } - - path->buildPath(boundsCalculator); + path->rawPath().addTo(&boundsCalculator); AABB aabb = boundsCalculator.bounds(xform == nullptr ? path->pathTransform() : path->pathTransform() * *xform); diff --git a/src/shapes/shape_paint_container.cpp b/src/shapes/shape_paint_container.cpp index a0232dbd..ab9057a1 100644 --- a/src/shapes/shape_paint_container.cpp +++ b/src/shapes/shape_paint_container.cpp @@ -2,7 +2,6 @@ #include "rive/artboard.hpp" #include "rive/factory.hpp" #include "rive/component.hpp" -#include "rive/shapes/metrics_path.hpp" #include "rive/shapes/paint/stroke.hpp" #include "rive/shapes/shape.hpp" #include "rive/text/text_style.hpp" @@ -46,53 +45,6 @@ void ShapePaintContainer::invalidateStrokeEffects() } } -rcp ShapePaintContainer::makeCommandPath(PathSpace space) -{ - // Force a render path if we specifically request to use it for clipping or - // this shape is used for clipping. - bool needForRender = - ((space | m_DefaultPathSpace) & PathSpace::Clipping) == PathSpace::Clipping; - bool needForConstraint = - ((space | m_DefaultPathSpace) & PathSpace::FollowPath) == PathSpace::FollowPath; - - bool needForEffects = false; - - for (auto paint : m_ShapePaints) - { - if (space != PathSpace::Neither && (space & paint->pathSpace()) != space) - { - continue; - } - - if (paint->is() && paint->as()->hasStrokeEffect()) - { - needForEffects = true; - } - else - { - needForRender = true; - } - } - - auto factory = getArtboard()->factory(); - if (needForEffects && needForRender) - { - return make_rcp(factory->makeEmptyRenderPath()); - } - else if (needForConstraint) - { - return make_rcp(factory->makeEmptyRenderPath()); - } - else if (needForEffects) - { - return make_rcp(); - } - else - { - return factory->makeEmptyRenderPath(); - } -} - void ShapePaintContainer::propagateOpacity(float opacity) { for (auto shapePaint : m_ShapePaints) diff --git a/src/text/text_style.cpp b/src/text/text_style.cpp index e1b13434..a2a81eae 100644 --- a/src/text/text_style.cpp +++ b/src/text/text_style.cpp @@ -191,7 +191,7 @@ void TextStyle::draw(Renderer* renderer) { RenderPaint* renderPaint = m_paintPool[paintIndex++].get(); shapePaint->applyTo(renderPaint, itr->first); - shapePaint->draw(renderer, itr->second.get(), renderPaint); + shapePaint->draw(renderer, itr->second.get(), nullptr, renderPaint); } } } diff --git a/tess/test/triangulation_test.cpp b/tess/test/triangulation_test.cpp index 58376354..d2a4b018 100644 --- a/tess/test/triangulation_test.cpp +++ b/tess/test/triangulation_test.cpp @@ -29,7 +29,7 @@ TEST_CASE("simple triangle path triangulates as expected", "[file]") auto path = artboard->find("triangle_path"); REQUIRE(path != nullptr); TestRenderPath renderPath; - path->buildPath(renderPath); + path->rawPath().addTo(&renderPath); rive::Mat2D identity; TestRenderPath shapeRenderPath; diff --git a/test/contour_measure_test.cpp b/test/contour_measure_test.cpp index c9164d68..35483665 100644 --- a/test/contour_measure_test.cpp +++ b/test/contour_measure_test.cpp @@ -177,3 +177,25 @@ TEST_CASE("nan-path", "[contourmeasure]") CHECK(iter.next() == nullptr); } } + +// Regression test for a crash found by fuzzing. +TEST_CASE("fuzz_issue_7295", "[MetricsPath]") +{ + NoOpFactory factory; + + RawPath innerPath; + innerPath.moveTo(.0f, -20.5f); + innerPath.cubicTo(11.3218384f, -20.5f, 20.5f, -11.3218384f, 20.5f, .0f); + innerPath.cubicTo(20.5f, 11.3218384f, 11.3218384f, 20.5f, .0f, 20.5f); + innerPath.cubicTo(-11.3218384f, 20.5f, -20.5f, 11.3218384f, -20.5f, .0f); + innerPath.cubicTo(-20.5f, -11.3218384f, -11.3218384f, -20.5f, .0f, -20.5f); + + RawPath outerPath; + Mat2D transform(1.f, .0f, .0f, 1.f, -134217728.f, -134217728.f); + outerPath.addPath(innerPath, &transform); + + auto contour = ContourMeasureIter(&outerPath).next(); + RawPath result; + contour->getSegment(.0f, 168.389008f, &result, true); + CHECK(math::nearly_equal(contour->length(), 168.389008f)); +} diff --git a/test/metrics_path_test.cpp b/test/metrics_path_test.cpp deleted file mode 100644 index cde47276..00000000 --- a/test/metrics_path_test.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace rive; - -TEST_CASE("path metrics compute correctly", "[bezier]") -{ - // TODO: fix these based on new logic - // Make a square with sides length 10. - // rive::OnlyMetricsPath path; - // path.moveTo(0, 0); - // path.lineTo(10, 0); - // path.lineTo(10, 10); - // path.lineTo(0, 10); - // path.close(); - - // // Total length should be 40. - // rive::Mat2D identity; - // float length = path.computeLength(identity); - // REQUIRE(length == 40); - - // // Make a path with a single cubic. - // rive::OnlyMetricsPath cubicPath; - // cubicPath.moveTo(102, 22); - // cubicPath.cubicTo(10, 80, 120, 100, 150, 222); - // cubicPath.close(); - - // float cubicLength = cubicPath.computeLength(identity); - // REQUIRE(cubicLength == 238.38698f); -} - -// Regression test for a crash found by fuzzing. -TEST_CASE("fuzz_issue_7295", "[MetricsPath]") -{ - NoOpFactory factory; - - OnlyMetricsPath innerPath; - innerPath.moveTo(.0f, -20.5f); - innerPath.cubicTo(11.3218384f, -20.5f, 20.5f, -11.3218384f, 20.5f, .0f); - innerPath.cubicTo(20.5f, 11.3218384f, 11.3218384f, 20.5f, .0f, 20.5f); - innerPath.cubicTo(-11.3218384f, 20.5f, -20.5f, 11.3218384f, -20.5f, .0f); - innerPath.cubicTo(-20.5f, -11.3218384f, -11.3218384f, -20.5f, .0f, -20.5f); - - OnlyMetricsPath outerPath; - outerPath.addPath(&innerPath, Mat2D(1.f, .0f, .0f, 1.f, -134217728.f, -134217728.f)); - - RawPath result; - outerPath.paths()[0]->trim(.0f, 168.389008f, true, &result); - CHECK(math::nearly_equal(outerPath.paths()[0]->length(), 168.389008f)); -} diff --git a/test/path_test.cpp b/test/path_test.cpp index bd580786..a6640753 100644 --- a/test/path_test.cpp +++ b/test/path_test.cpp @@ -12,6 +12,7 @@ #include #include #include "rive_file_reader.hpp" +#include "rive/math/path_types.hpp" #include #include @@ -111,18 +112,16 @@ TEST_CASE("rectangle path builds expected commands", "[path]") artboard.advance(0.0f); - REQUIRE(rectangle->commandPath() != nullptr); + auto rawPath = rectangle->rawPath(); - auto path = static_cast(rectangle->commandPath()); - - REQUIRE(path->commands.size() == 7); - REQUIRE(path->commands[0].command == TestPathCommandType::Reset); - REQUIRE(path->commands[1].command == TestPathCommandType::MoveTo); - REQUIRE(path->commands[2].command == TestPathCommandType::LineTo); - REQUIRE(path->commands[3].command == TestPathCommandType::LineTo); - REQUIRE(path->commands[4].command == TestPathCommandType::LineTo); - REQUIRE(path->commands[5].command == TestPathCommandType::LineTo); - REQUIRE(path->commands[6].command == TestPathCommandType::Close); + auto verbs = rawPath.verbs(); + REQUIRE(verbs.size() == 6); + REQUIRE(verbs[0] == rive::PathVerb::move); + REQUIRE(verbs[1] == rive::PathVerb::line); + REQUIRE(verbs[2] == rive::PathVerb::line); + REQUIRE(verbs[3] == rive::PathVerb::line); + REQUIRE(verbs[4] == rive::PathVerb::line); + REQUIRE(verbs[5] == rive::PathVerb::close); } TEST_CASE("rounded rectangle path builds expected commands", "[path]") @@ -148,9 +147,7 @@ TEST_CASE("rounded rectangle path builds expected commands", "[path]") artboard.advance(0.0f); - REQUIRE(rectangle->commandPath() != nullptr); - - auto path = static_cast(rectangle->commandPath()); + auto rawPath = rectangle->rawPath(); // rewind // moveTo @@ -161,31 +158,30 @@ TEST_CASE("rounded rectangle path builds expected commands", "[path]") // lineTo, cubicTo for 4th corner // close - - REQUIRE(path->commands.size() == 11); + auto verbs = rawPath.verbs(); + REQUIRE(verbs.size() == 10); // Init - REQUIRE(path->commands[0].command == TestPathCommandType::Reset); - REQUIRE(path->commands[1].command == TestPathCommandType::MoveTo); + REQUIRE(verbs[0] == rive::PathVerb::move); // 1st - REQUIRE(path->commands[2].command == TestPathCommandType::CubicTo); + REQUIRE(verbs[1] == rive::PathVerb::cubic); // 2nd - REQUIRE(path->commands[3].command == TestPathCommandType::LineTo); - REQUIRE(path->commands[4].command == TestPathCommandType::CubicTo); + REQUIRE(verbs[2] == rive::PathVerb::line); + REQUIRE(verbs[3] == rive::PathVerb::cubic); // 3rd - REQUIRE(path->commands[5].command == TestPathCommandType::LineTo); - REQUIRE(path->commands[6].command == TestPathCommandType::CubicTo); + REQUIRE(verbs[4] == rive::PathVerb::line); + REQUIRE(verbs[5] == rive::PathVerb::cubic); // 4th - REQUIRE(path->commands[7].command == TestPathCommandType::LineTo); - REQUIRE(path->commands[8].command == TestPathCommandType::CubicTo); + REQUIRE(verbs[6] == rive::PathVerb::line); + REQUIRE(verbs[7] == rive::PathVerb::cubic); - REQUIRE(path->commands[9].command == TestPathCommandType::LineTo); + REQUIRE(verbs[8] == rive::PathVerb::line); - REQUIRE(path->commands[10].command == TestPathCommandType::Close); + REQUIRE(verbs[9] == rive::PathVerb::close); } TEST_CASE("ellipse path builds expected commands", "[path]") @@ -209,9 +205,7 @@ TEST_CASE("ellipse path builds expected commands", "[path]") artboard.advance(0.0f); - REQUIRE(ellipse->commandPath() != nullptr); - - auto path = static_cast(ellipse->commandPath()); + auto path = ellipse->rawPath(); // rewind // moveTo @@ -223,51 +217,52 @@ TEST_CASE("ellipse path builds expected commands", "[path]") // close - REQUIRE(path->commands.size() == 7); + auto verbs = path.verbs(); + auto points = path.points(); + REQUIRE(verbs.size() == 6); // Init - REQUIRE(path->commands[0].command == TestPathCommandType::Reset); - REQUIRE(path->commands[1].command == TestPathCommandType::MoveTo); - REQUIRE(path->commands[1].x == 0.0f); - REQUIRE(path->commands[1].y == -100.0f); + REQUIRE(verbs[0] == rive::PathVerb::move); + REQUIRE(points[0].x == 0.0f); + REQUIRE(points[0].y == -100.0f); // 1st - REQUIRE(path->commands[2].command == TestPathCommandType::CubicTo); - REQUIRE(path->commands[2].outX == 50.0f * rive::circleConstant); - REQUIRE(path->commands[2].outY == -100.0f); - REQUIRE(path->commands[2].inX == 50.0f); - REQUIRE(path->commands[2].inY == -100.0f * rive::circleConstant); - REQUIRE(path->commands[2].x == 50.0f); - REQUIRE(path->commands[2].y == 0.0f); + REQUIRE(verbs[1] == rive::PathVerb::cubic); + REQUIRE(points[1].x == 50.0f * rive::circleConstant); + REQUIRE(points[1].y == -100.0f); + REQUIRE(points[2].x == 50.0f); + REQUIRE(points[2].y == -100.0f * rive::circleConstant); + REQUIRE(points[3].x == 50.0f); + REQUIRE(points[3].y == 0.0f); // 2nd - REQUIRE(path->commands[3].command == TestPathCommandType::CubicTo); - REQUIRE(path->commands[3].outX == 50.0f); - REQUIRE(path->commands[3].outY == 100.0f * rive::circleConstant); - REQUIRE(path->commands[3].inX == 50.0f * rive::circleConstant); - REQUIRE(path->commands[3].inY == 100.0f); - REQUIRE(path->commands[3].x == 0.0f); - REQUIRE(path->commands[3].y == 100.0f); + REQUIRE(verbs[2] == rive::PathVerb::cubic); + REQUIRE(points[4].x == 50.0f); + REQUIRE(points[4].y == 100.0f * rive::circleConstant); + REQUIRE(points[5].x == 50.0f * rive::circleConstant); + REQUIRE(points[5].y == 100.0f); + REQUIRE(points[6].x == 0.0f); + REQUIRE(points[6].y == 100.0f); // 3rd - REQUIRE(path->commands[4].command == TestPathCommandType::CubicTo); - REQUIRE(path->commands[4].outX == -50.0f * rive::circleConstant); - REQUIRE(path->commands[4].outY == 100.0f); - REQUIRE(path->commands[4].inX == -50.0f); - REQUIRE(path->commands[4].inY == 100.0f * rive::circleConstant); - REQUIRE(path->commands[4].x == -50.0f); - REQUIRE(path->commands[4].y == 0.0f); + REQUIRE(verbs[3] == rive::PathVerb::cubic); + REQUIRE(points[7].x == -50.0f * rive::circleConstant); + REQUIRE(points[7].y == 100.0f); + REQUIRE(points[8].x == -50.0f); + REQUIRE(points[8].y == 100.0f * rive::circleConstant); + REQUIRE(points[9].x == -50.0f); + REQUIRE(points[9].y == 0.0f); // 4th - REQUIRE(path->commands[5].command == TestPathCommandType::CubicTo); - REQUIRE(path->commands[5].outX == -50.0f); - REQUIRE(path->commands[5].outY == -100.0f * rive::circleConstant); - REQUIRE(path->commands[5].inX == -50.0f * rive::circleConstant); - REQUIRE(path->commands[5].inY == -100.0f); - REQUIRE(path->commands[5].x == 0.0f); - REQUIRE(path->commands[5].y == -100.0f); - - REQUIRE(path->commands[6].command == TestPathCommandType::Close); + REQUIRE(verbs[4] == rive::PathVerb::cubic); + REQUIRE(points[10].x == -50.0f); + REQUIRE(points[10].y == -100.0f * rive::circleConstant); + REQUIRE(points[11].x == -50.0f * rive::circleConstant); + REQUIRE(points[11].y == -100.0f); + REQUIRE(points[12].x == 0.0f); + REQUIRE(points[12].y == -100.0f); + + REQUIRE(verbs[5] == rive::PathVerb::close); } TEST_CASE("nested solo with shape expanded and path collapsed", "[path]") @@ -295,7 +290,7 @@ TEST_CASE("nested solo with shape expanded and path collapsed", "[path]") auto path = solo->children()[1]->as(); REQUIRE(rectangleShape->isCollapsed() == false); REQUIRE(path->isCollapsed() == true); - REQUIRE(path->commandPath() != nullptr); + auto pathComposer = rootShape->pathComposer(); auto pathComposerPath = static_cast(pathComposer->localPath()); // Path is skipped and the nested shape forms its own drawable, so size is 0 @@ -327,7 +322,7 @@ TEST_CASE("nested solo clipping with shape collapsed and path expanded", "[path] auto path = solo->children()[1]->as(); REQUIRE(rectangleShape->isCollapsed() == true); REQUIRE(path->isCollapsed() == false); - REQUIRE(path->commandPath() != nullptr); + auto clippingShape = rectangleClip->clippingShapes()[0]; REQUIRE(clippingShape != nullptr); auto clippingPath = static_cast(clippingShape->renderPath()); From afd3a5cd34500fe5f22f2758f676074a4b291e8c Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Fri, 7 Jun 2024 23:59:35 +0000 Subject: [PATCH 059/138] =?UTF-8?q?don=E2=80=99t=20defer=20updates=20when?= =?UTF-8?q?=20a=20shape/path=20is=20used=20for=20hit=20detect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes issue reported by Duolingo. https://2dimensions.slack.com/archives/C029X99PETE/p1717700429867579 Diffs= a10b1e61e don’t defer updates when a shape/path is used for hit detect (#7392) Co-authored-by: Luigi Rosso Co-authored-by: hernan --- .rive_head | 2 +- .../rive/animation/state_machine_listener.hpp | 13 ++-- include/rive/component.hpp | 3 + include/rive/container_component.hpp | 12 +++- include/rive/shapes/paint/fill.hpp | 4 +- include/rive/shapes/paint/shape_paint.hpp | 5 +- include/rive/shapes/paint/stroke.hpp | 4 +- include/rive/shapes/path.hpp | 6 +- include/rive/shapes/path_flags.hpp | 66 +++++++++++++++++++ include/rive/shapes/path_space.hpp | 65 ------------------ include/rive/shapes/shape.hpp | 3 +- include/rive/shapes/shape_paint_container.hpp | 6 +- src/animation/state_machine_instance.cpp | 47 ++++++------- src/animation/state_machine_listener.cpp | 44 ++----------- src/component.cpp | 4 +- src/constraints/follow_path_constraint.cpp | 4 +- src/container_component.cpp | 20 ++++++ src/shapes/clipping_shape.cpp | 2 +- src/shapes/paint/fill.cpp | 2 +- src/shapes/paint/linear_gradient.cpp | 4 +- src/shapes/paint/stroke.cpp | 5 +- src/shapes/path.cpp | 10 +-- src/shapes/path_composer.cpp | 5 +- src/shapes/shape.cpp | 16 ++--- src/shapes/shape_paint_container.cpp | 6 +- 25 files changed, 174 insertions(+), 184 deletions(-) create mode 100644 include/rive/shapes/path_flags.hpp delete mode 100644 include/rive/shapes/path_space.hpp diff --git a/.rive_head b/.rive_head index 8bafa524..de25b584 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8486c344528d5f7f84de1984510064a7d0788e73 +a10b1e61edfd5a5d01801f78d9ee76a064c9c7ce diff --git a/include/rive/animation/state_machine_listener.hpp b/include/rive/animation/state_machine_listener.hpp index 244eb276..2867188b 100644 --- a/include/rive/animation/state_machine_listener.hpp +++ b/include/rive/animation/state_machine_listener.hpp @@ -14,26 +14,23 @@ class StateMachineListener : public StateMachineListenerBase { friend class StateMachineListenerImporter; -private: - std::vector m_HitShapesIds; - std::vector> m_Actions; - void addAction(std::unique_ptr); - public: StateMachineListener(); ~StateMachineListener() override; ListenerType listenerType() const { return (ListenerType)listenerTypeValue(); } - size_t actionCount() const { return m_Actions.size(); } + size_t actionCount() const { return m_actions.size(); } const ListenerAction* action(size_t index) const; StatusCode import(ImportStack& importStack) override; - StatusCode onAddedClean(CoreContext* context) override; - const std::vector& hitShapeIds() const { return m_HitShapesIds; } void performChanges(StateMachineInstance* stateMachineInstance, Vec2D position, Vec2D previousPosition) const; + +private: + void addAction(std::unique_ptr); + std::vector> m_actions; }; } // namespace rive diff --git a/include/rive/component.hpp b/include/rive/component.hpp index 0aee6eeb..7c260994 100644 --- a/include/rive/component.hpp +++ b/include/rive/component.hpp @@ -4,6 +4,7 @@ #include "rive/generated/component_base.hpp" #include +#include namespace rive { @@ -55,6 +56,8 @@ class Component : public ComponentBase { return (m_Dirt & ComponentDirt::Collapsed) == ComponentDirt::Collapsed; } + + virtual bool forAll(std::function predicate); }; } // namespace rive diff --git a/include/rive/container_component.hpp b/include/rive/container_component.hpp index f1879260..e340a17d 100644 --- a/include/rive/container_component.hpp +++ b/include/rive/container_component.hpp @@ -2,17 +2,23 @@ #define _RIVE_CONTAINER_COMPONENT_HPP_ #include "rive/generated/container_component_base.hpp" #include +#include + namespace rive { class ContainerComponent : public ContainerComponentBase { -private: - std::vector m_children; - public: const std::vector& children() const { return m_children; } virtual void addChild(Component* component); bool collapse(bool value) override; + + // Returns true if it searched through all of its children. predicate can + // return false to stop searching. + bool forAll(std::function predicate) override; + +private: + std::vector m_children; }; } // namespace rive diff --git a/include/rive/shapes/paint/fill.hpp b/include/rive/shapes/paint/fill.hpp index 97291e61..a9a0a644 100644 --- a/include/rive/shapes/paint/fill.hpp +++ b/include/rive/shapes/paint/fill.hpp @@ -1,14 +1,14 @@ #ifndef _RIVE_FILL_HPP_ #define _RIVE_FILL_HPP_ #include "rive/generated/shapes/paint/fill_base.hpp" -#include "rive/shapes/path_space.hpp" +#include "rive/shapes/path_flags.hpp" namespace rive { class Fill : public FillBase { public: RenderPaint* initRenderPaint(ShapePaintMutator* mutator) override; - PathSpace pathSpace() const override; + PathFlags pathFlags() const override; void draw(Renderer* renderer, CommandPath* path, const RawPath* rawPath, diff --git a/include/rive/shapes/paint/shape_paint.hpp b/include/rive/shapes/paint/shape_paint.hpp index 388fb134..67e9660c 100644 --- a/include/rive/shapes/paint/shape_paint.hpp +++ b/include/rive/shapes/paint/shape_paint.hpp @@ -4,7 +4,7 @@ #include "rive/renderer.hpp" #include "rive/shapes/paint/blend_mode.hpp" #include "rive/shapes/paint/shape_paint_mutator.hpp" -#include "rive/shapes/path_space.hpp" +#include "rive/shapes/path_flags.hpp" #include "rive/math/raw_path.hpp" namespace rive @@ -30,7 +30,8 @@ class ShapePaint : public ShapePaintBase /// lifecycle of the RenderPaint. virtual RenderPaint* initRenderPaint(ShapePaintMutator* mutator); - virtual PathSpace pathSpace() const = 0; + virtual PathFlags pathFlags() const = 0; + bool isFlagged(PathFlags flags) const { return (int)(pathFlags() & flags) != 0x00; } void draw(Renderer* renderer, CommandPath* path, const RawPath* rawPath = nullptr) { diff --git a/include/rive/shapes/paint/stroke.hpp b/include/rive/shapes/paint/stroke.hpp index 7663669b..99a7a0a8 100644 --- a/include/rive/shapes/paint/stroke.hpp +++ b/include/rive/shapes/paint/stroke.hpp @@ -1,7 +1,7 @@ #ifndef _RIVE_STROKE_HPP_ #define _RIVE_STROKE_HPP_ #include "rive/generated/shapes/paint/stroke_base.hpp" -#include "rive/shapes/path_space.hpp" +#include "rive/shapes/path_flags.hpp" namespace rive { class StrokeEffect; @@ -12,7 +12,7 @@ class Stroke : public StrokeBase public: RenderPaint* initRenderPaint(ShapePaintMutator* mutator) override; - PathSpace pathSpace() const override; + PathFlags pathFlags() const override; void draw(Renderer* renderer, CommandPath* path, const RawPath* rawPath, diff --git a/include/rive/shapes/path.hpp b/include/rive/shapes/path.hpp index d5ba979d..59cc59b5 100644 --- a/include/rive/shapes/path.hpp +++ b/include/rive/shapes/path.hpp @@ -40,7 +40,7 @@ class Path : public PathBase Shape* m_Shape = nullptr; std::vector m_Vertices; bool m_deferredPathDirt = false; - PathSpace m_DefaultPathSpace = PathSpace::Neither; + PathFlags m_pathFlags = PathFlags::none; RawPath m_rawPath; public: @@ -52,7 +52,9 @@ class Path : public PathBase const RawPath& rawPath() const { return m_rawPath; } void update(ComponentDirt value) override; - void addDefaultPathSpace(PathSpace space); + void addFlags(PathFlags flags); + bool isFlagged(PathFlags flags) const; + bool canDeferPathUpdate(); void addVertex(PathVertex* vertex); diff --git a/include/rive/shapes/path_flags.hpp b/include/rive/shapes/path_flags.hpp new file mode 100644 index 00000000..172ed424 --- /dev/null +++ b/include/rive/shapes/path_flags.hpp @@ -0,0 +1,66 @@ +#ifndef _RIVE_PATH_FLAGS_HPP_ +#define _RIVE_PATH_FLAGS_HPP_ + +#include "rive/rive_types.hpp" + +namespace rive +{ +enum class PathFlags : uint8_t +{ + none = 0, + local = 1 << 1, + world = 1 << 2, + clipping = 1 << 3, + followPath = 1 << 4, + neverDeferUpdate = 1 << 5, +}; + +inline constexpr PathFlags operator&(PathFlags lhs, PathFlags rhs) +{ + return static_cast(static_cast::type>(lhs) & + static_cast::type>(rhs)); +} + +inline constexpr PathFlags operator^(PathFlags lhs, PathFlags rhs) +{ + return static_cast(static_cast::type>(lhs) ^ + static_cast::type>(rhs)); +} + +inline constexpr PathFlags operator|(PathFlags lhs, PathFlags rhs) +{ + return static_cast(static_cast::type>(lhs) | + static_cast::type>(rhs)); +} + +inline constexpr PathFlags operator~(PathFlags rhs) +{ + return static_cast(~static_cast::type>(rhs)); +} + +inline PathFlags& operator|=(PathFlags& lhs, PathFlags rhs) +{ + lhs = static_cast(static_cast::type>(lhs) | + static_cast::type>(rhs)); + + return lhs; +} + +inline PathFlags& operator&=(PathFlags& lhs, PathFlags rhs) +{ + lhs = static_cast(static_cast::type>(lhs) & + static_cast::type>(rhs)); + + return lhs; +} + +inline PathFlags& operator^=(PathFlags& lhs, PathFlags rhs) +{ + lhs = static_cast(static_cast::type>(lhs) ^ + static_cast::type>(rhs)); + + return lhs; +} +} // namespace rive + +#endif diff --git a/include/rive/shapes/path_space.hpp b/include/rive/shapes/path_space.hpp deleted file mode 100644 index d44e5c74..00000000 --- a/include/rive/shapes/path_space.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _RIVE_PATH_SPACE_HPP_ -#define _RIVE_PATH_SPACE_HPP_ - -#include "rive/rive_types.hpp" - -namespace rive -{ -enum class PathSpace : unsigned char -{ - Neither = 0, - Local = 1 << 1, - World = 1 << 2, - Clipping = 1 << 3, - FollowPath = 1 << 4 -}; - -inline constexpr PathSpace operator&(PathSpace lhs, PathSpace rhs) -{ - return static_cast(static_cast::type>(lhs) & - static_cast::type>(rhs)); -} - -inline constexpr PathSpace operator^(PathSpace lhs, PathSpace rhs) -{ - return static_cast(static_cast::type>(lhs) ^ - static_cast::type>(rhs)); -} - -inline constexpr PathSpace operator|(PathSpace lhs, PathSpace rhs) -{ - return static_cast(static_cast::type>(lhs) | - static_cast::type>(rhs)); -} - -inline constexpr PathSpace operator~(PathSpace rhs) -{ - return static_cast(~static_cast::type>(rhs)); -} - -inline PathSpace& operator|=(PathSpace& lhs, PathSpace rhs) -{ - lhs = static_cast(static_cast::type>(lhs) | - static_cast::type>(rhs)); - - return lhs; -} - -inline PathSpace& operator&=(PathSpace& lhs, PathSpace rhs) -{ - lhs = static_cast(static_cast::type>(lhs) & - static_cast::type>(rhs)); - - return lhs; -} - -inline PathSpace& operator^=(PathSpace& lhs, PathSpace rhs) -{ - lhs = static_cast(static_cast::type>(lhs) ^ - static_cast::type>(rhs)); - - return lhs; -} -} // namespace rive - -#endif diff --git a/include/rive/shapes/shape.hpp b/include/rive/shapes/shape.hpp index 587d4aa3..e55f7946 100644 --- a/include/rive/shapes/shape.hpp +++ b/include/rive/shapes/shape.hpp @@ -44,7 +44,8 @@ class Shape : public ShapeBase, public ShapePaintContainer PathComposer* pathComposer() { return &m_PathComposer; } void pathChanged(); - void addDefaultPathSpace(PathSpace space); + void addFlags(PathFlags flags); + bool isFlagged(PathFlags flags) const; StatusCode onAddedDirty(CoreContext* context) override; bool isEmpty(); void pathCollapseChanged(); diff --git a/include/rive/shapes/shape_paint_container.hpp b/include/rive/shapes/shape_paint_container.hpp index 7ba4d766..8d394ce8 100644 --- a/include/rive/shapes/shape_paint_container.hpp +++ b/include/rive/shapes/shape_paint_container.hpp @@ -1,7 +1,7 @@ #ifndef _RIVE_SHAPE_PAINT_CONTAINER_HPP_ #define _RIVE_SHAPE_PAINT_CONTAINER_HPP_ #include "rive/refcnt.hpp" -#include "rive/shapes/path_space.hpp" +#include "rive/shapes/path_flags.hpp" #include namespace rive @@ -21,7 +21,7 @@ class ShapePaintContainer // as a Shape or Artboard, so both of those will override this. virtual Artboard* getArtboard() = 0; - PathSpace m_DefaultPathSpace = PathSpace::Neither; + PathFlags m_pathFlags = PathFlags::none; std::vector m_ShapePaints; void addPaint(ShapePaint* paint); @@ -31,7 +31,7 @@ class ShapePaintContainer virtual ~ShapePaintContainer() {} - PathSpace pathSpace() const; + PathFlags pathFlags() const; void invalidateStrokeEffects(); diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index dd3f7858..11225a19 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -631,37 +631,33 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, // Initialize listeners. Store a lookup table of shape id to hit shape // representation (an object that stores all the listeners triggered by the // shape producing a listener). - std::unordered_map hitShapeLookup; + std::unordered_map hitShapeLookup; for (std::size_t i = 0; i < machine->listenerCount(); i++) { auto listener = machine->listener(i); - - // Iterate actual leaf hittable shapes tied to this listener and resolve - // corresponding ones in the artboard instance. - for (auto id : listener->hitShapeIds()) + auto target = m_artboardInstance->resolve(listener->targetId()); + if (target != nullptr && target->is()) { - HitShape* hitShape; - auto itr = hitShapeLookup.find(id); - if (itr == hitShapeLookup.end()) - { - auto shape = m_artboardInstance->resolve(id); - if (shape != nullptr && shape->is()) + target->as()->forAll([&](Component* component) { + if (component->is()) { - auto hs = rivestd::make_unique(shape->as(), this); - hitShapeLookup[id] = hitShape = hs.get(); - m_hitComponents.push_back(std::move(hs)); - } - else - { - // No object or not a shape... - continue; + HitShape* hitShape; + auto itr = hitShapeLookup.find(component); + if (itr == hitShapeLookup.end()) + { + component->as()->addFlags(PathFlags::neverDeferUpdate); + auto hs = rivestd::make_unique(component, this); + hitShapeLookup[component] = hitShape = hs.get(); + m_hitComponents.push_back(std::move(hs)); + } + else + { + hitShape = itr->second; + } + hitShape->listeners.push_back(listener); } - } - else - { - hitShape = itr->second; - } - hitShape->listeners.push_back(listener); + return true; + }); } } @@ -669,7 +665,6 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, { if (nestedArtboard->hasNestedStateMachines()) { - auto hn = rivestd::make_unique(nestedArtboard->as(), this); m_hitComponents.push_back(std::move(hn)); diff --git a/src/animation/state_machine_listener.cpp b/src/animation/state_machine_listener.cpp index f943f828..7abf5215 100644 --- a/src/animation/state_machine_listener.cpp +++ b/src/animation/state_machine_listener.cpp @@ -14,7 +14,7 @@ StateMachineListener::~StateMachineListener() {} void StateMachineListener::addAction(std::unique_ptr action) { - m_Actions.push_back(std::move(action)); + m_actions.push_back(std::move(action)); } StatusCode StateMachineListener::import(ImportStack& importStack) @@ -31,54 +31,18 @@ StatusCode StateMachineListener::import(ImportStack& importStack) const ListenerAction* StateMachineListener::action(size_t index) const { - if (index < m_Actions.size()) + if (index < m_actions.size()) { - return m_Actions[index].get(); + return m_actions[index].get(); } return nullptr; } -StatusCode StateMachineListener::onAddedClean(CoreContext* context) -{ - auto artboard = static_cast(context); - auto target = artboard->resolve(targetId()); - - for (auto core : artboard->objects()) - { - if (core == nullptr) - { - continue; - } - - // Iterate artboard to find Shapes that are parented to the target - if (core->is()) - { - auto shape = core->as(); - - for (ContainerComponent* component = shape; component != nullptr; - component = component->parent()) - { - if (component == target) - { - auto index = artboard->idOf(shape); - if (index != 0) - { - m_HitShapesIds.push_back(index); - } - break; - } - } - } - } - - return Super::onAddedClean(context); -} - void StateMachineListener::performChanges(StateMachineInstance* stateMachineInstance, Vec2D position, Vec2D previousPosition) const { - for (auto& action : m_Actions) + for (auto& action : m_actions) { action->perform(stateMachineInstance, position, previousPosition); } diff --git a/src/component.cpp b/src/component.cpp index b68ffdfd..eaf7003b 100644 --- a/src/component.cpp +++ b/src/component.cpp @@ -99,4 +99,6 @@ bool Component::collapse(bool value) onDirty(m_Dirt); m_Artboard->onComponentDirty(this); return true; -} \ No newline at end of file +} + +bool Component::forAll(std::function predicate) { return predicate(this); } \ No newline at end of file diff --git a/src/constraints/follow_path_constraint.cpp b/src/constraints/follow_path_constraint.cpp index 199a0db4..8c74d9a5 100644 --- a/src/constraints/follow_path_constraint.cpp +++ b/src/constraints/follow_path_constraint.cpp @@ -167,12 +167,12 @@ StatusCode FollowPathConstraint::onAddedClean(CoreContext* context) if (m_Target->is()) { Shape* shape = static_cast(m_Target); - shape->addDefaultPathSpace(PathSpace::FollowPath); + shape->addFlags(PathFlags::followPath); } else if (m_Target->is()) { Path* path = static_cast(m_Target); - path->addDefaultPathSpace(PathSpace::FollowPath); + path->addFlags(PathFlags::followPath); } } return Super::onAddedClean(context); diff --git a/src/container_component.cpp b/src/container_component.cpp index 0a252609..af033486 100644 --- a/src/container_component.cpp +++ b/src/container_component.cpp @@ -14,4 +14,24 @@ bool ContainerComponent::collapse(bool value) child->collapse(value); } return true; +} + +bool ContainerComponent::forAll(std::function predicate) +{ + if (!Super::forAll(predicate)) + { + return false; + } + for (Component* child : m_children) + { + if (!predicate(child)) + { + return false; + } + if (child->is() && !child->as()->forAll(predicate)) + { + return false; + } + } + return true; } \ No newline at end of file diff --git a/src/shapes/clipping_shape.cpp b/src/shapes/clipping_shape.cpp index cfa7f902..e795a6ce 100644 --- a/src/shapes/clipping_shape.cpp +++ b/src/shapes/clipping_shape.cpp @@ -47,7 +47,7 @@ StatusCode ClippingShape::onAddedClean(CoreContext* context) if (component == m_Source) { auto shape = core->as(); - shape->addDefaultPathSpace(PathSpace::World | PathSpace::Clipping); + shape->addFlags(PathFlags::world | PathFlags::clipping); m_Shapes.push_back(shape); break; } diff --git a/src/shapes/paint/fill.cpp b/src/shapes/paint/fill.cpp index 466b61a7..d0af7ef1 100644 --- a/src/shapes/paint/fill.cpp +++ b/src/shapes/paint/fill.cpp @@ -2,7 +2,7 @@ using namespace rive; -PathSpace Fill::pathSpace() const { return PathSpace::Local; } +PathFlags Fill::pathFlags() const { return PathFlags::local; } RenderPaint* Fill::initRenderPaint(ShapePaintMutator* mutator) { diff --git a/src/shapes/paint/linear_gradient.cpp b/src/shapes/paint/linear_gradient.cpp index aa49c945..0bcc1c6a 100644 --- a/src/shapes/paint/linear_gradient.cpp +++ b/src/shapes/paint/linear_gradient.cpp @@ -84,7 +84,7 @@ void LinearGradient::update(ComponentDirt value) ComponentDirt::Paint | ComponentDirt::RenderOpacity | ComponentDirt::Transform) || ( // paints in world space - parent()->as()->pathSpace() == PathSpace::World && + parent()->as()->isFlagged(PathFlags::world) && // and had a world transform change hasDirt(value, ComponentDirt::WorldTransform)); if (rebuildGradient) @@ -95,7 +95,7 @@ void LinearGradient::update(ComponentDirt value) void LinearGradient::applyTo(RenderPaint* renderPaint, float opacityModifier) const { - bool paintsInWorldSpace = parent()->as()->pathSpace() == PathSpace::World; + bool paintsInWorldSpace = parent()->as()->isFlagged(PathFlags::world); Vec2D start(startX(), startY()); Vec2D end(endX(), endY()); // Check if we need to update the world space gradient (if there's no diff --git a/src/shapes/paint/stroke.cpp b/src/shapes/paint/stroke.cpp index b0d7348b..a76adaee 100644 --- a/src/shapes/paint/stroke.cpp +++ b/src/shapes/paint/stroke.cpp @@ -6,11 +6,10 @@ using namespace rive; -PathSpace Stroke::pathSpace() const +PathFlags Stroke::pathFlags() const { - return transformAffectsStroke() ? PathSpace::Local : PathSpace::World; + return transformAffectsStroke() ? PathFlags::local : PathFlags::world; } - RenderPaint* Stroke::initRenderPaint(ShapePaintMutator* mutator) { auto renderPaint = Super::initRenderPaint(mutator); diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp index cdf45aa2..fd5af983 100644 --- a/src/shapes/path.cpp +++ b/src/shapes/path.cpp @@ -51,7 +51,8 @@ void Path::buildDependencies() { Super::buildDependencies(); } void Path::addVertex(PathVertex* vertex) { m_Vertices.push_back(vertex); } -void Path::addDefaultPathSpace(PathSpace space) { m_DefaultPathSpace |= space; } +void Path::addFlags(PathFlags flags) { m_pathFlags |= flags; } +bool Path::isFlagged(PathFlags flags) const { return (int)(m_pathFlags & flags) != 0x00; } bool Path::canDeferPathUpdate() { @@ -60,10 +61,9 @@ bool Path::canDeferPathUpdate() // (meaning all child paths need to follow path). This doesn't mean the // Shape is necessarily forced to update put the paths are, which is why we // explicitly also check the shape's path space. - return m_Shape->canDeferPathUpdate() && - (m_Shape->pathSpace() & PathSpace::FollowPath) != PathSpace::FollowPath && - ((m_DefaultPathSpace & PathSpace::Clipping) != PathSpace::Clipping) && - ((m_DefaultPathSpace & PathSpace::FollowPath) != PathSpace::FollowPath); + + return m_Shape->canDeferPathUpdate() && !m_Shape->isFlagged(PathFlags::followPath) && + !isFlagged(PathFlags::followPath | PathFlags::clipping); } const Mat2D& Path::pathTransform() const { return worldTransform(); } diff --git a/src/shapes/path_composer.cpp b/src/shapes/path_composer.cpp index 71a4c00e..5efda247 100644 --- a/src/shapes/path_composer.cpp +++ b/src/shapes/path_composer.cpp @@ -41,8 +41,7 @@ void PathComposer::update(ComponentDirt value) } m_deferredPathDirt = false; - auto space = m_shape->pathSpace(); - if ((space & PathSpace::Local) == PathSpace::Local) + if (m_shape->isFlagged(PathFlags::local)) { if (m_localPath == nullptr) { @@ -68,7 +67,7 @@ void PathComposer::update(ComponentDirt value) // TODO: add a CommandPath::copy(RawPath) m_localRawPath.addTo(m_localPath.get()); } - if ((space & PathSpace::World) == PathSpace::World) + if (m_shape->isFlagged(PathFlags::world)) { if (m_worldPath == nullptr) { diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index 01310ed4..6a22160a 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -22,10 +22,13 @@ void Shape::addPath(Path* path) m_Paths.push_back(path); } +void Shape::addFlags(PathFlags flags) { m_pathFlags |= flags; } +bool Shape::isFlagged(PathFlags flags) const { return (int)(pathFlags() & flags) != 0x00; } + bool Shape::canDeferPathUpdate() { auto canDefer = - renderOpacity() == 0 && (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping; + renderOpacity() == 0 && !isFlagged(PathFlags::clipping | PathFlags::neverDeferUpdate); if (canDefer) { // If we have a dependent Skin, don't defer the update @@ -72,8 +75,7 @@ void Shape::pathChanged() void Shape::addToRenderPath(RenderPath* path, const Mat2D& transform) { - auto space = pathSpace(); - if ((space & PathSpace::Local) == PathSpace::Local) + if (isFlagged(PathFlags::local)) { path->addPath(m_PathComposer.localPath(), transform * worldTransform()); } @@ -100,7 +102,7 @@ void Shape::draw(Renderer* renderer) continue; } renderer->save(); - bool paintsInLocal = (shapePaint->pathSpace() & PathSpace::Local) == PathSpace::Local; + bool paintsInLocal = shapePaint->isFlagged(PathFlags::local); if (paintsInLocal) { renderer->transform(worldTransform()); @@ -143,7 +145,7 @@ Core* Shape::hitTest(HitInfo* hinfo, const Mat2D& xform) // TODO: clip: - const bool shapeIsLocal = (pathSpace() & PathSpace::Local) == PathSpace::Local; + const bool shapeIsLocal = isFlagged(PathFlags::local); for (auto rit = m_ShapePaints.rbegin(); rit != m_ShapePaints.rend(); ++rit) { @@ -157,7 +159,7 @@ Core* Shape::hitTest(HitInfo* hinfo, const Mat2D& xform) continue; } - auto paintIsLocal = (shapePaint->pathSpace() & PathSpace::Local) == PathSpace::Local; + auto paintIsLocal = shapePaint->isFlagged(PathFlags::local); auto mx = xform; if (paintIsLocal) @@ -204,8 +206,6 @@ void Shape::buildDependencies() } } -void Shape::addDefaultPathSpace(PathSpace space) { m_DefaultPathSpace |= space; } - StatusCode Shape::onAddedDirty(CoreContext* context) { auto code = Super::onAddedDirty(context); diff --git a/src/shapes/shape_paint_container.cpp b/src/shapes/shape_paint_container.cpp index ab9057a1..37e58538 100644 --- a/src/shapes/shape_paint_container.cpp +++ b/src/shapes/shape_paint_container.cpp @@ -24,12 +24,12 @@ ShapePaintContainer* ShapePaintContainer::from(Component* component) void ShapePaintContainer::addPaint(ShapePaint* paint) { m_ShapePaints.push_back(paint); } -PathSpace ShapePaintContainer::pathSpace() const +PathFlags ShapePaintContainer::pathFlags() const { - PathSpace space = m_DefaultPathSpace; + PathFlags space = m_pathFlags; for (auto paint : m_ShapePaints) { - space |= paint->pathSpace(); + space |= paint->pathFlags(); } return space; } From 5fbbf5f874fe3aba0203ad2d9b0368e966ebf9c4 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Sat, 8 Jun 2024 02:54:58 +0000 Subject: [PATCH 060/138] mark shape as dirty after flagged as target Diffs= b88272290 mark shape as dirty after flagged as target (#7396) Co-authored-by: hernan --- .rive_head | 2 +- src/animation/state_machine_instance.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index de25b584..f3c7912e 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a10b1e61edfd5a5d01801f78d9ee76a064c9c7ce +b88272290c7d45f1be5b4b7403707c0f1bc9384f diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 11225a19..1f0b0a2a 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -646,6 +646,7 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, if (itr == hitShapeLookup.end()) { component->as()->addFlags(PathFlags::neverDeferUpdate); + component->as()->addDirt(ComponentDirt::Path, true); auto hs = rivestd::make_unique(component, this); hitShapeLookup[component] = hitShape = hs.get(); m_hitComponents.push_back(std::move(hs)); From 7101954caa84c950c0c6a7951964a71d1fe33095 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Mon, 10 Jun 2024 23:48:38 +0000 Subject: [PATCH 061/138] more renames for harfbuzz Caught this when working on the JUCE integration. Some harfbuzz renames we missed that cause linking problems on apps that use newer versions of harfbuzz. Diffs= 34e186b32 more renames for harfbuzz (#7398) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- dependencies/rive_harfbuzz_renames.h | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index f3c7912e..00cccbb2 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -b88272290c7d45f1be5b4b7403707c0f1bc9384f +34e186b32dbb956a36807635ea16fe039f988333 diff --git a/dependencies/rive_harfbuzz_renames.h b/dependencies/rive_harfbuzz_renames.h index 80b66c8b..bb8ea909 100644 --- a/dependencies/rive_harfbuzz_renames.h +++ b/dependencies/rive_harfbuzz_renames.h @@ -76,6 +76,8 @@ #define hb_face_t rive_hb_face_t #define hb_table_lazy_loader_t rive_hb_table_lazy_loader_t #define hb_blob_t rive_hb_blob_t +#define glyf_accelerator_t rive_glyf_accelerator_t +#define OT rive_OT #define hb_nonnull_ptr_t rive_hb_nonnull_ptr_t #define hb_atomic_short_t rive_hb_atomic_short_t #define hb_segment_properties_t rive_hb_segment_properties_t @@ -312,9 +314,19 @@ #define hb_syllabic_clear_var rive_hb_syllabic_clear_var #define hb_syllabic_insert_dotted_circles rive_hb_syllabic_insert_dotted_circles #define hb_options rive_hb_options +#define hb_options_initv rive_hb_options_initv +#define minus_1 rive_minus_1 +#define hb_aat_apply_context_t rive_hb_aat_apply_context_t +#define _hb_unicode_is_emoji_Extended_Pictographic rive__hb_unicode_is_emoji_Extended_Pictographic +#define endchar_str rive_endchar_str +#define _hb_ot_name_language_for_mac_code rive__hb_ot_name_language_for_mac_code +#define _hb_ot_name_language_for_ms_code rive__hb_ot_name_language_for_ms_code #define hb_indic_would_substitute_feature_t rive_hb_indic_would_substitute_feature_t #define hb_ot_layout_glyph_props_flags_t rive_hb_ot_layout_glyph_props_flags_t #define hb_use_u16 rive_hb_use_u16 +#define lookup_expert_subset_charset_for_glyph rive_lookup_expert_subset_charset_for_glyph +#define lookup_expert_charset_for_glyph rive_lookup_expert_charset_for_glyph +#define _hb_options_init rive__hb_options_init #define hb_use_get_category rive_hb_use_get_category #define hb_use_b4 rive_hb_use_b4 #define hb_use_u8 rive_hb_use_u8 From 3bba1c9384cc53bb3080723e206d8ec3ede9a2d0 Mon Sep 17 00:00:00 2001 From: philter Date: Tue, 11 Jun 2024 04:11:25 +0000 Subject: [PATCH 062/138] Nested linear animations report events up to parent artboards Previously, only nested state machines could report events so that listeners in parent artboards could listen for them. This PR adds event reporting for nested simple animations. Had to refactor some stuff to genericize in order for both state machines and linear animations to have similar functionality. I'm not sure if its possible, or desirable, for nested remap animations to have the same functionality, but that is not included in this PR. Diffs= 097b68f56 Nested linear animations report events up to parent artboards (#7310) Co-authored-by: Philip Chung --- .rive_head | 2 +- .../animation/linear_animation_instance.hpp | 5 +- .../animation/nested_linear_animation.hpp | 1 + .../rive/animation/state_machine_instance.hpp | 19 +++----- include/rive/event_report.hpp | 21 ++++++++ include/rive/nested_animation.hpp | 48 +++++++++++++++++++ src/animation/linear_animation_instance.cpp | 6 +++ src/animation/nested_simple_animation.cpp | 3 +- src/animation/state_machine_instance.cpp | 38 ++++++++++----- 9 files changed, 114 insertions(+), 29 deletions(-) create mode 100644 include/rive/event_report.hpp diff --git a/.rive_head b/.rive_head index 00cccbb2..918acd82 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -34e186b32dbb956a36807635ea16fe039f988333 +097b68f5616951d83b0c5b28345e6bfc9f0b1a5b diff --git a/include/rive/animation/linear_animation_instance.hpp b/include/rive/animation/linear_animation_instance.hpp index 316b0c7c..d04d5964 100644 --- a/include/rive/animation/linear_animation_instance.hpp +++ b/include/rive/animation/linear_animation_instance.hpp @@ -3,13 +3,15 @@ #include "rive/artboard.hpp" #include "rive/core/field_types/core_callback_type.hpp" +#include "rive/nested_animation.hpp" #include "rive/scene.hpp" namespace rive { class LinearAnimation; +class NestedEventNotifier; -class LinearAnimationInstance : public Scene +class LinearAnimationInstance : public Scene, public NestedEventNotifier { public: LinearAnimationInstance(const LinearAnimation*, ArtboardInstance*, float speedMultiplier = 1.0); @@ -97,6 +99,7 @@ class LinearAnimationInstance : public Scene bool advanceAndApply(float seconds) override; std::string name() const override; void reset(float speedMultiplier); + void reportEvent(Event* event, float secondsDelay = 0.0f) override; private: const LinearAnimation* m_animation = nullptr; diff --git a/include/rive/animation/nested_linear_animation.hpp b/include/rive/animation/nested_linear_animation.hpp index 7de512c8..6d307270 100644 --- a/include/rive/animation/nested_linear_animation.hpp +++ b/include/rive/animation/nested_linear_animation.hpp @@ -15,6 +15,7 @@ class NestedLinearAnimation : public NestedLinearAnimationBase ~NestedLinearAnimation() override; void initializeAnimation(ArtboardInstance*) override; + LinearAnimationInstance* animationInstance() { return m_AnimationInstance.get(); } }; } // namespace rive diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 4618a82f..13e37407 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -10,6 +10,7 @@ #include "rive/core/field_types/core_callback_type.hpp" #include "rive/hit_result.hpp" #include "rive/listener_type.hpp" +#include "rive/nested_animation.hpp" #include "rive/scene.hpp" namespace rive @@ -25,22 +26,13 @@ class Shape; class StateMachineLayerInstance; class HitComponent; class NestedArtboard; +class NestedEventListener; +class NestedEventNotifier; class Event; +class EventReport; class KeyedProperty; -class EventReport -{ -public: - EventReport(Event* event, float secondsDelay) : m_event(event), m_secondsDelay(secondsDelay) {} - Event* event() const { return m_event; } - float secondsDelay() const { return m_secondsDelay; } - -private: - Event* m_event; - float m_secondsDelay; -}; - -class StateMachineInstance : public Scene +class StateMachineInstance : public Scene, public NestedEventNotifier, public NestedEventListener { friend class SMIInput; friend class KeyedProperty; @@ -117,6 +109,7 @@ class StateMachineInstance : public Scene void setParentNestedArtboard(NestedArtboard* artboard) { m_parentNestedArtboard = artboard; } NestedArtboard* parentNestedArtboard() { return m_parentNestedArtboard; } + void notify(const std::vector& events, NestedArtboard* context) override; /// Tracks an event that reported, will be cleared at the end of the next advance. void reportEvent(Event* event, float secondsDelay = 0.0f) override; diff --git a/include/rive/event_report.hpp b/include/rive/event_report.hpp new file mode 100644 index 00000000..fe56315e --- /dev/null +++ b/include/rive/event_report.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_EVENT_REPORT_HPP_ +#define _RIVE_EVENT_REPORT_HPP_ + +namespace rive +{ +class Event; + +class EventReport +{ +public: + EventReport(Event* event, float secondsDelay) : m_event(event), m_secondsDelay(secondsDelay) {} + Event* event() const { return m_event; } + float secondsDelay() const { return m_secondsDelay; } + +private: + Event* m_event; + float m_secondsDelay; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/nested_animation.hpp b/include/rive/nested_animation.hpp index 843739e8..fc31df6c 100644 --- a/include/rive/nested_animation.hpp +++ b/include/rive/nested_animation.hpp @@ -1,11 +1,59 @@ #ifndef _RIVE_NESTED_ANIMATION_HPP_ #define _RIVE_NESTED_ANIMATION_HPP_ +#include "rive/event.hpp" +#include "rive/event_report.hpp" #include "rive/generated/nested_animation_base.hpp" +#include "rive/nested_artboard.hpp" #include namespace rive { class ArtboardInstance; +class NestedEventListener +{ +public: + virtual ~NestedEventListener() {} + virtual void notify(const std::vector& events, NestedArtboard* context) = 0; +}; + +class NestedEventNotifier +{ +public: + ~NestedEventNotifier() + { + m_nestedArtboard = nullptr; + m_nestedEventListeners.clear(); + } + void addNestedEventListener(NestedEventListener* listener) + { + m_nestedEventListeners.push_back(listener); + } + std::vector nestedEventListeners() { return m_nestedEventListeners; } + + void setNestedArtboard(NestedArtboard* artboard) { m_nestedArtboard = artboard; } + NestedArtboard* nestedArtboard() { return m_nestedArtboard; } + + void notifyListeners(const std::vector& events) + { + if (m_nestedArtboard != nullptr) + { + std::vector eventReports; + for (auto event : events) + { + eventReports.push_back(EventReport(event, 0)); + } + for (auto listener : m_nestedEventListeners) + { + listener->notify(eventReports, m_nestedArtboard); + } + } + } + +private: + NestedArtboard* m_nestedArtboard; + std::vector m_nestedEventListeners; +}; + class NestedAnimation : public NestedAnimationBase { public: diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp index f40f8afe..1399912c 100644 --- a/src/animation/linear_animation_instance.cpp +++ b/src/animation/linear_animation_instance.cpp @@ -245,3 +245,9 @@ void LinearAnimationInstance::loopValue(int value) } float LinearAnimationInstance::durationSeconds() const { return m_animation->durationSeconds(); } + +void LinearAnimationInstance::reportEvent(Event* event, float secondsDelay) +{ + const std::vector events{event}; + notifyListeners(events); +} \ No newline at end of file diff --git a/src/animation/nested_simple_animation.cpp b/src/animation/nested_simple_animation.cpp index dd6bb6e2..c747fd29 100644 --- a/src/animation/nested_simple_animation.cpp +++ b/src/animation/nested_simple_animation.cpp @@ -10,7 +10,8 @@ bool NestedSimpleAnimation::advance(float elapsedSeconds) { if (isPlaying()) { - keepGoing = m_AnimationInstance->advance(elapsedSeconds * speed()); + keepGoing = + m_AnimationInstance->advance(elapsedSeconds * speed(), m_AnimationInstance.get()); } if (mix() != 0.0f) { diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 1f0b0a2a..e70d4f40 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -4,6 +4,7 @@ #include "rive/animation/cubic_interpolator.hpp" #include "rive/animation/entry_state.hpp" #include "rive/animation/layer_state_flags.hpp" +#include "rive/animation/nested_linear_animation.hpp" #include "rive/animation/nested_state_machine.hpp" #include "rive/animation/state_instance.hpp" #include "rive/animation/state_machine_bool.hpp" @@ -18,6 +19,7 @@ #include "rive/animation/state_transition.hpp" #include "rive/animation/transition_condition.hpp" #include "rive/animation/state_machine_fire_event.hpp" +#include "rive/event_report.hpp" #include "rive/hit_result.hpp" #include "rive/math/aabb.hpp" #include "rive/math/hit_test.hpp" @@ -669,18 +671,20 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, auto hn = rivestd::make_unique(nestedArtboard->as(), this); m_hitComponents.push_back(std::move(hn)); - - for (auto animation : nestedArtboard->nestedAnimations()) + } + for (auto animation : nestedArtboard->nestedAnimations()) + { + if (animation->is()) { - if (animation->is()) - { - animation->as() - ->stateMachineInstance() - ->setParentNestedArtboard(nestedArtboard); - animation->as() - ->stateMachineInstance() - ->setParentStateMachineInstance(this); - } + auto notifier = animation->as()->stateMachineInstance(); + notifier->setNestedArtboard(nestedArtboard); + notifier->addNestedEventListener(this); + } + else if (animation->is()) + { + auto notifier = animation->as()->animationInstance(); + notifier->setNestedArtboard(nestedArtboard); + notifier->addNestedEventListener(this); } } } @@ -880,6 +884,11 @@ const EventReport StateMachineInstance::reportedEventAt(std::size_t index) const return m_reportedEvents[index]; } +void StateMachineInstance::notify(const std::vector& events, NestedArtboard* context) +{ + notifyEventListeners(events, context); +} + void StateMachineInstance::notifyEventListeners(const std::vector& events, NestedArtboard* source) { @@ -920,9 +929,12 @@ void StateMachineInstance::notifyEventListeners(const std::vector& } } // Bubble the event up to parent artboard state machines immediately - if (m_parentStateMachineInstance != nullptr) + if (nestedArtboard() != nullptr) { - m_parentStateMachineInstance->notifyEventListeners(events, m_parentNestedArtboard); + for (auto listener : nestedEventListeners()) + { + listener->notify(events, nestedArtboard()); + } } for (auto report : events) From c134293d05f3fc593daf8042ab569f7ad25c70af Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 11 Jun 2024 16:03:05 +0000 Subject: [PATCH 063/138] Yoga layout runtimes Starting to implement layout component with Yoga in CPP. Layouts works on iOS, macOS, Android and web runtimes. https://github.com/rive-app/rive/assets/186340/e09e639a-d38e-46b8-951d-a5ecc392b53a Diffs= 6c76b425f Yoga layout runtimes (#6787) Co-authored-by: Luigi Rosso Co-authored-by: Philip Chung --- .rive_head | 2 +- build.sh | 4 +- build/premake5.lua | 13 + dependencies/premake5_yoga.lua | 138 ++++ dependencies/premake5_yoga_v2.lua | 28 + dev/defs/artboard.json | 29 +- dev/defs/layout/layout_component_style.json | 307 +++++++++ dev/defs/layout_component.json | 50 ++ dev/defs/layout_component_absolute.json | 19 + dev/defs/nested_artboard.json | 16 + dev/test.sh | 2 +- dev/test/premake5.lua | 4 + include/rive/artboard.hpp | 31 + include/rive/bounds_provider.hpp | 17 + include/rive/generated/artboard_base.hpp | 66 +- include/rive/generated/core_registry.hpp | 315 +++++++++- .../layout/layout_component_style_base.hpp | 594 ++++++++++++++++++ .../layout_component_absolute_base.hpp | 39 ++ .../rive/generated/layout_component_base.hpp | 129 ++++ .../rive/generated/nested_artboard_base.hpp | 36 ++ .../rive/layout/layout_component_style.hpp | 134 ++++ include/rive/layout_component.hpp | 94 +++ include/rive/layout_component_absolute.hpp | 13 + include/rive/math/bit_field_loc.hpp | 28 + include/rive/nested_artboard.hpp | 38 ++ include/rive/shapes/image.hpp | 2 + include/rive/shapes/parametric_path.hpp | 5 + include/rive/text/text.hpp | 15 +- include/rive/transform_component.hpp | 4 + premake5_v2.lua | 13 + src/artboard.cpp | 20 + .../layout/layout_component_style_base.cpp | 11 + .../layout_component_absolute_base.cpp | 11 + src/generated/layout_component_base.cpp | 11 + src/layout/layout_component_style.cpp | 203 ++++++ src/layout_component.cpp | 278 ++++++++ src/math/bit_field_loc.cpp | 20 + src/nested_artboard.cpp | 15 + src/shapes/image.cpp | 15 + src/shapes/parametric_path.cpp | 13 + src/text/text.cpp | 126 +++- tess/build/premake5_tess.lua | 6 +- test/assets/layout/layout_center.riv | Bin 0 -> 220 bytes test/assets/layout/layout_horizontal.riv | Bin 0 -> 361 bytes test/assets/layout/layout_horizontal_gaps.riv | Bin 0 -> 374 bytes test/assets/layout/layout_horizontal_wrap.riv | Bin 0 -> 605 bytes test/assets/layout/layout_vertical.riv | Bin 0 -> 369 bytes test/layout_test.cpp | 123 ++++ viewer/build/macosx/build_viewer.sh | 2 +- viewer/build/premake5_viewer.lua | 5 +- 50 files changed, 2906 insertions(+), 138 deletions(-) create mode 100644 dependencies/premake5_yoga.lua create mode 100644 dependencies/premake5_yoga_v2.lua create mode 100644 dev/defs/layout/layout_component_style.json create mode 100644 dev/defs/layout_component.json create mode 100644 dev/defs/layout_component_absolute.json create mode 100644 include/rive/bounds_provider.hpp create mode 100644 include/rive/generated/layout/layout_component_style_base.hpp create mode 100644 include/rive/generated/layout_component_absolute_base.hpp create mode 100644 include/rive/generated/layout_component_base.hpp create mode 100644 include/rive/layout/layout_component_style.hpp create mode 100644 include/rive/layout_component.hpp create mode 100644 include/rive/layout_component_absolute.hpp create mode 100644 include/rive/math/bit_field_loc.hpp create mode 100644 src/generated/layout/layout_component_style_base.cpp create mode 100644 src/generated/layout_component_absolute_base.cpp create mode 100644 src/generated/layout_component_base.cpp create mode 100644 src/layout/layout_component_style.cpp create mode 100644 src/layout_component.cpp create mode 100644 src/math/bit_field_loc.cpp create mode 100644 test/assets/layout/layout_center.riv create mode 100644 test/assets/layout/layout_horizontal.riv create mode 100644 test/assets/layout/layout_horizontal_gaps.riv create mode 100644 test/assets/layout/layout_horizontal_wrap.riv create mode 100644 test/assets/layout/layout_vertical.riv create mode 100644 test/layout_test.cpp diff --git a/.rive_head b/.rive_head index 918acd82..499eaf14 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -097b68f5616951d83b0c5b28345e6bfc9f0b1a5b +6c76b425f887a8adb3beb8ba8263200b9cdbb2c9 diff --git a/build.sh b/build.sh index ec40d626..e89795d5 100755 --- a/build.sh +++ b/build.sh @@ -32,8 +32,8 @@ if [ "$OPTION" = 'help' ]; then else build() { echo "Building Rive for platform=$platform option=$OPTION" - echo premake5 gmake2 --with_rive_text --with_rive_audio=system "$1" - PREMAKE="premake5 gmake2 --with_rive_text --with_rive_audio=system $1" + echo premake5 gmake2 --with_rive_text --with_rive_audio=system --with_rive_layout "$1" + PREMAKE="premake5 gmake2 --with_rive_text --with_rive_audio=system --with_rive_layout $1" eval "$PREMAKE" if [ "$OPTION" = "clean" ]; then make clean diff --git a/build/premake5.lua b/build/premake5.lua index dfe2dd1c..576761c5 100644 --- a/build/premake5.lua +++ b/build/premake5.lua @@ -25,11 +25,16 @@ do 'MA_NO_RESOURCE_MANAGER', }) end +filter({ 'options:with_rive_layout' }) +do + defines({ 'WITH_RIVE_LAYOUT' }) +end filter({}) dofile(path.join(path.getabsolute('../dependencies/'), 'premake5_harfbuzz.lua')) dofile(path.join(path.getabsolute('../dependencies/'), 'premake5_sheenbidi.lua')) dofile(path.join(path.getabsolute('../dependencies/'), 'premake5_miniaudio.lua')) +dofile(path.join(path.getabsolute('../dependencies/'), 'premake5_yoga.lua')) project('rive') do @@ -43,8 +48,11 @@ do harfbuzz .. '/src', sheenbidi .. '/Headers', miniaudio, + yoga }) + defines({ 'YOGA_EXPORT=' }) + files({ '../src/**.cpp' }) flags({ 'FatalCompileWarnings' }) @@ -205,3 +213,8 @@ newoption({ description = 'The audio mode to use.', allowed = { { 'disabled' }, { 'system' }, { 'external' } }, }) + +newoption({ + trigger = 'with_rive_layout', + description = 'Compiles in layout features.', +}) \ No newline at end of file diff --git a/dependencies/premake5_yoga.lua b/dependencies/premake5_yoga.lua new file mode 100644 index 00000000..d4149e71 --- /dev/null +++ b/dependencies/premake5_yoga.lua @@ -0,0 +1,138 @@ +local dependency = require('dependency') +yoga = dependency.github('rive-app/yoga', 'rive_changes_v2_0_1') + +workspace('rive') +configurations({ 'debug', 'release' }) + +project('rive_yoga') +do + kind('StaticLib') + language('C++') + cppdialect('C++11') + targetdir('%{cfg.system}/cache/bin/%{cfg.buildcfg}/') + objdir('%{cfg.system}/cache/obj/%{cfg.buildcfg}/') + warnings('Off') + + defines({ 'YOGA_EXPORT=' }) + + includedirs({ yoga }) + + files({ + yoga .. '/yoga/Utils.cpp', + yoga .. '/yoga/YGConfig.cpp', + yoga .. '/yoga/YGLayout.cpp', + yoga .. '/yoga/YGEnums.cpp', + yoga .. '/yoga/YGNodePrint.cpp', + yoga .. '/yoga/YGNode.cpp', + yoga .. '/yoga/YGValue.cpp', + yoga .. '/yoga/YGStyle.cpp', + yoga .. '/yoga/Yoga.cpp', + yoga .. '/yoga/event/event.cpp', + yoga .. '/yoga/log.cpp', + }) + + buildoptions({ '-Wall', '-pedantic' }) + + linkoptions({ '-r' }) + + filter('system:emscripten') + do + buildoptions({ '-pthread' }) + end + + filter('configurations:debug') + do + defines({ 'DEBUG' }) + symbols('On') + end + + filter('toolset:clang') + do + flags({ 'FatalWarnings' }) + buildoptions({ + '-Werror=format', + '-Wimplicit-int-conversion', + '-Werror=vla', + }) + end + + filter('configurations:release') + do + buildoptions({ '-Oz' }) + defines({ 'RELEASE', 'NDEBUG' }) + optimize('On') + end + + filter({ 'system:macosx', 'options:variant=runtime' }) + do + buildoptions({ + '-Wimplicit-float-conversion -fembed-bitcode -arch arm64 -arch x86_64 -isysroot' + .. (os.getenv('MACOS_SYSROOT') or ''), + }) + end + + filter({ 'system:macosx', 'configurations:release' }) + do + buildoptions({ '-flto=full' }) + end + + filter({ 'system:ios' }) + do + buildoptions({ '-flto=full' }) + end + + filter('system:windows') + do + architecture('x64') + defines({ '_USE_MATH_DEFINES' }) + end + + filter({ 'system:ios', 'options:variant=system' }) + do + buildoptions({ + '-mios-version-min=13.0 -fembed-bitcode -arch arm64 -isysroot ' + .. (os.getenv('IOS_SYSROOT') or ''), + }) + end + + filter({ 'system:ios', 'options:variant=emulator' }) + do + buildoptions({ + '--target=arm64-apple-ios13.0.0-simulator', + '-mios-version-min=13.0 -arch arm64 -arch x86_64 -isysroot ' + .. (os.getenv('IOS_SYSROOT') or ''), + }) + targetdir('%{cfg.system}_sim/cache/bin/%{cfg.buildcfg}') + objdir('%{cfg.system}_sim/cache/obj/%{cfg.buildcfg}') + end + + filter({ 'system:android', 'configurations:release' }) + do + buildoptions({ '-flto=full' }) + end + + -- Is there a way to pass 'arch' as a variable here? + filter({ 'system:android', 'options:arch=x86' }) + do + targetdir('%{cfg.system}/cache/x86/bin/%{cfg.buildcfg}') + objdir('%{cfg.system}/cache/x86/obj/%{cfg.buildcfg}') + end + + filter({ 'system:android', 'options:arch=x64' }) + do + targetdir('%{cfg.system}/cache/x64/bin/%{cfg.buildcfg}') + objdir('%{cfg.system}/cache/x64/obj/%{cfg.buildcfg}') + end + + filter({ 'system:android', 'options:arch=arm' }) + do + targetdir('%{cfg.system}/cache/arm/bin/%{cfg.buildcfg}') + objdir('%{cfg.system}/cache/arm/obj/%{cfg.buildcfg}') + end + + filter({ 'system:android', 'options:arch=arm64' }) + do + targetdir('%{cfg.system}/cache/arm64/bin/%{cfg.buildcfg}') + objdir('%{cfg.system}/cache/arm64/obj/%{cfg.buildcfg}') + end +end diff --git a/dependencies/premake5_yoga_v2.lua b/dependencies/premake5_yoga_v2.lua new file mode 100644 index 00000000..4583132f --- /dev/null +++ b/dependencies/premake5_yoga_v2.lua @@ -0,0 +1,28 @@ +dofile('rive_build_config.lua') + +local dependency = require('dependency') +yoga = dependency.github('rive-app/yoga', 'rive_changes_v2_0_1') + +project('rive_yoga') +do + kind('StaticLib') + warnings('Off') + + defines({ 'YOGA_EXPORT=' }) + + includedirs({ yoga }) + + files({ + yoga .. '/yoga/Utils.cpp', + yoga .. '/yoga/YGConfig.cpp', + yoga .. '/yoga/YGLayout.cpp', + yoga .. '/yoga/YGEnums.cpp', + yoga .. '/yoga/YGNodePrint.cpp', + yoga .. '/yoga/YGNode.cpp', + yoga .. '/yoga/YGValue.cpp', + yoga .. '/yoga/YGStyle.cpp', + yoga .. '/yoga/Yoga.cpp', + yoga .. '/yoga/event/event.cpp', + yoga .. '/yoga/log.cpp', + }) +end diff --git a/dev/defs/artboard.json b/dev/defs/artboard.json index 628ce9be..4d482a94 100644 --- a/dev/defs/artboard.json +++ b/dev/defs/artboard.json @@ -4,35 +4,8 @@ "int": 1, "string": "artboard" }, - "extends": "world_transform_component.json", + "extends": "layout_component.json", "properties": { - "clip": { - "type": "bool", - "initialValue": "true", - "key": { - "int": 196, - "string": "clip" - }, - "description": "True when the artboard bounds clip its contents." - }, - "width": { - "type": "double", - "initialValue": "0", - "key": { - "int": 7, - "string": "w" - }, - "description": "Width of the artboard." - }, - "height": { - "type": "double", - "initialValue": "0", - "key": { - "int": 8, - "string": "h" - }, - "description": "Height of the artboard." - }, "x": { "type": "double", "initialValue": "0", diff --git a/dev/defs/layout/layout_component_style.json b/dev/defs/layout/layout_component_style.json new file mode 100644 index 00000000..d3da49c8 --- /dev/null +++ b/dev/defs/layout/layout_component_style.json @@ -0,0 +1,307 @@ +{ + "name": "LayoutComponentStyle", + "key": { + "int": 420, + "string": "layoutcomponentstyle" + }, + "extends": "component.json", + "properties": { + "layoutFlags0": { + "type": "uint", + "initialValue": "0x5000412", + "key": { + "int": 495, + "string": "layoutflags0" + }, + "description": "First BitFlags for layout styles." + }, + "layoutFlags1": { + "type": "uint", + "initialValue": "0x00", + "key": { + "int": 496, + "string": "layoutflags1" + }, + "description": "Second BitFlags for layout styles." + }, + "layoutFlags2": { + "type": "uint", + "initialValue": "0x00", + "key": { + "int": 497, + "string": "layoutflags2" + }, + "description": "Third BitFlags for layout styles." + }, + "gapHorizontal": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 498, + "string": "gaphorizontal" + }, + "description": "Horizontal gap between children in layout component" + }, + "gapVertical": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 499, + "string": "gapvertical" + }, + "description": "Vertical gap between children in layout component" + }, + "maxWidth": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 500, + "string": "maxwidth" + }, + "description": "Max width of the item." + }, + "maxHeight": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 501, + "string": "maxheight" + }, + "description": "Max height of the item." + }, + "minWidth": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 502, + "string": "minwidth" + }, + "description": "Min width of the item." + }, + "minHeight": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 503, + "string": "minheight" + }, + "description": "Min height of the item." + }, + "borderLeft": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 504, + "string": "borderleft" + }, + "description": "Left border value." + }, + "borderRight": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 505, + "string": "borderright" + }, + "description": "Right border value." + }, + "borderTop": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 506, + "string": "bordertop" + }, + "description": "Top border value." + }, + "borderBottom": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 507, + "string": "borderbottom" + }, + "description": "Bottom border value." + }, + "marginLeft": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 508, + "string": "marginleft" + }, + "description": "Left margin value." + }, + "marginRight": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 509, + "string": "marginright" + }, + "description": "Right margin value." + }, + "marginTop": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 510, + "string": "margintop" + }, + "description": "Top margin value." + }, + "marginBottom": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 511, + "string": "marginbottom" + }, + "description": "Bottom margin value." + }, + "paddingLeft": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 512, + "string": "paddingleft" + }, + "description": "Left padding value." + }, + "paddingRight": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 513, + "string": "paddingright" + }, + "description": "Right padding value." + }, + "paddingTop": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 514, + "string": "paddingtop" + }, + "description": "Top padding value." + }, + "paddingBottom": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 515, + "string": "paddingbottom" + }, + "description": "Bottom padding value." + }, + "positionLeft": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 516, + "string": "positionleft" + }, + "description": "Left position value." + }, + "positionRight": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 517, + "string": "positionright" + }, + "description": "Right position value." + }, + "positionTop": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 518, + "string": "positiontop" + }, + "description": "Top position value." + }, + "positionBottom": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 519, + "string": "positionbottom" + }, + "description": "Bottom position value." + }, + "flex": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 520, + "string": "flex" + }, + "description": "Flex value." + }, + "flexGrow": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 521, + "string": "flexgrow" + }, + "description": "Flex grow value." + }, + "flexShrink": { + "type": "double", + "initialValue": "1", + "animates": true, + "key": { + "int": 522, + "string": "flexshrink" + }, + "description": "Flex shrink value." + }, + "flexBasis": { + "type": "double", + "initialValue": "1", + "animates": true, + "key": { + "int": 523, + "string": "flexbasis" + }, + "description": "Flex basis value." + }, + "aspectRatio": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 524, + "string": "aspectratio" + }, + "description": "Aspect ratio value." + } + } +} \ No newline at end of file diff --git a/dev/defs/layout_component.json b/dev/defs/layout_component.json new file mode 100644 index 00000000..ac24d51d --- /dev/null +++ b/dev/defs/layout_component.json @@ -0,0 +1,50 @@ +{ + "name": "LayoutComponent", + "key": { + "int": 409, + "string": "layoutcomponent" + }, + "extends": "world_transform_component.json", + "properties": { + "clip": { + "type": "bool", + "initialValue": "true", + "key": { + "int": 196, + "string": "clip" + }, + "description": "True when the layout component bounds clip its contents." + }, + "width": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 7, + "string": "w" + }, + "description": "Initial width of the item." + }, + "height": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 8, + "string": "h" + }, + "description": "Initial height of the item." + }, + "styleId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 494, + "string": "styleid" + }, + "description": "LayoutStyle that defines the styling for this LayoutComponent" + } + } +} \ No newline at end of file diff --git a/dev/defs/layout_component_absolute.json b/dev/defs/layout_component_absolute.json new file mode 100644 index 00000000..a239d432 --- /dev/null +++ b/dev/defs/layout_component_absolute.json @@ -0,0 +1,19 @@ +{ + "name": "AbsoluteLayoutComponent", + "key": { + "int": 423, + "string": "absolutelayoutcomponent" + }, + "extends": "layout_component.json", + "properties": { + "constraints": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 535, + "string": "constraints" + }, + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/nested_artboard.json b/dev/defs/nested_artboard.json index abe086a4..e6a52110 100644 --- a/dev/defs/nested_artboard.json +++ b/dev/defs/nested_artboard.json @@ -16,6 +16,22 @@ "string": "artboardid" }, "description": "Identifier used to track the Artboard nested." + }, + "fit": { + "type": "uint", + "key": { + "int": 538, + "string": "fit" + }, + "description": "Fit type for the nested artboard's runtime artboard." + }, + "alignment": { + "type": "uint", + "key": { + "int": 539, + "string": "alignment" + }, + "description": "Alignment type for the nested artboard's runtime artboard." } } } \ No newline at end of file diff --git a/dev/test.sh b/dev/test.sh index 4e4047bb..0167ca2a 100755 --- a/dev/test.sh +++ b/dev/test.sh @@ -75,7 +75,7 @@ RUNTIME=$PWD popd export PREMAKE_PATH="$RUNTIME/dependencies/export-compile-commands":"$RUNTIME/build":"$PREMAKE_PATH" -PREMAKE_COMMANDS="--with_rive_text --with_rive_audio=external --config=$CONFIG" +PREMAKE_COMMANDS="--with_rive_text --with_rive_audio=external --with_rive_layout --config=$CONFIG" out_dir() { echo "out/$CONFIG" diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index 7fe5e83d..00db7025 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -7,6 +7,8 @@ defines({ 'WITH_RIVE_TEXT', 'WITH_RIVE_AUDIO', 'WITH_RIVE_AUDIO_TOOLS', + 'WITH_RIVE_LAYOUT', + 'YOGA_EXPORT=' }) dofile(path.join(path.getabsolute('../../'), 'premake5_v2.lua')) @@ -22,12 +24,14 @@ do '../../include', '../../decoders/include', miniaudio, + yoga, }) links({ 'rive', 'rive_harfbuzz', 'rive_sheenbidi', + 'rive_yoga', 'rive_decoders', 'libpng', 'zlib', diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index d93d91de..97d6afd5 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -15,6 +15,7 @@ #include "rive/math/raw_path.hpp" #include +#include #include namespace rive @@ -64,6 +65,9 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta Drawable* m_FirstDrawable = nullptr; bool m_IsInstance = false; bool m_FrameOrigin = true; + std::unordered_set m_dirtyLayout; + float m_originalWidth = 0; + float m_originalHeight = 0; #ifdef EXTERNAL_RIVE_AUDIO_ENGINE rcp m_audioEngine; @@ -106,6 +110,11 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta void update(ComponentDirt value) override; void onDirty(ComponentDirt dirt) override; + void markLayoutDirty(LayoutComponent* layoutComponent) + { + m_dirtyLayout.insert(layoutComponent); + } + bool advance(double elapsedSeconds); bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; } Drawable* firstDrawable() { return m_FirstDrawable; } @@ -129,6 +138,9 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta NestedArtboard* nestedArtboard(const std::string& name) const; NestedArtboard* nestedArtboardAtPath(const std::string& path) const; + float originalWidth() { return m_originalWidth; } + float originalHeight() { return m_originalHeight; } + AABB bounds() const; // Can we hide these from the public? (they use playable) @@ -219,6 +231,8 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta artboardClone->m_Factory = m_Factory; artboardClone->m_FrameOrigin = m_FrameOrigin; artboardClone->m_IsInstance = true; + artboardClone->m_originalWidth = m_originalWidth; + artboardClone->m_originalHeight = m_originalHeight; std::vector& cloneObjects = artboardClone->m_Objects; cloneObjects.push_back(artboardClone.get()); @@ -267,6 +281,23 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta /// relative to the bounds. void frameOrigin(bool value); + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + bool result = ArtboardBase::deserialize(propertyKey, reader); + switch (propertyKey) + { + case widthPropertyKey: + m_originalWidth = width(); + break; + case heightPropertyKey: + m_originalHeight = height(); + break; + default: + break; + } + return result; + } + StatusCode import(ImportStack& importStack) override; float volume() const; diff --git a/include/rive/bounds_provider.hpp b/include/rive/bounds_provider.hpp new file mode 100644 index 00000000..7f3ca83a --- /dev/null +++ b/include/rive/bounds_provider.hpp @@ -0,0 +1,17 @@ +#ifndef _RIVE_BOUNDS_PROVIDER_HPP_ +#define _RIVE_BOUNDS_PROVIDER_HPP_ + +#include "rive/math/aabb.hpp" +#include "rive/math/mat2d.hpp" + +namespace rive +{ + +class BoundsProvider +{ +public: + virtual ~BoundsProvider() {} + virtual AABB computeBounds(Mat2D toParent); +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/generated/artboard_base.hpp b/include/rive/generated/artboard_base.hpp index feac51fb..54a378b2 100644 --- a/include/rive/generated/artboard_base.hpp +++ b/include/rive/generated/artboard_base.hpp @@ -1,15 +1,14 @@ #ifndef _RIVE_ARTBOARD_BASE_HPP_ #define _RIVE_ARTBOARD_BASE_HPP_ -#include "rive/core/field_types/core_bool_type.hpp" #include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" -#include "rive/world_transform_component.hpp" +#include "rive/layout_component.hpp" namespace rive { -class ArtboardBase : public WorldTransformComponent +class ArtboardBase : public LayoutComponent { protected: - typedef WorldTransformComponent Super; + typedef LayoutComponent Super; public: static const uint16_t typeKey = 1; @@ -21,6 +20,7 @@ class ArtboardBase : public WorldTransformComponent switch (typeKey) { case ArtboardBase::typeKey: + case LayoutComponentBase::typeKey: case WorldTransformComponentBase::typeKey: case ContainerComponentBase::typeKey: case ComponentBase::typeKey: @@ -32,9 +32,6 @@ class ArtboardBase : public WorldTransformComponent uint16_t coreType() const override { return typeKey; } - static const uint16_t clipPropertyKey = 196; - static const uint16_t widthPropertyKey = 7; - static const uint16_t heightPropertyKey = 8; static const uint16_t xPropertyKey = 9; static const uint16_t yPropertyKey = 10; static const uint16_t originXPropertyKey = 11; @@ -42,9 +39,6 @@ class ArtboardBase : public WorldTransformComponent static const uint16_t defaultStateMachineIdPropertyKey = 236; private: - bool m_Clip = true; - float m_Width = 0.0f; - float m_Height = 0.0f; float m_X = 0.0f; float m_Y = 0.0f; float m_OriginX = 0.0f; @@ -52,39 +46,6 @@ class ArtboardBase : public WorldTransformComponent uint32_t m_DefaultStateMachineId = -1; public: - inline bool clip() const { return m_Clip; } - void clip(bool value) - { - if (m_Clip == value) - { - return; - } - m_Clip = value; - clipChanged(); - } - - inline float width() const { return m_Width; } - void width(float value) - { - if (m_Width == value) - { - return; - } - m_Width = value; - widthChanged(); - } - - inline float height() const { return m_Height; } - void height(float value) - { - if (m_Height == value) - { - return; - } - m_Height = value; - heightChanged(); - } - inline float x() const { return m_X; } void x(float value) { @@ -143,30 +104,18 @@ class ArtboardBase : public WorldTransformComponent Core* clone() const override; void copy(const ArtboardBase& object) { - m_Clip = object.m_Clip; - m_Width = object.m_Width; - m_Height = object.m_Height; m_X = object.m_X; m_Y = object.m_Y; m_OriginX = object.m_OriginX; m_OriginY = object.m_OriginY; m_DefaultStateMachineId = object.m_DefaultStateMachineId; - WorldTransformComponent::copy(object); + LayoutComponent::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { switch (propertyKey) { - case clipPropertyKey: - m_Clip = CoreBoolType::deserialize(reader); - return true; - case widthPropertyKey: - m_Width = CoreDoubleType::deserialize(reader); - return true; - case heightPropertyKey: - m_Height = CoreDoubleType::deserialize(reader); - return true; case xPropertyKey: m_X = CoreDoubleType::deserialize(reader); return true; @@ -183,13 +132,10 @@ class ArtboardBase : public WorldTransformComponent m_DefaultStateMachineId = CoreUintType::deserialize(reader); return true; } - return WorldTransformComponent::deserialize(propertyKey, reader); + return LayoutComponent::deserialize(propertyKey, reader); } protected: - virtual void clipChanged() {} - virtual void widthChanged() {} - virtual void heightChanged() {} virtual void xChanged() {} virtual void yChanged() {} virtual void originXChanged() {} diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index c306c1fe..f9416480 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -104,6 +104,9 @@ #include "rive/drawable.hpp" #include "rive/event.hpp" #include "rive/joystick.hpp" +#include "rive/layout/layout_component_style.hpp" +#include "rive/layout_component.hpp" +#include "rive/layout_component_absolute.hpp" #include "rive/nested_animation.hpp" #include "rive/nested_artboard.hpp" #include "rive/node.hpp" @@ -183,6 +186,8 @@ class CoreRegistry return new NestedArtboard(); case SoloBase::typeKey: return new Solo(); + case LayoutComponentStyleBase::typeKey: + return new LayoutComponentStyle(); case ListenerFireEventBase::typeKey: return new ListenerFireEvent(); case NestedSimpleAnimationBase::typeKey: @@ -325,12 +330,16 @@ class CoreRegistry return new DrawRules(); case CustomPropertyBooleanBase::typeKey: return new CustomPropertyBoolean(); + case LayoutComponentBase::typeKey: + return new LayoutComponent(); case ArtboardBase::typeKey: return new Artboard(); case JoystickBase::typeKey: return new Joystick(); case BackboardBase::typeKey: return new Backboard(); + case AbsoluteLayoutComponentBase::typeKey: + return new AbsoluteLayoutComponent(); case OpenUrlEventBase::typeKey: return new OpenUrlEvent(); case WeightBase::typeKey: @@ -451,12 +460,27 @@ class CoreRegistry case NestedArtboardBase::artboardIdPropertyKey: object->as()->artboardId(value); break; + case NestedArtboardBase::fitPropertyKey: + object->as()->fit(value); + break; + case NestedArtboardBase::alignmentPropertyKey: + object->as()->alignment(value); + break; case NestedAnimationBase::animationIdPropertyKey: object->as()->animationId(value); break; case SoloBase::activeComponentIdPropertyKey: object->as()->activeComponentId(value); break; + case LayoutComponentStyleBase::layoutFlags0PropertyKey: + object->as()->layoutFlags0(value); + break; + case LayoutComponentStyleBase::layoutFlags1PropertyKey: + object->as()->layoutFlags1(value); + break; + case LayoutComponentStyleBase::layoutFlags2PropertyKey: + object->as()->layoutFlags2(value); + break; case ListenerFireEventBase::eventIdPropertyKey: object->as()->eventId(value); break; @@ -604,6 +628,9 @@ class CoreRegistry case DrawRulesBase::drawTargetIdPropertyKey: object->as()->drawTargetId(value); break; + case LayoutComponentBase::styleIdPropertyKey: + object->as()->styleId(value); + break; case ArtboardBase::defaultStateMachineIdPropertyKey: object->as()->defaultStateMachineId(value); break; @@ -754,6 +781,87 @@ class CoreRegistry case NodeBase::yPropertyKey: object->as()->y(value); break; + case LayoutComponentStyleBase::gapHorizontalPropertyKey: + object->as()->gapHorizontal(value); + break; + case LayoutComponentStyleBase::gapVerticalPropertyKey: + object->as()->gapVertical(value); + break; + case LayoutComponentStyleBase::maxWidthPropertyKey: + object->as()->maxWidth(value); + break; + case LayoutComponentStyleBase::maxHeightPropertyKey: + object->as()->maxHeight(value); + break; + case LayoutComponentStyleBase::minWidthPropertyKey: + object->as()->minWidth(value); + break; + case LayoutComponentStyleBase::minHeightPropertyKey: + object->as()->minHeight(value); + break; + case LayoutComponentStyleBase::borderLeftPropertyKey: + object->as()->borderLeft(value); + break; + case LayoutComponentStyleBase::borderRightPropertyKey: + object->as()->borderRight(value); + break; + case LayoutComponentStyleBase::borderTopPropertyKey: + object->as()->borderTop(value); + break; + case LayoutComponentStyleBase::borderBottomPropertyKey: + object->as()->borderBottom(value); + break; + case LayoutComponentStyleBase::marginLeftPropertyKey: + object->as()->marginLeft(value); + break; + case LayoutComponentStyleBase::marginRightPropertyKey: + object->as()->marginRight(value); + break; + case LayoutComponentStyleBase::marginTopPropertyKey: + object->as()->marginTop(value); + break; + case LayoutComponentStyleBase::marginBottomPropertyKey: + object->as()->marginBottom(value); + break; + case LayoutComponentStyleBase::paddingLeftPropertyKey: + object->as()->paddingLeft(value); + break; + case LayoutComponentStyleBase::paddingRightPropertyKey: + object->as()->paddingRight(value); + break; + case LayoutComponentStyleBase::paddingTopPropertyKey: + object->as()->paddingTop(value); + break; + case LayoutComponentStyleBase::paddingBottomPropertyKey: + object->as()->paddingBottom(value); + break; + case LayoutComponentStyleBase::positionLeftPropertyKey: + object->as()->positionLeft(value); + break; + case LayoutComponentStyleBase::positionRightPropertyKey: + object->as()->positionRight(value); + break; + case LayoutComponentStyleBase::positionTopPropertyKey: + object->as()->positionTop(value); + break; + case LayoutComponentStyleBase::positionBottomPropertyKey: + object->as()->positionBottom(value); + break; + case LayoutComponentStyleBase::flexPropertyKey: + object->as()->flex(value); + break; + case LayoutComponentStyleBase::flexGrowPropertyKey: + object->as()->flexGrow(value); + break; + case LayoutComponentStyleBase::flexShrinkPropertyKey: + object->as()->flexShrink(value); + break; + case LayoutComponentStyleBase::flexBasisPropertyKey: + object->as()->flexBasis(value); + break; + case LayoutComponentStyleBase::aspectRatioPropertyKey: + object->as()->aspectRatio(value); + break; case NestedLinearAnimationBase::mixPropertyKey: object->as()->mix(value); break; @@ -928,11 +1036,11 @@ class CoreRegistry case CubicDetachedVertexBase::outDistancePropertyKey: object->as()->outDistance(value); break; - case ArtboardBase::widthPropertyKey: - object->as()->width(value); + case LayoutComponentBase::widthPropertyKey: + object->as()->width(value); break; - case ArtboardBase::heightPropertyKey: - object->as()->height(value); + case LayoutComponentBase::heightPropertyKey: + object->as()->height(value); break; case ArtboardBase::xPropertyKey: object->as()->x(value); @@ -1171,8 +1279,8 @@ class CoreRegistry case CustomPropertyBooleanBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; - case ArtboardBase::clipPropertyKey: - object->as()->clip(value); + case LayoutComponentBase::clipPropertyKey: + object->as()->clip(value); break; case TextModifierRangeBase::clampPropertyKey: object->as()->clamp(value); @@ -1259,10 +1367,20 @@ class CoreRegistry return object->as()->drawableFlags(); case NestedArtboardBase::artboardIdPropertyKey: return object->as()->artboardId(); + case NestedArtboardBase::fitPropertyKey: + return object->as()->fit(); + case NestedArtboardBase::alignmentPropertyKey: + return object->as()->alignment(); case NestedAnimationBase::animationIdPropertyKey: return object->as()->animationId(); case SoloBase::activeComponentIdPropertyKey: return object->as()->activeComponentId(); + case LayoutComponentStyleBase::layoutFlags0PropertyKey: + return object->as()->layoutFlags0(); + case LayoutComponentStyleBase::layoutFlags1PropertyKey: + return object->as()->layoutFlags1(); + case LayoutComponentStyleBase::layoutFlags2PropertyKey: + return object->as()->layoutFlags2(); case ListenerFireEventBase::eventIdPropertyKey: return object->as()->eventId(); case LayerStateBase::flagsPropertyKey: @@ -1361,6 +1479,8 @@ class CoreRegistry return object->as()->assetId(); case DrawRulesBase::drawTargetIdPropertyKey: return object->as()->drawTargetId(); + case LayoutComponentBase::styleIdPropertyKey: + return object->as()->styleId(); case ArtboardBase::defaultStateMachineIdPropertyKey: return object->as()->defaultStateMachineId(); case JoystickBase::xIdPropertyKey: @@ -1464,6 +1584,60 @@ class CoreRegistry return object->as()->x(); case NodeBase::yPropertyKey: return object->as()->y(); + case LayoutComponentStyleBase::gapHorizontalPropertyKey: + return object->as()->gapHorizontal(); + case LayoutComponentStyleBase::gapVerticalPropertyKey: + return object->as()->gapVertical(); + case LayoutComponentStyleBase::maxWidthPropertyKey: + return object->as()->maxWidth(); + case LayoutComponentStyleBase::maxHeightPropertyKey: + return object->as()->maxHeight(); + case LayoutComponentStyleBase::minWidthPropertyKey: + return object->as()->minWidth(); + case LayoutComponentStyleBase::minHeightPropertyKey: + return object->as()->minHeight(); + case LayoutComponentStyleBase::borderLeftPropertyKey: + return object->as()->borderLeft(); + case LayoutComponentStyleBase::borderRightPropertyKey: + return object->as()->borderRight(); + case LayoutComponentStyleBase::borderTopPropertyKey: + return object->as()->borderTop(); + case LayoutComponentStyleBase::borderBottomPropertyKey: + return object->as()->borderBottom(); + case LayoutComponentStyleBase::marginLeftPropertyKey: + return object->as()->marginLeft(); + case LayoutComponentStyleBase::marginRightPropertyKey: + return object->as()->marginRight(); + case LayoutComponentStyleBase::marginTopPropertyKey: + return object->as()->marginTop(); + case LayoutComponentStyleBase::marginBottomPropertyKey: + return object->as()->marginBottom(); + case LayoutComponentStyleBase::paddingLeftPropertyKey: + return object->as()->paddingLeft(); + case LayoutComponentStyleBase::paddingRightPropertyKey: + return object->as()->paddingRight(); + case LayoutComponentStyleBase::paddingTopPropertyKey: + return object->as()->paddingTop(); + case LayoutComponentStyleBase::paddingBottomPropertyKey: + return object->as()->paddingBottom(); + case LayoutComponentStyleBase::positionLeftPropertyKey: + return object->as()->positionLeft(); + case LayoutComponentStyleBase::positionRightPropertyKey: + return object->as()->positionRight(); + case LayoutComponentStyleBase::positionTopPropertyKey: + return object->as()->positionTop(); + case LayoutComponentStyleBase::positionBottomPropertyKey: + return object->as()->positionBottom(); + case LayoutComponentStyleBase::flexPropertyKey: + return object->as()->flex(); + case LayoutComponentStyleBase::flexGrowPropertyKey: + return object->as()->flexGrow(); + case LayoutComponentStyleBase::flexShrinkPropertyKey: + return object->as()->flexShrink(); + case LayoutComponentStyleBase::flexBasisPropertyKey: + return object->as()->flexBasis(); + case LayoutComponentStyleBase::aspectRatioPropertyKey: + return object->as()->aspectRatio(); case NestedLinearAnimationBase::mixPropertyKey: return object->as()->mix(); case NestedSimpleAnimationBase::speedPropertyKey: @@ -1580,10 +1754,10 @@ class CoreRegistry return object->as()->outRotation(); case CubicDetachedVertexBase::outDistancePropertyKey: return object->as()->outDistance(); - case ArtboardBase::widthPropertyKey: - return object->as()->width(); - case ArtboardBase::heightPropertyKey: - return object->as()->height(); + case LayoutComponentBase::widthPropertyKey: + return object->as()->width(); + case LayoutComponentBase::heightPropertyKey: + return object->as()->height(); case ArtboardBase::xPropertyKey: return object->as()->x(); case ArtboardBase::yPropertyKey: @@ -1745,8 +1919,8 @@ class CoreRegistry return object->as()->isVisible(); case CustomPropertyBooleanBase::propertyValuePropertyKey: return object->as()->propertyValue(); - case ArtboardBase::clipPropertyKey: - return object->as()->clip(); + case LayoutComponentBase::clipPropertyKey: + return object->as()->clip(); case TextModifierRangeBase::clampPropertyKey: return object->as()->clamp(); } @@ -1791,8 +1965,13 @@ class CoreRegistry case DrawableBase::blendModeValuePropertyKey: case DrawableBase::drawableFlagsPropertyKey: case NestedArtboardBase::artboardIdPropertyKey: + case NestedArtboardBase::fitPropertyKey: + case NestedArtboardBase::alignmentPropertyKey: case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: + case LayoutComponentStyleBase::layoutFlags0PropertyKey: + case LayoutComponentStyleBase::layoutFlags1PropertyKey: + case LayoutComponentStyleBase::layoutFlags2PropertyKey: case ListenerFireEventBase::eventIdPropertyKey: case LayerStateBase::flagsPropertyKey: case ListenerInputChangeBase::inputIdPropertyKey: @@ -1842,6 +2021,7 @@ class CoreRegistry case PolygonBase::pointsPropertyKey: case ImageBase::assetIdPropertyKey: case DrawRulesBase::drawTargetIdPropertyKey: + case LayoutComponentBase::styleIdPropertyKey: case ArtboardBase::defaultStateMachineIdPropertyKey: case JoystickBase::xIdPropertyKey: case JoystickBase::yIdPropertyKey: @@ -1891,6 +2071,33 @@ class CoreRegistry case TransformComponentBase::scaleYPropertyKey: case NodeBase::xPropertyKey: case NodeBase::yPropertyKey: + case LayoutComponentStyleBase::gapHorizontalPropertyKey: + case LayoutComponentStyleBase::gapVerticalPropertyKey: + case LayoutComponentStyleBase::maxWidthPropertyKey: + case LayoutComponentStyleBase::maxHeightPropertyKey: + case LayoutComponentStyleBase::minWidthPropertyKey: + case LayoutComponentStyleBase::minHeightPropertyKey: + case LayoutComponentStyleBase::borderLeftPropertyKey: + case LayoutComponentStyleBase::borderRightPropertyKey: + case LayoutComponentStyleBase::borderTopPropertyKey: + case LayoutComponentStyleBase::borderBottomPropertyKey: + case LayoutComponentStyleBase::marginLeftPropertyKey: + case LayoutComponentStyleBase::marginRightPropertyKey: + case LayoutComponentStyleBase::marginTopPropertyKey: + case LayoutComponentStyleBase::marginBottomPropertyKey: + case LayoutComponentStyleBase::paddingLeftPropertyKey: + case LayoutComponentStyleBase::paddingRightPropertyKey: + case LayoutComponentStyleBase::paddingTopPropertyKey: + case LayoutComponentStyleBase::paddingBottomPropertyKey: + case LayoutComponentStyleBase::positionLeftPropertyKey: + case LayoutComponentStyleBase::positionRightPropertyKey: + case LayoutComponentStyleBase::positionTopPropertyKey: + case LayoutComponentStyleBase::positionBottomPropertyKey: + case LayoutComponentStyleBase::flexPropertyKey: + case LayoutComponentStyleBase::flexGrowPropertyKey: + case LayoutComponentStyleBase::flexShrinkPropertyKey: + case LayoutComponentStyleBase::flexBasisPropertyKey: + case LayoutComponentStyleBase::aspectRatioPropertyKey: case NestedLinearAnimationBase::mixPropertyKey: case NestedSimpleAnimationBase::speedPropertyKey: case AdvanceableStateBase::speedPropertyKey: @@ -1949,8 +2156,8 @@ class CoreRegistry case CubicDetachedVertexBase::inDistancePropertyKey: case CubicDetachedVertexBase::outRotationPropertyKey: case CubicDetachedVertexBase::outDistancePropertyKey: - case ArtboardBase::widthPropertyKey: - case ArtboardBase::heightPropertyKey: + case LayoutComponentBase::widthPropertyKey: + case LayoutComponentBase::heightPropertyKey: case ArtboardBase::xPropertyKey: case ArtboardBase::yPropertyKey: case ArtboardBase::originXPropertyKey: @@ -2029,7 +2236,7 @@ class CoreRegistry case RectangleBase::linkCornerRadiusPropertyKey: case ClippingShapeBase::isVisiblePropertyKey: case CustomPropertyBooleanBase::propertyValuePropertyKey: - case ArtboardBase::clipPropertyKey: + case LayoutComponentBase::clipPropertyKey: case TextModifierRangeBase::clampPropertyKey: return CoreBoolType::id; case KeyFrameColorBase::valuePropertyKey: @@ -2101,10 +2308,20 @@ class CoreRegistry return object->is(); case NestedArtboardBase::artboardIdPropertyKey: return object->is(); + case NestedArtboardBase::fitPropertyKey: + return object->is(); + case NestedArtboardBase::alignmentPropertyKey: + return object->is(); case NestedAnimationBase::animationIdPropertyKey: return object->is(); case SoloBase::activeComponentIdPropertyKey: return object->is(); + case LayoutComponentStyleBase::layoutFlags0PropertyKey: + return object->is(); + case LayoutComponentStyleBase::layoutFlags1PropertyKey: + return object->is(); + case LayoutComponentStyleBase::layoutFlags2PropertyKey: + return object->is(); case ListenerFireEventBase::eventIdPropertyKey: return object->is(); case LayerStateBase::flagsPropertyKey: @@ -2203,6 +2420,8 @@ class CoreRegistry return object->is(); case DrawRulesBase::drawTargetIdPropertyKey: return object->is(); + case LayoutComponentBase::styleIdPropertyKey: + return object->is(); case ArtboardBase::defaultStateMachineIdPropertyKey: return object->is(); case JoystickBase::xIdPropertyKey: @@ -2299,6 +2518,60 @@ class CoreRegistry return object->is(); case NodeBase::yPropertyKey: return object->is(); + case LayoutComponentStyleBase::gapHorizontalPropertyKey: + return object->is(); + case LayoutComponentStyleBase::gapVerticalPropertyKey: + return object->is(); + case LayoutComponentStyleBase::maxWidthPropertyKey: + return object->is(); + case LayoutComponentStyleBase::maxHeightPropertyKey: + return object->is(); + case LayoutComponentStyleBase::minWidthPropertyKey: + return object->is(); + case LayoutComponentStyleBase::minHeightPropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderLeftPropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderRightPropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderTopPropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderBottomPropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginLeftPropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginRightPropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginTopPropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginBottomPropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingLeftPropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingRightPropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingTopPropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingBottomPropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionLeftPropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionRightPropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionTopPropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionBottomPropertyKey: + return object->is(); + case LayoutComponentStyleBase::flexPropertyKey: + return object->is(); + case LayoutComponentStyleBase::flexGrowPropertyKey: + return object->is(); + case LayoutComponentStyleBase::flexShrinkPropertyKey: + return object->is(); + case LayoutComponentStyleBase::flexBasisPropertyKey: + return object->is(); + case LayoutComponentStyleBase::aspectRatioPropertyKey: + return object->is(); case NestedLinearAnimationBase::mixPropertyKey: return object->is(); case NestedSimpleAnimationBase::speedPropertyKey: @@ -2415,10 +2688,10 @@ class CoreRegistry return object->is(); case CubicDetachedVertexBase::outDistancePropertyKey: return object->is(); - case ArtboardBase::widthPropertyKey: - return object->is(); - case ArtboardBase::heightPropertyKey: - return object->is(); + case LayoutComponentBase::widthPropertyKey: + return object->is(); + case LayoutComponentBase::heightPropertyKey: + return object->is(); case ArtboardBase::xPropertyKey: return object->is(); case ArtboardBase::yPropertyKey: @@ -2573,8 +2846,8 @@ class CoreRegistry return object->is(); case CustomPropertyBooleanBase::propertyValuePropertyKey: return object->is(); - case ArtboardBase::clipPropertyKey: - return object->is(); + case LayoutComponentBase::clipPropertyKey: + return object->is(); case TextModifierRangeBase::clampPropertyKey: return object->is(); case NestedTriggerBase::firePropertyKey: diff --git a/include/rive/generated/layout/layout_component_style_base.hpp b/include/rive/generated/layout/layout_component_style_base.hpp new file mode 100644 index 00000000..28dd01b5 --- /dev/null +++ b/include/rive/generated/layout/layout_component_style_base.hpp @@ -0,0 +1,594 @@ +#ifndef _RIVE_LAYOUT_COMPONENT_STYLE_BASE_HPP_ +#define _RIVE_LAYOUT_COMPONENT_STYLE_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class LayoutComponentStyleBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 420; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case LayoutComponentStyleBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t layoutFlags0PropertyKey = 495; + static const uint16_t layoutFlags1PropertyKey = 496; + static const uint16_t layoutFlags2PropertyKey = 497; + static const uint16_t gapHorizontalPropertyKey = 498; + static const uint16_t gapVerticalPropertyKey = 499; + static const uint16_t maxWidthPropertyKey = 500; + static const uint16_t maxHeightPropertyKey = 501; + static const uint16_t minWidthPropertyKey = 502; + static const uint16_t minHeightPropertyKey = 503; + static const uint16_t borderLeftPropertyKey = 504; + static const uint16_t borderRightPropertyKey = 505; + static const uint16_t borderTopPropertyKey = 506; + static const uint16_t borderBottomPropertyKey = 507; + static const uint16_t marginLeftPropertyKey = 508; + static const uint16_t marginRightPropertyKey = 509; + static const uint16_t marginTopPropertyKey = 510; + static const uint16_t marginBottomPropertyKey = 511; + static const uint16_t paddingLeftPropertyKey = 512; + static const uint16_t paddingRightPropertyKey = 513; + static const uint16_t paddingTopPropertyKey = 514; + static const uint16_t paddingBottomPropertyKey = 515; + static const uint16_t positionLeftPropertyKey = 516; + static const uint16_t positionRightPropertyKey = 517; + static const uint16_t positionTopPropertyKey = 518; + static const uint16_t positionBottomPropertyKey = 519; + static const uint16_t flexPropertyKey = 520; + static const uint16_t flexGrowPropertyKey = 521; + static const uint16_t flexShrinkPropertyKey = 522; + static const uint16_t flexBasisPropertyKey = 523; + static const uint16_t aspectRatioPropertyKey = 524; + +private: + uint32_t m_LayoutFlags0 = 0x5000412; + uint32_t m_LayoutFlags1 = 0x00; + uint32_t m_LayoutFlags2 = 0x00; + float m_GapHorizontal = 0.0f; + float m_GapVertical = 0.0f; + float m_MaxWidth = 0.0f; + float m_MaxHeight = 0.0f; + float m_MinWidth = 0.0f; + float m_MinHeight = 0.0f; + float m_BorderLeft = 0.0f; + float m_BorderRight = 0.0f; + float m_BorderTop = 0.0f; + float m_BorderBottom = 0.0f; + float m_MarginLeft = 0.0f; + float m_MarginRight = 0.0f; + float m_MarginTop = 0.0f; + float m_MarginBottom = 0.0f; + float m_PaddingLeft = 0.0f; + float m_PaddingRight = 0.0f; + float m_PaddingTop = 0.0f; + float m_PaddingBottom = 0.0f; + float m_PositionLeft = 0.0f; + float m_PositionRight = 0.0f; + float m_PositionTop = 0.0f; + float m_PositionBottom = 0.0f; + float m_Flex = 0.0f; + float m_FlexGrow = 0.0f; + float m_FlexShrink = 1.0f; + float m_FlexBasis = 1.0f; + float m_AspectRatio = 0.0f; + +public: + inline uint32_t layoutFlags0() const { return m_LayoutFlags0; } + void layoutFlags0(uint32_t value) + { + if (m_LayoutFlags0 == value) + { + return; + } + m_LayoutFlags0 = value; + layoutFlags0Changed(); + } + + inline uint32_t layoutFlags1() const { return m_LayoutFlags1; } + void layoutFlags1(uint32_t value) + { + if (m_LayoutFlags1 == value) + { + return; + } + m_LayoutFlags1 = value; + layoutFlags1Changed(); + } + + inline uint32_t layoutFlags2() const { return m_LayoutFlags2; } + void layoutFlags2(uint32_t value) + { + if (m_LayoutFlags2 == value) + { + return; + } + m_LayoutFlags2 = value; + layoutFlags2Changed(); + } + + inline float gapHorizontal() const { return m_GapHorizontal; } + void gapHorizontal(float value) + { + if (m_GapHorizontal == value) + { + return; + } + m_GapHorizontal = value; + gapHorizontalChanged(); + } + + inline float gapVertical() const { return m_GapVertical; } + void gapVertical(float value) + { + if (m_GapVertical == value) + { + return; + } + m_GapVertical = value; + gapVerticalChanged(); + } + + inline float maxWidth() const { return m_MaxWidth; } + void maxWidth(float value) + { + if (m_MaxWidth == value) + { + return; + } + m_MaxWidth = value; + maxWidthChanged(); + } + + inline float maxHeight() const { return m_MaxHeight; } + void maxHeight(float value) + { + if (m_MaxHeight == value) + { + return; + } + m_MaxHeight = value; + maxHeightChanged(); + } + + inline float minWidth() const { return m_MinWidth; } + void minWidth(float value) + { + if (m_MinWidth == value) + { + return; + } + m_MinWidth = value; + minWidthChanged(); + } + + inline float minHeight() const { return m_MinHeight; } + void minHeight(float value) + { + if (m_MinHeight == value) + { + return; + } + m_MinHeight = value; + minHeightChanged(); + } + + inline float borderLeft() const { return m_BorderLeft; } + void borderLeft(float value) + { + if (m_BorderLeft == value) + { + return; + } + m_BorderLeft = value; + borderLeftChanged(); + } + + inline float borderRight() const { return m_BorderRight; } + void borderRight(float value) + { + if (m_BorderRight == value) + { + return; + } + m_BorderRight = value; + borderRightChanged(); + } + + inline float borderTop() const { return m_BorderTop; } + void borderTop(float value) + { + if (m_BorderTop == value) + { + return; + } + m_BorderTop = value; + borderTopChanged(); + } + + inline float borderBottom() const { return m_BorderBottom; } + void borderBottom(float value) + { + if (m_BorderBottom == value) + { + return; + } + m_BorderBottom = value; + borderBottomChanged(); + } + + inline float marginLeft() const { return m_MarginLeft; } + void marginLeft(float value) + { + if (m_MarginLeft == value) + { + return; + } + m_MarginLeft = value; + marginLeftChanged(); + } + + inline float marginRight() const { return m_MarginRight; } + void marginRight(float value) + { + if (m_MarginRight == value) + { + return; + } + m_MarginRight = value; + marginRightChanged(); + } + + inline float marginTop() const { return m_MarginTop; } + void marginTop(float value) + { + if (m_MarginTop == value) + { + return; + } + m_MarginTop = value; + marginTopChanged(); + } + + inline float marginBottom() const { return m_MarginBottom; } + void marginBottom(float value) + { + if (m_MarginBottom == value) + { + return; + } + m_MarginBottom = value; + marginBottomChanged(); + } + + inline float paddingLeft() const { return m_PaddingLeft; } + void paddingLeft(float value) + { + if (m_PaddingLeft == value) + { + return; + } + m_PaddingLeft = value; + paddingLeftChanged(); + } + + inline float paddingRight() const { return m_PaddingRight; } + void paddingRight(float value) + { + if (m_PaddingRight == value) + { + return; + } + m_PaddingRight = value; + paddingRightChanged(); + } + + inline float paddingTop() const { return m_PaddingTop; } + void paddingTop(float value) + { + if (m_PaddingTop == value) + { + return; + } + m_PaddingTop = value; + paddingTopChanged(); + } + + inline float paddingBottom() const { return m_PaddingBottom; } + void paddingBottom(float value) + { + if (m_PaddingBottom == value) + { + return; + } + m_PaddingBottom = value; + paddingBottomChanged(); + } + + inline float positionLeft() const { return m_PositionLeft; } + void positionLeft(float value) + { + if (m_PositionLeft == value) + { + return; + } + m_PositionLeft = value; + positionLeftChanged(); + } + + inline float positionRight() const { return m_PositionRight; } + void positionRight(float value) + { + if (m_PositionRight == value) + { + return; + } + m_PositionRight = value; + positionRightChanged(); + } + + inline float positionTop() const { return m_PositionTop; } + void positionTop(float value) + { + if (m_PositionTop == value) + { + return; + } + m_PositionTop = value; + positionTopChanged(); + } + + inline float positionBottom() const { return m_PositionBottom; } + void positionBottom(float value) + { + if (m_PositionBottom == value) + { + return; + } + m_PositionBottom = value; + positionBottomChanged(); + } + + inline float flex() const { return m_Flex; } + void flex(float value) + { + if (m_Flex == value) + { + return; + } + m_Flex = value; + flexChanged(); + } + + inline float flexGrow() const { return m_FlexGrow; } + void flexGrow(float value) + { + if (m_FlexGrow == value) + { + return; + } + m_FlexGrow = value; + flexGrowChanged(); + } + + inline float flexShrink() const { return m_FlexShrink; } + void flexShrink(float value) + { + if (m_FlexShrink == value) + { + return; + } + m_FlexShrink = value; + flexShrinkChanged(); + } + + inline float flexBasis() const { return m_FlexBasis; } + void flexBasis(float value) + { + if (m_FlexBasis == value) + { + return; + } + m_FlexBasis = value; + flexBasisChanged(); + } + + inline float aspectRatio() const { return m_AspectRatio; } + void aspectRatio(float value) + { + if (m_AspectRatio == value) + { + return; + } + m_AspectRatio = value; + aspectRatioChanged(); + } + + Core* clone() const override; + void copy(const LayoutComponentStyleBase& object) + { + m_LayoutFlags0 = object.m_LayoutFlags0; + m_LayoutFlags1 = object.m_LayoutFlags1; + m_LayoutFlags2 = object.m_LayoutFlags2; + m_GapHorizontal = object.m_GapHorizontal; + m_GapVertical = object.m_GapVertical; + m_MaxWidth = object.m_MaxWidth; + m_MaxHeight = object.m_MaxHeight; + m_MinWidth = object.m_MinWidth; + m_MinHeight = object.m_MinHeight; + m_BorderLeft = object.m_BorderLeft; + m_BorderRight = object.m_BorderRight; + m_BorderTop = object.m_BorderTop; + m_BorderBottom = object.m_BorderBottom; + m_MarginLeft = object.m_MarginLeft; + m_MarginRight = object.m_MarginRight; + m_MarginTop = object.m_MarginTop; + m_MarginBottom = object.m_MarginBottom; + m_PaddingLeft = object.m_PaddingLeft; + m_PaddingRight = object.m_PaddingRight; + m_PaddingTop = object.m_PaddingTop; + m_PaddingBottom = object.m_PaddingBottom; + m_PositionLeft = object.m_PositionLeft; + m_PositionRight = object.m_PositionRight; + m_PositionTop = object.m_PositionTop; + m_PositionBottom = object.m_PositionBottom; + m_Flex = object.m_Flex; + m_FlexGrow = object.m_FlexGrow; + m_FlexShrink = object.m_FlexShrink; + m_FlexBasis = object.m_FlexBasis; + m_AspectRatio = object.m_AspectRatio; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case layoutFlags0PropertyKey: + m_LayoutFlags0 = CoreUintType::deserialize(reader); + return true; + case layoutFlags1PropertyKey: + m_LayoutFlags1 = CoreUintType::deserialize(reader); + return true; + case layoutFlags2PropertyKey: + m_LayoutFlags2 = CoreUintType::deserialize(reader); + return true; + case gapHorizontalPropertyKey: + m_GapHorizontal = CoreDoubleType::deserialize(reader); + return true; + case gapVerticalPropertyKey: + m_GapVertical = CoreDoubleType::deserialize(reader); + return true; + case maxWidthPropertyKey: + m_MaxWidth = CoreDoubleType::deserialize(reader); + return true; + case maxHeightPropertyKey: + m_MaxHeight = CoreDoubleType::deserialize(reader); + return true; + case minWidthPropertyKey: + m_MinWidth = CoreDoubleType::deserialize(reader); + return true; + case minHeightPropertyKey: + m_MinHeight = CoreDoubleType::deserialize(reader); + return true; + case borderLeftPropertyKey: + m_BorderLeft = CoreDoubleType::deserialize(reader); + return true; + case borderRightPropertyKey: + m_BorderRight = CoreDoubleType::deserialize(reader); + return true; + case borderTopPropertyKey: + m_BorderTop = CoreDoubleType::deserialize(reader); + return true; + case borderBottomPropertyKey: + m_BorderBottom = CoreDoubleType::deserialize(reader); + return true; + case marginLeftPropertyKey: + m_MarginLeft = CoreDoubleType::deserialize(reader); + return true; + case marginRightPropertyKey: + m_MarginRight = CoreDoubleType::deserialize(reader); + return true; + case marginTopPropertyKey: + m_MarginTop = CoreDoubleType::deserialize(reader); + return true; + case marginBottomPropertyKey: + m_MarginBottom = CoreDoubleType::deserialize(reader); + return true; + case paddingLeftPropertyKey: + m_PaddingLeft = CoreDoubleType::deserialize(reader); + return true; + case paddingRightPropertyKey: + m_PaddingRight = CoreDoubleType::deserialize(reader); + return true; + case paddingTopPropertyKey: + m_PaddingTop = CoreDoubleType::deserialize(reader); + return true; + case paddingBottomPropertyKey: + m_PaddingBottom = CoreDoubleType::deserialize(reader); + return true; + case positionLeftPropertyKey: + m_PositionLeft = CoreDoubleType::deserialize(reader); + return true; + case positionRightPropertyKey: + m_PositionRight = CoreDoubleType::deserialize(reader); + return true; + case positionTopPropertyKey: + m_PositionTop = CoreDoubleType::deserialize(reader); + return true; + case positionBottomPropertyKey: + m_PositionBottom = CoreDoubleType::deserialize(reader); + return true; + case flexPropertyKey: + m_Flex = CoreDoubleType::deserialize(reader); + return true; + case flexGrowPropertyKey: + m_FlexGrow = CoreDoubleType::deserialize(reader); + return true; + case flexShrinkPropertyKey: + m_FlexShrink = CoreDoubleType::deserialize(reader); + return true; + case flexBasisPropertyKey: + m_FlexBasis = CoreDoubleType::deserialize(reader); + return true; + case aspectRatioPropertyKey: + m_AspectRatio = CoreDoubleType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void layoutFlags0Changed() {} + virtual void layoutFlags1Changed() {} + virtual void layoutFlags2Changed() {} + virtual void gapHorizontalChanged() {} + virtual void gapVerticalChanged() {} + virtual void maxWidthChanged() {} + virtual void maxHeightChanged() {} + virtual void minWidthChanged() {} + virtual void minHeightChanged() {} + virtual void borderLeftChanged() {} + virtual void borderRightChanged() {} + virtual void borderTopChanged() {} + virtual void borderBottomChanged() {} + virtual void marginLeftChanged() {} + virtual void marginRightChanged() {} + virtual void marginTopChanged() {} + virtual void marginBottomChanged() {} + virtual void paddingLeftChanged() {} + virtual void paddingRightChanged() {} + virtual void paddingTopChanged() {} + virtual void paddingBottomChanged() {} + virtual void positionLeftChanged() {} + virtual void positionRightChanged() {} + virtual void positionTopChanged() {} + virtual void positionBottomChanged() {} + virtual void flexChanged() {} + virtual void flexGrowChanged() {} + virtual void flexShrinkChanged() {} + virtual void flexBasisChanged() {} + virtual void aspectRatioChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/layout_component_absolute_base.hpp b/include/rive/generated/layout_component_absolute_base.hpp new file mode 100644 index 00000000..b61486fe --- /dev/null +++ b/include/rive/generated/layout_component_absolute_base.hpp @@ -0,0 +1,39 @@ +#ifndef _RIVE_ABSOLUTE_LAYOUT_COMPONENT_BASE_HPP_ +#define _RIVE_ABSOLUTE_LAYOUT_COMPONENT_BASE_HPP_ +#include "rive/layout_component.hpp" +namespace rive +{ +class AbsoluteLayoutComponentBase : public LayoutComponent +{ +protected: + typedef LayoutComponent Super; + +public: + static const uint16_t typeKey = 423; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case AbsoluteLayoutComponentBase::typeKey: + case LayoutComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/layout_component_base.hpp b/include/rive/generated/layout_component_base.hpp new file mode 100644 index 00000000..e0c508a9 --- /dev/null +++ b/include/rive/generated/layout_component_base.hpp @@ -0,0 +1,129 @@ +#ifndef _RIVE_LAYOUT_COMPONENT_BASE_HPP_ +#define _RIVE_LAYOUT_COMPONENT_BASE_HPP_ +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/world_transform_component.hpp" +namespace rive +{ +class LayoutComponentBase : public WorldTransformComponent +{ +protected: + typedef WorldTransformComponent Super; + +public: + static const uint16_t typeKey = 409; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case LayoutComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t clipPropertyKey = 196; + static const uint16_t widthPropertyKey = 7; + static const uint16_t heightPropertyKey = 8; + static const uint16_t styleIdPropertyKey = 494; + +private: + bool m_Clip = true; + float m_Width = 0.0f; + float m_Height = 0.0f; + uint32_t m_StyleId = -1; + +public: + inline bool clip() const { return m_Clip; } + void clip(bool value) + { + if (m_Clip == value) + { + return; + } + m_Clip = value; + clipChanged(); + } + + inline float width() const { return m_Width; } + void width(float value) + { + if (m_Width == value) + { + return; + } + m_Width = value; + widthChanged(); + } + + inline float height() const { return m_Height; } + void height(float value) + { + if (m_Height == value) + { + return; + } + m_Height = value; + heightChanged(); + } + + inline uint32_t styleId() const { return m_StyleId; } + void styleId(uint32_t value) + { + if (m_StyleId == value) + { + return; + } + m_StyleId = value; + styleIdChanged(); + } + + Core* clone() const override; + void copy(const LayoutComponentBase& object) + { + m_Clip = object.m_Clip; + m_Width = object.m_Width; + m_Height = object.m_Height; + m_StyleId = object.m_StyleId; + WorldTransformComponent::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case clipPropertyKey: + m_Clip = CoreBoolType::deserialize(reader); + return true; + case widthPropertyKey: + m_Width = CoreDoubleType::deserialize(reader); + return true; + case heightPropertyKey: + m_Height = CoreDoubleType::deserialize(reader); + return true; + case styleIdPropertyKey: + m_StyleId = CoreUintType::deserialize(reader); + return true; + } + return WorldTransformComponent::deserialize(propertyKey, reader); + } + +protected: + virtual void clipChanged() {} + virtual void widthChanged() {} + virtual void heightChanged() {} + virtual void styleIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/nested_artboard_base.hpp b/include/rive/generated/nested_artboard_base.hpp index ce5d8747..141aa60f 100644 --- a/include/rive/generated/nested_artboard_base.hpp +++ b/include/rive/generated/nested_artboard_base.hpp @@ -34,9 +34,13 @@ class NestedArtboardBase : public Drawable uint16_t coreType() const override { return typeKey; } static const uint16_t artboardIdPropertyKey = 197; + static const uint16_t fitPropertyKey = 538; + static const uint16_t alignmentPropertyKey = 539; private: uint32_t m_ArtboardId = -1; + uint32_t m_Fit = 0; + uint32_t m_Alignment = 0; public: inline uint32_t artboardId() const { return m_ArtboardId; } @@ -50,10 +54,34 @@ class NestedArtboardBase : public Drawable artboardIdChanged(); } + inline uint32_t fit() const { return m_Fit; } + void fit(uint32_t value) + { + if (m_Fit == value) + { + return; + } + m_Fit = value; + fitChanged(); + } + + inline uint32_t alignment() const { return m_Alignment; } + void alignment(uint32_t value) + { + if (m_Alignment == value) + { + return; + } + m_Alignment = value; + alignmentChanged(); + } + Core* clone() const override; void copy(const NestedArtboardBase& object) { m_ArtboardId = object.m_ArtboardId; + m_Fit = object.m_Fit; + m_Alignment = object.m_Alignment; Drawable::copy(object); } @@ -64,12 +92,20 @@ class NestedArtboardBase : public Drawable case artboardIdPropertyKey: m_ArtboardId = CoreUintType::deserialize(reader); return true; + case fitPropertyKey: + m_Fit = CoreUintType::deserialize(reader); + return true; + case alignmentPropertyKey: + m_Alignment = CoreUintType::deserialize(reader); + return true; } return Drawable::deserialize(propertyKey, reader); } protected: virtual void artboardIdChanged() {} + virtual void fitChanged() {} + virtual void alignmentChanged() {} }; } // namespace rive diff --git a/include/rive/layout/layout_component_style.hpp b/include/rive/layout/layout_component_style.hpp new file mode 100644 index 00000000..277373ff --- /dev/null +++ b/include/rive/layout/layout_component_style.hpp @@ -0,0 +1,134 @@ +#ifndef _RIVE_LAYOUT_COMPONENT_STYLE_HPP_ +#define _RIVE_LAYOUT_COMPONENT_STYLE_HPP_ +#include "rive/generated/layout/layout_component_style_base.hpp" +#include "rive/math/bit_field_loc.hpp" +#ifdef WITH_RIVE_LAYOUT +#include "yoga/Yoga.h" +#endif +#include +namespace rive +{ +// ---- Flags 0 +static BitFieldLoc DisplayBits = BitFieldLoc(0, 0); +static BitFieldLoc PositionTypeBits = BitFieldLoc(1, 2); +static BitFieldLoc FlexDirectionBits = BitFieldLoc(3, 4); +static BitFieldLoc DirectionBits = BitFieldLoc(5, 6); +static BitFieldLoc AlignContentBits = BitFieldLoc(7, 9); +static BitFieldLoc AlignItemsBits = BitFieldLoc(10, 12); +static BitFieldLoc AlignSelfBits = BitFieldLoc(13, 15); +static BitFieldLoc JustifyContentBits = BitFieldLoc(16, 18); +static BitFieldLoc FlexWrapBits = BitFieldLoc(19, 20); +static BitFieldLoc OverflowBits = BitFieldLoc(21, 22); +static BitFieldLoc IntrinsicallySizedBits = BitFieldLoc(23, 23); +static BitFieldLoc WidthUnitsBits = BitFieldLoc(24, 25); +static BitFieldLoc HeightUnitsBits = BitFieldLoc(26, 27); + +// ---- Flags 1 +static BitFieldLoc BorderLeftUnitsBits = BitFieldLoc(0, 1); +static BitFieldLoc BorderRightUnitsBits = BitFieldLoc(2, 3); +static BitFieldLoc BorderTopUnitsBits = BitFieldLoc(4, 5); +static BitFieldLoc BorderBottomUnitsBits = BitFieldLoc(6, 7); +static BitFieldLoc MarginLeftUnitsBits = BitFieldLoc(8, 9); +static BitFieldLoc MarginRightUnitsBits = BitFieldLoc(10, 11); +static BitFieldLoc MarginTopUnitsBits = BitFieldLoc(12, 13); +static BitFieldLoc MarginBottomUnitsBits = BitFieldLoc(14, 15); +static BitFieldLoc PaddingLeftUnitsBits = BitFieldLoc(16, 17); +static BitFieldLoc PaddingRightUnitsBits = BitFieldLoc(18, 19); +static BitFieldLoc PaddingTopUnitsBits = BitFieldLoc(20, 21); +static BitFieldLoc PaddingBottomUnitsBits = BitFieldLoc(22, 23); +static BitFieldLoc PositionLeftUnitsBits = BitFieldLoc(24, 25); +static BitFieldLoc PositionRightUnitsBits = BitFieldLoc(26, 27); +static BitFieldLoc PositionTopUnitsBits = BitFieldLoc(28, 29); +static BitFieldLoc PositionBottomUnitsBits = BitFieldLoc(30, 31); + +// ---- Flags 2 +static BitFieldLoc GapHorizontalUnitsBits = BitFieldLoc(0, 1); +static BitFieldLoc GapVerticalUnitsBits = BitFieldLoc(2, 3); +static BitFieldLoc MinWidthUnitsBits = BitFieldLoc(4, 5); +static BitFieldLoc MinHeightUnitsBits = BitFieldLoc(6, 7); +static BitFieldLoc MaxWidthUnitsBits = BitFieldLoc(8, 9); +static BitFieldLoc MaxHeightUnitsBits = BitFieldLoc(10, 11); + +class LayoutComponentStyle : public LayoutComponentStyleBase +{ +public: + LayoutComponentStyle() {} + +#ifdef WITH_RIVE_LAYOUT + YGDisplay display(); + YGPositionType positionType(); + + YGFlexDirection flexDirection(); + YGDirection direction(); + YGWrap flexWrap(); + YGOverflow overflow(); + + YGAlign alignItems(); + YGAlign alignSelf(); + YGAlign alignContent(); + YGJustify justifyContent(); + bool intrinsicallySized(); + YGUnit widthUnits(); + YGUnit heightUnits(); + + YGUnit borderLeftUnits(); + YGUnit borderRightUnits(); + YGUnit borderTopUnits(); + YGUnit borderBottomUnits(); + YGUnit marginLeftUnits(); + YGUnit marginRightUnits(); + YGUnit marginTopUnits(); + YGUnit marginBottomUnits(); + YGUnit paddingLeftUnits(); + YGUnit paddingRightUnits(); + YGUnit paddingTopUnits(); + YGUnit paddingBottomUnits(); + YGUnit positionLeftUnits(); + YGUnit positionRightUnits(); + YGUnit positionTopUnits(); + YGUnit positionBottomUnits(); + + YGUnit gapHorizontalUnits(); + YGUnit gapVerticalUnits(); + YGUnit maxWidthUnits(); + YGUnit maxHeightUnits(); + YGUnit minWidthUnits(); + YGUnit minHeightUnits(); +#endif + + void markLayoutNodeDirty(); + + void layoutFlags0Changed() override; + void layoutFlags1Changed() override; + void layoutFlags2Changed() override; + void flexChanged() override; + void flexGrowChanged() override; + void flexShrinkChanged() override; + void flexBasisChanged() override; + void aspectRatioChanged() override; + void gapHorizontalChanged() override; + void gapVerticalChanged() override; + void maxWidthChanged() override; + void maxHeightChanged() override; + void minWidthChanged() override; + void minHeightChanged() override; + void borderLeftChanged() override; + void borderRightChanged() override; + void borderTopChanged() override; + void borderBottomChanged() override; + void marginLeftChanged() override; + void marginRightChanged() override; + void marginTopChanged() override; + void marginBottomChanged() override; + void paddingLeftChanged() override; + void paddingRightChanged() override; + void paddingTopChanged() override; + void paddingBottomChanged() override; + void positionLeftChanged() override; + void positionRightChanged() override; + void positionTopChanged() override; + void positionBottomChanged() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp new file mode 100644 index 00000000..e7c5d553 --- /dev/null +++ b/include/rive/layout_component.hpp @@ -0,0 +1,94 @@ +#ifndef _RIVE_LAYOUT_COMPONENT_HPP_ +#define _RIVE_LAYOUT_COMPONENT_HPP_ +#include "rive/generated/layout_component_base.hpp" +#include "rive/layout/layout_component_style.hpp" +#ifdef WITH_RIVE_LAYOUT +#include "yoga/YGNode.h" +#include "yoga/YGStyle.h" +#include "yoga/Yoga.h" +#endif +#include +namespace rive +{ +#ifndef WITH_RIVE_LAYOUT +class YGNodeRef +{ +public: + YGNodeRef() {} +}; +class YGStyle +{ +public: + YGStyle() {} +}; +#endif +class LayoutComponent : public LayoutComponentBase +{ +private: + LayoutComponentStyle* m_style = nullptr; + YGNodeRef m_layoutNode; + YGStyle* m_layoutStyle; + float m_layoutSizeWidth = 0; + float m_layoutSizeHeight = 0; + float m_layoutLocationX = 0; + float m_layoutLocationY = 0; + +#ifdef WITH_RIVE_LAYOUT +private: + void syncLayoutChildren(); + void propagateSizeToChildren(ContainerComponent* component); + AABB findMaxIntrinsicSize(ContainerComponent* component, AABB maxIntrinsicSize); + +protected: + void calculateLayout(); +#endif + +public: + LayoutComponentStyle* style() { return m_style; } + void style(LayoutComponentStyle* style) { m_style = style; } + +#ifdef WITH_RIVE_LAYOUT + YGNodeRef layoutNode() { return m_layoutNode; } + + YGStyle* layoutStyle() { return m_layoutStyle; } + + LayoutComponent() + { + m_layoutNode = new YGNode(); + m_layoutStyle = new YGStyle(); + } + + ~LayoutComponent() + { + YGNodeFreeRecursive(m_layoutNode); + delete m_layoutStyle; + } + void syncStyle(); + void propagateSize(); + void updateLayoutBounds(); + void update(ComponentDirt value) override; + StatusCode onAddedDirty(CoreContext* context) override; + +#else + LayoutComponent() + { + m_layoutNode = YGNodeRef(); + auto s = new YGStyle(); + m_layoutStyle = s; + m_layoutSizeWidth = 0; + m_layoutSizeHeight = 0; + m_layoutLocationX = 0; + m_layoutLocationY = 0; + } +#endif + void buildDependencies() override; + + void markLayoutNodeDirty(); + void clipChanged() override; + void widthChanged() override; + void heightChanged() override; + void styleIdChanged() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout_component_absolute.hpp b/include/rive/layout_component_absolute.hpp new file mode 100644 index 00000000..955f64c1 --- /dev/null +++ b/include/rive/layout_component_absolute.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_ABSOLUTE_LAYOUT_COMPONENT_HPP_ +#define _RIVE_ABSOLUTE_LAYOUT_COMPONENT_HPP_ +#include "rive/generated/layout_component_absolute_base.hpp" +#include +namespace rive +{ +class AbsoluteLayoutComponent : public AbsoluteLayoutComponentBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/math/bit_field_loc.hpp b/include/rive/math/bit_field_loc.hpp new file mode 100644 index 00000000..7c0c983c --- /dev/null +++ b/include/rive/math/bit_field_loc.hpp @@ -0,0 +1,28 @@ +#ifndef _RIVE_BIT_FIELD_LOC_HPP_ +#define _RIVE_BIT_FIELD_LOC_HPP_ + +#include +#include +#include +#include +#include + +namespace rive +{ + +class BitFieldLoc +{ +public: + BitFieldLoc(uint32_t start, uint32_t end); + + uint32_t read(uint32_t bits); + uint32_t write(uint32_t bits, uint32_t value); + +private: + uint32_t m_start; + uint32_t m_count; + uint32_t m_mask; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index 14bd7c13..3eac7dc7 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp @@ -8,6 +8,31 @@ namespace rive { + +enum class NestedArtboardFitType : uint8_t +{ + fill, // Default value - scales to fill available view without maintaining aspect ratio + contain, + cover, + fitWidth, + fitHeight, + resizeArtboard, + none, +}; + +enum class NestedArtboardAlignmentType : uint8_t +{ + center, // Default value + topLeft, + topCenter, + topRight, + centerLeft, + centerRight, + bottomLeft, + bottomCenter, + bottomRight, +}; + class ArtboardInstance; class NestedAnimation; class NestedInput; @@ -20,6 +45,8 @@ class NestedArtboard : public NestedArtboardBase Artboard* m_Artboard = nullptr; // might point to m_Instance, and might not std::unique_ptr m_Instance; // may be null std::vector m_NestedAnimations; + float m_layoutScaleX = NAN; + float m_layoutScaleY = NAN; public: NestedArtboard(); @@ -45,6 +72,17 @@ class NestedArtboard : public NestedArtboardBase NestedInput* input(std::string name) const; NestedInput* input(std::string name, std::string stateMachineName) const; + NestedArtboardAlignmentType alignmentType() const + { + return (NestedArtboardAlignmentType)alignment(); + } + NestedArtboardFitType fitType() const { return (NestedArtboardFitType)fit(); } + float effectiveScaleX() { return std::isnan(m_layoutScaleX) ? scaleX() : m_layoutScaleX; } + float effectiveScaleY() { return std::isnan(m_layoutScaleY) ? scaleY() : m_layoutScaleY; } + + AABB computeIntrinsicSize(AABB min, AABB max) override; + void controlSize(AABB size) override; + /// Convert a world space (relative to the artboard that this /// NestedArtboard is a child of) to the local space of the Artboard /// nested within. Returns true when the conversion succeeds, and false diff --git a/include/rive/shapes/image.hpp b/include/rive/shapes/image.hpp index 554c25b9..60a0c729 100644 --- a/include/rive/shapes/image.hpp +++ b/include/rive/shapes/image.hpp @@ -24,6 +24,8 @@ class Image : public ImageBase, public FileAssetReferencer void setAsset(FileAsset*) override; uint32_t assetId() override; Core* clone() const override; + AABB computeIntrinsicSize(AABB min, AABB max) override; + void controlSize(AABB size) override; }; } // namespace rive diff --git a/include/rive/shapes/parametric_path.hpp b/include/rive/shapes/parametric_path.hpp index 03f872ac..7bb32044 100644 --- a/include/rive/shapes/parametric_path.hpp +++ b/include/rive/shapes/parametric_path.hpp @@ -1,10 +1,15 @@ #ifndef _RIVE_PARAMETRIC_PATH_HPP_ #define _RIVE_PARAMETRIC_PATH_HPP_ +#include "rive/math/aabb.hpp" #include "rive/generated/shapes/parametric_path_base.hpp" namespace rive { class ParametricPath : public ParametricPathBase { +public: + AABB computeIntrinsicSize(AABB min, AABB max) override; + void controlSize(AABB size) override; + protected: void widthChanged() override; void heightChanged() override; diff --git a/include/rive/text/text.hpp b/include/rive/text/text.hpp index bed19f2d..073af1d2 100644 --- a/include/rive/text/text.hpp +++ b/include/rive/text/text.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_TEXT_CORE_HPP_ #define _RIVE_TEXT_CORE_HPP_ #include "rive/generated/text/text_base.hpp" +#include "rive/math/aabb.hpp" #include "rive/text/text_value_run.hpp" #include "rive/text_engine.hpp" #include "rive/simple_array.hpp" @@ -170,12 +171,16 @@ class Text : public TextBase Core* hitTest(HitInfo*, const Mat2D&) override; void addRun(TextValueRun* run); void addModifierGroup(TextModifierGroup* group); - void markShapeDirty(); + void markShapeDirty(bool sendToLayout = true); void modifierShapeDirty(); void markPaintDirty(); void update(ComponentDirt value) override; TextSizing sizing() const { return (TextSizing)sizingValue(); } + TextSizing effectiveSizing() const + { + return std::isnan(m_layoutHeight) ? sizing() : TextSizing::fixed; + } TextOverflow overflow() const { return (TextOverflow)overflowValue(); } TextOrigin textOrigin() const { return (TextOrigin)originValue(); } void overflow(TextOverflow value) { return overflowValue((uint32_t)value); } @@ -185,6 +190,11 @@ class Text : public TextBase AABB localBounds() const override; void originXChanged() override; void originYChanged() override; + + AABB computeIntrinsicSize(AABB min, AABB max) override; + void controlSize(AABB size) override; + float effectiveWidth() { return std::isnan(m_layoutWidth) ? width() : m_layoutWidth; } + float effectiveHeight() { return std::isnan(m_layoutHeight) ? height() : m_layoutHeight; } #ifdef WITH_RIVE_TEXT const std::vector& runs() const { return m_runs; } #endif @@ -235,6 +245,9 @@ class Text : public TextBase GlyphLookup m_glyphLookup; #endif + float m_layoutWidth = NAN; + float m_layoutHeight = NAN; + AABB measure(AABB maxSize); }; } // namespace rive diff --git a/include/rive/transform_component.hpp b/include/rive/transform_component.hpp index 8b13bce0..6b63a11c 100644 --- a/include/rive/transform_component.hpp +++ b/include/rive/transform_component.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_TRANSFORM_COMPONENT_HPP_ #define _RIVE_TRANSFORM_COMPONENT_HPP_ #include "rive/generated/transform_component_base.hpp" +#include "rive/math/aabb.hpp" #include "rive/math/mat2d.hpp" namespace rive @@ -47,6 +48,9 @@ class TransformComponent : public TransformComponentBase void addConstraint(Constraint* constraint); virtual AABB localBounds() const; void markDirtyIfConstrained(); + + virtual AABB computeIntrinsicSize(AABB min, AABB max) { return AABB(); } + virtual void controlSize(AABB size) {} }; } // namespace rive diff --git a/premake5_v2.lua b/premake5_v2.lua index 5311fb73..44244a27 100644 --- a/premake5_v2.lua +++ b/premake5_v2.lua @@ -22,12 +22,17 @@ do 'MA_NO_RESOURCE_MANAGER', }) end +filter({ 'options:with_rive_layout' }) +do + defines({ 'WITH_RIVE_LAYOUT' }) +end filter({}) dependencies = path.getabsolute('dependencies/') dofile(path.join(dependencies, 'premake5_harfbuzz_v2.lua')) dofile(path.join(dependencies, 'premake5_sheenbidi_v2.lua')) dofile(path.join(dependencies, 'premake5_miniaudio_v2.lua')) +dofile(path.join(dependencies, 'premake5_yoga_v2.lua')) project('rive') do @@ -38,8 +43,11 @@ do harfbuzz .. '/src', sheenbidi .. '/Headers', miniaudio, + yoga, }) + defines({ 'YOGA_EXPORT=' }) + files({ 'src/**.cpp' }) flags({ 'FatalCompileWarnings' }) @@ -157,3 +165,8 @@ newoption({ description = 'The audio mode to use.', allowed = { { 'disabled' }, { 'system' }, { 'external' } }, }) + +newoption({ + trigger = 'with_rive_layout', + description = 'Compiles in layout features.', +}) \ No newline at end of file diff --git a/src/artboard.cpp b/src/artboard.cpp index 6fb08e7a..9a9b7414 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -509,6 +509,26 @@ bool Artboard::updateComponents() bool Artboard::advance(double elapsedSeconds) { m_HasChangedDrawOrderInLastUpdate = false; +#ifdef WITH_RIVE_LAYOUT + if (!m_dirtyLayout.empty()) + { + syncStyle(); + for (auto layout : m_dirtyLayout) + { + layout->syncStyle(); + } + m_dirtyLayout.clear(); + calculateLayout(); + for (auto dep : m_DependencyOrder) + { + if (dep->is()) + { + auto layout = dep->as(); + layout->updateLayoutBounds(); + } + } + } +#endif if (m_JoysticksApplyBeforeUpdate) { for (auto joystick : m_Joysticks) diff --git a/src/generated/layout/layout_component_style_base.cpp b/src/generated/layout/layout_component_style_base.cpp new file mode 100644 index 00000000..22c4da87 --- /dev/null +++ b/src/generated/layout/layout_component_style_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout/layout_component_style_base.hpp" +#include "rive/layout/layout_component_style.hpp" + +using namespace rive; + +Core* LayoutComponentStyleBase::clone() const +{ + auto cloned = new LayoutComponentStyle(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/layout_component_absolute_base.cpp b/src/generated/layout_component_absolute_base.cpp new file mode 100644 index 00000000..c35c4a8f --- /dev/null +++ b/src/generated/layout_component_absolute_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout_component_absolute_base.hpp" +#include "rive/layout_component_absolute.hpp" + +using namespace rive; + +Core* AbsoluteLayoutComponentBase::clone() const +{ + auto cloned = new AbsoluteLayoutComponent(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/layout_component_base.cpp b/src/generated/layout_component_base.cpp new file mode 100644 index 00000000..13e6c86d --- /dev/null +++ b/src/generated/layout_component_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout_component_base.hpp" +#include "rive/layout_component.hpp" + +using namespace rive; + +Core* LayoutComponentBase::clone() const +{ + auto cloned = new LayoutComponent(); + cloned->copy(*this); + return cloned; +} diff --git a/src/layout/layout_component_style.cpp b/src/layout/layout_component_style.cpp new file mode 100644 index 00000000..882d7521 --- /dev/null +++ b/src/layout/layout_component_style.cpp @@ -0,0 +1,203 @@ +#include "rive/layout_component.hpp" +#include "rive/layout/layout_component_style.hpp" +#include + +using namespace rive; + +#ifdef WITH_RIVE_LAYOUT +YGDisplay LayoutComponentStyle::display() { return YGDisplay(DisplayBits.read(layoutFlags0())); } + +YGPositionType LayoutComponentStyle::positionType() +{ + return YGPositionType(PositionTypeBits.read(layoutFlags0())); +} + +YGFlexDirection LayoutComponentStyle::flexDirection() +{ + return YGFlexDirection(FlexDirectionBits.read(layoutFlags0())); +} + +YGDirection LayoutComponentStyle::direction() +{ + return YGDirection(DirectionBits.read(layoutFlags0())); +} + +YGWrap LayoutComponentStyle::flexWrap() { return YGWrap(FlexWrapBits.read(layoutFlags0())); } + +YGAlign LayoutComponentStyle::alignItems() { return YGAlign(AlignItemsBits.read(layoutFlags0())); } + +YGAlign LayoutComponentStyle::alignSelf() { return YGAlign(AlignSelfBits.read(layoutFlags0())); } + +YGAlign LayoutComponentStyle::alignContent() +{ + return YGAlign(AlignContentBits.read(layoutFlags0())); +} + +YGJustify LayoutComponentStyle::justifyContent() +{ + return YGJustify(JustifyContentBits.read(layoutFlags0())); +} + +YGOverflow LayoutComponentStyle::overflow() +{ + return YGOverflow(OverflowBits.read(layoutFlags0())); +} + +bool LayoutComponentStyle::intrinsicallySized() +{ + return IntrinsicallySizedBits.read(layoutFlags0()) == 1; +} + +YGUnit LayoutComponentStyle::widthUnits() { return YGUnit(WidthUnitsBits.read(layoutFlags0())); } + +YGUnit LayoutComponentStyle::heightUnits() { return YGUnit(HeightUnitsBits.read(layoutFlags0())); } + +YGUnit LayoutComponentStyle::borderLeftUnits() +{ + return YGUnit(BorderLeftUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::borderRightUnits() +{ + return YGUnit(BorderRightUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::borderTopUnits() +{ + return YGUnit(BorderTopUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::borderBottomUnits() +{ + return YGUnit(BorderBottomUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::marginLeftUnits() +{ + return YGUnit(MarginLeftUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::marginRightUnits() +{ + return YGUnit(MarginRightUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::marginTopUnits() +{ + return YGUnit(MarginTopUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::marginBottomUnits() +{ + return YGUnit(MarginBottomUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::paddingLeftUnits() +{ + return YGUnit(PaddingLeftUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::paddingRightUnits() +{ + return YGUnit(PaddingRightUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::paddingTopUnits() +{ + return YGUnit(PaddingTopUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::paddingBottomUnits() +{ + return YGUnit(PaddingBottomUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::positionLeftUnits() +{ + return YGUnit(PositionLeftUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::positionRightUnits() +{ + return YGUnit(PositionRightUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::positionTopUnits() +{ + return YGUnit(PositionTopUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::positionBottomUnits() +{ + return YGUnit(PositionBottomUnitsBits.read(layoutFlags1())); +} + +YGUnit LayoutComponentStyle::gapHorizontalUnits() +{ + return YGUnit(GapHorizontalUnitsBits.read(layoutFlags2())); +} + +YGUnit LayoutComponentStyle::gapVerticalUnits() +{ + return YGUnit(GapVerticalUnitsBits.read(layoutFlags2())); +} + +YGUnit LayoutComponentStyle::maxWidthUnits() +{ + return YGUnit(MaxWidthUnitsBits.read(layoutFlags2())); +} + +YGUnit LayoutComponentStyle::maxHeightUnits() +{ + return YGUnit(MaxHeightUnitsBits.read(layoutFlags2())); +} + +YGUnit LayoutComponentStyle::minWidthUnits() +{ + return YGUnit(MinWidthUnitsBits.read(layoutFlags2())); +} +YGUnit LayoutComponentStyle::minHeightUnits() +{ + return YGUnit(MinHeightUnitsBits.read(layoutFlags2())); +} +void LayoutComponentStyle::markLayoutNodeDirty() +{ + if (parent()->is()) + { + parent()->as()->markLayoutNodeDirty(); + } +} +#else +void LayoutComponentStyle::markLayoutNodeDirty() {} +#endif + +void LayoutComponentStyle::layoutFlags0Changed() { markLayoutNodeDirty(); } +void LayoutComponentStyle::layoutFlags1Changed() { markLayoutNodeDirty(); } +void LayoutComponentStyle::layoutFlags2Changed() { markLayoutNodeDirty(); } +void LayoutComponentStyle::flexChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::flexGrowChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::flexShrinkChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::flexBasisChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::aspectRatioChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::gapHorizontalChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::gapVerticalChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::maxWidthChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::maxHeightChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::minWidthChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::minHeightChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderLeftChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderRightChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderTopChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderBottomChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginLeftChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginRightChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginTopChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginBottomChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingLeftChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingRightChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingTopChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingBottomChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionLeftChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionRightChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionTopChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionBottomChanged() { markLayoutNodeDirty(); } \ No newline at end of file diff --git a/src/layout_component.cpp b/src/layout_component.cpp new file mode 100644 index 00000000..ac908f63 --- /dev/null +++ b/src/layout_component.cpp @@ -0,0 +1,278 @@ +#include "rive/artboard.hpp" +#include "rive/layout_component.hpp" +#include "rive/node.hpp" +#include "rive/math/aabb.hpp" +#ifdef WITH_RIVE_LAYOUT +#include "rive/transform_component.hpp" +#include "yoga/YGEnums.h" +#include "yoga/YGFloatOptional.h" +#endif +#include + +using namespace rive; + +void LayoutComponent::buildDependencies() +{ + Super::buildDependencies(); + if (parent() != nullptr) + { + parent()->addDependent(this); + } +} + +#ifdef WITH_RIVE_LAYOUT +StatusCode LayoutComponent::onAddedDirty(CoreContext* context) +{ + auto code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto coreStyle = context->resolve(styleId()); + if (coreStyle == nullptr || !coreStyle->is()) + { + return StatusCode::MissingObject; + } + m_style = static_cast(coreStyle); + addChild(m_style); + artboard()->markLayoutDirty(this); + if (parent() != nullptr && parent()->is()) + { + parent()->as()->syncLayoutChildren(); + } + return StatusCode::Ok; +} + +void LayoutComponent::update(ComponentDirt value) +{ + if (hasDirt(value, ComponentDirt::WorldTransform)) + { + Mat2D parentWorld = parent()->is() + ? (parent()->as())->worldTransform() + : Mat2D(); + auto transform = Mat2D(); + transform[4] = m_layoutLocationX; + transform[5] = m_layoutLocationY; + + auto multipliedTransform = Mat2D::multiply(parentWorld, transform); + m_WorldTransform = multipliedTransform; + } +} + +AABB LayoutComponent::findMaxIntrinsicSize(ContainerComponent* component, AABB maxIntrinsicSize) +{ + auto intrinsicSize = maxIntrinsicSize; + for (auto child : component->children()) + { + if (child->is()) + { + continue; + } + if (child->is()) + { + auto sizableChild = child->as(); + auto minSize = + AABB::fromLTWH(0, + 0, + style()->minWidthUnits() == YGUnitPoint ? style()->minWidth() : 0, + style()->minHeightUnits() == YGUnitPoint ? style()->minHeight() : 0); + auto maxSize = AABB::fromLTWH( + 0, + 0, + style()->maxWidthUnits() == YGUnitPoint ? style()->maxWidth() + : std::numeric_limits::infinity(), + style()->maxHeightUnits() == YGUnitPoint ? style()->maxHeight() + : std::numeric_limits::infinity()); + auto size = sizableChild->computeIntrinsicSize(minSize, maxSize); + intrinsicSize = AABB::fromLTWH(0, + 0, + std::max(maxIntrinsicSize.width(), size.width()), + std::max(maxIntrinsicSize.height(), size.height())); + } + if (child->is()) + { + return findMaxIntrinsicSize(child->as(), intrinsicSize); + } + } + return intrinsicSize; +} + +void LayoutComponent::syncStyle() +{ + if (style() == nullptr || layoutStyle() == nullptr || layoutNode() == nullptr) + { + return; + } + bool setIntrinsicWidth = false; + bool setIntrinsicHeight = false; + if (style()->intrinsicallySized() && + (style()->widthUnits() == YGUnitAuto || style()->heightUnits() == YGUnitAuto)) + { + AABB intrinsicSize = findMaxIntrinsicSize(this, AABB()); + bool foundIntrinsicSize = intrinsicSize.width() != 0 || intrinsicSize.height() != 0; + + if (foundIntrinsicSize) + { + if (style()->widthUnits() == YGUnitAuto) + { + setIntrinsicWidth = true; + layoutStyle()->dimensions()[YGDimensionWidth] = + YGValue{intrinsicSize.width(), YGUnitPoint}; + } + if (style()->heightUnits() == YGUnitAuto) + { + setIntrinsicHeight = true; + layoutStyle()->dimensions()[YGDimensionHeight] = + YGValue{intrinsicSize.height(), YGUnitPoint}; + } + } + } + if (!setIntrinsicWidth) + { + layoutStyle()->dimensions()[YGDimensionWidth] = YGValue{width(), style()->widthUnits()}; + } + if (!setIntrinsicHeight) + { + layoutStyle()->dimensions()[YGDimensionHeight] = YGValue{height(), style()->heightUnits()}; + } + layoutStyle()->minDimensions()[YGDimensionWidth] = + YGValue{style()->minWidth(), style()->minWidthUnits()}; + layoutStyle()->minDimensions()[YGDimensionHeight] = + YGValue{style()->minHeight(), style()->minHeightUnits()}; + layoutStyle()->maxDimensions()[YGDimensionWidth] = + YGValue{style()->maxWidth(), style()->maxWidthUnits()}; + layoutStyle()->maxDimensions()[YGDimensionHeight] = + YGValue{style()->maxHeight(), style()->maxHeightUnits()}; + + layoutStyle()->gap()[YGGutterColumn] = + YGValue{style()->gapHorizontal(), style()->gapHorizontalUnits()}; + layoutStyle()->gap()[YGGutterRow] = + YGValue{style()->gapVertical(), style()->gapVerticalUnits()}; + layoutStyle()->border()[YGEdgeLeft] = + YGValue{style()->borderLeft(), style()->borderLeftUnits()}; + layoutStyle()->border()[YGEdgeRight] = + YGValue{style()->borderRight(), style()->borderRightUnits()}; + layoutStyle()->border()[YGEdgeTop] = YGValue{style()->borderTop(), style()->borderTopUnits()}; + layoutStyle()->border()[YGEdgeBottom] = + YGValue{style()->borderBottom(), style()->borderBottomUnits()}; + layoutStyle()->margin()[YGEdgeLeft] = + YGValue{style()->marginLeft(), style()->marginLeftUnits()}; + layoutStyle()->margin()[YGEdgeRight] = + YGValue{style()->marginRight(), style()->marginRightUnits()}; + layoutStyle()->margin()[YGEdgeTop] = YGValue{style()->marginTop(), style()->marginTopUnits()}; + layoutStyle()->margin()[YGEdgeBottom] = + YGValue{style()->marginBottom(), style()->marginBottomUnits()}; + layoutStyle()->padding()[YGEdgeLeft] = + YGValue{style()->paddingLeft(), style()->paddingLeftUnits()}; + layoutStyle()->padding()[YGEdgeRight] = + YGValue{style()->paddingRight(), style()->paddingRightUnits()}; + layoutStyle()->padding()[YGEdgeTop] = + YGValue{style()->paddingTop(), style()->paddingTopUnits()}; + layoutStyle()->padding()[YGEdgeBottom] = + YGValue{style()->paddingBottom(), style()->paddingBottomUnits()}; + layoutStyle()->position()[YGEdgeLeft] = + YGValue{style()->positionLeft(), style()->positionLeftUnits()}; + layoutStyle()->position()[YGEdgeRight] = + YGValue{style()->positionRight(), style()->positionRightUnits()}; + layoutStyle()->position()[YGEdgeTop] = + YGValue{style()->positionTop(), style()->positionTopUnits()}; + layoutStyle()->position()[YGEdgeBottom] = + YGValue{style()->positionBottom(), style()->positionBottomUnits()}; + + layoutStyle()->display() = style()->display(); + layoutStyle()->positionType() = style()->positionType(); + layoutStyle()->flex() = YGFloatOptional(style()->flex()); + layoutStyle()->flexGrow() = YGFloatOptional(style()->flexGrow()); + layoutStyle()->flexShrink() = YGFloatOptional(style()->flexShrink()); + // layoutStyle()->flexBasis() = style()->flexBasis(); + layoutStyle()->flexDirection() = style()->flexDirection(); + layoutStyle()->flexWrap() = style()->flexWrap(); + layoutStyle()->alignItems() = style()->alignItems(); + layoutStyle()->alignContent() = style()->alignContent(); + layoutStyle()->alignSelf() = style()->alignSelf(); + layoutStyle()->justifyContent() = style()->justifyContent(); + + layoutNode()->setStyle(*layoutStyle()); +} + +void LayoutComponent::syncLayoutChildren() +{ + YGNodeRemoveAllChildren(layoutNode()); + int index = 0; + for (size_t i = 0; i < children().size(); i++) + { + Component* child = children()[i]; + if (child->is()) + { + YGNodeInsertChild(layoutNode(), child->as()->layoutNode(), index); + index += 1; + } + } +} + +void LayoutComponent::propagateSize() +{ + if (artboard() == this) + { + return; + } + propagateSizeToChildren(this); +} + +void LayoutComponent::propagateSizeToChildren(ContainerComponent* component) +{ + for (auto child : component->children()) + { + if (child->is() || child->coreType() == NodeBase::typeKey) + { + continue; + } + if (child->is()) + { + auto sizableChild = child->as(); + sizableChild->controlSize(AABB::fromLTWH(0, 0, m_layoutSizeWidth, m_layoutSizeHeight)); + } + if (child->is()) + { + propagateSizeToChildren(child->as()); + } + } +} + +void LayoutComponent::calculateLayout() +{ + YGNodeCalculateLayout(layoutNode(), width(), height(), YGDirection::YGDirectionInherit); +} + +void LayoutComponent::updateLayoutBounds() +{ + auto left = YGNodeLayoutGetLeft(layoutNode()); + auto top = YGNodeLayoutGetTop(layoutNode()); + auto width = YGNodeLayoutGetWidth(layoutNode()); + auto height = YGNodeLayoutGetHeight(layoutNode()); + if (left != m_layoutLocationX || top != m_layoutLocationY || width != m_layoutSizeWidth || + height != m_layoutSizeHeight) + { + m_layoutLocationX = left; + m_layoutLocationY = top; + m_layoutSizeWidth = width; + m_layoutSizeHeight = height; + propagateSize(); + markWorldTransformDirty(); + } +} + +void LayoutComponent::markLayoutNodeDirty() +{ + layoutNode()->markDirtyAndPropagate(); + artboard()->markLayoutDirty(this); +} +#else +void LayoutComponent::markLayoutNodeDirty() {} +#endif + +void LayoutComponent::clipChanged() { markLayoutNodeDirty(); } +void LayoutComponent::widthChanged() { markLayoutNodeDirty(); } +void LayoutComponent::heightChanged() { markLayoutNodeDirty(); } +void LayoutComponent::styleIdChanged() { markLayoutNodeDirty(); } \ No newline at end of file diff --git a/src/math/bit_field_loc.cpp b/src/math/bit_field_loc.cpp new file mode 100644 index 00000000..377b10aa --- /dev/null +++ b/src/math/bit_field_loc.cpp @@ -0,0 +1,20 @@ +#include "rive/math/bit_field_loc.hpp" +#include + +using namespace rive; + +BitFieldLoc::BitFieldLoc(uint32_t start, uint32_t end) : m_start(start) +{ + assert(end >= start); + assert(end < 32); + + m_count = end - start + 1; + m_mask = ((1 << (end - start + 1)) - 1) << start; +} + +uint32_t BitFieldLoc::read(uint32_t bits) { return (bits & m_mask) >> m_start; } + +uint32_t BitFieldLoc::write(uint32_t bits, uint32_t value) +{ + return (bits & ~m_mask) | ((value << m_start) & m_mask); +} \ No newline at end of file diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 1c580409..7bf7df29 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -230,4 +230,19 @@ bool NestedArtboard::worldToLocal(Vec2D world, Vec2D* local) *local = toMountedArtboard * world; return true; +} + +AABB NestedArtboard::computeIntrinsicSize(AABB min, AABB max) { return max; } + +void NestedArtboard::controlSize(AABB size) +{ + auto newScaleX = size.width() / m_Artboard->originalWidth(); + auto newScaleY = size.height() / m_Artboard->originalHeight(); + if (newScaleX != scaleX() || newScaleY != scaleY()) + { + // TODO: Support nested artboard fit & alignment + scaleX(newScaleX); + scaleY(newScaleY); + addDirt(ComponentDirt::WorldTransform, false); + } } \ No newline at end of file diff --git a/src/shapes/image.cpp b/src/shapes/image.cpp index 021f84ba..c2f21cf7 100644 --- a/src/shapes/image.cpp +++ b/src/shapes/image.cpp @@ -121,3 +121,18 @@ Core* Image::clone() const void Image::setMesh(Mesh* mesh) { m_Mesh = mesh; } Mesh* Image::mesh() const { return m_Mesh; } + +AABB Image::computeIntrinsicSize(AABB min, AABB max) { return max; } + +void Image::controlSize(AABB size) +{ + auto renderImage = imageAsset()->renderImage(); + auto newScaleX = size.width() / renderImage->width(); + auto newScaleY = size.height() / renderImage->height(); + if (newScaleX != scaleX() || newScaleY != scaleY()) + { + scaleX(newScaleX); + scaleY(newScaleY); + addDirt(ComponentDirt::WorldTransform, false); + } +} \ No newline at end of file diff --git a/src/shapes/parametric_path.cpp b/src/shapes/parametric_path.cpp index 923d1d7d..534dfc4c 100644 --- a/src/shapes/parametric_path.cpp +++ b/src/shapes/parametric_path.cpp @@ -1,7 +1,20 @@ +#include "rive/math/aabb.hpp" #include "rive/shapes/parametric_path.hpp" using namespace rive; +AABB ParametricPath::computeIntrinsicSize(AABB min, AABB max) +{ + return AABB::fromLTWH(0, 0, width(), height()); +} + +void ParametricPath::controlSize(AABB size) +{ + width(size.width()); + height(size.height()); + markWorldTransformDirty(); +} + void ParametricPath::widthChanged() { markPathDirty(); } void ParametricPath::heightChanged() { markPathDirty(); } void ParametricPath::originXChanged() { markPathDirty(); } diff --git a/src/text/text.cpp b/src/text/text.cpp index 56bbbfd3..84311400 100644 --- a/src/text/text.cpp +++ b/src/text/text.cpp @@ -241,6 +241,18 @@ bool OrderedLine::buildEllipsisRuns(std::vector& logicalRuns, return true; } +AABB Text::computeIntrinsicSize(AABB min, AABB max) { return measure(max); } + +void Text::controlSize(AABB size) +{ + if (m_layoutWidth != size.width() || m_layoutHeight != size.height()) + { + m_layoutWidth = size.width(); + m_layoutHeight = size.height(); + markShapeDirty(false); + } +} + void Text::buildRenderStyles() { for (TextStyle* style : m_renderStyles) @@ -270,7 +282,8 @@ void Text::buildRenderStyles() bool isEllipsisLineLast = false; // Find the line to put the ellipsis on (line before the one that // overflows). - bool wantEllipsis = overflow() == TextOverflow::ellipsis && sizing() == TextSizing::fixed; + bool wantEllipsis = + overflow() == TextOverflow::ellipsis && effectiveSizing() == TextSizing::fixed; int lastLineIndex = -1; for (const SimpleArray& paragraphLines : m_lines) @@ -287,7 +300,7 @@ void Text::buildRenderStyles() maxWidth = width; } lastLineIndex++; - if (wantEllipsis && y + line.bottom <= height()) + if (wantEllipsis && y + line.bottom <= effectiveHeight()) { ellipsisLine++; } @@ -308,16 +321,16 @@ void Text::buildRenderStyles() int lineIndex = 0; paragraphIndex = 0; - switch (sizing()) + switch (effectiveSizing()) { case TextSizing::autoWidth: m_bounds = AABB(0.0f, minY, maxWidth, std::max(minY, y - paragraphSpace)); break; case TextSizing::autoHeight: - m_bounds = AABB(0.0f, minY, width(), std::max(minY, y - paragraphSpace)); + m_bounds = AABB(0.0f, minY, effectiveWidth(), std::max(minY, y - paragraphSpace)); break; case TextSizing::fixed: - m_bounds = AABB(0.0f, minY, width(), minY + height()); + m_bounds = AABB(0.0f, minY, effectiveWidth(), minY + effectiveHeight()); break; } @@ -366,13 +379,14 @@ void Text::buildRenderStyles() switch (overflow()) { case TextOverflow::hidden: - if (sizing() == TextSizing::fixed && y + line.bottom > height()) + if (effectiveSizing() == TextSizing::fixed && + y + line.bottom > effectiveHeight()) { return; } break; case TextOverflow::clipped: - if (sizing() == TextSizing::fixed && y + line.top > height()) + if (effectiveSizing() == TextSizing::fixed && y + line.top > effectiveHeight()) { return; } @@ -386,7 +400,7 @@ void Text::buildRenderStyles() // We need to still compute this line's ordered runs. m_orderedLines.emplace_back(OrderedLine(paragraph, line, - width(), + effectiveWidth(), ellipsisLine == lineIndex, isEllipsisLineLast, &m_ellipsisRun)); @@ -512,7 +526,7 @@ void Text::addRun(TextValueRun* run) { m_runs.push_back(run); } void Text::addModifierGroup(TextModifierGroup* group) { m_modifierGroups.push_back(group); } -void Text::markShapeDirty() +void Text::markShapeDirty(bool sendToLayout) { addDirt(ComponentDirt::Path); for (TextModifierGroup* group : m_modifierGroups) @@ -520,6 +534,18 @@ void Text::markShapeDirty() group->clearRangeMaps(); } markWorldTransformDirty(); +#ifdef WITH_RIVE_LAYOUT + if (sendToLayout) + { + for (ContainerComponent* p = parent(); p != nullptr; p = p->parent()) + { + if (p->is()) + { + p->as()->markLayoutNodeDirty(); + } + } + } +#endif } void Text::modifierShapeDirty() { addDirt(ComponentDirt::Path); } @@ -532,7 +558,7 @@ void Text::sizingValueChanged() { markShapeDirty(); } void Text::overflowValueChanged() { - if (sizing() != TextSizing::autoWidth) + if (effectiveSizing() != TextSizing::autoWidth) { markShapeDirty(); } @@ -540,7 +566,7 @@ void Text::overflowValueChanged() void Text::widthChanged() { - if (sizing() != TextSizing::autoWidth) + if (effectiveSizing() != TextSizing::autoWidth) { markShapeDirty(); } @@ -550,7 +576,7 @@ void Text::paragraphSpacingChanged() { markPaintDirty(); } void Text::heightChanged() { - if (sizing() == TextSizing::fixed) + if (effectiveSizing() == TextSizing::fixed) { markShapeDirty(); } @@ -670,9 +696,10 @@ void Text::update(ComponentDirt value) makeStyled(m_modifierStyledText, false); auto runs = m_modifierStyledText.runs(); m_modifierShape = runs[0].font->shapeText(m_modifierStyledText.unichars(), runs); - m_modifierLines = breakLines(m_modifierShape, - sizing() == TextSizing::autoWidth ? -1.0f : width(), - (TextAlign)alignValue()); + m_modifierLines = + breakLines(m_modifierShape, + effectiveSizing() == TextSizing::autoWidth ? -1.0f : effectiveWidth(), + (TextAlign)alignValue()); m_glyphLookup.compute(m_modifierStyledText.unichars(), m_modifierShape); uint32_t textSize = (uint32_t)m_modifierStyledText.unichars().size(); for (TextModifierGroup* group : m_modifierGroups) @@ -688,9 +715,10 @@ void Text::update(ComponentDirt value) { auto runs = m_styledText.runs(); m_shape = runs[0].font->shapeText(m_styledText.unichars(), runs); - m_lines = breakLines(m_shape, - sizing() == TextSizing::autoWidth ? -1.0f : width(), - (TextAlign)alignValue()); + m_lines = + breakLines(m_shape, + effectiveSizing() == TextSizing::autoWidth ? -1.0f : effectiveWidth(), + (TextAlign)alignValue()); if (!precomputeModifierCoverage && haveModifiers()) { m_glyphLookup.compute(m_styledText.unichars(), m_shape); @@ -732,6 +760,64 @@ void Text::update(ComponentDirt value) } } +AABB Text::measure(AABB maxSize) +{ + if (makeStyled(m_styledText)) + { + const float paragraphSpace = paragraphSpacing(); + auto runs = m_styledText.runs(); + auto shape = runs[0].font->shapeText(m_styledText.unichars(), runs); + auto lines = + breakLines(shape, + effectiveSizing() == TextSizing::autoWidth ? -1.0f : effectiveWidth(), + (TextAlign)alignValue()); + float y = 0; + float minY = 0; + int paragraphIndex = 0; + float maxWidth = 0; + + if (textOrigin() == TextOrigin::baseline && !lines.empty() && !lines[0].empty()) + { + y -= m_lines[0][0].baseline; + minY = y; + } + for (const SimpleArray& paragraphLines : lines) + { + const Paragraph& paragraph = shape[paragraphIndex++]; + for (const GlyphLine& line : paragraphLines) + { + const GlyphRun& endRun = paragraph.runs[line.endRunIndex]; + const GlyphRun& startRun = paragraph.runs[line.startRunIndex]; + float width = endRun.xpos[line.endGlyphIndex] - + startRun.xpos[line.startGlyphIndex] - endRun.letterSpacing; + if (width > maxWidth) + { + maxWidth = width; + } + } + if (!paragraphLines.empty()) + { + y += paragraphLines.back().bottom; + } + y += paragraphSpace; + } + + switch (sizing()) + { + case TextSizing::autoWidth: + return AABB::fromLTWH(0, 0, maxWidth, std::max(minY, y - paragraphSpace)); + break; + case TextSizing::autoHeight: + return AABB::fromLTWH(0, 0, width(), std::max(minY, y - paragraphSpace)); + break; + case TextSizing::fixed: + return AABB::fromLTWH(0, 0, width(), minY + height()); + break; + } + } + return AABB(); +} + AABB Text::localBounds() const { float width = m_bounds.width(); @@ -775,7 +861,7 @@ void Text::draw(Renderer* renderer) {} Core* Text::hitTest(HitInfo*, const Mat2D&) { return nullptr; } void Text::addRun(TextValueRun* run) {} void Text::addModifierGroup(TextModifierGroup* group) {} -void Text::markShapeDirty() {} +void Text::markShapeDirty(bool sendToLayout) {} void Text::update(ComponentDirt value) {} void Text::alignValueChanged() {} void Text::sizingValueChanged() {} @@ -791,4 +877,6 @@ AABB Text::localBounds() const { return AABB(); } void Text::originValueChanged() {} void Text::originXChanged() {} void Text::originYChanged() {} +AABB Text::computeIntrinsicSize(AABB min, AABB max) { return AABB(); } +void Text::controlSize(AABB size) {} #endif \ No newline at end of file diff --git a/tess/build/premake5_tess.lua b/tess/build/premake5_tess.lua index 7a07170e..7f93b186 100644 --- a/tess/build/premake5_tess.lua +++ b/tess/build/premake5_tess.lua @@ -21,6 +21,7 @@ do dependencies .. '/sokol', dependencies .. '/earcut.hpp/include/mapbox', dependencies .. '/libtess2/Include', + yoga, }) files({ '../src/**.cpp', dependencies .. '/libtess2/Source/**.c' }) buildoptions({ '-Wall', '-fno-exceptions', '-fno-rtti', '-Werror=format' }) @@ -79,11 +80,12 @@ do rive .. '/include', dependencies .. '/sokol', dependencies .. '/earcut.hpp/include/mapbox', + yoga, }) files({ '../test/**.cpp', rive .. 'utils/no_op_factory.cpp' }) - links({ 'rive_tess_renderer', 'rive', 'rive_harfbuzz', 'rive_sheenbidi' }) + links({ 'rive_tess_renderer', 'rive', 'rive_harfbuzz', 'rive_sheenbidi', 'rive_yoga' }) buildoptions({ '-Wall', '-fno-exceptions', '-fno-rtti', '-Werror=format' }) - defines({ 'TESTING' }) + defines({ 'TESTING', 'YOGA_EXPORT=' }) filter('configurations:debug') do diff --git a/test/assets/layout/layout_center.riv b/test/assets/layout/layout_center.riv new file mode 100644 index 0000000000000000000000000000000000000000..f64c66c45b0ad117000b417cb66f8d20f125921d GIT binary patch literal 220 zcmWIY40B~?I9UCW`3>Vc=J(7DARx}b$j-p<%b5d2yklm6!^ptGVPVbo67?@d^7}!~v zMHu+zI*BqcO?0XTSyBTcfCh0gECDG15)AK|CrxP4_{hw}Ai~N3#LNux=3F6}xv4ps xd8rD945sG%!6k_$sS3V{$r%tK%PvNCp#7;uKxx~lj0_BR3=RzT435)*OaLvMGQa=; literal 0 HcmV?d00001 diff --git a/test/assets/layout/layout_horizontal.riv b/test/assets/layout/layout_horizontal.riv new file mode 100644 index 0000000000000000000000000000000000000000..7813fa9c3d0d8784abb4c0c806e5781de1038f68 GIT binary patch literal 361 zcmWIY40B~?I9UCL@f|Y*2#7NunP2`8WtC!F3fvokQWGBdEV zvWPJ7&2Vc=1DS7OM@05t1_ z6VR*^PVbo68JJm_8Q57_L>TzyI*BqcO?0XT+Q?7?B7nvUgG^+`W{?r8K|DZ%IDiIm z;xI@AWDo~7gN#uP;sYt<1)9bSG>spJX`&1wtPDWR0>qp^%+DZi&J~iGo0^lEm#SdM uU~0}ET#{Ils^FWLoB|$gGhDB--P}+{cfx(`^aXKS2gY8sC1_l7>$4-d= literal 0 HcmV?d00001 diff --git a/test/assets/layout/layout_horizontal_wrap.riv b/test/assets/layout/layout_horizontal_wrap.riv new file mode 100644 index 0000000000000000000000000000000000000000..f851c6bfb19e65e3c55d3f7977436c5c622978c1 GIT binary patch literal 605 zcmZ|NJxjwt7zglwa*Y=>)i$&ZSc~zc>Ke5c2Va`vAgF_id(;C9Hjxk!sUJYx6hs^Z z2fv70KTJvK>Y~r#6i5#K569i}{BF79{j)ue@7{a*LEk37gi&^*3mLkhH-geC~$1nC*jf`oV)w3dVl1Q`V7GoVEY8EMdZ5-Jl^B*@Hw z>JloZL5(CdO;Cj(D+5}RP$do8NJ2BRu}WH%v|5I?ESoT7FOQ!qBc`IHfx;*{B~LLa z7Nv&S=J;u+E3P}fupKm-QzwxZ3H#8yxcWcZd{Q`l01?vl)~f<+V;4JUz0vj$nTC6w literal 0 HcmV?d00001 diff --git a/test/assets/layout/layout_vertical.riv b/test/assets/layout/layout_vertical.riv new file mode 100644 index 0000000000000000000000000000000000000000..35248ab5944a2b0d74513ace751dbbdd96c86f84 GIT binary patch literal 369 zcmWIY40B~?I9UCL@g4JfW(E)tXJBM!VEEL8EmIAGB5xD0d-Al literal 0 HcmV?d00001 diff --git a/test/layout_test.cpp b/test/layout_test.cpp new file mode 100644 index 00000000..08db250c --- /dev/null +++ b/test/layout_test.cpp @@ -0,0 +1,123 @@ +#include +#include +#include "utils/no_op_factory.hpp" +#include "rive_file_reader.hpp" +#include "rive_testing.hpp" +#include +#include + +TEST_CASE("LayoutComponent FlexDirection row", "[layout]") +{ + auto file = ReadRiveFile("../../test/assets/layout/layout_horizontal.riv"); + + auto artboard = file->artboard(); + + REQUIRE(artboard->find("LayoutComponent1") != nullptr); + auto target1 = artboard->find("LayoutComponent1"); + + REQUIRE(artboard->find("LayoutComponent2") != nullptr); + auto target2 = artboard->find("LayoutComponent2"); + + REQUIRE(artboard->find("LayoutComponent3") != nullptr); + auto target3 = artboard->find("LayoutComponent3"); + + artboard->advance(0.0f); + auto target1Components = target1->worldTransform().decompose(); + auto target2Components = target2->worldTransform().decompose(); + auto target3Components = target3->worldTransform().decompose(); + + REQUIRE(target1Components.x() == 0); + REQUIRE(target2Components.x() == 100); + REQUIRE(target3Components.x() == 200); + REQUIRE(target1Components.y() == 0); + REQUIRE(target2Components.y() == 0); + REQUIRE(target3Components.y() == 0); +} + +TEST_CASE("LayoutComponent FlexDirection column", "[layout]") +{ + auto file = ReadRiveFile("../../test/assets/layout/layout_vertical.riv"); + + auto artboard = file->artboard(); + + REQUIRE(artboard->find("LayoutComponent1") != nullptr); + auto target1 = artboard->find("LayoutComponent1"); + + REQUIRE(artboard->find("LayoutComponent2") != nullptr); + auto target2 = artboard->find("LayoutComponent2"); + + REQUIRE(artboard->find("LayoutComponent3") != nullptr); + auto target3 = artboard->find("LayoutComponent3"); + + artboard->advance(0.0f); + auto target1Components = target1->worldTransform().decompose(); + auto target2Components = target2->worldTransform().decompose(); + auto target3Components = target3->worldTransform().decompose(); + + REQUIRE(target1Components.x() == 0); + REQUIRE(target2Components.x() == 0); + REQUIRE(target3Components.x() == 0); + REQUIRE(target1Components.y() == 0); + REQUIRE(target2Components.y() == 100); + REQUIRE(target3Components.y() == 200); +} + +TEST_CASE("LayoutComponent FlexDirection row with gap", "[layout]") +{ + auto file = ReadRiveFile("../../test/assets/layout/layout_horizontal_gaps.riv"); + + auto artboard = file->artboard(); + + REQUIRE(artboard->find("LayoutComponent1") != nullptr); + auto target1 = artboard->find("LayoutComponent1"); + + REQUIRE(artboard->find("LayoutComponent2") != nullptr); + auto target2 = artboard->find("LayoutComponent2"); + + REQUIRE(artboard->find("LayoutComponent3") != nullptr); + auto target3 = artboard->find("LayoutComponent3"); + + artboard->advance(0.0f); + auto target1Components = target1->worldTransform().decompose(); + auto target2Components = target2->worldTransform().decompose(); + auto target3Components = target3->worldTransform().decompose(); + + REQUIRE(target1Components.x() == 0); + REQUIRE(target2Components.x() == 110); + REQUIRE(target3Components.x() == 220); + REQUIRE(target1Components.y() == 0); + REQUIRE(target2Components.y() == 0); + REQUIRE(target3Components.y() == 0); +} + +TEST_CASE("LayoutComponent FlexDirection row with wrap", "[layout]") +{ + auto file = ReadRiveFile("../../test/assets/layout/layout_horizontal_wrap.riv"); + + auto artboard = file->artboard(); + + REQUIRE(artboard->find("LayoutComponent6") != nullptr); + auto target = artboard->find("LayoutComponent6"); + + artboard->advance(0.0f); + auto targetComponents = target->worldTransform().decompose(); + + REQUIRE(targetComponents.x() == 0); + REQUIRE(targetComponents.y() == 100); +} + +TEST_CASE("LayoutComponent Center using alignItems and justifyContent", "[layout]") +{ + auto file = ReadRiveFile("../../test/assets/layout/layout_center.riv"); + + auto artboard = file->artboard(); + + REQUIRE(artboard->find("LayoutComponent1") != nullptr); + auto target = artboard->find("LayoutComponent1"); + + artboard->advance(0.0f); + auto targetComponents = target->worldTransform().decompose(); + + REQUIRE(targetComponents.x() == 200); + REQUIRE(targetComponents.y() == 200); +} \ No newline at end of file diff --git a/viewer/build/macosx/build_viewer.sh b/viewer/build/macosx/build_viewer.sh index f41f0fe1..80539470 100755 --- a/viewer/build/macosx/build_viewer.sh +++ b/viewer/build/macosx/build_viewer.sh @@ -57,7 +57,7 @@ export PREMAKE=$DEPENDENCIES/bin/premake5 pushd .. OUT=out/$RENDERER/$GRAPHICS/$CONFIG -$PREMAKE --scripts=../../build --file=./premake5_viewer.lua --config=$CONFIG --out=$OUT gmake2 --graphics=$GRAPHICS --renderer=$RENDERER --with_rive_tools --with_rive_text --with_rive_audio=system +$PREMAKE --scripts=../../build --file=./premake5_viewer.lua --config=$CONFIG --out=$OUT gmake2 --graphics=$GRAPHICS --renderer=$RENDERER --with_rive_tools --with_rive_text --with_rive_audio=system --with_rive_layout for var in "$@"; do if [[ $var = "clean" ]]; then diff --git a/viewer/build/premake5_viewer.lua b/viewer/build/premake5_viewer.lua index 741c4976..9418d8c3 100644 --- a/viewer/build/premake5_viewer.lua +++ b/viewer/build/premake5_viewer.lua @@ -24,7 +24,7 @@ do end kind('ConsoleApp') - defines({ 'WITH_RIVE_TEXT', 'WITH_RIVE_AUDIO' }) + defines({ 'WITH_RIVE_TEXT', 'WITH_RIVE_AUDIO', 'WITH_RIVE_LAYOUT', 'YOGA_EXPORT=' }) includedirs({ '../include', @@ -34,9 +34,10 @@ do dependencies .. '/sokol', dependencies .. '/imgui', miniaudio, + yoga, }) - links({ 'rive', 'rive_harfbuzz', 'rive_sheenbidi' }) + links({ 'rive', 'rive_harfbuzz', 'rive_sheenbidi', 'rive_yoga' }) libdirs({ rive .. '/build/%{cfg.system}/bin/%{cfg.buildcfg}' }) From c825b0a04942e9421caddeb5f23f330a8d4cf12e Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Wed, 12 Jun 2024 21:03:00 +0000 Subject: [PATCH 064/138] Replace computeIntrinsicSize with measureLayout Replaces computeIntrinsicSize with measureLayout which lets the layout engine call the measure function as necessary to allow the objects that can respond to changes in size to fit as best as they can given the constraints. This allow for better handling of line wrapping, ellipsis, and pushing content under text to the exact boundary of the text when using max width/height options in the layout engine. I also tied in a few other fixes for how we allocate layout nodes and styles. Diffs= da0b71559 Replace computeIntrinsicSize with measureLayout (#7410) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- dev/test.sh | 2 +- dev/test/premake5.lua | 2 +- .../rive/animation/state_machine_instance.hpp | 2 +- include/rive/layout/layout_measure_mode.hpp | 12 + include/rive/layout_component.hpp | 55 ++--- include/rive/nested_artboard.hpp | 7 +- include/rive/shapes/image.hpp | 9 +- include/rive/shapes/parametric_path.hpp | 7 +- include/rive/text/text.hpp | 9 +- include/rive/transform_component.hpp | 12 +- src/artboard.cpp | 3 + src/layout_component.cpp | 220 ++++++++---------- src/nested_artboard.cpp | 21 +- src/shapes/image.cpp | 71 +++++- src/shapes/parametric_path.cpp | 38 ++- src/text/text.cpp | 65 ++++-- test/assets/layout/measure_tests.riv | Bin 0 -> 806365 bytes test/layout_test.cpp | 26 ++- 19 files changed, 361 insertions(+), 202 deletions(-) create mode 100644 include/rive/layout/layout_measure_mode.hpp create mode 100644 test/assets/layout/measure_tests.riv diff --git a/.rive_head b/.rive_head index 499eaf14..162ea2cb 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -6c76b425f887a8adb3beb8ba8263200b9cdbb2c9 +da0b7155934e5e6b94d3d7e3d8b5eef76ae6607d diff --git a/dev/test.sh b/dev/test.sh index 0167ca2a..213e09a8 100755 --- a/dev/test.sh +++ b/dev/test.sh @@ -75,7 +75,7 @@ RUNTIME=$PWD popd export PREMAKE_PATH="$RUNTIME/dependencies/export-compile-commands":"$RUNTIME/build":"$PREMAKE_PATH" -PREMAKE_COMMANDS="--with_rive_text --with_rive_audio=external --with_rive_layout --config=$CONFIG" +PREMAKE_COMMANDS="--with_rive_text --with_rive_audio=external --with_rive_layout --config=$CONFIG" out_dir() { echo "out/$CONFIG" diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index 00db7025..78c2296f 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -8,7 +8,7 @@ defines({ 'WITH_RIVE_AUDIO', 'WITH_RIVE_AUDIO_TOOLS', 'WITH_RIVE_LAYOUT', - 'YOGA_EXPORT=' + 'YOGA_EXPORT=', }) dofile(path.join(path.getabsolute('../../'), 'premake5_v2.lua')) diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 13e37407..786366f7 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -29,8 +29,8 @@ class NestedArtboard; class NestedEventListener; class NestedEventNotifier; class Event; -class EventReport; class KeyedProperty; +class EventReport; class StateMachineInstance : public Scene, public NestedEventNotifier, public NestedEventListener { diff --git a/include/rive/layout/layout_measure_mode.hpp b/include/rive/layout/layout_measure_mode.hpp new file mode 100644 index 00000000..50f6eb85 --- /dev/null +++ b/include/rive/layout/layout_measure_mode.hpp @@ -0,0 +1,12 @@ +#ifndef _RIVE_LAYOUT_MEASURE_MODE_HPP_ +#define _RIVE_LAYOUT_MEASURE_MODE_HPP_ +namespace rive +{ +enum class LayoutMeasureMode : uint8_t +{ + undefined = 0, + exactly = 1, + atMost = 2 +}; +} +#endif \ No newline at end of file diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index e7c5d553..1049e3b1 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -2,6 +2,7 @@ #define _RIVE_LAYOUT_COMPONENT_HPP_ #include "rive/generated/layout_component_base.hpp" #include "rive/layout/layout_component_style.hpp" +#include "rive/layout/layout_measure_mode.hpp" #ifdef WITH_RIVE_LAYOUT #include "yoga/YGNode.h" #include "yoga/YGStyle.h" @@ -10,24 +11,20 @@ #include namespace rive { -#ifndef WITH_RIVE_LAYOUT -class YGNodeRef +struct LayoutData { -public: - YGNodeRef() {} -}; -class YGStyle -{ -public: - YGStyle() {} -}; +#ifdef WITH_RIVE_LAYOUT + YGNode node; + YGStyle style; #endif +}; + class LayoutComponent : public LayoutComponentBase { private: LayoutComponentStyle* m_style = nullptr; - YGNodeRef m_layoutNode; - YGStyle* m_layoutStyle; + std::unique_ptr m_layoutData; + float m_layoutSizeWidth = 0; float m_layoutSizeHeight = 0; float m_layoutLocationX = 0; @@ -35,6 +32,8 @@ class LayoutComponent : public LayoutComponentBase #ifdef WITH_RIVE_LAYOUT private: + YGNode& layoutNode() { return m_layoutData->node; } + YGStyle& layoutStyle() { return m_layoutData->style; } void syncLayoutChildren(); void propagateSizeToChildren(ContainerComponent* component); AABB findMaxIntrinsicSize(ContainerComponent* component, AABB maxIntrinsicSize); @@ -48,38 +47,13 @@ class LayoutComponent : public LayoutComponentBase void style(LayoutComponentStyle* style) { m_style = style; } #ifdef WITH_RIVE_LAYOUT - YGNodeRef layoutNode() { return m_layoutNode; } - - YGStyle* layoutStyle() { return m_layoutStyle; } - - LayoutComponent() - { - m_layoutNode = new YGNode(); - m_layoutStyle = new YGStyle(); - } - - ~LayoutComponent() - { - YGNodeFreeRecursive(m_layoutNode); - delete m_layoutStyle; - } + LayoutComponent(); void syncStyle(); void propagateSize(); void updateLayoutBounds(); void update(ComponentDirt value) override; StatusCode onAddedDirty(CoreContext* context) override; -#else - LayoutComponent() - { - m_layoutNode = YGNodeRef(); - auto s = new YGStyle(); - m_layoutStyle = s; - m_layoutSizeWidth = 0; - m_layoutSizeHeight = 0; - m_layoutLocationX = 0; - m_layoutLocationY = 0; - } #endif void buildDependencies() override; @@ -88,6 +62,11 @@ class LayoutComponent : public LayoutComponentBase void widthChanged() override; void heightChanged() override; void styleIdChanged() override; + + Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode); }; } // namespace rive diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index 3eac7dc7..0c2ecd70 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp @@ -80,8 +80,11 @@ class NestedArtboard : public NestedArtboardBase float effectiveScaleX() { return std::isnan(m_layoutScaleX) ? scaleX() : m_layoutScaleX; } float effectiveScaleY() { return std::isnan(m_layoutScaleY) ? scaleY() : m_layoutScaleY; } - AABB computeIntrinsicSize(AABB min, AABB max) override; - void controlSize(AABB size) override; + Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) override; + void controlSize(Vec2D size) override; /// Convert a world space (relative to the artboard that this /// NestedArtboard is a child of) to the local space of the Artboard diff --git a/include/rive/shapes/image.hpp b/include/rive/shapes/image.hpp index 60a0c729..7d9510b7 100644 --- a/include/rive/shapes/image.hpp +++ b/include/rive/shapes/image.hpp @@ -24,8 +24,13 @@ class Image : public ImageBase, public FileAssetReferencer void setAsset(FileAsset*) override; uint32_t assetId() override; Core* clone() const override; - AABB computeIntrinsicSize(AABB min, AABB max) override; - void controlSize(AABB size) override; + Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) override; + void controlSize(Vec2D size) override; + float width() const; + float height() const; }; } // namespace rive diff --git a/include/rive/shapes/parametric_path.hpp b/include/rive/shapes/parametric_path.hpp index 7bb32044..477b9e2d 100644 --- a/include/rive/shapes/parametric_path.hpp +++ b/include/rive/shapes/parametric_path.hpp @@ -7,8 +7,11 @@ namespace rive class ParametricPath : public ParametricPathBase { public: - AABB computeIntrinsicSize(AABB min, AABB max) override; - void controlSize(AABB size) override; + Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) override; + void controlSize(Vec2D size) override; protected: void widthChanged() override; diff --git a/include/rive/text/text.hpp b/include/rive/text/text.hpp index 073af1d2..7d0ae9ac 100644 --- a/include/rive/text/text.hpp +++ b/include/rive/text/text.hpp @@ -191,8 +191,11 @@ class Text : public TextBase void originXChanged() override; void originYChanged() override; - AABB computeIntrinsicSize(AABB min, AABB max) override; - void controlSize(AABB size) override; + Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) override; + void controlSize(Vec2D size) override; float effectiveWidth() { return std::isnan(m_layoutWidth) ? width() : m_layoutWidth; } float effectiveHeight() { return std::isnan(m_layoutHeight) ? height() : m_layoutHeight; } #ifdef WITH_RIVE_TEXT @@ -247,7 +250,7 @@ class Text : public TextBase #endif float m_layoutWidth = NAN; float m_layoutHeight = NAN; - AABB measure(AABB maxSize); + Vec2D measure(Vec2D maxSize); }; } // namespace rive diff --git a/include/rive/transform_component.hpp b/include/rive/transform_component.hpp index 6b63a11c..534165c2 100644 --- a/include/rive/transform_component.hpp +++ b/include/rive/transform_component.hpp @@ -3,6 +3,7 @@ #include "rive/generated/transform_component_base.hpp" #include "rive/math/aabb.hpp" #include "rive/math/mat2d.hpp" +#include "rive/layout/layout_measure_mode.hpp" namespace rive { @@ -49,8 +50,15 @@ class TransformComponent : public TransformComponentBase virtual AABB localBounds() const; void markDirtyIfConstrained(); - virtual AABB computeIntrinsicSize(AABB min, AABB max) { return AABB(); } - virtual void controlSize(AABB size) {} + virtual Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) + { + return Vec2D(); + } + + virtual void controlSize(Vec2D size) {} }; } // namespace rive diff --git a/src/artboard.cpp b/src/artboard.cpp index 9a9b7414..6b8e83db 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -84,6 +84,9 @@ StatusCode Artboard::initialize() m_BackgroundPath = factory()->makeEmptyRenderPath(); m_ClipPath = factory()->makeEmptyRenderPath(); +#ifdef WITH_RIVE_LAYOUT + markLayoutDirty(this); +#endif // onAddedDirty guarantees that all objects are now available so they can be // looked up by index/id. This is where nodes find their parents, but they // can't assume that their parent's parent will have resolved yet. diff --git a/src/layout_component.cpp b/src/layout_component.cpp index ac908f63..c9b600fc 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -21,6 +21,8 @@ void LayoutComponent::buildDependencies() } #ifdef WITH_RIVE_LAYOUT +LayoutComponent::LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())) {} + StatusCode LayoutComponent::onAddedDirty(CoreContext* context) { auto code = Super::onAddedDirty(context); @@ -60,10 +62,28 @@ void LayoutComponent::update(ComponentDirt value) } } -AABB LayoutComponent::findMaxIntrinsicSize(ContainerComponent* component, AABB maxIntrinsicSize) +static YGSize measureFunc(YGNode* node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { - auto intrinsicSize = maxIntrinsicSize; - for (auto child : component->children()) + Vec2D size = ((LayoutComponent*)node->getContext()) + ->measureLayout(width, + (LayoutMeasureMode)widthMode, + height, + (LayoutMeasureMode)heightMode); + + return YGSize{size.x, size.y}; +} + +Vec2D LayoutComponent::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + Vec2D size = Vec2D(); + for (auto child : children()) { if (child->is()) { @@ -71,141 +91,106 @@ AABB LayoutComponent::findMaxIntrinsicSize(ContainerComponent* component, AABB m } if (child->is()) { - auto sizableChild = child->as(); - auto minSize = - AABB::fromLTWH(0, - 0, - style()->minWidthUnits() == YGUnitPoint ? style()->minWidth() : 0, - style()->minHeightUnits() == YGUnitPoint ? style()->minHeight() : 0); - auto maxSize = AABB::fromLTWH( - 0, - 0, - style()->maxWidthUnits() == YGUnitPoint ? style()->maxWidth() - : std::numeric_limits::infinity(), - style()->maxHeightUnits() == YGUnitPoint ? style()->maxHeight() - : std::numeric_limits::infinity()); - auto size = sizableChild->computeIntrinsicSize(minSize, maxSize); - intrinsicSize = AABB::fromLTWH(0, - 0, - std::max(maxIntrinsicSize.width(), size.width()), - std::max(maxIntrinsicSize.height(), size.height())); - } - if (child->is()) - { - return findMaxIntrinsicSize(child->as(), intrinsicSize); + auto transformComponent = child->as(); + Vec2D measured = + transformComponent->measureLayout(width, widthMode, height, heightMode); + size = Vec2D(std::max(size.x, measured.x), std::max(size.y, measured.y)); } } - return intrinsicSize; + return size; } void LayoutComponent::syncStyle() { - if (style() == nullptr || layoutStyle() == nullptr || layoutNode() == nullptr) + if (m_style == nullptr) { return; } - bool setIntrinsicWidth = false; - bool setIntrinsicHeight = false; - if (style()->intrinsicallySized() && - (style()->widthUnits() == YGUnitAuto || style()->heightUnits() == YGUnitAuto)) + YGNode& ygNode = layoutNode(); + YGStyle& ygStyle = layoutStyle(); + if (m_style->intrinsicallySized()) { - AABB intrinsicSize = findMaxIntrinsicSize(this, AABB()); - bool foundIntrinsicSize = intrinsicSize.width() != 0 || intrinsicSize.height() != 0; - - if (foundIntrinsicSize) - { - if (style()->widthUnits() == YGUnitAuto) - { - setIntrinsicWidth = true; - layoutStyle()->dimensions()[YGDimensionWidth] = - YGValue{intrinsicSize.width(), YGUnitPoint}; - } - if (style()->heightUnits() == YGUnitAuto) - { - setIntrinsicHeight = true; - layoutStyle()->dimensions()[YGDimensionHeight] = - YGValue{intrinsicSize.height(), YGUnitPoint}; - } - } + ygNode.setContext(this); + ygNode.setMeasureFunc(measureFunc); + } + else + { + ygNode.setMeasureFunc(nullptr); + } + if (m_style->widthUnits() != YGUnitAuto) + { + ygStyle.dimensions()[YGDimensionWidth] = YGValue{width(), m_style->widthUnits()}; + } + else + { + ygStyle.dimensions()[YGDimensionWidth] = YGValueAuto; } - if (!setIntrinsicWidth) + if (m_style->heightUnits() != YGUnitAuto) { - layoutStyle()->dimensions()[YGDimensionWidth] = YGValue{width(), style()->widthUnits()}; + ygStyle.dimensions()[YGDimensionHeight] = YGValue{height(), m_style->heightUnits()}; } - if (!setIntrinsicHeight) + else { - layoutStyle()->dimensions()[YGDimensionHeight] = YGValue{height(), style()->heightUnits()}; + ygStyle.dimensions()[YGDimensionHeight] = YGValueAuto; } - layoutStyle()->minDimensions()[YGDimensionWidth] = - YGValue{style()->minWidth(), style()->minWidthUnits()}; - layoutStyle()->minDimensions()[YGDimensionHeight] = - YGValue{style()->minHeight(), style()->minHeightUnits()}; - layoutStyle()->maxDimensions()[YGDimensionWidth] = - YGValue{style()->maxWidth(), style()->maxWidthUnits()}; - layoutStyle()->maxDimensions()[YGDimensionHeight] = - YGValue{style()->maxHeight(), style()->maxHeightUnits()}; + ygStyle.minDimensions()[YGDimensionWidth] = + YGValue{m_style->minWidth(), m_style->minWidthUnits()}; + ygStyle.minDimensions()[YGDimensionHeight] = + YGValue{m_style->minHeight(), m_style->minHeightUnits()}; + ygStyle.maxDimensions()[YGDimensionWidth] = + YGValue{m_style->maxWidth(), m_style->maxWidthUnits()}; + ygStyle.maxDimensions()[YGDimensionHeight] = + YGValue{m_style->maxHeight(), m_style->maxHeightUnits()}; - layoutStyle()->gap()[YGGutterColumn] = - YGValue{style()->gapHorizontal(), style()->gapHorizontalUnits()}; - layoutStyle()->gap()[YGGutterRow] = - YGValue{style()->gapVertical(), style()->gapVerticalUnits()}; - layoutStyle()->border()[YGEdgeLeft] = - YGValue{style()->borderLeft(), style()->borderLeftUnits()}; - layoutStyle()->border()[YGEdgeRight] = - YGValue{style()->borderRight(), style()->borderRightUnits()}; - layoutStyle()->border()[YGEdgeTop] = YGValue{style()->borderTop(), style()->borderTopUnits()}; - layoutStyle()->border()[YGEdgeBottom] = - YGValue{style()->borderBottom(), style()->borderBottomUnits()}; - layoutStyle()->margin()[YGEdgeLeft] = - YGValue{style()->marginLeft(), style()->marginLeftUnits()}; - layoutStyle()->margin()[YGEdgeRight] = - YGValue{style()->marginRight(), style()->marginRightUnits()}; - layoutStyle()->margin()[YGEdgeTop] = YGValue{style()->marginTop(), style()->marginTopUnits()}; - layoutStyle()->margin()[YGEdgeBottom] = - YGValue{style()->marginBottom(), style()->marginBottomUnits()}; - layoutStyle()->padding()[YGEdgeLeft] = - YGValue{style()->paddingLeft(), style()->paddingLeftUnits()}; - layoutStyle()->padding()[YGEdgeRight] = - YGValue{style()->paddingRight(), style()->paddingRightUnits()}; - layoutStyle()->padding()[YGEdgeTop] = - YGValue{style()->paddingTop(), style()->paddingTopUnits()}; - layoutStyle()->padding()[YGEdgeBottom] = - YGValue{style()->paddingBottom(), style()->paddingBottomUnits()}; - layoutStyle()->position()[YGEdgeLeft] = - YGValue{style()->positionLeft(), style()->positionLeftUnits()}; - layoutStyle()->position()[YGEdgeRight] = - YGValue{style()->positionRight(), style()->positionRightUnits()}; - layoutStyle()->position()[YGEdgeTop] = - YGValue{style()->positionTop(), style()->positionTopUnits()}; - layoutStyle()->position()[YGEdgeBottom] = - YGValue{style()->positionBottom(), style()->positionBottomUnits()}; + ygStyle.gap()[YGGutterColumn] = + YGValue{m_style->gapHorizontal(), m_style->gapHorizontalUnits()}; + ygStyle.gap()[YGGutterRow] = YGValue{m_style->gapVertical(), m_style->gapVerticalUnits()}; + ygStyle.border()[YGEdgeLeft] = YGValue{m_style->borderLeft(), m_style->borderLeftUnits()}; + ygStyle.border()[YGEdgeRight] = YGValue{m_style->borderRight(), m_style->borderRightUnits()}; + ygStyle.border()[YGEdgeTop] = YGValue{m_style->borderTop(), m_style->borderTopUnits()}; + ygStyle.border()[YGEdgeBottom] = YGValue{m_style->borderBottom(), m_style->borderBottomUnits()}; + ygStyle.margin()[YGEdgeLeft] = YGValue{m_style->marginLeft(), m_style->marginLeftUnits()}; + ygStyle.margin()[YGEdgeRight] = YGValue{m_style->marginRight(), m_style->marginRightUnits()}; + ygStyle.margin()[YGEdgeTop] = YGValue{m_style->marginTop(), m_style->marginTopUnits()}; + ygStyle.margin()[YGEdgeBottom] = YGValue{m_style->marginBottom(), m_style->marginBottomUnits()}; + ygStyle.padding()[YGEdgeLeft] = YGValue{m_style->paddingLeft(), m_style->paddingLeftUnits()}; + ygStyle.padding()[YGEdgeRight] = YGValue{m_style->paddingRight(), m_style->paddingRightUnits()}; + ygStyle.padding()[YGEdgeTop] = YGValue{m_style->paddingTop(), m_style->paddingTopUnits()}; + ygStyle.padding()[YGEdgeBottom] = + YGValue{m_style->paddingBottom(), m_style->paddingBottomUnits()}; + ygStyle.position()[YGEdgeLeft] = YGValue{m_style->positionLeft(), m_style->positionLeftUnits()}; + ygStyle.position()[YGEdgeRight] = + YGValue{m_style->positionRight(), m_style->positionRightUnits()}; + ygStyle.position()[YGEdgeTop] = YGValue{m_style->positionTop(), m_style->positionTopUnits()}; + ygStyle.position()[YGEdgeBottom] = + YGValue{m_style->positionBottom(), m_style->positionBottomUnits()}; - layoutStyle()->display() = style()->display(); - layoutStyle()->positionType() = style()->positionType(); - layoutStyle()->flex() = YGFloatOptional(style()->flex()); - layoutStyle()->flexGrow() = YGFloatOptional(style()->flexGrow()); - layoutStyle()->flexShrink() = YGFloatOptional(style()->flexShrink()); - // layoutStyle()->flexBasis() = style()->flexBasis(); - layoutStyle()->flexDirection() = style()->flexDirection(); - layoutStyle()->flexWrap() = style()->flexWrap(); - layoutStyle()->alignItems() = style()->alignItems(); - layoutStyle()->alignContent() = style()->alignContent(); - layoutStyle()->alignSelf() = style()->alignSelf(); - layoutStyle()->justifyContent() = style()->justifyContent(); + ygStyle.display() = m_style->display(); + ygStyle.positionType() = m_style->positionType(); + ygStyle.flex() = YGFloatOptional(m_style->flex()); + ygStyle.flexGrow() = YGFloatOptional(m_style->flexGrow()); + ygStyle.flexShrink() = YGFloatOptional(m_style->flexShrink()); + // ygStyle.flexBasis() = m_style->flexBasis(); + ygStyle.flexDirection() = m_style->flexDirection(); + ygStyle.flexWrap() = m_style->flexWrap(); + ygStyle.alignItems() = m_style->alignItems(); + ygStyle.alignContent() = m_style->alignContent(); + ygStyle.alignSelf() = m_style->alignSelf(); + ygStyle.justifyContent() = m_style->justifyContent(); - layoutNode()->setStyle(*layoutStyle()); + ygNode.setStyle(ygStyle); } void LayoutComponent::syncLayoutChildren() { - YGNodeRemoveAllChildren(layoutNode()); + YGNodeRemoveAllChildren(&layoutNode()); int index = 0; for (size_t i = 0; i < children().size(); i++) { Component* child = children()[i]; if (child->is()) { - YGNodeInsertChild(layoutNode(), child->as()->layoutNode(), index); + YGNodeInsertChild(&layoutNode(), &child->as()->layoutNode(), index); index += 1; } } @@ -231,7 +216,7 @@ void LayoutComponent::propagateSizeToChildren(ContainerComponent* component) if (child->is()) { auto sizableChild = child->as(); - sizableChild->controlSize(AABB::fromLTWH(0, 0, m_layoutSizeWidth, m_layoutSizeHeight)); + sizableChild->controlSize(Vec2D(m_layoutSizeWidth, m_layoutSizeHeight)); } if (child->is()) { @@ -242,15 +227,16 @@ void LayoutComponent::propagateSizeToChildren(ContainerComponent* component) void LayoutComponent::calculateLayout() { - YGNodeCalculateLayout(layoutNode(), width(), height(), YGDirection::YGDirectionInherit); + YGNodeCalculateLayout(&layoutNode(), width(), height(), YGDirection::YGDirectionInherit); } void LayoutComponent::updateLayoutBounds() { - auto left = YGNodeLayoutGetLeft(layoutNode()); - auto top = YGNodeLayoutGetTop(layoutNode()); - auto width = YGNodeLayoutGetWidth(layoutNode()); - auto height = YGNodeLayoutGetHeight(layoutNode()); + auto node = &layoutNode(); + auto left = YGNodeLayoutGetLeft(node); + auto top = YGNodeLayoutGetTop(node); + auto width = YGNodeLayoutGetWidth(node); + auto height = YGNodeLayoutGetHeight(node); if (left != m_layoutLocationX || top != m_layoutLocationY || width != m_layoutSizeWidth || height != m_layoutSizeHeight) { @@ -265,7 +251,7 @@ void LayoutComponent::updateLayoutBounds() void LayoutComponent::markLayoutNodeDirty() { - layoutNode()->markDirtyAndPropagate(); + layoutNode().markDirtyAndPropagate(); artboard()->markLayoutDirty(this); } #else diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 7bf7df29..e59b9e9d 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -6,6 +6,7 @@ #include "rive/nested_animation.hpp" #include "rive/animation/nested_state_machine.hpp" #include "rive/clip_result.hpp" +#include #include using namespace rive; @@ -232,12 +233,24 @@ bool NestedArtboard::worldToLocal(Vec2D world, Vec2D* local) return true; } -AABB NestedArtboard::computeIntrinsicSize(AABB min, AABB max) { return max; } +Vec2D NestedArtboard::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + return Vec2D( + std::min(widthMode == LayoutMeasureMode::undefined ? std::numeric_limits::max() + : width, + m_Instance ? m_Instance->width() : 0.0f), + std::min(heightMode == LayoutMeasureMode::undefined ? std::numeric_limits::max() + : height, + m_Instance ? m_Instance->height() : 0.0f)); +} -void NestedArtboard::controlSize(AABB size) +void NestedArtboard::controlSize(Vec2D size) { - auto newScaleX = size.width() / m_Artboard->originalWidth(); - auto newScaleY = size.height() / m_Artboard->originalHeight(); + auto newScaleX = size.x / m_Artboard->originalWidth(); + auto newScaleY = size.y / m_Artboard->originalHeight(); if (newScaleX != scaleX() || newScaleY != scaleY()) { // TODO: Support nested artboard fit & alignment diff --git a/src/shapes/image.cpp b/src/shapes/image.cpp index c2f21cf7..e7612307 100644 --- a/src/shapes/image.cpp +++ b/src/shapes/image.cpp @@ -122,13 +122,76 @@ Core* Image::clone() const void Image::setMesh(Mesh* mesh) { m_Mesh = mesh; } Mesh* Image::mesh() const { return m_Mesh; } -AABB Image::computeIntrinsicSize(AABB min, AABB max) { return max; } +float Image::width() const +{ + rive::ImageAsset* asset = this->imageAsset(); + if (asset == nullptr) + { + return 0.0f; + } + + rive::RenderImage* renderImage = asset->renderImage(); + if (renderImage == nullptr) + { + return 0.0f; + } + return renderImage->width(); +} + +float Image::height() const +{ + rive::ImageAsset* asset = this->imageAsset(); + if (asset == nullptr) + { + return 0.0f; + } + + rive::RenderImage* renderImage = asset->renderImage(); + if (renderImage == nullptr) + { + return 0.0f; + } + return renderImage->height(); +} + +Vec2D Image::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + float measuredWidth, measuredHeight; + switch (widthMode) + { + case LayoutMeasureMode::atMost: + measuredWidth = std::max(Image::width(), width); + break; + case LayoutMeasureMode::exactly: + measuredWidth = width; + break; + case LayoutMeasureMode::undefined: + measuredWidth = Image::width(); + break; + } + switch (heightMode) + { + case LayoutMeasureMode::atMost: + measuredHeight = std::max(Image::height(), height); + break; + case LayoutMeasureMode::exactly: + measuredHeight = height; + break; + case LayoutMeasureMode::undefined: + measuredHeight = Image::height(); + break; + } + return Vec2D(measuredWidth, measuredHeight); +} -void Image::controlSize(AABB size) +void Image::controlSize(Vec2D size) { auto renderImage = imageAsset()->renderImage(); - auto newScaleX = size.width() / renderImage->width(); - auto newScaleY = size.height() / renderImage->height(); + auto newScaleX = size.x / renderImage->width(); + auto newScaleY = size.y / renderImage->height(); if (newScaleX != scaleX() || newScaleY != scaleY()) { scaleX(newScaleX); diff --git a/src/shapes/parametric_path.cpp b/src/shapes/parametric_path.cpp index 534dfc4c..b854cdfc 100644 --- a/src/shapes/parametric_path.cpp +++ b/src/shapes/parametric_path.cpp @@ -3,15 +3,43 @@ using namespace rive; -AABB ParametricPath::computeIntrinsicSize(AABB min, AABB max) +Vec2D ParametricPath::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) { - return AABB::fromLTWH(0, 0, width(), height()); + float measuredWidth, measuredHeight; + switch (widthMode) + { + case LayoutMeasureMode::atMost: + measuredWidth = std::max(ParametricPath::width(), width); + break; + case LayoutMeasureMode::exactly: + measuredWidth = width; + break; + case LayoutMeasureMode::undefined: + measuredWidth = ParametricPath::width(); + break; + } + switch (heightMode) + { + case LayoutMeasureMode::atMost: + measuredHeight = std::max(ParametricPath::height(), height); + break; + case LayoutMeasureMode::exactly: + measuredHeight = height; + break; + case LayoutMeasureMode::undefined: + measuredHeight = ParametricPath::height(); + break; + } + return Vec2D(measuredWidth, measuredHeight); } -void ParametricPath::controlSize(AABB size) +void ParametricPath::controlSize(Vec2D size) { - width(size.width()); - height(size.height()); + width(size.x); + height(size.y); markWorldTransformDirty(); } diff --git a/src/text/text.cpp b/src/text/text.cpp index 84311400..48624a56 100644 --- a/src/text/text.cpp +++ b/src/text/text.cpp @@ -11,6 +11,7 @@ using namespace rive; #include "rive/artboard.hpp" #include "rive/factory.hpp" #include "rive/clip_result.hpp" +#include void GlyphItr::tryAdvanceRun() { @@ -241,14 +242,22 @@ bool OrderedLine::buildEllipsisRuns(std::vector& logicalRuns, return true; } -AABB Text::computeIntrinsicSize(AABB min, AABB max) { return measure(max); } +Vec2D Text::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + return measure(Vec2D( + widthMode == LayoutMeasureMode::undefined ? std::numeric_limits::max() : width, + heightMode == LayoutMeasureMode::undefined ? std::numeric_limits::max() : height)); +} -void Text::controlSize(AABB size) +void Text::controlSize(Vec2D size) { - if (m_layoutWidth != size.width() || m_layoutHeight != size.height()) + if (m_layoutWidth != size.x || m_layoutHeight != size.y) { - m_layoutWidth = size.width(); - m_layoutHeight = size.height(); + m_layoutWidth = size.x; + m_layoutHeight = size.y; markShapeDirty(false); } } @@ -760,18 +769,21 @@ void Text::update(ComponentDirt value) } } -AABB Text::measure(AABB maxSize) +Vec2D Text::measure(Vec2D maxSize) { if (makeStyled(m_styledText)) { const float paragraphSpace = paragraphSpacing(); auto runs = m_styledText.runs(); auto shape = runs[0].font->shapeText(m_styledText.unichars(), runs); - auto lines = - breakLines(shape, - effectiveSizing() == TextSizing::autoWidth ? -1.0f : effectiveWidth(), - (TextAlign)alignValue()); + auto lines = breakLines(shape, + std::min(maxSize.x, + sizing() == TextSizing::autoWidth + ? std::numeric_limits::max() + : width()), + (TextAlign)alignValue()); float y = 0; + float computedHeight = 0.0f; float minY = 0; int paragraphIndex = 0; float maxWidth = 0; @@ -781,6 +793,9 @@ AABB Text::measure(AABB maxSize) y -= m_lines[0][0].baseline; minY = y; } + int ellipsisLine = -1; + bool wantEllipsis = overflow() == TextOverflow::ellipsis; + for (const SimpleArray& paragraphLines : lines) { const Paragraph& paragraph = shape[paragraphIndex++]; @@ -794,6 +809,17 @@ AABB Text::measure(AABB maxSize) { maxWidth = width; } + if (wantEllipsis && y + line.bottom > maxSize.y) + { + if (ellipsisLine == -1) + { + // Nothing fits, just show the first line and ellipse it. + computedHeight = y + line.bottom; + } + goto doneMeasuring; + } + ellipsisLine++; + computedHeight = y + line.bottom; } if (!paragraphLines.empty()) { @@ -801,21 +827,22 @@ AABB Text::measure(AABB maxSize) } y += paragraphSpace; } + doneMeasuring: switch (sizing()) { case TextSizing::autoWidth: - return AABB::fromLTWH(0, 0, maxWidth, std::max(minY, y - paragraphSpace)); + return Vec2D(maxWidth, std::max(minY, computedHeight)); break; case TextSizing::autoHeight: - return AABB::fromLTWH(0, 0, width(), std::max(minY, y - paragraphSpace)); + return Vec2D(width(), std::max(minY, computedHeight)); break; case TextSizing::fixed: - return AABB::fromLTWH(0, 0, width(), minY + height()); + return Vec2D(width(), minY + height()); break; } } - return AABB(); + return Vec2D(); } AABB Text::localBounds() const @@ -877,6 +904,12 @@ AABB Text::localBounds() const { return AABB(); } void Text::originValueChanged() {} void Text::originXChanged() {} void Text::originYChanged() {} -AABB Text::computeIntrinsicSize(AABB min, AABB max) { return AABB(); } -void Text::controlSize(AABB size) {} +Vec2D Text::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + return Vec2D(); +} +void Text::controlSize(Vec2D size) {} #endif \ No newline at end of file diff --git a/test/assets/layout/measure_tests.riv b/test/assets/layout/measure_tests.riv new file mode 100644 index 0000000000000000000000000000000000000000..1f4e5cc96af3a5ff1f7cd83befbe49de26e6ce7b GIT binary patch literal 806365 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 z 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 x_8JuJ!%!OjYQ3ssDB|yD>iR>tm2Yb^x%r2#b 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 -#include +#include "rive/math/transform_components.hpp" +#include "rive/shapes/rectangle.hpp" +#include "rive/text/text.hpp" #include "utils/no_op_factory.hpp" #include "rive_file_reader.hpp" #include "rive_testing.hpp" @@ -120,4 +121,23 @@ TEST_CASE("LayoutComponent Center using alignItems and justifyContent", "[layout REQUIRE(targetComponents.x() == 200); REQUIRE(targetComponents.y() == 200); -} \ No newline at end of file +} + +TEST_CASE("LayoutComponent with intrinsic size gets measured correctly", "[layout]") +{ + auto file = ReadRiveFile("../../test/assets/layout/measure_tests.riv"); + + auto artboard = file->artboard("hi"); + + REQUIRE(artboard->find("TextLayout") != nullptr); + REQUIRE(artboard->find("HiText") != nullptr); + + artboard->advance(0.0f); + + auto text = artboard->find("HiText"); + auto bounds = text->localBounds(); + REQUIRE(bounds.left() == 0); + REQUIRE(bounds.top() == 0); + REQUIRE(bounds.width() == 63.0f); + REQUIRE(bounds.height() == 73.0f); +} From e1e125a6595100e4cdc14def85c97d463bde23ef Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Fri, 14 Jun 2024 21:08:55 +0000 Subject: [PATCH 065/138] Optimize image encoding/decoding in debug builds We don't need to run this code in debug mode, even when we're debugging our own code. This makes the golden testing go almost twice as fast. Diffs= 7e1b3027d Optimize image encoding/decoding in debug builds (#7418) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- dependencies/premake5_libjpeg_v2.lua | 1 + dependencies/premake5_libpng_v2.lua | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 162ea2cb..2cdb2c00 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -da0b7155934e5e6b94d3d7e3d8b5eef76ae6607d +7e1b3027d5ea97c7950b8f5951b0b44f33413987 diff --git a/dependencies/premake5_libjpeg_v2.lua b/dependencies/premake5_libjpeg_v2.lua index 30be9665..4b5280f5 100644 --- a/dependencies/premake5_libjpeg_v2.lua +++ b/dependencies/premake5_libjpeg_v2.lua @@ -10,6 +10,7 @@ libjpeg = dependency.github('rive-app/libjpeg', 'v9f') project('libjpeg') do kind('StaticLib') + optimize("Speed") -- Always optimize image encoding/decoding, even in debug builds. includedirs({ libjpeg }) diff --git a/dependencies/premake5_libpng_v2.lua b/dependencies/premake5_libpng_v2.lua index ac653b79..ea26a9e9 100644 --- a/dependencies/premake5_libpng_v2.lua +++ b/dependencies/premake5_libpng_v2.lua @@ -12,6 +12,7 @@ do kind('StaticLib') os.copyfile(libpng .. '/scripts/pnglibconf.h.prebuilt', libpng .. '/pnglibconf.h') includedirs({ libpng, zlib }) + optimize("Speed") -- Always optimize image encoding/decoding, even in debug builds. files({ libpng .. '/png.c', libpng .. '/pngerror.c', @@ -44,6 +45,7 @@ do kind('StaticLib') defines({ 'ZLIB_IMPLEMENTATION' }) includedirs({ zlib }) + optimize("Speed") -- Always optimize image encoding/decoding, even in debug builds. files({ zlib .. '/adler32.c', zlib .. '/compress.c', From 2d4e534a4711482e59fa3708f0c4816054a76732 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Thu, 20 Jun 2024 16:54:52 +0000 Subject: [PATCH 066/138] databinding Diffs= 75823467d databinding (#7341) Co-authored-by: hernan --- .rive_head | 2 +- dev/core_generator/lib/src/property.dart | 5 + dev/defs/artboard.json | 21 + dev/defs/data_bind/data_bind.json | 40 + dev/defs/data_bind/data_bind_context.json | 21 + dev/defs/nested_artboard.json | 11 + dev/defs/viewmodel/data_enum.json | 40 + dev/defs/viewmodel/data_enum_value.json | 48 ++ dev/defs/viewmodel/viewmodel.json | 32 + dev/defs/viewmodel/viewmodel_component.json | 18 + dev/defs/viewmodel/viewmodel_instance.json | 50 ++ .../viewmodel/viewmodel_instance_color.json | 29 + .../viewmodel/viewmodel_instance_enum.json | 21 + .../viewmodel/viewmodel_instance_list.json | 8 + .../viewmodel_instance_list_item.json | 71 ++ .../viewmodel/viewmodel_instance_number.json | 29 + .../viewmodel/viewmodel_instance_string.json | 29 + .../viewmodel/viewmodel_instance_value.json | 33 + .../viewmodel_instance_viewmodel.json | 21 + dev/defs/viewmodel/viewmodel_property.json | 33 + .../viewmodel/viewmodel_property_color.json | 8 + .../viewmodel/viewmodel_property_enum.json | 31 + .../viewmodel/viewmodel_property_list.json | 8 + .../viewmodel/viewmodel_property_number.json | 8 + .../viewmodel/viewmodel_property_string.json | 8 + .../viewmodel_property_viewmodel.json | 21 + include/rive/artboard.hpp | 27 +- include/rive/component.hpp | 5 +- include/rive/component_dirt.hpp | 3 + .../rive/data_bind/context/context_value.hpp | 22 + .../data_bind/context/context_value_color.hpp | 19 + .../data_bind/context/context_value_enum.hpp | 19 + .../data_bind/context/context_value_list.hpp | 33 + .../context/context_value_list_item.hpp | 25 + .../context/context_value_number.hpp | 19 + .../context/context_value_string.hpp | 19 + include/rive/data_bind/data_bind.hpp | 21 + include/rive/data_bind/data_bind_context.hpp | 27 + include/rive/data_bind/data_bind_mode.hpp | 13 + include/rive/data_bind/data_context.hpp | 38 + include/rive/dependency_helper.hpp | 46 + include/rive/dependency_sorter.hpp | 1 + include/rive/file.hpp | 29 + include/rive/generated/artboard_base.hpp | 18 + include/rive/generated/core_registry.hpp | 796 +++++++++++------- .../generated/data_bind/data_bind_base.hpp | 107 +++ .../data_bind/data_bind_context_base.hpp | 62 ++ .../rive/generated/nested_artboard_base.hpp | 11 + .../generated/viewmodel/data_enum_base.hpp | 38 + .../viewmodel/data_enum_value_base.hpp | 88 ++ .../generated/viewmodel/viewmodel_base.hpp | 71 ++ .../viewmodel/viewmodel_component_base.hpp | 67 ++ .../viewmodel/viewmodel_instance_base.hpp | 71 ++ .../viewmodel_instance_color_base.hpp | 71 ++ .../viewmodel_instance_enum_base.hpp | 71 ++ .../viewmodel_instance_list_base.hpp | 36 + .../viewmodel_instance_list_item_base.hpp | 124 +++ .../viewmodel_instance_number_base.hpp | 71 ++ .../viewmodel_instance_string_base.hpp | 72 ++ .../viewmodel_instance_value_base.hpp | 68 ++ .../viewmodel_instance_viewmodel_base.hpp | 71 ++ .../viewmodel/viewmodel_property_base.hpp | 36 + .../viewmodel_property_color_base.hpp | 37 + .../viewmodel_property_enum_base.hpp | 72 ++ .../viewmodel_property_list_base.hpp | 37 + .../viewmodel_property_number_base.hpp | 37 + .../viewmodel_property_string_base.hpp | 37 + .../viewmodel_property_viewmodel_base.hpp | 72 ++ include/rive/importers/enum_importer.hpp | 23 + include/rive/importers/viewmodel_importer.hpp | 24 + .../importers/viewmodel_instance_importer.hpp | 22 + .../viewmodel_instance_list_importer.hpp | 22 + include/rive/nested_artboard.hpp | 6 + include/rive/viewmodel/data_enum.hpp | 25 + include/rive/viewmodel/data_enum_value.hpp | 14 + include/rive/viewmodel/viewmodel.hpp | 26 + .../rive/viewmodel/viewmodel_component.hpp | 13 + include/rive/viewmodel/viewmodel_instance.hpp | 32 + .../viewmodel/viewmodel_instance_color.hpp | 14 + .../viewmodel/viewmodel_instance_enum.hpp | 18 + .../viewmodel/viewmodel_instance_list.hpp | 26 + .../viewmodel_instance_list_item.hpp | 23 + .../viewmodel/viewmodel_instance_number.hpp | 14 + .../viewmodel/viewmodel_instance_string.hpp | 14 + .../viewmodel/viewmodel_instance_value.hpp | 31 + .../viewmodel_instance_viewmodel.hpp | 23 + include/rive/viewmodel/viewmodel_property.hpp | 14 + .../viewmodel/viewmodel_property_color.hpp | 13 + .../viewmodel/viewmodel_property_enum.hpp | 27 + .../viewmodel/viewmodel_property_list.hpp | 13 + .../viewmodel/viewmodel_property_number.hpp | 13 + .../viewmodel/viewmodel_property_string.hpp | 13 + .../viewmodel_property_viewmodel.hpp | 13 + src/artboard.cpp | 189 ++++- src/component.cpp | 20 +- src/data_bind/context/context_value_color.cpp | 26 + src/data_bind/context/context_value_enum.cpp | 30 + src/data_bind/context/context_value_list.cpp | 133 +++ .../context/context_value_list_item.cpp | 11 + .../context/context_value_number.cpp | 26 + .../context/context_value_string.cpp | 26 + src/data_bind/data_bind.cpp | 43 + src/data_bind/data_bind_context.cpp | 100 +++ src/data_bind/data_context.cpp | 90 ++ src/dependency_sorter.cpp | 9 + src/file.cpp | 193 +++++ src/generated/data_bind/data_bind_base.cpp | 11 + .../data_bind/data_bind_context_base.cpp | 11 + src/generated/viewmodel/data_enum_base.cpp | 11 + .../viewmodel/data_enum_value_base.cpp | 11 + src/generated/viewmodel/viewmodel_base.cpp | 11 + .../viewmodel/viewmodel_component_base.cpp | 11 + .../viewmodel/viewmodel_instance_base.cpp | 11 + .../viewmodel_instance_color_base.cpp | 11 + .../viewmodel_instance_enum_base.cpp | 11 + .../viewmodel_instance_list_base.cpp | 11 + .../viewmodel_instance_list_item_base.cpp | 11 + .../viewmodel_instance_number_base.cpp | 11 + .../viewmodel_instance_string_base.cpp | 11 + .../viewmodel_instance_viewmodel_base.cpp | 11 + .../viewmodel/viewmodel_property_base.cpp | 11 + .../viewmodel_property_color_base.cpp | 11 + .../viewmodel_property_enum_base.cpp | 11 + .../viewmodel_property_list_base.cpp | 11 + .../viewmodel_property_number_base.cpp | 11 + .../viewmodel_property_string_base.cpp | 11 + .../viewmodel_property_viewmodel_base.cpp | 11 + src/importers/backboard_importer.cpp | 7 +- src/importers/enum_importer.cpp | 11 + src/importers/viewmodel_importer.cpp | 15 + src/importers/viewmodel_instance_importer.cpp | 15 + .../viewmodel_instance_list_importer.cpp | 16 + src/nested_artboard.cpp | 19 +- src/viewmodel/data_enum.cpp | 80 ++ src/viewmodel/data_enum_value.cpp | 21 + src/viewmodel/viewmodel.cpp | 58 ++ src/viewmodel/viewmodel_instance.cpp | 105 +++ src/viewmodel/viewmodel_instance_color.cpp | 10 + src/viewmodel/viewmodel_instance_enum.cpp | 34 + src/viewmodel/viewmodel_instance_list.cpp | 74 ++ .../viewmodel_instance_list_item.cpp | 22 + src/viewmodel/viewmodel_instance_number.cpp | 10 + src/viewmodel/viewmodel_instance_string.cpp | 10 + src/viewmodel/viewmodel_instance_value.cpp | 41 + .../viewmodel_instance_viewmodel.cpp | 13 + src/viewmodel/viewmodel_property.cpp | 17 + src/viewmodel/viewmodel_property_enum.cpp | 61 ++ viewer/src/viewer_content/scene_content.cpp | 5 + 148 files changed, 5193 insertions(+), 307 deletions(-) create mode 100644 dev/defs/data_bind/data_bind.json create mode 100644 dev/defs/data_bind/data_bind_context.json create mode 100644 dev/defs/viewmodel/data_enum.json create mode 100644 dev/defs/viewmodel/data_enum_value.json create mode 100644 dev/defs/viewmodel/viewmodel.json create mode 100644 dev/defs/viewmodel/viewmodel_component.json create mode 100644 dev/defs/viewmodel/viewmodel_instance.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_color.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_enum.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_list.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_list_item.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_number.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_string.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_value.json create mode 100644 dev/defs/viewmodel/viewmodel_instance_viewmodel.json create mode 100644 dev/defs/viewmodel/viewmodel_property.json create mode 100644 dev/defs/viewmodel/viewmodel_property_color.json create mode 100644 dev/defs/viewmodel/viewmodel_property_enum.json create mode 100644 dev/defs/viewmodel/viewmodel_property_list.json create mode 100644 dev/defs/viewmodel/viewmodel_property_number.json create mode 100644 dev/defs/viewmodel/viewmodel_property_string.json create mode 100644 dev/defs/viewmodel/viewmodel_property_viewmodel.json create mode 100644 include/rive/data_bind/context/context_value.hpp create mode 100644 include/rive/data_bind/context/context_value_color.hpp create mode 100644 include/rive/data_bind/context/context_value_enum.hpp create mode 100644 include/rive/data_bind/context/context_value_list.hpp create mode 100644 include/rive/data_bind/context/context_value_list_item.hpp create mode 100644 include/rive/data_bind/context/context_value_number.hpp create mode 100644 include/rive/data_bind/context/context_value_string.hpp create mode 100644 include/rive/data_bind/data_bind.hpp create mode 100644 include/rive/data_bind/data_bind_context.hpp create mode 100644 include/rive/data_bind/data_bind_mode.hpp create mode 100644 include/rive/data_bind/data_context.hpp create mode 100644 include/rive/dependency_helper.hpp create mode 100644 include/rive/generated/data_bind/data_bind_base.hpp create mode 100644 include/rive/generated/data_bind/data_bind_context_base.hpp create mode 100644 include/rive/generated/viewmodel/data_enum_base.hpp create mode 100644 include/rive/generated/viewmodel/data_enum_value_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_component_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_list_item_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_color_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_enum_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_list_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_number_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_string_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_viewmodel_base.hpp create mode 100644 include/rive/importers/enum_importer.hpp create mode 100644 include/rive/importers/viewmodel_importer.hpp create mode 100644 include/rive/importers/viewmodel_instance_importer.hpp create mode 100644 include/rive/importers/viewmodel_instance_list_importer.hpp create mode 100644 include/rive/viewmodel/data_enum.hpp create mode 100644 include/rive/viewmodel/data_enum_value.hpp create mode 100644 include/rive/viewmodel/viewmodel.hpp create mode 100644 include/rive/viewmodel/viewmodel_component.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_color.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_enum.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_list.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_list_item.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_number.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_string.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_value.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_viewmodel.hpp create mode 100644 include/rive/viewmodel/viewmodel_property.hpp create mode 100644 include/rive/viewmodel/viewmodel_property_color.hpp create mode 100644 include/rive/viewmodel/viewmodel_property_enum.hpp create mode 100644 include/rive/viewmodel/viewmodel_property_list.hpp create mode 100644 include/rive/viewmodel/viewmodel_property_number.hpp create mode 100644 include/rive/viewmodel/viewmodel_property_string.hpp create mode 100644 include/rive/viewmodel/viewmodel_property_viewmodel.hpp create mode 100644 src/data_bind/context/context_value_color.cpp create mode 100644 src/data_bind/context/context_value_enum.cpp create mode 100644 src/data_bind/context/context_value_list.cpp create mode 100644 src/data_bind/context/context_value_list_item.cpp create mode 100644 src/data_bind/context/context_value_number.cpp create mode 100644 src/data_bind/context/context_value_string.cpp create mode 100644 src/data_bind/data_bind.cpp create mode 100644 src/data_bind/data_bind_context.cpp create mode 100644 src/data_bind/data_context.cpp create mode 100644 src/generated/data_bind/data_bind_base.cpp create mode 100644 src/generated/data_bind/data_bind_context_base.cpp create mode 100644 src/generated/viewmodel/data_enum_base.cpp create mode 100644 src/generated/viewmodel/data_enum_value_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_component_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_color_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_enum_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_list_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_list_item_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_number_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_string_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_viewmodel_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_color_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_enum_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_list_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_number_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_string_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_viewmodel_base.cpp create mode 100644 src/importers/enum_importer.cpp create mode 100644 src/importers/viewmodel_importer.cpp create mode 100644 src/importers/viewmodel_instance_importer.cpp create mode 100644 src/importers/viewmodel_instance_list_importer.cpp create mode 100644 src/viewmodel/data_enum.cpp create mode 100644 src/viewmodel/data_enum_value.cpp create mode 100644 src/viewmodel/viewmodel.cpp create mode 100644 src/viewmodel/viewmodel_instance.cpp create mode 100644 src/viewmodel/viewmodel_instance_color.cpp create mode 100644 src/viewmodel/viewmodel_instance_enum.cpp create mode 100644 src/viewmodel/viewmodel_instance_list.cpp create mode 100644 src/viewmodel/viewmodel_instance_list_item.cpp create mode 100644 src/viewmodel/viewmodel_instance_number.cpp create mode 100644 src/viewmodel/viewmodel_instance_string.cpp create mode 100644 src/viewmodel/viewmodel_instance_value.cpp create mode 100644 src/viewmodel/viewmodel_instance_viewmodel.cpp create mode 100644 src/viewmodel/viewmodel_property.cpp create mode 100644 src/viewmodel/viewmodel_property_enum.cpp diff --git a/.rive_head b/.rive_head index 2cdb2c00..3fd5c8b5 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -7e1b3027d5ea97c7950b8f5951b0b44f33413987 +75823467d0c007983e66df245f1e9c27d707728c diff --git a/dev/core_generator/lib/src/property.dart b/dev/core_generator/lib/src/property.dart index e147e81c..46993b13 100644 --- a/dev/core_generator/lib/src/property.dart +++ b/dev/core_generator/lib/src/property.dart @@ -20,6 +20,7 @@ class Property { bool isSetOverride = false; bool isGetOverride = false; bool isEncoded = false; + bool isBindable = false; bool isPureVirtual = false; FieldType? typeRuntime; @@ -94,6 +95,10 @@ class Property { if (rt is String) { typeRuntime = FieldType.find(rt); } + dynamic b = data['bindable']; + if (b is bool) { + isBindable = b; + } dynamic pv = data['pureVirtual']; if (pv is bool) { isPureVirtual = pv; diff --git a/dev/defs/artboard.json b/dev/defs/artboard.json index 4d482a94..4079ccbe 100644 --- a/dev/defs/artboard.json +++ b/dev/defs/artboard.json @@ -96,6 +96,27 @@ "description": "List of selected animations", "runtime": false, "coop": false + }, + "viewModelId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 583, + "string": "viewmodelid" + }, + "description": "The view model attached to this artboard data context." + }, + "viewModelInstanceId": { + "type": "Id", + "initialValue": "Core.missingId", + "key": { + "int": 584, + "string": "viewmodelinstanceid" + }, + "description": "A view model instance attached for editing purposes.", + "runtime": false } } } \ No newline at end of file diff --git a/dev/defs/data_bind/data_bind.json b/dev/defs/data_bind/data_bind.json new file mode 100644 index 00000000..eaf9be27 --- /dev/null +++ b/dev/defs/data_bind/data_bind.json @@ -0,0 +1,40 @@ +{ + "name": "DataBind", + "key": { + "int": 446, + "string": "databind" + }, + "extends": "component.json", + "properties": { + "targetId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 585, + "string": "targetid" + }, + "description": "Identifier used to track the object that is targetted." + }, + "propertyKey": { + "type": "uint", + "initialValue": "CoreContext.invalidPropertyKey", + "key": { + "int": 586, + "string": "propertykey" + }, + "description": "The property that is targeted." + }, + "modeValue": { + "type": "uint", + "typeRuntime": "uint", + "initialValue": "0", + "key": { + "int": 587, + "string": "modevalue" + }, + "description": "Backing enum value for the binding mode." + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/data_bind_context.json b/dev/defs/data_bind/data_bind_context.json new file mode 100644 index 00000000..d9e04e6a --- /dev/null +++ b/dev/defs/data_bind/data_bind_context.json @@ -0,0 +1,21 @@ +{ + "name": "DataBindContext", + "key": { + "int": 447, + "string": "databindcontext" + }, + "extends": "data_bind/data_bind.json", + "properties": { + "sourcePathIds": { + "type": "List", + "typeRuntime": "Bytes", + "encoded": true, + "initialValue": "[]", + "key": { + "int": 588, + "string": "sourcepathids" + }, + "description": "Path to the selected property." + } + } +} \ No newline at end of file diff --git a/dev/defs/nested_artboard.json b/dev/defs/nested_artboard.json index e6a52110..112415c8 100644 --- a/dev/defs/nested_artboard.json +++ b/dev/defs/nested_artboard.json @@ -32,6 +32,17 @@ "string": "alignment" }, "description": "Alignment type for the nested artboard's runtime artboard." + }, + "dataBindPathIds": { + "type": "List", + "typeRuntime": "Bytes", + "encoded": true, + "initialValue": "[]", + "key": { + "int": 580, + "string": "databindpathids" + }, + "description": "Path to the selected property." } } } \ No newline at end of file diff --git a/dev/defs/viewmodel/data_enum.json b/dev/defs/viewmodel/data_enum.json new file mode 100644 index 00000000..c65b2522 --- /dev/null +++ b/dev/defs/viewmodel/data_enum.json @@ -0,0 +1,40 @@ +{ + "name": "DataEnum", + "key": { + "int": 438, + "string": "dataenum" + }, + "properties": { + "order": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "initialValueRuntime": "0", + "key": { + "int": 570, + "string": "order" + }, + "description": "Order value for sorting data enums.", + "runtime": false + }, + "splitKeyValues": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 571, + "string": "splitkeyvalues" + }, + "description": "Whether the user can edit keys and values separately.", + "runtime": false + }, + "name": { + "type": "String", + "initialValue": "''", + "key": { + "int": 572, + "string": "name" + }, + "description": "Non-unique identifier, used to give friendly names to enums.", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/data_enum_value.json b/dev/defs/viewmodel/data_enum_value.json new file mode 100644 index 00000000..d597785f --- /dev/null +++ b/dev/defs/viewmodel/data_enum_value.json @@ -0,0 +1,48 @@ +{ + "name": "DataEnumValue", + "key": { + "int": 445, + "string": "dataenumvalue" + }, + "properties": { + "key": { + "type": "String", + "initialValue": "''", + "key": { + "int": 578, + "string": "key" + }, + "description": "The key of this key value enum pair." + }, + "value": { + "type": "String", + "initialValue": "''", + "key": { + "int": 579, + "string": "value" + }, + "description": "The value of this key value enum pair." + }, + "enumId": { + "type": "Id", + "initialValue": "Core.missingId", + "key": { + "int": 580, + "string": "enumid" + }, + "description": "The id of the enum property this value belongs to.", + "runtime": false + }, + "order": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "initialValueRuntime": "0", + "key": { + "int": 581, + "string": "order" + }, + "description": "Order value for sorting enum values.", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel.json b/dev/defs/viewmodel/viewmodel.json new file mode 100644 index 00000000..bff9a160 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel.json @@ -0,0 +1,32 @@ +{ + "name": "ViewModel", + "key": { + "int": 435, + "string": "viewmodel" + }, + "extends": "viewmodel/viewmodel_component.json", + "properties": { + "viewModelOrder": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "initialValueRuntime": "0", + "key": { + "int": 563, + "string": "viewmodelorder" + }, + "description": "Order value for sorting View Models.", + "runtime": false + }, + "defaultInstanceId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 564, + "string": "defaultinstanceid" + }, + "description": "The default instance attached to the view model." + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_component.json b/dev/defs/viewmodel/viewmodel_component.json new file mode 100644 index 00000000..fd68e1ef --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_component.json @@ -0,0 +1,18 @@ +{ + "name": "ViewModelComponent", + "key": { + "int": 429, + "string": "viewmodelcomponent" + }, + "properties": { + "name": { + "type": "String", + "initialValue": "''", + "key": { + "int": 557, + "string": "name" + }, + "description": "Non-unique identifier, used to give friendly names to any view model component." + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance.json b/dev/defs/viewmodel/viewmodel_instance.json new file mode 100644 index 00000000..1ac44472 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance.json @@ -0,0 +1,50 @@ +{ + "name": "ViewModelInstance", + "key": { + "int": 437, + "string": "viewmodelinstance" + }, + "extends": "component.json", + "properties": { + "viewModelId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 566, + "string": "viewmodelid" + } + }, + "x": { + "type": "double", + "initialValue": "0", + "key": { + "int": 567, + "string": "x" + }, + "description": "The x coordinate of the stage representation.", + "runtime": false + }, + "y": { + "type": "double", + "initialValue": "0", + "key": { + "int": 568, + "string": "y" + }, + "description": "The y coordinate of the stage representation.", + "runtime": false + }, + "onStage": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 569, + "string": "onstage" + }, + "description": "Whether it is visible on stage or not.", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_color.json b/dev/defs/viewmodel/viewmodel_instance_color.json new file mode 100644 index 00000000..23ae5df0 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_color.json @@ -0,0 +1,29 @@ +{ + "name": "ViewModelInstanceColor", + "key": { + "int": 426, + "string": "viewmodelinstancecolor" + }, + "extends": "viewmodel/viewmodel_instance_value.json", + "properties": { + "propertyValue": { + "type": "Color", + "initialValue": "0xFF1D1D1D", + "key": { + "int": 555, + "string": "propertyvalue" + }, + "description": "The color value" + }, + "playbackValue": { + "type": "Color", + "initialValue": "0xFF1D1D1D", + "key": { + "int": 556, + "string": "playbackvalue" + }, + "runtime": false, + "coop": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_enum.json b/dev/defs/viewmodel/viewmodel_instance_enum.json new file mode 100644 index 00000000..7dd93df5 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_enum.json @@ -0,0 +1,21 @@ +{ + "name": "ViewModelInstanceEnum", + "key": { + "int": 432, + "string": "viewmodelinstanceenum" + }, + "extends": "viewmodel/viewmodel_instance_value.json", + "properties": { + "propertyValue": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 560, + "string": "propertyvalue" + }, + "description": "The id of the enum value." + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_list.json b/dev/defs/viewmodel/viewmodel_instance_list.json new file mode 100644 index 00000000..d38e669a --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_list.json @@ -0,0 +1,8 @@ +{ + "name": "ViewModelInstanceList", + "key": { + "int": 441, + "string": "viewmodelinstancelist" + }, + "extends": "viewmodel/viewmodel_instance_value.json" +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_list_item.json b/dev/defs/viewmodel/viewmodel_instance_list_item.json new file mode 100644 index 00000000..30938fb2 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_list_item.json @@ -0,0 +1,71 @@ +{ + "name": "ViewModelInstanceListItem", + "key": { + "int": 427, + "string": "viewmodelinstancelistitem" + }, + "properties": { + "useLinkedArtboard": { + "type": "bool", + "initialValue": "true", + "key": { + "int": 547, + "string": "uselinkedartboard" + }, + "description": "Whether the artboard linked to the view model should be used." + }, + "instanceListId": { + "type": "Id", + "initialValue": "Core.missingId", + "key": { + "int": 548, + "string": "instancelistid" + }, + "description": "The id of the list it belongs to.", + "runtime": false + }, + "viewModelId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 549, + "string": "viewmodelid" + }, + "description": "The view model id." + }, + "viewModelInstanceId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 550, + "string": "viewmodelinstanceid" + }, + "description": "The view model instance id." + }, + "artboardId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 551, + "string": "artboardid" + }, + "description": "The artboard id to link the viewmodel to if implicit is set to false." + }, + "order": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "key": { + "int": 552, + "string": "order" + }, + "description": "The order position in the list.", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_number.json b/dev/defs/viewmodel/viewmodel_instance_number.json new file mode 100644 index 00000000..e0637f9e --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_number.json @@ -0,0 +1,29 @@ +{ + "name": "ViewModelInstanceNumber", + "key": { + "int": 442, + "string": "viewmodelinstancenumber" + }, + "extends": "viewmodel/viewmodel_instance_value.json", + "properties": { + "propertyValue": { + "type": "double", + "initialValue": "0", + "key": { + "int": 575, + "string": "propertyvalue" + }, + "description": "The number value." + }, + "playbackValue": { + "type": "double", + "initialValue": "0", + "key": { + "int": 576, + "string": "playbackvalue" + }, + "runtime": false, + "coop": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_string.json b/dev/defs/viewmodel/viewmodel_instance_string.json new file mode 100644 index 00000000..bd12abb9 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_string.json @@ -0,0 +1,29 @@ +{ + "name": "ViewModelInstanceString", + "key": { + "int": 433, + "string": "viewmodelinstancestring" + }, + "extends": "viewmodel/viewmodel_instance_value.json", + "properties": { + "propertyValue": { + "type": "String", + "initialValue": "''", + "key": { + "int": 561, + "string": "propertyvalue" + }, + "description": "The string value." + }, + "playbackValue": { + "type": "String", + "initialValue": "''", + "key": { + "int": 562, + "string": "playbackvalue" + }, + "runtime": false, + "coop": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_value.json b/dev/defs/viewmodel/viewmodel_instance_value.json new file mode 100644 index 00000000..df37f837 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_value.json @@ -0,0 +1,33 @@ +{ + "name": "ViewModelInstanceValue", + "key": { + "int": 428, + "string": "viewmodelinstancevalue" + }, + "abstract": true, + "properties": { + "viewModelInstanceId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 553, + "string": "viewmodelinstanceid" + }, + "description": "Identifier of the view model instance this value is for, at runtime this is expected in context (after) a ViewModelInstance object.", + "runtime": false + }, + "viewModelPropertyId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 554, + "string": "viewmodelpropertyid" + }, + "description": "Identifier of the property this value will provide data for. At runtime these ids are normalized relative to the ViewModel itself." + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_instance_viewmodel.json b/dev/defs/viewmodel/viewmodel_instance_viewmodel.json new file mode 100644 index 00000000..e156b148 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_viewmodel.json @@ -0,0 +1,21 @@ +{ + "name": "ViewModelInstanceViewModel", + "key": { + "int": 444, + "string": "viewmodelinstanceviewmodel" + }, + "extends": "viewmodel/viewmodel_instance_value.json", + "properties": { + "propertyValue": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 577, + "string": "propertyvalue" + }, + "description": "The id of the viewmodel instance." + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property.json b/dev/defs/viewmodel/viewmodel_property.json new file mode 100644 index 00000000..5ee24829 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property.json @@ -0,0 +1,33 @@ +{ + "name": "ViewModelProperty", + "key": { + "int": 430, + "string": "viewmodelproperty" + }, + "extends": "viewmodel/viewmodel_component.json", + "properties": { + "viewModelId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 558, + "string": "viewmodelid" + }, + "description": "Identifier used to track parent View Model.", + "runtime": false + }, + "propertyOrder": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "initialValueRuntime": "0", + "key": { + "int": 559, + "string": "propertyorder" + }, + "description": "Order value for sorting child elements in View Model.", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property_color.json b/dev/defs/viewmodel/viewmodel_property_color.json new file mode 100644 index 00000000..c64d0ff8 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property_color.json @@ -0,0 +1,8 @@ +{ + "name": "ViewModelPropertyColor", + "key": { + "int": 440, + "string": "viewmodelpropertycolor" + }, + "extends": "viewmodel/viewmodel_property.json" +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property_enum.json b/dev/defs/viewmodel/viewmodel_property_enum.json new file mode 100644 index 00000000..2706486f --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property_enum.json @@ -0,0 +1,31 @@ +{ + "name": "ViewModelPropertyEnum", + "key": { + "int": 439, + "string": "viewmodelpropertyenum" + }, + "extends": "viewmodel/viewmodel_property.json", + "properties": { + "splitKeyValues": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 573, + "string": "splitkeyvalues" + }, + "description": "Whether the user can edit keys and values separately.", + "runtime": false + }, + "enumId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 574, + "string": "enumid" + }, + "description": "The id of the enum." + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property_list.json b/dev/defs/viewmodel/viewmodel_property_list.json new file mode 100644 index 00000000..1fa6b0ef --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property_list.json @@ -0,0 +1,8 @@ +{ + "name": "ViewModelPropertyList", + "key": { + "int": 434, + "string": "viewmodelpropertylist" + }, + "extends": "viewmodel/viewmodel_property.json" +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property_number.json b/dev/defs/viewmodel/viewmodel_property_number.json new file mode 100644 index 00000000..ef9cced7 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property_number.json @@ -0,0 +1,8 @@ +{ + "name": "ViewModelPropertyNumber", + "key": { + "int": 431, + "string": "viewmodelpropertynumber" + }, + "extends": "viewmodel/viewmodel_property.json" +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property_string.json b/dev/defs/viewmodel/viewmodel_property_string.json new file mode 100644 index 00000000..ca95b29b --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property_string.json @@ -0,0 +1,8 @@ +{ + "name": "ViewModelPropertyString", + "key": { + "int": 443, + "string": "viewmodelpropertystring" + }, + "extends": "viewmodel/viewmodel_property.json" +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property_viewmodel.json b/dev/defs/viewmodel/viewmodel_property_viewmodel.json new file mode 100644 index 00000000..10d615a8 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property_viewmodel.json @@ -0,0 +1,21 @@ +{ + "name": "ViewModelPropertyViewModel", + "key": { + "int": 436, + "string": "viewmodelpropertyviewmodel" + }, + "extends": "viewmodel/viewmodel_property.json", + "properties": { + "viewModelReferenceId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 565, + "string": "viewmodelreferenceid" + }, + "description": "Identifier used to track the viewmodel this property points to." + } + } +} \ No newline at end of file diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 97d6afd5..ad869a98 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -4,6 +4,11 @@ #include "rive/animation/linear_animation.hpp" #include "rive/animation/state_machine.hpp" #include "rive/core_context.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_context.hpp" +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" #include "rive/generated/artboard_base.hpp" #include "rive/hit_info.hpp" #include "rive/math/aabb.hpp" @@ -54,6 +59,9 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta std::vector m_DrawTargets; std::vector m_NestedArtboards; std::vector m_Joysticks; + std::vector m_DataBinds; + std::vector m_AllDataBinds; + DataContext* m_DataContext = nullptr; bool m_JoysticksApplyBeforeUpdate = true; bool m_HasChangedDrawOrderInLastUpdate = false; @@ -75,6 +83,7 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta void sortDependencies(); void sortDrawOrder(); + void updateDataBinds(); Artboard* getArtboard() override { return this; } @@ -116,8 +125,9 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta } bool advance(double elapsedSeconds); - bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; } - Drawable* firstDrawable() { return m_FirstDrawable; } + bool advanceInternal(double elapsedSeconds, bool isRoot); + bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; }; + Drawable* firstDrawable() { return m_FirstDrawable; }; enum class DrawOption { @@ -135,6 +145,8 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta const std::vector& objects() const { return m_Objects; } const std::vector nestedArtboards() const { return m_NestedArtboards; } + const std::vector dataBinds() const { return m_DataBinds; } + DataContext* dataContext() { return m_DataContext; } NestedArtboard* nestedArtboard(const std::string& name) const; NestedArtboard* nestedArtboardAtPath(const std::string& path) const; @@ -147,6 +159,16 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta bool isTranslucent() const; bool isTranslucent(const LinearAnimation*) const; bool isTranslucent(const LinearAnimationInstance*) const; + void dataContext(DataContext* dataContext, DataContext* parent); + void internalDataContext(DataContext* dataContext, DataContext* parent, bool isRoot); + void dataContextFromInstance(ViewModelInstance* viewModelInstance, DataContext* parent); + void dataContextFromInstance(ViewModelInstance* viewModelInstance, + DataContext* parent, + bool isRoot); + void dataContextFromInstance(ViewModelInstance* viewModelInstance); + void populateDataBinds(std::vector* dataBinds); + void buildDataBindDependencies(std::vector* dataBinds); + void sortDataBinds(std::vector dataBinds); bool hasAudio() const; template T* find(const std::string& name) @@ -230,6 +252,7 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta artboardClone->m_Factory = m_Factory; artboardClone->m_FrameOrigin = m_FrameOrigin; + artboardClone->m_DataContext = m_DataContext; artboardClone->m_IsInstance = true; artboardClone->m_originalWidth = m_originalWidth; artboardClone->m_originalHeight = m_originalHeight; diff --git a/include/rive/component.hpp b/include/rive/component.hpp index 7c260994..ba06a694 100644 --- a/include/rive/component.hpp +++ b/include/rive/component.hpp @@ -2,6 +2,7 @@ #define _RIVE_COMPONENT_HPP_ #include "rive/component_dirt.hpp" #include "rive/generated/component_base.hpp" +#include "rive/dependency_helper.hpp" #include #include @@ -17,7 +18,6 @@ class Component : public ComponentBase private: ContainerComponent* m_Parent = nullptr; - std::vector m_Dependents; unsigned int m_GraphOrder; Artboard* m_Artboard = nullptr; @@ -26,11 +26,12 @@ class Component : public ComponentBase ComponentDirt m_Dirt = ComponentDirt::Filthy; public: + DependencyHelper m_DependencyHelper; virtual bool collapse(bool value); inline Artboard* artboard() const { return m_Artboard; } StatusCode onAddedDirty(CoreContext* context) override; inline ContainerComponent* parent() const { return m_Parent; } - const std::vector& dependents() const { return m_Dependents; } + const std::vector& dependents() const { return m_DependencyHelper.dependents(); } void addDependent(Component* component); diff --git a/include/rive/component_dirt.hpp b/include/rive/component_dirt.hpp index 73f465e3..fedb0c70 100644 --- a/include/rive/component_dirt.hpp +++ b/include/rive/component_dirt.hpp @@ -56,6 +56,9 @@ enum class ComponentDirt : unsigned short /// Used by the gradients track when the stops need to be re-ordered. Stops = 1 << 10, + /// Used by data binds to track the value has changed. + Bindings = 1 << 11, + /// Blend modes need to be updated // TODO: do we need this? // BlendMode = 1 << 9, diff --git a/include/rive/data_bind/context/context_value.hpp b/include/rive/data_bind/context/context_value.hpp new file mode 100644 index 00000000..1f08e45f --- /dev/null +++ b/include/rive/data_bind/context/context_value.hpp @@ -0,0 +1,22 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_HPP_ +#include "rive/refcnt.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include +namespace rive +{ +class DataBindContextValue +{ +protected: + ViewModelInstanceValue* m_Source; + +public: + DataBindContextValue(){}; + virtual ~DataBindContextValue(){}; + virtual void applyToSource(Component* component, uint32_t propertyKey){}; + virtual void apply(Component* component, uint32_t propertyKey){}; + virtual void update(Component* component){}; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value_color.hpp b/include/rive/data_bind/context/context_value_color.hpp new file mode 100644 index 00000000..c1c7f48c --- /dev/null +++ b/include/rive/data_bind/context/context_value_color.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_COLOR_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_COLOR_HPP_ +#include "rive/data_bind/context/context_value.hpp" +namespace rive +{ +class DataBindContextValueColor : public DataBindContextValue +{ + +public: + DataBindContextValueColor(ViewModelInstanceValue* value); + void apply(Component* component, uint32_t propertyKey) override; + virtual void applyToSource(Component* component, uint32_t propertyKey) override; + +private: + double m_Value; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value_enum.hpp b/include/rive/data_bind/context/context_value_enum.hpp new file mode 100644 index 00000000..e78a1b5a --- /dev/null +++ b/include/rive/data_bind/context/context_value_enum.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_ENUM_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_ENUM_HPP_ +#include "rive/data_bind/context/context_value.hpp" +namespace rive +{ +class DataBindContextValueEnum : public DataBindContextValue +{ + +public: + DataBindContextValueEnum(ViewModelInstanceValue* value); + void apply(Component* component, uint32_t propertyKey) override; + virtual void applyToSource(Component* component, uint32_t propertyKey) override; + +private: + int m_Value; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value_list.hpp b/include/rive/data_bind/context/context_value_list.hpp new file mode 100644 index 00000000..3ee4f2dc --- /dev/null +++ b/include/rive/data_bind/context/context_value_list.hpp @@ -0,0 +1,33 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_LIST_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_LIST_HPP_ +#include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/context/context_value_list_item.hpp" +#include "rive/artboard.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +namespace rive +{ +class DataBindContextValueList : public DataBindContextValue +{ + +public: + DataBindContextValueList(ViewModelInstanceValue* value); + void apply(Component* component, uint32_t propertyKey) override; + void update(Component* target) override; + virtual void applyToSource(Component* component, uint32_t propertyKey) override; + +private: + std::vector> m_ListItemsCache; + void insertItem(Component* target, + ViewModelInstanceListItem* viewModelInstanceListItem, + int index); + void swapItems(Component* target, int index1, int index2); + void popItem(Component* target); + std::unique_ptr createArtboard(Component* target, + Artboard* artboard, + ViewModelInstanceListItem* listItem) const; + std::unique_ptr createStateMachineInstance(ArtboardInstance* artboard); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value_list_item.hpp b/include/rive/data_bind/context/context_value_list_item.hpp new file mode 100644 index 00000000..f15493b3 --- /dev/null +++ b/include/rive/data_bind/context/context_value_list_item.hpp @@ -0,0 +1,25 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_LIST_ITEM_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_LIST_ITEM_HPP_ +#include "rive/data_bind/context/context_value.hpp" +#include "rive/artboard.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +namespace rive +{ +class DataBindContextValueListItem +{ + +private: + std::unique_ptr m_Artboard; + std::unique_ptr m_StateMachine; + ViewModelInstanceListItem* m_ListItem; + +public: + DataBindContextValueListItem(std::unique_ptr artboard, + std::unique_ptr stateMachine, + ViewModelInstanceListItem* listItem); + ViewModelInstanceListItem* listItem() { return m_ListItem; }; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value_number.hpp b/include/rive/data_bind/context/context_value_number.hpp new file mode 100644 index 00000000..da866d34 --- /dev/null +++ b/include/rive/data_bind/context/context_value_number.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_NUMBER_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_NUMBER_HPP_ +#include "rive/data_bind/context/context_value.hpp" +namespace rive +{ +class DataBindContextValueNumber : public DataBindContextValue +{ + +public: + DataBindContextValueNumber(ViewModelInstanceValue* value); + void apply(Component* component, uint32_t propertyKey) override; + virtual void applyToSource(Component* component, uint32_t propertyKey) override; + +private: + double m_Value; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value_string.hpp b/include/rive/data_bind/context/context_value_string.hpp new file mode 100644 index 00000000..52f2ac39 --- /dev/null +++ b/include/rive/data_bind/context/context_value_string.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_STRING_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_STRING_HPP_ +#include "rive/data_bind/context/context_value.hpp" +namespace rive +{ +class DataBindContextValueString : public DataBindContextValue +{ + +public: + DataBindContextValueString(ViewModelInstanceValue* value); + void apply(Component* component, uint32_t propertyKey) override; + virtual void applyToSource(Component* component, uint32_t propertyKey) override; + +private: + std::string m_Value; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_bind.hpp b/include/rive/data_bind/data_bind.hpp new file mode 100644 index 00000000..ec9b5aeb --- /dev/null +++ b/include/rive/data_bind/data_bind.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_DATA_BIND_HPP_ +#define _RIVE_DATA_BIND_HPP_ +#include "rive/generated/data_bind/data_bind_base.hpp" +#include +namespace rive +{ +class DataBind : public DataBindBase +{ +public: + StatusCode onAddedDirty(CoreContext* context) override; + StatusCode import(ImportStack& importStack) override; + void buildDependencies() override; + virtual void updateSourceBinding(); + Component* target() { return m_target; }; + +protected: + Component* m_target; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_bind_context.hpp b/include/rive/data_bind/data_bind_context.hpp new file mode 100644 index 00000000..93028b46 --- /dev/null +++ b/include/rive/data_bind/data_bind_context.hpp @@ -0,0 +1,27 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_HPP_ +#include "rive/generated/data_bind/data_bind_context_base.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/data_bind/context/context_value.hpp" +#include "rive/refcnt.hpp" +#include +namespace rive +{ +class DataBindContext : public DataBindContextBase +{ +protected: + std::vector m_SourcePathIdsBuffer; + ViewModelInstanceValue* m_Source; + std::unique_ptr m_ContextValue; + +public: + void update(ComponentDirt value) override; + void decodeSourcePathIds(Span value) override; + void copySourcePathIds(const DataBindContextBase& object) override; + void bindToContext(); + void updateSourceBinding() override; + ViewModelInstanceValue* source() { return m_Source; }; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_bind_mode.hpp b/include/rive/data_bind/data_bind_mode.hpp new file mode 100644 index 00000000..692e62dc --- /dev/null +++ b/include/rive/data_bind/data_bind_mode.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_DATA_BIND_MODE_HPP_ +#define _RIVE_DATA_BIND_MODE_HPP_ +namespace rive +{ +enum class DataBindMode : unsigned int +{ + oneWay = 0, + twoWay = 1, + oneWayToSource = 2, + once = 3, +}; +} +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_context.hpp b/include/rive/data_bind/data_context.hpp new file mode 100644 index 00000000..5bc65282 --- /dev/null +++ b/include/rive/data_bind/data_context.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_DATA_CONTEXT_HPP_ +#define _RIVE_DATA_CONTEXT_HPP_ +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" + +namespace rive +{ +class DataContext +{ +private: + DataContext* m_Parent = nullptr; + std::vector m_ViewModelInstances; + ViewModelInstance* m_ViewModelInstance; + +public: + DataContext(); + DataContext(ViewModelInstance* viewModelInstance); + ~DataContext(); + + DataContext* parent() { return m_Parent; } + void parent(DataContext* value) { m_Parent = value; } + void addViewModelInstance(ViewModelInstance* value); + ViewModelInstanceValue* getViewModelProperty(const std::vector path) const; + ViewModelInstance* getViewModelInstance(const std::vector path) const; + void viewModelInstance(ViewModelInstance* value); + ViewModelInstance* viewModelInstance() { return m_ViewModelInstance; }; + + ViewModelInstanceValue* viewModelValue() + { + if (m_Parent) + { + return m_Parent->viewModelValue(); + } + return nullptr; + } +}; +} // namespace rive +#endif diff --git a/include/rive/dependency_helper.hpp b/include/rive/dependency_helper.hpp new file mode 100644 index 00000000..59ef805d --- /dev/null +++ b/include/rive/dependency_helper.hpp @@ -0,0 +1,46 @@ +#ifndef _RIVE_DEPENDENCY_HELPER_HPP_ +#define _RIVE_DEPENDENCY_HELPER_HPP_ + +#include "rive/component_dirt.hpp" + +namespace rive +{ +class Component; +// class DependencyRoot +// { +// public: +// virtual void onComponentDirty(Component* component) {}; +// }; + +template class DependencyHelper +{ + std::vector m_Dependents; + T* m_dependecyRoot; + +public: + void dependecyRoot(T* value) { m_dependecyRoot = value; } + DependencyHelper(T* value) : m_dependecyRoot(value) {} + DependencyHelper() {} + void addDependent(U* component) + { + // Make it's not already a dependent. + if (std::find(m_Dependents.begin(), m_Dependents.end(), component) != m_Dependents.end()) + { + return; + } + m_Dependents.push_back(component); + } + void addDirt(ComponentDirt value) + { + for (auto d : m_Dependents) + { + d->addDirt(value, true); + } + } + + void onComponentDirty(U* component) { m_dependecyRoot->onComponentDirty(component); } + + const std::vector& dependents() const { return m_Dependents; } +}; +} // namespace rive +#endif diff --git a/include/rive/dependency_sorter.hpp b/include/rive/dependency_sorter.hpp index 3c9cea3a..17ac8254 100644 --- a/include/rive/dependency_sorter.hpp +++ b/include/rive/dependency_sorter.hpp @@ -15,6 +15,7 @@ class DependencySorter public: void sort(Component* root, std::vector& order); + void sort(std::vector roots, std::vector& order); bool visit(Component* component, std::vector& order); }; } // namespace rive diff --git a/include/rive/file.hpp b/include/rive/file.hpp index 9f6659d9..52c1dfec 100644 --- a/include/rive/file.hpp +++ b/include/rive/file.hpp @@ -5,6 +5,12 @@ #include "rive/backboard.hpp" #include "rive/factory.hpp" #include "rive/file_asset_loader.hpp" +#include "rive/viewmodel/data_enum.hpp" +#include "rive/viewmodel/viewmodel_component.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" #include #include @@ -82,6 +88,23 @@ class File /// index is out of range. Artboard* artboard(size_t index) const; + /// @returns a view model instance of the view model with the specified name. + ViewModelInstance* createViewModelInstance(std::string name); + + /// @returns a view model instance attached to the artboard if it exists. + ViewModelInstance* createViewModelInstance(Artboard* artboard); + + /// @returns a view model instance of the viewModel. + ViewModelInstance* createViewModelInstance(ViewModel* viewModel); + + /// @returns a view model instance of the viewModel by name and instance name. + ViewModelInstance* createViewModelInstance(std::string name, std::string instanceName); + + ViewModel* viewModel(std::string name); + ViewModelInstanceListItem* viewModelInstanceListItem(ViewModelInstance* viewModelInstance); + ViewModelInstanceListItem* viewModelInstanceListItem(ViewModelInstance* viewModelInstance, + Artboard* artboard); + #ifdef WITH_RIVE_TOOLS /// Strips FileAssetContents for FileAssets of given typeKeys. /// @param data the raw data of the file. @@ -107,11 +130,17 @@ class File /// Rive components and animations. std::vector m_artboards; + std::vector m_ViewModels; + std::vector m_Enums; + Factory* m_factory; /// The helper used to load assets when they're not provided in-band /// with the file. FileAssetLoader* m_assetLoader; + + void completeViewModelInstance(ViewModelInstance* viewModelInstance); + ViewModelInstance* copyViewModelInstance(ViewModelInstance* viewModelInstance); }; } // namespace rive #endif diff --git a/include/rive/generated/artboard_base.hpp b/include/rive/generated/artboard_base.hpp index 54a378b2..ff19a02a 100644 --- a/include/rive/generated/artboard_base.hpp +++ b/include/rive/generated/artboard_base.hpp @@ -37,6 +37,7 @@ class ArtboardBase : public LayoutComponent static const uint16_t originXPropertyKey = 11; static const uint16_t originYPropertyKey = 12; static const uint16_t defaultStateMachineIdPropertyKey = 236; + static const uint16_t viewModelIdPropertyKey = 583; private: float m_X = 0.0f; @@ -44,6 +45,7 @@ class ArtboardBase : public LayoutComponent float m_OriginX = 0.0f; float m_OriginY = 0.0f; uint32_t m_DefaultStateMachineId = -1; + uint32_t m_ViewModelId = -1; public: inline float x() const { return m_X; } @@ -101,6 +103,17 @@ class ArtboardBase : public LayoutComponent defaultStateMachineIdChanged(); } + inline uint32_t viewModelId() const { return m_ViewModelId; } + void viewModelId(uint32_t value) + { + if (m_ViewModelId == value) + { + return; + } + m_ViewModelId = value; + viewModelIdChanged(); + } + Core* clone() const override; void copy(const ArtboardBase& object) { @@ -109,6 +122,7 @@ class ArtboardBase : public LayoutComponent m_OriginX = object.m_OriginX; m_OriginY = object.m_OriginY; m_DefaultStateMachineId = object.m_DefaultStateMachineId; + m_ViewModelId = object.m_ViewModelId; LayoutComponent::copy(object); } @@ -131,6 +145,9 @@ class ArtboardBase : public LayoutComponent case defaultStateMachineIdPropertyKey: m_DefaultStateMachineId = CoreUintType::deserialize(reader); return true; + case viewModelIdPropertyKey: + m_ViewModelId = CoreUintType::deserialize(reader); + return true; } return LayoutComponent::deserialize(propertyKey, reader); } @@ -141,6 +158,7 @@ class ArtboardBase : public LayoutComponent virtual void originXChanged() {} virtual void originYChanged() {} virtual void defaultStateMachineIdChanged() {} + virtual void viewModelIdChanged() {} }; } // namespace rive diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index f9416480..c4018d2e 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -99,6 +99,8 @@ #include "rive/custom_property_boolean.hpp" #include "rive/custom_property_number.hpp" #include "rive/custom_property_string.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_bind_context.hpp" #include "rive/draw_rules.hpp" #include "rive/draw_target.hpp" #include "rive/drawable.hpp" @@ -152,6 +154,26 @@ #include "rive/text/text_value_run.hpp" #include "rive/text/text_variation_modifier.hpp" #include "rive/transform_component.hpp" +#include "rive/viewmodel/data_enum.hpp" +#include "rive/viewmodel/data_enum_value.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_component.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_color.hpp" +#include "rive/viewmodel/viewmodel_instance_enum.hpp" +#include "rive/viewmodel/viewmodel_instance_list.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" +#include "rive/viewmodel/viewmodel_instance_string.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/viewmodel/viewmodel_property_color.hpp" +#include "rive/viewmodel/viewmodel_property_enum.hpp" +#include "rive/viewmodel/viewmodel_property_list.hpp" +#include "rive/viewmodel/viewmodel_property_number.hpp" +#include "rive/viewmodel/viewmodel_property_string.hpp" +#include "rive/viewmodel/viewmodel_property_viewmodel.hpp" #include "rive/world_transform_component.hpp" namespace rive { @@ -162,6 +184,44 @@ class CoreRegistry { switch (typeKey) { + case ViewModelInstanceListItemBase::typeKey: + return new ViewModelInstanceListItem(); + case ViewModelInstanceColorBase::typeKey: + return new ViewModelInstanceColor(); + case ViewModelComponentBase::typeKey: + return new ViewModelComponent(); + case ViewModelPropertyBase::typeKey: + return new ViewModelProperty(); + case ViewModelPropertyNumberBase::typeKey: + return new ViewModelPropertyNumber(); + case ViewModelInstanceEnumBase::typeKey: + return new ViewModelInstanceEnum(); + case ViewModelInstanceStringBase::typeKey: + return new ViewModelInstanceString(); + case ViewModelPropertyListBase::typeKey: + return new ViewModelPropertyList(); + case ViewModelBase::typeKey: + return new ViewModel(); + case ViewModelPropertyViewModelBase::typeKey: + return new ViewModelPropertyViewModel(); + case ViewModelInstanceBase::typeKey: + return new ViewModelInstance(); + case DataEnumBase::typeKey: + return new DataEnum(); + case ViewModelPropertyEnumBase::typeKey: + return new ViewModelPropertyEnum(); + case ViewModelPropertyColorBase::typeKey: + return new ViewModelPropertyColor(); + case ViewModelInstanceListBase::typeKey: + return new ViewModelInstanceList(); + case ViewModelInstanceNumberBase::typeKey: + return new ViewModelInstanceNumber(); + case ViewModelPropertyStringBase::typeKey: + return new ViewModelPropertyString(); + case ViewModelInstanceViewModelBase::typeKey: + return new ViewModelInstanceViewModel(); + case DataEnumValueBase::typeKey: + return new DataEnumValue(); case DrawTargetBase::typeKey: return new DrawTarget(); case CustomPropertyNumberBase::typeKey: @@ -342,6 +402,10 @@ class CoreRegistry return new AbsoluteLayoutComponent(); case OpenUrlEventBase::typeKey: return new OpenUrlEvent(); + case DataBindBase::typeKey: + return new DataBind(); + case DataBindContextBase::typeKey: + return new DataBindContext(); case WeightBase::typeKey: return new Weight(); case BoneBase::typeKey: @@ -387,36 +451,87 @@ class CoreRegistry } return nullptr; } - static void setString(Core* object, int propertyKey, std::string value) + static void setBool(Core* object, int propertyKey, bool value) { switch (propertyKey) { - case ComponentBase::namePropertyKey: - object->as()->name(value); + case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: + object->as()->useLinkedArtboard(value); break; - case AnimationBase::namePropertyKey: - object->as()->name(value); + case TransformComponentConstraintBase::offsetPropertyKey: + object->as()->offset(value); break; - case StateMachineComponentBase::namePropertyKey: - object->as()->name(value); + case TransformComponentConstraintBase::doesCopyPropertyKey: + object->as()->doesCopy(value); break; - case KeyFrameStringBase::valuePropertyKey: - object->as()->value(value); + case TransformComponentConstraintBase::minPropertyKey: + object->as()->min(value); break; - case OpenUrlEventBase::urlPropertyKey: - object->as()->url(value); + case TransformComponentConstraintBase::maxPropertyKey: + object->as()->max(value); break; - case TextValueRunBase::textPropertyKey: - object->as()->text(value); + case TransformComponentConstraintYBase::doesCopyYPropertyKey: + object->as()->doesCopyY(value); break; - case CustomPropertyStringBase::propertyValuePropertyKey: - object->as()->propertyValue(value); + case TransformComponentConstraintYBase::minYPropertyKey: + object->as()->minY(value); break; - case AssetBase::namePropertyKey: - object->as()->name(value); + case TransformComponentConstraintYBase::maxYPropertyKey: + object->as()->maxY(value); break; - case FileAssetBase::cdnBaseUrlPropertyKey: - object->as()->cdnBaseUrl(value); + case IKConstraintBase::invertDirectionPropertyKey: + object->as()->invertDirection(value); + break; + case FollowPathConstraintBase::orientPropertyKey: + object->as()->orient(value); + break; + case FollowPathConstraintBase::offsetPropertyKey: + object->as()->offset(value); + break; + case NestedSimpleAnimationBase::isPlayingPropertyKey: + object->as()->isPlaying(value); + break; + case KeyFrameBoolBase::valuePropertyKey: + object->as()->value(value); + break; + case ListenerAlignTargetBase::preserveOffsetPropertyKey: + object->as()->preserveOffset(value); + break; + case NestedBoolBase::nestedValuePropertyKey: + object->as()->nestedValue(value); + break; + case LinearAnimationBase::enableWorkAreaPropertyKey: + object->as()->enableWorkArea(value); + break; + case LinearAnimationBase::quantizePropertyKey: + object->as()->quantize(value); + break; + case StateMachineBoolBase::valuePropertyKey: + object->as()->value(value); + break; + case ShapePaintBase::isVisiblePropertyKey: + object->as()->isVisible(value); + break; + case StrokeBase::transformAffectsStrokePropertyKey: + object->as()->transformAffectsStroke(value); + break; + case PointsPathBase::isClosedPropertyKey: + object->as()->isClosed(value); + break; + case RectangleBase::linkCornerRadiusPropertyKey: + object->as()->linkCornerRadius(value); + break; + case ClippingShapeBase::isVisiblePropertyKey: + object->as()->isVisible(value); + break; + case CustomPropertyBooleanBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case LayoutComponentBase::clipPropertyKey: + object->as()->clip(value); + break; + case TextModifierRangeBase::clampPropertyKey: + object->as()->clamp(value); break; } } @@ -424,9 +539,39 @@ class CoreRegistry { switch (propertyKey) { + case ViewModelInstanceListItemBase::viewModelIdPropertyKey: + object->as()->viewModelId(value); + break; + case ViewModelInstanceListItemBase::viewModelInstanceIdPropertyKey: + object->as()->viewModelInstanceId(value); + break; + case ViewModelInstanceListItemBase::artboardIdPropertyKey: + object->as()->artboardId(value); + break; + case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: + object->as()->viewModelPropertyId(value); + break; + case ViewModelInstanceEnumBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case ViewModelBase::defaultInstanceIdPropertyKey: + object->as()->defaultInstanceId(value); + break; + case ViewModelPropertyViewModelBase::viewModelReferenceIdPropertyKey: + object->as()->viewModelReferenceId(value); + break; case ComponentBase::parentIdPropertyKey: object->as()->parentId(value); break; + case ViewModelInstanceBase::viewModelIdPropertyKey: + object->as()->viewModelId(value); + break; + case ViewModelPropertyEnumBase::enumIdPropertyKey: + object->as()->enumId(value); + break; + case ViewModelInstanceViewModelBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case DrawTargetBase::drawableIdPropertyKey: object->as()->drawableId(value); break; @@ -634,6 +779,9 @@ class CoreRegistry case ArtboardBase::defaultStateMachineIdPropertyKey: object->as()->defaultStateMachineId(value); break; + case ArtboardBase::viewModelIdPropertyKey: + object->as()->viewModelId(value); + break; case JoystickBase::xIdPropertyKey: object->as()->xId(value); break; @@ -649,6 +797,15 @@ class CoreRegistry case OpenUrlEventBase::targetValuePropertyKey: object->as()->targetValue(value); break; + case DataBindBase::targetIdPropertyKey: + object->as()->targetId(value); + break; + case DataBindBase::propertyKeyPropertyKey: + object->as()->propertyKey(value); + break; + case DataBindBase::modeValuePropertyKey: + object->as()->modeValue(value); + break; case WeightBase::valuesPropertyKey: object->as()->values(value); break; @@ -723,10 +880,76 @@ class CoreRegistry break; } } + static void setColor(Core* object, int propertyKey, int value) + { + switch (propertyKey) + { + case ViewModelInstanceColorBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case KeyFrameColorBase::valuePropertyKey: + object->as()->value(value); + break; + case SolidColorBase::colorValuePropertyKey: + object->as()->colorValue(value); + break; + case GradientStopBase::colorValuePropertyKey: + object->as()->colorValue(value); + break; + } + } + static void setString(Core* object, int propertyKey, std::string value) + { + switch (propertyKey) + { + case ViewModelComponentBase::namePropertyKey: + object->as()->name(value); + break; + case ViewModelInstanceStringBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case ComponentBase::namePropertyKey: + object->as()->name(value); + break; + case DataEnumValueBase::keyPropertyKey: + object->as()->key(value); + break; + case DataEnumValueBase::valuePropertyKey: + object->as()->value(value); + break; + case AnimationBase::namePropertyKey: + object->as()->name(value); + break; + case StateMachineComponentBase::namePropertyKey: + object->as()->name(value); + break; + case KeyFrameStringBase::valuePropertyKey: + object->as()->value(value); + break; + case OpenUrlEventBase::urlPropertyKey: + object->as()->url(value); + break; + case TextValueRunBase::textPropertyKey: + object->as()->text(value); + break; + case CustomPropertyStringBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; + case AssetBase::namePropertyKey: + object->as()->name(value); + break; + case FileAssetBase::cdnBaseUrlPropertyKey: + object->as()->cdnBaseUrl(value); + break; + } + } static void setDouble(Core* object, int propertyKey, float value) { switch (propertyKey) { + case ViewModelInstanceNumberBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case CustomPropertyNumberBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -1206,145 +1429,103 @@ class CoreRegistry break; } } - static void setBool(Core* object, int propertyKey, bool value) + static void setCallback(Core* object, int propertyKey, CallbackData value) { switch (propertyKey) { - case TransformComponentConstraintBase::offsetPropertyKey: - object->as()->offset(value); + case NestedTriggerBase::firePropertyKey: + object->as()->fire(value); break; - case TransformComponentConstraintBase::doesCopyPropertyKey: - object->as()->doesCopy(value); + case EventBase::triggerPropertyKey: + object->as()->trigger(value); break; + } + } + static bool getBool(Core* object, int propertyKey) + { + switch (propertyKey) + { + case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: + return object->as()->useLinkedArtboard(); + case TransformComponentConstraintBase::offsetPropertyKey: + return object->as()->offset(); + case TransformComponentConstraintBase::doesCopyPropertyKey: + return object->as()->doesCopy(); case TransformComponentConstraintBase::minPropertyKey: - object->as()->min(value); - break; + return object->as()->min(); case TransformComponentConstraintBase::maxPropertyKey: - object->as()->max(value); - break; + return object->as()->max(); case TransformComponentConstraintYBase::doesCopyYPropertyKey: - object->as()->doesCopyY(value); - break; + return object->as()->doesCopyY(); case TransformComponentConstraintYBase::minYPropertyKey: - object->as()->minY(value); - break; + return object->as()->minY(); case TransformComponentConstraintYBase::maxYPropertyKey: - object->as()->maxY(value); - break; + return object->as()->maxY(); case IKConstraintBase::invertDirectionPropertyKey: - object->as()->invertDirection(value); - break; + return object->as()->invertDirection(); case FollowPathConstraintBase::orientPropertyKey: - object->as()->orient(value); - break; + return object->as()->orient(); case FollowPathConstraintBase::offsetPropertyKey: - object->as()->offset(value); - break; + return object->as()->offset(); case NestedSimpleAnimationBase::isPlayingPropertyKey: - object->as()->isPlaying(value); - break; + return object->as()->isPlaying(); case KeyFrameBoolBase::valuePropertyKey: - object->as()->value(value); - break; + return object->as()->value(); case ListenerAlignTargetBase::preserveOffsetPropertyKey: - object->as()->preserveOffset(value); - break; + return object->as()->preserveOffset(); case NestedBoolBase::nestedValuePropertyKey: - object->as()->nestedValue(value); - break; + return object->as()->nestedValue(); case LinearAnimationBase::enableWorkAreaPropertyKey: - object->as()->enableWorkArea(value); - break; + return object->as()->enableWorkArea(); case LinearAnimationBase::quantizePropertyKey: - object->as()->quantize(value); - break; + return object->as()->quantize(); case StateMachineBoolBase::valuePropertyKey: - object->as()->value(value); - break; + return object->as()->value(); case ShapePaintBase::isVisiblePropertyKey: - object->as()->isVisible(value); - break; + return object->as()->isVisible(); case StrokeBase::transformAffectsStrokePropertyKey: - object->as()->transformAffectsStroke(value); - break; + return object->as()->transformAffectsStroke(); case PointsPathBase::isClosedPropertyKey: - object->as()->isClosed(value); - break; + return object->as()->isClosed(); case RectangleBase::linkCornerRadiusPropertyKey: - object->as()->linkCornerRadius(value); - break; + return object->as()->linkCornerRadius(); case ClippingShapeBase::isVisiblePropertyKey: - object->as()->isVisible(value); - break; + return object->as()->isVisible(); case CustomPropertyBooleanBase::propertyValuePropertyKey: - object->as()->propertyValue(value); - break; + return object->as()->propertyValue(); case LayoutComponentBase::clipPropertyKey: - object->as()->clip(value); - break; + return object->as()->clip(); case TextModifierRangeBase::clampPropertyKey: - object->as()->clamp(value); - break; - } - } - static void setCallback(Core* object, int propertyKey, CallbackData value) - { - switch (propertyKey) - { - case NestedTriggerBase::firePropertyKey: - object->as()->fire(value); - break; - case EventBase::triggerPropertyKey: - object->as()->trigger(value); - break; - } - } - static void setColor(Core* object, int propertyKey, int value) - { - switch (propertyKey) - { - case KeyFrameColorBase::valuePropertyKey: - object->as()->value(value); - break; - case SolidColorBase::colorValuePropertyKey: - object->as()->colorValue(value); - break; - case GradientStopBase::colorValuePropertyKey: - object->as()->colorValue(value); - break; - } - } - static std::string getString(Core* object, int propertyKey) - { - switch (propertyKey) - { - case ComponentBase::namePropertyKey: - return object->as()->name(); - case AnimationBase::namePropertyKey: - return object->as()->name(); - case StateMachineComponentBase::namePropertyKey: - return object->as()->name(); - case KeyFrameStringBase::valuePropertyKey: - return object->as()->value(); - case OpenUrlEventBase::urlPropertyKey: - return object->as()->url(); - case TextValueRunBase::textPropertyKey: - return object->as()->text(); - case CustomPropertyStringBase::propertyValuePropertyKey: - return object->as()->propertyValue(); - case AssetBase::namePropertyKey: - return object->as()->name(); - case FileAssetBase::cdnBaseUrlPropertyKey: - return object->as()->cdnBaseUrl(); + return object->as()->clamp(); } - return ""; + return false; } static uint32_t getUint(Core* object, int propertyKey) { switch (propertyKey) { + case ViewModelInstanceListItemBase::viewModelIdPropertyKey: + return object->as()->viewModelId(); + case ViewModelInstanceListItemBase::viewModelInstanceIdPropertyKey: + return object->as()->viewModelInstanceId(); + case ViewModelInstanceListItemBase::artboardIdPropertyKey: + return object->as()->artboardId(); + case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: + return object->as()->viewModelPropertyId(); + case ViewModelInstanceEnumBase::propertyValuePropertyKey: + return object->as()->propertyValue(); + case ViewModelBase::defaultInstanceIdPropertyKey: + return object->as()->defaultInstanceId(); + case ViewModelPropertyViewModelBase::viewModelReferenceIdPropertyKey: + return object->as()->viewModelReferenceId(); case ComponentBase::parentIdPropertyKey: return object->as()->parentId(); + case ViewModelInstanceBase::viewModelIdPropertyKey: + return object->as()->viewModelId(); + case ViewModelPropertyEnumBase::enumIdPropertyKey: + return object->as()->enumId(); + case ViewModelInstanceViewModelBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case DrawTargetBase::drawableIdPropertyKey: return object->as()->drawableId(); case DrawTargetBase::placementValuePropertyKey: @@ -1483,6 +1664,8 @@ class CoreRegistry return object->as()->styleId(); case ArtboardBase::defaultStateMachineIdPropertyKey: return object->as()->defaultStateMachineId(); + case ArtboardBase::viewModelIdPropertyKey: + return object->as()->viewModelId(); case JoystickBase::xIdPropertyKey: return object->as()->xId(); case JoystickBase::yIdPropertyKey: @@ -1493,6 +1676,12 @@ class CoreRegistry return object->as()->handleSourceId(); case OpenUrlEventBase::targetValuePropertyKey: return object->as()->targetValue(); + case DataBindBase::targetIdPropertyKey: + return object->as()->targetId(); + case DataBindBase::propertyKeyPropertyKey: + return object->as()->propertyKey(); + case DataBindBase::modeValuePropertyKey: + return object->as()->modeValue(); case WeightBase::valuesPropertyKey: return object->as()->values(); case WeightBase::indicesPropertyKey: @@ -1542,12 +1731,62 @@ class CoreRegistry case AudioEventBase::assetIdPropertyKey: return object->as()->assetId(); } - return 0; + return 0; + } + static int getColor(Core* object, int propertyKey) + { + switch (propertyKey) + { + case ViewModelInstanceColorBase::propertyValuePropertyKey: + return object->as()->propertyValue(); + case KeyFrameColorBase::valuePropertyKey: + return object->as()->value(); + case SolidColorBase::colorValuePropertyKey: + return object->as()->colorValue(); + case GradientStopBase::colorValuePropertyKey: + return object->as()->colorValue(); + } + return 0; + } + static std::string getString(Core* object, int propertyKey) + { + switch (propertyKey) + { + case ViewModelComponentBase::namePropertyKey: + return object->as()->name(); + case ViewModelInstanceStringBase::propertyValuePropertyKey: + return object->as()->propertyValue(); + case ComponentBase::namePropertyKey: + return object->as()->name(); + case DataEnumValueBase::keyPropertyKey: + return object->as()->key(); + case DataEnumValueBase::valuePropertyKey: + return object->as()->value(); + case AnimationBase::namePropertyKey: + return object->as()->name(); + case StateMachineComponentBase::namePropertyKey: + return object->as()->name(); + case KeyFrameStringBase::valuePropertyKey: + return object->as()->value(); + case OpenUrlEventBase::urlPropertyKey: + return object->as()->url(); + case TextValueRunBase::textPropertyKey: + return object->as()->text(); + case CustomPropertyStringBase::propertyValuePropertyKey: + return object->as()->propertyValue(); + case AssetBase::namePropertyKey: + return object->as()->name(); + case FileAssetBase::cdnBaseUrlPropertyKey: + return object->as()->cdnBaseUrl(); + } + return ""; } static float getDouble(Core* object, int propertyKey) { switch (propertyKey) { + case ViewModelInstanceNumberBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case CustomPropertyNumberBase::propertyValuePropertyKey: return object->as()->propertyValue(); case ConstraintBase::strengthPropertyKey: @@ -1869,91 +2108,48 @@ class CoreRegistry } return 0.0f; } - static bool getBool(Core* object, int propertyKey) + static int propertyFieldId(int propertyKey) { switch (propertyKey) { + case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: case TransformComponentConstraintBase::offsetPropertyKey: - return object->as()->offset(); case TransformComponentConstraintBase::doesCopyPropertyKey: - return object->as()->doesCopy(); case TransformComponentConstraintBase::minPropertyKey: - return object->as()->min(); case TransformComponentConstraintBase::maxPropertyKey: - return object->as()->max(); case TransformComponentConstraintYBase::doesCopyYPropertyKey: - return object->as()->doesCopyY(); case TransformComponentConstraintYBase::minYPropertyKey: - return object->as()->minY(); case TransformComponentConstraintYBase::maxYPropertyKey: - return object->as()->maxY(); case IKConstraintBase::invertDirectionPropertyKey: - return object->as()->invertDirection(); case FollowPathConstraintBase::orientPropertyKey: - return object->as()->orient(); case FollowPathConstraintBase::offsetPropertyKey: - return object->as()->offset(); case NestedSimpleAnimationBase::isPlayingPropertyKey: - return object->as()->isPlaying(); case KeyFrameBoolBase::valuePropertyKey: - return object->as()->value(); case ListenerAlignTargetBase::preserveOffsetPropertyKey: - return object->as()->preserveOffset(); case NestedBoolBase::nestedValuePropertyKey: - return object->as()->nestedValue(); case LinearAnimationBase::enableWorkAreaPropertyKey: - return object->as()->enableWorkArea(); case LinearAnimationBase::quantizePropertyKey: - return object->as()->quantize(); case StateMachineBoolBase::valuePropertyKey: - return object->as()->value(); case ShapePaintBase::isVisiblePropertyKey: - return object->as()->isVisible(); case StrokeBase::transformAffectsStrokePropertyKey: - return object->as()->transformAffectsStroke(); case PointsPathBase::isClosedPropertyKey: - return object->as()->isClosed(); case RectangleBase::linkCornerRadiusPropertyKey: - return object->as()->linkCornerRadius(); case ClippingShapeBase::isVisiblePropertyKey: - return object->as()->isVisible(); case CustomPropertyBooleanBase::propertyValuePropertyKey: - return object->as()->propertyValue(); case LayoutComponentBase::clipPropertyKey: - return object->as()->clip(); case TextModifierRangeBase::clampPropertyKey: - return object->as()->clamp(); - } - return false; - } - static int getColor(Core* object, int propertyKey) - { - switch (propertyKey) - { - case KeyFrameColorBase::valuePropertyKey: - return object->as()->value(); - case SolidColorBase::colorValuePropertyKey: - return object->as()->colorValue(); - case GradientStopBase::colorValuePropertyKey: - return object->as()->colorValue(); - } - return 0; - } - static int propertyFieldId(int propertyKey) - { - switch (propertyKey) - { - case ComponentBase::namePropertyKey: - case AnimationBase::namePropertyKey: - case StateMachineComponentBase::namePropertyKey: - case KeyFrameStringBase::valuePropertyKey: - case OpenUrlEventBase::urlPropertyKey: - case TextValueRunBase::textPropertyKey: - case CustomPropertyStringBase::propertyValuePropertyKey: - case AssetBase::namePropertyKey: - case FileAssetBase::cdnBaseUrlPropertyKey: - return CoreStringType::id; + return CoreBoolType::id; + case ViewModelInstanceListItemBase::viewModelIdPropertyKey: + case ViewModelInstanceListItemBase::viewModelInstanceIdPropertyKey: + case ViewModelInstanceListItemBase::artboardIdPropertyKey: + case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: + case ViewModelInstanceEnumBase::propertyValuePropertyKey: + case ViewModelBase::defaultInstanceIdPropertyKey: + case ViewModelPropertyViewModelBase::viewModelReferenceIdPropertyKey: case ComponentBase::parentIdPropertyKey: + case ViewModelInstanceBase::viewModelIdPropertyKey: + case ViewModelPropertyEnumBase::enumIdPropertyKey: + case ViewModelInstanceViewModelBase::propertyValuePropertyKey: case DrawTargetBase::drawableIdPropertyKey: case DrawTargetBase::placementValuePropertyKey: case TargetedConstraintBase::targetIdPropertyKey: @@ -2023,11 +2219,15 @@ class CoreRegistry case DrawRulesBase::drawTargetIdPropertyKey: case LayoutComponentBase::styleIdPropertyKey: case ArtboardBase::defaultStateMachineIdPropertyKey: + case ArtboardBase::viewModelIdPropertyKey: case JoystickBase::xIdPropertyKey: case JoystickBase::yIdPropertyKey: case JoystickBase::joystickFlagsPropertyKey: case JoystickBase::handleSourceIdPropertyKey: case OpenUrlEventBase::targetValuePropertyKey: + case DataBindBase::targetIdPropertyKey: + case DataBindBase::propertyKeyPropertyKey: + case DataBindBase::modeValuePropertyKey: case WeightBase::valuesPropertyKey: case WeightBase::indicesPropertyKey: case TendonBase::boneIdPropertyKey: @@ -2053,6 +2253,26 @@ class CoreRegistry case FileAssetBase::assetIdPropertyKey: case AudioEventBase::assetIdPropertyKey: return CoreUintType::id; + case ViewModelInstanceColorBase::propertyValuePropertyKey: + case KeyFrameColorBase::valuePropertyKey: + case SolidColorBase::colorValuePropertyKey: + case GradientStopBase::colorValuePropertyKey: + return CoreColorType::id; + case ViewModelComponentBase::namePropertyKey: + case ViewModelInstanceStringBase::propertyValuePropertyKey: + case ComponentBase::namePropertyKey: + case DataEnumValueBase::keyPropertyKey: + case DataEnumValueBase::valuePropertyKey: + case AnimationBase::namePropertyKey: + case StateMachineComponentBase::namePropertyKey: + case KeyFrameStringBase::valuePropertyKey: + case OpenUrlEventBase::urlPropertyKey: + case TextValueRunBase::textPropertyKey: + case CustomPropertyStringBase::propertyValuePropertyKey: + case AssetBase::namePropertyKey: + case FileAssetBase::cdnBaseUrlPropertyKey: + return CoreStringType::id; + case ViewModelInstanceNumberBase::propertyValuePropertyKey: case CustomPropertyNumberBase::propertyValuePropertyKey: case ConstraintBase::strengthPropertyKey: case DistanceConstraintBase::distancePropertyKey: @@ -2213,79 +2433,105 @@ class CoreRegistry case DrawableAssetBase::widthPropertyKey: case ExportAudioBase::volumePropertyKey: return CoreDoubleType::id; + case NestedArtboardBase::dataBindPathIdsPropertyKey: + case MeshBase::triangleIndexBytesPropertyKey: + case DataBindContextBase::sourcePathIdsPropertyKey: + case FileAssetBase::cdnUuidPropertyKey: + case FileAssetContentsBase::bytesPropertyKey: + return CoreBytesType::id; + default: + return -1; + } + } + static bool isCallback(uint32_t propertyKey) + { + switch (propertyKey) + { + case NestedTriggerBase::firePropertyKey: + case EventBase::triggerPropertyKey: + return true; + default: + return false; + } + } + static bool objectSupportsProperty(Core* object, uint32_t propertyKey) + { + switch (propertyKey) + { + case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: + return object->is(); case TransformComponentConstraintBase::offsetPropertyKey: + return object->is(); case TransformComponentConstraintBase::doesCopyPropertyKey: + return object->is(); case TransformComponentConstraintBase::minPropertyKey: + return object->is(); case TransformComponentConstraintBase::maxPropertyKey: + return object->is(); case TransformComponentConstraintYBase::doesCopyYPropertyKey: + return object->is(); case TransformComponentConstraintYBase::minYPropertyKey: + return object->is(); case TransformComponentConstraintYBase::maxYPropertyKey: + return object->is(); case IKConstraintBase::invertDirectionPropertyKey: + return object->is(); case FollowPathConstraintBase::orientPropertyKey: + return object->is(); case FollowPathConstraintBase::offsetPropertyKey: + return object->is(); case NestedSimpleAnimationBase::isPlayingPropertyKey: + return object->is(); case KeyFrameBoolBase::valuePropertyKey: + return object->is(); case ListenerAlignTargetBase::preserveOffsetPropertyKey: + return object->is(); case NestedBoolBase::nestedValuePropertyKey: + return object->is(); case LinearAnimationBase::enableWorkAreaPropertyKey: + return object->is(); case LinearAnimationBase::quantizePropertyKey: + return object->is(); case StateMachineBoolBase::valuePropertyKey: + return object->is(); case ShapePaintBase::isVisiblePropertyKey: + return object->is(); case StrokeBase::transformAffectsStrokePropertyKey: + return object->is(); case PointsPathBase::isClosedPropertyKey: + return object->is(); case RectangleBase::linkCornerRadiusPropertyKey: + return object->is(); case ClippingShapeBase::isVisiblePropertyKey: + return object->is(); case CustomPropertyBooleanBase::propertyValuePropertyKey: + return object->is(); case LayoutComponentBase::clipPropertyKey: + return object->is(); case TextModifierRangeBase::clampPropertyKey: - return CoreBoolType::id; - case KeyFrameColorBase::valuePropertyKey: - case SolidColorBase::colorValuePropertyKey: - case GradientStopBase::colorValuePropertyKey: - return CoreColorType::id; - case MeshBase::triangleIndexBytesPropertyKey: - case FileAssetBase::cdnUuidPropertyKey: - case FileAssetContentsBase::bytesPropertyKey: - return CoreBytesType::id; - default: - return -1; - } - } - static bool isCallback(uint32_t propertyKey) - { - switch (propertyKey) - { - case NestedTriggerBase::firePropertyKey: - case EventBase::triggerPropertyKey: - return true; - default: - return false; - } - } - static bool objectSupportsProperty(Core* object, uint32_t propertyKey) - { - switch (propertyKey) - { - case ComponentBase::namePropertyKey: - return object->is(); - case AnimationBase::namePropertyKey: - return object->is(); - case StateMachineComponentBase::namePropertyKey: - return object->is(); - case KeyFrameStringBase::valuePropertyKey: - return object->is(); - case OpenUrlEventBase::urlPropertyKey: - return object->is(); - case TextValueRunBase::textPropertyKey: - return object->is(); - case CustomPropertyStringBase::propertyValuePropertyKey: - return object->is(); - case AssetBase::namePropertyKey: - return object->is(); - case FileAssetBase::cdnBaseUrlPropertyKey: - return object->is(); + return object->is(); + case ViewModelInstanceListItemBase::viewModelIdPropertyKey: + return object->is(); + case ViewModelInstanceListItemBase::viewModelInstanceIdPropertyKey: + return object->is(); + case ViewModelInstanceListItemBase::artboardIdPropertyKey: + return object->is(); + case ViewModelInstanceValueBase::viewModelPropertyIdPropertyKey: + return object->is(); + case ViewModelInstanceEnumBase::propertyValuePropertyKey: + return object->is(); + case ViewModelBase::defaultInstanceIdPropertyKey: + return object->is(); + case ViewModelPropertyViewModelBase::viewModelReferenceIdPropertyKey: + return object->is(); case ComponentBase::parentIdPropertyKey: return object->is(); + case ViewModelInstanceBase::viewModelIdPropertyKey: + return object->is(); + case ViewModelPropertyEnumBase::enumIdPropertyKey: + return object->is(); + case ViewModelInstanceViewModelBase::propertyValuePropertyKey: + return object->is(); case DrawTargetBase::drawableIdPropertyKey: return object->is(); case DrawTargetBase::placementValuePropertyKey: @@ -2424,6 +2670,8 @@ class CoreRegistry return object->is(); case ArtboardBase::defaultStateMachineIdPropertyKey: return object->is(); + case ArtboardBase::viewModelIdPropertyKey: + return object->is(); case JoystickBase::xIdPropertyKey: return object->is(); case JoystickBase::yIdPropertyKey: @@ -2434,6 +2682,12 @@ class CoreRegistry return object->is(); case OpenUrlEventBase::targetValuePropertyKey: return object->is(); + case DataBindBase::targetIdPropertyKey: + return object->is(); + case DataBindBase::propertyKeyPropertyKey: + return object->is(); + case DataBindBase::modeValuePropertyKey: + return object->is(); case WeightBase::valuesPropertyKey: return object->is(); case WeightBase::indicesPropertyKey: @@ -2482,6 +2736,42 @@ class CoreRegistry return object->is(); case AudioEventBase::assetIdPropertyKey: return object->is(); + case ViewModelInstanceColorBase::propertyValuePropertyKey: + return object->is(); + case KeyFrameColorBase::valuePropertyKey: + return object->is(); + case SolidColorBase::colorValuePropertyKey: + return object->is(); + case GradientStopBase::colorValuePropertyKey: + return object->is(); + case ViewModelComponentBase::namePropertyKey: + return object->is(); + case ViewModelInstanceStringBase::propertyValuePropertyKey: + return object->is(); + case ComponentBase::namePropertyKey: + return object->is(); + case DataEnumValueBase::keyPropertyKey: + return object->is(); + case DataEnumValueBase::valuePropertyKey: + return object->is(); + case AnimationBase::namePropertyKey: + return object->is(); + case StateMachineComponentBase::namePropertyKey: + return object->is(); + case KeyFrameStringBase::valuePropertyKey: + return object->is(); + case OpenUrlEventBase::urlPropertyKey: + return object->is(); + case TextValueRunBase::textPropertyKey: + return object->is(); + case CustomPropertyStringBase::propertyValuePropertyKey: + return object->is(); + case AssetBase::namePropertyKey: + return object->is(); + case FileAssetBase::cdnBaseUrlPropertyKey: + return object->is(); + case ViewModelInstanceNumberBase::propertyValuePropertyKey: + return object->is(); case CustomPropertyNumberBase::propertyValuePropertyKey: return object->is(); case ConstraintBase::strengthPropertyKey: @@ -2800,66 +3090,10 @@ class CoreRegistry return object->is(); case ExportAudioBase::volumePropertyKey: return object->is(); - case TransformComponentConstraintBase::offsetPropertyKey: - return object->is(); - case TransformComponentConstraintBase::doesCopyPropertyKey: - return object->is(); - case TransformComponentConstraintBase::minPropertyKey: - return object->is(); - case TransformComponentConstraintBase::maxPropertyKey: - return object->is(); - case TransformComponentConstraintYBase::doesCopyYPropertyKey: - return object->is(); - case TransformComponentConstraintYBase::minYPropertyKey: - return object->is(); - case TransformComponentConstraintYBase::maxYPropertyKey: - return object->is(); - case IKConstraintBase::invertDirectionPropertyKey: - return object->is(); - case FollowPathConstraintBase::orientPropertyKey: - return object->is(); - case FollowPathConstraintBase::offsetPropertyKey: - return object->is(); - case NestedSimpleAnimationBase::isPlayingPropertyKey: - return object->is(); - case KeyFrameBoolBase::valuePropertyKey: - return object->is(); - case ListenerAlignTargetBase::preserveOffsetPropertyKey: - return object->is(); - case NestedBoolBase::nestedValuePropertyKey: - return object->is(); - case LinearAnimationBase::enableWorkAreaPropertyKey: - return object->is(); - case LinearAnimationBase::quantizePropertyKey: - return object->is(); - case StateMachineBoolBase::valuePropertyKey: - return object->is(); - case ShapePaintBase::isVisiblePropertyKey: - return object->is(); - case StrokeBase::transformAffectsStrokePropertyKey: - return object->is(); - case PointsPathBase::isClosedPropertyKey: - return object->is(); - case RectangleBase::linkCornerRadiusPropertyKey: - return object->is(); - case ClippingShapeBase::isVisiblePropertyKey: - return object->is(); - case CustomPropertyBooleanBase::propertyValuePropertyKey: - return object->is(); - case LayoutComponentBase::clipPropertyKey: - return object->is(); - case TextModifierRangeBase::clampPropertyKey: - return object->is(); case NestedTriggerBase::firePropertyKey: return object->is(); case EventBase::triggerPropertyKey: return object->is(); - case KeyFrameColorBase::valuePropertyKey: - return object->is(); - case SolidColorBase::colorValuePropertyKey: - return object->is(); - case GradientStopBase::colorValuePropertyKey: - return object->is(); } return false; } diff --git a/include/rive/generated/data_bind/data_bind_base.hpp b/include/rive/generated/data_bind/data_bind_base.hpp new file mode 100644 index 00000000..ed0d48db --- /dev/null +++ b/include/rive/generated/data_bind/data_bind_base.hpp @@ -0,0 +1,107 @@ +#ifndef _RIVE_DATA_BIND_BASE_HPP_ +#define _RIVE_DATA_BIND_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class DataBindBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 446; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataBindBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t targetIdPropertyKey = 585; + static const uint16_t propertyKeyPropertyKey = 586; + static const uint16_t modeValuePropertyKey = 587; + +private: + uint32_t m_TargetId = -1; + uint32_t m_PropertyKey = Core::invalidPropertyKey; + uint32_t m_ModeValue = 0; + +public: + inline uint32_t targetId() const { return m_TargetId; } + void targetId(uint32_t value) + { + if (m_TargetId == value) + { + return; + } + m_TargetId = value; + targetIdChanged(); + } + + inline uint32_t propertyKey() const { return m_PropertyKey; } + void propertyKey(uint32_t value) + { + if (m_PropertyKey == value) + { + return; + } + m_PropertyKey = value; + propertyKeyChanged(); + } + + inline uint32_t modeValue() const { return m_ModeValue; } + void modeValue(uint32_t value) + { + if (m_ModeValue == value) + { + return; + } + m_ModeValue = value; + modeValueChanged(); + } + + Core* clone() const override; + void copy(const DataBindBase& object) + { + m_TargetId = object.m_TargetId; + m_PropertyKey = object.m_PropertyKey; + m_ModeValue = object.m_ModeValue; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case targetIdPropertyKey: + m_TargetId = CoreUintType::deserialize(reader); + return true; + case propertyKeyPropertyKey: + m_PropertyKey = CoreUintType::deserialize(reader); + return true; + case modeValuePropertyKey: + m_ModeValue = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void targetIdChanged() {} + virtual void propertyKeyChanged() {} + virtual void modeValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/data_bind_context_base.hpp b/include/rive/generated/data_bind/data_bind_context_base.hpp new file mode 100644 index 00000000..d1871d46 --- /dev/null +++ b/include/rive/generated/data_bind/data_bind_context_base.hpp @@ -0,0 +1,62 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_BASE_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_BASE_HPP_ +#include "rive/core/field_types/core_bytes_type.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/span.hpp" +namespace rive +{ +class DataBindContextBase : public DataBind +{ +protected: + typedef DataBind Super; + +public: + static const uint16_t typeKey = 447; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataBindContextBase::typeKey: + case DataBindBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t sourcePathIdsPropertyKey = 588; + +public: + virtual void decodeSourcePathIds(Span value) = 0; + virtual void copySourcePathIds(const DataBindContextBase& object) = 0; + + Core* clone() const override; + void copy(const DataBindContextBase& object) + { + copySourcePathIds(object); + DataBind::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case sourcePathIdsPropertyKey: + decodeSourcePathIds(CoreBytesType::deserialize(reader)); + return true; + } + return DataBind::deserialize(propertyKey, reader); + } + +protected: + virtual void sourcePathIdsChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/nested_artboard_base.hpp b/include/rive/generated/nested_artboard_base.hpp index 141aa60f..a115ba29 100644 --- a/include/rive/generated/nested_artboard_base.hpp +++ b/include/rive/generated/nested_artboard_base.hpp @@ -1,7 +1,9 @@ #ifndef _RIVE_NESTED_ARTBOARD_BASE_HPP_ #define _RIVE_NESTED_ARTBOARD_BASE_HPP_ +#include "rive/core/field_types/core_bytes_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" #include "rive/drawable.hpp" +#include "rive/span.hpp" namespace rive { class NestedArtboardBase : public Drawable @@ -36,6 +38,7 @@ class NestedArtboardBase : public Drawable static const uint16_t artboardIdPropertyKey = 197; static const uint16_t fitPropertyKey = 538; static const uint16_t alignmentPropertyKey = 539; + static const uint16_t dataBindPathIdsPropertyKey = 580; private: uint32_t m_ArtboardId = -1; @@ -76,12 +79,16 @@ class NestedArtboardBase : public Drawable alignmentChanged(); } + virtual void decodeDataBindPathIds(Span value) = 0; + virtual void copyDataBindPathIds(const NestedArtboardBase& object) = 0; + Core* clone() const override; void copy(const NestedArtboardBase& object) { m_ArtboardId = object.m_ArtboardId; m_Fit = object.m_Fit; m_Alignment = object.m_Alignment; + copyDataBindPathIds(object); Drawable::copy(object); } @@ -98,6 +105,9 @@ class NestedArtboardBase : public Drawable case alignmentPropertyKey: m_Alignment = CoreUintType::deserialize(reader); return true; + case dataBindPathIdsPropertyKey: + decodeDataBindPathIds(CoreBytesType::deserialize(reader)); + return true; } return Drawable::deserialize(propertyKey, reader); } @@ -106,6 +116,7 @@ class NestedArtboardBase : public Drawable virtual void artboardIdChanged() {} virtual void fitChanged() {} virtual void alignmentChanged() {} + virtual void dataBindPathIdsChanged() {} }; } // namespace rive diff --git a/include/rive/generated/viewmodel/data_enum_base.hpp b/include/rive/generated/viewmodel/data_enum_base.hpp new file mode 100644 index 00000000..dc5860dc --- /dev/null +++ b/include/rive/generated/viewmodel/data_enum_base.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_DATA_ENUM_BASE_HPP_ +#define _RIVE_DATA_ENUM_BASE_HPP_ +#include "rive/core.hpp" +namespace rive +{ +class DataEnumBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 438; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataEnumBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + void copy(const DataEnumBase& object) {} + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { return false; } + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/data_enum_value_base.hpp b/include/rive/generated/viewmodel/data_enum_value_base.hpp new file mode 100644 index 00000000..53c89f92 --- /dev/null +++ b/include/rive/generated/viewmodel/data_enum_value_base.hpp @@ -0,0 +1,88 @@ +#ifndef _RIVE_DATA_ENUM_VALUE_BASE_HPP_ +#define _RIVE_DATA_ENUM_VALUE_BASE_HPP_ +#include +#include "rive/core.hpp" +#include "rive/core/field_types/core_string_type.hpp" +namespace rive +{ +class DataEnumValueBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 445; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataEnumValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t keyPropertyKey = 578; + static const uint16_t valuePropertyKey = 579; + +private: + std::string m_Key = ""; + std::string m_Value = ""; + +public: + inline const std::string& key() const { return m_Key; } + void key(std::string value) + { + if (m_Key == value) + { + return; + } + m_Key = value; + keyChanged(); + } + + inline const std::string& value() const { return m_Value; } + void value(std::string value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const DataEnumValueBase& object) + { + m_Key = object.m_Key; + m_Value = object.m_Value; + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case keyPropertyKey: + m_Key = CoreStringType::deserialize(reader); + return true; + case valuePropertyKey: + m_Value = CoreStringType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void keyChanged() {} + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_base.hpp b/include/rive/generated/viewmodel/viewmodel_base.hpp new file mode 100644 index 00000000..e9f63b26 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_VIEW_MODEL_BASE_HPP_ +#define _RIVE_VIEW_MODEL_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/viewmodel/viewmodel_component.hpp" +namespace rive +{ +class ViewModelBase : public ViewModelComponent +{ +protected: + typedef ViewModelComponent Super; + +public: + static const uint16_t typeKey = 435; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t defaultInstanceIdPropertyKey = 564; + +private: + uint32_t m_DefaultInstanceId = -1; + +public: + inline uint32_t defaultInstanceId() const { return m_DefaultInstanceId; } + void defaultInstanceId(uint32_t value) + { + if (m_DefaultInstanceId == value) + { + return; + } + m_DefaultInstanceId = value; + defaultInstanceIdChanged(); + } + + Core* clone() const override; + void copy(const ViewModelBase& object) + { + m_DefaultInstanceId = object.m_DefaultInstanceId; + ViewModelComponent::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case defaultInstanceIdPropertyKey: + m_DefaultInstanceId = CoreUintType::deserialize(reader); + return true; + } + return ViewModelComponent::deserialize(propertyKey, reader); + } + +protected: + virtual void defaultInstanceIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_component_base.hpp b/include/rive/generated/viewmodel/viewmodel_component_base.hpp new file mode 100644 index 00000000..611ebb36 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_component_base.hpp @@ -0,0 +1,67 @@ +#ifndef _RIVE_VIEW_MODEL_COMPONENT_BASE_HPP_ +#define _RIVE_VIEW_MODEL_COMPONENT_BASE_HPP_ +#include +#include "rive/core.hpp" +#include "rive/core/field_types/core_string_type.hpp" +namespace rive +{ +class ViewModelComponentBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 429; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t namePropertyKey = 557; + +private: + std::string m_Name = ""; + +public: + inline const std::string& name() const { return m_Name; } + void name(std::string value) + { + if (m_Name == value) + { + return; + } + m_Name = value; + nameChanged(); + } + + Core* clone() const override; + void copy(const ViewModelComponentBase& object) { m_Name = object.m_Name; } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case namePropertyKey: + m_Name = CoreStringType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void nameChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_base.hpp new file mode 100644 index 00000000..21f95aa2 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ViewModelInstanceBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 437; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t viewModelIdPropertyKey = 566; + +private: + uint32_t m_ViewModelId = 0; + +public: + inline uint32_t viewModelId() const { return m_ViewModelId; } + void viewModelId(uint32_t value) + { + if (m_ViewModelId == value) + { + return; + } + m_ViewModelId = value; + viewModelIdChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceBase& object) + { + m_ViewModelId = object.m_ViewModelId; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case viewModelIdPropertyKey: + m_ViewModelId = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void viewModelIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp new file mode 100644 index 00000000..873f6020 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_color_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_COLOR_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_COLOR_BASE_HPP_ +#include "rive/core/field_types/core_color_type.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceColorBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 426; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceColorBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 555; + +private: + int m_PropertyValue = 0xFF1D1D1D; + +public: + inline int propertyValue() const { return m_PropertyValue; } + void propertyValue(int value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceColorBase& object) + { + m_PropertyValue = object.m_PropertyValue; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreColorType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp new file mode 100644 index 00000000..7d489b30 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_enum_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_ENUM_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_ENUM_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceEnumBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 432; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceEnumBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 560; + +private: + uint32_t m_PropertyValue = 0; + +public: + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceEnumBase& object) + { + m_PropertyValue = object.m_PropertyValue; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp new file mode 100644 index 00000000..7a30aeb5 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_list_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_LIST_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_LIST_BASE_HPP_ +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceListBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 441; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceListBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_list_item_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_list_item_base.hpp new file mode 100644 index 00000000..4fedbf6f --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_list_item_base.hpp @@ -0,0 +1,124 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_LIST_ITEM_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_LIST_ITEM_BASE_HPP_ +#include "rive/core.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ViewModelInstanceListItemBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 427; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceListItemBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t useLinkedArtboardPropertyKey = 547; + static const uint16_t viewModelIdPropertyKey = 549; + static const uint16_t viewModelInstanceIdPropertyKey = 550; + static const uint16_t artboardIdPropertyKey = 551; + +private: + bool m_UseLinkedArtboard = true; + uint32_t m_ViewModelId = -1; + uint32_t m_ViewModelInstanceId = -1; + uint32_t m_ArtboardId = -1; + +public: + inline bool useLinkedArtboard() const { return m_UseLinkedArtboard; } + void useLinkedArtboard(bool value) + { + if (m_UseLinkedArtboard == value) + { + return; + } + m_UseLinkedArtboard = value; + useLinkedArtboardChanged(); + } + + inline uint32_t viewModelId() const { return m_ViewModelId; } + void viewModelId(uint32_t value) + { + if (m_ViewModelId == value) + { + return; + } + m_ViewModelId = value; + viewModelIdChanged(); + } + + inline uint32_t viewModelInstanceId() const { return m_ViewModelInstanceId; } + void viewModelInstanceId(uint32_t value) + { + if (m_ViewModelInstanceId == value) + { + return; + } + m_ViewModelInstanceId = value; + viewModelInstanceIdChanged(); + } + + inline uint32_t artboardId() const { return m_ArtboardId; } + void artboardId(uint32_t value) + { + if (m_ArtboardId == value) + { + return; + } + m_ArtboardId = value; + artboardIdChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceListItemBase& object) + { + m_UseLinkedArtboard = object.m_UseLinkedArtboard; + m_ViewModelId = object.m_ViewModelId; + m_ViewModelInstanceId = object.m_ViewModelInstanceId; + m_ArtboardId = object.m_ArtboardId; + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case useLinkedArtboardPropertyKey: + m_UseLinkedArtboard = CoreBoolType::deserialize(reader); + return true; + case viewModelIdPropertyKey: + m_ViewModelId = CoreUintType::deserialize(reader); + return true; + case viewModelInstanceIdPropertyKey: + m_ViewModelInstanceId = CoreUintType::deserialize(reader); + return true; + case artboardIdPropertyKey: + m_ArtboardId = CoreUintType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void useLinkedArtboardChanged() {} + virtual void viewModelIdChanged() {} + virtual void viewModelInstanceIdChanged() {} + virtual void artboardIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp new file mode 100644 index 00000000..6df85d0f --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_number_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_NUMBER_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_NUMBER_BASE_HPP_ +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceNumberBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 442; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceNumberBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 575; + +private: + float m_PropertyValue = 0.0f; + +public: + inline float propertyValue() const { return m_PropertyValue; } + void propertyValue(float value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceNumberBase& object) + { + m_PropertyValue = object.m_PropertyValue; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreDoubleType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp new file mode 100644 index 00000000..538c833e --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_string_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_STRING_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_STRING_BASE_HPP_ +#include +#include "rive/core/field_types/core_string_type.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceStringBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 433; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceStringBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 561; + +private: + std::string m_PropertyValue = ""; + +public: + inline const std::string& propertyValue() const { return m_PropertyValue; } + void propertyValue(std::string value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceStringBase& object) + { + m_PropertyValue = object.m_PropertyValue; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreStringType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp new file mode 100644 index 00000000..3bb08bdc --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_value_base.hpp @@ -0,0 +1,68 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_VALUE_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_VALUE_BASE_HPP_ +#include "rive/core.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class ViewModelInstanceValueBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 428; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t viewModelPropertyIdPropertyKey = 554; + +private: + uint32_t m_ViewModelPropertyId = 0; + +public: + inline uint32_t viewModelPropertyId() const { return m_ViewModelPropertyId; } + void viewModelPropertyId(uint32_t value) + { + if (m_ViewModelPropertyId == value) + { + return; + } + m_ViewModelPropertyId = value; + viewModelPropertyIdChanged(); + } + + void copy(const ViewModelInstanceValueBase& object) + { + m_ViewModelPropertyId = object.m_ViewModelPropertyId; + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case viewModelPropertyIdPropertyKey: + m_ViewModelPropertyId = CoreUintType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void viewModelPropertyIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp new file mode 100644 index 00000000..395569a5 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_VIEW_MODEL_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_VIEW_MODEL_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceViewModelBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 444; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceViewModelBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 577; + +private: + uint32_t m_PropertyValue = 0; + +public: + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceViewModelBase& object) + { + m_PropertyValue = object.m_PropertyValue; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_base.hpp new file mode 100644 index 00000000..fd65087f --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_BASE_HPP_ +#include "rive/viewmodel/viewmodel_component.hpp" +namespace rive +{ +class ViewModelPropertyBase : public ViewModelComponent +{ +protected: + typedef ViewModelComponent Super; + +public: + static const uint16_t typeKey = 430; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_color_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_color_base.hpp new file mode 100644 index 00000000..a24b20f1 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_color_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_COLOR_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_COLOR_BASE_HPP_ +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyColorBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 440; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyColorBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_enum_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_enum_base.hpp new file mode 100644 index 00000000..63bd198b --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_enum_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_ENUM_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_ENUM_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyEnumBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 439; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyEnumBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t enumIdPropertyKey = 574; + +private: + uint32_t m_EnumId = -1; + +public: + inline uint32_t enumId() const { return m_EnumId; } + void enumId(uint32_t value) + { + if (m_EnumId == value) + { + return; + } + m_EnumId = value; + enumIdChanged(); + } + + Core* clone() const override; + void copy(const ViewModelPropertyEnumBase& object) + { + m_EnumId = object.m_EnumId; + ViewModelProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case enumIdPropertyKey: + m_EnumId = CoreUintType::deserialize(reader); + return true; + } + return ViewModelProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void enumIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_list_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_list_base.hpp new file mode 100644 index 00000000..0ced54b4 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_list_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_LIST_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_LIST_BASE_HPP_ +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyListBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 434; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyListBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_number_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_number_base.hpp new file mode 100644 index 00000000..6b4055a7 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_number_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_NUMBER_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_NUMBER_BASE_HPP_ +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyNumberBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 431; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyNumberBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_string_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_string_base.hpp new file mode 100644 index 00000000..49bd3aa9 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_string_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_STRING_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_STRING_BASE_HPP_ +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyStringBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 443; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyStringBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_viewmodel_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_viewmodel_base.hpp new file mode 100644 index 00000000..e79e25ae --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_viewmodel_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_VIEW_MODEL_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_VIEW_MODEL_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyViewModelBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 436; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyViewModelBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t viewModelReferenceIdPropertyKey = 565; + +private: + uint32_t m_ViewModelReferenceId = 0; + +public: + inline uint32_t viewModelReferenceId() const { return m_ViewModelReferenceId; } + void viewModelReferenceId(uint32_t value) + { + if (m_ViewModelReferenceId == value) + { + return; + } + m_ViewModelReferenceId = value; + viewModelReferenceIdChanged(); + } + + Core* clone() const override; + void copy(const ViewModelPropertyViewModelBase& object) + { + m_ViewModelReferenceId = object.m_ViewModelReferenceId; + ViewModelProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case viewModelReferenceIdPropertyKey: + m_ViewModelReferenceId = CoreUintType::deserialize(reader); + return true; + } + return ViewModelProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void viewModelReferenceIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/importers/enum_importer.hpp b/include/rive/importers/enum_importer.hpp new file mode 100644 index 00000000..a79b1b6f --- /dev/null +++ b/include/rive/importers/enum_importer.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_ENUM_IMPORTER_HPP_ +#define _RIVE_ENUM_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class Core; +class DataEnum; +class DataEnumValue; +class EnumImporter : public ImportStackObject +{ +private: + DataEnum* m_DataEnum; + +public: + EnumImporter(DataEnum* dataEnum); + void addValue(DataEnumValue* object); + StatusCode resolve() override; + const DataEnum* dataEnum() const { return m_DataEnum; } +}; +} // namespace rive +#endif diff --git a/include/rive/importers/viewmodel_importer.hpp b/include/rive/importers/viewmodel_importer.hpp new file mode 100644 index 00000000..8298c26c --- /dev/null +++ b/include/rive/importers/viewmodel_importer.hpp @@ -0,0 +1,24 @@ +#ifndef _RIVE_VIEWMODEL_IMPORTER_HPP_ +#define _RIVE_VIEWMODEL_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class ViewModel; +class ViewModelProperty; +class ViewModelInstance; + +class ViewModelImporter : public ImportStackObject +{ +private: + ViewModel* m_ViewModel; + +public: + ViewModelImporter(ViewModel* viewModel); + void addProperty(ViewModelProperty* property); + void addInstance(ViewModelInstance* value); + StatusCode resolve() override; +}; +} // namespace rive +#endif diff --git a/include/rive/importers/viewmodel_instance_importer.hpp b/include/rive/importers/viewmodel_instance_importer.hpp new file mode 100644 index 00000000..d70c8583 --- /dev/null +++ b/include/rive/importers/viewmodel_instance_importer.hpp @@ -0,0 +1,22 @@ +#ifndef _RIVE_VIEWMODEL_INSTANCE_IMPORTER_HPP_ +#define _RIVE_VIEWMODEL_INSTANCE_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class ViewModelInstance; +class ViewModelInstanceValue; + +class ViewModelInstanceImporter : public ImportStackObject +{ +private: + ViewModelInstance* m_ViewModelInstance; + +public: + ViewModelInstanceImporter(ViewModelInstance* viewModelInstance); + void addValue(ViewModelInstanceValue* value); + StatusCode resolve() override; +}; +} // namespace rive +#endif diff --git a/include/rive/importers/viewmodel_instance_list_importer.hpp b/include/rive/importers/viewmodel_instance_list_importer.hpp new file mode 100644 index 00000000..3833b2ec --- /dev/null +++ b/include/rive/importers/viewmodel_instance_list_importer.hpp @@ -0,0 +1,22 @@ +#ifndef _RIVE_VIEWMODEL_INSTANCE_LIST_IMPORTER_HPP_ +#define _RIVE_VIEWMODEL_INSTANCE_LIST_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class Core; +class ViewModelInstanceList; +class ViewModelInstanceListItem; +class ViewModelInstanceListImporter : public ImportStackObject +{ +private: + ViewModelInstanceList* m_ViewModelInstanceList; + +public: + ViewModelInstanceListImporter(ViewModelInstanceList* viewModelInstanceList); + void addItem(ViewModelInstanceListItem* listItem); + StatusCode resolve() override; +}; +} // namespace rive +#endif diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index 0c2ecd70..9f57ec43 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp @@ -48,6 +48,9 @@ class NestedArtboard : public NestedArtboardBase float m_layoutScaleX = NAN; float m_layoutScaleY = NAN; +protected: + std::vector m_DataBindPathIdsBuffer; + public: NestedArtboard(); ~NestedArtboard() override; @@ -91,6 +94,9 @@ class NestedArtboard : public NestedArtboardBase /// nested within. Returns true when the conversion succeeds, and false /// when one is not possible. bool worldToLocal(Vec2D world, Vec2D* local); + void decodeDataBindPathIds(Span value) override; + void copyDataBindPathIds(const NestedArtboardBase& object) override; + std::vector dataBindPathIds() { return m_DataBindPathIdsBuffer; }; }; } // namespace rive diff --git a/include/rive/viewmodel/data_enum.hpp b/include/rive/viewmodel/data_enum.hpp new file mode 100644 index 00000000..ed8addb6 --- /dev/null +++ b/include/rive/viewmodel/data_enum.hpp @@ -0,0 +1,25 @@ +#ifndef _RIVE_DATA_ENUM_HPP_ +#define _RIVE_DATA_ENUM_HPP_ +#include "rive/generated/viewmodel/data_enum_base.hpp" +#include "rive/viewmodel/data_enum_value.hpp" +#include +namespace rive +{ +class DataEnum : public DataEnumBase +{ +private: + std::vector m_Values; + +public: + void addValue(DataEnumValue* value); + std::vector values() { return m_Values; }; + std::string value(std::string name); + std::string value(uint32_t index); + bool value(std::string name, std::string value); + bool value(uint32_t index, std::string value); + int valueIndex(std::string name); + int valueIndex(uint32_t index); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/data_enum_value.hpp b/include/rive/viewmodel/data_enum_value.hpp new file mode 100644 index 00000000..de642162 --- /dev/null +++ b/include/rive/viewmodel/data_enum_value.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_DATA_ENUM_VALUE_HPP_ +#define _RIVE_DATA_ENUM_VALUE_HPP_ +#include "rive/generated/viewmodel/data_enum_value_base.hpp" +#include +namespace rive +{ +class DataEnumValue : public DataEnumValueBase +{ +public: + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel.hpp b/include/rive/viewmodel/viewmodel.hpp new file mode 100644 index 00000000..2dbc6002 --- /dev/null +++ b/include/rive/viewmodel/viewmodel.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_VIEW_MODEL_HPP_ +#define _RIVE_VIEW_MODEL_HPP_ +#include "rive/generated/viewmodel/viewmodel_base.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include +namespace rive +{ +class ViewModel : public ViewModelBase +{ +private: + std::vector m_Properties; + std::vector m_Instances; + +public: + void addProperty(ViewModelProperty* property); + ViewModelProperty* property(const std::string& name); + ViewModelProperty* property(size_t index); + void addInstance(ViewModelInstance* value); + ViewModelInstance* instance(size_t index); + ViewModelInstance* instance(const std::string& name); + ViewModelInstance* defaultInstance(); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_component.hpp b/include/rive/viewmodel/viewmodel_component.hpp new file mode 100644 index 00000000..28354b40 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_component.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_COMPONENT_HPP_ +#define _RIVE_VIEW_MODEL_COMPONENT_HPP_ +#include "rive/generated/viewmodel/viewmodel_component_base.hpp" +#include +namespace rive +{ +class ViewModelComponent : public ViewModelComponentBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance.hpp b/include/rive/viewmodel/viewmodel_instance.hpp new file mode 100644 index 00000000..3115dc41 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance.hpp @@ -0,0 +1,32 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_base.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/component.hpp" +#include +namespace rive +{ +class ViewModel; +class ViewModelInstance : public ViewModelInstanceBase +{ +private: + std::vector m_PropertyValues; + ViewModel* m_ViewModel; + +public: + void addValue(ViewModelInstanceValue* value); + ViewModelInstanceValue* propertyValue(const uint32_t id); + ViewModelInstanceValue* propertyValue(const std::string& name); + std::vector propertyValues(); + void viewModel(ViewModel* value); + ViewModel* viewModel(); + void onComponentDirty(Component* component); + void setAsRoot(); + void setRoot(ViewModelInstance* value); + Core* clone() const override; + StatusCode import(ImportStack& importStack) override; + StatusCode onAddedDirty(CoreContext* context) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_color.hpp b/include/rive/viewmodel/viewmodel_instance_color.hpp new file mode 100644 index 00000000..833ddbb4 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_color.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_COLOR_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_COLOR_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_color_base.hpp" +#include +namespace rive +{ +class ViewModelInstanceColor : public ViewModelInstanceColorBase +{ +public: + void propertyValueChanged() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_enum.hpp b/include/rive/viewmodel/viewmodel_instance_enum.hpp new file mode 100644 index 00000000..6980ae45 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_enum.hpp @@ -0,0 +1,18 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_ENUM_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_ENUM_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_enum_base.hpp" +#include +namespace rive +{ +class ViewModelInstanceEnum : public ViewModelInstanceEnumBase +{ +public: + bool value(std::string name); + bool value(uint32_t index); + +protected: + void propertyValueChanged() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_list.hpp b/include/rive/viewmodel/viewmodel_instance_list.hpp new file mode 100644 index 00000000..8f1b9348 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_list.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_LIST_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_LIST_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_list_base.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include +namespace rive +{ +class ViewModelInstanceList : public ViewModelInstanceListBase +{ +public: + void addItem(ViewModelInstanceListItem* listItem); + void insertItem(int index, ViewModelInstanceListItem* listItem); + void removeItem(int index); + void removeItem(ViewModelInstanceListItem* listItem); + std::vector listItems() { return m_ListItems; }; + ViewModelInstanceListItem* item(uint32_t index); + void swap(uint32_t index1, uint32_t index2); + Core* clone() const override; + +protected: + std::vector m_ListItems; + void propertyValueChanged(); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_list_item.hpp b/include/rive/viewmodel/viewmodel_instance_list_item.hpp new file mode 100644 index 00000000..d09ab721 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_list_item.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_LIST_ITEM_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_LIST_ITEM_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_list_item_base.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include +namespace rive +{ +class ViewModelInstanceListItem : public ViewModelInstanceListItemBase +{ +private: + ViewModelInstance* m_viewModelInstance; + Artboard* m_artboard; + +public: + void viewModelInstance(ViewModelInstance* value) { m_viewModelInstance = value; }; + ViewModelInstance* viewModelInstance() { return m_viewModelInstance; } + void artboard(Artboard* value) { m_artboard = value; }; + Artboard* artboard() { return m_artboard; } + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_number.hpp b/include/rive/viewmodel/viewmodel_instance_number.hpp new file mode 100644 index 00000000..a5f40e93 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_number.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_NUMBER_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_NUMBER_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_number_base.hpp" +#include +namespace rive +{ +class ViewModelInstanceNumber : public ViewModelInstanceNumberBase +{ +protected: + void propertyValueChanged() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_string.hpp b/include/rive/viewmodel/viewmodel_instance_string.hpp new file mode 100644 index 00000000..a7234e84 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_string.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_STRING_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_STRING_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_string_base.hpp" +#include +namespace rive +{ +class ViewModelInstanceString : public ViewModelInstanceStringBase +{ +public: + void propertyValueChanged() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_value.hpp b/include/rive/viewmodel/viewmodel_instance_value.hpp new file mode 100644 index 00000000..7e3d5c7e --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_value.hpp @@ -0,0 +1,31 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_VALUE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_VALUE_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_value_base.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/dependency_helper.hpp" +#include "rive/component.hpp" +#include "rive/component_dirt.hpp" +#include +namespace rive +{ +class DataBindContext; +class ViewModelInstance; +class ViewModelInstanceValue : public ViewModelInstanceValueBase +{ +private: + ViewModelProperty* m_ViewModelProperty; + +protected: + DependencyHelper m_DependencyHelper; + void addDirt(ComponentDirt value); + +public: + StatusCode import(ImportStack& importStack) override; + void viewModelProperty(ViewModelProperty* value); + ViewModelProperty* viewModelProperty(); + void addDependent(DataBindContext* value); + virtual void setRoot(ViewModelInstance* value); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_viewmodel.hpp b/include/rive/viewmodel/viewmodel_instance_viewmodel.hpp new file mode 100644 index 00000000..d2ea9ab4 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_viewmodel.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_VIEW_MODEL_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_VIEW_MODEL_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include +namespace rive +{ +class ViewModelInstanceViewModel : public ViewModelInstanceViewModelBase +{ +private: + ViewModelInstance* m_referenceViewModelInstance; + +public: + void referenceViewModelInstance(ViewModelInstance* value) + { + m_referenceViewModelInstance = value; + }; + ViewModelInstance* referenceViewModelInstance() { return m_referenceViewModelInstance; } + void setRoot(ViewModelInstance* value) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property.hpp b/include/rive/viewmodel/viewmodel_property.hpp new file mode 100644 index 00000000..87b3a25f --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_base.hpp" +#include +namespace rive +{ +class ViewModelProperty : public ViewModelPropertyBase +{ +public: + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property_color.hpp b/include/rive/viewmodel/viewmodel_property_color.hpp new file mode 100644 index 00000000..ffc1191a --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property_color.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_COLOR_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_COLOR_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_color_base.hpp" +#include +namespace rive +{ +class ViewModelPropertyColor : public ViewModelPropertyColorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property_enum.hpp b/include/rive/viewmodel/viewmodel_property_enum.hpp new file mode 100644 index 00000000..41582e43 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property_enum.hpp @@ -0,0 +1,27 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_ENUM_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_ENUM_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_enum_base.hpp" +#include "rive/viewmodel/data_enum.hpp" +#include +namespace rive +{ +class ViewModelPropertyEnum : public ViewModelPropertyEnumBase +{ + +public: + std::string value(std::string name); + std::string value(uint32_t index); + bool value(std::string name, std::string value); + bool value(uint32_t index, std::string value); + int valueIndex(std::string name); + int valueIndex(uint32_t index); + void dataEnum(DataEnum* value); + DataEnum* dataEnum(); + +private: + DataEnum* m_DataEnum; +}; + +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property_list.hpp b/include/rive/viewmodel/viewmodel_property_list.hpp new file mode 100644 index 00000000..a4fa054d --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property_list.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_LIST_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_LIST_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_list_base.hpp" +#include +namespace rive +{ +class ViewModelPropertyList : public ViewModelPropertyListBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property_number.hpp b/include/rive/viewmodel/viewmodel_property_number.hpp new file mode 100644 index 00000000..0ba24683 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property_number.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_NUMBER_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_NUMBER_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_number_base.hpp" +#include +namespace rive +{ +class ViewModelPropertyNumber : public ViewModelPropertyNumberBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property_string.hpp b/include/rive/viewmodel/viewmodel_property_string.hpp new file mode 100644 index 00000000..0ff37458 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property_string.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_STRING_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_STRING_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_string_base.hpp" +#include +namespace rive +{ +class ViewModelPropertyString : public ViewModelPropertyStringBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property_viewmodel.hpp b/include/rive/viewmodel/viewmodel_property_viewmodel.hpp new file mode 100644 index 00000000..32ae2133 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property_viewmodel.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_VIEW_MODEL_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_VIEW_MODEL_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_viewmodel_base.hpp" +#include +namespace rive +{ +class ViewModelPropertyViewModel : public ViewModelPropertyViewModelBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/src/artboard.cpp b/src/artboard.cpp index 6b8e83db..6c0fe6a5 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -2,6 +2,9 @@ #include "rive/backboard.hpp" #include "rive/animation/linear_animation_instance.hpp" #include "rive/dependency_sorter.hpp" +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_bind_mode.hpp" #include "rive/draw_rules.hpp" #include "rive/draw_target.hpp" #include "rive/audio_event.hpp" @@ -168,6 +171,9 @@ StatusCode Artboard::initialize() case NestedArtboardBase::typeKey: m_NestedArtboards.push_back(object->as()); break; + case DataBindContext::typeKey: + m_DataBinds.push_back(object->as()); + break; case JoystickBase::typeKey: { @@ -468,6 +474,21 @@ void Artboard::update(ComponentDirt value) } } +void Artboard::updateDataBinds() +{ + for (auto dataBind : m_AllDataBinds) + { + dataBind->updateSourceBinding(); + auto d = dataBind->m_Dirt; + if (d == ComponentDirt::None) + { + continue; + } + dataBind->m_Dirt = ComponentDirt::None; + dataBind->update(d); + } +} + bool Artboard::updateComponents() { if (hasDirt(ComponentDirt::Components)) @@ -509,7 +530,7 @@ bool Artboard::updateComponents() return false; } -bool Artboard::advance(double elapsedSeconds) +bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot) { m_HasChangedDrawOrderInLastUpdate = false; #ifdef WITH_RIVE_LAYOUT @@ -539,7 +560,10 @@ bool Artboard::advance(double elapsedSeconds) joystick->apply(this); } } - + if (isRoot) + { + updateDataBinds(); + } bool didUpdate = updateComponents(); if (!m_JoysticksApplyBeforeUpdate) { @@ -547,6 +571,10 @@ bool Artboard::advance(double elapsedSeconds) { if (!joystick->canApplyBeforeUpdate()) { + if (isRoot) + { + updateDataBinds(); + } if (updateComponents()) { didUpdate = true; @@ -554,6 +582,10 @@ bool Artboard::advance(double elapsedSeconds) } joystick->apply(this); } + if (isRoot) + { + updateDataBinds(); + } if (updateComponents()) { didUpdate = true; @@ -569,6 +601,8 @@ bool Artboard::advance(double elapsedSeconds) return didUpdate; } +bool Artboard::advance(double elapsedSeconds) { return advanceInternal(elapsedSeconds, true); } + Core* Artboard::hitTest(HitInfo* hinfo, const Mat2D* xform) { if (clip()) @@ -900,6 +934,112 @@ StatusCode Artboard::import(ImportStack& importStack) return result; } +void Artboard::internalDataContext(DataContext* value, DataContext* parent, bool isRoot) +{ + m_DataContext = value; + m_DataContext->parent(parent); + for (auto nestedArtboard : m_NestedArtboards) + { + if (nestedArtboard->artboard() == nullptr) + { + continue; + } + auto value = m_DataContext->getViewModelInstance(nestedArtboard->dataBindPathIds()); + if (value != nullptr && value->is()) + { + nestedArtboard->artboard()->dataContextFromInstance(value, m_DataContext, false); + } + else + { + nestedArtboard->artboard()->internalDataContext(m_DataContext, + m_DataContext->parent(), + false); + } + } + for (auto dataBind : m_DataBinds) + { + if (dataBind->is()) + { + dataBind->as()->bindToContext(); + } + } + if (isRoot) + { + std::vector dataBinds; + populateDataBinds(&dataBinds); + buildDataBindDependencies(&dataBinds); + sortDataBinds(dataBinds); + } +} + +void Artboard::sortDataBinds(std::vector dataBinds) +{ + DependencySorter sorter; + // TODO: @hernan review this. Should not need to push to a component list to sort. + + std::vector dbOrder; + sorter.sort(dataBinds, dbOrder); + for (auto dataBind : dbOrder) + { + m_AllDataBinds.push_back(dataBind->as()); + } +} + +void Artboard::buildDataBindDependencies(std::vector* dataBinds) +{ + // TODO: @hernan review this dependency building + // Do we really need this? If a property is bound to a data bind, it can't be bound + // to a second data bind object. + for (auto component : *dataBinds) + { + auto dataBind = component->as(); + auto mode = static_cast(dataBind->modeValue()); + // If the data bind reads from the target, we want to add it as dependent from any other + // data bind that writes into that target. + if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + { + for (auto innerComponent : *dataBinds) + { + auto dataBindParent = innerComponent->as(); + auto parentMode = static_cast(dataBind->modeValue()); + if (dataBindParent != dataBind && (parentMode != DataBindMode::oneWayToSource) && + dataBindParent->target() == dataBind->target() && + dataBindParent->propertyKey() == dataBind->propertyKey()) + { + dataBindParent->addDependent(dataBind); + break; + } + } + } + else + { + // If the data bind reads from a source we want to add it as dependent + // from any other data bind that writes into that source. + if (dataBind->is()) + { + for (auto innerComponent : *dataBinds) + { + auto dataBindChild = innerComponent->as(); + if (dataBindChild != dataBind) + { + auto childMode = static_cast(dataBind->modeValue()); + if (childMode == DataBindMode::oneWayToSource || + childMode == DataBindMode::twoWay) + { + if (dataBindChild->is() && + dataBindChild->as()->source() == + dataBind->as()->source()) + { + dataBind->addDependent(dataBindChild); + break; + } + } + } + } + } + } + } +} float Artboard::volume() const { return m_volume; } void Artboard::volume(float value) { @@ -914,6 +1054,51 @@ void Artboard::volume(float value) } } +void Artboard::populateDataBinds(std::vector* dataBinds) +{ + for (auto dataBind : m_DataBinds) + { + dataBinds->push_back(dataBind); + } + for (auto nestedArtboard : m_NestedArtboards) + { + if (nestedArtboard->artboard() != nullptr) + { + nestedArtboard->artboard()->populateDataBinds(dataBinds); + } + } +} + +void Artboard::dataContext(DataContext* value, DataContext* parent) +{ + internalDataContext(value, parent, true); +} + +void Artboard::dataContextFromInstance(ViewModelInstance* viewModelInstance) +{ + dataContextFromInstance(viewModelInstance, nullptr, true); +} + +void Artboard::dataContextFromInstance(ViewModelInstance* viewModelInstance, DataContext* parent) +{ + dataContextFromInstance(viewModelInstance, parent, true); +} + +void Artboard::dataContextFromInstance(ViewModelInstance* viewModelInstance, + DataContext* parent, + bool isRoot) +{ + if (viewModelInstance == nullptr) + { + return; + } + if (isRoot) + { + viewModelInstance->setAsRoot(); + } + internalDataContext(new DataContext(viewModelInstance), parent, isRoot); +} + ////////// ArtboardInstance #include "rive/animation/linear_animation_instance.hpp" diff --git a/src/component.cpp b/src/component.cpp index eaf7003b..b7fa0387 100644 --- a/src/component.cpp +++ b/src/component.cpp @@ -11,6 +11,7 @@ using namespace rive; StatusCode Component::onAddedDirty(CoreContext* context) { m_Artboard = static_cast(context); + m_DependencyHelper.dependecyRoot(m_Artboard); if (this == m_Artboard) { // We're the artboard, don't parent to ourselves. @@ -26,15 +27,7 @@ StatusCode Component::onAddedDirty(CoreContext* context) return StatusCode::Ok; } -void Component::addDependent(Component* component) -{ - // Make it's not already a dependent. - if (std::find(m_Dependents.begin(), m_Dependents.end(), component) != m_Dependents.end()) - { - return; - } - m_Dependents.push_back(component); -} +void Component::addDependent(Component* component) { m_DependencyHelper.addDependent(component); } bool Component::addDirt(ComponentDirt value, bool recurse) { @@ -49,17 +42,14 @@ bool Component::addDirt(ComponentDirt value, bool recurse) onDirty(m_Dirt); - m_Artboard->onComponentDirty(this); + m_DependencyHelper.onComponentDirty(this); if (!recurse) { return true; } - for (auto d : m_Dependents) - { - d->addDirt(value, true); - } + m_DependencyHelper.addDirt(value); return true; } @@ -97,7 +87,7 @@ bool Component::collapse(bool value) m_Dirt &= ~ComponentDirt::Collapsed; } onDirty(m_Dirt); - m_Artboard->onComponentDirty(this); + m_DependencyHelper.onComponentDirty(this); return true; } diff --git a/src/data_bind/context/context_value_color.cpp b/src/data_bind/context/context_value_color.cpp new file mode 100644 index 00000000..18d392f2 --- /dev/null +++ b/src/data_bind/context/context_value_color.cpp @@ -0,0 +1,26 @@ +#include "rive/data_bind/context/context_value_color.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindContextValueColor::DataBindContextValueColor(ViewModelInstanceValue* value) +{ + m_Source = value; +} + +void DataBindContextValueColor::apply(Component* target, uint32_t propertyKey) +{ + CoreRegistry::setColor(target, + propertyKey, + m_Source->as()->propertyValue()); +} + +void DataBindContextValueColor::applyToSource(Component* target, uint32_t propertyKey) +{ + auto value = CoreRegistry::getColor(target, propertyKey); + if (m_Value != value) + { + m_Value = value; + m_Source->as()->propertyValue(value); + } +} \ No newline at end of file diff --git a/src/data_bind/context/context_value_enum.cpp b/src/data_bind/context/context_value_enum.cpp new file mode 100644 index 00000000..8569ce9b --- /dev/null +++ b/src/data_bind/context/context_value_enum.cpp @@ -0,0 +1,30 @@ +#include "rive/data_bind/context/context_value_enum.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindContextValueEnum::DataBindContextValueEnum(ViewModelInstanceValue* value) +{ + m_Source = value; +} + +void DataBindContextValueEnum::apply(Component* target, uint32_t propertyKey) +{ + auto enumSource = m_Source->as(); + auto enumProperty = enumSource->viewModelProperty()->as(); + auto enumValue = enumProperty->value(m_Source->as()->propertyValue()); + CoreRegistry::setString(target, propertyKey, enumValue); +} + +void DataBindContextValueEnum::applyToSource(Component* target, uint32_t propertyKey) +{ + auto value = CoreRegistry::getString(target, propertyKey); + auto enumSource = m_Source->as(); + auto enumProperty = enumSource->viewModelProperty()->as(); + auto valueIndex = enumProperty->valueIndex(value); + if (valueIndex != -1 && m_Value != valueIndex) + { + m_Value = valueIndex; + m_Source->as()->value(static_cast(valueIndex)); + } +} \ No newline at end of file diff --git a/src/data_bind/context/context_value_list.cpp b/src/data_bind/context/context_value_list.cpp new file mode 100644 index 00000000..59f0f55d --- /dev/null +++ b/src/data_bind/context/context_value_list.cpp @@ -0,0 +1,133 @@ +#include "rive/data_bind/context/context_value_list.hpp" +#include "rive/data_bind/context/context_value_list_item.hpp" +#include "rive/generated/core_registry.hpp" +#include "rive/node.hpp" + +using namespace rive; + +DataBindContextValueList::DataBindContextValueList(ViewModelInstanceValue* value) +{ + m_Source = value; +} + +std::unique_ptr DataBindContextValueList::createArtboard( + Component* target, + Artboard* artboard, + ViewModelInstanceListItem* listItem) const +{ + if (artboard != nullptr) + { + + auto mainArtboard = target->artboard(); + auto dataContext = mainArtboard->dataContext(); + auto artboardCopy = artboard->instance(); + artboardCopy->advanceInternal(0.0f, false); + artboardCopy->dataContextFromInstance(listItem->viewModelInstance(), dataContext, false); + return artboardCopy; + } + return nullptr; +} + +std::unique_ptr DataBindContextValueList::createStateMachineInstance( + ArtboardInstance* artboard) +{ + if (artboard != nullptr) + { + auto stateMachineInstance = artboard->stateMachineAt(0); + stateMachineInstance->advance(0.0f); + return stateMachineInstance; + } + return nullptr; +} + +void DataBindContextValueList::insertItem(Component* target, + ViewModelInstanceListItem* listItem, + int index) +{ + auto artboard = listItem->artboard(); + auto artboardCopy = createArtboard(target, artboard, listItem); + auto stateMachineInstance = createStateMachineInstance(artboardCopy.get()); + std::unique_ptr cacheListItem = + rivestd::make_unique(std::move(artboardCopy), + std::move(stateMachineInstance), + listItem); + if (index == -1) + { + m_ListItemsCache.push_back(std::move(cacheListItem)); + } + else + { + m_ListItemsCache.insert(m_ListItemsCache.begin() + index, std::move(cacheListItem)); + } +} + +void DataBindContextValueList::swapItems(Component* target, int index1, int index2) +{ + std::iter_swap(m_ListItemsCache.begin() + index1, m_ListItemsCache.begin() + index2); +} + +void DataBindContextValueList::popItem(Component* target) { m_ListItemsCache.pop_back(); } + +void DataBindContextValueList::update(Component* target) +{ + if (target != nullptr) + { + auto sourceList = m_Source->as(); + auto listItems = sourceList->listItems(); + + int listIndex = 0; + while (listIndex < listItems.size()) + { + auto listItem = listItems[listIndex]; + if (listIndex < m_ListItemsCache.size()) + { + if (m_ListItemsCache[listIndex]->listItem() == listItem) + { + // Same item in same position: do nothing + } + else + { + int cacheIndex = listIndex + 1; + bool found = false; + while (cacheIndex < m_ListItemsCache.size()) + { + if (m_ListItemsCache[cacheIndex]->listItem() == listItem) + { + // swap cache position with new item + swapItems(target, listIndex, cacheIndex); + found = true; + break; + } + cacheIndex++; + } + if (!found) + { + // create new element and insert it in listIndex + insertItem(target, listItem, listIndex); + } + } + } + else + { + // create new element and cache the listItem in listIndex + insertItem(target, listItem, -1); + } + + listIndex++; + } + // remove remaining cached elements backwars to pop from the vector. + listIndex = m_ListItemsCache.size() - 1; + while (listIndex >= listItems.size()) + { + popItem(target); + listIndex--; + } + } +} + +void DataBindContextValueList::apply(Component* target, uint32_t propertyKey) {} + +void DataBindContextValueList::applyToSource(Component* target, uint32_t propertyKey) +{ + // TODO: @hernan does applyToSource make sense? Should we block it somehow? +} \ No newline at end of file diff --git a/src/data_bind/context/context_value_list_item.cpp b/src/data_bind/context/context_value_list_item.cpp new file mode 100644 index 00000000..07f1a0f4 --- /dev/null +++ b/src/data_bind/context/context_value_list_item.cpp @@ -0,0 +1,11 @@ +#include "rive/data_bind/context/context_value_list_item.hpp" + +using namespace rive; + +DataBindContextValueListItem::DataBindContextValueListItem( + std::unique_ptr artboard, + std::unique_ptr stateMachine, + ViewModelInstanceListItem* listItem) : + m_Artboard(std::move(artboard)), + m_StateMachine(std::move(stateMachine)), + m_ListItem(listItem){}; \ No newline at end of file diff --git a/src/data_bind/context/context_value_number.cpp b/src/data_bind/context/context_value_number.cpp new file mode 100644 index 00000000..ecc5b7f9 --- /dev/null +++ b/src/data_bind/context/context_value_number.cpp @@ -0,0 +1,26 @@ +#include "rive/data_bind/context/context_value_number.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindContextValueNumber::DataBindContextValueNumber(ViewModelInstanceValue* value) +{ + m_Source = value; +} + +void DataBindContextValueNumber::apply(Component* target, uint32_t propertyKey) +{ + CoreRegistry::setDouble(target, + propertyKey, + m_Source->as()->propertyValue()); +} + +void DataBindContextValueNumber::applyToSource(Component* target, uint32_t propertyKey) +{ + auto value = CoreRegistry::getDouble(target, propertyKey); + if (m_Value != value) + { + m_Value = value; + m_Source->as()->propertyValue(value); + } +} \ No newline at end of file diff --git a/src/data_bind/context/context_value_string.cpp b/src/data_bind/context/context_value_string.cpp new file mode 100644 index 00000000..6a62e753 --- /dev/null +++ b/src/data_bind/context/context_value_string.cpp @@ -0,0 +1,26 @@ +#include "rive/data_bind/context/context_value_string.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindContextValueString::DataBindContextValueString(ViewModelInstanceValue* value) +{ + m_Source = value; +} + +void DataBindContextValueString::apply(Component* target, uint32_t propertyKey) +{ + CoreRegistry::setString(target, + propertyKey, + m_Source->as()->propertyValue()); +} + +void DataBindContextValueString::applyToSource(Component* target, uint32_t propertyKey) +{ + auto value = CoreRegistry::getString(target, propertyKey); + if (m_Value != value) + { + m_Value = value; + m_Source->as()->propertyValue(value); + } +} \ No newline at end of file diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp new file mode 100644 index 00000000..4f59d894 --- /dev/null +++ b/src/data_bind/data_bind.cpp @@ -0,0 +1,43 @@ +#include "rive/data_bind/data_bind.hpp" +#include "rive/data_bind/data_bind_mode.hpp" +#include "rive/artboard.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +// StatusCode DataBind::onAddedClean(CoreContext* context) +// { +// return Super::onAddedClean(context); +// } + +StatusCode DataBind::onAddedDirty(CoreContext* context) +{ + StatusCode code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + auto coreObject = context->resolve(targetId()); + if (coreObject == nullptr || !coreObject->is()) + { + return StatusCode::MissingObject; + } + + m_target = static_cast(coreObject); + + return StatusCode::Ok; +} + +StatusCode DataBind::import(ImportStack& importStack) { return Super::import(importStack); } + +void DataBind::buildDependencies() +{ + Super::buildDependencies(); + auto mode = static_cast(modeValue()); + if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + { + m_target->addDependent(this); + } +} + +void DataBind::updateSourceBinding() {} \ No newline at end of file diff --git a/src/data_bind/data_bind_context.cpp b/src/data_bind/data_bind_context.cpp new file mode 100644 index 00000000..77194d4e --- /dev/null +++ b/src/data_bind/data_bind_context.cpp @@ -0,0 +1,100 @@ +#include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_bind_mode.hpp" +#include "rive/data_bind/context/context_value_number.hpp" +#include "rive/data_bind/context/context_value_string.hpp" +#include "rive/data_bind/context/context_value_enum.hpp" +#include "rive/data_bind/context/context_value_list.hpp" +#include "rive/data_bind/context/context_value_color.hpp" +#include "rive/artboard.hpp" +#include "rive/generated/core_registry.hpp" +#include + +using namespace rive; + +void DataBindContext::decodeSourcePathIds(Span value) +{ + BinaryReader reader(value); + while (!reader.reachedEnd()) + { + auto val = reader.readVarUintAs(); + m_SourcePathIdsBuffer.push_back(val); + } +} + +void DataBindContext::copySourcePathIds(const DataBindContextBase& object) +{ + m_SourcePathIdsBuffer = object.as()->m_SourcePathIdsBuffer; +} + +void DataBindContext::bindToContext() +{ + auto dataContext = artboard()->dataContext(); + if (dataContext != nullptr) + { + auto value = dataContext->getViewModelProperty(m_SourcePathIdsBuffer); + if (value != nullptr) + { + value->addDependent(this); + m_Source = value; + if (m_Source->is()) + { + m_ContextValue = rivestd::make_unique(m_Source); + } + else if (m_Source->is()) + { + m_ContextValue = rivestd::make_unique(m_Source); + } + else if (m_Source->is()) + { + m_ContextValue = rivestd::make_unique(m_Source); + } + else if (m_Source->is()) + { + m_ContextValue = rivestd::make_unique(m_Source); + // TODO: @hernan decide the best place to initialize this + m_ContextValue->update(m_target); + } + else if (m_Source->is()) + { + m_ContextValue = rivestd::make_unique(m_Source); + } + } + } +} + +void DataBindContext::update(ComponentDirt value) +{ + if (m_Source != nullptr && m_ContextValue != nullptr) + { + + // Use the ComponentDirt::Components flag to indicate the viewmodel has added or removed + // an element to a list. + if ((value & ComponentDirt::Components) == ComponentDirt::Components) + { + m_ContextValue->update(m_target); + } + if ((value & ComponentDirt::Bindings) == ComponentDirt::Bindings) + { + // TODO: @hernan review how dirt and mode work together. If dirt is not set for + // certain modes, we might be able to skip the mode validation. + auto mode = static_cast(modeValue()); + if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay) + { + m_ContextValue->apply(m_target, propertyKey()); + } + } + } + Super::update(value); +} + +void DataBindContext::updateSourceBinding() +{ + auto mode = static_cast(modeValue()); + if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + { + if (m_ContextValue != nullptr) + { + m_ContextValue->applyToSource(m_target, propertyKey()); + } + } +} \ No newline at end of file diff --git a/src/data_bind/data_context.cpp b/src/data_bind/data_context.cpp new file mode 100644 index 00000000..a8b3f307 --- /dev/null +++ b/src/data_bind/data_context.cpp @@ -0,0 +1,90 @@ +#include "rive/data_bind/data_context.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" + +using namespace rive; + +DataContext::DataContext(ViewModelInstance* viewModelInstance) : + m_ViewModelInstance(viewModelInstance) +{} + +DataContext::DataContext() : m_ViewModelInstances({}) {} + +DataContext::~DataContext() {} + +void DataContext::addViewModelInstance(ViewModelInstance* value) +{ + m_ViewModelInstances.push_back(value); +} + +void DataContext::viewModelInstance(ViewModelInstance* value) { m_ViewModelInstance = value; } + +ViewModelInstanceValue* DataContext::getViewModelProperty(const std::vector path) const +{ + std::vector::const_iterator it; + if (path.size() == 0) + { + return nullptr; + } + // TODO: @hernan review. We should probably remove the std::vector and only keep the instance + for (auto viewModel : m_ViewModelInstances) + { + if (viewModel->viewModelId() == path[0]) + { + ViewModelInstance* instance = viewModel; + for (it = path.begin() + 1; it != path.end() - 1; it++) + { + instance = instance->propertyValue(*it) + ->as() + ->referenceViewModelInstance(); + } + ViewModelInstanceValue* value = instance->propertyValue(*it++); + return value; + } + } + if (m_ViewModelInstance != nullptr && m_ViewModelInstance->viewModelId() == path[0]) + { + ViewModelInstance* instance = m_ViewModelInstance; + for (it = path.begin() + 1; it != path.end() - 1; it++) + { + instance = instance->propertyValue(*it) + ->as() + ->referenceViewModelInstance(); + } + ViewModelInstanceValue* value = instance->propertyValue(*it++); + return value; + } + if (m_Parent != nullptr) + { + return m_Parent->getViewModelProperty(path); + } + return nullptr; +} + +ViewModelInstance* DataContext::getViewModelInstance(const std::vector path) const +{ + std::vector::const_iterator it; + if (path.size() == 0) + { + return nullptr; + } + if (m_ViewModelInstance != nullptr && m_ViewModelInstance->viewModelId() == path[0]) + { + ViewModelInstance* instance = m_ViewModelInstance; + for (it = path.begin() + 1; it != path.end(); it++) + { + instance = instance->propertyValue(*it) + ->as() + ->referenceViewModelInstance(); + if (instance == nullptr) + { + return instance; + } + } + return instance; + } + if (m_Parent != nullptr) + { + return m_Parent->getViewModelInstance(path); + } + return nullptr; +} \ No newline at end of file diff --git a/src/dependency_sorter.cpp b/src/dependency_sorter.cpp index 1bf9f44d..dcfa266e 100644 --- a/src/dependency_sorter.cpp +++ b/src/dependency_sorter.cpp @@ -9,6 +9,15 @@ void DependencySorter::sort(Component* root, std::vector& order) visit(root, order); } +void DependencySorter::sort(std::vector roots, std::vector& order) +{ + order.clear(); + for (auto root : roots) + { + visit(root, order); + } +} + bool DependencySorter::visit(Component* component, std::vector& order) { if (m_Perm.find(component) != m_Perm.end()) diff --git a/src/file.cpp b/src/file.cpp index 1fc3fbb4..93bdf042 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -8,6 +8,7 @@ #include "rive/generated/core_registry.hpp" #include "rive/importers/artboard_importer.hpp" #include "rive/importers/backboard_importer.hpp" +#include "rive/importers/enum_importer.hpp" #include "rive/importers/file_asset_importer.hpp" #include "rive/importers/import_stack.hpp" #include "rive/importers/keyed_object_importer.hpp" @@ -19,6 +20,9 @@ #include "rive/importers/layer_state_importer.hpp" #include "rive/importers/state_transition_importer.hpp" #include "rive/importers/state_machine_layer_component_importer.hpp" +#include "rive/importers/viewmodel_importer.hpp" +#include "rive/importers/viewmodel_instance_importer.hpp" +#include "rive/importers/viewmodel_instance_list_importer.hpp" #include "rive/animation/blend_state_transition.hpp" #include "rive/animation/any_state.hpp" #include "rive/animation/entry_state.hpp" @@ -29,6 +33,18 @@ #include "rive/assets/file_asset.hpp" #include "rive/assets/audio_asset.hpp" #include "rive/assets/file_asset_contents.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/data_enum.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_list.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" +#include "rive/viewmodel/viewmodel_instance_string.hpp" +#include "rive/viewmodel/viewmodel_property_viewmodel.hpp" +#include "rive/viewmodel/viewmodel_property_string.hpp" +#include "rive/viewmodel/viewmodel_property_number.hpp" +#include "rive/viewmodel/viewmodel_property_enum.hpp" +#include "rive/viewmodel/viewmodel_property_list.hpp" // Default namespace for Rive Cpp code using namespace rive; @@ -218,6 +234,24 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) m_fileAssets.push_back(fa); } break; + case ViewModel::typeKey: + { + auto vmc = object->as(); + m_ViewModels.push_back(vmc); + break; + } + case DataEnum::typeKey: + { + auto de = object->as(); + m_Enums.push_back(de); + break; + } + case ViewModelPropertyEnum::typeKey: + { + auto vme = object->as(); + vme->dataEnum(m_Enums[vme->enumId()]); + } + break; } } else @@ -237,6 +271,9 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) case Artboard::typeKey: stackObject = rivestd::make_unique(object->as()); break; + case DataEnum::typeKey: + stackObject = rivestd::make_unique(object->as()); + break; case LinearAnimation::typeKey: stackObject = rivestd::make_unique(object->as()); @@ -302,6 +339,20 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) m_factory); stackType = FileAsset::typeKey; break; + case ViewModel::typeKey: + stackObject = rivestd::make_unique(object->as()); + stackType = ViewModel::typeKey; + break; + case ViewModelInstance::typeKey: + stackObject = rivestd::make_unique( + object->as()); + stackType = ViewModelInstance::typeKey; + break; + case ViewModelInstanceList::typeKey: + stackObject = rivestd::make_unique( + object->as()); + stackType = ViewModelInstanceList::typeKey; + break; } if (importStack.makeLatest(stackType, std::move(stackObject)) != StatusCode::Ok) { @@ -375,6 +426,148 @@ std::unique_ptr File::artboardNamed(std::string name) const return ab ? ab->instance() : nullptr; } +void File::completeViewModelInstance(ViewModelInstance* viewModelInstance) +{ + auto viewModel = m_ViewModels[viewModelInstance->viewModelId()]; + auto propertyValues = viewModelInstance->propertyValues(); + for (auto value : propertyValues) + { + if (value->is()) + { + auto property = viewModel->property(value->viewModelPropertyId()); + if (property->is()) + { + auto valueViewModel = value->as(); + auto propertViewModel = property->as(); + auto viewModelReference = m_ViewModels[propertViewModel->viewModelReferenceId()]; + auto viewModelInstance = + viewModelReference->instance(valueViewModel->propertyValue()); + if (viewModelInstance != nullptr) + { + valueViewModel->referenceViewModelInstance( + copyViewModelInstance(viewModelInstance)); + } + } + } + else if (value->is()) + { + auto viewModelList = value->as(); + for (auto listItem : viewModelList->listItems()) + { + auto viewModel = m_ViewModels[listItem->viewModelId()]; + auto viewModelInstance = viewModel->instance(listItem->viewModelInstanceId()); + listItem->viewModelInstance(copyViewModelInstance(viewModelInstance)); + if (listItem->artboardId() < m_artboards.size()) + { + listItem->artboard(m_artboards[listItem->artboardId()]); + } + } + } + value->viewModelProperty(viewModel->property(value->viewModelPropertyId())); + } +} + +ViewModelInstance* File::copyViewModelInstance(ViewModelInstance* viewModelInstance) +{ + auto copy = viewModelInstance->clone()->as(); + completeViewModelInstance(copy); + return copy; +} + +ViewModelInstance* File::createViewModelInstance(std::string name) +{ + for (auto viewModel : m_ViewModels) + { + if (viewModel->is()) + { + if (viewModel->name() == name) + { + return createViewModelInstance(viewModel); + } + } + } + return nullptr; +} + +ViewModelInstance* File::createViewModelInstance(std::string name, std::string instanceName) +{ + for (auto viewModel : m_ViewModels) + { + if (viewModel->is()) + { + if (viewModel->name() == name) + { + auto instance = viewModel->instance(instanceName); + if (instance != nullptr) + { + return copyViewModelInstance(instance); + } + } + } + } + return nullptr; +} + +ViewModelInstance* File::createViewModelInstance(ViewModel* viewModel) +{ + if (viewModel != nullptr) + { + auto viewModelInstance = viewModel->defaultInstance(); + return copyViewModelInstance(viewModelInstance); + } + return nullptr; +} + +ViewModelInstance* File::createViewModelInstance(Artboard* artboard) +{ + if ((size_t)artboard->viewModelId() < m_ViewModels.size()) + { + auto viewModel = m_ViewModels[artboard->viewModelId()]; + if (viewModel != nullptr) + { + return createViewModelInstance(viewModel); + } + } + return nullptr; +} + +ViewModelInstanceListItem* File::viewModelInstanceListItem(ViewModelInstance* viewModelInstance) +{ + // Search for an implicit artboard linked to the viewModel. + // It will return the first one it finds, but there could be more. + // We should decide if we want to be more restrictive and only return + // an artboard if one and only one is found. + for (auto artboard : m_artboards) + { + if (artboard->viewModelId() == viewModelInstance->viewModelId()) + { + return viewModelInstanceListItem(viewModelInstance, artboard); + } + } + return nullptr; +} + +ViewModelInstanceListItem* File::viewModelInstanceListItem(ViewModelInstance* viewModelInstance, + Artboard* artboard) +{ + auto viewModelInstanceListItem = new ViewModelInstanceListItem(); + viewModelInstanceListItem->viewModelInstance(viewModelInstance); + viewModelInstanceListItem->artboard(artboard); + return viewModelInstanceListItem; +} + +ViewModel* File::viewModel(std::string name) +{ + for (auto viewModel : m_ViewModels) + { + if (viewModel->name() == name) + { + return viewModel; + } + } + return nullptr; +} + const std::vector& File::assets() const { return m_fileAssets; } #ifdef WITH_RIVE_TOOLS diff --git a/src/generated/data_bind/data_bind_base.cpp b/src/generated/data_bind/data_bind_base.cpp new file mode 100644 index 00000000..cc993f88 --- /dev/null +++ b/src/generated/data_bind/data_bind_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/data_bind_base.hpp" +#include "rive/data_bind/data_bind.hpp" + +using namespace rive; + +Core* DataBindBase::clone() const +{ + auto cloned = new DataBind(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/data_bind_context_base.cpp b/src/generated/data_bind/data_bind_context_base.cpp new file mode 100644 index 00000000..4691f4ca --- /dev/null +++ b/src/generated/data_bind/data_bind_context_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/data_bind_context_base.hpp" +#include "rive/data_bind/data_bind_context.hpp" + +using namespace rive; + +Core* DataBindContextBase::clone() const +{ + auto cloned = new DataBindContext(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/data_enum_base.cpp b/src/generated/viewmodel/data_enum_base.cpp new file mode 100644 index 00000000..9ac0ef0a --- /dev/null +++ b/src/generated/viewmodel/data_enum_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/data_enum_base.hpp" +#include "rive/viewmodel/data_enum.hpp" + +using namespace rive; + +Core* DataEnumBase::clone() const +{ + auto cloned = new DataEnum(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/data_enum_value_base.cpp b/src/generated/viewmodel/data_enum_value_base.cpp new file mode 100644 index 00000000..f695edc5 --- /dev/null +++ b/src/generated/viewmodel/data_enum_value_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/data_enum_value_base.hpp" +#include "rive/viewmodel/data_enum_value.hpp" + +using namespace rive; + +Core* DataEnumValueBase::clone() const +{ + auto cloned = new DataEnumValue(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_base.cpp b/src/generated/viewmodel/viewmodel_base.cpp new file mode 100644 index 00000000..87e7f7a1 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_base.hpp" +#include "rive/viewmodel/viewmodel.hpp" + +using namespace rive; + +Core* ViewModelBase::clone() const +{ + auto cloned = new ViewModel(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_component_base.cpp b/src/generated/viewmodel/viewmodel_component_base.cpp new file mode 100644 index 00000000..706138b9 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_component_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_component_base.hpp" +#include "rive/viewmodel/viewmodel_component.hpp" + +using namespace rive; + +Core* ViewModelComponentBase::clone() const +{ + auto cloned = new ViewModelComponent(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_base.cpp b/src/generated/viewmodel/viewmodel_instance_base.cpp new file mode 100644 index 00000000..892eba08 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_base.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" + +using namespace rive; + +Core* ViewModelInstanceBase::clone() const +{ + auto cloned = new ViewModelInstance(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_color_base.cpp b/src/generated/viewmodel/viewmodel_instance_color_base.cpp new file mode 100644 index 00000000..599a25d4 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_color_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_color_base.hpp" +#include "rive/viewmodel/viewmodel_instance_color.hpp" + +using namespace rive; + +Core* ViewModelInstanceColorBase::clone() const +{ + auto cloned = new ViewModelInstanceColor(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_enum_base.cpp b/src/generated/viewmodel/viewmodel_instance_enum_base.cpp new file mode 100644 index 00000000..3937d48b --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_enum_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_enum_base.hpp" +#include "rive/viewmodel/viewmodel_instance_enum.hpp" + +using namespace rive; + +Core* ViewModelInstanceEnumBase::clone() const +{ + auto cloned = new ViewModelInstanceEnum(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_list_base.cpp b/src/generated/viewmodel/viewmodel_instance_list_base.cpp new file mode 100644 index 00000000..b73c5a63 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_list_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_list_base.hpp" +#include "rive/viewmodel/viewmodel_instance_list.hpp" + +using namespace rive; + +Core* ViewModelInstanceListBase::clone() const +{ + auto cloned = new ViewModelInstanceList(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_list_item_base.cpp b/src/generated/viewmodel/viewmodel_instance_list_item_base.cpp new file mode 100644 index 00000000..b327aad5 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_list_item_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_list_item_base.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" + +using namespace rive; + +Core* ViewModelInstanceListItemBase::clone() const +{ + auto cloned = new ViewModelInstanceListItem(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_number_base.cpp b/src/generated/viewmodel/viewmodel_instance_number_base.cpp new file mode 100644 index 00000000..6ac41a54 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_number_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_number_base.hpp" +#include "rive/viewmodel/viewmodel_instance_number.hpp" + +using namespace rive; + +Core* ViewModelInstanceNumberBase::clone() const +{ + auto cloned = new ViewModelInstanceNumber(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_string_base.cpp b/src/generated/viewmodel/viewmodel_instance_string_base.cpp new file mode 100644 index 00000000..ce488391 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_string_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_string_base.hpp" +#include "rive/viewmodel/viewmodel_instance_string.hpp" + +using namespace rive; + +Core* ViewModelInstanceStringBase::clone() const +{ + auto cloned = new ViewModelInstanceString(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_instance_viewmodel_base.cpp b/src/generated/viewmodel/viewmodel_instance_viewmodel_base.cpp new file mode 100644 index 00000000..b0854a0c --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_viewmodel_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_viewmodel_base.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" + +using namespace rive; + +Core* ViewModelInstanceViewModelBase::clone() const +{ + auto cloned = new ViewModelInstanceViewModel(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_base.cpp b/src/generated/viewmodel/viewmodel_property_base.cpp new file mode 100644 index 00000000..333ffa88 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_base.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" + +using namespace rive; + +Core* ViewModelPropertyBase::clone() const +{ + auto cloned = new ViewModelProperty(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_color_base.cpp b/src/generated/viewmodel/viewmodel_property_color_base.cpp new file mode 100644 index 00000000..6f3bf826 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_color_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_color_base.hpp" +#include "rive/viewmodel/viewmodel_property_color.hpp" + +using namespace rive; + +Core* ViewModelPropertyColorBase::clone() const +{ + auto cloned = new ViewModelPropertyColor(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_enum_base.cpp b/src/generated/viewmodel/viewmodel_property_enum_base.cpp new file mode 100644 index 00000000..5f05b710 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_enum_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_enum_base.hpp" +#include "rive/viewmodel/viewmodel_property_enum.hpp" + +using namespace rive; + +Core* ViewModelPropertyEnumBase::clone() const +{ + auto cloned = new ViewModelPropertyEnum(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_list_base.cpp b/src/generated/viewmodel/viewmodel_property_list_base.cpp new file mode 100644 index 00000000..d6a7e79c --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_list_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_list_base.hpp" +#include "rive/viewmodel/viewmodel_property_list.hpp" + +using namespace rive; + +Core* ViewModelPropertyListBase::clone() const +{ + auto cloned = new ViewModelPropertyList(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_number_base.cpp b/src/generated/viewmodel/viewmodel_property_number_base.cpp new file mode 100644 index 00000000..bf388200 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_number_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_number_base.hpp" +#include "rive/viewmodel/viewmodel_property_number.hpp" + +using namespace rive; + +Core* ViewModelPropertyNumberBase::clone() const +{ + auto cloned = new ViewModelPropertyNumber(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_string_base.cpp b/src/generated/viewmodel/viewmodel_property_string_base.cpp new file mode 100644 index 00000000..5deac13c --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_string_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_string_base.hpp" +#include "rive/viewmodel/viewmodel_property_string.hpp" + +using namespace rive; + +Core* ViewModelPropertyStringBase::clone() const +{ + auto cloned = new ViewModelPropertyString(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_viewmodel_base.cpp b/src/generated/viewmodel/viewmodel_property_viewmodel_base.cpp new file mode 100644 index 00000000..5b57217d --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_viewmodel_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_viewmodel_base.hpp" +#include "rive/viewmodel/viewmodel_property_viewmodel.hpp" + +using namespace rive; + +Core* ViewModelPropertyViewModelBase::clone() const +{ + auto cloned = new ViewModelPropertyViewModel(); + cloned->copy(*this); + return cloned; +} diff --git a/src/importers/backboard_importer.cpp b/src/importers/backboard_importer.cpp index 19eb762c..286f133a 100644 --- a/src/importers/backboard_importer.cpp +++ b/src/importers/backboard_importer.cpp @@ -1,8 +1,12 @@ #include "rive/importers/backboard_importer.hpp" +#include "rive/artboard.hpp" #include "rive/nested_artboard.hpp" +#include "rive/backboard.hpp" #include "rive/assets/file_asset_referencer.hpp" #include "rive/assets/file_asset.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" #include using namespace rive; @@ -59,7 +63,6 @@ void BackboardImporter::addMissingArtboard() { m_NextArtboardId++; } StatusCode BackboardImporter::resolve() { - for (auto nestedArtboard : m_NestedArtboards) { auto itr = m_ArtboardLookup.find(nestedArtboard->artboardId()); @@ -84,4 +87,4 @@ StatusCode BackboardImporter::resolve() } return StatusCode::Ok; -} +} \ No newline at end of file diff --git a/src/importers/enum_importer.cpp b/src/importers/enum_importer.cpp new file mode 100644 index 00000000..65d616a5 --- /dev/null +++ b/src/importers/enum_importer.cpp @@ -0,0 +1,11 @@ +#include "rive/importers/enum_importer.hpp" +#include "rive/viewmodel/data_enum.hpp" +#include "rive/viewmodel/data_enum_value.hpp" + +using namespace rive; + +EnumImporter::EnumImporter(DataEnum* dataEnum) : m_DataEnum(dataEnum) {} + +void EnumImporter::addValue(DataEnumValue* value) { m_DataEnum->addValue(value); } + +StatusCode EnumImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/src/importers/viewmodel_importer.cpp b/src/importers/viewmodel_importer.cpp new file mode 100644 index 00000000..d868d052 --- /dev/null +++ b/src/importers/viewmodel_importer.cpp @@ -0,0 +1,15 @@ +#include "rive/importers/viewmodel_importer.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" + +using namespace rive; + +ViewModelImporter::ViewModelImporter(ViewModel* viewModel) : m_ViewModel(viewModel) {} +void ViewModelImporter::addProperty(ViewModelProperty* property) +{ + m_ViewModel->addProperty(property); +} +void ViewModelImporter::addInstance(ViewModelInstance* value) { m_ViewModel->addInstance(value); } + +StatusCode ViewModelImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/src/importers/viewmodel_instance_importer.cpp b/src/importers/viewmodel_instance_importer.cpp new file mode 100644 index 00000000..c4642fc0 --- /dev/null +++ b/src/importers/viewmodel_instance_importer.cpp @@ -0,0 +1,15 @@ +#include "rive/importers/viewmodel_instance_importer.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" + +using namespace rive; + +ViewModelInstanceImporter::ViewModelInstanceImporter(ViewModelInstance* viewModelInstance) : + m_ViewModelInstance(viewModelInstance) +{} +void ViewModelInstanceImporter::addValue(ViewModelInstanceValue* value) +{ + m_ViewModelInstance->addValue(value); +} + +StatusCode ViewModelInstanceImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/src/importers/viewmodel_instance_list_importer.cpp b/src/importers/viewmodel_instance_list_importer.cpp new file mode 100644 index 00000000..2edf0625 --- /dev/null +++ b/src/importers/viewmodel_instance_list_importer.cpp @@ -0,0 +1,16 @@ +#include "rive/importers/viewmodel_instance_list_importer.hpp" +#include "rive/viewmodel/viewmodel_instance_list.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" + +using namespace rive; + +ViewModelInstanceListImporter::ViewModelInstanceListImporter( + ViewModelInstanceList* viewModelInstanceList) : + m_ViewModelInstanceList(viewModelInstanceList) +{} +void ViewModelInstanceListImporter::addItem(ViewModelInstanceListItem* listItem) +{ + m_ViewModelInstanceList->addItem(listItem); +} + +StatusCode ViewModelInstanceListImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index e59b9e9d..6ef8cf36 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -45,7 +45,7 @@ void NestedArtboard::nest(Artboard* artboard) { m_Instance.reset(static_cast(artboard)); // take ownership } - m_Artboard->advance(0.0f); + m_Artboard->advanceInternal(0.0f, false); } static Mat2D makeTranslate(const Artboard* artboard) @@ -139,7 +139,7 @@ bool NestedArtboard::advance(float elapsedSeconds) { keepGoing = animation->advance(elapsedSeconds) || keepGoing; } - return m_Artboard->advance(elapsedSeconds) || keepGoing; + return m_Artboard->advanceInternal(elapsedSeconds, false) || keepGoing; } void NestedArtboard::update(ComponentDirt value) @@ -258,4 +258,19 @@ void NestedArtboard::controlSize(Vec2D size) scaleY(newScaleY); addDirt(ComponentDirt::WorldTransform, false); } +} + +void NestedArtboard::decodeDataBindPathIds(Span value) +{ + BinaryReader reader(value); + while (!reader.reachedEnd()) + { + auto val = reader.readVarUintAs(); + m_DataBindPathIdsBuffer.push_back(val); + } +} + +void NestedArtboard::copyDataBindPathIds(const NestedArtboardBase& object) +{ + m_DataBindPathIdsBuffer = object.as()->m_DataBindPathIdsBuffer; } \ No newline at end of file diff --git a/src/viewmodel/data_enum.cpp b/src/viewmodel/data_enum.cpp new file mode 100644 index 00000000..a1780cb1 --- /dev/null +++ b/src/viewmodel/data_enum.cpp @@ -0,0 +1,80 @@ +#include +#include +#include + +#include "rive/viewmodel/data_enum.hpp" +#include "rive/viewmodel/data_enum_value.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/backboard.hpp" +#include "rive/importers/backboard_importer.hpp" + +using namespace rive; + +void DataEnum::addValue(DataEnumValue* value) { m_Values.push_back(value); } + +std::string DataEnum::value(std::string key) +{ + for (auto enumValue : m_Values) + { + if (enumValue->key() == key) + { + return enumValue->value(); + }; + } + return ""; +} + +std::string DataEnum::value(uint32_t index) +{ + if (index < m_Values.size()) + { + return m_Values[index]->value(); + } + return ""; +} + +bool DataEnum::value(std::string key, std::string value) +{ + for (auto enumValue : m_Values) + { + if (enumValue->key() == key) + { + enumValue->value(value); + return true; + }; + } + return false; +} + +bool DataEnum::value(uint32_t index, std::string value) +{ + if (index < m_Values.size()) + { + m_Values[index]->value(value); + return true; + } + return false; +} + +int DataEnum::valueIndex(std::string key) +{ + int index = 0; + for (auto enumValue : m_Values) + { + if (enumValue->key() == key) + { + return index; + }; + index++; + } + return -1; +} + +int DataEnum::valueIndex(uint32_t index) +{ + if (index < m_Values.size()) + { + return index; + } + return -1; +} \ No newline at end of file diff --git a/src/viewmodel/data_enum_value.cpp b/src/viewmodel/data_enum_value.cpp new file mode 100644 index 00000000..e5a2e90e --- /dev/null +++ b/src/viewmodel/data_enum_value.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +#include "rive/viewmodel/data_enum.hpp" +#include "rive/viewmodel/data_enum_value.hpp" +#include "rive/importers/enum_importer.hpp" + +using namespace rive; + +StatusCode DataEnumValue::import(ImportStack& importStack) +{ + auto enumImporter = importStack.latest(DataEnum::typeKey); + if (enumImporter == nullptr) + { + return StatusCode::MissingObject; + } + + enumImporter->addValue(this); + return Super::import(importStack); +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel.cpp b/src/viewmodel/viewmodel.cpp new file mode 100644 index 00000000..7e764b94 --- /dev/null +++ b/src/viewmodel/viewmodel.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/backboard.hpp" +#include "rive/importers/backboard_importer.hpp" + +using namespace rive; + +void ViewModel::addProperty(ViewModelProperty* property) { m_Properties.push_back(property); } + +ViewModelProperty* ViewModel::property(size_t index) +{ + if (index < m_Properties.size()) + { + return m_Properties[index]; + } + return nullptr; +} + +ViewModelProperty* ViewModel::property(const std::string& name) +{ + for (auto property : m_Properties) + { + if (property->name() == name) + { + return property; + } + } + return nullptr; +} + +void ViewModel::addInstance(ViewModelInstance* value) { m_Instances.push_back(value); } + +ViewModelInstance* ViewModel::defaultInstance() { return m_Instances[defaultInstanceId()]; } + +ViewModelInstance* ViewModel::instance(size_t index) +{ + if (index < m_Instances.size()) + { + return m_Instances[index]; + } + return nullptr; +} + +ViewModelInstance* ViewModel::instance(const std::string& name) +{ + for (auto instance : m_Instances) + { + if (instance->name() == name) + { + return instance; + } + } + return nullptr; +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance.cpp b/src/viewmodel/viewmodel_instance.cpp new file mode 100644 index 00000000..bac68826 --- /dev/null +++ b/src/viewmodel/viewmodel_instance.cpp @@ -0,0 +1,105 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/importers/viewmodel_importer.hpp" +#include "rive/core_context.hpp" + +using namespace rive; + +void ViewModelInstance::addValue(ViewModelInstanceValue* value) +{ + m_PropertyValues.push_back(value); +} + +StatusCode ViewModelInstance::onAddedDirty(CoreContext* context) +{ + StatusCode result = Super::onAddedDirty(context); + if (result != StatusCode::Ok) + { + return result; + } + auto coreObject = context->resolve(viewModelId()); + if (coreObject != nullptr && coreObject->is()) + { + m_ViewModel = static_cast(coreObject); + } + + return StatusCode::Ok; +} + +ViewModelInstanceValue* ViewModelInstance::propertyValue(const uint32_t id) +{ + for (auto value : m_PropertyValues) + { + if (value->viewModelPropertyId() == id) + { + return value; + } + } + return nullptr; +} + +ViewModelInstanceValue* ViewModelInstance::propertyValue(const std::string& name) +{ + auto viewModelProperty = viewModel()->property(name); + if (viewModelProperty != nullptr) + { + for (auto value : m_PropertyValues) + { + if (value->viewModelProperty() == viewModelProperty) + { + return value; + } + } + } + return nullptr; +} + +void ViewModelInstance::viewModel(ViewModel* value) { m_ViewModel = value; } + +ViewModel* ViewModelInstance::viewModel() { return m_ViewModel; } + +void ViewModelInstance::onComponentDirty(Component* component) {} + +void ViewModelInstance::setAsRoot() { setRoot(this); } + +void ViewModelInstance::setRoot(ViewModelInstance* value) +{ + for (auto propertyValue : m_PropertyValues) + { + propertyValue->setRoot(value); + } +} + +std::vector ViewModelInstance::propertyValues() +{ + return m_PropertyValues; +} + +Core* ViewModelInstance::clone() const +{ + auto cloned = new ViewModelInstance(); + cloned->copy(*this); + for (auto propertyValue : m_PropertyValues) + { + auto clonedValue = propertyValue->clone()->as(); + cloned->addValue(clonedValue); + } + return cloned; +} + +StatusCode ViewModelInstance::import(ImportStack& importStack) +{ + auto viewModelImporter = importStack.latest(ViewModel::typeKey); + if (viewModelImporter == nullptr) + { + return StatusCode::MissingObject; + } + + viewModelImporter->addInstance(this); + return StatusCode::Ok; +} diff --git a/src/viewmodel/viewmodel_instance_color.cpp b/src/viewmodel/viewmodel_instance_color.cpp new file mode 100644 index 00000000..9cd82bd1 --- /dev/null +++ b/src/viewmodel/viewmodel_instance_color.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_color.hpp" +#include "rive/component_dirt.hpp" + +using namespace rive; + +void ViewModelInstanceColor::propertyValueChanged() { addDirt(ComponentDirt::Bindings); } \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance_enum.cpp b/src/viewmodel/viewmodel_instance_enum.cpp new file mode 100644 index 00000000..0cdbc603 --- /dev/null +++ b/src/viewmodel/viewmodel_instance_enum.cpp @@ -0,0 +1,34 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_enum.hpp" +#include "rive/viewmodel/viewmodel_property_enum.hpp" +#include "rive/component_dirt.hpp" + +using namespace rive; + +void ViewModelInstanceEnum::propertyValueChanged() { addDirt(ComponentDirt::Components); } + +bool ViewModelInstanceEnum::value(std::string name) +{ + auto enumProperty = viewModelProperty()->as(); + int index = enumProperty->valueIndex(name); + if (index != -1) + { + propertyValue(index); + return true; + } + return false; +} + +bool ViewModelInstanceEnum::value(uint32_t index) +{ + auto enumProperty = viewModelProperty()->as(); + if (enumProperty->valueIndex(index) != -1) + { + propertyValue(index); + return true; + } + return false; +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance_list.cpp b/src/viewmodel/viewmodel_instance_list.cpp new file mode 100644 index 00000000..0ac9f5a1 --- /dev/null +++ b/src/viewmodel/viewmodel_instance_list.cpp @@ -0,0 +1,74 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_list.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/component_dirt.hpp" + +using namespace rive; + +void ViewModelInstanceList::propertyValueChanged() { addDirt(ComponentDirt::Components); } + +void ViewModelInstanceList::addItem(ViewModelInstanceListItem* item) +{ + m_ListItems.push_back(item); + propertyValueChanged(); +} + +void ViewModelInstanceList::insertItem(int index, ViewModelInstanceListItem* item) +{ + // TODO: @hernan decide if we want to return a boolean + if (index < m_ListItems.size()) + { + m_ListItems.insert(m_ListItems.begin() + index, item); + propertyValueChanged(); + } +} + +void ViewModelInstanceList::removeItem(int index) +{ + // TODO: @hernan decide if we want to return a boolean + if (index < m_ListItems.size()) + { + m_ListItems.erase(m_ListItems.begin() + index); + propertyValueChanged(); + } +} + +void ViewModelInstanceList::removeItem(ViewModelInstanceListItem* listItem) +{ + auto noSpaceEnd = std::remove(m_ListItems.begin(), m_ListItems.end(), listItem); + m_ListItems.erase(noSpaceEnd, m_ListItems.end()); + propertyValueChanged(); +} + +ViewModelInstanceListItem* ViewModelInstanceList::item(uint32_t index) +{ + if (index < m_ListItems.size()) + { + return m_ListItems[index]; + } + return nullptr; +} + +void ViewModelInstanceList::swap(uint32_t index1, uint32_t index2) +{ + if (index1 < m_ListItems.size() && index2 < m_ListItems.size()) + { + std::iter_swap(m_ListItems.begin() + index1, m_ListItems.begin() + index2); + propertyValueChanged(); + } +} + +Core* ViewModelInstanceList::clone() const +{ + auto cloned = new ViewModelInstanceList(); + cloned->copy(*this); + for (auto property : m_ListItems) + { + auto clonedValue = property->clone()->as(); + cloned->addItem(clonedValue); + } + return cloned; +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance_list_item.cpp b/src/viewmodel/viewmodel_instance_list_item.cpp new file mode 100644 index 00000000..a723c6c7 --- /dev/null +++ b/src/viewmodel/viewmodel_instance_list_item.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_list.hpp" +#include "rive/viewmodel/viewmodel_instance_list_item.hpp" +#include "rive/importers/viewmodel_instance_list_importer.hpp" + +using namespace rive; + +StatusCode ViewModelInstanceListItem::import(ImportStack& importStack) +{ + auto viewModelInstanceList = + importStack.latest(ViewModelInstanceList::typeKey); + if (viewModelInstanceList == nullptr) + { + return StatusCode::MissingObject; + } + viewModelInstanceList->addItem(this); + + return Super::import(importStack); +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance_number.cpp b/src/viewmodel/viewmodel_instance_number.cpp new file mode 100644 index 00000000..6e2620a6 --- /dev/null +++ b/src/viewmodel/viewmodel_instance_number.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_number.hpp" +#include "rive/component_dirt.hpp" + +using namespace rive; + +void ViewModelInstanceNumber::propertyValueChanged() { addDirt(ComponentDirt::Bindings); } \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance_string.cpp b/src/viewmodel/viewmodel_instance_string.cpp new file mode 100644 index 00000000..6c60d4b8 --- /dev/null +++ b/src/viewmodel/viewmodel_instance_string.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_string.hpp" +#include "rive/component_dirt.hpp" + +using namespace rive; + +void ViewModelInstanceString::propertyValueChanged() { addDirt(ComponentDirt::Bindings); } \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance_value.cpp b/src/viewmodel/viewmodel_instance_value.cpp new file mode 100644 index 00000000..2e4fac2e --- /dev/null +++ b/src/viewmodel/viewmodel_instance_value.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/importers/viewmodel_instance_importer.hpp" +#include "rive/data_bind/data_bind_context.hpp" + +using namespace rive; + +StatusCode ViewModelInstanceValue::import(ImportStack& importStack) +{ + auto viewModelInstanceImporter = + importStack.latest(ViewModelInstance::typeKey); + if (viewModelInstanceImporter == nullptr) + { + return StatusCode::MissingObject; + } + viewModelInstanceImporter->addValue(this); + + return Super::import(importStack); +} + +void ViewModelInstanceValue::viewModelProperty(ViewModelProperty* value) +{ + m_ViewModelProperty = value; +} +ViewModelProperty* ViewModelInstanceValue::viewModelProperty() { return m_ViewModelProperty; } + +void ViewModelInstanceValue::addDependent(DataBindContext* value) +{ + m_DependencyHelper.addDependent(value); +} + +void ViewModelInstanceValue::addDirt(ComponentDirt value) { m_DependencyHelper.addDirt(value); } + +void ViewModelInstanceValue::setRoot(ViewModelInstance* viewModelInstance) +{ + m_DependencyHelper.dependecyRoot(viewModelInstance); +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance_viewmodel.cpp b/src/viewmodel/viewmodel_instance_viewmodel.cpp new file mode 100644 index 00000000..7630112e --- /dev/null +++ b/src/viewmodel/viewmodel_instance_viewmodel.cpp @@ -0,0 +1,13 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" + +using namespace rive; + +void ViewModelInstanceViewModel::setRoot(ViewModelInstance* value) +{ + Super::setRoot(value); + referenceViewModelInstance()->setRoot(value); +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel_property.cpp b/src/viewmodel/viewmodel_property.cpp new file mode 100644 index 00000000..4450bc16 --- /dev/null +++ b/src/viewmodel/viewmodel_property.cpp @@ -0,0 +1,17 @@ +#include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/importers/viewmodel_importer.hpp" +#include "rive/viewmodel/viewmodel.hpp" + +using namespace rive; + +StatusCode ViewModelProperty::import(ImportStack& importStack) +{ + auto viewModelImporter = importStack.latest(ViewModel::typeKey); + if (viewModelImporter == nullptr) + { + return StatusCode::MissingObject; + } + + viewModelImporter->addProperty(this); + return Super::import(importStack); +} diff --git a/src/viewmodel/viewmodel_property_enum.cpp b/src/viewmodel/viewmodel_property_enum.cpp new file mode 100644 index 00000000..ef5e12f8 --- /dev/null +++ b/src/viewmodel/viewmodel_property_enum.cpp @@ -0,0 +1,61 @@ +#include "rive/viewmodel/viewmodel_property_enum.hpp" + +using namespace rive; + +void ViewModelPropertyEnum::dataEnum(DataEnum* value) { m_DataEnum = value; } + +DataEnum* ViewModelPropertyEnum::dataEnum() { return m_DataEnum; } + +std::string ViewModelPropertyEnum::value(std::string name) +{ + if (dataEnum() != nullptr) + { + return dataEnum()->value(name); + } + return ""; +} + +std::string ViewModelPropertyEnum::value(uint32_t index) +{ + if (dataEnum() != nullptr) + { + return dataEnum()->value(index); + } + return ""; +} + +bool ViewModelPropertyEnum::value(std::string name, std::string value) +{ + if (dataEnum() != nullptr) + { + return dataEnum()->value(name, value); + } + return false; +} + +bool ViewModelPropertyEnum::value(uint32_t index, std::string value) +{ + if (dataEnum() != nullptr) + { + return dataEnum()->value(index, value); + } + return false; +} + +int ViewModelPropertyEnum::valueIndex(std::string name) +{ + if (dataEnum() != nullptr) + { + return dataEnum()->valueIndex(name); + } + return -1; +} + +int ViewModelPropertyEnum::valueIndex(uint32_t index) +{ + if (dataEnum() != nullptr) + { + return dataEnum()->valueIndex(index); + } + return -1; +} diff --git a/viewer/src/viewer_content/scene_content.cpp b/viewer/src/viewer_content/scene_content.cpp index e847adb1..ee43e2e1 100644 --- a/viewer/src/viewer_content/scene_content.cpp +++ b/viewer/src/viewer_content/scene_content.cpp @@ -13,6 +13,7 @@ #include "rive/layout.hpp" #include "rive/math/aabb.hpp" #include "rive/assets/image_asset.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" #include "viewer/viewer_content.hpp" #include "rive/relative_local_asset_loader.hpp" @@ -68,6 +69,7 @@ class SceneContent : public ViewerContent std::unique_ptr m_ArtboardInstance; std::unique_ptr m_CurrentScene; + rive::ViewModelInstance* m_ViewModelInstance; int m_ArtboardIndex = 0; int m_AnimationIndex = 0; int m_StateMachineIndex = -1; @@ -84,6 +86,9 @@ class SceneContent : public ViewerContent m_ArtboardIndex = (index == REQUEST_DEFAULT_SCENE) ? 0 : index; m_ArtboardInstance = m_File->artboardAt(m_ArtboardIndex); + // m_ViewModelInstance = m_File->viewModelInstanceNamed("vm-3"); + m_ViewModelInstance = m_File->createViewModelInstance(m_ArtboardInstance.get()); + m_ArtboardInstance->dataContextFromInstance(m_ViewModelInstance); m_ArtboardInstance->advance(0.0f); loadNames(m_ArtboardInstance.get()); From ba19285dd5723a4f336def854f1275eb4f50e1fe Mon Sep 17 00:00:00 2001 From: philter Date: Thu, 20 Jun 2024 18:07:27 +0000 Subject: [PATCH 067/138] Update LayoutComponentStyle bitfields to be compatible with older C++ versions Diffs= 97578005c Update LayoutComponentStyle bitfields to be compatible with older C++ versions (#7436) Co-authored-by: Philip Chung --- .rive_head | 2 +- .../rive/layout/layout_component_style.hpp | 70 +++++++++---------- src/layout/layout_component_style.cpp | 41 +++++++++++ 3 files changed, 77 insertions(+), 36 deletions(-) diff --git a/.rive_head b/.rive_head index 3fd5c8b5..aaeeaf30 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -75823467d0c007983e66df245f1e9c27d707728c +97578005cb9eb1561b13e80755d3cfe632c0752f diff --git a/include/rive/layout/layout_component_style.hpp b/include/rive/layout/layout_component_style.hpp index 277373ff..69335930 100644 --- a/include/rive/layout/layout_component_style.hpp +++ b/include/rive/layout/layout_component_style.hpp @@ -9,45 +9,45 @@ namespace rive { // ---- Flags 0 -static BitFieldLoc DisplayBits = BitFieldLoc(0, 0); -static BitFieldLoc PositionTypeBits = BitFieldLoc(1, 2); -static BitFieldLoc FlexDirectionBits = BitFieldLoc(3, 4); -static BitFieldLoc DirectionBits = BitFieldLoc(5, 6); -static BitFieldLoc AlignContentBits = BitFieldLoc(7, 9); -static BitFieldLoc AlignItemsBits = BitFieldLoc(10, 12); -static BitFieldLoc AlignSelfBits = BitFieldLoc(13, 15); -static BitFieldLoc JustifyContentBits = BitFieldLoc(16, 18); -static BitFieldLoc FlexWrapBits = BitFieldLoc(19, 20); -static BitFieldLoc OverflowBits = BitFieldLoc(21, 22); -static BitFieldLoc IntrinsicallySizedBits = BitFieldLoc(23, 23); -static BitFieldLoc WidthUnitsBits = BitFieldLoc(24, 25); -static BitFieldLoc HeightUnitsBits = BitFieldLoc(26, 27); +extern BitFieldLoc DisplayBits; +extern BitFieldLoc PositionTypeBits; +extern BitFieldLoc FlexDirectionBits; +extern BitFieldLoc DirectionBits; +extern BitFieldLoc AlignContentBits; +extern BitFieldLoc AlignItemsBits; +extern BitFieldLoc AlignSelfBits; +extern BitFieldLoc JustifyContentBits; +extern BitFieldLoc FlexWrapBits; +extern BitFieldLoc OverflowBits; +extern BitFieldLoc IntrinsicallySizedBits; +extern BitFieldLoc WidthUnitsBits; +extern BitFieldLoc HeightUnitsBits; // ---- Flags 1 -static BitFieldLoc BorderLeftUnitsBits = BitFieldLoc(0, 1); -static BitFieldLoc BorderRightUnitsBits = BitFieldLoc(2, 3); -static BitFieldLoc BorderTopUnitsBits = BitFieldLoc(4, 5); -static BitFieldLoc BorderBottomUnitsBits = BitFieldLoc(6, 7); -static BitFieldLoc MarginLeftUnitsBits = BitFieldLoc(8, 9); -static BitFieldLoc MarginRightUnitsBits = BitFieldLoc(10, 11); -static BitFieldLoc MarginTopUnitsBits = BitFieldLoc(12, 13); -static BitFieldLoc MarginBottomUnitsBits = BitFieldLoc(14, 15); -static BitFieldLoc PaddingLeftUnitsBits = BitFieldLoc(16, 17); -static BitFieldLoc PaddingRightUnitsBits = BitFieldLoc(18, 19); -static BitFieldLoc PaddingTopUnitsBits = BitFieldLoc(20, 21); -static BitFieldLoc PaddingBottomUnitsBits = BitFieldLoc(22, 23); -static BitFieldLoc PositionLeftUnitsBits = BitFieldLoc(24, 25); -static BitFieldLoc PositionRightUnitsBits = BitFieldLoc(26, 27); -static BitFieldLoc PositionTopUnitsBits = BitFieldLoc(28, 29); -static BitFieldLoc PositionBottomUnitsBits = BitFieldLoc(30, 31); +extern BitFieldLoc BorderLeftUnitsBits; +extern BitFieldLoc BorderRightUnitsBits; +extern BitFieldLoc BorderTopUnitsBits; +extern BitFieldLoc BorderBottomUnitsBits; +extern BitFieldLoc MarginLeftUnitsBits; +extern BitFieldLoc MarginRightUnitsBits; +extern BitFieldLoc MarginTopUnitsBits; +extern BitFieldLoc MarginBottomUnitsBits; +extern BitFieldLoc PaddingLeftUnitsBits; +extern BitFieldLoc PaddingRightUnitsBits; +extern BitFieldLoc PaddingTopUnitsBits; +extern BitFieldLoc PaddingBottomUnitsBits; +extern BitFieldLoc PositionLeftUnitsBits; +extern BitFieldLoc PositionRightUnitsBits; +extern BitFieldLoc PositionTopUnitsBits; +extern BitFieldLoc PositionBottomUnitsBits; // ---- Flags 2 -static BitFieldLoc GapHorizontalUnitsBits = BitFieldLoc(0, 1); -static BitFieldLoc GapVerticalUnitsBits = BitFieldLoc(2, 3); -static BitFieldLoc MinWidthUnitsBits = BitFieldLoc(4, 5); -static BitFieldLoc MinHeightUnitsBits = BitFieldLoc(6, 7); -static BitFieldLoc MaxWidthUnitsBits = BitFieldLoc(8, 9); -static BitFieldLoc MaxHeightUnitsBits = BitFieldLoc(10, 11); +extern BitFieldLoc GapHorizontalUnitsBits; +extern BitFieldLoc GapVerticalUnitsBits; +extern BitFieldLoc MinWidthUnitsBits; +extern BitFieldLoc MinHeightUnitsBits; +extern BitFieldLoc MaxWidthUnitsBits; +extern BitFieldLoc MaxHeightUnitsBits; class LayoutComponentStyle : public LayoutComponentStyleBase { diff --git a/src/layout/layout_component_style.cpp b/src/layout/layout_component_style.cpp index 882d7521..c1693f6d 100644 --- a/src/layout/layout_component_style.cpp +++ b/src/layout/layout_component_style.cpp @@ -4,6 +4,47 @@ using namespace rive; +// ---- Flags 0 +BitFieldLoc rive::DisplayBits = BitFieldLoc(0, 0); +BitFieldLoc rive::PositionTypeBits = BitFieldLoc(1, 2); +BitFieldLoc rive::FlexDirectionBits = BitFieldLoc(3, 4); +BitFieldLoc rive::DirectionBits = BitFieldLoc(5, 6); +BitFieldLoc rive::AlignContentBits = BitFieldLoc(7, 9); +BitFieldLoc rive::AlignItemsBits = BitFieldLoc(10, 12); +BitFieldLoc rive::AlignSelfBits = BitFieldLoc(13, 15); +BitFieldLoc rive::JustifyContentBits = BitFieldLoc(16, 18); +BitFieldLoc rive::FlexWrapBits = BitFieldLoc(19, 20); +BitFieldLoc rive::OverflowBits = BitFieldLoc(21, 22); +BitFieldLoc rive::IntrinsicallySizedBits = BitFieldLoc(23, 23); +BitFieldLoc rive::WidthUnitsBits = BitFieldLoc(24, 25); +BitFieldLoc rive::HeightUnitsBits = BitFieldLoc(26, 27); + +// ---- Flags 1 +BitFieldLoc rive::BorderLeftUnitsBits = BitFieldLoc(0, 1); +BitFieldLoc rive::BorderRightUnitsBits = BitFieldLoc(2, 3); +BitFieldLoc rive::BorderTopUnitsBits = BitFieldLoc(4, 5); +BitFieldLoc rive::BorderBottomUnitsBits = BitFieldLoc(6, 7); +BitFieldLoc rive::MarginLeftUnitsBits = BitFieldLoc(8, 9); +BitFieldLoc rive::MarginRightUnitsBits = BitFieldLoc(10, 11); +BitFieldLoc rive::MarginTopUnitsBits = BitFieldLoc(12, 13); +BitFieldLoc rive::MarginBottomUnitsBits = BitFieldLoc(14, 15); +BitFieldLoc rive::PaddingLeftUnitsBits = BitFieldLoc(16, 17); +BitFieldLoc rive::PaddingRightUnitsBits = BitFieldLoc(18, 19); +BitFieldLoc rive::PaddingTopUnitsBits = BitFieldLoc(20, 21); +BitFieldLoc rive::PaddingBottomUnitsBits = BitFieldLoc(22, 23); +BitFieldLoc rive::PositionLeftUnitsBits = BitFieldLoc(24, 25); +BitFieldLoc rive::PositionRightUnitsBits = BitFieldLoc(26, 27); +BitFieldLoc rive::PositionTopUnitsBits = BitFieldLoc(28, 29); +BitFieldLoc rive::PositionBottomUnitsBits = BitFieldLoc(30, 31); + +// ---- Flags 2 +BitFieldLoc rive::GapHorizontalUnitsBits = BitFieldLoc(0, 1); +BitFieldLoc rive::GapVerticalUnitsBits = BitFieldLoc(2, 3); +BitFieldLoc rive::MinWidthUnitsBits = BitFieldLoc(4, 5); +BitFieldLoc rive::MinHeightUnitsBits = BitFieldLoc(6, 7); +BitFieldLoc rive::MaxWidthUnitsBits = BitFieldLoc(8, 9); +BitFieldLoc rive::MaxHeightUnitsBits = BitFieldLoc(10, 11); + #ifdef WITH_RIVE_LAYOUT YGDisplay LayoutComponentStyle::display() { return YGDisplay(DisplayBits.read(layoutFlags0())); } From 40c94ab7ff11ac596b27e4d66d3595d0aeec331a Mon Sep 17 00:00:00 2001 From: philter Date: Thu, 20 Jun 2024 19:03:33 +0000 Subject: [PATCH 068/138] Renames for Yoga and libjpeg Addresses the Unity issues raised by Adam here: https://2dimensions.slack.com/archives/CLLCU09T6/p1718727712078119 libjpeg has a flag `NEED_SHORT_EXTERNAL_NAMES`, which renames functions to shorter names, however, I didn't use this approach because its possible we could get naming collisions if someone brings another 3rd party lib which also has this flag enabled. Diffs= a4439ee42 Renames for Yoga and libjpeg (#7446) Co-authored-by: Philip Chung --- .rive_head | 2 +- decoders/premake5_v2.lua | 8 + .../gen_libjpeg_renames/gen_header.dart | 74 ++++++ .../gen_libjpeg_renames/gen_renames.sh | 58 +++++ dependencies/gen_yoga_renames/gen_header.dart | 46 ++++ dependencies/gen_yoga_renames/gen_renames.sh | 56 ++++ dependencies/premake5_libjpeg_v2.lua | 11 + dependencies/premake5_yoga_v2.lua | 11 + dependencies/rive_libjpeg_renames.h | 204 +++++++++++++++ dependencies/rive_yoga_renames.h | 241 ++++++++++++++++++ dev/test/premake5.lua | 8 + premake5_v2.lua | 8 + 12 files changed, 726 insertions(+), 1 deletion(-) create mode 100644 dependencies/gen_libjpeg_renames/gen_header.dart create mode 100755 dependencies/gen_libjpeg_renames/gen_renames.sh create mode 100644 dependencies/gen_yoga_renames/gen_header.dart create mode 100755 dependencies/gen_yoga_renames/gen_renames.sh create mode 100644 dependencies/rive_libjpeg_renames.h create mode 100644 dependencies/rive_yoga_renames.h diff --git a/.rive_head b/.rive_head index aaeeaf30..20270357 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -97578005cb9eb1561b13e80755d3cfe632c0752f +a4439ee42b2a159663212b9bff3f0b32c46e06c3 diff --git a/decoders/premake5_v2.lua b/decoders/premake5_v2.lua index bf0a1156..44ba4c92 100644 --- a/decoders/premake5_v2.lua +++ b/decoders/premake5_v2.lua @@ -14,4 +14,12 @@ do includedirs({ 'include', '../include', libpng, libjpeg }) files({ 'src/**.cpp' }) + + filter({ 'options:not no-libjpeg-renames' }) + do + includedirs({ + rive .. '/dependencies', + }) + forceincludes({ 'rive_libjpeg_renames.h' }) + end end diff --git a/dependencies/gen_libjpeg_renames/gen_header.dart b/dependencies/gen_libjpeg_renames/gen_header.dart new file mode 100644 index 00000000..59cc2135 --- /dev/null +++ b/dependencies/gen_libjpeg_renames/gen_header.dart @@ -0,0 +1,74 @@ +import 'dart:collection'; +import 'dart:io'; + +final skip = HashSet.from( + [], +); + +final extras = HashSet.from( + [ + 'read_quant_tables', + 'read_scan_script', + 'set_quality_ratings', + 'set_quant_slots', + 'set_sample_factors', + 'read_color_map', + 'enable_signal_catcher', + 'start_progress_monitor', + 'end_progress_monitor', + 'read_stdin', + 'write_stdout', + 'jdiv_round_up', + 'jround_up', + 'jzero_far', + 'jcopy_sample_rows', + 'jcopy_block_row', + 'jtransform_parse_crop_spec', + 'jtransform_request_workspace', + 'jtransform_adjust_parameters', + 'jtransform_execute_transform', + 'jtransform_perfect_transform', + 'jcopy_markers_setup', + 'jcopy_markers_execute', + ], +); + +void main() { + final uniqueNames = HashSet(); + var header = StringBuffer(); + header.writeln('// clang-format off'); + header.writeln('// jpeg_*'); + var contents = File('libjpeg_names.txt').readAsStringSync(); + RegExp exp = RegExp(r'\s_(jpeg_([a-zA-Z0-9_]*))', multiLine: true); + Iterable matches = exp.allMatches(contents); + for (final m in matches) { + var symbolName = m[1]; + if (symbolName == null || + skip.contains(symbolName) || + uniqueNames.contains(symbolName)) { + continue; + } + uniqueNames.add(symbolName); + header.writeln('#define $symbolName rive_$symbolName'); + } + header.writeln('// jinit_*'); + { + RegExp exp = RegExp(r'\s_(jinit_([a-zA-Z0-9_]*))', multiLine: true); + Iterable matches = exp.allMatches(contents); + for (final m in matches) { + var symbolName = m[1]; + if (symbolName == null || + skip.contains(symbolName) || + uniqueNames.contains(symbolName)) { + continue; + } + uniqueNames.add(symbolName); + header.writeln('#define $symbolName rive_$symbolName'); + } + } + header.writeln('// _j extras'); + for (final symbolName in extras) { + header.writeln('#define $symbolName rive_$symbolName'); + } + File('../rive_libjpeg_renames.h').writeAsStringSync(header.toString()); +} diff --git a/dependencies/gen_libjpeg_renames/gen_renames.sh b/dependencies/gen_libjpeg_renames/gen_renames.sh new file mode 100755 index 00000000..6f45c0bf --- /dev/null +++ b/dependencies/gen_libjpeg_renames/gen_renames.sh @@ -0,0 +1,58 @@ +#!/bin/bash +set -e + +# This script should be called on a Mac! + +# NOTE: Before building, jconfig.txt needs to be renamed to jconfig.h + +if [[ ! -f "dependencies/bin/premake5" ]]; then + mkdir -p dependencies/bin + pushd dependencies + # v5.0.0-beta2 doesn't support apple silicon properly, update the branch + # once a stable one is avaialble that supports it + git clone --depth 1 --branch master https://github.com/premake/premake-core.git + pushd premake-core + if [[ $LOCAL_ARCH == "arm64" ]]; then + PREMAKE_MAKE_ARCH=ARM + else + PREMAKE_MAKE_ARCH=x86 + fi + make -f Bootstrap.mak osx PLATFORM=$PREMAKE_MAKE_ARCH + cp bin/release/* ../bin + popd + popd +fi + +export PREMAKE=$PWD/dependencies/bin/premake5 + +for var in "$@"; do + if [[ $var = "clean" ]]; then + echo 'Cleaning...' + rm -fR out + fi +done + +mkdir -p out +mkdir -p out_with_renames + +pushd ../../../ +PACKAGES=$PWD +popd +export PREMAKE_PATH="dependencies/export-compile-commands":"$PACKAGES/runtime_unity/native_plugin/platform":"$PACKAGES/runtime/build":"$PREMAKE_PATH" + +$PREMAKE gmake2 --file=../premake5_libjpeg_v2.lua --out=out --no-libjpeg-renames +pushd out +make -j$(($(sysctl -n hw.physicalcpu) + 1)) +popd + +nm out/liblibjpeg.a --demangle &>libjpeg_names.txt + +dart gen_header.dart + +# make with renames just to examine the exported symbols... +$PREMAKE gmake2 --file=../premake5_libjpeg_v2.lua --out=out_with_renames +pushd out_with_renames +make -j$(($(sysctl -n hw.physicalcpu) + 1)) +popd + +nm out_with_renames/liblibjpeg.a --demangle &>libjpeg_renames.txt diff --git a/dependencies/gen_yoga_renames/gen_header.dart b/dependencies/gen_yoga_renames/gen_header.dart new file mode 100644 index 00000000..d5f724db --- /dev/null +++ b/dependencies/gen_yoga_renames/gen_header.dart @@ -0,0 +1,46 @@ +import 'dart:collection'; +import 'dart:io'; + +final skip = HashSet.from( + [], +); + +final extras = HashSet.from( + [], +); + +void main() { + final uniqueNames = HashSet(); + var header = StringBuffer(); + header.writeln('// clang-format off'); + header.writeln('// YG*'); + var contents = File('yoga_names.txt').readAsStringSync(); + RegExp exp = RegExp(r'\s(YG([a-zA-Z0-9_]*))', multiLine: true); + Iterable matches = exp.allMatches(contents); + for (final m in matches) { + var symbolName = m[1]; + if (symbolName == null || + skip.contains(symbolName) || + uniqueNames.contains(symbolName)) { + continue; + } + uniqueNames.add(symbolName); + header.writeln('#define $symbolName rive_$symbolName'); + } + header.writeln('// _YG*'); + { + RegExp exp = RegExp(r'\s_(YG([a-zA-Z0-9_]*))', multiLine: true); + Iterable matches = exp.allMatches(contents); + for (final m in matches) { + var symbolName = m[1]; + if (symbolName == null || + skip.contains(symbolName) || + uniqueNames.contains(symbolName)) { + continue; + } + uniqueNames.add(symbolName); + header.writeln('#define $symbolName rive_$symbolName'); + } + } + File('../rive_yoga_renames.h').writeAsStringSync(header.toString()); +} diff --git a/dependencies/gen_yoga_renames/gen_renames.sh b/dependencies/gen_yoga_renames/gen_renames.sh new file mode 100755 index 00000000..eadf7d7c --- /dev/null +++ b/dependencies/gen_yoga_renames/gen_renames.sh @@ -0,0 +1,56 @@ +#!/bin/bash +set -e + +# This script should be called on a Mac! + +if [[ ! -f "dependencies/bin/premake5" ]]; then + mkdir -p dependencies/bin + pushd dependencies + # v5.0.0-beta2 doesn't support apple silicon properly, update the branch + # once a stable one is avaialble that supports it + git clone --depth 1 --branch master https://github.com/premake/premake-core.git + pushd premake-core + if [[ $LOCAL_ARCH == "arm64" ]]; then + PREMAKE_MAKE_ARCH=ARM + else + PREMAKE_MAKE_ARCH=x86 + fi + make -f Bootstrap.mak osx PLATFORM=$PREMAKE_MAKE_ARCH + cp bin/release/* ../bin + popd + popd +fi + +export PREMAKE=$PWD/dependencies/bin/premake5 + +for var in "$@"; do + if [[ $var = "clean" ]]; then + echo 'Cleaning...' + rm -fR out + fi +done + +mkdir -p out +mkdir -p out_with_renames + +pushd ../../../ +PACKAGES=$PWD +popd +export PREMAKE_PATH="dependencies/export-compile-commands":"$PACKAGES/runtime_unity/native_plugin/platform":"$PACKAGES/runtime/build":"$PREMAKE_PATH" + +$PREMAKE gmake2 --file=../premake5_yoga_v2.lua --out=out --no-yoga-renames +pushd out +make -j$(($(sysctl -n hw.physicalcpu) + 1)) +popd + +nm out/librive_yoga.a --demangle &>yoga_names.txt + +dart gen_header.dart + +# make with renames just to examine the exported symbols... +$PREMAKE gmake2 --file=../premake5_yoga_v2.lua --out=out_with_renames +pushd out_with_renames +make -j$(($(sysctl -n hw.physicalcpu) + 1)) +popd + +nm out_with_renames/librive_yoga.a --demangle &>yoga_renames.txt diff --git a/dependencies/premake5_libjpeg_v2.lua b/dependencies/premake5_libjpeg_v2.lua index 4b5280f5..6ef35f95 100644 --- a/dependencies/premake5_libjpeg_v2.lua +++ b/dependencies/premake5_libjpeg_v2.lua @@ -7,6 +7,11 @@ end local dependency = require('dependency') libjpeg = dependency.github('rive-app/libjpeg', 'v9f') +newoption({ + trigger = 'no-libjpeg-renames', + description = 'don\'t rename libjpeg symbols', +}) + project('libjpeg') do kind('StaticLib') @@ -62,4 +67,10 @@ do libjpeg .. '/jmemmgr.c', libjpeg .. '/jmemansi.c', }) + + filter({ 'options:not no-libjpeg-renames' }) + do + includedirs({ './' }) + forceincludes({ 'rive_libjpeg_renames.h' }) + end end diff --git a/dependencies/premake5_yoga_v2.lua b/dependencies/premake5_yoga_v2.lua index 4583132f..30d8284f 100644 --- a/dependencies/premake5_yoga_v2.lua +++ b/dependencies/premake5_yoga_v2.lua @@ -3,6 +3,11 @@ dofile('rive_build_config.lua') local dependency = require('dependency') yoga = dependency.github('rive-app/yoga', 'rive_changes_v2_0_1') +newoption({ + trigger = 'no-yoga-renames', + description = 'don\'t rename yoga symbols', +}) + project('rive_yoga') do kind('StaticLib') @@ -25,4 +30,10 @@ do yoga .. '/yoga/event/event.cpp', yoga .. '/yoga/log.cpp', }) + + filter({ 'options:not no-yoga-renames' }) + do + includedirs({ './' }) + forceincludes({ 'rive_yoga_renames.h' }) + end end diff --git a/dependencies/rive_libjpeg_renames.h b/dependencies/rive_libjpeg_renames.h new file mode 100644 index 00000000..9e1ad74f --- /dev/null +++ b/dependencies/rive_libjpeg_renames.h @@ -0,0 +1,204 @@ +// clang-format off +// jpeg_* +#define jpeg_aritab rive_jpeg_aritab +#define jpeg_CreateCompress rive_jpeg_CreateCompress +#define jpeg_abort rive_jpeg_abort +#define jpeg_abort_compress rive_jpeg_abort_compress +#define jpeg_destroy rive_jpeg_destroy +#define jpeg_destroy_compress rive_jpeg_destroy_compress +#define jpeg_finish_compress rive_jpeg_finish_compress +#define jpeg_natural_order rive_jpeg_natural_order +#define jpeg_suppress_tables rive_jpeg_suppress_tables +#define jpeg_write_m_byte rive_jpeg_write_m_byte +#define jpeg_write_m_header rive_jpeg_write_m_header +#define jpeg_write_marker rive_jpeg_write_marker +#define jpeg_write_tables rive_jpeg_write_tables +#define jpeg_start_compress rive_jpeg_start_compress +#define jpeg_write_raw_data rive_jpeg_write_raw_data +#define jpeg_write_scanlines rive_jpeg_write_scanlines +#define jpeg_fdct_10x10 rive_jpeg_fdct_10x10 +#define jpeg_fdct_10x5 rive_jpeg_fdct_10x5 +#define jpeg_fdct_11x11 rive_jpeg_fdct_11x11 +#define jpeg_fdct_12x12 rive_jpeg_fdct_12x12 +#define jpeg_fdct_12x6 rive_jpeg_fdct_12x6 +#define jpeg_fdct_13x13 rive_jpeg_fdct_13x13 +#define jpeg_fdct_14x14 rive_jpeg_fdct_14x14 +#define jpeg_fdct_14x7 rive_jpeg_fdct_14x7 +#define jpeg_fdct_15x15 rive_jpeg_fdct_15x15 +#define jpeg_fdct_16x16 rive_jpeg_fdct_16x16 +#define jpeg_fdct_16x8 rive_jpeg_fdct_16x8 +#define jpeg_fdct_1x1 rive_jpeg_fdct_1x1 +#define jpeg_fdct_1x2 rive_jpeg_fdct_1x2 +#define jpeg_fdct_2x1 rive_jpeg_fdct_2x1 +#define jpeg_fdct_2x2 rive_jpeg_fdct_2x2 +#define jpeg_fdct_2x4 rive_jpeg_fdct_2x4 +#define jpeg_fdct_3x3 rive_jpeg_fdct_3x3 +#define jpeg_fdct_3x6 rive_jpeg_fdct_3x6 +#define jpeg_fdct_4x2 rive_jpeg_fdct_4x2 +#define jpeg_fdct_4x4 rive_jpeg_fdct_4x4 +#define jpeg_fdct_4x8 rive_jpeg_fdct_4x8 +#define jpeg_fdct_5x10 rive_jpeg_fdct_5x10 +#define jpeg_fdct_5x5 rive_jpeg_fdct_5x5 +#define jpeg_fdct_6x12 rive_jpeg_fdct_6x12 +#define jpeg_fdct_6x3 rive_jpeg_fdct_6x3 +#define jpeg_fdct_6x6 rive_jpeg_fdct_6x6 +#define jpeg_fdct_7x14 rive_jpeg_fdct_7x14 +#define jpeg_fdct_7x7 rive_jpeg_fdct_7x7 +#define jpeg_fdct_8x16 rive_jpeg_fdct_8x16 +#define jpeg_fdct_8x4 rive_jpeg_fdct_8x4 +#define jpeg_fdct_9x9 rive_jpeg_fdct_9x9 +#define jpeg_fdct_float rive_jpeg_fdct_float +#define jpeg_fdct_ifast rive_jpeg_fdct_ifast +#define jpeg_fdct_islow rive_jpeg_fdct_islow +#define jpeg_alloc_huff_table rive_jpeg_alloc_huff_table +#define jpeg_gen_optimal_table rive_jpeg_gen_optimal_table +#define jpeg_make_c_derived_tbl rive_jpeg_make_c_derived_tbl +#define jpeg_std_huff_table rive_jpeg_std_huff_table +#define jpeg_calc_jpeg_dimensions rive_jpeg_calc_jpeg_dimensions +#define jpeg_natural_order2 rive_jpeg_natural_order2 +#define jpeg_natural_order3 rive_jpeg_natural_order3 +#define jpeg_natural_order4 rive_jpeg_natural_order4 +#define jpeg_natural_order5 rive_jpeg_natural_order5 +#define jpeg_natural_order6 rive_jpeg_natural_order6 +#define jpeg_natural_order7 rive_jpeg_natural_order7 +#define jpeg_alloc_quant_table rive_jpeg_alloc_quant_table +#define jpeg_add_quant_table rive_jpeg_add_quant_table +#define jpeg_default_colorspace rive_jpeg_default_colorspace +#define jpeg_default_qtables rive_jpeg_default_qtables +#define jpeg_quality_scaling rive_jpeg_quality_scaling +#define jpeg_set_colorspace rive_jpeg_set_colorspace +#define jpeg_set_defaults rive_jpeg_set_defaults +#define jpeg_set_linear_quality rive_jpeg_set_linear_quality +#define jpeg_set_quality rive_jpeg_set_quality +#define jpeg_simple_progression rive_jpeg_simple_progression +#define jpeg_copy_critical_parameters rive_jpeg_copy_critical_parameters +#define jpeg_write_coefficients rive_jpeg_write_coefficients +#define jpeg_CreateDecompress rive_jpeg_CreateDecompress +#define jpeg_abort_decompress rive_jpeg_abort_decompress +#define jpeg_consume_input rive_jpeg_consume_input +#define jpeg_destroy_decompress rive_jpeg_destroy_decompress +#define jpeg_finish_decompress rive_jpeg_finish_decompress +#define jpeg_has_multiple_scans rive_jpeg_has_multiple_scans +#define jpeg_input_complete rive_jpeg_input_complete +#define jpeg_read_header rive_jpeg_read_header +#define jpeg_finish_output rive_jpeg_finish_output +#define jpeg_read_raw_data rive_jpeg_read_raw_data +#define jpeg_read_scanlines rive_jpeg_read_scanlines +#define jpeg_start_decompress rive_jpeg_start_decompress +#define jpeg_start_output rive_jpeg_start_output +#define jpeg_mem_dest rive_jpeg_mem_dest +#define jpeg_stdio_dest rive_jpeg_stdio_dest +#define jpeg_mem_src rive_jpeg_mem_src +#define jpeg_resync_to_restart rive_jpeg_resync_to_restart +#define jpeg_stdio_src rive_jpeg_stdio_src +#define jpeg_idct_10x10 rive_jpeg_idct_10x10 +#define jpeg_idct_10x5 rive_jpeg_idct_10x5 +#define jpeg_idct_11x11 rive_jpeg_idct_11x11 +#define jpeg_idct_12x12 rive_jpeg_idct_12x12 +#define jpeg_idct_12x6 rive_jpeg_idct_12x6 +#define jpeg_idct_13x13 rive_jpeg_idct_13x13 +#define jpeg_idct_14x14 rive_jpeg_idct_14x14 +#define jpeg_idct_14x7 rive_jpeg_idct_14x7 +#define jpeg_idct_15x15 rive_jpeg_idct_15x15 +#define jpeg_idct_16x16 rive_jpeg_idct_16x16 +#define jpeg_idct_16x8 rive_jpeg_idct_16x8 +#define jpeg_idct_1x1 rive_jpeg_idct_1x1 +#define jpeg_idct_1x2 rive_jpeg_idct_1x2 +#define jpeg_idct_2x1 rive_jpeg_idct_2x1 +#define jpeg_idct_2x2 rive_jpeg_idct_2x2 +#define jpeg_idct_2x4 rive_jpeg_idct_2x4 +#define jpeg_idct_3x3 rive_jpeg_idct_3x3 +#define jpeg_idct_3x6 rive_jpeg_idct_3x6 +#define jpeg_idct_4x2 rive_jpeg_idct_4x2 +#define jpeg_idct_4x4 rive_jpeg_idct_4x4 +#define jpeg_idct_4x8 rive_jpeg_idct_4x8 +#define jpeg_idct_5x10 rive_jpeg_idct_5x10 +#define jpeg_idct_5x5 rive_jpeg_idct_5x5 +#define jpeg_idct_6x12 rive_jpeg_idct_6x12 +#define jpeg_idct_6x3 rive_jpeg_idct_6x3 +#define jpeg_idct_6x6 rive_jpeg_idct_6x6 +#define jpeg_idct_7x14 rive_jpeg_idct_7x14 +#define jpeg_idct_7x7 rive_jpeg_idct_7x7 +#define jpeg_idct_8x16 rive_jpeg_idct_8x16 +#define jpeg_idct_8x4 rive_jpeg_idct_8x4 +#define jpeg_idct_9x9 rive_jpeg_idct_9x9 +#define jpeg_idct_float rive_jpeg_idct_float +#define jpeg_idct_ifast rive_jpeg_idct_ifast +#define jpeg_idct_islow rive_jpeg_idct_islow +#define jpeg_fill_bit_buffer rive_jpeg_fill_bit_buffer +#define jpeg_huff_decode rive_jpeg_huff_decode +#define jpeg_make_d_derived_tbl rive_jpeg_make_d_derived_tbl +#define jpeg_zigzag_order rive_jpeg_zigzag_order +#define jpeg_zigzag_order2 rive_jpeg_zigzag_order2 +#define jpeg_zigzag_order3 rive_jpeg_zigzag_order3 +#define jpeg_zigzag_order4 rive_jpeg_zigzag_order4 +#define jpeg_zigzag_order5 rive_jpeg_zigzag_order5 +#define jpeg_zigzag_order6 rive_jpeg_zigzag_order6 +#define jpeg_zigzag_order7 rive_jpeg_zigzag_order7 +#define jpeg_core_output_dimensions rive_jpeg_core_output_dimensions +#define jpeg_save_markers rive_jpeg_save_markers +#define jpeg_set_marker_processor rive_jpeg_set_marker_processor +#define jpeg_calc_output_dimensions rive_jpeg_calc_output_dimensions +#define jpeg_new_colormap rive_jpeg_new_colormap +#define jpeg_read_coefficients rive_jpeg_read_coefficients +#define jpeg_std_error rive_jpeg_std_error +#define jpeg_std_message_table rive_jpeg_std_message_table +#define jpeg_free_large rive_jpeg_free_large +#define jpeg_free_small rive_jpeg_free_small +#define jpeg_get_large rive_jpeg_get_large +#define jpeg_get_small rive_jpeg_get_small +#define jpeg_mem_available rive_jpeg_mem_available +#define jpeg_mem_init rive_jpeg_mem_init +#define jpeg_mem_term rive_jpeg_mem_term +#define jpeg_open_backing_store rive_jpeg_open_backing_store +// jinit_* +#define jinit_marker_writer rive_jinit_marker_writer +#define jinit_memory_mgr rive_jinit_memory_mgr +#define jinit_compress_master rive_jinit_compress_master +#define jinit_arith_encoder rive_jinit_arith_encoder +#define jinit_c_coef_controller rive_jinit_c_coef_controller +#define jinit_color_converter rive_jinit_color_converter +#define jinit_forward_dct rive_jinit_forward_dct +#define jinit_huff_encoder rive_jinit_huff_encoder +#define jinit_c_main_controller rive_jinit_c_main_controller +#define jinit_c_master_control rive_jinit_c_master_control +#define jinit_c_prep_controller rive_jinit_c_prep_controller +#define jinit_downsampler rive_jinit_downsampler +#define jinit_input_controller rive_jinit_input_controller +#define jinit_marker_reader rive_jinit_marker_reader +#define jinit_master_decompress rive_jinit_master_decompress +#define jinit_arith_decoder rive_jinit_arith_decoder +#define jinit_d_coef_controller rive_jinit_d_coef_controller +#define jinit_color_deconverter rive_jinit_color_deconverter +#define jinit_inverse_dct rive_jinit_inverse_dct +#define jinit_huff_decoder rive_jinit_huff_decoder +#define jinit_d_main_controller rive_jinit_d_main_controller +#define jinit_1pass_quantizer rive_jinit_1pass_quantizer +#define jinit_2pass_quantizer rive_jinit_2pass_quantizer +#define jinit_d_post_controller rive_jinit_d_post_controller +#define jinit_merged_upsampler rive_jinit_merged_upsampler +#define jinit_upsampler rive_jinit_upsampler +// _j extras +#define jtransform_execute_transform rive_jtransform_execute_transform +#define read_scan_script rive_read_scan_script +#define jcopy_markers_execute rive_jcopy_markers_execute +#define jcopy_markers_setup rive_jcopy_markers_setup +#define enable_signal_catcher rive_enable_signal_catcher +#define set_quant_slots rive_set_quant_slots +#define read_stdin rive_read_stdin +#define set_quality_ratings rive_set_quality_ratings +#define write_stdout rive_write_stdout +#define set_sample_factors rive_set_sample_factors +#define jtransform_perfect_transform rive_jtransform_perfect_transform +#define jcopy_sample_rows rive_jcopy_sample_rows +#define jdiv_round_up rive_jdiv_round_up +#define jtransform_request_workspace rive_jtransform_request_workspace +#define jcopy_block_row rive_jcopy_block_row +#define end_progress_monitor rive_end_progress_monitor +#define read_quant_tables rive_read_quant_tables +#define jzero_far rive_jzero_far +#define read_color_map rive_read_color_map +#define jtransform_adjust_parameters rive_jtransform_adjust_parameters +#define jround_up rive_jround_up +#define start_progress_monitor rive_start_progress_monitor +#define jtransform_parse_crop_spec rive_jtransform_parse_crop_spec diff --git a/dependencies/rive_yoga_renames.h b/dependencies/rive_yoga_renames.h new file mode 100644 index 00000000..f10efae0 --- /dev/null +++ b/dependencies/rive_yoga_renames.h @@ -0,0 +1,241 @@ +// clang-format off +// YG* +#define YGFloatMax rive_YGFloatMax +#define YGFloatMin rive_YGFloatMin +#define YGValueEqual rive_YGValueEqual +#define YGValue rive_YGValue +#define YGDoubleEqual rive_YGDoubleEqual +#define YGFloatsEqual rive_YGFloatsEqual +#define YGFloatSanitize rive_YGFloatSanitize +#define YGFloatOptionalMax rive_YGFloatOptionalMax +#define YGFloatOptional rive_YGFloatOptional +#define YGFlexDirectionCross rive_YGFlexDirectionCross +#define YGDirection rive_YGDirection +#define YGResolveFlexDirection rive_YGResolveFlexDirection +#define YGFlexDirectionIsColumn rive_YGFlexDirectionIsColumn +#define YGConfig rive_YGConfig +#define YGNode rive_YGNode +#define YGLogLevel rive_YGLogLevel +#define YGErrata rive_YGErrata +#define YGEnums rive_YGEnums +#define YGLayout rive_YGLayout +#define YGFloatArrayEqual rive_YGFloatArrayEqual +#define YGCachedMeasurement rive_YGCachedMeasurement +#define YGResolveValue rive_YGResolveValue +#define YGFlexDirectionIsRow rive_YGFlexDirectionIsRow +#define YGResolveValueMargin rive_YGResolveValueMargin +#define YGMeasureMode rive_YGMeasureMode +#define YGEdge rive_YGEdge +#define YGStyle rive_YGStyle +#define YGPositionType rive_YGPositionType +#define YGFlexDirection rive_YGFlexDirection +#define YGNodePrint rive_YGNodePrint +#define YGPrintOptions rive_YGPrintOptions +#define YGOverflow rive_YGOverflow +#define YGWrap rive_YGWrap +#define YGAlign rive_YGAlign +#define YGDisplay rive_YGDisplay +#define YGJustify rive_YGJustify +#define YGLayoutNodeInternal rive_YGLayoutNodeInternal +#define YGConfigGetDefault rive_YGConfigGetDefault +#define YGBaseline rive_YGBaseline +#define YGDefaultLog rive_YGDefaultLog +#define YGNodeAlignItem rive_YGNodeAlignItem +#define YGNodeBoundAxis rive_YGNodeBoundAxis +#define YGNodelayoutImpl rive_YGNodelayoutImpl +#define YGJustifyMainAxis rive_YGJustifyMainAxis +#define YGCollectFlexItemsRowValues rive_YGCollectFlexItemsRowValues +#define YGMeasureModeName rive_YGMeasureModeName +#define YGIsBaselineLayout rive_YGIsBaselineLayout +#define YGRoundToPixelGrid rive_YGRoundToPixelGrid +#define YGDoubleIsUndefined rive_YGDoubleIsUndefined +#define YGNodeDimWithMargin rive_YGNodeDimWithMargin +#define YGNodePrintInternal rive_YGNodePrintInternal +#define YGNodeIsStyleDimDefined rive_YGNodeIsStyleDimDefined +#define YGResolveFlexibleLength rive_YGResolveFlexibleLength +#define YGNodeIsLayoutDimDefined rive_YGNodeIsLayoutDimDefined +#define YGConstrainMaxSizeForMode rive_YGConstrainMaxSizeForMode +#define YGNodeAbsoluteLayoutChild rive_YGNodeAbsoluteLayoutChild +#define YGZeroOutLayoutRecursively rive_YGZeroOutLayoutRecursively +#define YGNodePaddingAndBorderForAxis rive_YGNodePaddingAndBorderForAxis +#define YGDistributeFreeSpaceFirstPass rive_YGDistributeFreeSpaceFirstPass +#define YGNodeBoundAxisWithinMinAndMax rive_YGNodeBoundAxisWithinMinAndMax +#define YGNodeComputeFlexBasisForChild rive_YGNodeComputeFlexBasisForChild +#define YGNodeSetChildTrailingPosition rive_YGNodeSetChildTrailingPosition +#define YGDistributeFreeSpaceSecondPass rive_YGDistributeFreeSpaceSecondPass +#define YGNodeCalculateAvailableInnerDim rive_YGNodeCalculateAvailableInnerDim +#define YGDimension rive_YGDimension +#define YGNodeComputeFlexBasisForChildren rive_YGNodeComputeFlexBasisForChildren +#define YGCalculateCollectFlexItemsRowValues rive_YGCalculateCollectFlexItemsRowValues +#define YGNodeFixedSizeSetMeasuredDimensions rive_YGNodeFixedSizeSetMeasuredDimensions +#define YGNodeEmptyContainerSetMeasuredDimensions rive_YGNodeEmptyContainerSetMeasuredDimensions +#define YGNodeWithMeasureFuncSetMeasuredDimensions rive_YGNodeWithMeasureFuncSetMeasuredDimensions +#define YGMeasureModeOldSizeIsUnspecifiedAndStillFits rive_YGMeasureModeOldSizeIsUnspecifiedAndStillFits +#define YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize rive_YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize +#define YGMeasureModeNewMeasureSizeIsStricterAndStillValid rive_YGMeasureModeNewMeasureSizeIsStricterAndStillValid +#define YGSpacer rive_YGSpacer +#define YGGutter rive_YGGutter +// _YG* +#define YGNodeClone rive_YGNodeClone +#define YGAlignToString rive_YGAlignToString +#define YGDimensionToString rive_YGDimensionToString +#define YGDirectionToString rive_YGDirectionToString +#define YGDisplayToString rive_YGDisplayToString +#define YGEdgeToString rive_YGEdgeToString +#define YGErrataToString rive_YGErrataToString +#define YGExperimentalFeatureToString rive_YGExperimentalFeatureToString +#define YGFlexDirectionToString rive_YGFlexDirectionToString +#define YGGutterToString rive_YGGutterToString +#define YGJustifyToString rive_YGJustifyToString +#define YGLogLevelToString rive_YGLogLevelToString +#define YGMeasureModeToString rive_YGMeasureModeToString +#define YGNodeTypeToString rive_YGNodeTypeToString +#define YGOverflowToString rive_YGOverflowToString +#define YGPositionTypeToString rive_YGPositionTypeToString +#define YGPrintOptionsToString rive_YGPrintOptionsToString +#define YGUnitToString rive_YGUnitToString +#define YGWrapToString rive_YGWrapToString +#define YGAssert rive_YGAssert +#define YGAssertWithConfig rive_YGAssertWithConfig +#define YGAssertWithNode rive_YGAssertWithNode +#define YGValueAuto rive_YGValueAuto +#define YGValueUndefined rive_YGValueUndefined +#define YGValueZero rive_YGValueZero +#define YGNodeGetChild rive_YGNodeGetChild +#define YGConfigCopy rive_YGConfigCopy +#define YGConfigFree rive_YGConfigFree +#define YGConfigGetContext rive_YGConfigGetContext +#define YGConfigGetErrata rive_YGConfigGetErrata +#define YGConfigGetInstanceCount rive_YGConfigGetInstanceCount +#define YGConfigGetPointScaleFactor rive_YGConfigGetPointScaleFactor +#define YGConfigGetUseLegacyStretchBehaviour rive_YGConfigGetUseLegacyStretchBehaviour +#define YGConfigGetUseWebDefaults rive_YGConfigGetUseWebDefaults +#define YGConfigIsExperimentalFeatureEnabled rive_YGConfigIsExperimentalFeatureEnabled +#define YGConfigNew rive_YGConfigNew +#define YGConfigSetCloneNodeFunc rive_YGConfigSetCloneNodeFunc +#define YGConfigSetContext rive_YGConfigSetContext +#define YGConfigSetErrata rive_YGConfigSetErrata +#define YGConfigSetExperimentalFeatureEnabled rive_YGConfigSetExperimentalFeatureEnabled +#define YGConfigSetLogger rive_YGConfigSetLogger +#define YGConfigSetPointScaleFactor rive_YGConfigSetPointScaleFactor +#define YGConfigSetPrintTreeFlag rive_YGConfigSetPrintTreeFlag +#define YGConfigSetUseLegacyStretchBehaviour rive_YGConfigSetUseLegacyStretchBehaviour +#define YGConfigSetUseWebDefaults rive_YGConfigSetUseWebDefaults +#define YGFloatIsUndefined rive_YGFloatIsUndefined +#define YGNodeCalculateLayout rive_YGNodeCalculateLayout +#define YGNodeCalculateLayoutWithContext rive_YGNodeCalculateLayoutWithContext +#define YGNodeCanUseCachedMeasurement rive_YGNodeCanUseCachedMeasurement +#define YGNodeCopyStyle rive_YGNodeCopyStyle +#define YGNodeDeallocate rive_YGNodeDeallocate +#define YGNodeFree rive_YGNodeFree +#define YGNodeFreeRecursive rive_YGNodeFreeRecursive +#define YGNodeFreeRecursiveWithCleanupFunc rive_YGNodeFreeRecursiveWithCleanupFunc +#define YGNodeGetChildCount rive_YGNodeGetChildCount +#define YGNodeGetConfig rive_YGNodeGetConfig +#define YGNodeGetContext rive_YGNodeGetContext +#define YGNodeGetDirtiedFunc rive_YGNodeGetDirtiedFunc +#define YGNodeGetHasNewLayout rive_YGNodeGetHasNewLayout +#define YGNodeGetNodeType rive_YGNodeGetNodeType +#define YGNodeGetOwner rive_YGNodeGetOwner +#define YGNodeGetParent rive_YGNodeGetParent +#define YGNodeHasBaselineFunc rive_YGNodeHasBaselineFunc +#define YGNodeHasMeasureFunc rive_YGNodeHasMeasureFunc +#define YGNodeInsertChild rive_YGNodeInsertChild +#define YGNodeIsDirty rive_YGNodeIsDirty +#define YGNodeIsReferenceBaseline rive_YGNodeIsReferenceBaseline +#define YGNodeLayoutGetBorder rive_YGNodeLayoutGetBorder +#define YGNodeLayoutGetBottom rive_YGNodeLayoutGetBottom +#define YGNodeLayoutGetDirection rive_YGNodeLayoutGetDirection +#define YGNodeLayoutGetHadOverflow rive_YGNodeLayoutGetHadOverflow +#define YGNodeLayoutGetHeight rive_YGNodeLayoutGetHeight +#define YGNodeLayoutGetLeft rive_YGNodeLayoutGetLeft +#define YGNodeLayoutGetMargin rive_YGNodeLayoutGetMargin +#define YGNodeLayoutGetPadding rive_YGNodeLayoutGetPadding +#define YGNodeLayoutGetRight rive_YGNodeLayoutGetRight +#define YGNodeLayoutGetTop rive_YGNodeLayoutGetTop +#define YGNodeLayoutGetWidth rive_YGNodeLayoutGetWidth +#define YGNodeMarkDirty rive_YGNodeMarkDirty +#define YGNodeMarkDirtyAndPropagateToDescendants rive_YGNodeMarkDirtyAndPropagateToDescendants +#define YGNodeNew rive_YGNodeNew +#define YGNodeNewWithConfig rive_YGNodeNewWithConfig +#define YGNodeRemoveAllChildren rive_YGNodeRemoveAllChildren +#define YGNodeRemoveChild rive_YGNodeRemoveChild +#define YGNodeReset rive_YGNodeReset +#define YGNodeSetBaselineFunc rive_YGNodeSetBaselineFunc +#define YGNodeSetChildren rive_YGNodeSetChildren +#define YGNodeSetConfig rive_YGNodeSetConfig +#define YGNodeSetContext rive_YGNodeSetContext +#define YGNodeSetDirtiedFunc rive_YGNodeSetDirtiedFunc +#define YGNodeSetHasNewLayout rive_YGNodeSetHasNewLayout +#define YGNodeSetIsReferenceBaseline rive_YGNodeSetIsReferenceBaseline +#define YGNodeSetMeasureFunc rive_YGNodeSetMeasureFunc +#define YGNodeSetNodeType rive_YGNodeSetNodeType +#define YGNodeSetPrintFunc rive_YGNodeSetPrintFunc +#define YGNodeStyleGetAlignContent rive_YGNodeStyleGetAlignContent +#define YGNodeStyleGetAlignItems rive_YGNodeStyleGetAlignItems +#define YGNodeStyleGetAlignSelf rive_YGNodeStyleGetAlignSelf +#define YGNodeStyleGetAspectRatio rive_YGNodeStyleGetAspectRatio +#define YGNodeStyleGetBorder rive_YGNodeStyleGetBorder +#define YGNodeStyleGetDirection rive_YGNodeStyleGetDirection +#define YGNodeStyleGetDisplay rive_YGNodeStyleGetDisplay +#define YGNodeStyleGetFlex rive_YGNodeStyleGetFlex +#define YGNodeStyleGetFlexBasis rive_YGNodeStyleGetFlexBasis +#define YGNodeStyleGetFlexDirection rive_YGNodeStyleGetFlexDirection +#define YGNodeStyleGetFlexGrow rive_YGNodeStyleGetFlexGrow +#define YGNodeStyleGetFlexShrink rive_YGNodeStyleGetFlexShrink +#define YGNodeStyleGetFlexWrap rive_YGNodeStyleGetFlexWrap +#define YGNodeStyleGetGap rive_YGNodeStyleGetGap +#define YGNodeStyleGetHeight rive_YGNodeStyleGetHeight +#define YGNodeStyleGetJustifyContent rive_YGNodeStyleGetJustifyContent +#define YGNodeStyleGetMargin rive_YGNodeStyleGetMargin +#define YGNodeStyleGetMaxHeight rive_YGNodeStyleGetMaxHeight +#define YGNodeStyleGetMaxWidth rive_YGNodeStyleGetMaxWidth +#define YGNodeStyleGetMinHeight rive_YGNodeStyleGetMinHeight +#define YGNodeStyleGetMinWidth rive_YGNodeStyleGetMinWidth +#define YGNodeStyleGetOverflow rive_YGNodeStyleGetOverflow +#define YGNodeStyleGetPadding rive_YGNodeStyleGetPadding +#define YGNodeStyleGetPosition rive_YGNodeStyleGetPosition +#define YGNodeStyleGetPositionType rive_YGNodeStyleGetPositionType +#define YGNodeStyleGetWidth rive_YGNodeStyleGetWidth +#define YGNodeStyleSetAlignContent rive_YGNodeStyleSetAlignContent +#define YGNodeStyleSetAlignItems rive_YGNodeStyleSetAlignItems +#define YGNodeStyleSetAlignSelf rive_YGNodeStyleSetAlignSelf +#define YGNodeStyleSetAspectRatio rive_YGNodeStyleSetAspectRatio +#define YGNodeStyleSetBorder rive_YGNodeStyleSetBorder +#define YGNodeStyleSetDirection rive_YGNodeStyleSetDirection +#define YGNodeStyleSetDisplay rive_YGNodeStyleSetDisplay +#define YGNodeStyleSetFlex rive_YGNodeStyleSetFlex +#define YGNodeStyleSetFlexBasis rive_YGNodeStyleSetFlexBasis +#define YGNodeStyleSetFlexBasisAuto rive_YGNodeStyleSetFlexBasisAuto +#define YGNodeStyleSetFlexBasisPercent rive_YGNodeStyleSetFlexBasisPercent +#define YGNodeStyleSetFlexDirection rive_YGNodeStyleSetFlexDirection +#define YGNodeStyleSetFlexGrow rive_YGNodeStyleSetFlexGrow +#define YGNodeStyleSetFlexShrink rive_YGNodeStyleSetFlexShrink +#define YGNodeStyleSetFlexWrap rive_YGNodeStyleSetFlexWrap +#define YGNodeStyleSetGap rive_YGNodeStyleSetGap +#define YGNodeStyleSetHeight rive_YGNodeStyleSetHeight +#define YGNodeStyleSetHeightAuto rive_YGNodeStyleSetHeightAuto +#define YGNodeStyleSetHeightPercent rive_YGNodeStyleSetHeightPercent +#define YGNodeStyleSetJustifyContent rive_YGNodeStyleSetJustifyContent +#define YGNodeStyleSetMargin rive_YGNodeStyleSetMargin +#define YGNodeStyleSetMarginAuto rive_YGNodeStyleSetMarginAuto +#define YGNodeStyleSetMarginPercent rive_YGNodeStyleSetMarginPercent +#define YGNodeStyleSetMaxHeight rive_YGNodeStyleSetMaxHeight +#define YGNodeStyleSetMaxHeightPercent rive_YGNodeStyleSetMaxHeightPercent +#define YGNodeStyleSetMaxWidth rive_YGNodeStyleSetMaxWidth +#define YGNodeStyleSetMaxWidthPercent rive_YGNodeStyleSetMaxWidthPercent +#define YGNodeStyleSetMinHeight rive_YGNodeStyleSetMinHeight +#define YGNodeStyleSetMinHeightPercent rive_YGNodeStyleSetMinHeightPercent +#define YGNodeStyleSetMinWidth rive_YGNodeStyleSetMinWidth +#define YGNodeStyleSetMinWidthPercent rive_YGNodeStyleSetMinWidthPercent +#define YGNodeStyleSetOverflow rive_YGNodeStyleSetOverflow +#define YGNodeStyleSetPadding rive_YGNodeStyleSetPadding +#define YGNodeStyleSetPaddingPercent rive_YGNodeStyleSetPaddingPercent +#define YGNodeStyleSetPosition rive_YGNodeStyleSetPosition +#define YGNodeStyleSetPositionPercent rive_YGNodeStyleSetPositionPercent +#define YGNodeStyleSetPositionType rive_YGNodeStyleSetPositionType +#define YGNodeStyleSetWidth rive_YGNodeStyleSetWidth +#define YGNodeStyleSetWidthAuto rive_YGNodeStyleSetWidthAuto +#define YGNodeStyleSetWidthPercent rive_YGNodeStyleSetWidthPercent +#define YGNodeSwapChild rive_YGNodeSwapChild +#define YGRoundValueToPixelGrid rive_YGRoundValueToPixelGrid diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index 78c2296f..318aeba4 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -54,4 +54,12 @@ do }) forceincludes({ 'rive_harfbuzz_renames.h' }) end + + filter({ 'options:not no-yoga-renames' }) + do + includedirs({ + dependencies, + }) + forceincludes({ 'rive_yoga_renames.h' }) + end end diff --git a/premake5_v2.lua b/premake5_v2.lua index 44244a27..3d6c8aa5 100644 --- a/premake5_v2.lua +++ b/premake5_v2.lua @@ -60,6 +60,14 @@ do forceincludes({ 'rive_harfbuzz_renames.h' }) end + filter({ 'options:not no-yoga-renames' }) + do + includedirs({ + dependencies, + }) + forceincludes({ 'rive_yoga_renames.h' }) + end + filter({ 'system:linux' }) do defines({ 'MA_NO_RUNTIME_LINKING' }) From c7ecdf41112fa5e97b837b0001ac584bdffcb29a Mon Sep 17 00:00:00 2001 From: philter Date: Fri, 21 Jun 2024 15:20:46 +0000 Subject: [PATCH 069/138] Animation for Layouts - Popout for setting layout animation - Supports hold, linear, cubic ease and elastic - Layouts can have custom interpolation or inherit from up the layout tree - This PR also implements the change to not store flexGrow or alignSelf when setting scaleType, rather we put the logic into syncStyle and directly pass the values for those into the layout engine - Tested with Rive Renderer in editor and seems to work well! - @alxgibsn I moved the animation popout to the Layout inspector. We discussed the Auto Layout inspector, but since animation can be applied to a layoutcomponent that has no children (whereas the Auto Layout inspector must have children to be expanded), it seemed more appropriate there. Diffs= 31f5ee5c4 Animation for Layouts (#7426) Co-authored-by: Philip Chung --- .rive_head | 2 +- dev/defs/layout/layout_component_style.json | 83 +++++++ dev/defs/layout_component_absolute.json | 19 -- include/rive/component_dirt.hpp | 2 + include/rive/generated/core_registry.hpp | 43 +++- .../layout/layout_component_style_base.hpp | 90 +++++++ .../layout_component_absolute_base.hpp | 39 --- .../rive/layout/layout_component_style.hpp | 26 ++ include/rive/layout_component.hpp | 40 +++ include/rive/layout_component_absolute.hpp | 13 - src/artboard.cpp | 15 +- .../layout_component_absolute_base.cpp | 11 - src/layout/layout_component_style.cpp | 40 +++ src/layout_component.cpp | 229 +++++++++++++++++- test/layout_test.cpp | 4 +- 15 files changed, 564 insertions(+), 92 deletions(-) delete mode 100644 dev/defs/layout_component_absolute.json delete mode 100644 include/rive/generated/layout_component_absolute_base.hpp delete mode 100644 include/rive/layout_component_absolute.hpp delete mode 100644 src/generated/layout_component_absolute_base.cpp diff --git a/.rive_head b/.rive_head index 20270357..bd73d8c3 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a4439ee42b2a159663212b9bff3f0b32c46e06c3 +31f5ee5c480ab9b2c1a0d263305f56bfd943d780 diff --git a/dev/defs/layout/layout_component_style.json b/dev/defs/layout/layout_component_style.json index d3da49c8..194601b8 100644 --- a/dev/defs/layout/layout_component_style.json +++ b/dev/defs/layout/layout_component_style.json @@ -37,6 +37,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutgap", "key": { "int": 498, "string": "gaphorizontal" @@ -47,6 +48,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutgap", "key": { "int": 499, "string": "gapvertical" @@ -57,6 +59,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmax", "key": { "int": 500, "string": "maxwidth" @@ -67,6 +70,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmax", "key": { "int": 501, "string": "maxheight" @@ -77,6 +81,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmin", "key": { "int": 502, "string": "minwidth" @@ -87,6 +92,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmin", "key": { "int": 503, "string": "minheight" @@ -137,6 +143,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmargin", "key": { "int": 508, "string": "marginleft" @@ -147,6 +154,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmargin", "key": { "int": 509, "string": "marginright" @@ -157,6 +165,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmargin", "key": { "int": 510, "string": "margintop" @@ -167,6 +176,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutmargin", "key": { "int": 511, "string": "marginbottom" @@ -177,6 +187,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutpadding", "key": { "int": 512, "string": "paddingleft" @@ -187,6 +198,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutpadding", "key": { "int": 513, "string": "paddingright" @@ -197,6 +209,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutpadding", "key": { "int": 514, "string": "paddingtop" @@ -207,6 +220,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutpadding", "key": { "int": 515, "string": "paddingbottom" @@ -217,6 +231,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutposition", "key": { "int": 516, "string": "positionleft" @@ -227,6 +242,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutposition", "key": { "int": 517, "string": "positionright" @@ -237,6 +253,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutposition", "key": { "int": 518, "string": "positiontop" @@ -247,6 +264,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutposition", "key": { "int": 519, "string": "positionbottom" @@ -302,6 +320,71 @@ "string": "aspectratio" }, "description": "Aspect ratio value." + }, + "showUnitToggle": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 542, + "string": "showunittoggle" + }, + "description": "Show layout unit toggle in inspector position widget. Editor only.", + "runtime": false + }, + "edgeConstraints": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 545, + "string": "edgeconstraints" + }, + "runtime": false + }, + "scaleType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 546, + "string": "scaletype" + } + }, + "animationStyleType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 589, + "string": "animationstyletype" + }, + "description": "The type of animation none|custom|inherit applied to this layout." + }, + "interpolationType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 590, + "string": "interpolationtype" + }, + "description": "The type of interpolation index in KeyframeInterpolation applied to this layout." + }, + "interpolatorId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 591, + "string": "interpolatorid" + }, + "description": "The id of the custom interpolator used when interpolation is Cubic." + }, + "interpolationTime": { + "type": "double", + "initialValue": "0", + "key": { + "int": 592, + "string": "interpolationtime" + }, + "description": "The time over which the interpolator applies." } } } \ No newline at end of file diff --git a/dev/defs/layout_component_absolute.json b/dev/defs/layout_component_absolute.json deleted file mode 100644 index a239d432..00000000 --- a/dev/defs/layout_component_absolute.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "AbsoluteLayoutComponent", - "key": { - "int": 423, - "string": "absolutelayoutcomponent" - }, - "extends": "layout_component.json", - "properties": { - "constraints": { - "type": "uint", - "initialValue": "0", - "key": { - "int": 535, - "string": "constraints" - }, - "runtime": false - } - } -} \ No newline at end of file diff --git a/include/rive/component_dirt.hpp b/include/rive/component_dirt.hpp index fedb0c70..ccd64c0c 100644 --- a/include/rive/component_dirt.hpp +++ b/include/rive/component_dirt.hpp @@ -63,6 +63,8 @@ enum class ComponentDirt : unsigned short // TODO: do we need this? // BlendMode = 1 << 9, + LayoutStyle = 1 << 11, + /// All dirty. Every flag (apart from Collapsed) is set. Filthy = 0xFFFE }; diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index c4018d2e..b073d8aa 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -108,7 +108,6 @@ #include "rive/joystick.hpp" #include "rive/layout/layout_component_style.hpp" #include "rive/layout_component.hpp" -#include "rive/layout_component_absolute.hpp" #include "rive/nested_animation.hpp" #include "rive/nested_artboard.hpp" #include "rive/node.hpp" @@ -398,8 +397,6 @@ class CoreRegistry return new Joystick(); case BackboardBase::typeKey: return new Backboard(); - case AbsoluteLayoutComponentBase::typeKey: - return new AbsoluteLayoutComponent(); case OpenUrlEventBase::typeKey: return new OpenUrlEvent(); case DataBindBase::typeKey: @@ -626,6 +623,18 @@ class CoreRegistry case LayoutComponentStyleBase::layoutFlags2PropertyKey: object->as()->layoutFlags2(value); break; + case LayoutComponentStyleBase::scaleTypePropertyKey: + object->as()->scaleType(value); + break; + case LayoutComponentStyleBase::animationStyleTypePropertyKey: + object->as()->animationStyleType(value); + break; + case LayoutComponentStyleBase::interpolationTypePropertyKey: + object->as()->interpolationType(value); + break; + case LayoutComponentStyleBase::interpolatorIdPropertyKey: + object->as()->interpolatorId(value); + break; case ListenerFireEventBase::eventIdPropertyKey: object->as()->eventId(value); break; @@ -1085,6 +1094,9 @@ class CoreRegistry case LayoutComponentStyleBase::aspectRatioPropertyKey: object->as()->aspectRatio(value); break; + case LayoutComponentStyleBase::interpolationTimePropertyKey: + object->as()->interpolationTime(value); + break; case NestedLinearAnimationBase::mixPropertyKey: object->as()->mix(value); break; @@ -1562,6 +1574,14 @@ class CoreRegistry return object->as()->layoutFlags1(); case LayoutComponentStyleBase::layoutFlags2PropertyKey: return object->as()->layoutFlags2(); + case LayoutComponentStyleBase::scaleTypePropertyKey: + return object->as()->scaleType(); + case LayoutComponentStyleBase::animationStyleTypePropertyKey: + return object->as()->animationStyleType(); + case LayoutComponentStyleBase::interpolationTypePropertyKey: + return object->as()->interpolationType(); + case LayoutComponentStyleBase::interpolatorIdPropertyKey: + return object->as()->interpolatorId(); case ListenerFireEventBase::eventIdPropertyKey: return object->as()->eventId(); case LayerStateBase::flagsPropertyKey: @@ -1877,6 +1897,8 @@ class CoreRegistry return object->as()->flexBasis(); case LayoutComponentStyleBase::aspectRatioPropertyKey: return object->as()->aspectRatio(); + case LayoutComponentStyleBase::interpolationTimePropertyKey: + return object->as()->interpolationTime(); case NestedLinearAnimationBase::mixPropertyKey: return object->as()->mix(); case NestedSimpleAnimationBase::speedPropertyKey: @@ -2168,6 +2190,10 @@ class CoreRegistry case LayoutComponentStyleBase::layoutFlags0PropertyKey: case LayoutComponentStyleBase::layoutFlags1PropertyKey: case LayoutComponentStyleBase::layoutFlags2PropertyKey: + case LayoutComponentStyleBase::scaleTypePropertyKey: + case LayoutComponentStyleBase::animationStyleTypePropertyKey: + case LayoutComponentStyleBase::interpolationTypePropertyKey: + case LayoutComponentStyleBase::interpolatorIdPropertyKey: case ListenerFireEventBase::eventIdPropertyKey: case LayerStateBase::flagsPropertyKey: case ListenerInputChangeBase::inputIdPropertyKey: @@ -2318,6 +2344,7 @@ class CoreRegistry case LayoutComponentStyleBase::flexShrinkPropertyKey: case LayoutComponentStyleBase::flexBasisPropertyKey: case LayoutComponentStyleBase::aspectRatioPropertyKey: + case LayoutComponentStyleBase::interpolationTimePropertyKey: case NestedLinearAnimationBase::mixPropertyKey: case NestedSimpleAnimationBase::speedPropertyKey: case AdvanceableStateBase::speedPropertyKey: @@ -2568,6 +2595,14 @@ class CoreRegistry return object->is(); case LayoutComponentStyleBase::layoutFlags2PropertyKey: return object->is(); + case LayoutComponentStyleBase::scaleTypePropertyKey: + return object->is(); + case LayoutComponentStyleBase::animationStyleTypePropertyKey: + return object->is(); + case LayoutComponentStyleBase::interpolationTypePropertyKey: + return object->is(); + case LayoutComponentStyleBase::interpolatorIdPropertyKey: + return object->is(); case ListenerFireEventBase::eventIdPropertyKey: return object->is(); case LayerStateBase::flagsPropertyKey: @@ -2862,6 +2897,8 @@ class CoreRegistry return object->is(); case LayoutComponentStyleBase::aspectRatioPropertyKey: return object->is(); + case LayoutComponentStyleBase::interpolationTimePropertyKey: + return object->is(); case NestedLinearAnimationBase::mixPropertyKey: return object->is(); case NestedSimpleAnimationBase::speedPropertyKey: diff --git a/include/rive/generated/layout/layout_component_style_base.hpp b/include/rive/generated/layout/layout_component_style_base.hpp index 28dd01b5..60163da9 100644 --- a/include/rive/generated/layout/layout_component_style_base.hpp +++ b/include/rive/generated/layout/layout_component_style_base.hpp @@ -59,6 +59,11 @@ class LayoutComponentStyleBase : public Component static const uint16_t flexShrinkPropertyKey = 522; static const uint16_t flexBasisPropertyKey = 523; static const uint16_t aspectRatioPropertyKey = 524; + static const uint16_t scaleTypePropertyKey = 546; + static const uint16_t animationStyleTypePropertyKey = 589; + static const uint16_t interpolationTypePropertyKey = 590; + static const uint16_t interpolatorIdPropertyKey = 591; + static const uint16_t interpolationTimePropertyKey = 592; private: uint32_t m_LayoutFlags0 = 0x5000412; @@ -91,6 +96,11 @@ class LayoutComponentStyleBase : public Component float m_FlexShrink = 1.0f; float m_FlexBasis = 1.0f; float m_AspectRatio = 0.0f; + uint32_t m_ScaleType = 0; + uint32_t m_AnimationStyleType = 0; + uint32_t m_InterpolationType = 0; + uint32_t m_InterpolatorId = -1; + float m_InterpolationTime = 0.0f; public: inline uint32_t layoutFlags0() const { return m_LayoutFlags0; } @@ -423,6 +433,61 @@ class LayoutComponentStyleBase : public Component aspectRatioChanged(); } + inline uint32_t scaleType() const { return m_ScaleType; } + void scaleType(uint32_t value) + { + if (m_ScaleType == value) + { + return; + } + m_ScaleType = value; + scaleTypeChanged(); + } + + inline uint32_t animationStyleType() const { return m_AnimationStyleType; } + void animationStyleType(uint32_t value) + { + if (m_AnimationStyleType == value) + { + return; + } + m_AnimationStyleType = value; + animationStyleTypeChanged(); + } + + inline uint32_t interpolationType() const { return m_InterpolationType; } + void interpolationType(uint32_t value) + { + if (m_InterpolationType == value) + { + return; + } + m_InterpolationType = value; + interpolationTypeChanged(); + } + + inline uint32_t interpolatorId() const { return m_InterpolatorId; } + void interpolatorId(uint32_t value) + { + if (m_InterpolatorId == value) + { + return; + } + m_InterpolatorId = value; + interpolatorIdChanged(); + } + + inline float interpolationTime() const { return m_InterpolationTime; } + void interpolationTime(float value) + { + if (m_InterpolationTime == value) + { + return; + } + m_InterpolationTime = value; + interpolationTimeChanged(); + } + Core* clone() const override; void copy(const LayoutComponentStyleBase& object) { @@ -456,6 +521,11 @@ class LayoutComponentStyleBase : public Component m_FlexShrink = object.m_FlexShrink; m_FlexBasis = object.m_FlexBasis; m_AspectRatio = object.m_AspectRatio; + m_ScaleType = object.m_ScaleType; + m_AnimationStyleType = object.m_AnimationStyleType; + m_InterpolationType = object.m_InterpolationType; + m_InterpolatorId = object.m_InterpolatorId; + m_InterpolationTime = object.m_InterpolationTime; Component::copy(object); } @@ -553,6 +623,21 @@ class LayoutComponentStyleBase : public Component case aspectRatioPropertyKey: m_AspectRatio = CoreDoubleType::deserialize(reader); return true; + case scaleTypePropertyKey: + m_ScaleType = CoreUintType::deserialize(reader); + return true; + case animationStyleTypePropertyKey: + m_AnimationStyleType = CoreUintType::deserialize(reader); + return true; + case interpolationTypePropertyKey: + m_InterpolationType = CoreUintType::deserialize(reader); + return true; + case interpolatorIdPropertyKey: + m_InterpolatorId = CoreUintType::deserialize(reader); + return true; + case interpolationTimePropertyKey: + m_InterpolationTime = CoreDoubleType::deserialize(reader); + return true; } return Component::deserialize(propertyKey, reader); } @@ -588,6 +673,11 @@ class LayoutComponentStyleBase : public Component virtual void flexShrinkChanged() {} virtual void flexBasisChanged() {} virtual void aspectRatioChanged() {} + virtual void scaleTypeChanged() {} + virtual void animationStyleTypeChanged() {} + virtual void interpolationTypeChanged() {} + virtual void interpolatorIdChanged() {} + virtual void interpolationTimeChanged() {} }; } // namespace rive diff --git a/include/rive/generated/layout_component_absolute_base.hpp b/include/rive/generated/layout_component_absolute_base.hpp deleted file mode 100644 index b61486fe..00000000 --- a/include/rive/generated/layout_component_absolute_base.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _RIVE_ABSOLUTE_LAYOUT_COMPONENT_BASE_HPP_ -#define _RIVE_ABSOLUTE_LAYOUT_COMPONENT_BASE_HPP_ -#include "rive/layout_component.hpp" -namespace rive -{ -class AbsoluteLayoutComponentBase : public LayoutComponent -{ -protected: - typedef LayoutComponent Super; - -public: - static const uint16_t typeKey = 423; - - /// Helper to quickly determine if a core object extends another without RTTI - /// at runtime. - bool isTypeOf(uint16_t typeKey) const override - { - switch (typeKey) - { - case AbsoluteLayoutComponentBase::typeKey: - case LayoutComponentBase::typeKey: - case WorldTransformComponentBase::typeKey: - case ContainerComponentBase::typeKey: - case ComponentBase::typeKey: - return true; - default: - return false; - } - } - - uint16_t coreType() const override { return typeKey; } - - Core* clone() const override; - -protected: -}; -} // namespace rive - -#endif \ No newline at end of file diff --git a/include/rive/layout/layout_component_style.hpp b/include/rive/layout/layout_component_style.hpp index 69335930..4b8c0ffe 100644 --- a/include/rive/layout/layout_component_style.hpp +++ b/include/rive/layout/layout_component_style.hpp @@ -49,12 +49,37 @@ extern BitFieldLoc MinHeightUnitsBits; extern BitFieldLoc MaxWidthUnitsBits; extern BitFieldLoc MaxHeightUnitsBits; +enum class LayoutAnimationStyle : uint8_t +{ + none, + custom, + inherit +}; + +enum class LayoutStyleInterpolation : uint8_t +{ + hold, + linear, + cubic, + elastic +}; + +class KeyFrameInterpolator; class LayoutComponentStyle : public LayoutComponentStyleBase { +private: +#ifdef WITH_RIVE_LAYOUT + KeyFrameInterpolator* m_interpolator; +#endif + public: LayoutComponentStyle() {} #ifdef WITH_RIVE_LAYOUT + StatusCode onAddedDirty(CoreContext* context) override; + KeyFrameInterpolator* interpolator(); + LayoutStyleInterpolation interpolation(); + LayoutAnimationStyle animationStyle(); YGDisplay display(); YGPositionType positionType(); @@ -97,6 +122,7 @@ class LayoutComponentStyle : public LayoutComponentStyleBase #endif void markLayoutNodeDirty(); + void markLayoutStyleDirty(); void layoutFlags0Changed() override; void layoutFlags1Changed() override; diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index 1049e3b1..4a5be758 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -11,6 +11,10 @@ #include namespace rive { + +class AABB; +class KeyFrameInterpolator; + struct LayoutData { #ifdef WITH_RIVE_LAYOUT @@ -19,6 +23,13 @@ struct LayoutData #endif }; +struct LayoutAnimationData +{ + float elapsedSeconds = 0; + AABB fromBounds = AABB(); + AABB toBounds = AABB(); +}; + class LayoutComponent : public LayoutComponentBase { private: @@ -30,6 +41,11 @@ class LayoutComponent : public LayoutComponentBase float m_layoutLocationX = 0; float m_layoutLocationY = 0; + LayoutAnimationData m_animationData; + KeyFrameInterpolator* m_inheritedInterpolator; + LayoutStyleInterpolation m_inheritedInterpolation = LayoutStyleInterpolation::hold; + float m_inheritedInterpolationTime = 0; + #ifdef WITH_RIVE_LAYOUT private: YGNode& layoutNode() { return m_layoutData->node; } @@ -37,6 +53,7 @@ class LayoutComponent : public LayoutComponentBase void syncLayoutChildren(); void propagateSizeToChildren(ContainerComponent* component); AABB findMaxIntrinsicSize(ContainerComponent* component, AABB maxIntrinsicSize); + bool applyInterpolation(double elapsedSeconds); protected: void calculateLayout(); @@ -54,10 +71,33 @@ class LayoutComponent : public LayoutComponentBase void update(ComponentDirt value) override; StatusCode onAddedDirty(CoreContext* context) override; + bool advance(double elapsedSeconds); + bool animates(); + LayoutAnimationStyle animationStyle(); + KeyFrameInterpolator* interpolator(); + LayoutStyleInterpolation interpolation(); + float interpolationTime(); + + void cascadeAnimationStyle(LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime); + void setInheritedInterpolation(LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime); + void clearInheritedInterpolation(); + AABB layoutBounds() + { + return AABB(m_layoutLocationX, + m_layoutLocationY, + m_layoutLocationX + m_layoutSizeWidth, + m_layoutLocationY + m_layoutSizeHeight); + } + #endif void buildDependencies() override; void markLayoutNodeDirty(); + void markLayoutStyleDirty(); void clipChanged() override; void widthChanged() override; void heightChanged() override; diff --git a/include/rive/layout_component_absolute.hpp b/include/rive/layout_component_absolute.hpp deleted file mode 100644 index 955f64c1..00000000 --- a/include/rive/layout_component_absolute.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _RIVE_ABSOLUTE_LAYOUT_COMPONENT_HPP_ -#define _RIVE_ABSOLUTE_LAYOUT_COMPONENT_HPP_ -#include "rive/generated/layout_component_absolute_base.hpp" -#include -namespace rive -{ -class AbsoluteLayoutComponent : public AbsoluteLayoutComponentBase -{ -public: -}; -} // namespace rive - -#endif \ No newline at end of file diff --git a/src/artboard.cpp b/src/artboard.cpp index 6c0fe6a5..4ecf5da7 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -532,6 +532,7 @@ bool Artboard::updateComponents() bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot) { + bool didUpdate = false; m_HasChangedDrawOrderInLastUpdate = false; #ifdef WITH_RIVE_LAYOUT if (!m_dirtyLayout.empty()) @@ -543,12 +544,21 @@ bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot) } m_dirtyLayout.clear(); calculateLayout(); + if (hasDirt(ComponentDirt::LayoutStyle)) + { + cascadeAnimationStyle(interpolation(), interpolator(), interpolationTime()); + } for (auto dep : m_DependencyOrder) { if (dep->is()) { auto layout = dep->as(); layout->updateLayoutBounds(); + if ((dep == this && Super::advance(elapsedSeconds)) || + layout->advance(elapsedSeconds)) + { + didUpdate = true; + } } } } @@ -564,7 +574,10 @@ bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot) { updateDataBinds(); } - bool didUpdate = updateComponents(); + if (updateComponents()) + { + didUpdate = true; + } if (!m_JoysticksApplyBeforeUpdate) { for (auto joystick : m_Joysticks) diff --git a/src/generated/layout_component_absolute_base.cpp b/src/generated/layout_component_absolute_base.cpp deleted file mode 100644 index c35c4a8f..00000000 --- a/src/generated/layout_component_absolute_base.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "rive/generated/layout_component_absolute_base.hpp" -#include "rive/layout_component_absolute.hpp" - -using namespace rive; - -Core* AbsoluteLayoutComponentBase::clone() const -{ - auto cloned = new AbsoluteLayoutComponent(); - cloned->copy(*this); - return cloned; -} diff --git a/src/layout/layout_component_style.cpp b/src/layout/layout_component_style.cpp index c1693f6d..325e92a6 100644 --- a/src/layout/layout_component_style.cpp +++ b/src/layout/layout_component_style.cpp @@ -1,3 +1,5 @@ +#include "rive/animation/keyframe_interpolator.hpp" +#include "rive/core_context.hpp" #include "rive/layout_component.hpp" #include "rive/layout/layout_component_style.hpp" #include @@ -46,6 +48,19 @@ BitFieldLoc rive::MaxWidthUnitsBits = BitFieldLoc(8, 9); BitFieldLoc rive::MaxHeightUnitsBits = BitFieldLoc(10, 11); #ifdef WITH_RIVE_LAYOUT + +KeyFrameInterpolator* LayoutComponentStyle::interpolator() { return m_interpolator; } + +LayoutStyleInterpolation LayoutComponentStyle::interpolation() +{ + return LayoutStyleInterpolation(interpolationType()); +} + +LayoutAnimationStyle LayoutComponentStyle::animationStyle() +{ + return LayoutAnimationStyle(animationStyleType()); +} + YGDisplay LayoutComponentStyle::display() { return YGDisplay(DisplayBits.read(layoutFlags0())); } YGPositionType LayoutComponentStyle::positionType() @@ -208,8 +223,33 @@ void LayoutComponentStyle::markLayoutNodeDirty() parent()->as()->markLayoutNodeDirty(); } } + +void LayoutComponentStyle::markLayoutStyleDirty() +{ + if (parent()->is()) + { + parent()->as()->markLayoutStyleDirty(); + } +} + +StatusCode LayoutComponentStyle::onAddedDirty(CoreContext* context) +{ + auto code = Super::onAddedDirty(context); + if (code != StatusCode::Ok) + { + return code; + } + + auto coreObject = context->resolve(interpolatorId()); + if (coreObject != nullptr && coreObject->is()) + { + m_interpolator = static_cast(coreObject); + } + return StatusCode::Ok; +} #else void LayoutComponentStyle::markLayoutNodeDirty() {} +void LayoutComponentStyle::markLayoutStyleDirty() {} #endif void LayoutComponentStyle::layoutFlags0Changed() { markLayoutNodeDirty(); } diff --git a/src/layout_component.cpp b/src/layout_component.cpp index c9b600fc..402d0f4e 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -1,3 +1,4 @@ +#include "rive/animation/keyframe_interpolator.hpp" #include "rive/artboard.hpp" #include "rive/layout_component.hpp" #include "rive/node.hpp" @@ -21,7 +22,10 @@ void LayoutComponent::buildDependencies() } #ifdef WITH_RIVE_LAYOUT -LayoutComponent::LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())) {} +LayoutComponent::LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())) +{ + layoutNode().getConfig()->setPointScaleFactor(0); +} StatusCode LayoutComponent::onAddedDirty(CoreContext* context) { @@ -39,6 +43,7 @@ StatusCode LayoutComponent::onAddedDirty(CoreContext* context) m_style = static_cast(coreStyle); addChild(m_style); artboard()->markLayoutDirty(this); + markLayoutStyleDirty(); if (parent() != nullptr && parent()->is()) { parent()->as()->syncLayoutChildren(); @@ -237,16 +242,224 @@ void LayoutComponent::updateLayoutBounds() auto top = YGNodeLayoutGetTop(node); auto width = YGNodeLayoutGetWidth(node); auto height = YGNodeLayoutGetHeight(node); - if (left != m_layoutLocationX || top != m_layoutLocationY || width != m_layoutSizeWidth || - height != m_layoutSizeHeight) + if (animates()) + { + auto toBounds = m_animationData.toBounds; + if (left != toBounds.left() || top != toBounds.top() || width != toBounds.width() || + height != toBounds.height()) + { + m_animationData.elapsedSeconds = 0; + m_animationData.fromBounds = AABB(m_layoutLocationX, + m_layoutLocationY, + m_layoutLocationX + this->width(), + m_layoutLocationY + this->height()); + m_animationData.toBounds = AABB(left, top, left + width, top + height); + propagateSize(); + markWorldTransformDirty(); + } + } + else if (left != m_layoutLocationX || top != m_layoutLocationY || width != m_layoutSizeWidth || + height != m_layoutSizeHeight) + { + m_layoutLocationX = left; + m_layoutLocationY = top; + m_layoutSizeWidth = width; + m_layoutSizeHeight = height; + propagateSize(); + markWorldTransformDirty(); + } +} + +bool LayoutComponent::advance(double elapsedSeconds) { return applyInterpolation(elapsedSeconds); } + +bool LayoutComponent::animates() +{ + if (m_style == nullptr) + { + return false; + } + return m_style->positionType() == YGPositionType::YGPositionTypeRelative && + m_style->animationStyle() != LayoutAnimationStyle::none && + interpolation() != LayoutStyleInterpolation::hold && interpolationTime() > 0; +} + +LayoutAnimationStyle LayoutComponent::animationStyle() +{ + if (m_style == nullptr) + { + return LayoutAnimationStyle::none; + } + return m_style->animationStyle(); +} + +KeyFrameInterpolator* LayoutComponent::interpolator() +{ + if (m_style == nullptr) + { + return nullptr; + } + switch (m_style->animationStyle()) + { + case LayoutAnimationStyle::inherit: + return m_inheritedInterpolator != nullptr ? m_inheritedInterpolator + : m_style->interpolator(); + case LayoutAnimationStyle::custom: + return m_style->interpolator(); + default: + return nullptr; + } +} + +LayoutStyleInterpolation LayoutComponent::interpolation() +{ + auto defaultInterpolation = LayoutStyleInterpolation::hold; + if (m_style == nullptr) + { + return defaultInterpolation; + } + switch (m_style->animationStyle()) + { + case LayoutAnimationStyle::inherit: + return m_inheritedInterpolation; + case LayoutAnimationStyle::custom: + return m_style->interpolation(); + default: + return defaultInterpolation; + } +} + +float LayoutComponent::interpolationTime() +{ + if (m_style == nullptr) + { + return 0; + } + switch (m_style->animationStyle()) { + case LayoutAnimationStyle::inherit: + return m_inheritedInterpolationTime; + case LayoutAnimationStyle::custom: + return m_style->interpolationTime(); + default: + return 0; + } +} + +void LayoutComponent::cascadeAnimationStyle(LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime) +{ + if (m_style != nullptr && m_style->animationStyle() == LayoutAnimationStyle::inherit) + { + setInheritedInterpolation(inheritedInterpolation, + inheritedInterpolator, + inheritedInterpolationTime); + } + else + { + clearInheritedInterpolation(); + } + for (auto child : children()) + { + if (child->is()) + { + child->as()->cascadeAnimationStyle(interpolation(), + interpolator(), + interpolationTime()); + } + } +} + +void LayoutComponent::setInheritedInterpolation(LayoutStyleInterpolation inheritedInterpolation, + KeyFrameInterpolator* inheritedInterpolator, + float inheritedInterpolationTime) +{ + m_inheritedInterpolation = inheritedInterpolation; + m_inheritedInterpolator = inheritedInterpolator; + m_inheritedInterpolationTime = inheritedInterpolationTime; +} + +void LayoutComponent::clearInheritedInterpolation() +{ + m_inheritedInterpolation = LayoutStyleInterpolation::hold; + m_inheritedInterpolator = nullptr; + m_inheritedInterpolationTime = 0; +} + +bool LayoutComponent::applyInterpolation(double elapsedSeconds) +{ + if (!animates() || m_style == nullptr || m_animationData.toBounds == layoutBounds()) + { + return false; + } + if (m_animationData.elapsedSeconds >= interpolationTime()) + { + m_layoutLocationX = m_animationData.toBounds.left(); + m_layoutLocationY = m_animationData.toBounds.top(); + m_layoutSizeWidth = m_animationData.toBounds.width(); + m_layoutSizeHeight = m_animationData.toBounds.height(); + m_animationData.elapsedSeconds = 0; + markWorldTransformDirty(); + return false; + } + float f = 1; + if (interpolationTime() > 0) + { + f = m_animationData.elapsedSeconds / interpolationTime(); + } + bool needsAdvance = false; + auto fromBounds = m_animationData.fromBounds; + auto toBounds = m_animationData.toBounds; + auto left = m_layoutLocationX; + auto top = m_layoutLocationY; + auto width = m_layoutSizeWidth; + auto height = m_layoutSizeHeight; + if (toBounds.left() != left || toBounds.top() != top) + { + if (interpolation() == LayoutStyleInterpolation::linear) + { + left = fromBounds.left() + f * (toBounds.left() - fromBounds.left()); + top = fromBounds.top() + f * (toBounds.top() - fromBounds.top()); + } + else + { + if (interpolator() != nullptr) + { + left = interpolator()->transformValue(fromBounds.left(), toBounds.left(), f); + top = interpolator()->transformValue(fromBounds.top(), toBounds.top(), f); + } + } + needsAdvance = true; m_layoutLocationX = left; m_layoutLocationY = top; + } + if (toBounds.width() != width || toBounds.height() != height) + { + if (interpolation() == LayoutStyleInterpolation::linear) + { + width = fromBounds.width() + f * (toBounds.width() - fromBounds.width()); + height = fromBounds.height() + f * (toBounds.height() - fromBounds.height()); + } + else + { + if (interpolator() != nullptr) + { + width = interpolator()->transformValue(fromBounds.width(), toBounds.width(), f); + height = interpolator()->transformValue(fromBounds.height(), toBounds.height(), f); + } + } + needsAdvance = true; m_layoutSizeWidth = width; m_layoutSizeHeight = height; + } + m_animationData.elapsedSeconds = m_animationData.elapsedSeconds + (float)elapsedSeconds; + if (needsAdvance) + { propagateSize(); markWorldTransformDirty(); + markLayoutNodeDirty(); } + return needsAdvance; } void LayoutComponent::markLayoutNodeDirty() @@ -254,8 +467,18 @@ void LayoutComponent::markLayoutNodeDirty() layoutNode().markDirtyAndPropagate(); artboard()->markLayoutDirty(this); } + +void LayoutComponent::markLayoutStyleDirty() +{ + addDirt(ComponentDirt::LayoutStyle); + if (artboard() != this) + { + artboard()->markLayoutStyleDirty(); + } +} #else void LayoutComponent::markLayoutNodeDirty() {} +void LayoutComponent::markLayoutStyleDirty() {} #endif void LayoutComponent::clipChanged() { markLayoutNodeDirty(); } diff --git a/test/layout_test.cpp b/test/layout_test.cpp index c5c07ec6..e7176a13 100644 --- a/test/layout_test.cpp +++ b/test/layout_test.cpp @@ -138,6 +138,6 @@ TEST_CASE("LayoutComponent with intrinsic size gets measured correctly", "[layou auto bounds = text->localBounds(); REQUIRE(bounds.left() == 0); REQUIRE(bounds.top() == 0); - REQUIRE(bounds.width() == 63.0f); - REQUIRE(bounds.height() == 73.0f); + REQUIRE(bounds.width() == 62.48047f); + REQUIRE(bounds.height() == 72.62695f); } From 8edc70fc3bba589daf2ae770c4a92601f52c0cb6 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 21 Jun 2024 16:14:07 +0000 Subject: [PATCH 070/138] Xxxx data binding data context some small code improvements - reorganize code to get things ready for binding text runs - support to bind color two way - fix bug: new data binds not updating if they were created in animate mode Diffs= 9cd8759a0 Xxxx data binding data context (#7454) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/data_bind/data_bind.hpp | 6 ++ include/rive/data_bind/data_bind_context.hpp | 4 +- .../viewmodel/viewmodel_instance_value.hpp | 6 +- src/artboard.cpp | 2 +- src/data_bind/data_bind.cpp | 66 ++++++++++++++++++- src/data_bind/data_bind_context.cpp | 25 +------ src/viewmodel/viewmodel_instance_value.cpp | 4 +- 8 files changed, 81 insertions(+), 34 deletions(-) diff --git a/.rive_head b/.rive_head index bd73d8c3..d6e407c3 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -31f5ee5c480ab9b2c1a0d263305f56bfd943d780 +9cd8759a02aaa45684e80a8d77671c1536ab387d diff --git a/include/rive/data_bind/data_bind.hpp b/include/rive/data_bind/data_bind.hpp index ec9b5aeb..7efbcc81 100644 --- a/include/rive/data_bind/data_bind.hpp +++ b/include/rive/data_bind/data_bind.hpp @@ -1,6 +1,8 @@ #ifndef _RIVE_DATA_BIND_HPP_ #define _RIVE_DATA_BIND_HPP_ #include "rive/generated/data_bind/data_bind_base.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/data_bind/context/context_value.hpp" #include namespace rive { @@ -11,10 +13,14 @@ class DataBind : public DataBindBase StatusCode import(ImportStack& importStack) override; void buildDependencies() override; virtual void updateSourceBinding(); + void update(ComponentDirt value) override; Component* target() { return m_target; }; + virtual void bind(); protected: Component* m_target; + ViewModelInstanceValue* m_Source; + std::unique_ptr m_ContextValue; }; } // namespace rive diff --git a/include/rive/data_bind/data_bind_context.hpp b/include/rive/data_bind/data_bind_context.hpp index 93028b46..113b7fb3 100644 --- a/include/rive/data_bind/data_bind_context.hpp +++ b/include/rive/data_bind/data_bind_context.hpp @@ -11,14 +11,12 @@ class DataBindContext : public DataBindContextBase { protected: std::vector m_SourcePathIdsBuffer; - ViewModelInstanceValue* m_Source; - std::unique_ptr m_ContextValue; public: void update(ComponentDirt value) override; void decodeSourcePathIds(Span value) override; void copySourcePathIds(const DataBindContextBase& object) override; - void bindToContext(); + void bind() override; void updateSourceBinding() override; ViewModelInstanceValue* source() { return m_Source; }; }; diff --git a/include/rive/viewmodel/viewmodel_instance_value.hpp b/include/rive/viewmodel/viewmodel_instance_value.hpp index 7e3d5c7e..484aa8e3 100644 --- a/include/rive/viewmodel/viewmodel_instance_value.hpp +++ b/include/rive/viewmodel/viewmodel_instance_value.hpp @@ -8,7 +8,7 @@ #include namespace rive { -class DataBindContext; +class DataBind; class ViewModelInstance; class ViewModelInstanceValue : public ViewModelInstanceValueBase { @@ -16,14 +16,14 @@ class ViewModelInstanceValue : public ViewModelInstanceValueBase ViewModelProperty* m_ViewModelProperty; protected: - DependencyHelper m_DependencyHelper; + DependencyHelper m_DependencyHelper; void addDirt(ComponentDirt value); public: StatusCode import(ImportStack& importStack) override; void viewModelProperty(ViewModelProperty* value); ViewModelProperty* viewModelProperty(); - void addDependent(DataBindContext* value); + void addDependent(DataBind* value); virtual void setRoot(ViewModelInstance* value); }; } // namespace rive diff --git a/src/artboard.cpp b/src/artboard.cpp index 4ecf5da7..dbd2f6e3 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -973,7 +973,7 @@ void Artboard::internalDataContext(DataContext* value, DataContext* parent, bool { if (dataBind->is()) { - dataBind->as()->bindToContext(); + dataBind->as()->bind(); } } if (isRoot) diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp index 4f59d894..441be603 100644 --- a/src/data_bind/data_bind.cpp +++ b/src/data_bind/data_bind.cpp @@ -2,6 +2,12 @@ #include "rive/data_bind/data_bind_mode.hpp" #include "rive/artboard.hpp" #include "rive/generated/core_registry.hpp" +#include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/context/context_value_number.hpp" +#include "rive/data_bind/context/context_value_string.hpp" +#include "rive/data_bind/context/context_value_enum.hpp" +#include "rive/data_bind/context/context_value_list.hpp" +#include "rive/data_bind/context/context_value_color.hpp" using namespace rive; @@ -40,4 +46,62 @@ void DataBind::buildDependencies() } } -void DataBind::updateSourceBinding() {} \ No newline at end of file +void DataBind::bind() +{ + switch (m_Source->coreType()) + { + case ViewModelInstanceNumberBase::typeKey: + m_ContextValue = rivestd::make_unique(m_Source); + break; + case ViewModelInstanceStringBase::typeKey: + m_ContextValue = rivestd::make_unique(m_Source); + break; + case ViewModelInstanceEnumBase::typeKey: + m_ContextValue = rivestd::make_unique(m_Source); + break; + case ViewModelInstanceListBase::typeKey: + m_ContextValue = rivestd::make_unique(m_Source); + m_ContextValue->update(m_target); + break; + case ViewModelInstanceColorBase::typeKey: + m_ContextValue = rivestd::make_unique(m_Source); + break; + } +} + +void DataBind::update(ComponentDirt value) +{ + if (m_Source != nullptr && m_ContextValue != nullptr) + { + + // Use the ComponentDirt::Components flag to indicate the viewmodel has added or removed + // an element to a list. + if ((value & ComponentDirt::Components) == ComponentDirt::Components) + { + m_ContextValue->update(m_target); + } + if ((value & ComponentDirt::Bindings) == ComponentDirt::Bindings) + { + // TODO: @hernan review how dirt and mode work together. If dirt is not set for + // certain modes, we might be able to skip the mode validation. + auto mode = static_cast(modeValue()); + if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay) + { + m_ContextValue->apply(m_target, propertyKey()); + } + } + } + Super::update(value); +} + +void DataBind::updateSourceBinding() +{ + auto mode = static_cast(modeValue()); + if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + { + if (m_ContextValue != nullptr) + { + m_ContextValue->applyToSource(m_target, propertyKey()); + } + } +} \ No newline at end of file diff --git a/src/data_bind/data_bind_context.cpp b/src/data_bind/data_bind_context.cpp index 77194d4e..a2492265 100644 --- a/src/data_bind/data_bind_context.cpp +++ b/src/data_bind/data_bind_context.cpp @@ -26,7 +26,7 @@ void DataBindContext::copySourcePathIds(const DataBindContextBase& object) m_SourcePathIdsBuffer = object.as()->m_SourcePathIdsBuffer; } -void DataBindContext::bindToContext() +void DataBindContext::bind() { auto dataContext = artboard()->dataContext(); if (dataContext != nullptr) @@ -36,28 +36,7 @@ void DataBindContext::bindToContext() { value->addDependent(this); m_Source = value; - if (m_Source->is()) - { - m_ContextValue = rivestd::make_unique(m_Source); - } - else if (m_Source->is()) - { - m_ContextValue = rivestd::make_unique(m_Source); - } - else if (m_Source->is()) - { - m_ContextValue = rivestd::make_unique(m_Source); - } - else if (m_Source->is()) - { - m_ContextValue = rivestd::make_unique(m_Source); - // TODO: @hernan decide the best place to initialize this - m_ContextValue->update(m_target); - } - else if (m_Source->is()) - { - m_ContextValue = rivestd::make_unique(m_Source); - } + Super::bind(); } } } diff --git a/src/viewmodel/viewmodel_instance_value.cpp b/src/viewmodel/viewmodel_instance_value.cpp index 2e4fac2e..de7bdba0 100644 --- a/src/viewmodel/viewmodel_instance_value.cpp +++ b/src/viewmodel/viewmodel_instance_value.cpp @@ -5,7 +5,7 @@ #include "rive/viewmodel/viewmodel_instance.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/importers/viewmodel_instance_importer.hpp" -#include "rive/data_bind/data_bind_context.hpp" +#include "rive/data_bind/data_bind.hpp" using namespace rive; @@ -28,7 +28,7 @@ void ViewModelInstanceValue::viewModelProperty(ViewModelProperty* value) } ViewModelProperty* ViewModelInstanceValue::viewModelProperty() { return m_ViewModelProperty; } -void ViewModelInstanceValue::addDependent(DataBindContext* value) +void ViewModelInstanceValue::addDependent(DataBind* value) { m_DependencyHelper.addDependent(value); } From 3c092fd250c075e399b306141df658126c3db1be Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 21 Jun 2024 17:48:36 +0000 Subject: [PATCH 071/138] Xxxx databinding add boolean Adding booleans to the list of view model primitives Diffs= e66e242c6 Xxxx databinding add boolean (#7456) Co-authored-by: hernan --- .rive_head | 2 +- .../viewmodel/viewmodel_instance_boolean.json | 29 ++++++++ .../viewmodel/viewmodel_property_boolean.json | 8 +++ .../context/context_value_boolean.hpp | 19 +++++ include/rive/generated/core_registry.hpp | 14 ++++ .../viewmodel_instance_boolean_base.hpp | 71 +++++++++++++++++++ .../viewmodel_property_boolean_base.hpp | 37 ++++++++++ .../viewmodel/viewmodel_instance_boolean.hpp | 14 ++++ .../viewmodel/viewmodel_property_boolean.hpp | 13 ++++ .../context/context_value_boolean.cpp | 26 +++++++ src/data_bind/data_bind.cpp | 4 ++ .../viewmodel_instance_boolean_base.cpp | 11 +++ .../viewmodel_property_boolean_base.cpp | 11 +++ src/viewmodel/viewmodel_instance_boolean.cpp | 10 +++ 14 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 dev/defs/viewmodel/viewmodel_instance_boolean.json create mode 100644 dev/defs/viewmodel/viewmodel_property_boolean.json create mode 100644 include/rive/data_bind/context/context_value_boolean.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp create mode 100644 include/rive/generated/viewmodel/viewmodel_property_boolean_base.hpp create mode 100644 include/rive/viewmodel/viewmodel_instance_boolean.hpp create mode 100644 include/rive/viewmodel/viewmodel_property_boolean.hpp create mode 100644 src/data_bind/context/context_value_boolean.cpp create mode 100644 src/generated/viewmodel/viewmodel_instance_boolean_base.cpp create mode 100644 src/generated/viewmodel/viewmodel_property_boolean_base.cpp create mode 100644 src/viewmodel/viewmodel_instance_boolean.cpp diff --git a/.rive_head b/.rive_head index d6e407c3..85b696c1 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -9cd8759a02aaa45684e80a8d77671c1536ab387d +e66e242c649e3e61f12a3adbd824bcd9a7525a53 diff --git a/dev/defs/viewmodel/viewmodel_instance_boolean.json b/dev/defs/viewmodel/viewmodel_instance_boolean.json new file mode 100644 index 00000000..a3ea1d57 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_instance_boolean.json @@ -0,0 +1,29 @@ +{ + "name": "ViewModelInstanceBoolean", + "key": { + "int": 449, + "string": "viewmodelinstanceboolean" + }, + "extends": "viewmodel/viewmodel_instance_value.json", + "properties": { + "propertyValue": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 593, + "string": "propertyvalue" + }, + "description": "The boolean value." + }, + "playbackValue": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 594, + "string": "playbackvalue" + }, + "runtime": false, + "coop": false + } + } +} \ No newline at end of file diff --git a/dev/defs/viewmodel/viewmodel_property_boolean.json b/dev/defs/viewmodel/viewmodel_property_boolean.json new file mode 100644 index 00000000..a7703463 --- /dev/null +++ b/dev/defs/viewmodel/viewmodel_property_boolean.json @@ -0,0 +1,8 @@ +{ + "name": "ViewModelPropertyBoolean", + "key": { + "int": 448, + "string": "viewmodelpropertyboolean" + }, + "extends": "viewmodel/viewmodel_property.json" +} \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value_boolean.hpp b/include/rive/data_bind/context/context_value_boolean.hpp new file mode 100644 index 00000000..b7a963b9 --- /dev/null +++ b/include/rive/data_bind/context/context_value_boolean.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_BOOLEAN_HPP_ +#define _RIVE_DATA_BIND_CONTEXT_VALUE_BOOLEAN_HPP_ +#include "rive/data_bind/context/context_value.hpp" +namespace rive +{ +class DataBindContextValueBoolean : public DataBindContextValue +{ + +public: + DataBindContextValueBoolean(ViewModelInstanceValue* value); + void apply(Component* component, uint32_t propertyKey) override; + virtual void applyToSource(Component* component, uint32_t propertyKey) override; + +private: + bool m_Value; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index b073d8aa..66dc240e 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -158,6 +158,7 @@ #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_component.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_boolean.hpp" #include "rive/viewmodel/viewmodel_instance_color.hpp" #include "rive/viewmodel/viewmodel_instance_enum.hpp" #include "rive/viewmodel/viewmodel_instance_list.hpp" @@ -167,6 +168,7 @@ #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" #include "rive/viewmodel/viewmodel_property.hpp" +#include "rive/viewmodel/viewmodel_property_boolean.hpp" #include "rive/viewmodel/viewmodel_property_color.hpp" #include "rive/viewmodel/viewmodel_property_enum.hpp" #include "rive/viewmodel/viewmodel_property_list.hpp" @@ -205,12 +207,16 @@ class CoreRegistry return new ViewModelPropertyViewModel(); case ViewModelInstanceBase::typeKey: return new ViewModelInstance(); + case ViewModelPropertyBooleanBase::typeKey: + return new ViewModelPropertyBoolean(); case DataEnumBase::typeKey: return new DataEnum(); case ViewModelPropertyEnumBase::typeKey: return new ViewModelPropertyEnum(); case ViewModelPropertyColorBase::typeKey: return new ViewModelPropertyColor(); + case ViewModelInstanceBooleanBase::typeKey: + return new ViewModelInstanceBoolean(); case ViewModelInstanceListBase::typeKey: return new ViewModelInstanceList(); case ViewModelInstanceNumberBase::typeKey: @@ -455,6 +461,9 @@ class CoreRegistry case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: object->as()->useLinkedArtboard(value); break; + case ViewModelInstanceBooleanBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case TransformComponentConstraintBase::offsetPropertyKey: object->as()->offset(value); break; @@ -1459,6 +1468,8 @@ class CoreRegistry { case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: return object->as()->useLinkedArtboard(); + case ViewModelInstanceBooleanBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case TransformComponentConstraintBase::offsetPropertyKey: return object->as()->offset(); case TransformComponentConstraintBase::doesCopyPropertyKey: @@ -2135,6 +2146,7 @@ class CoreRegistry switch (propertyKey) { case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: + case ViewModelInstanceBooleanBase::propertyValuePropertyKey: case TransformComponentConstraintBase::offsetPropertyKey: case TransformComponentConstraintBase::doesCopyPropertyKey: case TransformComponentConstraintBase::minPropertyKey: @@ -2487,6 +2499,8 @@ class CoreRegistry { case ViewModelInstanceListItemBase::useLinkedArtboardPropertyKey: return object->is(); + case ViewModelInstanceBooleanBase::propertyValuePropertyKey: + return object->is(); case TransformComponentConstraintBase::offsetPropertyKey: return object->is(); case TransformComponentConstraintBase::doesCopyPropertyKey: diff --git a/include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp b/include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp new file mode 100644 index 00000000..5841b6cc --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_BOOLEAN_BASE_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_BOOLEAN_BASE_HPP_ +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +namespace rive +{ +class ViewModelInstanceBooleanBase : public ViewModelInstanceValue +{ +protected: + typedef ViewModelInstanceValue Super; + +public: + static const uint16_t typeKey = 449; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelInstanceBooleanBase::typeKey: + case ViewModelInstanceValueBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 593; + +private: + bool m_PropertyValue = false; + +public: + inline bool propertyValue() const { return m_PropertyValue; } + void propertyValue(bool value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const ViewModelInstanceBooleanBase& object) + { + m_PropertyValue = object.m_PropertyValue; + ViewModelInstanceValue::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreBoolType::deserialize(reader); + return true; + } + return ViewModelInstanceValue::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/viewmodel/viewmodel_property_boolean_base.hpp b/include/rive/generated/viewmodel/viewmodel_property_boolean_base.hpp new file mode 100644 index 00000000..61a8c293 --- /dev/null +++ b/include/rive/generated/viewmodel/viewmodel_property_boolean_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_BOOLEAN_BASE_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_BOOLEAN_BASE_HPP_ +#include "rive/viewmodel/viewmodel_property.hpp" +namespace rive +{ +class ViewModelPropertyBooleanBase : public ViewModelProperty +{ +protected: + typedef ViewModelProperty Super; + +public: + static const uint16_t typeKey = 448; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ViewModelPropertyBooleanBase::typeKey: + case ViewModelPropertyBase::typeKey: + case ViewModelComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance_boolean.hpp b/include/rive/viewmodel/viewmodel_instance_boolean.hpp new file mode 100644 index 00000000..c00c159b --- /dev/null +++ b/include/rive/viewmodel/viewmodel_instance_boolean.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_VIEW_MODEL_INSTANCE_BOOLEAN_HPP_ +#define _RIVE_VIEW_MODEL_INSTANCE_BOOLEAN_HPP_ +#include "rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp" +#include +namespace rive +{ +class ViewModelInstanceBoolean : public ViewModelInstanceBooleanBase +{ +protected: + void propertyValueChanged() override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_property_boolean.hpp b/include/rive/viewmodel/viewmodel_property_boolean.hpp new file mode 100644 index 00000000..c86fb615 --- /dev/null +++ b/include/rive/viewmodel/viewmodel_property_boolean.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_VIEW_MODEL_PROPERTY_BOOLEAN_HPP_ +#define _RIVE_VIEW_MODEL_PROPERTY_BOOLEAN_HPP_ +#include "rive/generated/viewmodel/viewmodel_property_boolean_base.hpp" +#include +namespace rive +{ +class ViewModelPropertyBoolean : public ViewModelPropertyBooleanBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/src/data_bind/context/context_value_boolean.cpp b/src/data_bind/context/context_value_boolean.cpp new file mode 100644 index 00000000..3116aa90 --- /dev/null +++ b/src/data_bind/context/context_value_boolean.cpp @@ -0,0 +1,26 @@ +#include "rive/data_bind/context/context_value_boolean.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindContextValueBoolean::DataBindContextValueBoolean(ViewModelInstanceValue* value) +{ + m_Source = value; +} + +void DataBindContextValueBoolean::apply(Component* target, uint32_t propertyKey) +{ + CoreRegistry::setBool(target, + propertyKey, + m_Source->as()->propertyValue()); +} + +void DataBindContextValueBoolean::applyToSource(Component* target, uint32_t propertyKey) +{ + auto value = CoreRegistry::getBool(target, propertyKey); + if (m_Value != value) + { + m_Value = value; + m_Source->as()->propertyValue(value); + } +} \ No newline at end of file diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp index 441be603..d6f3ce9a 100644 --- a/src/data_bind/data_bind.cpp +++ b/src/data_bind/data_bind.cpp @@ -3,6 +3,7 @@ #include "rive/artboard.hpp" #include "rive/generated/core_registry.hpp" #include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/context/context_value_boolean.hpp" #include "rive/data_bind/context/context_value_number.hpp" #include "rive/data_bind/context/context_value_string.hpp" #include "rive/data_bind/context/context_value_enum.hpp" @@ -66,6 +67,9 @@ void DataBind::bind() case ViewModelInstanceColorBase::typeKey: m_ContextValue = rivestd::make_unique(m_Source); break; + case ViewModelInstanceBooleanBase::typeKey: + m_ContextValue = rivestd::make_unique(m_Source); + break; } } diff --git a/src/generated/viewmodel/viewmodel_instance_boolean_base.cpp b/src/generated/viewmodel/viewmodel_instance_boolean_base.cpp new file mode 100644 index 00000000..641bfecb --- /dev/null +++ b/src/generated/viewmodel/viewmodel_instance_boolean_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_instance_boolean_base.hpp" +#include "rive/viewmodel/viewmodel_instance_boolean.hpp" + +using namespace rive; + +Core* ViewModelInstanceBooleanBase::clone() const +{ + auto cloned = new ViewModelInstanceBoolean(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/viewmodel/viewmodel_property_boolean_base.cpp b/src/generated/viewmodel/viewmodel_property_boolean_base.cpp new file mode 100644 index 00000000..0371e8c6 --- /dev/null +++ b/src/generated/viewmodel/viewmodel_property_boolean_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/viewmodel/viewmodel_property_boolean_base.hpp" +#include "rive/viewmodel/viewmodel_property_boolean.hpp" + +using namespace rive; + +Core* ViewModelPropertyBooleanBase::clone() const +{ + auto cloned = new ViewModelPropertyBoolean(); + cloned->copy(*this); + return cloned; +} diff --git a/src/viewmodel/viewmodel_instance_boolean.cpp b/src/viewmodel/viewmodel_instance_boolean.cpp new file mode 100644 index 00000000..c4e55996 --- /dev/null +++ b/src/viewmodel/viewmodel_instance_boolean.cpp @@ -0,0 +1,10 @@ +#include +#include +#include + +#include "rive/viewmodel/viewmodel_instance_boolean.hpp" +#include "rive/component_dirt.hpp" + +using namespace rive; + +void ViewModelInstanceBoolean::propertyValueChanged() { addDirt(ComponentDirt::Bindings); } \ No newline at end of file From bb814c306a8a3f61ac4f6caa5397482753a83a4c Mon Sep 17 00:00:00 2001 From: bodymovin Date: Thu, 27 Jun 2024 16:45:15 +0000 Subject: [PATCH 072/138] change how viewmodel instances target their viewmodel we don't call onAddedDirty to viewmodel instances because they don't belong to an artboard. So this PR changes how they target their viewmodel reference. Diffs= aa390d5dc change how viewmodel instances target their viewmodel (#7468) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/viewmodel/viewmodel_instance.hpp | 3 +-- src/viewmodel/viewmodel.cpp | 6 +++++- src/viewmodel/viewmodel_instance.cpp | 19 ++----------------- 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/.rive_head b/.rive_head index 85b696c1..6183a829 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e66e242c649e3e61f12a3adbd824bcd9a7525a53 +aa390d5dc521f5e99605bf84cab8853e5bd44910 diff --git a/include/rive/viewmodel/viewmodel_instance.hpp b/include/rive/viewmodel/viewmodel_instance.hpp index 3115dc41..f5ecd5ad 100644 --- a/include/rive/viewmodel/viewmodel_instance.hpp +++ b/include/rive/viewmodel/viewmodel_instance.hpp @@ -19,13 +19,12 @@ class ViewModelInstance : public ViewModelInstanceBase ViewModelInstanceValue* propertyValue(const std::string& name); std::vector propertyValues(); void viewModel(ViewModel* value); - ViewModel* viewModel(); + ViewModel* viewModel() const; void onComponentDirty(Component* component); void setAsRoot(); void setRoot(ViewModelInstance* value); Core* clone() const override; StatusCode import(ImportStack& importStack) override; - StatusCode onAddedDirty(CoreContext* context) override; }; } // namespace rive diff --git a/src/viewmodel/viewmodel.cpp b/src/viewmodel/viewmodel.cpp index 7e764b94..3d9ecfa2 100644 --- a/src/viewmodel/viewmodel.cpp +++ b/src/viewmodel/viewmodel.cpp @@ -32,7 +32,11 @@ ViewModelProperty* ViewModel::property(const std::string& name) return nullptr; } -void ViewModel::addInstance(ViewModelInstance* value) { m_Instances.push_back(value); } +void ViewModel::addInstance(ViewModelInstance* value) +{ + m_Instances.push_back(value); + value->viewModel(this); +} ViewModelInstance* ViewModel::defaultInstance() { return m_Instances[defaultInstanceId()]; } diff --git a/src/viewmodel/viewmodel_instance.cpp b/src/viewmodel/viewmodel_instance.cpp index bac68826..f3e741d5 100644 --- a/src/viewmodel/viewmodel_instance.cpp +++ b/src/viewmodel/viewmodel_instance.cpp @@ -15,22 +15,6 @@ void ViewModelInstance::addValue(ViewModelInstanceValue* value) m_PropertyValues.push_back(value); } -StatusCode ViewModelInstance::onAddedDirty(CoreContext* context) -{ - StatusCode result = Super::onAddedDirty(context); - if (result != StatusCode::Ok) - { - return result; - } - auto coreObject = context->resolve(viewModelId()); - if (coreObject != nullptr && coreObject->is()) - { - m_ViewModel = static_cast(coreObject); - } - - return StatusCode::Ok; -} - ViewModelInstanceValue* ViewModelInstance::propertyValue(const uint32_t id) { for (auto value : m_PropertyValues) @@ -61,7 +45,7 @@ ViewModelInstanceValue* ViewModelInstance::propertyValue(const std::string& name void ViewModelInstance::viewModel(ViewModel* value) { m_ViewModel = value; } -ViewModel* ViewModelInstance::viewModel() { return m_ViewModel; } +ViewModel* ViewModelInstance::viewModel() const { return m_ViewModel; } void ViewModelInstance::onComponentDirty(Component* component) {} @@ -89,6 +73,7 @@ Core* ViewModelInstance::clone() const auto clonedValue = propertyValue->clone()->as(); cloned->addValue(clonedValue); } + cloned->viewModel(viewModel()); return cloned; } From 60ca97d3a4088ce76fc6f7e2094415b52ef7c461 Mon Sep 17 00:00:00 2001 From: philter Date: Thu, 27 Jun 2024 18:26:02 +0000 Subject: [PATCH 073/138] Add yoga to thumbnail generator build Diffs= 09ccc9ebb Add yoga to thumbnail generator build (#7494) Co-authored-by: Philip Chung --- .rive_head | 2 +- skia/thumbnail_generator/build.sh | 4 ++-- skia/thumbnail_generator/build/premake5.lua | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 6183a829..8b76ff4b 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -aa390d5dc521f5e99605bf84cab8853e5bd44910 +09ccc9ebbc43c168b96362a02ce8c5a587bdb72b diff --git a/skia/thumbnail_generator/build.sh b/skia/thumbnail_generator/build.sh index 3fb31108..34de3fd1 100755 --- a/skia/thumbnail_generator/build.sh +++ b/skia/thumbnail_generator/build.sh @@ -26,7 +26,7 @@ elif [ "$OPTION" = "clean" ]; then echo Cleaning project ... premake5 clean --scripts="$RIVE_RUNTIME_DIR/build" elif [ "$OPTION" = "release" ]; then - premake5 gmake --scripts="$RIVE_RUNTIME_DIR/build" --with_rive_text && make config=release -j7 + premake5 gmake --scripts="$RIVE_RUNTIME_DIR/build" --with_rive_text --with_rive_layout && make config=release -j7 else - premake5 gmake --scripts="$RIVE_RUNTIME_DIR/build" --with_rive_text && make -j7 + premake5 gmake --scripts="$RIVE_RUNTIME_DIR/build" --with_rive_text --with_rive_layout && make -j7 fi diff --git a/skia/thumbnail_generator/build/premake5.lua b/skia/thumbnail_generator/build/premake5.lua index 66fb3d7c..40171376 100644 --- a/skia/thumbnail_generator/build/premake5.lua +++ b/skia/thumbnail_generator/build/premake5.lua @@ -70,6 +70,15 @@ defines({ 'RELEASE' }) defines({ 'NDEBUG' }) optimize('On') +filter({ 'options:with_rive_layout' }) + do + defines({ 'YOGA_EXPORT=' }) + includedirs({ yoga }) + links({ + 'rive_yoga', + }) + end + -- Clean Function -- newaction({ trigger = 'clean', From e438959e2f3b7d6d1524e3271244eb8dc8ed6845 Mon Sep 17 00:00:00 2001 From: philter Date: Thu, 27 Jun 2024 19:35:30 +0000 Subject: [PATCH 074/138] Miscellaneous Layout UX Fixes - Fixes issues with edge constraints UX not updating - Fixes issue with absolute/relative toggle not updating - Fixes bug with incorrect point value when moving edge constraints to Left+Right and Top+Bottom - Fix getting into bad state with inherited interpolator - Fix layout animation advance bug - Force layout bounds to be updated when parent changes (fixes a bug where relative layoutcomponents weren't updating because left/top value doesnt change when reparenting) Diffs= 6f29a9c0c Miscellaneous Layout UX Fixes (#7491) Co-authored-by: Philip Chung --- .rive_head | 2 +- src/artboard.cpp | 2 +- src/layout_component.cpp | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 8b76ff4b..f8f1b580 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -09ccc9ebbc43c168b96362a02ce8c5a587bdb72b +6f29a9c0c368f94a38e8077343359fdaa97663e6 diff --git a/src/artboard.cpp b/src/artboard.cpp index dbd2f6e3..25aa369d 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -555,7 +555,7 @@ bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot) auto layout = dep->as(); layout->updateLayoutBounds(); if ((dep == this && Super::advance(elapsedSeconds)) || - layout->advance(elapsedSeconds)) + (dep != this && layout->advance(elapsedSeconds))) { didUpdate = true; } diff --git a/src/layout_component.cpp b/src/layout_component.cpp index 402d0f4e..bf32da95 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -470,6 +470,7 @@ void LayoutComponent::markLayoutNodeDirty() void LayoutComponent::markLayoutStyleDirty() { + clearInheritedInterpolation(); addDirt(ComponentDirt::LayoutStyle); if (artboard() != this) { From b9ff2f46d709334d506ec4a769520b153908b014 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 28 Jun 2024 19:37:39 +0000 Subject: [PATCH 075/138] disable fallback font during artboard rendering fixes #7479 The reason why the text looks different is that the editor uses a default font if it doesn't find a codepoint in the style defined font. For example, in the font SF Pro, the symbol carriage return (\r) doesn't have a codepoint, but it does in the default font, which generates a new text run. Share links, or our video recorder, don't have a default font so they skip that symbol. This issue could happen with any other symbol that isn't found in the style font, so we decided to disable default fonts when rendering artboard text to guarantee they will look the same as at export time. Diffs= 1adf3dbf4 disable fallback font during artboard rendering (#7480) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/text_engine.hpp | 1 + src/text/font_hb.cpp | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index f8f1b580..b0507840 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -6f29a9c0c368f94a38e8077343359fdaa97663e6 +1adf3dbf4acbba7560e6e25986de126a0ca11c49 diff --git a/include/rive/text_engine.hpp b/include/rive/text_engine.hpp index d244f045..a0ccd637 100644 --- a/include/rive/text_engine.hpp +++ b/include/rive/text_engine.hpp @@ -169,6 +169,7 @@ class Font : public RefCnt using FallbackProc = rive::rcp (*)(rive::Span); static FallbackProc gFallbackProc; + static bool gFallbackProcEnabled; protected: Font(const LineMetrics& lm) : m_lineMetrics(lm) {} diff --git a/src/text/font_hb.cpp b/src/text/font_hb.cpp index 2bb77e6b..8bd2324d 100644 --- a/src/text/font_hb.cpp +++ b/src/text/font_hb.cpp @@ -22,6 +22,8 @@ extern "C" // Initialized to null. Client can set this to a callback. rive::Font::FallbackProc rive::Font::gFallbackProc; +bool rive::Font::gFallbackProcEnabled = true; + rive::rcp HBFont::Decode(rive::Span span) { auto blob = hb_blob_create_or_fail((const char*)span.data(), @@ -554,7 +556,7 @@ rive::SimpleArray HBFont::onShapeText(rive::Span 0) { From c7176bd69c671454c25c2096988fafdbaba71bba Mon Sep 17 00:00:00 2001 From: philter Date: Sat, 29 Jun 2024 01:23:03 +0000 Subject: [PATCH 076/138] Layout bitfield to props with keying - Move layout styles previously in bitfields to core properties - Add KeyFrameUint for keying int values (hold keyframes) - Add alignment property that can compute the layout properties related to alignment at runtime rather than storing them - Add ComboBox in the keyed object hierarchy which displays style related enum values https://github.com/rive-app/rive/assets/186340/ec2ecbde-e539-40cc-b964-2791ad28cc22 Diffs= e5db5a652 Layout bitfield to props with keying (#7478) Co-authored-by: Philip Chung --- .rive_head | 2 +- dev/defs/animation/keyframe_uint.json | 19 + dev/defs/layout/layout_component_style.json | 386 +++++++++- include/rive/animation/keyframe_uint.hpp | 19 + include/rive/artboard.hpp | 11 + .../animation/keyframe_uint_base.hpp | 72 ++ include/rive/generated/core_registry.hpp | 371 +++++++-- .../layout/layout_component_style_base.hpp | 703 ++++++++++++++++-- .../rive/layout/layout_component_style.hpp | 99 +-- include/rive/layout_component.hpp | 9 +- src/animation/keyframe_uint.cpp | 18 + .../animation/keyframe_uint_base.cpp | 11 + src/layout/layout_component_style.cpp | 241 ++---- src/layout_component.cpp | 96 ++- test/assets/layout/layout_center.riv | Bin 220 -> 289 bytes test/assets/layout/layout_horizontal.riv | Bin 361 -> 470 bytes test/assets/layout/layout_horizontal_gaps.riv | Bin 374 -> 482 bytes test/assets/layout/layout_horizontal_wrap.riv | Bin 605 -> 764 bytes test/assets/layout/layout_vertical.riv | Bin 369 -> 479 bytes test/assets/layout/measure_tests.riv | Bin 806365 -> 805981 bytes 20 files changed, 1714 insertions(+), 343 deletions(-) create mode 100644 dev/defs/animation/keyframe_uint.json create mode 100644 include/rive/animation/keyframe_uint.hpp create mode 100644 include/rive/generated/animation/keyframe_uint_base.hpp create mode 100644 src/animation/keyframe_uint.cpp create mode 100644 src/generated/animation/keyframe_uint_base.cpp diff --git a/.rive_head b/.rive_head index b0507840..a74cdfb5 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -1adf3dbf4acbba7560e6e25986de126a0ca11c49 +e5db5a652fedb8dd8c9708f02536e23ab12210d9 diff --git a/dev/defs/animation/keyframe_uint.json b/dev/defs/animation/keyframe_uint.json new file mode 100644 index 00000000..2a0fe0eb --- /dev/null +++ b/dev/defs/animation/keyframe_uint.json @@ -0,0 +1,19 @@ +{ + "name": "KeyFrameUint", + "key": { + "int": 450, + "string": "keyframeuint" + }, + "extends": "animation/interpolating_keyframe.json", + "properties": { + "value": { + "type": "uint", + "typeRuntime": "uint", + "initialValue": "0", + "key": { + "int": 631, + "string": "value" + } + } + } +} \ No newline at end of file diff --git a/dev/defs/layout/layout_component_style.json b/dev/defs/layout/layout_component_style.json index 194601b8..9bddf110 100644 --- a/dev/defs/layout/layout_component_style.json +++ b/dev/defs/layout/layout_component_style.json @@ -6,33 +6,6 @@ }, "extends": "component.json", "properties": { - "layoutFlags0": { - "type": "uint", - "initialValue": "0x5000412", - "key": { - "int": 495, - "string": "layoutflags0" - }, - "description": "First BitFlags for layout styles." - }, - "layoutFlags1": { - "type": "uint", - "initialValue": "0x00", - "key": { - "int": 496, - "string": "layoutflags1" - }, - "description": "Second BitFlags for layout styles." - }, - "layoutFlags2": { - "type": "uint", - "initialValue": "0x00", - "key": { - "int": 497, - "string": "layoutflags2" - }, - "description": "Third BitFlags for layout styles." - }, "gapHorizontal": { "type": "double", "initialValue": "0", @@ -103,6 +76,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutborder", "key": { "int": 504, "string": "borderleft" @@ -113,6 +87,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutborder", "key": { "int": 505, "string": "borderright" @@ -123,6 +98,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutborder", "key": { "int": 506, "string": "bordertop" @@ -133,6 +109,7 @@ "type": "double", "initialValue": "0", "animates": true, + "group": "layoutborder", "key": { "int": 507, "string": "borderbottom" @@ -348,6 +325,15 @@ "string": "scaletype" } }, + "layoutAlignmentType": { + "type": "uint", + "initialValue": "0", + "animates": true, + "key": { + "int": 632, + "string": "layoutalignmenttype" + } + }, "animationStyleType": { "type": "uint", "initialValue": "0", @@ -385,6 +371,352 @@ "string": "interpolationtime" }, "description": "The time over which the interpolator applies." + }, + "displayValue": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 596, + "string": "displayvalue" + }, + "description": "" + }, + "positionTypeValue": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 597, + "string": "positiontypevalue" + }, + "description": "" + }, + "flexDirectionValue": { + "type": "uint", + "initialValue": "2", + "animates": true, + "key": { + "int": 598, + "string": "flexdirectionvalue" + }, + "description": "Flex dir" + }, + "directionValue": { + "type": "uint", + "initialValue": "0", + "animates": true, + "key": { + "int": 599, + "string": "directionvalue" + }, + "description": "" + }, + "alignContentValue": { + "type": "uint", + "initialValue": "0", + "animates": true, + "key": { + "int": 600, + "string": "aligncontentvalue" + }, + "description": "" + }, + "alignItemsValue": { + "type": "uint", + "initialValue": "1", + "animates": true, + "key": { + "int": 601, + "string": "alignitemsvalue" + }, + "description": "" + }, + "alignSelfValue": { + "type": "uint", + "initialValue": "0", + "animates": true, + "key": { + "int": 602, + "string": "alignselfvalue" + }, + "description": "" + }, + "justifyContentValue": { + "type": "uint", + "initialValue": "0", + "animates": true, + "key": { + "int": 603, + "string": "justifycontentvalue" + }, + "description": "" + }, + "flexWrapValue": { + "type": "uint", + "initialValue": "0", + "animates": true, + "key": { + "int": 604, + "string": "flexwrapvalue" + }, + "description": "" + }, + "overflowValue": { + "type": "uint", + "initialValue": "0", + "animates": true, + "key": { + "int": 605, + "string": "overflowvalue" + }, + "description": "" + }, + "intrinsicallySizedValue": { + "type": "bool", + "initialValue": "false", + "animates": true, + "key": { + "int": 606, + "string": "intrinsicallysizedvalue" + }, + "description": "" + }, + "widthUnitsValue": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 607, + "string": "widthunitsvalue" + }, + "description": "" + }, + "heightUnitsValue": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 608, + "string": "heightunitsvalue" + }, + "description": "" + }, + "borderLeftUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutborder", + "key": { + "int": 609, + "string": "borderleftunitsvalue" + }, + "description": "" + }, + "borderRightUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutborder", + "key": { + "int": 610, + "string": "borderrightunitsvalue" + }, + "description": "" + }, + "borderTopUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutborder", + "key": { + "int": 611, + "string": "bordertopunitsvalue" + }, + "description": "" + }, + "borderBottomUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutborder", + "key": { + "int": 612, + "string": "borderbottomunitsvalue" + }, + "description": "" + }, + "marginLeftUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmargin", + "key": { + "int": 613, + "string": "marginleftunitsvalue" + }, + "description": "" + }, + "marginRightUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmargin", + "key": { + "int": 614, + "string": "marginrightunitsvalue" + }, + "description": "" + }, + "marginTopUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmargin", + "key": { + "int": 615, + "string": "margintopunitsvalue" + }, + "description": "" + }, + "marginBottomUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmargin", + "key": { + "int": 616, + "string": "marginbottomunitsvalue" + }, + "description": "" + }, + "paddingLeftUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutpadding", + "key": { + "int": 617, + "string": "paddingleftunitsvalue" + }, + "description": "" + }, + "paddingRightUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutpadding", + "key": { + "int": 618, + "string": "paddingrightunitsvalue" + }, + "description": "" + }, + "paddingTopUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutpadding", + "key": { + "int": 619, + "string": "paddingtopunitsvalue" + }, + "description": "" + }, + "paddingBottomUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutpadding", + "key": { + "int": 620, + "string": "paddingbottomunitsvalue" + }, + "description": "" + }, + "positionLeftUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutposition", + "key": { + "int": 621, + "string": "positionleftunitsvalue" + }, + "description": "" + }, + "positionRightUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutposition", + "key": { + "int": 622, + "string": "positionrightunitsvalue" + }, + "description": "" + }, + "positionTopUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutposition", + "key": { + "int": 623, + "string": "positiontopunitsvalue" + }, + "description": "" + }, + "positionBottomUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutposition", + "key": { + "int": 624, + "string": "positionbottomunitsvalue" + }, + "description": "" + }, + "gapHorizontalUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutgap", + "key": { + "int": 625, + "string": "gaphorizontalunitsvalue" + }, + "description": "" + }, + "gapVerticalUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutgap", + "key": { + "int": 626, + "string": "gapverticalunitsvalue" + }, + "description": "" + }, + "minWidthUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmin", + "key": { + "int": 627, + "string": "minwidthunitsvalue" + }, + "description": "" + }, + "minHeightUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmin", + "key": { + "int": 628, + "string": "minheightunitsvalue" + }, + "description": "" + }, + "maxWidthUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmax", + "key": { + "int": 629, + "string": "maxwidthunitsvalue" + }, + "description": "" + }, + "maxHeightUnitsValue": { + "type": "uint", + "initialValue": "0", + "group": "layoutmax", + "key": { + "int": 630, + "string": "maxheightunitsvalue" + }, + "description": "" } } } \ No newline at end of file diff --git a/include/rive/animation/keyframe_uint.hpp b/include/rive/animation/keyframe_uint.hpp new file mode 100644 index 00000000..2b398de3 --- /dev/null +++ b/include/rive/animation/keyframe_uint.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_KEY_FRAME_UINT_HPP_ +#define _RIVE_KEY_FRAME_UINT_HPP_ +#include "rive/generated/animation/keyframe_uint_base.hpp" +#include +namespace rive +{ +class KeyFrameUint : public KeyFrameUintBase +{ +public: + void apply(Core* object, int propertyKey, float mix) override; + void applyInterpolation(Core* object, + int propertyKey, + float seconds, + const KeyFrame* nextFrame, + float mix) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index ad869a98..1051af9b 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -124,6 +124,17 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta m_dirtyLayout.insert(layoutComponent); } +#ifdef WITH_RIVE_LAYOUT + AABB layoutBounds() override + { + if (!hasLayoutMeasurements()) + { + return AABB(x(), y(), x() + width(), y() + height()); + } + return Super::layoutBounds(); + } +#endif + bool advance(double elapsedSeconds); bool advanceInternal(double elapsedSeconds, bool isRoot); bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; }; diff --git a/include/rive/generated/animation/keyframe_uint_base.hpp b/include/rive/generated/animation/keyframe_uint_base.hpp new file mode 100644 index 00000000..cdf0bd13 --- /dev/null +++ b/include/rive/generated/animation/keyframe_uint_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_KEY_FRAME_UINT_BASE_HPP_ +#define _RIVE_KEY_FRAME_UINT_BASE_HPP_ +#include "rive/animation/interpolating_keyframe.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class KeyFrameUintBase : public InterpolatingKeyFrame +{ +protected: + typedef InterpolatingKeyFrame Super; + +public: + static const uint16_t typeKey = 450; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case KeyFrameUintBase::typeKey: + case InterpolatingKeyFrameBase::typeKey: + case KeyFrameBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 631; + +private: + uint32_t m_Value = 0; + +public: + inline uint32_t value() const { return m_Value; } + void value(uint32_t value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const KeyFrameUintBase& object) + { + m_Value = object.m_Value; + InterpolatingKeyFrame::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreUintType::deserialize(reader); + return true; + } + return InterpolatingKeyFrame::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 66dc240e..519c0641 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -29,6 +29,7 @@ #include "rive/animation/keyframe_id.hpp" #include "rive/animation/keyframe_interpolator.hpp" #include "rive/animation/keyframe_string.hpp" +#include "rive/animation/keyframe_uint.hpp" #include "rive/animation/layer_state.hpp" #include "rive/animation/linear_animation.hpp" #include "rive/animation/listener_action.hpp" @@ -255,6 +256,8 @@ class CoreRegistry return new LayoutComponentStyle(); case ListenerFireEventBase::typeKey: return new ListenerFireEvent(); + case KeyFrameUintBase::typeKey: + return new KeyFrameUint(); case NestedSimpleAnimationBase::typeKey: return new NestedSimpleAnimation(); case AnimationStateBase::typeKey: @@ -494,6 +497,9 @@ class CoreRegistry case FollowPathConstraintBase::offsetPropertyKey: object->as()->offset(value); break; + case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: + object->as()->intrinsicallySizedValue(value); + break; case NestedSimpleAnimationBase::isPlayingPropertyKey: object->as()->isPlaying(value); break; @@ -623,18 +629,12 @@ class CoreRegistry case SoloBase::activeComponentIdPropertyKey: object->as()->activeComponentId(value); break; - case LayoutComponentStyleBase::layoutFlags0PropertyKey: - object->as()->layoutFlags0(value); - break; - case LayoutComponentStyleBase::layoutFlags1PropertyKey: - object->as()->layoutFlags1(value); - break; - case LayoutComponentStyleBase::layoutFlags2PropertyKey: - object->as()->layoutFlags2(value); - break; case LayoutComponentStyleBase::scaleTypePropertyKey: object->as()->scaleType(value); break; + case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: + object->as()->layoutAlignmentType(value); + break; case LayoutComponentStyleBase::animationStyleTypePropertyKey: object->as()->animationStyleType(value); break; @@ -644,12 +644,126 @@ class CoreRegistry case LayoutComponentStyleBase::interpolatorIdPropertyKey: object->as()->interpolatorId(value); break; + case LayoutComponentStyleBase::displayValuePropertyKey: + object->as()->displayValue(value); + break; + case LayoutComponentStyleBase::positionTypeValuePropertyKey: + object->as()->positionTypeValue(value); + break; + case LayoutComponentStyleBase::flexDirectionValuePropertyKey: + object->as()->flexDirectionValue(value); + break; + case LayoutComponentStyleBase::directionValuePropertyKey: + object->as()->directionValue(value); + break; + case LayoutComponentStyleBase::alignContentValuePropertyKey: + object->as()->alignContentValue(value); + break; + case LayoutComponentStyleBase::alignItemsValuePropertyKey: + object->as()->alignItemsValue(value); + break; + case LayoutComponentStyleBase::alignSelfValuePropertyKey: + object->as()->alignSelfValue(value); + break; + case LayoutComponentStyleBase::justifyContentValuePropertyKey: + object->as()->justifyContentValue(value); + break; + case LayoutComponentStyleBase::flexWrapValuePropertyKey: + object->as()->flexWrapValue(value); + break; + case LayoutComponentStyleBase::overflowValuePropertyKey: + object->as()->overflowValue(value); + break; + case LayoutComponentStyleBase::widthUnitsValuePropertyKey: + object->as()->widthUnitsValue(value); + break; + case LayoutComponentStyleBase::heightUnitsValuePropertyKey: + object->as()->heightUnitsValue(value); + break; + case LayoutComponentStyleBase::borderLeftUnitsValuePropertyKey: + object->as()->borderLeftUnitsValue(value); + break; + case LayoutComponentStyleBase::borderRightUnitsValuePropertyKey: + object->as()->borderRightUnitsValue(value); + break; + case LayoutComponentStyleBase::borderTopUnitsValuePropertyKey: + object->as()->borderTopUnitsValue(value); + break; + case LayoutComponentStyleBase::borderBottomUnitsValuePropertyKey: + object->as()->borderBottomUnitsValue(value); + break; + case LayoutComponentStyleBase::marginLeftUnitsValuePropertyKey: + object->as()->marginLeftUnitsValue(value); + break; + case LayoutComponentStyleBase::marginRightUnitsValuePropertyKey: + object->as()->marginRightUnitsValue(value); + break; + case LayoutComponentStyleBase::marginTopUnitsValuePropertyKey: + object->as()->marginTopUnitsValue(value); + break; + case LayoutComponentStyleBase::marginBottomUnitsValuePropertyKey: + object->as()->marginBottomUnitsValue(value); + break; + case LayoutComponentStyleBase::paddingLeftUnitsValuePropertyKey: + object->as()->paddingLeftUnitsValue(value); + break; + case LayoutComponentStyleBase::paddingRightUnitsValuePropertyKey: + object->as()->paddingRightUnitsValue(value); + break; + case LayoutComponentStyleBase::paddingTopUnitsValuePropertyKey: + object->as()->paddingTopUnitsValue(value); + break; + case LayoutComponentStyleBase::paddingBottomUnitsValuePropertyKey: + object->as()->paddingBottomUnitsValue(value); + break; + case LayoutComponentStyleBase::positionLeftUnitsValuePropertyKey: + object->as()->positionLeftUnitsValue(value); + break; + case LayoutComponentStyleBase::positionRightUnitsValuePropertyKey: + object->as()->positionRightUnitsValue(value); + break; + case LayoutComponentStyleBase::positionTopUnitsValuePropertyKey: + object->as()->positionTopUnitsValue(value); + break; + case LayoutComponentStyleBase::positionBottomUnitsValuePropertyKey: + object->as()->positionBottomUnitsValue(value); + break; + case LayoutComponentStyleBase::gapHorizontalUnitsValuePropertyKey: + object->as()->gapHorizontalUnitsValue(value); + break; + case LayoutComponentStyleBase::gapVerticalUnitsValuePropertyKey: + object->as()->gapVerticalUnitsValue(value); + break; + case LayoutComponentStyleBase::minWidthUnitsValuePropertyKey: + object->as()->minWidthUnitsValue(value); + break; + case LayoutComponentStyleBase::minHeightUnitsValuePropertyKey: + object->as()->minHeightUnitsValue(value); + break; + case LayoutComponentStyleBase::maxWidthUnitsValuePropertyKey: + object->as()->maxWidthUnitsValue(value); + break; + case LayoutComponentStyleBase::maxHeightUnitsValuePropertyKey: + object->as()->maxHeightUnitsValue(value); + break; case ListenerFireEventBase::eventIdPropertyKey: object->as()->eventId(value); break; case LayerStateBase::flagsPropertyKey: object->as()->flags(value); break; + case KeyFrameBase::framePropertyKey: + object->as()->frame(value); + break; + case InterpolatingKeyFrameBase::interpolationTypePropertyKey: + object->as()->interpolationType(value); + break; + case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: + object->as()->interpolatorId(value); + break; + case KeyFrameUintBase::valuePropertyKey: + object->as()->value(value); + break; case ListenerInputChangeBase::inputIdPropertyKey: object->as()->inputId(value); break; @@ -689,15 +803,6 @@ class CoreRegistry case StateMachineListenerBase::eventIdPropertyKey: object->as()->eventId(value); break; - case KeyFrameBase::framePropertyKey: - object->as()->frame(value); - break; - case InterpolatingKeyFrameBase::interpolationTypePropertyKey: - object->as()->interpolationType(value); - break; - case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: - object->as()->interpolatorId(value); - break; case KeyFrameIdBase::valuePropertyKey: object->as()->value(value); break; @@ -1490,6 +1595,8 @@ class CoreRegistry return object->as()->orient(); case FollowPathConstraintBase::offsetPropertyKey: return object->as()->offset(); + case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: + return object->as()->intrinsicallySizedValue(); case NestedSimpleAnimationBase::isPlayingPropertyKey: return object->as()->isPlaying(); case KeyFrameBoolBase::valuePropertyKey: @@ -1579,24 +1686,96 @@ class CoreRegistry return object->as()->animationId(); case SoloBase::activeComponentIdPropertyKey: return object->as()->activeComponentId(); - case LayoutComponentStyleBase::layoutFlags0PropertyKey: - return object->as()->layoutFlags0(); - case LayoutComponentStyleBase::layoutFlags1PropertyKey: - return object->as()->layoutFlags1(); - case LayoutComponentStyleBase::layoutFlags2PropertyKey: - return object->as()->layoutFlags2(); case LayoutComponentStyleBase::scaleTypePropertyKey: return object->as()->scaleType(); + case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: + return object->as()->layoutAlignmentType(); case LayoutComponentStyleBase::animationStyleTypePropertyKey: return object->as()->animationStyleType(); case LayoutComponentStyleBase::interpolationTypePropertyKey: return object->as()->interpolationType(); case LayoutComponentStyleBase::interpolatorIdPropertyKey: return object->as()->interpolatorId(); + case LayoutComponentStyleBase::displayValuePropertyKey: + return object->as()->displayValue(); + case LayoutComponentStyleBase::positionTypeValuePropertyKey: + return object->as()->positionTypeValue(); + case LayoutComponentStyleBase::flexDirectionValuePropertyKey: + return object->as()->flexDirectionValue(); + case LayoutComponentStyleBase::directionValuePropertyKey: + return object->as()->directionValue(); + case LayoutComponentStyleBase::alignContentValuePropertyKey: + return object->as()->alignContentValue(); + case LayoutComponentStyleBase::alignItemsValuePropertyKey: + return object->as()->alignItemsValue(); + case LayoutComponentStyleBase::alignSelfValuePropertyKey: + return object->as()->alignSelfValue(); + case LayoutComponentStyleBase::justifyContentValuePropertyKey: + return object->as()->justifyContentValue(); + case LayoutComponentStyleBase::flexWrapValuePropertyKey: + return object->as()->flexWrapValue(); + case LayoutComponentStyleBase::overflowValuePropertyKey: + return object->as()->overflowValue(); + case LayoutComponentStyleBase::widthUnitsValuePropertyKey: + return object->as()->widthUnitsValue(); + case LayoutComponentStyleBase::heightUnitsValuePropertyKey: + return object->as()->heightUnitsValue(); + case LayoutComponentStyleBase::borderLeftUnitsValuePropertyKey: + return object->as()->borderLeftUnitsValue(); + case LayoutComponentStyleBase::borderRightUnitsValuePropertyKey: + return object->as()->borderRightUnitsValue(); + case LayoutComponentStyleBase::borderTopUnitsValuePropertyKey: + return object->as()->borderTopUnitsValue(); + case LayoutComponentStyleBase::borderBottomUnitsValuePropertyKey: + return object->as()->borderBottomUnitsValue(); + case LayoutComponentStyleBase::marginLeftUnitsValuePropertyKey: + return object->as()->marginLeftUnitsValue(); + case LayoutComponentStyleBase::marginRightUnitsValuePropertyKey: + return object->as()->marginRightUnitsValue(); + case LayoutComponentStyleBase::marginTopUnitsValuePropertyKey: + return object->as()->marginTopUnitsValue(); + case LayoutComponentStyleBase::marginBottomUnitsValuePropertyKey: + return object->as()->marginBottomUnitsValue(); + case LayoutComponentStyleBase::paddingLeftUnitsValuePropertyKey: + return object->as()->paddingLeftUnitsValue(); + case LayoutComponentStyleBase::paddingRightUnitsValuePropertyKey: + return object->as()->paddingRightUnitsValue(); + case LayoutComponentStyleBase::paddingTopUnitsValuePropertyKey: + return object->as()->paddingTopUnitsValue(); + case LayoutComponentStyleBase::paddingBottomUnitsValuePropertyKey: + return object->as()->paddingBottomUnitsValue(); + case LayoutComponentStyleBase::positionLeftUnitsValuePropertyKey: + return object->as()->positionLeftUnitsValue(); + case LayoutComponentStyleBase::positionRightUnitsValuePropertyKey: + return object->as()->positionRightUnitsValue(); + case LayoutComponentStyleBase::positionTopUnitsValuePropertyKey: + return object->as()->positionTopUnitsValue(); + case LayoutComponentStyleBase::positionBottomUnitsValuePropertyKey: + return object->as()->positionBottomUnitsValue(); + case LayoutComponentStyleBase::gapHorizontalUnitsValuePropertyKey: + return object->as()->gapHorizontalUnitsValue(); + case LayoutComponentStyleBase::gapVerticalUnitsValuePropertyKey: + return object->as()->gapVerticalUnitsValue(); + case LayoutComponentStyleBase::minWidthUnitsValuePropertyKey: + return object->as()->minWidthUnitsValue(); + case LayoutComponentStyleBase::minHeightUnitsValuePropertyKey: + return object->as()->minHeightUnitsValue(); + case LayoutComponentStyleBase::maxWidthUnitsValuePropertyKey: + return object->as()->maxWidthUnitsValue(); + case LayoutComponentStyleBase::maxHeightUnitsValuePropertyKey: + return object->as()->maxHeightUnitsValue(); case ListenerFireEventBase::eventIdPropertyKey: return object->as()->eventId(); case LayerStateBase::flagsPropertyKey: return object->as()->flags(); + case KeyFrameBase::framePropertyKey: + return object->as()->frame(); + case InterpolatingKeyFrameBase::interpolationTypePropertyKey: + return object->as()->interpolationType(); + case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: + return object->as()->interpolatorId(); + case KeyFrameUintBase::valuePropertyKey: + return object->as()->value(); case ListenerInputChangeBase::inputIdPropertyKey: return object->as()->inputId(); case ListenerInputChangeBase::nestedInputIdPropertyKey: @@ -1623,12 +1802,6 @@ class CoreRegistry return object->as()->listenerTypeValue(); case StateMachineListenerBase::eventIdPropertyKey: return object->as()->eventId(); - case KeyFrameBase::framePropertyKey: - return object->as()->frame(); - case InterpolatingKeyFrameBase::interpolationTypePropertyKey: - return object->as()->interpolationType(); - case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: - return object->as()->interpolatorId(); case KeyFrameIdBase::valuePropertyKey: return object->as()->value(); case ListenerBoolChangeBase::valuePropertyKey: @@ -2157,6 +2330,7 @@ class CoreRegistry case IKConstraintBase::invertDirectionPropertyKey: case FollowPathConstraintBase::orientPropertyKey: case FollowPathConstraintBase::offsetPropertyKey: + case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: case NestedSimpleAnimationBase::isPlayingPropertyKey: case KeyFrameBoolBase::valuePropertyKey: case ListenerAlignTargetBase::preserveOffsetPropertyKey: @@ -2199,15 +2373,51 @@ class CoreRegistry case NestedArtboardBase::alignmentPropertyKey: case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: - case LayoutComponentStyleBase::layoutFlags0PropertyKey: - case LayoutComponentStyleBase::layoutFlags1PropertyKey: - case LayoutComponentStyleBase::layoutFlags2PropertyKey: case LayoutComponentStyleBase::scaleTypePropertyKey: + case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: case LayoutComponentStyleBase::animationStyleTypePropertyKey: case LayoutComponentStyleBase::interpolationTypePropertyKey: case LayoutComponentStyleBase::interpolatorIdPropertyKey: + case LayoutComponentStyleBase::displayValuePropertyKey: + case LayoutComponentStyleBase::positionTypeValuePropertyKey: + case LayoutComponentStyleBase::flexDirectionValuePropertyKey: + case LayoutComponentStyleBase::directionValuePropertyKey: + case LayoutComponentStyleBase::alignContentValuePropertyKey: + case LayoutComponentStyleBase::alignItemsValuePropertyKey: + case LayoutComponentStyleBase::alignSelfValuePropertyKey: + case LayoutComponentStyleBase::justifyContentValuePropertyKey: + case LayoutComponentStyleBase::flexWrapValuePropertyKey: + case LayoutComponentStyleBase::overflowValuePropertyKey: + case LayoutComponentStyleBase::widthUnitsValuePropertyKey: + case LayoutComponentStyleBase::heightUnitsValuePropertyKey: + case LayoutComponentStyleBase::borderLeftUnitsValuePropertyKey: + case LayoutComponentStyleBase::borderRightUnitsValuePropertyKey: + case LayoutComponentStyleBase::borderTopUnitsValuePropertyKey: + case LayoutComponentStyleBase::borderBottomUnitsValuePropertyKey: + case LayoutComponentStyleBase::marginLeftUnitsValuePropertyKey: + case LayoutComponentStyleBase::marginRightUnitsValuePropertyKey: + case LayoutComponentStyleBase::marginTopUnitsValuePropertyKey: + case LayoutComponentStyleBase::marginBottomUnitsValuePropertyKey: + case LayoutComponentStyleBase::paddingLeftUnitsValuePropertyKey: + case LayoutComponentStyleBase::paddingRightUnitsValuePropertyKey: + case LayoutComponentStyleBase::paddingTopUnitsValuePropertyKey: + case LayoutComponentStyleBase::paddingBottomUnitsValuePropertyKey: + case LayoutComponentStyleBase::positionLeftUnitsValuePropertyKey: + case LayoutComponentStyleBase::positionRightUnitsValuePropertyKey: + case LayoutComponentStyleBase::positionTopUnitsValuePropertyKey: + case LayoutComponentStyleBase::positionBottomUnitsValuePropertyKey: + case LayoutComponentStyleBase::gapHorizontalUnitsValuePropertyKey: + case LayoutComponentStyleBase::gapVerticalUnitsValuePropertyKey: + case LayoutComponentStyleBase::minWidthUnitsValuePropertyKey: + case LayoutComponentStyleBase::minHeightUnitsValuePropertyKey: + case LayoutComponentStyleBase::maxWidthUnitsValuePropertyKey: + case LayoutComponentStyleBase::maxHeightUnitsValuePropertyKey: case ListenerFireEventBase::eventIdPropertyKey: case LayerStateBase::flagsPropertyKey: + case KeyFrameBase::framePropertyKey: + case InterpolatingKeyFrameBase::interpolationTypePropertyKey: + case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: + case KeyFrameUintBase::valuePropertyKey: case ListenerInputChangeBase::inputIdPropertyKey: case ListenerInputChangeBase::nestedInputIdPropertyKey: case AnimationStateBase::animationIdPropertyKey: @@ -2221,9 +2431,6 @@ class CoreRegistry case StateMachineListenerBase::targetIdPropertyKey: case StateMachineListenerBase::listenerTypeValuePropertyKey: case StateMachineListenerBase::eventIdPropertyKey: - case KeyFrameBase::framePropertyKey: - case InterpolatingKeyFrameBase::interpolationTypePropertyKey: - case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: case KeyFrameIdBase::valuePropertyKey: case ListenerBoolChangeBase::valuePropertyKey: case ListenerAlignTargetBase::targetIdPropertyKey: @@ -2521,6 +2728,8 @@ class CoreRegistry return object->is(); case FollowPathConstraintBase::offsetPropertyKey: return object->is(); + case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: + return object->is(); case NestedSimpleAnimationBase::isPlayingPropertyKey: return object->is(); case KeyFrameBoolBase::valuePropertyKey: @@ -2603,24 +2812,96 @@ class CoreRegistry return object->is(); case SoloBase::activeComponentIdPropertyKey: return object->is(); - case LayoutComponentStyleBase::layoutFlags0PropertyKey: - return object->is(); - case LayoutComponentStyleBase::layoutFlags1PropertyKey: - return object->is(); - case LayoutComponentStyleBase::layoutFlags2PropertyKey: - return object->is(); case LayoutComponentStyleBase::scaleTypePropertyKey: return object->is(); + case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: + return object->is(); case LayoutComponentStyleBase::animationStyleTypePropertyKey: return object->is(); case LayoutComponentStyleBase::interpolationTypePropertyKey: return object->is(); case LayoutComponentStyleBase::interpolatorIdPropertyKey: return object->is(); + case LayoutComponentStyleBase::displayValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionTypeValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::flexDirectionValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::directionValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::alignContentValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::alignItemsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::alignSelfValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::justifyContentValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::flexWrapValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::overflowValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::widthUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::heightUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderLeftUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderRightUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderTopUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::borderBottomUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginLeftUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginRightUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginTopUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::marginBottomUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingLeftUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingRightUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingTopUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::paddingBottomUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionLeftUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionRightUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionTopUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::positionBottomUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::gapHorizontalUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::gapVerticalUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::minWidthUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::minHeightUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::maxWidthUnitsValuePropertyKey: + return object->is(); + case LayoutComponentStyleBase::maxHeightUnitsValuePropertyKey: + return object->is(); case ListenerFireEventBase::eventIdPropertyKey: return object->is(); case LayerStateBase::flagsPropertyKey: return object->is(); + case KeyFrameBase::framePropertyKey: + return object->is(); + case InterpolatingKeyFrameBase::interpolationTypePropertyKey: + return object->is(); + case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: + return object->is(); + case KeyFrameUintBase::valuePropertyKey: + return object->is(); case ListenerInputChangeBase::inputIdPropertyKey: return object->is(); case ListenerInputChangeBase::nestedInputIdPropertyKey: @@ -2647,12 +2928,6 @@ class CoreRegistry return object->is(); case StateMachineListenerBase::eventIdPropertyKey: return object->is(); - case KeyFrameBase::framePropertyKey: - return object->is(); - case InterpolatingKeyFrameBase::interpolationTypePropertyKey: - return object->is(); - case InterpolatingKeyFrameBase::interpolatorIdPropertyKey: - return object->is(); case KeyFrameIdBase::valuePropertyKey: return object->is(); case ListenerBoolChangeBase::valuePropertyKey: diff --git a/include/rive/generated/layout/layout_component_style_base.hpp b/include/rive/generated/layout/layout_component_style_base.hpp index 60163da9..b62fa973 100644 --- a/include/rive/generated/layout/layout_component_style_base.hpp +++ b/include/rive/generated/layout/layout_component_style_base.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_LAYOUT_COMPONENT_STYLE_BASE_HPP_ #define _RIVE_LAYOUT_COMPONENT_STYLE_BASE_HPP_ #include "rive/component.hpp" +#include "rive/core/field_types/core_bool_type.hpp" #include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive @@ -29,9 +30,6 @@ class LayoutComponentStyleBase : public Component uint16_t coreType() const override { return typeKey; } - static const uint16_t layoutFlags0PropertyKey = 495; - static const uint16_t layoutFlags1PropertyKey = 496; - static const uint16_t layoutFlags2PropertyKey = 497; static const uint16_t gapHorizontalPropertyKey = 498; static const uint16_t gapVerticalPropertyKey = 499; static const uint16_t maxWidthPropertyKey = 500; @@ -60,15 +58,48 @@ class LayoutComponentStyleBase : public Component static const uint16_t flexBasisPropertyKey = 523; static const uint16_t aspectRatioPropertyKey = 524; static const uint16_t scaleTypePropertyKey = 546; + static const uint16_t layoutAlignmentTypePropertyKey = 632; static const uint16_t animationStyleTypePropertyKey = 589; static const uint16_t interpolationTypePropertyKey = 590; static const uint16_t interpolatorIdPropertyKey = 591; static const uint16_t interpolationTimePropertyKey = 592; + static const uint16_t displayValuePropertyKey = 596; + static const uint16_t positionTypeValuePropertyKey = 597; + static const uint16_t flexDirectionValuePropertyKey = 598; + static const uint16_t directionValuePropertyKey = 599; + static const uint16_t alignContentValuePropertyKey = 600; + static const uint16_t alignItemsValuePropertyKey = 601; + static const uint16_t alignSelfValuePropertyKey = 602; + static const uint16_t justifyContentValuePropertyKey = 603; + static const uint16_t flexWrapValuePropertyKey = 604; + static const uint16_t overflowValuePropertyKey = 605; + static const uint16_t intrinsicallySizedValuePropertyKey = 606; + static const uint16_t widthUnitsValuePropertyKey = 607; + static const uint16_t heightUnitsValuePropertyKey = 608; + static const uint16_t borderLeftUnitsValuePropertyKey = 609; + static const uint16_t borderRightUnitsValuePropertyKey = 610; + static const uint16_t borderTopUnitsValuePropertyKey = 611; + static const uint16_t borderBottomUnitsValuePropertyKey = 612; + static const uint16_t marginLeftUnitsValuePropertyKey = 613; + static const uint16_t marginRightUnitsValuePropertyKey = 614; + static const uint16_t marginTopUnitsValuePropertyKey = 615; + static const uint16_t marginBottomUnitsValuePropertyKey = 616; + static const uint16_t paddingLeftUnitsValuePropertyKey = 617; + static const uint16_t paddingRightUnitsValuePropertyKey = 618; + static const uint16_t paddingTopUnitsValuePropertyKey = 619; + static const uint16_t paddingBottomUnitsValuePropertyKey = 620; + static const uint16_t positionLeftUnitsValuePropertyKey = 621; + static const uint16_t positionRightUnitsValuePropertyKey = 622; + static const uint16_t positionTopUnitsValuePropertyKey = 623; + static const uint16_t positionBottomUnitsValuePropertyKey = 624; + static const uint16_t gapHorizontalUnitsValuePropertyKey = 625; + static const uint16_t gapVerticalUnitsValuePropertyKey = 626; + static const uint16_t minWidthUnitsValuePropertyKey = 627; + static const uint16_t minHeightUnitsValuePropertyKey = 628; + static const uint16_t maxWidthUnitsValuePropertyKey = 629; + static const uint16_t maxHeightUnitsValuePropertyKey = 630; private: - uint32_t m_LayoutFlags0 = 0x5000412; - uint32_t m_LayoutFlags1 = 0x00; - uint32_t m_LayoutFlags2 = 0x00; float m_GapHorizontal = 0.0f; float m_GapVertical = 0.0f; float m_MaxWidth = 0.0f; @@ -97,45 +128,48 @@ class LayoutComponentStyleBase : public Component float m_FlexBasis = 1.0f; float m_AspectRatio = 0.0f; uint32_t m_ScaleType = 0; + uint32_t m_LayoutAlignmentType = 0; uint32_t m_AnimationStyleType = 0; uint32_t m_InterpolationType = 0; uint32_t m_InterpolatorId = -1; float m_InterpolationTime = 0.0f; + uint32_t m_DisplayValue = 0; + uint32_t m_PositionTypeValue = 1; + uint32_t m_FlexDirectionValue = 2; + uint32_t m_DirectionValue = 0; + uint32_t m_AlignContentValue = 0; + uint32_t m_AlignItemsValue = 1; + uint32_t m_AlignSelfValue = 0; + uint32_t m_JustifyContentValue = 0; + uint32_t m_FlexWrapValue = 0; + uint32_t m_OverflowValue = 0; + bool m_IntrinsicallySizedValue = false; + uint32_t m_WidthUnitsValue = 1; + uint32_t m_HeightUnitsValue = 1; + uint32_t m_BorderLeftUnitsValue = 0; + uint32_t m_BorderRightUnitsValue = 0; + uint32_t m_BorderTopUnitsValue = 0; + uint32_t m_BorderBottomUnitsValue = 0; + uint32_t m_MarginLeftUnitsValue = 0; + uint32_t m_MarginRightUnitsValue = 0; + uint32_t m_MarginTopUnitsValue = 0; + uint32_t m_MarginBottomUnitsValue = 0; + uint32_t m_PaddingLeftUnitsValue = 0; + uint32_t m_PaddingRightUnitsValue = 0; + uint32_t m_PaddingTopUnitsValue = 0; + uint32_t m_PaddingBottomUnitsValue = 0; + uint32_t m_PositionLeftUnitsValue = 0; + uint32_t m_PositionRightUnitsValue = 0; + uint32_t m_PositionTopUnitsValue = 0; + uint32_t m_PositionBottomUnitsValue = 0; + uint32_t m_GapHorizontalUnitsValue = 0; + uint32_t m_GapVerticalUnitsValue = 0; + uint32_t m_MinWidthUnitsValue = 0; + uint32_t m_MinHeightUnitsValue = 0; + uint32_t m_MaxWidthUnitsValue = 0; + uint32_t m_MaxHeightUnitsValue = 0; public: - inline uint32_t layoutFlags0() const { return m_LayoutFlags0; } - void layoutFlags0(uint32_t value) - { - if (m_LayoutFlags0 == value) - { - return; - } - m_LayoutFlags0 = value; - layoutFlags0Changed(); - } - - inline uint32_t layoutFlags1() const { return m_LayoutFlags1; } - void layoutFlags1(uint32_t value) - { - if (m_LayoutFlags1 == value) - { - return; - } - m_LayoutFlags1 = value; - layoutFlags1Changed(); - } - - inline uint32_t layoutFlags2() const { return m_LayoutFlags2; } - void layoutFlags2(uint32_t value) - { - if (m_LayoutFlags2 == value) - { - return; - } - m_LayoutFlags2 = value; - layoutFlags2Changed(); - } - inline float gapHorizontal() const { return m_GapHorizontal; } void gapHorizontal(float value) { @@ -444,6 +478,17 @@ class LayoutComponentStyleBase : public Component scaleTypeChanged(); } + inline uint32_t layoutAlignmentType() const { return m_LayoutAlignmentType; } + void layoutAlignmentType(uint32_t value) + { + if (m_LayoutAlignmentType == value) + { + return; + } + m_LayoutAlignmentType = value; + layoutAlignmentTypeChanged(); + } + inline uint32_t animationStyleType() const { return m_AnimationStyleType; } void animationStyleType(uint32_t value) { @@ -488,12 +533,394 @@ class LayoutComponentStyleBase : public Component interpolationTimeChanged(); } + inline uint32_t displayValue() const { return m_DisplayValue; } + void displayValue(uint32_t value) + { + if (m_DisplayValue == value) + { + return; + } + m_DisplayValue = value; + displayValueChanged(); + } + + inline uint32_t positionTypeValue() const { return m_PositionTypeValue; } + void positionTypeValue(uint32_t value) + { + if (m_PositionTypeValue == value) + { + return; + } + m_PositionTypeValue = value; + positionTypeValueChanged(); + } + + inline uint32_t flexDirectionValue() const { return m_FlexDirectionValue; } + void flexDirectionValue(uint32_t value) + { + if (m_FlexDirectionValue == value) + { + return; + } + m_FlexDirectionValue = value; + flexDirectionValueChanged(); + } + + inline uint32_t directionValue() const { return m_DirectionValue; } + void directionValue(uint32_t value) + { + if (m_DirectionValue == value) + { + return; + } + m_DirectionValue = value; + directionValueChanged(); + } + + inline uint32_t alignContentValue() const { return m_AlignContentValue; } + void alignContentValue(uint32_t value) + { + if (m_AlignContentValue == value) + { + return; + } + m_AlignContentValue = value; + alignContentValueChanged(); + } + + inline uint32_t alignItemsValue() const { return m_AlignItemsValue; } + void alignItemsValue(uint32_t value) + { + if (m_AlignItemsValue == value) + { + return; + } + m_AlignItemsValue = value; + alignItemsValueChanged(); + } + + inline uint32_t alignSelfValue() const { return m_AlignSelfValue; } + void alignSelfValue(uint32_t value) + { + if (m_AlignSelfValue == value) + { + return; + } + m_AlignSelfValue = value; + alignSelfValueChanged(); + } + + inline uint32_t justifyContentValue() const { return m_JustifyContentValue; } + void justifyContentValue(uint32_t value) + { + if (m_JustifyContentValue == value) + { + return; + } + m_JustifyContentValue = value; + justifyContentValueChanged(); + } + + inline uint32_t flexWrapValue() const { return m_FlexWrapValue; } + void flexWrapValue(uint32_t value) + { + if (m_FlexWrapValue == value) + { + return; + } + m_FlexWrapValue = value; + flexWrapValueChanged(); + } + + inline uint32_t overflowValue() const { return m_OverflowValue; } + void overflowValue(uint32_t value) + { + if (m_OverflowValue == value) + { + return; + } + m_OverflowValue = value; + overflowValueChanged(); + } + + inline bool intrinsicallySizedValue() const { return m_IntrinsicallySizedValue; } + void intrinsicallySizedValue(bool value) + { + if (m_IntrinsicallySizedValue == value) + { + return; + } + m_IntrinsicallySizedValue = value; + intrinsicallySizedValueChanged(); + } + + inline uint32_t widthUnitsValue() const { return m_WidthUnitsValue; } + void widthUnitsValue(uint32_t value) + { + if (m_WidthUnitsValue == value) + { + return; + } + m_WidthUnitsValue = value; + widthUnitsValueChanged(); + } + + inline uint32_t heightUnitsValue() const { return m_HeightUnitsValue; } + void heightUnitsValue(uint32_t value) + { + if (m_HeightUnitsValue == value) + { + return; + } + m_HeightUnitsValue = value; + heightUnitsValueChanged(); + } + + inline uint32_t borderLeftUnitsValue() const { return m_BorderLeftUnitsValue; } + void borderLeftUnitsValue(uint32_t value) + { + if (m_BorderLeftUnitsValue == value) + { + return; + } + m_BorderLeftUnitsValue = value; + borderLeftUnitsValueChanged(); + } + + inline uint32_t borderRightUnitsValue() const { return m_BorderRightUnitsValue; } + void borderRightUnitsValue(uint32_t value) + { + if (m_BorderRightUnitsValue == value) + { + return; + } + m_BorderRightUnitsValue = value; + borderRightUnitsValueChanged(); + } + + inline uint32_t borderTopUnitsValue() const { return m_BorderTopUnitsValue; } + void borderTopUnitsValue(uint32_t value) + { + if (m_BorderTopUnitsValue == value) + { + return; + } + m_BorderTopUnitsValue = value; + borderTopUnitsValueChanged(); + } + + inline uint32_t borderBottomUnitsValue() const { return m_BorderBottomUnitsValue; } + void borderBottomUnitsValue(uint32_t value) + { + if (m_BorderBottomUnitsValue == value) + { + return; + } + m_BorderBottomUnitsValue = value; + borderBottomUnitsValueChanged(); + } + + inline uint32_t marginLeftUnitsValue() const { return m_MarginLeftUnitsValue; } + void marginLeftUnitsValue(uint32_t value) + { + if (m_MarginLeftUnitsValue == value) + { + return; + } + m_MarginLeftUnitsValue = value; + marginLeftUnitsValueChanged(); + } + + inline uint32_t marginRightUnitsValue() const { return m_MarginRightUnitsValue; } + void marginRightUnitsValue(uint32_t value) + { + if (m_MarginRightUnitsValue == value) + { + return; + } + m_MarginRightUnitsValue = value; + marginRightUnitsValueChanged(); + } + + inline uint32_t marginTopUnitsValue() const { return m_MarginTopUnitsValue; } + void marginTopUnitsValue(uint32_t value) + { + if (m_MarginTopUnitsValue == value) + { + return; + } + m_MarginTopUnitsValue = value; + marginTopUnitsValueChanged(); + } + + inline uint32_t marginBottomUnitsValue() const { return m_MarginBottomUnitsValue; } + void marginBottomUnitsValue(uint32_t value) + { + if (m_MarginBottomUnitsValue == value) + { + return; + } + m_MarginBottomUnitsValue = value; + marginBottomUnitsValueChanged(); + } + + inline uint32_t paddingLeftUnitsValue() const { return m_PaddingLeftUnitsValue; } + void paddingLeftUnitsValue(uint32_t value) + { + if (m_PaddingLeftUnitsValue == value) + { + return; + } + m_PaddingLeftUnitsValue = value; + paddingLeftUnitsValueChanged(); + } + + inline uint32_t paddingRightUnitsValue() const { return m_PaddingRightUnitsValue; } + void paddingRightUnitsValue(uint32_t value) + { + if (m_PaddingRightUnitsValue == value) + { + return; + } + m_PaddingRightUnitsValue = value; + paddingRightUnitsValueChanged(); + } + + inline uint32_t paddingTopUnitsValue() const { return m_PaddingTopUnitsValue; } + void paddingTopUnitsValue(uint32_t value) + { + if (m_PaddingTopUnitsValue == value) + { + return; + } + m_PaddingTopUnitsValue = value; + paddingTopUnitsValueChanged(); + } + + inline uint32_t paddingBottomUnitsValue() const { return m_PaddingBottomUnitsValue; } + void paddingBottomUnitsValue(uint32_t value) + { + if (m_PaddingBottomUnitsValue == value) + { + return; + } + m_PaddingBottomUnitsValue = value; + paddingBottomUnitsValueChanged(); + } + + inline uint32_t positionLeftUnitsValue() const { return m_PositionLeftUnitsValue; } + void positionLeftUnitsValue(uint32_t value) + { + if (m_PositionLeftUnitsValue == value) + { + return; + } + m_PositionLeftUnitsValue = value; + positionLeftUnitsValueChanged(); + } + + inline uint32_t positionRightUnitsValue() const { return m_PositionRightUnitsValue; } + void positionRightUnitsValue(uint32_t value) + { + if (m_PositionRightUnitsValue == value) + { + return; + } + m_PositionRightUnitsValue = value; + positionRightUnitsValueChanged(); + } + + inline uint32_t positionTopUnitsValue() const { return m_PositionTopUnitsValue; } + void positionTopUnitsValue(uint32_t value) + { + if (m_PositionTopUnitsValue == value) + { + return; + } + m_PositionTopUnitsValue = value; + positionTopUnitsValueChanged(); + } + + inline uint32_t positionBottomUnitsValue() const { return m_PositionBottomUnitsValue; } + void positionBottomUnitsValue(uint32_t value) + { + if (m_PositionBottomUnitsValue == value) + { + return; + } + m_PositionBottomUnitsValue = value; + positionBottomUnitsValueChanged(); + } + + inline uint32_t gapHorizontalUnitsValue() const { return m_GapHorizontalUnitsValue; } + void gapHorizontalUnitsValue(uint32_t value) + { + if (m_GapHorizontalUnitsValue == value) + { + return; + } + m_GapHorizontalUnitsValue = value; + gapHorizontalUnitsValueChanged(); + } + + inline uint32_t gapVerticalUnitsValue() const { return m_GapVerticalUnitsValue; } + void gapVerticalUnitsValue(uint32_t value) + { + if (m_GapVerticalUnitsValue == value) + { + return; + } + m_GapVerticalUnitsValue = value; + gapVerticalUnitsValueChanged(); + } + + inline uint32_t minWidthUnitsValue() const { return m_MinWidthUnitsValue; } + void minWidthUnitsValue(uint32_t value) + { + if (m_MinWidthUnitsValue == value) + { + return; + } + m_MinWidthUnitsValue = value; + minWidthUnitsValueChanged(); + } + + inline uint32_t minHeightUnitsValue() const { return m_MinHeightUnitsValue; } + void minHeightUnitsValue(uint32_t value) + { + if (m_MinHeightUnitsValue == value) + { + return; + } + m_MinHeightUnitsValue = value; + minHeightUnitsValueChanged(); + } + + inline uint32_t maxWidthUnitsValue() const { return m_MaxWidthUnitsValue; } + void maxWidthUnitsValue(uint32_t value) + { + if (m_MaxWidthUnitsValue == value) + { + return; + } + m_MaxWidthUnitsValue = value; + maxWidthUnitsValueChanged(); + } + + inline uint32_t maxHeightUnitsValue() const { return m_MaxHeightUnitsValue; } + void maxHeightUnitsValue(uint32_t value) + { + if (m_MaxHeightUnitsValue == value) + { + return; + } + m_MaxHeightUnitsValue = value; + maxHeightUnitsValueChanged(); + } + Core* clone() const override; void copy(const LayoutComponentStyleBase& object) { - m_LayoutFlags0 = object.m_LayoutFlags0; - m_LayoutFlags1 = object.m_LayoutFlags1; - m_LayoutFlags2 = object.m_LayoutFlags2; m_GapHorizontal = object.m_GapHorizontal; m_GapVertical = object.m_GapVertical; m_MaxWidth = object.m_MaxWidth; @@ -522,10 +949,46 @@ class LayoutComponentStyleBase : public Component m_FlexBasis = object.m_FlexBasis; m_AspectRatio = object.m_AspectRatio; m_ScaleType = object.m_ScaleType; + m_LayoutAlignmentType = object.m_LayoutAlignmentType; m_AnimationStyleType = object.m_AnimationStyleType; m_InterpolationType = object.m_InterpolationType; m_InterpolatorId = object.m_InterpolatorId; m_InterpolationTime = object.m_InterpolationTime; + m_DisplayValue = object.m_DisplayValue; + m_PositionTypeValue = object.m_PositionTypeValue; + m_FlexDirectionValue = object.m_FlexDirectionValue; + m_DirectionValue = object.m_DirectionValue; + m_AlignContentValue = object.m_AlignContentValue; + m_AlignItemsValue = object.m_AlignItemsValue; + m_AlignSelfValue = object.m_AlignSelfValue; + m_JustifyContentValue = object.m_JustifyContentValue; + m_FlexWrapValue = object.m_FlexWrapValue; + m_OverflowValue = object.m_OverflowValue; + m_IntrinsicallySizedValue = object.m_IntrinsicallySizedValue; + m_WidthUnitsValue = object.m_WidthUnitsValue; + m_HeightUnitsValue = object.m_HeightUnitsValue; + m_BorderLeftUnitsValue = object.m_BorderLeftUnitsValue; + m_BorderRightUnitsValue = object.m_BorderRightUnitsValue; + m_BorderTopUnitsValue = object.m_BorderTopUnitsValue; + m_BorderBottomUnitsValue = object.m_BorderBottomUnitsValue; + m_MarginLeftUnitsValue = object.m_MarginLeftUnitsValue; + m_MarginRightUnitsValue = object.m_MarginRightUnitsValue; + m_MarginTopUnitsValue = object.m_MarginTopUnitsValue; + m_MarginBottomUnitsValue = object.m_MarginBottomUnitsValue; + m_PaddingLeftUnitsValue = object.m_PaddingLeftUnitsValue; + m_PaddingRightUnitsValue = object.m_PaddingRightUnitsValue; + m_PaddingTopUnitsValue = object.m_PaddingTopUnitsValue; + m_PaddingBottomUnitsValue = object.m_PaddingBottomUnitsValue; + m_PositionLeftUnitsValue = object.m_PositionLeftUnitsValue; + m_PositionRightUnitsValue = object.m_PositionRightUnitsValue; + m_PositionTopUnitsValue = object.m_PositionTopUnitsValue; + m_PositionBottomUnitsValue = object.m_PositionBottomUnitsValue; + m_GapHorizontalUnitsValue = object.m_GapHorizontalUnitsValue; + m_GapVerticalUnitsValue = object.m_GapVerticalUnitsValue; + m_MinWidthUnitsValue = object.m_MinWidthUnitsValue; + m_MinHeightUnitsValue = object.m_MinHeightUnitsValue; + m_MaxWidthUnitsValue = object.m_MaxWidthUnitsValue; + m_MaxHeightUnitsValue = object.m_MaxHeightUnitsValue; Component::copy(object); } @@ -533,15 +996,6 @@ class LayoutComponentStyleBase : public Component { switch (propertyKey) { - case layoutFlags0PropertyKey: - m_LayoutFlags0 = CoreUintType::deserialize(reader); - return true; - case layoutFlags1PropertyKey: - m_LayoutFlags1 = CoreUintType::deserialize(reader); - return true; - case layoutFlags2PropertyKey: - m_LayoutFlags2 = CoreUintType::deserialize(reader); - return true; case gapHorizontalPropertyKey: m_GapHorizontal = CoreDoubleType::deserialize(reader); return true; @@ -626,6 +1080,9 @@ class LayoutComponentStyleBase : public Component case scaleTypePropertyKey: m_ScaleType = CoreUintType::deserialize(reader); return true; + case layoutAlignmentTypePropertyKey: + m_LayoutAlignmentType = CoreUintType::deserialize(reader); + return true; case animationStyleTypePropertyKey: m_AnimationStyleType = CoreUintType::deserialize(reader); return true; @@ -638,14 +1095,116 @@ class LayoutComponentStyleBase : public Component case interpolationTimePropertyKey: m_InterpolationTime = CoreDoubleType::deserialize(reader); return true; + case displayValuePropertyKey: + m_DisplayValue = CoreUintType::deserialize(reader); + return true; + case positionTypeValuePropertyKey: + m_PositionTypeValue = CoreUintType::deserialize(reader); + return true; + case flexDirectionValuePropertyKey: + m_FlexDirectionValue = CoreUintType::deserialize(reader); + return true; + case directionValuePropertyKey: + m_DirectionValue = CoreUintType::deserialize(reader); + return true; + case alignContentValuePropertyKey: + m_AlignContentValue = CoreUintType::deserialize(reader); + return true; + case alignItemsValuePropertyKey: + m_AlignItemsValue = CoreUintType::deserialize(reader); + return true; + case alignSelfValuePropertyKey: + m_AlignSelfValue = CoreUintType::deserialize(reader); + return true; + case justifyContentValuePropertyKey: + m_JustifyContentValue = CoreUintType::deserialize(reader); + return true; + case flexWrapValuePropertyKey: + m_FlexWrapValue = CoreUintType::deserialize(reader); + return true; + case overflowValuePropertyKey: + m_OverflowValue = CoreUintType::deserialize(reader); + return true; + case intrinsicallySizedValuePropertyKey: + m_IntrinsicallySizedValue = CoreBoolType::deserialize(reader); + return true; + case widthUnitsValuePropertyKey: + m_WidthUnitsValue = CoreUintType::deserialize(reader); + return true; + case heightUnitsValuePropertyKey: + m_HeightUnitsValue = CoreUintType::deserialize(reader); + return true; + case borderLeftUnitsValuePropertyKey: + m_BorderLeftUnitsValue = CoreUintType::deserialize(reader); + return true; + case borderRightUnitsValuePropertyKey: + m_BorderRightUnitsValue = CoreUintType::deserialize(reader); + return true; + case borderTopUnitsValuePropertyKey: + m_BorderTopUnitsValue = CoreUintType::deserialize(reader); + return true; + case borderBottomUnitsValuePropertyKey: + m_BorderBottomUnitsValue = CoreUintType::deserialize(reader); + return true; + case marginLeftUnitsValuePropertyKey: + m_MarginLeftUnitsValue = CoreUintType::deserialize(reader); + return true; + case marginRightUnitsValuePropertyKey: + m_MarginRightUnitsValue = CoreUintType::deserialize(reader); + return true; + case marginTopUnitsValuePropertyKey: + m_MarginTopUnitsValue = CoreUintType::deserialize(reader); + return true; + case marginBottomUnitsValuePropertyKey: + m_MarginBottomUnitsValue = CoreUintType::deserialize(reader); + return true; + case paddingLeftUnitsValuePropertyKey: + m_PaddingLeftUnitsValue = CoreUintType::deserialize(reader); + return true; + case paddingRightUnitsValuePropertyKey: + m_PaddingRightUnitsValue = CoreUintType::deserialize(reader); + return true; + case paddingTopUnitsValuePropertyKey: + m_PaddingTopUnitsValue = CoreUintType::deserialize(reader); + return true; + case paddingBottomUnitsValuePropertyKey: + m_PaddingBottomUnitsValue = CoreUintType::deserialize(reader); + return true; + case positionLeftUnitsValuePropertyKey: + m_PositionLeftUnitsValue = CoreUintType::deserialize(reader); + return true; + case positionRightUnitsValuePropertyKey: + m_PositionRightUnitsValue = CoreUintType::deserialize(reader); + return true; + case positionTopUnitsValuePropertyKey: + m_PositionTopUnitsValue = CoreUintType::deserialize(reader); + return true; + case positionBottomUnitsValuePropertyKey: + m_PositionBottomUnitsValue = CoreUintType::deserialize(reader); + return true; + case gapHorizontalUnitsValuePropertyKey: + m_GapHorizontalUnitsValue = CoreUintType::deserialize(reader); + return true; + case gapVerticalUnitsValuePropertyKey: + m_GapVerticalUnitsValue = CoreUintType::deserialize(reader); + return true; + case minWidthUnitsValuePropertyKey: + m_MinWidthUnitsValue = CoreUintType::deserialize(reader); + return true; + case minHeightUnitsValuePropertyKey: + m_MinHeightUnitsValue = CoreUintType::deserialize(reader); + return true; + case maxWidthUnitsValuePropertyKey: + m_MaxWidthUnitsValue = CoreUintType::deserialize(reader); + return true; + case maxHeightUnitsValuePropertyKey: + m_MaxHeightUnitsValue = CoreUintType::deserialize(reader); + return true; } return Component::deserialize(propertyKey, reader); } protected: - virtual void layoutFlags0Changed() {} - virtual void layoutFlags1Changed() {} - virtual void layoutFlags2Changed() {} virtual void gapHorizontalChanged() {} virtual void gapVerticalChanged() {} virtual void maxWidthChanged() {} @@ -674,10 +1233,46 @@ class LayoutComponentStyleBase : public Component virtual void flexBasisChanged() {} virtual void aspectRatioChanged() {} virtual void scaleTypeChanged() {} + virtual void layoutAlignmentTypeChanged() {} virtual void animationStyleTypeChanged() {} virtual void interpolationTypeChanged() {} virtual void interpolatorIdChanged() {} virtual void interpolationTimeChanged() {} + virtual void displayValueChanged() {} + virtual void positionTypeValueChanged() {} + virtual void flexDirectionValueChanged() {} + virtual void directionValueChanged() {} + virtual void alignContentValueChanged() {} + virtual void alignItemsValueChanged() {} + virtual void alignSelfValueChanged() {} + virtual void justifyContentValueChanged() {} + virtual void flexWrapValueChanged() {} + virtual void overflowValueChanged() {} + virtual void intrinsicallySizedValueChanged() {} + virtual void widthUnitsValueChanged() {} + virtual void heightUnitsValueChanged() {} + virtual void borderLeftUnitsValueChanged() {} + virtual void borderRightUnitsValueChanged() {} + virtual void borderTopUnitsValueChanged() {} + virtual void borderBottomUnitsValueChanged() {} + virtual void marginLeftUnitsValueChanged() {} + virtual void marginRightUnitsValueChanged() {} + virtual void marginTopUnitsValueChanged() {} + virtual void marginBottomUnitsValueChanged() {} + virtual void paddingLeftUnitsValueChanged() {} + virtual void paddingRightUnitsValueChanged() {} + virtual void paddingTopUnitsValueChanged() {} + virtual void paddingBottomUnitsValueChanged() {} + virtual void positionLeftUnitsValueChanged() {} + virtual void positionRightUnitsValueChanged() {} + virtual void positionTopUnitsValueChanged() {} + virtual void positionBottomUnitsValueChanged() {} + virtual void gapHorizontalUnitsValueChanged() {} + virtual void gapVerticalUnitsValueChanged() {} + virtual void minWidthUnitsValueChanged() {} + virtual void minHeightUnitsValueChanged() {} + virtual void maxWidthUnitsValueChanged() {} + virtual void maxHeightUnitsValueChanged() {} }; } // namespace rive diff --git a/include/rive/layout/layout_component_style.hpp b/include/rive/layout/layout_component_style.hpp index 4b8c0ffe..861545d5 100644 --- a/include/rive/layout/layout_component_style.hpp +++ b/include/rive/layout/layout_component_style.hpp @@ -1,54 +1,12 @@ #ifndef _RIVE_LAYOUT_COMPONENT_STYLE_HPP_ #define _RIVE_LAYOUT_COMPONENT_STYLE_HPP_ #include "rive/generated/layout/layout_component_style_base.hpp" -#include "rive/math/bit_field_loc.hpp" #ifdef WITH_RIVE_LAYOUT #include "yoga/Yoga.h" #endif #include namespace rive { -// ---- Flags 0 -extern BitFieldLoc DisplayBits; -extern BitFieldLoc PositionTypeBits; -extern BitFieldLoc FlexDirectionBits; -extern BitFieldLoc DirectionBits; -extern BitFieldLoc AlignContentBits; -extern BitFieldLoc AlignItemsBits; -extern BitFieldLoc AlignSelfBits; -extern BitFieldLoc JustifyContentBits; -extern BitFieldLoc FlexWrapBits; -extern BitFieldLoc OverflowBits; -extern BitFieldLoc IntrinsicallySizedBits; -extern BitFieldLoc WidthUnitsBits; -extern BitFieldLoc HeightUnitsBits; - -// ---- Flags 1 -extern BitFieldLoc BorderLeftUnitsBits; -extern BitFieldLoc BorderRightUnitsBits; -extern BitFieldLoc BorderTopUnitsBits; -extern BitFieldLoc BorderBottomUnitsBits; -extern BitFieldLoc MarginLeftUnitsBits; -extern BitFieldLoc MarginRightUnitsBits; -extern BitFieldLoc MarginTopUnitsBits; -extern BitFieldLoc MarginBottomUnitsBits; -extern BitFieldLoc PaddingLeftUnitsBits; -extern BitFieldLoc PaddingRightUnitsBits; -extern BitFieldLoc PaddingTopUnitsBits; -extern BitFieldLoc PaddingBottomUnitsBits; -extern BitFieldLoc PositionLeftUnitsBits; -extern BitFieldLoc PositionRightUnitsBits; -extern BitFieldLoc PositionTopUnitsBits; -extern BitFieldLoc PositionBottomUnitsBits; - -// ---- Flags 2 -extern BitFieldLoc GapHorizontalUnitsBits; -extern BitFieldLoc GapVerticalUnitsBits; -extern BitFieldLoc MinWidthUnitsBits; -extern BitFieldLoc MinHeightUnitsBits; -extern BitFieldLoc MaxWidthUnitsBits; -extern BitFieldLoc MaxHeightUnitsBits; - enum class LayoutAnimationStyle : uint8_t { none, @@ -64,6 +22,22 @@ enum class LayoutStyleInterpolation : uint8_t elastic }; +enum class LayoutAlignmentType : uint8_t +{ + topLeft, + topCenter, + topRight, + centerLeft, + center, + centerRight, + bottomLeft, + bottomCenter, + bottomRight, + spaceBetweenStart, + spaceBetweenCenter, + spaceBetweenEnd +}; + class KeyFrameInterpolator; class LayoutComponentStyle : public LayoutComponentStyleBase { @@ -82,6 +56,7 @@ class LayoutComponentStyle : public LayoutComponentStyleBase LayoutAnimationStyle animationStyle(); YGDisplay display(); YGPositionType positionType(); + LayoutAlignmentType alignmentType(); YGFlexDirection flexDirection(); YGDirection direction(); @@ -124,9 +99,18 @@ class LayoutComponentStyle : public LayoutComponentStyleBase void markLayoutNodeDirty(); void markLayoutStyleDirty(); - void layoutFlags0Changed() override; - void layoutFlags1Changed() override; - void layoutFlags2Changed() override; + void layoutAlignmentTypeChanged() override; + void displayValueChanged() override; + void positionTypeValueChanged() override; + void overflowValueChanged() override; + void intrinsicallySizedValueChanged() override; + void flexDirectionValueChanged() override; + void directionValueChanged() override; + void alignContentValueChanged() override; + void alignItemsValueChanged() override; + void alignSelfValueChanged() override; + void justifyContentValueChanged() override; + void flexWrapValueChanged() override; void flexChanged() override; void flexGrowChanged() override; void flexShrinkChanged() override; @@ -154,6 +138,31 @@ class LayoutComponentStyle : public LayoutComponentStyleBase void positionRightChanged() override; void positionTopChanged() override; void positionBottomChanged() override; + + void widthUnitsValueChanged() override; + void heightUnitsValueChanged() override; + void gapHorizontalUnitsValueChanged() override; + void gapVerticalUnitsValueChanged() override; + void maxWidthUnitsValueChanged() override; + void maxHeightUnitsValueChanged() override; + void minWidthUnitsValueChanged() override; + void minHeightUnitsValueChanged() override; + void borderLeftUnitsValueChanged() override; + void borderRightUnitsValueChanged() override; + void borderTopUnitsValueChanged() override; + void borderBottomUnitsValueChanged() override; + void marginLeftUnitsValueChanged() override; + void marginRightUnitsValueChanged() override; + void marginTopUnitsValueChanged() override; + void marginBottomUnitsValueChanged() override; + void paddingLeftUnitsValueChanged() override; + void paddingRightUnitsValueChanged() override; + void paddingTopUnitsValueChanged() override; + void paddingBottomUnitsValueChanged() override; + void positionLeftUnitsValueChanged() override; + void positionRightUnitsValueChanged() override; + void positionTopUnitsValueChanged() override; + void positionBottomUnitsValueChanged() override; }; } // namespace rive diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index 4a5be758..6b6e31aa 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -85,13 +85,18 @@ class LayoutComponent : public LayoutComponentBase KeyFrameInterpolator* inheritedInterpolator, float inheritedInterpolationTime); void clearInheritedInterpolation(); - AABB layoutBounds() + virtual AABB layoutBounds() { return AABB(m_layoutLocationX, m_layoutLocationY, m_layoutLocationX + m_layoutSizeWidth, m_layoutLocationY + m_layoutSizeHeight); - } + }; + bool hasLayoutMeasurements() + { + return m_layoutLocationX != 0 || m_layoutLocationY != 0 || m_layoutSizeWidth != 0 || + m_layoutSizeHeight != 0; + }; #endif void buildDependencies() override; diff --git a/src/animation/keyframe_uint.cpp b/src/animation/keyframe_uint.cpp new file mode 100644 index 00000000..398abe3a --- /dev/null +++ b/src/animation/keyframe_uint.cpp @@ -0,0 +1,18 @@ +#include "rive/animation/keyframe_uint.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +void KeyFrameUint::apply(Core* object, int propertyKey, float mix) +{ + CoreRegistry::setUint(object, propertyKey, value()); +} + +void KeyFrameUint::applyInterpolation(Core* object, + int propertyKey, + float currentTime, + const KeyFrame* nextFrame, + float mix) +{ + CoreRegistry::setUint(object, propertyKey, value()); +} \ No newline at end of file diff --git a/src/generated/animation/keyframe_uint_base.cpp b/src/generated/animation/keyframe_uint_base.cpp new file mode 100644 index 00000000..35ddbed4 --- /dev/null +++ b/src/generated/animation/keyframe_uint_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/keyframe_uint_base.hpp" +#include "rive/animation/keyframe_uint.hpp" + +using namespace rive; + +Core* KeyFrameUintBase::clone() const +{ + auto cloned = new KeyFrameUint(); + cloned->copy(*this); + return cloned; +} diff --git a/src/layout/layout_component_style.cpp b/src/layout/layout_component_style.cpp index 325e92a6..8fe4a32b 100644 --- a/src/layout/layout_component_style.cpp +++ b/src/layout/layout_component_style.cpp @@ -6,47 +6,6 @@ using namespace rive; -// ---- Flags 0 -BitFieldLoc rive::DisplayBits = BitFieldLoc(0, 0); -BitFieldLoc rive::PositionTypeBits = BitFieldLoc(1, 2); -BitFieldLoc rive::FlexDirectionBits = BitFieldLoc(3, 4); -BitFieldLoc rive::DirectionBits = BitFieldLoc(5, 6); -BitFieldLoc rive::AlignContentBits = BitFieldLoc(7, 9); -BitFieldLoc rive::AlignItemsBits = BitFieldLoc(10, 12); -BitFieldLoc rive::AlignSelfBits = BitFieldLoc(13, 15); -BitFieldLoc rive::JustifyContentBits = BitFieldLoc(16, 18); -BitFieldLoc rive::FlexWrapBits = BitFieldLoc(19, 20); -BitFieldLoc rive::OverflowBits = BitFieldLoc(21, 22); -BitFieldLoc rive::IntrinsicallySizedBits = BitFieldLoc(23, 23); -BitFieldLoc rive::WidthUnitsBits = BitFieldLoc(24, 25); -BitFieldLoc rive::HeightUnitsBits = BitFieldLoc(26, 27); - -// ---- Flags 1 -BitFieldLoc rive::BorderLeftUnitsBits = BitFieldLoc(0, 1); -BitFieldLoc rive::BorderRightUnitsBits = BitFieldLoc(2, 3); -BitFieldLoc rive::BorderTopUnitsBits = BitFieldLoc(4, 5); -BitFieldLoc rive::BorderBottomUnitsBits = BitFieldLoc(6, 7); -BitFieldLoc rive::MarginLeftUnitsBits = BitFieldLoc(8, 9); -BitFieldLoc rive::MarginRightUnitsBits = BitFieldLoc(10, 11); -BitFieldLoc rive::MarginTopUnitsBits = BitFieldLoc(12, 13); -BitFieldLoc rive::MarginBottomUnitsBits = BitFieldLoc(14, 15); -BitFieldLoc rive::PaddingLeftUnitsBits = BitFieldLoc(16, 17); -BitFieldLoc rive::PaddingRightUnitsBits = BitFieldLoc(18, 19); -BitFieldLoc rive::PaddingTopUnitsBits = BitFieldLoc(20, 21); -BitFieldLoc rive::PaddingBottomUnitsBits = BitFieldLoc(22, 23); -BitFieldLoc rive::PositionLeftUnitsBits = BitFieldLoc(24, 25); -BitFieldLoc rive::PositionRightUnitsBits = BitFieldLoc(26, 27); -BitFieldLoc rive::PositionTopUnitsBits = BitFieldLoc(28, 29); -BitFieldLoc rive::PositionBottomUnitsBits = BitFieldLoc(30, 31); - -// ---- Flags 2 -BitFieldLoc rive::GapHorizontalUnitsBits = BitFieldLoc(0, 1); -BitFieldLoc rive::GapVerticalUnitsBits = BitFieldLoc(2, 3); -BitFieldLoc rive::MinWidthUnitsBits = BitFieldLoc(4, 5); -BitFieldLoc rive::MinHeightUnitsBits = BitFieldLoc(6, 7); -BitFieldLoc rive::MaxWidthUnitsBits = BitFieldLoc(8, 9); -BitFieldLoc rive::MaxHeightUnitsBits = BitFieldLoc(10, 11); - #ifdef WITH_RIVE_LAYOUT KeyFrameInterpolator* LayoutComponentStyle::interpolator() { return m_interpolator; } @@ -61,161 +20,82 @@ LayoutAnimationStyle LayoutComponentStyle::animationStyle() return LayoutAnimationStyle(animationStyleType()); } -YGDisplay LayoutComponentStyle::display() { return YGDisplay(DisplayBits.read(layoutFlags0())); } - -YGPositionType LayoutComponentStyle::positionType() +LayoutAlignmentType LayoutComponentStyle::alignmentType() { - return YGPositionType(PositionTypeBits.read(layoutFlags0())); + return LayoutAlignmentType(layoutAlignmentType()); } +YGDisplay LayoutComponentStyle::display() { return YGDisplay(displayValue()); } + +YGPositionType LayoutComponentStyle::positionType() { return YGPositionType(positionTypeValue()); } + YGFlexDirection LayoutComponentStyle::flexDirection() { - return YGFlexDirection(FlexDirectionBits.read(layoutFlags0())); + return YGFlexDirection(flexDirectionValue()); } -YGDirection LayoutComponentStyle::direction() -{ - return YGDirection(DirectionBits.read(layoutFlags0())); -} +YGDirection LayoutComponentStyle::direction() { return YGDirection(directionValue()); } -YGWrap LayoutComponentStyle::flexWrap() { return YGWrap(FlexWrapBits.read(layoutFlags0())); } +YGWrap LayoutComponentStyle::flexWrap() { return YGWrap(flexWrapValue()); } -YGAlign LayoutComponentStyle::alignItems() { return YGAlign(AlignItemsBits.read(layoutFlags0())); } +YGAlign LayoutComponentStyle::alignItems() { return YGAlign(alignItemsValue()); } -YGAlign LayoutComponentStyle::alignSelf() { return YGAlign(AlignSelfBits.read(layoutFlags0())); } +YGAlign LayoutComponentStyle::alignSelf() { return YGAlign(alignSelfValue()); } -YGAlign LayoutComponentStyle::alignContent() -{ - return YGAlign(AlignContentBits.read(layoutFlags0())); -} +YGAlign LayoutComponentStyle::alignContent() { return YGAlign(alignContentValue()); } -YGJustify LayoutComponentStyle::justifyContent() -{ - return YGJustify(JustifyContentBits.read(layoutFlags0())); -} +YGJustify LayoutComponentStyle::justifyContent() { return YGJustify(justifyContentValue()); } -YGOverflow LayoutComponentStyle::overflow() -{ - return YGOverflow(OverflowBits.read(layoutFlags0())); -} +YGOverflow LayoutComponentStyle::overflow() { return YGOverflow(overflowValue()); } -bool LayoutComponentStyle::intrinsicallySized() -{ - return IntrinsicallySizedBits.read(layoutFlags0()) == 1; -} +bool LayoutComponentStyle::intrinsicallySized() { return intrinsicallySizedValue() == 1; } -YGUnit LayoutComponentStyle::widthUnits() { return YGUnit(WidthUnitsBits.read(layoutFlags0())); } +YGUnit LayoutComponentStyle::widthUnits() { return YGUnit(widthUnitsValue()); } -YGUnit LayoutComponentStyle::heightUnits() { return YGUnit(HeightUnitsBits.read(layoutFlags0())); } +YGUnit LayoutComponentStyle::heightUnits() { return YGUnit(heightUnitsValue()); } -YGUnit LayoutComponentStyle::borderLeftUnits() -{ - return YGUnit(BorderLeftUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::borderLeftUnits() { return YGUnit(borderLeftUnitsValue()); } -YGUnit LayoutComponentStyle::borderRightUnits() -{ - return YGUnit(BorderRightUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::borderRightUnits() { return YGUnit(borderRightUnitsValue()); } -YGUnit LayoutComponentStyle::borderTopUnits() -{ - return YGUnit(BorderTopUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::borderTopUnits() { return YGUnit(borderTopUnitsValue()); } -YGUnit LayoutComponentStyle::borderBottomUnits() -{ - return YGUnit(BorderBottomUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::borderBottomUnits() { return YGUnit(borderBottomUnitsValue()); } -YGUnit LayoutComponentStyle::marginLeftUnits() -{ - return YGUnit(MarginLeftUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::marginLeftUnits() { return YGUnit(marginLeftUnitsValue()); } -YGUnit LayoutComponentStyle::marginRightUnits() -{ - return YGUnit(MarginRightUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::marginRightUnits() { return YGUnit(marginRightUnitsValue()); } -YGUnit LayoutComponentStyle::marginTopUnits() -{ - return YGUnit(MarginTopUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::marginTopUnits() { return YGUnit(marginTopUnitsValue()); } -YGUnit LayoutComponentStyle::marginBottomUnits() -{ - return YGUnit(MarginBottomUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::marginBottomUnits() { return YGUnit(marginBottomUnitsValue()); } -YGUnit LayoutComponentStyle::paddingLeftUnits() -{ - return YGUnit(PaddingLeftUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::paddingLeftUnits() { return YGUnit(paddingLeftUnitsValue()); } -YGUnit LayoutComponentStyle::paddingRightUnits() -{ - return YGUnit(PaddingRightUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::paddingRightUnits() { return YGUnit(paddingRightUnitsValue()); } -YGUnit LayoutComponentStyle::paddingTopUnits() -{ - return YGUnit(PaddingTopUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::paddingTopUnits() { return YGUnit(paddingTopUnitsValue()); } -YGUnit LayoutComponentStyle::paddingBottomUnits() -{ - return YGUnit(PaddingBottomUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::paddingBottomUnits() { return YGUnit(paddingBottomUnitsValue()); } -YGUnit LayoutComponentStyle::positionLeftUnits() -{ - return YGUnit(PositionLeftUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::positionLeftUnits() { return YGUnit(positionLeftUnitsValue()); } -YGUnit LayoutComponentStyle::positionRightUnits() -{ - return YGUnit(PositionRightUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::positionRightUnits() { return YGUnit(positionRightUnitsValue()); } -YGUnit LayoutComponentStyle::positionTopUnits() -{ - return YGUnit(PositionTopUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::positionTopUnits() { return YGUnit(positionTopUnitsValue()); } -YGUnit LayoutComponentStyle::positionBottomUnits() -{ - return YGUnit(PositionBottomUnitsBits.read(layoutFlags1())); -} +YGUnit LayoutComponentStyle::positionBottomUnits() { return YGUnit(positionBottomUnitsValue()); } -YGUnit LayoutComponentStyle::gapHorizontalUnits() -{ - return YGUnit(GapHorizontalUnitsBits.read(layoutFlags2())); -} +YGUnit LayoutComponentStyle::gapHorizontalUnits() { return YGUnit(gapHorizontalUnitsValue()); } -YGUnit LayoutComponentStyle::gapVerticalUnits() -{ - return YGUnit(GapVerticalUnitsBits.read(layoutFlags2())); -} +YGUnit LayoutComponentStyle::gapVerticalUnits() { return YGUnit(gapVerticalUnitsValue()); } -YGUnit LayoutComponentStyle::maxWidthUnits() -{ - return YGUnit(MaxWidthUnitsBits.read(layoutFlags2())); -} +YGUnit LayoutComponentStyle::maxWidthUnits() { return YGUnit(maxWidthUnitsValue()); } -YGUnit LayoutComponentStyle::maxHeightUnits() -{ - return YGUnit(MaxHeightUnitsBits.read(layoutFlags2())); -} +YGUnit LayoutComponentStyle::maxHeightUnits() { return YGUnit(maxHeightUnitsValue()); } -YGUnit LayoutComponentStyle::minWidthUnits() -{ - return YGUnit(MinWidthUnitsBits.read(layoutFlags2())); -} -YGUnit LayoutComponentStyle::minHeightUnits() -{ - return YGUnit(MinHeightUnitsBits.read(layoutFlags2())); -} +YGUnit LayoutComponentStyle::minWidthUnits() { return YGUnit(minWidthUnitsValue()); } +YGUnit LayoutComponentStyle::minHeightUnits() { return YGUnit(minHeightUnitsValue()); } void LayoutComponentStyle::markLayoutNodeDirty() { if (parent()->is()) @@ -252,9 +132,19 @@ void LayoutComponentStyle::markLayoutNodeDirty() {} void LayoutComponentStyle::markLayoutStyleDirty() {} #endif -void LayoutComponentStyle::layoutFlags0Changed() { markLayoutNodeDirty(); } -void LayoutComponentStyle::layoutFlags1Changed() { markLayoutNodeDirty(); } -void LayoutComponentStyle::layoutFlags2Changed() { markLayoutNodeDirty(); } +void LayoutComponentStyle::layoutAlignmentTypeChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::displayValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionTypeValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::overflowValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::intrinsicallySizedValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::flexDirectionValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::directionValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::alignContentValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::alignItemsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::alignSelfValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::justifyContentValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::flexWrapValueChanged() { markLayoutNodeDirty(); } + void LayoutComponentStyle::flexChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::flexGrowChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::flexShrinkChanged() { markLayoutNodeDirty(); } @@ -281,4 +171,29 @@ void LayoutComponentStyle::paddingBottomChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::positionLeftChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::positionRightChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::positionTopChanged() { markLayoutNodeDirty(); } -void LayoutComponentStyle::positionBottomChanged() { markLayoutNodeDirty(); } \ No newline at end of file +void LayoutComponentStyle::positionBottomChanged() { markLayoutNodeDirty(); } + +void LayoutComponentStyle::widthUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::heightUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::gapHorizontalUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::gapVerticalUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::maxWidthUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::maxHeightUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::minWidthUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::minHeightUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderLeftUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderRightUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderTopUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::borderBottomUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginLeftUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginRightUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginTopUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::marginBottomUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingLeftUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingRightUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingTopUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::paddingBottomUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionLeftUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionRightUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionTopUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::positionBottomUnitsValueChanged() { markLayoutNodeDirty(); } \ No newline at end of file diff --git a/src/layout_component.cpp b/src/layout_component.cpp index bf32da95..2f393e22 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -138,6 +138,96 @@ void LayoutComponent::syncStyle() { ygStyle.dimensions()[YGDimensionHeight] = YGValueAuto; } + + bool isRowForAlignment = m_style->flexDirection() == YGFlexDirectionRow || + m_style->flexDirection() == YGFlexDirectionRowReverse; + switch (m_style->alignmentType()) + { + case LayoutAlignmentType::topLeft: + case LayoutAlignmentType::topCenter: + case LayoutAlignmentType::topRight: + case LayoutAlignmentType::spaceBetweenStart: + if (isRowForAlignment) + { + ygStyle.alignItems() = YGAlignFlexStart; + } + else + { + ygStyle.justifyContent() = YGJustifyFlexStart; + } + break; + case LayoutAlignmentType::centerLeft: + case LayoutAlignmentType::center: + case LayoutAlignmentType::centerRight: + case LayoutAlignmentType::spaceBetweenCenter: + if (isRowForAlignment) + { + ygStyle.alignItems() = YGAlignCenter; + } + else + { + ygStyle.justifyContent() = YGJustifyCenter; + } + break; + case LayoutAlignmentType::bottomLeft: + case LayoutAlignmentType::bottomCenter: + case LayoutAlignmentType::bottomRight: + case LayoutAlignmentType::spaceBetweenEnd: + if (isRowForAlignment) + { + ygStyle.alignItems() = YGAlignFlexEnd; + } + else + { + ygStyle.justifyContent() = YGJustifyFlexEnd; + } + break; + } + switch (m_style->alignmentType()) + { + case LayoutAlignmentType::topLeft: + case LayoutAlignmentType::centerLeft: + case LayoutAlignmentType::bottomLeft: + if (isRowForAlignment) + { + ygStyle.justifyContent() = YGJustifyFlexStart; + } + else + { + ygStyle.alignItems() = YGAlignFlexStart; + } + break; + case LayoutAlignmentType::topCenter: + case LayoutAlignmentType::center: + case LayoutAlignmentType::bottomCenter: + if (isRowForAlignment) + { + ygStyle.justifyContent() = YGJustifyCenter; + } + else + { + ygStyle.alignItems() = YGAlignCenter; + } + break; + case LayoutAlignmentType::topRight: + case LayoutAlignmentType::centerRight: + case LayoutAlignmentType::bottomRight: + if (isRowForAlignment) + { + ygStyle.justifyContent() = YGJustifyFlexEnd; + } + else + { + ygStyle.alignItems() = YGAlignFlexEnd; + } + break; + case LayoutAlignmentType::spaceBetweenStart: + case LayoutAlignmentType::spaceBetweenCenter: + case LayoutAlignmentType::spaceBetweenEnd: + ygStyle.justifyContent() = YGJustifySpaceBetween; + break; + } + ygStyle.minDimensions()[YGDimensionWidth] = YGValue{m_style->minWidth(), m_style->minWidthUnits()}; ygStyle.minDimensions()[YGDimensionHeight] = @@ -178,10 +268,10 @@ void LayoutComponent::syncStyle() // ygStyle.flexBasis() = m_style->flexBasis(); ygStyle.flexDirection() = m_style->flexDirection(); ygStyle.flexWrap() = m_style->flexWrap(); - ygStyle.alignItems() = m_style->alignItems(); - ygStyle.alignContent() = m_style->alignContent(); + // ygStyle.alignItems() = m_style->alignItems(); + // ygStyle.alignContent() = m_style->alignContent(); ygStyle.alignSelf() = m_style->alignSelf(); - ygStyle.justifyContent() = m_style->justifyContent(); + // ygStyle.justifyContent() = m_style->justifyContent(); ygNode.setStyle(ygStyle); } diff --git a/test/assets/layout/layout_center.riv b/test/assets/layout/layout_center.riv index f64c66c45b0ad117000b417cb66f8d20f125921d..4b57961798497e8d9c3d71f2a9d3fba58878258a 100644 GIT binary patch delta 205 zcmZXNu@1p-7{u>u@1NGzNIijANgtqE5`)!XCw56A79PObL2MFY^djCtY_z43Fm>b4 zByq_tclUk2qil>uuiNif*e~S43$MJJPbR!EWiC0-ESM2LiXGQCaslmDG#QQu(FkQ_ z*F4XAVP`57)JJlmB$SkrQLdC5^)C&OCnXN5AwN^|zk^O;Ddl2%XjgFBwr3yo{L3$^ W5?lps6|d_~6Cnb$R${_m3h)M04>E!P delta 152 zcmZ3;bcfMC$TQ59o#9~hN9H$-@0i~+Gk}0N10y>F!!KtJ5b=(g{S6}n3y)uFxq@R+ zNm71dQ3`_)D~GC~q2d3D4azob49u)d4D77TA`EHfCZaKh=S+?h`WfZIQk&< zCEWTQ0(NxK6J0E%7tS5d<^Il}bFh27W8m$cKDomKPSuFJJmelHlyIB-jQ?j5WB^}v zGrLkXl@QphMe#}KMQ5~H(r%So2kRpW$H2YnFdTl7ETy zY_yp(Iw$q&I6W_PQRvbHx}4F)9NN}^t+iA^s)VKL^iiYfUo-;0;$W>hdl-AMU)lFg a&;MHM4`j#&{YaiSv5hU%o=9Qik$@jVZ*Z&t delta 205 zcmcb{{F2Eb$TQ59o#9~h8^(9c3?LxRz{t+P@XMJ4M7(2Wdc(-T!sC}(uHaZyl9ZoV zl)@myDx_*?X!xID2{S9h#Byadb_QlvW(Iav77+%%xlW=COcR}|K}OYp2%vIdkV@u> wm-M8uN{fJ`IVS5eDx2|vn7lyac!9?8<1kK?L4=h7h*^M`6NvdI&tS9z056;)f&c&j diff --git a/test/assets/layout/layout_horizontal_gaps.riv b/test/assets/layout/layout_horizontal_gaps.riv index a10a936cd31e6d4d480def150d1cf00a542fea0f..75def702e9d29599bd16f72b437f0f960f98ba75 100644 GIT binary patch literal 482 zcmZ|Ly-LGS6bJDC={=XEVyng!N3-|3ImLE2BKaF!N}=Ai7}djcIyG(G^8kXVA5rt`yLw1WYMal~q--TAw>@w*2d6;9E8} k>kB8b7yH(ccX2ftZ9S8we$bE9^$zy13+I&twqFSN2idK1`2YX_ delta 199 zcmaFF{EbN{$TQ59o#9~hN9H$-@0dR^Gc-&z6j$N#OD$J$EGkLLPb^Ad5MmWlH8eE* z&#;7#hfc2*V<2EMsYq6|zEovImtpaw($^$CNtFi*Uv uCyiBF1SHKd*^*J&j1R=*1scZ-G>#vKaiR<&tPDWR0>qp^%s+Vvqa6U_fh5TQ diff --git a/test/assets/layout/layout_horizontal_wrap.riv b/test/assets/layout/layout_horizontal_wrap.riv index f851c6bfb19e65e3c55d3f7977436c5c622978c1..8ecfdbf6882295d7fc12b8bd98792ecbe0737358 100644 GIT binary patch literal 764 zcma*lJ4*vW5C`xXZLFpL$@xS2%S)F$|U z;(#i^S3#3kUm5Blke08w$BtDw1zpT!48!<_7ezpguuj+@Y!bEz+k_p$F0srF@skjq z6dK#LuANJ_;FK<$vR!r!0qj>z_N!)JAt@<7U%3jZ5HYxVGbiBv*}RdH-u{lOi&;N< z$xDxbA~ZHa0mhtct@*U}nR?kvk24)+Iubz7OFBFlz2c=Onbw((2GAKv>x0o*FFnO{ zoasaWy&&oMVDze&PBWckIu$@KN;>I7#{@u32u_F-;Y2wJP70=T!-vI^eO@fvX#=vk k(F50V?ev~?a`snRyGNDR%dYVA25iA5)i$&ZSc~zc>Ke5c2Va`vAgF_id(;C9Hjxk!sUJYx6hs^Z z2fv70KTJvK>Y~r#6i5#K569i}{BF79{j)ue@7{a*LEk37gi&^*3mLkhH-geC~$1nC*jf`oV)w3dVl1Q`V7GoVEY8EMdZ5-Jl^B*@Hw z>JloZL5(CdO;Cj(D+5}RP$do8NJ2BRu}WH%v|5I?ESoT7FOQ!qBc`IHfx;*{B~LLa z7Nv&S=J;u+E3P}fupKm-QzwxZ3H#8yxcWcZd{Q`l01?vl)~f<+V;4JUz0vj$nTC6w diff --git a/test/assets/layout/layout_vertical.riv b/test/assets/layout/layout_vertical.riv index 35248ab5944a2b0d74513ace751dbbdd96c86f84..742e001a38ff5faab138aa31cc505464ae68ac1e 100644 GIT binary patch literal 479 zcmZ|Ly-LGS6bJDC@t#Xku~lP=qg{M}C{i5!Xo`cNi;8>HfCZaKiGt_@h`WfZIQk&< z1v7N&pFsV-ZAiYPoLc30Vit2T^@3eV~V-WE$%b^pGA-X zd{xc#O4L+LV6)PQPC~D721{GZj^ljeRcW*sZKe)Wm#N3pXBsdKS!@|dBPKj6p4;(T zBR9dY)6r(e=#12>|x|Z ferex3J^yR1Kae3C^c(WLiEV75@+-$TQ59o#9~h8^(9c@0lm+ODgjCrIsr=7L_FBCl;kJ2(b#O8X6k@XIR3_ z%J81KsiQ$-VuP|8I|DN-GXpy-iwFbXTqjWmrio6~3_wr=B7mBNLF$<&Hi%4oFU1a3 tF@q4WX_8Gx7th&h3nfAT^`I{?=%BxV2r diff --git a/test/assets/layout/measure_tests.riv b/test/assets/layout/measure_tests.riv index 1f4e5cc96af3a5ff1f7cd83befbe49de26e6ce7b..9d8595eba38a27f92f13e8cdddd94c96830257db 100644 GIT binary patch delta 434 zcmYk2J4-`R49An4oO^wA5K-qYU4{DreAFVS6bBKP1HwfME%*Q*pp!ZrtKd*8QbnsR zxQaM9`2_?W92{+R@lm}9ij#}xf`Wm65(xS6Pbzy}Wyc#E>L2NK;dl+-`H>6s!W(pj zZ|aclI7c6RgO;E8mG`Mc_x#KO23({v<>`U5T;oeTpejQcDC!o`uhyjYh5d@L2CX4$ zlr?OPw#Ko>wWiLRdTSc2X*@HLvwdEPf1DGd*dkBm=@ z&x|$37sgi>M`9j77-3g&!*FV0F6l2$&(CQP;8qB16(ENIWyR}YBFnIRlBhD?vASpV zOIrGmT19sHG9gT>eWF8BMS@_l=YSx-*#qmSbzUwl#S4;isGTx>-k$EcfBkjw+%3uI zA|V$Le!rck4{d{q@q*)WU77^S~Q59!e}zm-qf)zFYSVO JK}t7t!Vh$ncsl?9 delta 773 zcmZ`$O>0v@6umQdCV4MS8;yyIn`U8)AXc*R1GOeE3Vvi!q_`0m?N~6P7D|MOg}fw8 zqeUbHB$g7IfS?-}F1m8#qKkkoTy$ywK}kPoAqBDCc};~1J~)Tr-Z}TYduHWbd}Tg< z@6OG;*Zt6(VXoM~CAN(s-j!jst$Ly=Nq(1{v4u+A~#-sicGm}9T^3$u)t(&EA= zD^(Wf-kfzHB7uMen-Hq?r-MWJVYu>^0VLomBx{TTTVg=&p%l4y$UR^~!nyW0bN(rJ%=JNI+4q!$DU6<%S!O1ALmJB!weI?8yVA;e1T(~!>=I+UNMPPZq~06hh^~e zz%G4IVNx{t*3ZxL{{8ch`WJtLF11onCRK%t+V9)J6ZdJs?$aFzUAtfD72UuVn$#$C x;tp{vx#O`3J?4cTOLmhG(0@KKnt3wuIP-KO7QdLg#A|2L!Pud0Cf!65@CSG5F? From d18ecfb9c7d9a9c745cce1719c3f0d1a5716c1c9 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Sun, 30 Jun 2024 15:00:08 +0000 Subject: [PATCH 077/138] Xxxx transitions with base virtual animation Diffs= f9b1e8ec2 Xxxx transitions with base virtual animation (#7157) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/animation/animation_reset.hpp | 32 +++ .../animation/animation_reset_factory.hpp | 40 ++++ .../animation/animation_state_instance.hpp | 2 +- .../animation/blend_state_1d_instance.hpp | 5 + .../rive/animation/blend_state_instance.hpp | 14 +- include/rive/animation/keyed_object.hpp | 14 ++ include/rive/animation/keyed_property.hpp | 8 + include/rive/animation/layer_state_flags.hpp | 2 + include/rive/animation/linear_animation.hpp | 15 +- include/rive/animation/state_instance.hpp | 2 +- .../rive/animation/system_state_instance.hpp | 2 +- include/rive/core/binary_data_reader.hpp | 38 ++++ include/rive/core/binary_reader.hpp | 1 + include/rive/core/binary_stream.hpp | 20 ++ include/rive/core/binary_writer.hpp | 31 +++ include/rive/core/reader.h | 46 +++- include/rive/core/vector_binary_writer.hpp | 43 ++++ src/animation/animation_reset.cpp | 49 ++++ src/animation/animation_reset_factory.cpp | 210 ++++++++++++++++++ src/animation/animation_state_instance.cpp | 5 +- src/animation/blend_state_1d_instance.cpp | 32 ++- src/animation/state_machine_instance.cpp | 33 ++- src/animation/system_state_instance.cpp | 2 +- src/core/binary_data_reader.cpp | 102 +++++++++ src/core/binary_reader.cpp | 2 + src/core/binary_writer.cpp | 120 ++++++++++ test/assets/animation_reset_cases.riv | Bin 0 -> 2105 bytes test/state_machine_test.cpp | 172 ++++++++++++++ 29 files changed, 1032 insertions(+), 12 deletions(-) create mode 100644 include/rive/animation/animation_reset.hpp create mode 100644 include/rive/animation/animation_reset_factory.hpp create mode 100644 include/rive/core/binary_data_reader.hpp create mode 100644 include/rive/core/binary_stream.hpp create mode 100644 include/rive/core/binary_writer.hpp create mode 100644 include/rive/core/vector_binary_writer.hpp create mode 100644 src/animation/animation_reset.cpp create mode 100644 src/animation/animation_reset_factory.cpp create mode 100644 src/core/binary_data_reader.cpp create mode 100644 src/core/binary_writer.cpp create mode 100644 test/assets/animation_reset_cases.riv diff --git a/.rive_head b/.rive_head index a74cdfb5..853c9155 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e5db5a652fedb8dd8c9708f02536e23ab12210d9 +f9b1e8ec2ff7960990f87ef855c669f6a4a86b1d diff --git a/include/rive/animation/animation_reset.hpp b/include/rive/animation/animation_reset.hpp new file mode 100644 index 00000000..6be0c995 --- /dev/null +++ b/include/rive/animation/animation_reset.hpp @@ -0,0 +1,32 @@ +#ifndef _RIVE_ANIMATION_RESET_HPP_ +#define _RIVE_ANIMATION_RESET_HPP_ + +#include +#include "rive/artboard.hpp" +#include +#include "rive/core/binary_writer.hpp" +#include "rive/core/vector_binary_writer.hpp" +#include "rive/core/binary_data_reader.hpp" + +namespace rive +{ + +class AnimationReset +{ +private: + VectorBinaryWriter m_binaryWriter; + BinaryDataReader m_binaryReader; + std::vector m_WriteBuffer; + +public: + AnimationReset(); + void writeObjectId(uint32_t objectId); + void writeTotalProperties(uint8_t value); + void writePropertyKey(uint8_t value); + void writePropertyValue(float value); + void apply(Artboard* artboard); + void complete(); + void clear(); +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/animation/animation_reset_factory.hpp b/include/rive/animation/animation_reset_factory.hpp new file mode 100644 index 00000000..8a4db56e --- /dev/null +++ b/include/rive/animation/animation_reset_factory.hpp @@ -0,0 +1,40 @@ +#ifndef _RIVE_ANIMATION_RESET_FACTORY_HPP_ +#define _RIVE_ANIMATION_RESET_FACTORY_HPP_ + +#include +#include +#include "rive/animation/animation_reset.hpp" +#include "rive/animation/state_instance.hpp" +#include "rive/animation/linear_animation.hpp" +#include "rive/artboard.hpp" + +namespace rive +{ + +class AnimationResetFactory +{ + static std::vector> m_resources; + static std::mutex m_mutex; + +private: + static void fromState(StateInstance* stateInstance, + std::vector& animations); + +public: + static std::unique_ptr getInstance(); + static std::unique_ptr fromStates(StateInstance* stateFrom, + StateInstance* currentState, + ArtboardInstance* artboard); + static std::unique_ptr fromAnimations( + std::vector& animations, + ArtboardInstance* artboard, + bool useFirstAsBaseline); + static void release(std::unique_ptr value); +#ifdef TESTING + // Used in testing to check pooled resources; + static int resourcesCount() { return m_resources.size(); }; + static void releaseResources() { m_resources.clear(); }; +#endif +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/animation/animation_state_instance.hpp b/include/rive/animation/animation_state_instance.hpp index 0eb15cc9..7e73343e 100644 --- a/include/rive/animation/animation_state_instance.hpp +++ b/include/rive/animation/animation_state_instance.hpp @@ -20,7 +20,7 @@ class AnimationStateInstance : public StateInstance AnimationStateInstance(const AnimationState* animationState, ArtboardInstance* instance); void advance(float seconds, StateMachineInstance* stateMachineInstance) override; - void apply(float mix) override; + void apply(ArtboardInstance* instance, float mix) override; bool keepGoing() const override; void clearSpilledTime() override; diff --git a/include/rive/animation/blend_state_1d_instance.hpp b/include/rive/animation/blend_state_1d_instance.hpp index d0c81a2d..ed1df09f 100644 --- a/include/rive/animation/blend_state_1d_instance.hpp +++ b/include/rive/animation/blend_state_1d_instance.hpp @@ -4,6 +4,8 @@ #include "rive/animation/blend_state_instance.hpp" #include "rive/animation/blend_state_1d.hpp" #include "rive/animation/blend_animation_1d.hpp" +#include "rive/animation/animation_reset.hpp" +#include "rive/animation/animation_reset_factory.hpp" namespace rive { @@ -12,11 +14,14 @@ class BlendState1DInstance : public BlendStateInstance* m_From = nullptr; BlendStateAnimationInstance* m_To = nullptr; + std::unique_ptr m_AnimationReset; int animationIndex(float value); public: BlendState1DInstance(const BlendState1D* blendState, ArtboardInstance* instance); + ~BlendState1DInstance(); void advance(float seconds, StateMachineInstance* stateMachineInstance) override; + void apply(ArtboardInstance* instance, float mix) override; }; } // namespace rive #endif \ No newline at end of file diff --git a/include/rive/animation/blend_state_instance.hpp b/include/rive/animation/blend_state_instance.hpp index fb52f12c..bf34466f 100644 --- a/include/rive/animation/blend_state_instance.hpp +++ b/include/rive/animation/blend_state_instance.hpp @@ -5,8 +5,11 @@ #include #include "rive/animation/state_instance.hpp" #include "rive/animation/blend_state.hpp" +#include "rive/animation/layer_state_flags.hpp" #include "rive/animation/linear_animation_instance.hpp" #include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/animation_reset.hpp" +#include "rive/animation/animation_reset_factory.hpp" namespace rive { @@ -49,6 +52,15 @@ template class BlendStateInstance : public StateInstance m_AnimationInstances.emplace_back( BlendStateAnimationInstance(static_cast(blendAnimation), instance)); } + if ((static_cast(blendState->flags()) & LayerStateFlags::Reset) == + LayerStateFlags::Reset) + { + auto animations = std::vector(); + for (auto blendAnimation : blendState->animations()) + { + animations.push_back(blendAnimation->animation()); + } + } } bool keepGoing() const override { return m_KeepGoing; } @@ -71,7 +83,7 @@ template class BlendStateInstance : public StateInstance } } - void apply(float mix) override + void apply(ArtboardInstance* instance, float mix) override { for (auto& animation : m_AnimationInstances) { diff --git a/include/rive/animation/keyed_object.hpp b/include/rive/animation/keyed_object.hpp index 860e11fc..3aba7b9f 100644 --- a/include/rive/animation/keyed_object.hpp +++ b/include/rive/animation/keyed_object.hpp @@ -24,6 +24,20 @@ class KeyedObject : public KeyedObjectBase StatusCode import(ImportStack& importStack) override; + const KeyedProperty* getProperty(size_t index) const + { + if (index < m_keyedProperties.size()) + { + return m_keyedProperties[index].get(); + } + else + { + return nullptr; + } + } + + size_t numKeyedProperties() const { return m_keyedProperties.size(); } + private: std::vector> m_keyedProperties; }; diff --git a/include/rive/animation/keyed_property.hpp b/include/rive/animation/keyed_property.hpp index 1ef73ce5..d9d04256 100644 --- a/include/rive/animation/keyed_property.hpp +++ b/include/rive/animation/keyed_property.hpp @@ -26,6 +26,14 @@ class KeyedProperty : public KeyedPropertyBase void apply(Core* object, float time, float mix); StatusCode import(ImportStack& importStack) override; + KeyFrame* first() const + { + if (m_keyFrames.size() > 0) + { + return m_keyFrames.front().get(); + } + return nullptr; + } private: int closestFrameIndex(float seconds, int exactOffset = 0) const; diff --git a/include/rive/animation/layer_state_flags.hpp b/include/rive/animation/layer_state_flags.hpp index 880bd35a..c9d61346 100644 --- a/include/rive/animation/layer_state_flags.hpp +++ b/include/rive/animation/layer_state_flags.hpp @@ -12,6 +12,8 @@ enum class LayerStateFlags : unsigned char /// Whether the transition is disabled. Random = 1 << 0, + /// Whether the blend should include an instance to reset values on apply + Reset = 1 << 1, }; inline constexpr LayerStateFlags operator&(LayerStateFlags lhs, LayerStateFlags rhs) diff --git a/include/rive/animation/linear_animation.hpp b/include/rive/animation/linear_animation.hpp index f7aa60ea..01f92053 100644 --- a/include/rive/animation/linear_animation.hpp +++ b/include/rive/animation/linear_animation.hpp @@ -42,8 +42,21 @@ class LinearAnimation : public LinearAnimationBase /// work area start/end, speed, looping). float globalToLocalSeconds(float seconds) const; + const KeyedObject* getObject(size_t index) const + { + if (index < m_KeyedObjects.size()) + { + return m_KeyedObjects[index].get(); + } + else + { + return nullptr; + } + } + + size_t numKeyedObjects() const { return m_KeyedObjects.size(); } + #ifdef TESTING - size_t numKeyedObjects() { return m_KeyedObjects.size(); } // Used in testing to check how many animations gets deleted. static int deleteCount; #endif diff --git a/include/rive/animation/state_instance.hpp b/include/rive/animation/state_instance.hpp index 401b9f06..1dffd9da 100644 --- a/include/rive/animation/state_instance.hpp +++ b/include/rive/animation/state_instance.hpp @@ -22,7 +22,7 @@ class StateInstance StateInstance(const LayerState* layerState); virtual ~StateInstance(); virtual void advance(float seconds, StateMachineInstance* stateMachineInstance) = 0; - virtual void apply(float mix) = 0; + virtual void apply(ArtboardInstance* instance, float mix) = 0; /// Returns true when the State Machine needs to keep advancing this /// state. diff --git a/include/rive/animation/system_state_instance.hpp b/include/rive/animation/system_state_instance.hpp index b439da8f..49f64b0e 100644 --- a/include/rive/animation/system_state_instance.hpp +++ b/include/rive/animation/system_state_instance.hpp @@ -17,7 +17,7 @@ class SystemStateInstance : public StateInstance SystemStateInstance(const LayerState* layerState, ArtboardInstance* instance); void advance(float seconds, StateMachineInstance* stateMachineInstance) override; - void apply(float mix) override; + void apply(ArtboardInstance* artboard, float mix) override; bool keepGoing() const override; }; diff --git a/include/rive/core/binary_data_reader.hpp b/include/rive/core/binary_data_reader.hpp new file mode 100644 index 00000000..beae449a --- /dev/null +++ b/include/rive/core/binary_data_reader.hpp @@ -0,0 +1,38 @@ +#ifndef _RIVE_CORE_BINARY_DATA_READER_HPP_ +#define _RIVE_CORE_BINARY_DATA_READER_HPP_ + +#include +#include + +namespace rive +{ +class BinaryDataReader +{ +private: + uint8_t* m_Position; + uint8_t* m_End; + bool m_Overflowed; + size_t m_Length; + + void overflow(); + +public: + BinaryDataReader(uint8_t* bytes, size_t length); + bool didOverflow() const; + bool isEOF() const { return m_Position >= m_End; } + const uint8_t* position() const { return m_Position; } + + size_t lengthInBytes() const; + + uint64_t readVarUint(); + uint32_t readVarUint32(); + double readFloat64(); + float readFloat32(); + uint8_t readByte(); + uint32_t readUint32(); + void complete(uint8_t* bytes, size_t length); + void reset(uint8_t* bytes); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/core/binary_reader.hpp b/include/rive/core/binary_reader.hpp index c0c2c3be..00687da8 100644 --- a/include/rive/core/binary_reader.hpp +++ b/include/rive/core/binary_reader.hpp @@ -49,6 +49,7 @@ class BinaryReader } return static_cast(value); } + void reset(); }; } // namespace rive diff --git a/include/rive/core/binary_stream.hpp b/include/rive/core/binary_stream.hpp new file mode 100644 index 00000000..f582ccf3 --- /dev/null +++ b/include/rive/core/binary_stream.hpp @@ -0,0 +1,20 @@ +#ifndef _RIVE_CORE_BINARY_STREAM_HPP_ +#define _RIVE_CORE_BINARY_STREAM_HPP_ + +#include +#include + +namespace rive +{ +// Used to write binary chunks to an underlying stream, makes no assumptions +// regarding storage/streaming it can flush the contents as it needs. +class BinaryStream +{ +public: + virtual void write(const uint8_t* bytes, std::size_t length) = 0; + virtual void flush() = 0; + virtual void clear() = 0; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/core/binary_writer.hpp b/include/rive/core/binary_writer.hpp new file mode 100644 index 00000000..213e295a --- /dev/null +++ b/include/rive/core/binary_writer.hpp @@ -0,0 +1,31 @@ + +#ifndef _RIVE_CORE_BINARY_WRITER_HPP_ +#define _RIVE_CORE_BINARY_WRITER_HPP_ + +#include +#include + +namespace rive +{ +class BinaryStream; +class BinaryWriter +{ +private: + BinaryStream* m_Stream; + +public: + BinaryWriter(BinaryStream* stream); + ~BinaryWriter(); + void write(float value); + void writeFloat(float value); + void write(double value); + void writeVarUint(uint64_t value); + void writeVarUint(uint32_t value); + void write(const uint8_t* bytes, std::size_t length); + void write(uint8_t value); + void writeDouble(double value); + void clear(); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/core/reader.h b/include/rive/core/reader.h index f6969ba9..45c8ffda 100644 --- a/include/rive/core/reader.h +++ b/include/rive/core/reader.h @@ -35,6 +35,29 @@ inline size_t decode_uint_leb(const uint8_t* buf, const uint8_t* buf_end, uint64 return p - buf; } +/* Decode an unsigned int LEB128 at buf into r, returning the nr of bytes read. + */ +inline size_t decode_uint_leb32(const uint8_t* buf, const uint8_t* buf_end, uint32_t* r) +{ + const uint8_t* p = buf; + uint8_t shift = 0; + uint32_t result = 0; + uint8_t byte; + + do + { + if (p >= buf_end) + { + return 0; + } + byte = *p++; + result |= ((uint32_t)(byte & 0x7f)) << shift; + shift += 7; + } while ((byte & 0x80) != 0); + *r = result; + return p - buf; +} + /* Decodes a string */ inline uint64_t decode_string(uint64_t str_len, @@ -57,6 +80,27 @@ inline uint64_t decode_string(uint64_t str_len, return str_len; } +/* Decodes a double (8 bytes) + */ +inline size_t decode_double(const uint8_t* buf, const uint8_t* buf_end, double* r) +{ + // Return zero bytes read on buffer overflow + if (buf_end - buf < sizeof(double)) + { + return 0; + } + if (is_big_endian()) + { + uint8_t inverted[8] = {buf[7], buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]}; + memcpy(r, inverted, sizeof(double)); + } + else + { + memcpy(r, buf, sizeof(double)); + } + return sizeof(double); +} + /* Decodes a float (4 bytes) */ inline size_t decode_float(const uint8_t* buf, const uint8_t* buf_end, float* r) @@ -110,4 +154,4 @@ inline size_t decode_uint_32(const uint8_t* buf, const uint8_t* buf_end, uint32_ memcpy(r, buf, sizeof(uint32_t)); } return sizeof(uint32_t); -} +} \ No newline at end of file diff --git a/include/rive/core/vector_binary_writer.hpp b/include/rive/core/vector_binary_writer.hpp new file mode 100644 index 00000000..34ba6491 --- /dev/null +++ b/include/rive/core/vector_binary_writer.hpp @@ -0,0 +1,43 @@ +#ifndef _RIVE_CORE_VECTOR_BINARY_WRITER_HPP_ +#define _RIVE_CORE_VECTOR_BINARY_WRITER_HPP_ + +#include "rive/core/binary_stream.hpp" +#include "rive/core/binary_writer.hpp" +#include + +namespace rive +{ +class VectorBinaryWriter : public BinaryStream, public BinaryWriter +{ +private: + std::vector* m_WriteBuffer; + std::size_t m_Start; + size_t m_pos = 0; + +public: + VectorBinaryWriter(std::vector* buffer) : + BinaryWriter(this), m_WriteBuffer(buffer), m_Start(m_WriteBuffer->size()) + {} + + uint8_t* buffer() const { return &(*m_WriteBuffer)[m_Start]; } + std::size_t bufferSize() const { return m_WriteBuffer->size() - m_Start; } + + std::size_t start() const { return m_Start; } + size_t size() const { return m_pos; } + + using BinaryWriter::write; + void write(const uint8_t* bytes, std::size_t length) override + { + auto end = m_pos; + if (m_WriteBuffer->size() < end + length) + { + m_WriteBuffer->resize(end + length); + } + std::memcpy(&((*m_WriteBuffer)[end]), bytes, length); + m_pos += length; + } + void flush() override {} + void clear() override { m_pos = 0; } +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/src/animation/animation_reset.cpp b/src/animation/animation_reset.cpp new file mode 100644 index 00000000..87b906ae --- /dev/null +++ b/src/animation/animation_reset.cpp @@ -0,0 +1,49 @@ +#include "rive/animation/animation_reset.hpp" +#include "rive/core/vector_binary_writer.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +AnimationReset::AnimationReset() : m_binaryWriter(&m_WriteBuffer), m_binaryReader(nullptr, 0) {} + +void AnimationReset::writeObjectId(uint32_t objectId) { m_binaryWriter.writeVarUint(objectId); } + +void AnimationReset::writeTotalProperties(uint8_t value) { m_binaryWriter.write(value); } + +void AnimationReset::writePropertyKey(uint8_t value) { m_binaryWriter.write(value); } + +void AnimationReset::writePropertyValue(float value) { m_binaryWriter.writeFloat(value); } + +void AnimationReset::clear() { m_binaryWriter.clear(); } + +void AnimationReset::complete() +{ + m_binaryReader.complete(&m_WriteBuffer.front(), m_binaryWriter.size()); +} + +void AnimationReset::apply(Artboard* artboard) +{ + m_binaryReader.reset(&m_WriteBuffer.front()); + while (!m_binaryReader.isEOF()) + { + auto objectId = m_binaryReader.readVarUint32(); + auto object = artboard->resolve(objectId); + auto totalProperties = m_binaryReader.readByte(); + auto currentPropertyIndex = 0; + while (currentPropertyIndex < totalProperties) + { + auto propertyKey = m_binaryReader.readByte(); + auto propertyValue = m_binaryReader.readFloat32(); + switch (CoreRegistry::propertyFieldId(propertyKey)) + { + case CoreDoubleType::id: + CoreRegistry::setDouble(object, propertyKey, propertyValue); + break; + case CoreColorType::id: + CoreRegistry::setColor(object, propertyKey, propertyValue); + break; + } + currentPropertyIndex++; + } + } +} diff --git a/src/animation/animation_reset_factory.cpp b/src/animation/animation_reset_factory.cpp new file mode 100644 index 00000000..a08f35f8 --- /dev/null +++ b/src/animation/animation_reset_factory.cpp @@ -0,0 +1,210 @@ +#include "rive/animation/animation_reset_factory.hpp" +#include "rive/animation/linear_animation.hpp" +#include "rive/animation/animation_state.hpp" +#include "rive/animation/keyed_object.hpp" +#include "rive/animation/keyed_property.hpp" +#include "rive/generated/core_registry.hpp" +#include +#include + +using namespace rive; + +class KeyedPropertyData +{ +public: + const KeyedProperty* keyedProperty; + bool isBaseline; + KeyedPropertyData(const KeyedProperty* value, bool baselineValue) : + keyedProperty(value), isBaseline(baselineValue) + {} +}; + +class KeyedObjectData +{ +public: + std::vector keyedPropertiesData; + std::set keyedPropertiesSet; + uint32_t objectId; + KeyedObjectData(const uint32_t value) { objectId = value; } + void addProperties(const KeyedObject* keyedObject, bool isBaseline) + { + size_t index = 0; + while (index < keyedObject->numKeyedProperties()) + { + auto keyedProperty = keyedObject->getProperty(index); + auto pos = keyedPropertiesSet.find(keyedProperty->propertyKey()); + if (pos == keyedPropertiesSet.end()) + { + keyedPropertiesSet.insert(keyedProperty->propertyKey()); + keyedPropertiesData.push_back(KeyedPropertyData(keyedProperty, isBaseline)); + } + index++; + } + } +}; + +class AnimationsData +{ + +private: + std::vector> keyedObjectsData; + KeyedObjectData* getKeyedObjectData(const KeyedObject* keyedObject) + { + for (auto& keyedObjectData : keyedObjectsData) + { + if (keyedObjectData->objectId == keyedObject->objectId()) + { + return keyedObjectData.get(); + } + } + + auto keyedObjectData = rivestd::make_unique(keyedObject->objectId()); + auto ref = keyedObjectData.get(); + keyedObjectsData.push_back(std::move(keyedObjectData)); + return ref; + } + + void findKeyedObjects(const LinearAnimation* animation, bool isFirstAnimation) + { + + size_t index = 0; + while (index < animation->numKeyedObjects()) + { + auto keyedObject = animation->getObject(index); + auto keyedObjectData = getKeyedObjectData(keyedObject); + + keyedObjectData->addProperties(keyedObject, isFirstAnimation); + index++; + } + } + +public: + AnimationsData(std::vector& animations, bool useFirstAsBaseline) + { + bool isFirstAnimation = useFirstAsBaseline; + for (auto animation : animations) + { + findKeyedObjects(animation, isFirstAnimation); + isFirstAnimation = false; + } + } + + void writeObjects(AnimationReset* animationReset, ArtboardInstance* artboard) + { + for (auto& keyedObjectData : keyedObjectsData) + { + auto object = artboard->resolve(keyedObjectData->objectId)->as(); + auto propertiesData = keyedObjectData->keyedPropertiesData; + if (propertiesData.size() > 0) + { + animationReset->writeObjectId(keyedObjectData->objectId); + animationReset->writeTotalProperties(propertiesData.size()); + for (auto keyedPropertyData : propertiesData) + { + auto keyedProperty = keyedPropertyData.keyedProperty; + auto propertyKey = keyedProperty->propertyKey(); + switch (CoreRegistry::propertyFieldId(propertyKey)) + { + case CoreDoubleType::id: + animationReset->writePropertyKey(propertyKey); + if (keyedPropertyData.isBaseline) + { + auto firstKeyframe = keyedProperty->first(); + if (firstKeyframe != nullptr) + { + auto value = + keyedProperty->first()->as()->value(); + animationReset->writePropertyValue(value); + } + } + else + { + animationReset->writePropertyValue( + CoreRegistry::getDouble(object, propertyKey)); + } + break; + case CoreColorType::id: + + animationReset->writePropertyKey(propertyKey); + if (keyedPropertyData.isBaseline) + { + auto firstKeyframe = keyedProperty->first(); + if (firstKeyframe != nullptr) + { + auto value = + keyedProperty->first()->as()->value(); + animationReset->writePropertyValue(value); + } + } + else + { + animationReset->writePropertyValue( + CoreRegistry::getColor(object, propertyKey)); + } + break; + } + } + } + } + animationReset->complete(); + } +}; + +std::unique_ptr AnimationResetFactory::getInstance() +{ + std::unique_lock lock(m_mutex); + if (m_resources.size() > 0) + { + auto instance = std::move(m_resources.back()); + m_resources.pop_back(); + return instance; + } + auto instance = rivestd::make_unique(); + return instance; +} + +void AnimationResetFactory::fromState(StateInstance* stateInstance, + std::vector& animations) +{ + if (stateInstance != nullptr) + { + auto state = stateInstance->state(); + if (state->is()) + { + animations.push_back(state->as()->animation()); + } + } +} + +std::unique_ptr AnimationResetFactory::fromStates(StateInstance* stateFrom, + StateInstance* currentState, + ArtboardInstance* artboard) +{ + std::vector animations; + fromState(stateFrom, animations); + fromState(currentState, animations); + return fromAnimations(animations, artboard, false); +} + +std::unique_ptr AnimationResetFactory::fromAnimations( + std::vector& animations, + ArtboardInstance* artboard, + bool useFirstAsBaseline) +{ + auto animationsData = new AnimationsData(animations, useFirstAsBaseline); + auto animationReset = AnimationResetFactory::getInstance(); + animationsData->writeObjects(animationReset.get(), artboard); + delete animationsData; + return animationReset; +} + +std::vector> AnimationResetFactory::m_resources; + +std::mutex AnimationResetFactory::m_mutex; + +void AnimationResetFactory::release(std::unique_ptr value) +{ + std::unique_lock lock(m_mutex); + value->clear(); + m_resources.push_back(std::move(value)); +} diff --git a/src/animation/animation_state_instance.cpp b/src/animation/animation_state_instance.cpp index 07395500..5cae3e8f 100644 --- a/src/animation/animation_state_instance.cpp +++ b/src/animation/animation_state_instance.cpp @@ -30,7 +30,10 @@ void AnimationStateInstance::advance(float seconds, StateMachineInstance* stateM stateMachineInstance); } -void AnimationStateInstance::apply(float mix) { m_AnimationInstance.apply(mix); } +void AnimationStateInstance::apply(ArtboardInstance* instance, float mix) +{ + m_AnimationInstance.apply(mix); +} bool AnimationStateInstance::keepGoing() const { return m_KeepGoing; } void AnimationStateInstance::clearSpilledTime() { m_AnimationInstance.clearSpilledTime(); } \ No newline at end of file diff --git a/src/animation/blend_state_1d_instance.cpp b/src/animation/blend_state_1d_instance.cpp index 69022737..f1049ba0 100644 --- a/src/animation/blend_state_1d_instance.cpp +++ b/src/animation/blend_state_1d_instance.cpp @@ -1,12 +1,33 @@ #include "rive/animation/blend_state_1d_instance.hpp" #include "rive/animation/state_machine_input_instance.hpp" +#include "rive/animation/layer_state_flags.hpp" using namespace rive; BlendState1DInstance::BlendState1DInstance(const BlendState1D* blendState, ArtboardInstance* instance) : BlendStateInstance(blendState, instance) -{} +{ + + if ((static_cast(blendState->flags()) & LayerStateFlags::Reset) == + LayerStateFlags::Reset) + { + auto animations = std::vector(); + for (auto blendAnimation : blendState->animations()) + { + animations.push_back(blendAnimation->animation()); + } + m_AnimationReset = AnimationResetFactory::fromAnimations(animations, instance, true); + } +} + +BlendState1DInstance::~BlendState1DInstance() +{ + if (m_AnimationReset != nullptr) + { + AnimationResetFactory::release(std::move(m_AnimationReset)); + } +} int BlendState1DInstance::animationIndex(float value) { @@ -39,6 +60,15 @@ int BlendState1DInstance::animationIndex(float value) return idx; } +void BlendState1DInstance::apply(ArtboardInstance* instance, float mix) +{ + if (m_AnimationReset != nullptr) + { + m_AnimationReset->apply(instance); + } + BlendStateInstance::apply(instance, mix); +} + void BlendState1DInstance::advance(float seconds, StateMachineInstance* stateMachineInstance) { BlendStateInstance::advance(seconds, stateMachineInstance); diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index e70d4f40..51f01f13 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -1,3 +1,5 @@ +#include "rive/animation/animation_reset.hpp" +#include "rive/animation/animation_reset_factory.hpp" #include "rive/animation/animation_state_instance.hpp" #include "rive/animation/animation_state.hpp" #include "rive/animation/any_state.hpp" @@ -70,6 +72,7 @@ class StateMachineLayerInstance if (m_mix == 1.0f && !m_transitionCompleted) { m_transitionCompleted = true; + clearAnimationReset(); fireEvents(StateMachineFireOccurance::atEnd, m_transition->events()); } } @@ -256,6 +259,21 @@ class StateMachineLayerInstance return nullptr; } + void buildAnimationResetForTransition() + { + m_animationReset = + AnimationResetFactory::fromStates(m_stateFrom, m_currentState, m_artboardInstance); + } + + void clearAnimationReset() + { + if (m_animationReset != nullptr) + { + AnimationResetFactory::release(std::move(m_animationReset)); + m_animationReset = nullptr; + } + } + bool tryChangeState(StateInstance* stateFromInstance, bool ignoreTriggers) { if (stateFromInstance == nullptr) @@ -266,6 +284,7 @@ class StateMachineLayerInstance auto transition = findAllowedTransition(stateFromInstance, ignoreTriggers); if (transition != nullptr) { + clearAnimationReset(); changeState(transition->stateTo()); m_stateMachineChangedOnAdvance = true; // state actually has changed @@ -288,6 +307,11 @@ class StateMachineLayerInstance } m_stateFrom = outState; + if (!m_transitionCompleted) + { + buildAnimationResetForTransition(); + } + // If we had an exit time and wanted to pause on exit, make // sure to hold the exit time. Delegate this to the // transition by telling it that it was completed. @@ -327,6 +351,10 @@ class StateMachineLayerInstance void apply(/*Artboard* artboard*/) { + if (m_animationReset != nullptr) + { + m_animationReset->apply(m_artboardInstance); + } if (m_holdAnimation != nullptr) { m_holdAnimation->apply(m_artboardInstance, m_holdTime, m_mixFrom); @@ -342,12 +370,12 @@ class StateMachineLayerInstance if (m_stateFrom != nullptr && m_mix < 1.0f) { auto fromMix = cubic != nullptr ? cubic->transform(m_mixFrom) : m_mixFrom; - m_stateFrom->apply(fromMix); + m_stateFrom->apply(m_artboardInstance, fromMix); } if (m_currentState != nullptr) { auto mix = cubic != nullptr ? cubic->transform(m_mix) : m_mix; - m_currentState->apply(mix); + m_currentState->apply(m_artboardInstance, mix); } } @@ -378,6 +406,7 @@ class StateMachineLayerInstance StateInstance* m_stateFrom = nullptr; const StateTransition* m_transition = nullptr; + std::unique_ptr m_animationReset = nullptr; bool m_transitionCompleted = false; bool m_holdAnimationFrom = false; diff --git a/src/animation/system_state_instance.cpp b/src/animation/system_state_instance.cpp index 92e28de5..4eb489a4 100644 --- a/src/animation/system_state_instance.cpp +++ b/src/animation/system_state_instance.cpp @@ -6,6 +6,6 @@ SystemStateInstance::SystemStateInstance(const LayerState* layerState, ArtboardI {} void SystemStateInstance::advance(float seconds, StateMachineInstance* stateMachineInstance) {} -void SystemStateInstance::apply(float mix) {} +void SystemStateInstance::apply(ArtboardInstance* artboard, float mix) {} bool SystemStateInstance::keepGoing() const { return false; } \ No newline at end of file diff --git a/src/core/binary_data_reader.cpp b/src/core/binary_data_reader.cpp new file mode 100644 index 00000000..1fa7f33a --- /dev/null +++ b/src/core/binary_data_reader.cpp @@ -0,0 +1,102 @@ +#include "rive/core/binary_data_reader.hpp" +#include "rive/core/reader.h" + +using namespace rive; + +BinaryDataReader::BinaryDataReader(uint8_t* bytes, size_t length) : + m_Position(bytes), m_End(bytes + length), m_Overflowed(false), m_Length(length) +{} + +size_t BinaryDataReader::lengthInBytes() const { return m_Length; } + +bool BinaryDataReader::didOverflow() const { return m_Overflowed; } + +void BinaryDataReader::overflow() +{ + m_Overflowed = true; + m_Position = m_End; +} + +uint64_t BinaryDataReader::readVarUint() +{ + uint64_t value; + auto readBytes = decode_uint_leb(m_Position, m_End, &value); + if (readBytes == 0) + { + overflow(); + return 0; + } + m_Position += readBytes; + return value; +} + +uint32_t BinaryDataReader::readVarUint32() +{ + uint32_t value; + auto readBytes = decode_uint_leb32(m_Position, m_End, &value); + if (readBytes == 0) + { + overflow(); + return 0; + } + m_Position += readBytes; + return value; +} + +double BinaryDataReader::readFloat64() +{ + double value; + auto readBytes = decode_double(m_Position, m_End, &value); + if (readBytes == 0) + { + overflow(); + return 0.0; + } + m_Position += readBytes; + return value; +} + +float BinaryDataReader::readFloat32() +{ + float value; + auto readBytes = decode_float(m_Position, m_End, &value); + if (readBytes == 0) + { + overflow(); + return 0.0f; + } + m_Position += readBytes; + return value; +} + +uint8_t BinaryDataReader::readByte() +{ + if (m_End - m_Position < 1) + { + overflow(); + return 0; + } + return *m_Position++; +} + +uint32_t BinaryDataReader::readUint32() +{ + uint32_t value; + auto readBytes = decode_uint_32(m_Position, m_End, &value); + if (readBytes == 0) + { + overflow(); + return 0; + } + m_Position += readBytes; + return value; +} + +void BinaryDataReader::complete(uint8_t* bytes, size_t length) +{ + m_Position = bytes; + m_End = bytes + length; + m_Length = length; +} + +void BinaryDataReader::reset(uint8_t* bytes) { m_Position = bytes; } diff --git a/src/core/binary_reader.cpp b/src/core/binary_reader.cpp index d00413f3..ee3ca01c 100644 --- a/src/core/binary_reader.cpp +++ b/src/core/binary_reader.cpp @@ -113,3 +113,5 @@ uint32_t BinaryReader::readUint32() m_Position += readBytes; return value; } + +void BinaryReader::reset() { m_Position = m_Bytes.begin(); } diff --git a/src/core/binary_writer.cpp b/src/core/binary_writer.cpp new file mode 100644 index 00000000..ef0fd686 --- /dev/null +++ b/src/core/binary_writer.cpp @@ -0,0 +1,120 @@ +#include "rive/core/binary_writer.hpp" +#include "rive/core/binary_stream.hpp" +#include "rive/core/reader.h" +#include + +using namespace rive; + +BinaryWriter::BinaryWriter(BinaryStream* stream) : m_Stream(stream) {} +BinaryWriter::~BinaryWriter() { m_Stream->flush(); } + +void BinaryWriter::write(float value) +{ + auto bytes = reinterpret_cast(&value); + if (is_big_endian()) + { + uint8_t backwards[4] = {bytes[3], bytes[2], bytes[1], bytes[0]}; + m_Stream->write(backwards, 4); + } + else + { + m_Stream->write(bytes, 4); + } +} + +void BinaryWriter::writeFloat(float value) +{ + auto bytes = reinterpret_cast(&value); + if (is_big_endian()) + { + uint8_t backwards[4] = {bytes[3], bytes[2], bytes[1], bytes[0]}; + m_Stream->write(backwards, 4); + } + else + { + m_Stream->write(bytes, 4); + } +} + +void BinaryWriter::write(double value) +{ + auto bytes = reinterpret_cast(&value); + if (is_big_endian()) + { + uint8_t backwards[8] = + {bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]}; + m_Stream->write(backwards, 8); + } + else + { + m_Stream->write(bytes, 8); + } +} + +void BinaryWriter::writeVarUint(uint64_t value) +{ + uint8_t buffer[16]; + int index = 0; + do + { + uint8_t byte = value & 0x7f; + value >>= 7; + + if (value != 0) + { + // more bytes follow + byte |= 0x80; + } + + buffer[index++] = byte; + } while (value != 0); + m_Stream->write(buffer, index); +} + +void BinaryWriter::writeVarUint(uint32_t value) +{ + uint8_t buffer[16]; + int index = 0; + do + { + uint8_t byte = value & 0x7f; + value >>= 7; + + if (value != 0) + { + // more bytes follow + byte |= 0x80; + } + + buffer[index++] = byte; + } while (value != 0); + m_Stream->write(buffer, index); +} + +void BinaryWriter::write(const uint8_t* bytes, size_t length) +{ + if (length == 0) + { + return; + } + m_Stream->write(bytes, length); +} + +void BinaryWriter::write(uint8_t value) { m_Stream->write(&value, 1); } + +void BinaryWriter::writeDouble(double value) +{ + auto bytes = reinterpret_cast(&value); + if (is_big_endian()) + { + uint8_t backwards[8] = + {bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0]}; + m_Stream->write(backwards, 8); + } + else + { + m_Stream->write(bytes, 8); + } +} + +void BinaryWriter::clear() { m_Stream->clear(); } \ No newline at end of file diff --git a/test/assets/animation_reset_cases.riv b/test/assets/animation_reset_cases.riv new file mode 100644 index 0000000000000000000000000000000000000000..09e544f5ee5e1b4b446bd6e905f1b9e4e25e9a5c GIT binary patch literal 2105 zcmb7EU5Fc17(F+c$z-!l(%mNQwhy{5i%=TrB)haCy6Mc?A6<%ww52bStwRlDvn88~ z6&8Z}Abs+|+68}}c3TjkP$>8yY=jEyizxU9TiUJYTUqqABJq4Plgv%3vJT8;?sw1k z-E;4J=e%^{)N>ZTd`I0@*VI=0x>`0Ks8xj|f@cqu1w3>)f9P(-M;<5`JLYO${nf%^ zv(oey5jU(03$;t<7wRU`cPg81W^C!SgOaIoV@p3dc^NQjjuL1vr9srKZ|=I8SML7e zV$w8nFMjc>lb3<0T|_0DjcTQSzUC1Lyy<4%FaPEuX<3N;xbMO;Q#oL_n+Mhfo9|+6zoZX4?huylgY71C&xCE;9jwGnAZIGR249PB zif@`P@c5zO;07iO_Q8YLTT<9JmBnK->L`hn8AvcNfr%M)W)o(I2}9ikfk&(OY_p^1 zN2N<)X^WLIerddWz|r?<6PyalmI_l+SFmXxdqr-nn|S!Gw`I~L`1M-Er&Q?X1$+26 z9YP~6#gI#uRf1EYb4+;ehyqxVK#GBY0b1Wj3;^D?#-L4T`rn}Ze;TwL(Xc}rlG!_q ztcRCd^bezvL}!5HN=yR7%+Cc^${yh)A5PdSeZ1IDTn%quJ3{|K`%w}5h?wmY>(R#4 zp?$i70wERVE9YLT);&CZSy{fc3X|G*N&7D1@MRUY;OmvzMGsFgXSQ<5YmD1?7PHq? z94D`;7><3Y@R3q@VKo?VP5F|TT{dDNNckXvC*(_oa6@w90_U&eXDrMtV;V=UDic}> zKQSh#qzs8iH}RP$*~FAhV&Nv1z|9a&2ZDvxAG8_{Tk-S|T2IcTfcK7w=?pg;mHJ|} zSzV|Pc+L-JXPwORUv0R7=iK{|p2LA+&JMWAchehg=35SQ6C<~zZaR4xh}=n}<<)A{ z3yWeqe?4)>%_Q3U9T>D7tNp2ymw~_$0*AzQB8NIIuH)N@xX!xMb)C_`MQCb)r#xyW zVkN1UtMgusKYo0wZ#Ky;i?jVg!7Z;#>kdVMpt%hOc82ZSTH|CypJ*!4#ripJNHMXC zZRSRf^~McIt~lN{bHx+31=a7O6!HtqNj#y)1zz^y7!0?j1Hl@SX-MWjLCUhK{)2|qqt)`Uz~9$c BzK8$- literal 0 HcmV?d00001 diff --git a/test/state_machine_test.cpp b/test/state_machine_test.cpp index e3dd9cf1..6f25ae84 100644 --- a/test/state_machine_test.cpp +++ b/test/state_machine_test.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -242,3 +243,174 @@ TEST_CASE("Transitions with duration completes the state correctly before changi delete stateMachineInstance; } + +TEST_CASE("Blend state animations with reset applied to them.", "[file]") +{ + auto file = ReadRiveFile("../../test/assets/animation_reset_cases.riv"); + + auto artboard = file->artboard(); + auto stateMachine = artboard->stateMachine("blend-states-state-machine"); + + // We empty all factory reset resources to start the test clean + rive::AnimationResetFactory::releaseResources(); + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 0); + + REQUIRE(artboard != nullptr); + REQUIRE(artboard->animationCount() == 9); + REQUIRE(artboard->stateMachineCount() == 1); + + auto abi = artboard->instance(); + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, abi.get()); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + + auto blendValueNumber = stateMachineInstance->getNumber("blend-value"); + REQUIRE(blendValueNumber != nullptr); + REQUIRE(blendValueNumber->value() == 0); + blendValueNumber->value(50); + REQUIRE(blendValueNumber->value() == 50); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + + auto rect1 = abi->children()[9]->as(); + REQUIRE(rect1->name() == "rect1"); + + auto rect2 = abi->children()[7]->as(); + REQUIRE(rect2->name() == "rect2"); + + auto triangle = abi->children()[5]->as(); + REQUIRE(triangle->name() == "triangle"); + + // This blend rotates 2 * Pi. At 50% it should have rotated 1 * Pi + REQUIRE(rect1->rotation() == Approx(3.141592f)); + + auto state2Bool = stateMachineInstance->getBool("state-2"); + REQUIRE(state2Bool != nullptr); + REQUIRE(state2Bool->value() == false); + state2Bool->value(true); + blendValueNumber->value(50); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(0.1f); + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 0); + REQUIRE(state2Bool->value() == true); + // X and Y interpolation in this state ranges are [75; 425] and [50; 450] + // so at 50% they should be at 250, 250 + REQUIRE(rect1->x() == 250.0f); + REQUIRE(rect1->y() == 250.0f); + // rect2 rotation range is [0; -360] + // so at 50% it should be at -180 + REQUIRE(rect2->rotation() == Approx(-3.141592f)); + + auto state3Bool = stateMachineInstance->getBool("state-3"); + REQUIRE(state3Bool != nullptr); + REQUIRE(state3Bool->value() == false); + state3Bool->value(true); + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 0); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(0.1f); + blendValueNumber->value(100); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(0.1f); + REQUIRE(state3Bool->value() == true); + REQUIRE(triangle->y() == Approx(43.13281f)); + + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 1); + + auto state4Bool = stateMachineInstance->getBool("state-4"); + REQUIRE(state4Bool != nullptr); + REQUIRE(state4Bool->value() == false); + state4Bool->value(true); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + REQUIRE(state4Bool->value() == true); + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 2); + + state4Bool->value(false); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(0.1f); + REQUIRE(state4Bool->value() == false); + // After switching states mutiple times resources stay at 2 because they are released + // and retrieved from the pool + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 2); + delete stateMachineInstance; +} + +TEST_CASE("Transitions with reset applied to them.", "[file]") +{ + auto file = ReadRiveFile("../../test/assets/animation_reset_cases.riv"); + + auto artboard = file->artboard("transitions"); + auto stateMachine = artboard->stateMachine("transitions-state-machine"); + + // We empty all factory reset resources to start the test clean + rive::AnimationResetFactory::releaseResources(); + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 0); + + REQUIRE(artboard != nullptr); + REQUIRE(artboard->animationCount() == 5); + REQUIRE(artboard->stateMachineCount() == 1); + + auto abi = artboard->instance(); + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, abi.get()); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + + auto rect = abi->children()[7]->as(); + REQUIRE(rect->name() == "rectangle"); + REQUIRE(rect->x() == 50); + + auto ellipse = abi->children()[5]->as(); + REQUIRE(ellipse->name() == "ellipse"); + REQUIRE(ellipse->x() == Approx(440.31241)); + + auto stateNumber = stateMachineInstance->getNumber("Number 1"); + REQUIRE(stateNumber != nullptr); + REQUIRE(stateNumber->value() == 0); + stateNumber->value(1); + REQUIRE(stateNumber->value() == 1); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(1.25f); + + // rect transitions in 2.5 secs from x->50 to x->433 + // so if the translation is linear, after 1.25s it should have + // traversed half the path + REQUIRE(rect->x() == 241.5f); + + stateNumber->value(2); + REQUIRE(stateNumber->value() == 2); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(1.25f); + // range is [440.31241; 42.69] + // half if the path is 42.69 + (440.21241 - 42.60) = 241.4962 + REQUIRE(ellipse->x() == Approx(241.49992f)); + + // Transitions release their instance immediately so it's available for the next instance to use + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 0); + + stateNumber->value(3); + REQUIRE(stateNumber->value() == 3); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(1.25f); + + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 0); + + stateNumber->value(4); + REQUIRE(stateNumber->value() == 4); + stateMachineInstance->advanceAndApply(0.1f); + abi->advance(0.1f); + stateMachineInstance->advanceAndApply(1.25f); + + // The last two states don't have a transition with duration set so the instance is released + // and available + REQUIRE(rive::AnimationResetFactory::resourcesCount() == 1); + + delete stateMachineInstance; +} From 716bb4d846935ad2b32d26791af7d6b614895e49 Mon Sep 17 00:00:00 2001 From: avivian Date: Tue, 2 Jul 2024 13:47:10 +0000 Subject: [PATCH 078/138] use varuint for writing/reading objectid, total properties and property key in animation reset objectId, propertykey are definitely written as varuint, not sure if properties total needs to be, but doesn't hurt to have it that way either I think. I'm not sure if this is everything that needs to be updated. I tried to use `generate_core_runtime` to update the flutter runtime but that made a bunch of changes like unused imports all over the place... Diffs= 07cbce551 use varuint for writing/reading objectid, total properties and property key in animation reset (#7510) Co-authored-by: Arthur Vivian Co-authored-by: Hernan Torrisi --- .rive_head | 2 +- include/rive/animation/animation_reset.hpp | 4 ++-- src/animation/animation_reset.cpp | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.rive_head b/.rive_head index 853c9155..2cc54581 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f9b1e8ec2ff7960990f87ef855c669f6a4a86b1d +07cbce5511e451396513f9d092a72193d41844f5 diff --git a/include/rive/animation/animation_reset.hpp b/include/rive/animation/animation_reset.hpp index 6be0c995..b501a834 100644 --- a/include/rive/animation/animation_reset.hpp +++ b/include/rive/animation/animation_reset.hpp @@ -21,8 +21,8 @@ class AnimationReset public: AnimationReset(); void writeObjectId(uint32_t objectId); - void writeTotalProperties(uint8_t value); - void writePropertyKey(uint8_t value); + void writeTotalProperties(uint32_t value); + void writePropertyKey(uint32_t value); void writePropertyValue(float value); void apply(Artboard* artboard); void complete(); diff --git a/src/animation/animation_reset.cpp b/src/animation/animation_reset.cpp index 87b906ae..2faf0d50 100644 --- a/src/animation/animation_reset.cpp +++ b/src/animation/animation_reset.cpp @@ -8,9 +8,9 @@ AnimationReset::AnimationReset() : m_binaryWriter(&m_WriteBuffer), m_binaryReade void AnimationReset::writeObjectId(uint32_t objectId) { m_binaryWriter.writeVarUint(objectId); } -void AnimationReset::writeTotalProperties(uint8_t value) { m_binaryWriter.write(value); } +void AnimationReset::writeTotalProperties(uint32_t value) { m_binaryWriter.writeVarUint(value); } -void AnimationReset::writePropertyKey(uint8_t value) { m_binaryWriter.write(value); } +void AnimationReset::writePropertyKey(uint32_t value) { m_binaryWriter.writeVarUint(value); } void AnimationReset::writePropertyValue(float value) { m_binaryWriter.writeFloat(value); } @@ -28,11 +28,11 @@ void AnimationReset::apply(Artboard* artboard) { auto objectId = m_binaryReader.readVarUint32(); auto object = artboard->resolve(objectId); - auto totalProperties = m_binaryReader.readByte(); - auto currentPropertyIndex = 0; + auto totalProperties = m_binaryReader.readVarUint32(); + uint32_t currentPropertyIndex = 0; while (currentPropertyIndex < totalProperties) { - auto propertyKey = m_binaryReader.readByte(); + auto propertyKey = m_binaryReader.readVarUint32(); auto propertyValue = m_binaryReader.readFloat32(); switch (CoreRegistry::propertyFieldId(propertyKey)) { From ca54937a1707639571552b82ddc140b503d23278 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 5 Jul 2024 21:06:31 +0000 Subject: [PATCH 079/138] add missing validations fixes #7531 there were two validations that were missing in the c++ runtime but were not in Flutter Diffs= 1e7b1c030 add missing validations (#7532) Co-authored-by: hernan --- .rive_head | 2 +- src/animation/animation_reset_factory.cpp | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index 2cc54581..21b7f3d7 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -07cbce5511e451396513f9d092a72193d41844f5 +1e7b1c0301a9fb9404798d5b4c0e7175d199659e diff --git a/src/animation/animation_reset_factory.cpp b/src/animation/animation_reset_factory.cpp index a08f35f8..55ca9640 100644 --- a/src/animation/animation_reset_factory.cpp +++ b/src/animation/animation_reset_factory.cpp @@ -35,8 +35,14 @@ class KeyedObjectData auto pos = keyedPropertiesSet.find(keyedProperty->propertyKey()); if (pos == keyedPropertiesSet.end()) { - keyedPropertiesSet.insert(keyedProperty->propertyKey()); - keyedPropertiesData.push_back(KeyedPropertyData(keyedProperty, isBaseline)); + switch (CoreRegistry::propertyFieldId(keyedProperty->propertyKey())) + { + case CoreDoubleType::id: + case CoreColorType::id: + keyedPropertiesSet.insert(keyedProperty->propertyKey()); + keyedPropertiesData.push_back(KeyedPropertyData(keyedProperty, isBaseline)); + break; + } } index++; } @@ -66,7 +72,6 @@ class AnimationsData void findKeyedObjects(const LinearAnimation* animation, bool isFirstAnimation) { - size_t index = 0; while (index < animation->numKeyedObjects()) { @@ -169,7 +174,7 @@ void AnimationResetFactory::fromState(StateInstance* stateInstance, if (stateInstance != nullptr) { auto state = stateInstance->state(); - if (state->is()) + if (state->is() && state->as()->animation() != nullptr) { animations.push_back(state->as()->animation()); } From 85a28fb8715e20e91ba986ae700f6b08a47438d7 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 9 Jul 2024 19:55:37 +0000 Subject: [PATCH 080/138] Fix jpeg and png decode overflows and error handling. Our png and jpeg decode methods suffer from overflow bugs caused when multiplying 32 bit dimensions that overflow 32 bits of storage. We fix this in two ways: - bump factors to size_t when multiplying to ensure large valid files can be decoded - check for overflow when passing row pointers for decoding or copying to ensure we don't access out of bounds memory Also includes some cleanup using unique ptr in png decoding. Also includes two tests with a bad png and a half-bad jpeg (half-bad as it can actually decode but provides incorrect/manipulated dimensions to attempt to cause overflow). Issue reported here: https://github.com/rive-app/rive-cpp/issues/373 Diffs= 93fb6eb83 Fix jpeg and png decode overflows and error handling. (#7535) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- decoders/src/decode_jpeg.cpp | 14 +++++++++++-- decoders/src/decode_png.cpp | 37 +++++++++++++++++++++++++---------- test/assets/bad.jpg | Bin 0 -> 88731 bytes test/assets/bad.png | Bin 0 -> 534283 bytes test/image_decoders_test.cpp | 23 ++++++++++++++++++++++ 6 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 test/assets/bad.jpg create mode 100644 test/assets/bad.png diff --git a/.rive_head b/.rive_head index 21b7f3d7..172e250f 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -1e7b1c0301a9fb9404798d5b4c0e7175d199659e +93fb6eb8365dba5c803d3132f7526dc1c888293e diff --git a/decoders/src/decode_jpeg.cpp b/decoders/src/decode_jpeg.cpp index 0eab5c78..2ed8c9ae 100644 --- a/decoders/src/decode_jpeg.cpp +++ b/decoders/src/decode_jpeg.cpp @@ -77,10 +77,13 @@ std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount) assert(cinfo.data_precision == 8); assert(cinfo.output_components == 3); - pixelBuffer = std::make_unique(cinfo.output_width * cinfo.output_height * - cinfo.output_components); + size_t pixelBufferSize = static_cast(cinfo.output_width) * + static_cast(cinfo.output_height) * + static_cast(cinfo.output_components); + pixelBuffer = std::make_unique(pixelBufferSize); uint8_t* pixelWriteBuffer = (uint8_t*)pixelBuffer.get(); + const uint8_t* pixelWriteBufferEnd = pixelWriteBuffer + pixelBufferSize; // Samples per row in output buffer row_stride = cinfo.output_width * cinfo.output_components; @@ -100,6 +103,13 @@ std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount) // more than one scanline at a time if that's more convenient. jpeg_read_scanlines(&cinfo, buffer, 1); + if (pixelWriteBuffer + row_stride > pixelWriteBufferEnd) + { + // memcpy would cause an overflow. + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + return nullptr; + } memcpy(pixelWriteBuffer, buffer[0], row_stride); pixelWriteBuffer += row_stride; } diff --git a/decoders/src/decode_png.cpp b/decoders/src/decode_png.cpp index edfb1bba..fcf441ca 100644 --- a/decoders/src/decode_png.cpp +++ b/decoders/src/decode_png.cpp @@ -7,6 +7,7 @@ #include #include #include +#include struct EncodedImageBuffer { @@ -40,6 +41,8 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount) png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; + std::unique_ptr pixelBuffer; + std::unique_ptr rowsPointer; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); @@ -57,6 +60,12 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount) return nullptr; } + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return nullptr; + } + EncodedImageBuffer stream = {bytes, 0, byteCount}; png_set_read_fn(png_ptr, &stream, ReadDataFromMemory); @@ -101,22 +110,30 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount) png_read_update_info(png_ptr, info_ptr); uint8_t channels = png_get_channels(png_ptr, info_ptr); - auto pixelBuffer = new uint8_t[width * height * channels]; - - png_bytep* row_pointers = new png_bytep[height]; + size_t pixelBufferSize = + static_cast(width) * static_cast(height) * static_cast(channels); + pixelBuffer = std::make_unique(pixelBufferSize); + const uint8_t* pixelBufferEnd = pixelBuffer.get() + pixelBufferSize; - for (unsigned row = 0; row < height; row++) + rowsPointer = std::make_unique(height); + png_bytep* rows = rowsPointer.get(); + size_t rowStride = (size_t)width * (size_t)channels; + uint8_t* rowWrite = pixelBuffer.get(); + for (png_uint_32 row = 0; row < height; row++) { - unsigned int rIndex = row; - row_pointers[rIndex] = pixelBuffer + (row * (width * channels)); + rows[row] = rowWrite; + rowWrite += rowStride; + if (rowWrite > pixelBufferEnd) + { + // Read would overflow. + return nullptr; + } } - png_read_image(png_ptr, row_pointers); + png_read_image(png_ptr, rows); png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) nullptr); - delete[] row_pointers; - Bitmap::PixelFormat pixelFormat; assert(channels == 3 || channels == 4); switch (channels) @@ -128,5 +145,5 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount) pixelFormat = Bitmap::PixelFormat::RGB; break; } - return std::make_unique(width, height, pixelFormat, pixelBuffer); + return std::make_unique(width, height, pixelFormat, std::move(pixelBuffer)); } diff --git a/test/assets/bad.jpg b/test/assets/bad.jpg new file mode 100644 index 0000000000000000000000000000000000000000..27a5d74a021a9a05de4598ad632572dc905a2d0d GIT binary patch literal 88731 zcmb5VS5#AL7d5;|0-=Y{L`o8qAk~JTfU$IvRh8gym3=Cz z8X8C>Qeh7oi$-A85lF=UE+Qg46)Fam6&II9D8dyH|IgcQ8vqv{tMFO{i=Y7zTm%dk z*=+|j000C6i~R3-|NjjP0f~x;K>=|I;cg2#;cgKy7z~1dp&&6302Kj&;SfM{pZpPm zn4^yZS}`<{1vMyE!dNu0d*+?~6IaF_^X>TA1@r-1-eX*9-vL1WL&>0alg>08vh7z{(hEYMCvTE z)PaCtF+GK>Ar@!6njn8>7qH>OpGsytpp@4-HJBw%!@S8Y`pJ??OmJ|KY_#Jbl0n-! z858IqJ2A^pOsAJ$lyG%bB#0%WHfF{9G;rL zq!=V-lO8wg9X7i8#k#2(Lj?CJY!o|`3k2u_E z61R1Esmdh$We7nXKDhpt5U8Ng?ZiGmrEHAg$Hy`FMijFq4C_n&&?OF?lxCoCQ2%{} z=N&O;U@+>#blZ{@oJJs zw*ROBMawa)YHTWD35i>Q?E(*O8j5e?bx>wnT=nWT`BeuDc`&0eiXgOg~GUs$!#5?Id3MaRB$^DN5RQLECzE3JMgW zVvyH0Ub`m4vtOyNqF?`Ed#Ia)MAz)$FiE~<99Fe|g@`G>^ae)diF^nY)X zx!AidQij;>h*=roG*bzKHDT55>7kpKl6P#Q3F7SzL9?}{hetVl5=7(lzGP_+xO8xm zd+JC}F5}1Thm(H0070vD-KM2Ia;;xDGB^ZF|*R< zNLs|}YlR0q@jQi5w&{)9PuQ=?%|HG*-F-XJhhSK?hVlSy$wCzkby)kZk%5P!ci*@^ zYJHN?6GR3j@?rDa05CasHUXocs}`nSNy+*_!lSUey^a4x|Pk?Gn+v` zyX^~Cs{?8`rGDD)oL*WOq?;u#wfh-frb&^!e)%j2N}EhI{Iy@NFO=>Ab45Ny}~HR*sZx)!B)IJa8c$alo^cp zfvpQUpfagn@@)g!yp0T9s=D3t)!-k1S1{aPcxB_8t-rjA9HB(K#7JIKWMYlC_RS)6 zVZ?fp@0L&2+23|NUM%%jCZ+w+1t_#^o@_|sw%`&bN9-$td#+~AG}d~!*Pd>_AnzSU zY*rJM0Oi_MYp_vrpyJ^p4ifz3dDt%=ax(r$o;FGMAIamHGO|$(!|{JJRJF4X^jK{% zMwa>p-WEjjktRp0kw5FrP(Qwl)eX|e1R)XsDLL|J{K#G4MIO@$?Ew3Qt=3@BW@;a? zhS)pLT+#=N6I36hUu2kXW+B=v26pb2?V*cC^-$vln-Ah#`nLx)WdkHibQoLFpSiQse@C_8%iM_Gx=5!S~UU3STgm)CDpbCjMtjK9c!BxzxBQ0DQC zaU%J{Yju}IFV#q+4Bx}+JoBOW!^*p6vNwVc>lIU$!B2oH`4dS&%G=(1V`=~(Ot#^pO^#r*o0+6xg)7E|}z z4z#r@$AW+C0&)8?_wJ>EYEPi%3ER&z&_jA!XSPFUc$bZtE{?6HK|O7#?Nx;M>bm)l zGvTO#DT$>TmiCkEsM4X+Q>2t%nG}B`zf(f4Y@N~sppja50$4IQ}9P=Miuxs%~+Qr3@yj>ut=;KeM1IW4H z;X*`s_@(no`QIMRX#qQUY7;Wck=pEcr=0 zGL$FqQq5wA!7GSTy3_!?Hu9#Uz&p~EE&&puN`CJVH4MXuxV+&OIaROu3?k84OTB^2 zX!R{*yddG?VU?P@d!|WEW}GR*FQfA0``Qhgbke_~DI{MTjlU7%W*vxCTQJebGohj( zj?G7mjhw}q%hoF@SPgvW1JFfC(^d1$V{|rm7tH1}XIYl+Zg4xqonr;_`Rn?pgvRBkw0dI3? z3+GfGX^(ug8_C`fCT)TD<$wNm?O-`s%fHuM=|CswJ?;*GHbCSEd^y5=xPr>ruR+Pr zG0cSV9eSFkRJag$+CAvV2G8V%ok(xU1U>R73Ns(a8+!*vpng%FZ)Jh*9SA$v5*vHv z6I+anN=5ZR!o)ER(0mBDC;g3a{o;A#J_|13?LyP5k#ciYH>gKZPoMGZ9 z(+geUr`y8!e?+dF<*iRgmv{%Jk+4UzA|`SSEcF1w*u!}ObP+{8`ESue`AVm_7i!HZ z){8ZrFhGn>8!I~lR{4ziX;6o|&V>xN3@5USMSaUy)*KWa#_qE!3KyS5EevkO#(Vv$ z>UV@}FAR~Q+BC>EXJ@0KLOfi&w3T65N!toSI~*fosvMqL!Jv*nX_B?>M*>6@wXJbP z&cVj}mOX?{7S5!_r7aC>_f6GWxoAiv4l^d;EgH5JN#E9XI(VlV`D-H~CnMZOzcd7IRqq7(u?4YRvhl z;QNmY>#;f@zTh8btPbZMBcZ;f=-U{WpD{eG;uzLmd3&L+XsO$tF@KMgY9gT+JvNeY zMgmK9$=R>_F$%MagUAKahE+{3C*s@o)vDs|Z~W;XhCS!U#>SuXL$&cvOU4-t49JNw z8M+CR<|6zsW5sX;-)sLPff1N3SBBVL?S)%B6}y%RqWGh{NQNpRANH^jCmCRi;)t!F z5L4#I#`d2E`*_`$K`Km<1VM<85ktUxrL?~7_q!G})atO-dVFrY%OuIZvsRs$d1uTb z(fJumYQK4Oz|(;1O{QscgOeVZD6Y)KTDjoEYtW%x;4$%o+(B0C6_i|Xf}MTEva?k- zh@$NBpM5~+^!2AP2u?%k2mfSz;^8f>yvTdRXHQsH!w#(J%ki)Bo!^hVVTp-mU(i!( z!DHnl_E={iA)&PZ0YxF|qzc6gUs#Tj+J0J&dtAL3D8^)GezDNAlWkt*S!g%Idj z+$F1?69Z@atbtD8W=gF~tewcxCm;oawq4-<_Twnj6DTgHtcuXE6dSc_q9d00K*Osz zs|IWZ=bHaWPN(YK<1uhK4;y*UIbh z%gS4etG=I*=3>d{=DAz`@2GiN&&^fN!e|%Zi#VUs^lN1Y@0@GRB`qDAfC$Tgv)7p8!k1dQ#bj)becwz}UJhceV0}Bd%_;->Wh+U~m zGbQ?#50N;Gx1{=7QlQLAz6)}w<-tiJB<>EZz%YRE5{L~PHBk>`LtIlE z7QEw&77ZUuGmF#Re4_?#$Bz^gY)0x!n#`x|yuN&es_A=3;vm#KB6+Oo1LomO%^r(e zF_NYZGqqzDt*2Zg0Qb6rm_T!Qu-^wSdAYWmW41ncTidbJWA+nKy)}313?sgGiStvsrQHFFwNYd5?oFE_HC{)C`5z;OF3gn& zoND>;F}XkG<866KCILkozU&eI2fDo0f4em-y#57v<~SF@8Q}@?Ut>%PZ!A?3o)ui>eZ&U88JP1RJ{+H|F8ug(*Zi=n@o=K#!RWWs_twq@%uUsn&zw)+Z%WKR^`YaPH+ zQS~u5N^m2*r%3Z%ps;IW;?!rgyVfY0H*H7|`E@h3TV5O^2(3M0N-nES4u%hJA-lG> zxAPoor8=JhTUn7v%-DA80kMtWU7LZa-O-`0!I+2ik5-o&eI2dk?es)Gmxky^9+Pp` z4EC_H?XfK{N*H(0XIw(GCph~3NJ(QIL!9#Wt9LuEh!5~48q}K_u-MS1Zw5XVNf-?> zg(<0U2_2(jPWb(h%UhI5tK_Oeb2FAN$QH4aoP$rAY%vN23=@aP+m|Oa;&VBFD^ngq z!g}rrG}ksXl2;8QBo^|HYxi|F(+=(HTSaXlN7&;|6N-Q(#&RVWY>k|}=XV#~X2h+R zQDB$45>(YXgWZN>I{5W=N`t}GhKtQJ#AjEXv8R_T zQdhmTdjQIB-wzqubc@=(mK?O2jp9#(d&8<2A%+o$sQyhW%l2{k@k%iUJ`0OeQ;kaZ zlRDhcaY>(E@A9 z!hk~((?m2|rP>u@kf+-=h=bB$of%9F%j#XGwc&)Q9&$71wO97M9bHDG{ZuB=Ls1C6 zxwxev4?_`ciSz)#TP=Cyo!p`N*rM%VJ|=|7fkP_U)Tg zy7I>wM!-~G`=~Iez(+#6{Js=HTd}J>a*fBGdK#?Y-XlU8CoL`Mm~Ge_4gG~fUSAWgL7=s+xUZ3l%r*qj^i?~f(6OYcZb`5|?mVSVQ9BM_h-`oX4j6nB;i|(`xMBKV2 zVdd}8)~qcxZCpGz=e8BO(fy9~CA~b03bTQ>G6r@c?z=$mX#eXR2K_Y)V_eTyw5C** z`ZAi#lKbAZ+yCrSN^CUNn~qNy&yT8$H!_6nm42r0Zsg6t@S`wR=V1GF{jJW4x_lr` zMLEbfYO8-hwq6OCHO8cgpiZa{n$h#N@Gztkx}f9{=h4w!z^Py*Vu`n|`A^`H8~a@z zPLcF<_DE8(V@WP%gUH_mtF*~dc5?dT-ekPesSpGa@B{C`Y zDqt1LZGl};I{T^pp{$Q$v5H9&$$HAh`KQ54X7uX+=AGOTWz&0NaILetIVeQnP1H@S zY*dTrx{2YbRgvBj0z>~-j&`24^IzU2T!#Z0H&L>7QBMao0+gp-H9uM^Y4_BTcmFxY zQhRjV$t8G(AotCZ{i;CV<&smRZ=_k+9RgR`!q^WBGd~DFi7YKCwzKQ`Y^-#(j*J zn1yv={(U`l;+`MSurw&hLzl~u5}@3k+s=Vhao$AA-iD5etCBQ-ms{Ls*pF!-0S8{{ zOFxtD*jFP<#^k$?HODE@&`Npx;`B=^$kX2|o)DL8#aB^Fr6ehRi1vl_h-1!FNrmBo z2-BO&urKA$(nJFQ`;$@;6iUvQ)uP6q3N46Ht)BZzN!MMk9Ous*bGvJ)-i+S1J4Wawt@^-I-jm6SLSUY@CXru)dP%rW!zMUfio zjLVO>>S>DcCq0W5$u5vb{F9N^z|wCnX7jQ?_v^(wC_)bgc1=4HJDD!+s`3*X_O5Fx z{3}t(>gv<=`()4;XAMyr zn8ZBE@Y{%8-+6w~glVtAxa#yOfNbrv=a z-X;665$$r~TyY@eJ*Sns3tW|SV~x>`v8+rb9o47ua`HBkFu-H~9VzUFiIP3_J|Y<6 zq($ofAnlE1eLYa>C(wkpeq6;2QY<#y=OAxoovAOLRL(@0C7Tm=*h21_vG;xM_V*-$EmICdduds{xGRk@uXKqV9IoOJssjblSC+c;6{Ms&M=zJ>|Xl#o# zx{&x;?GYq}>Dm=~fi@_(MLDEiV`yM_tyZ!zbFcU`K_huSVY6E=&^@10`K4tKT z^^F3HSlw>HeR4gDzEoomIjuhR_N)ap`z@cqiw@9ug-Mf4CSv2-z=NzUuNOtn07`6p zX=gd4k)Y*t$5hVcPL0lNSu~U}L6nnCUdT4nB%?OEQ%A1%TGYzObKPBXY;WT1I+l;T zVEnXMG)tc2gJkcD>wO&-iPIO&UN;{T#0;raOH(>9;$>KsUzf_DFHeKppn^JRD}=eX zG>RYi?=iZSriY5-Sw3=OW@E|?fVeY*qZWpP+?P!C?N2qIm<;#5bup&r$?&2O+F+a% z-VCzf~Kz~@a_x_#|$^EPgHFH2%7Ln!3B zf`l$7RKLe~6O=Y1_-n0?NaG+YGZdu`Ur?OXCGYuqEwvE$zd7okuAXITayjEmu;$6PQb20FY-|yF8K@#WM&m!eoHE09k2c-n%b*qob zj4JhGMni=wyrnUIHv0AWxQC>@UsuCYl~sB&8>RF7IwTD`xV?qocpm1W<)58F|D~;7 zE$I%NqWx$?4ct0jJ8<>f^s9w7E#4TJJ)Y;hB!hj>93Q422gBj>PEHGBpZ zW;9M}FF3O2zp(5wj$dEx-*5C2Iw|wl?o^`=BZLStTvZ;;eX_Yol|V^7LZ!8)E*f^8 zIf?)8Vs?L$6Zv*_MDvtWVE-Vh2TB!D)$mHZIWj^FQ)C#_7I_V6QSD_oeoND_tEP(~ zi5JZu7UY0f44?UUGX~?6r_S%BhCYh4Hd7@;LJ=k;r3oV=cKASr&W{})fpp#<6oRT( zeT}ovT>LpfsAizJw%S=iz`Nq5mAOlFPia24->Iy4>_)$smH(X}Q)WyJ*tH_rY`w(hAMJ1{}Sl;mC1MTJ1qvzUv3{qZ5 zf@)uWrf7?q<9TaBR9=K)w#h|#|C@mGg-sb9excW-?zm8K@vA@Xe9fQ4c8Zr*>h;1) za~*2D6i;^XnZzzgT~}yjIoGx+Enr3ZIk>|6&>tz#-w8r)^6tYUZ##{Him63ruLBc} zA@1uvy60bs6P^a9&)NMB#>$@ zj$x~wJdKgsV-;|%919<$m56Vqn6>UZSAS1=e=>jcsNrcZr{kzMZgXD$y!=jCMQPMDG41-od zekiBX9j#o+VQpwA`II{27h(fb^RWo=IwU`w=n1U#1x9rsQj|QdTE@`4;hQ%qSQaNT z<=d)fW#F5PtswYHcs9E4A!@ZXbUNXHhJ2!tr+LBwv7}`)#gLb>7fDnA6%#rlh|jwu zUaXC4Ibtg@8D`$O%9lF3F=#&KKva|ge^5t|ej7SiQ1FbN)~qi?`3XNO>A7v-X;s7ZNVLb{n41Q z=V8J0O|;b^j(J3)P~e*>(V~z{WDXA!RQ&v9PcrpZMxXzu0{MB5H|1kvWR?1Qy)TzY zJuy15h8eybsO(+osH~_kC}QcEBd_RTbd%JX+Hvb!ZMUFV6LhvJQi~yW_m0EkVoMFN zv8K^wP}wQk$NtNL9G`DR-9~LQ<-f{VxwqUM6`hews{XYe2Jna4`f=@rUBpY+<5;Sl z)HnId&dW*OMPa2cX9lnAbMN$Go5nYj7!T3+v<{bu8xp?WIPl#;M4fqPGw4gy7X5wa zy&PRrklh->DA7FF-!0QYsp#X#Kb4fYRtT^8iy$~O7xW_WC#=-iIKj?Gltl2Xyu~&O6 zk~;IkkJ(QaHOs?V^H0Nzog|;9HtYhpi-b04Edcd>%lV%|o~y@h`PbYiITN*V)Sy}{ zm$+OAq4Q&ecte>8_cii;*Z+;2%j*77Z|E#kU1m)+&Lor?>>ZfwIEvIA-XkT*vJNTMvBR^S-&jS2^6S*4e1+O&=)(> z8twZGFIm#zLh0eT+ZQy#JKb5yoF)4Z~K!b@0bNGv>y4W4}yk}LP)+a^fpx@0DG4# zz4z3&nqKKoKaB;h$k8(^zhd3TEYY@M-T&mIgO%znVbYb)`+Jb61wV&#zQN@-VnXJy zPz#v6+Vh!dpOA5sC4sM1o3a|=u2>C(kf^4NA8e>)v5QwuiFb)S=_`b_({s;ytB$>~ zYL>i%->W{TG|I?0eETuWxs3|*H50CwtmuIP6c7%1+|x29gcQX~8&e+I?v*!o3p!WvB!KdP=CH&X|h^G#H$vPyh*t=6Tx2Fyh#uVXx={(7!DGh(Y2 z25t}~>M0D$wiPa#pI8`@&YupipM@2E8sA=lYl|az@YwHtsT6&+)(z5G@LJEAqw$LV zrTWR06%Gf-u-#J#PO1<4*a>vHru0?gF}XJ$@Urz@ZJQD%GgJGR2ui+8O?PZoD4L)8 zdv@#ke=awU_(#uc#^27Sz|{J8bnyROkR>3m)D4%Vi71OTHR1+{X?keW=p$pf!m@sG zAM!VzO)U&j0f|fpr#=mPr3pF%c7VXwbed6-J0u3iFwNva@~Xpbt2%iK~u?Q z4+Xmb@v2o`FG$xgU-mTKd|?0W1FI0$=rgX+n{#P)J1DT6vd3b*bx&>g zYtXYmh1z8*82JlIi9f_%Z82-FfYD1Q6}0m(_qufFw44`>%y zjX3SX`>fwU;_trf$l7wL+hN~1&on7Zz!@S-YQ+853kQub-SQL_RxvpzO|LqlZ>sH zj1w3JNqEk1+cRBSPyVv!@;1ON_a}ff6eGmYSsHkaij71T zJPgb_6@1*%U+nDntU;X6^j6|nCDsTO+3;h%UUueDZ>VM=!{i7WHH+r5Zx%{3{d}W& zhf5L;t@d5)wC_n1|Mr?{+TBOJqa2u!Qz2Ka{=Fq`1x3jl{gRjBZv!yPiv9RP0zHU(3tAIa*fsL*-){Nsw^i>bbrh;~Qy4WYys zaW?#YppC;*QT5EIUEsi8^u9K4o4Uyw_rqWVX36xzU*onNFX^w`t4-s|RG+*P#7tEO zq=s9kRaOCex*iPKGQ&oUNT%uU(sop<{Yc&7>t;(B=buGUKR%cli zya1$lZZB#U6u`RamxE{aO3Q$10}GkgH{rF}g2hMg7*jEm_eCqEi=-lXTi|mv#;d;% z0X-%G+`1-3yrRceG8P0wj6hF+P%9WkAE8#>!M+w~NJ z_<7q8Vq)q421n`?t16z|>Arhq)AdxnvY*x~B=qBm(9uB-pmgrYib#vNdJ+)gYskJx zUTQA`ZtWkAqOIu&Om30v|OW7n$?xeN4JongLHxTF}w0xHCEeh7-r02VJxWX z%XJ(T>ComK-qSM;Ycdsho@l6WHN=#EmXEp)Y%~0X>bIr#g0U#soS=?eQ}w;Ntju*o z=~u-U@m^-?rLCEBxNCDo={H$>bJDaMTSqY;z+6NuedkH-td^tNAP|>M%v#^@qK`E# zO3pGAs1nj;N&&bA$j$9#g=MAoy3K?aDSHLemIod@=}Qd0Kg5MTWjzWTRNGTMM`9 zQz&N@Q_mULC9==X9%@*F(l&bJ8QKs(s592#k!D6pMv6!>FcMY^ z6`=^tf~0&1$5V9eG3ct2I6>52Xq@m&o~T1QIEkw#@?v8cQ|8tT_5C)=hq>j0QjwA+ zpFPYddp?+oe5uS%$-Z;{;C|;r(hJ8=cfL!_YuKWSquD|ZYhp-*1BnbuY>bAzMj7Y+ zpLZ6|l>*THS!=G)yJv+YC_J2Dm*&sjaIHFH|)~$JQF^$oJ&P zccdThpho*Y#TO7M!#%pof)Uk7u}lfqzzb!`!H0nX#VAv`|2YbTl8niITld9|^<2#jiDZ-EpdME zs0XBzN7MG@NaRH&YRD^UlTirgdsY|aB$Q?3wI^80sV;uE5 z33yh7pNvu9(b4R?(F}0!BF&e1aES}6_i1}#^tRa=Lf~< zDlbVokExu=S^mUNwoV{{T~A1S)Ja?0Zvr65t8dHW!9*mW^_8JguSyKo}80pA{? z;;0udqgJ}XFwv1woc`NQZRJ2s^=b*MLDk=)k?A0cP0&8>g&B^GS|~5QB61-Ql&Hbk zVlalRq$ez%!`WjEt0ECZ`Dy?i2uy>JC@WF(78O$*g`)Lpg)SQX^rPlL&j0bl6#(2}Bt z=~!5tjo;Iy5u$rWWDhx&t1b3~-NTBHjrsElY3iAtLVBp`&k72UcG_WdCZ`4^zYQRY zj9DpJa!mitkS$B6;9H?x2_t8f1EbalD3}5P%uE=Louq!u*)q32V1r}i$WKfQd%HHK zPI<^wmpT)EbDl?UKmVo9P}MvNYo7bJ#n6fWFu7Xhvz$F8;gdB9zNWRJNaz;atJ2I# zS~mGqJ)!u`UigwYBx}bovcj&umhzACi~W zCpWF7we968^qbp-vk(uSS4NDpP%hVm&AxUK7_Mk?>_$ZQ9_R7g5sJRL{RPokDl@v}yG4zm~X z0tf3WTmn4c*@?mhy8Ws@%fP~UW4-m^x3{SrTGw@xFfBzriv2bIg3xT~{UM3CF=;cK2g?Fc^ zq#u+;5-_l_*4^$Ecn(l*k@>#Xi~n&lG!g)FOgaD+H=~;VBKHRt{#X{b$VTZF_DGmy zUa2c={MJ>}bLcCvx6_jk8U~&uFML>4J!peEriTiYZVcPH3Pvfpf58V5b zm2KQGcZ-dX%GC2TQAZBtA41=3H103sswe|uvv?j-m`vzD9DAvO+pe{?{%*~xYop5& zzIxUfaPNUQ55t>rZ(mQJ z?ft5ST3_qV)m}vw4SYfsGNEpI>{XP| z(O^D;`&FD}^p%%5MkoA_l~i)KOw=}F=rPFEKFMy$Px0*uT^k!g?vKSEoW^gjj}6Uh52gWJ1Ou!W5IRkh;VpX=c<+m>;9Yz zFJA+DPCy*Rwm@-jpX5Csp{%Pa5UHS3h!YqunNsnQd>h|Fu)ss-$w3&*Q2jfC@ zJ>nqqqswe!BQ$i;)T?Pa!8}}akZpNnkB@u(WQ5Nu_oesoYorjO(21x)LTleKJ>zjs z@D1}=e6|)EzkQg;@bk7S1qK{29g*KagOggUHlrclworZ%^#jenu?1I)X2JP#F>)kG z)HWN+s?ont8~hJ>b*5kN;LfekqZT>Ap~D!;f&X3`9$;p=c2s+!i=~f(7Ub=8gx0nQ zotgNt25_Ds{uib5{p{4)fD2$-=&csQ8kAKUPswte9^O0uE3nd`QCny>pjKu__`Khz zeiuS3AC$j#XTYfDYU{Bh^w;rYE9a%I;VJXRDU`7OyOC@Q}4%O)cE}?NNvh*m^$%Y^sjX%t2NQ`R{S033jR4#6ie{{ zx0(OhA*HEb`Mh`f=gwT~mf)67Q8(@#%eKtmE}2HU@W-s3yHeFVE}o%Z9fc0l_g;SrK)vy% za%teQv^|5uQreIkbPpOTZ%q!E{xnjs9XZ~h!C;2JSzjP$pmo{0^vdKs*EO9uMsr~| ztF7_C;ZN$N6K>1>tcdu8PadG8@!_Z*X@3RYm7kEH_SB0sNfA}_fg3}MebgoY&=T=K zUC@T!GF^kDm!TJz-$~WX@zyZ}3DS^tx>Ab>g4B|iWNUy5+L-A~M};J|X<&O$KVy-8 zf?JYa8r*pa{^bX`Oln0&n0P&@0byP0*->4076i7WSuM;YAaSb9WZLi&d*PPBQDrk- zKqw1u3A`3}0W;;JecBW}-z#CjQ98?ArDzJJtyxn)n{X)M(^-cW=V zlo^q^gHLj3XRXn9fx4F5{mNfaO8PgqpS=r5NX$kXal6HjiMk6t6%mH7)#JzQ@Mj4_ zMa;)40jrIN7XRnaHhX65D_+cMzW=?-U>nYl_p0yfNruu-$`Pl$?D9?eDP~hv9Ur{(RXc6!*wBk9I>;iJx`6R%2(D-a`*#D zosSkYUsA#I)sWfnva7e!A0rY|*BY-RR+K&%9Hlg`ep5yf-Tsu4_FNOI&a`K}-0Ow~ zomhi*Z3`_g=WFJOC@R>X?9}FJ^6VQ@BlYSg3j60<(##OW{ z?0wa1@Xi$_Q4+N+IFreZr^>m=^3{ZbbDVzcPs(>KGZIsW)9dd^7Um$wkSg zfal&(!ZIIk{hJs3FK|sUc2yA^?CG5-lDqlR~B3yN!;GPa?-Gg!xt82aVqSQy`o8ZT=eC1v#SKWU|`6ApFzSMYH z-CFON(xKIEjgwOj$0!BItN|uLxmM=x22=naoV;{)a1oX`9Dgoc{*mMTYFNbnsx6u@ z$rL{9E-)y96YYI*+%04V0~uyj&}RrPdCl=+Wiip-QV zC$C8Eyp9H;kWkvkV6tRx%L{53kFy^MapX0W(zR#`O7 zltVcV=5v`R!8^hRyZ9U@Nulu>)3l+=AUyS!i~$@8PD7#|LBb@tu}(1jRtA zG4x9Y?TV6KZ1`gAO^l;95zNI^Zkq&hIMmRgzZ|xD96Iif$s2!> zt22`J*qaXcUSTi7wqgS-^pYD+BRX5hg)X)=`?ek~uNp|?3k9PWMIVC`ipQ+mFBb&j zUdvKG9banX#EQKozf#7hg2TahIyI zrT300o@~4qZnneSm^IyEEh*PZ*N0OkPIuagJt3@O*n*^{x6$^4RqYgs0L(VFpJ^WG z^;U*ltxnNfnkluXLr$C8t$6#2glLz-w`)xiGHNI~VHRARN%rUuTy+v%_})TlSlCLJn=6Ey?if56$uT>#i zUTJH%CmHJjuEOpLp$|NHyR+iYUMmMY40Ur_EF*)?r@R?3dwuy?VsNO-TxAI-+@fa@ zXp~S-Xxiwl4)LPvgrOE1MfyaeNB=B;&2@xs`8#qJ8`G9{h=S71psszdbjQY0jmkCN z$rBkUxVNBiam9bHf3DrJBTg})U66$L#aKM`PXjIbzt|H2kc zP&ocyC{kI5s+%lGI#=?~jZ+=BFL8xd2f3)n{v^)k6ru z-LENC8!46{Eu#rRH9%=>9C(CCo>;|I#wqy~FU+00q6v_>kRD;PM#IKxuNJ}z7q%$M zGzAX|3%hBms25LK+$E)B1{&6o1rKf;0O{pSdAwM%`KdxAreV?W>K!Xj?G!`N%Z$64LRerv{?y3zYBSqSSFpaOr z9T95d48I|}XQxKEWeNhs*s@k(w_yCNtt(1SW~~lqa+0YUY(MeL-yMP=KxeKC`QbaG zeKKL9ZY#Zi(%UGC%xHivAzW^%rcQ0$D6o}qSyUt?-}%vwxqaCCf}Sjq4(nLoiP}&_ z6VO~G0?b=vP>7{*m>TRmU)T_L?Cb?=Llt?z5N0%Yt^mEZ|J^g|TU}1eaJC{5`Kf6a z_&ewdOsLt1)>zWpfj*-uZK#8Riba*TDJ%MSoV7a2MCKeB4O$_Yvljn zbDthpsZ=_Q7``-ZWNL9DTL*e&bW7%lx>kd-sppep+tRtG)t%{Xj@AmqzY)uoIiOcy zVN-imocM<=$5L;yt_=!#O=z4M882GACDnF2L`^ASwb$XjmF)Yr-V{c!>&b~4*sr;= zXz`A*yBmPx&NJua@1tE;kFgdyf-H{2E=HXH|0p`^s3!k5j1QP}cW=O?m5>l5Mh+09 zQxK#?QjnA!NXLQ@qzfB#GSTm8uNtae0O?j{(JRcF6%$g1Exmb41!;^YJphSTdlIn zb^^%Je%X5c5hB&mVe7n;I53S`BRQxEJ)32iO3{eEv3cA}DaW+5)xl4Vc0CD&eFCRz z8z{{X4uzOw4p#d8r~KV@i~Zf0$qz}-NbqNeq=m%QNtp*ud;=PJ@;0Lk>nSr;LiAUt z>5m;a#O3LVnUJL`t;;3y4=Mt25&SYhWn^ynRKDJqb6;?g`zKL>l-7FFjJy-H*gVak zC%ukpY6>+nP}|&PGALPr_A^EE;jCJwM#poL$0~FdaCGrS^8%H zPkd$lXp%fEJU1t>pT4sSW78FWk1BOGaO~q}bk;Mu^Oe=}gC!`blz^AA%q- zgYAtQqsqZW@Wz_^p)`F?$L&uU9U}PY(c&|55~NMs2acl4?K@(#fvZ~<^Az%l%Bw-0 zK?!&ejF>PABK44DKI9Czc84rBUoj$8sxBcY;8Io%v}UkR$&w;4XX@pg>581$2`Ed_ zh*rEPB;mWk4ZPiFl0k6a;PwhLYi0|KLdMQMsF$RMKt}Xfqy3A@)3{JOz>sfcA5CLV z6E;)Lda=@U6<(Sx(jRat-%vl!!Vb7{S~Ytvn+)iB&`Naw{pXhf3PZ z2+j*3A@MbBE%CeOPPOmtP$f<+L? z87Hj@k=}hVt8hQ3h^w?S<#*j{^C9Ow(ba?^{kcDd^2_ssSQEx%o(SHf;d0UY7)~;1 z>u`02?*2tHS%3FcpM~rGq7v@xY+|1*KmFOG1k)u5RTxc5xWkQKQsy#7cT8aP)yv;S zYHOjft%{%6ml$vQU9&6S|Rl54PFWra;N%(O6TP`goT6}ei zDVa%kX}7-w6wIxLx9t1{h(W;wC*>gkrdq$|`ZyF_Ov+4Bx7DSYgu>w*99q`Pk&b?Z z`fYoqn4&CZxl4NtoJ^dNl=IH3M+rc@c9rg@(J7Ipp+)|yhd`ajZAid`LA@^-53Kyk zB7kUa6%ZkJN?5iW@MHL5jy3JN&^Vwh0gXt(AvDQfx>p5|L@I^R94l#-PO=u~@x@ig zj9~1d>`q1m{h@iz8zm&;Rkw6)7JL4Z_C!IYDjWF5 z>Hz?!$dy$>4hSt@A5_aQK*^Ps!o4pyi?W~!E>j#_T4G!gj|ybWS0Q}stw(#cq~|pn zXNr4IDR#mQupqO2vb}?_f1upAGJAVwa`%;63H!AR>=@Lr2>#em>xNoy1sP*e#a89! zgu25!rl<0=r9Y@2f&Yu*Y_`M4WhD3PS=%hkER-U;#I#0)_x$}r_E(U+)&}_jlZX_J9__gtGBCX zZb2X&T6)KdzPM5{$K5{PIg}2PA%aH+=Dg_hC+AP%#)gOx4axT2ka2Dgf?(zXtrq}3 zUMs>Tb(i|r+ZYg?IWF&FQNK6xEj=RzkjN|gLS6u(XKJeiGO15i1VR4b@S!ON{LP>} zpC{P296FV_3PBxDkVRB8wZloeBg1I6NA{|ug+Y}|`%g;q>AzY-yx6Py(HtTJ^9B9X z83LH4=?3wM@^ON*S1R36hte+O=u({N6v3tKK;t;sZ`WZ+-dD9gG>32uh*XcdL;%O> zBmJijzJxrjQ|ydiZgO;Ra8dli!|Bg-;o2{|D}u4`W(2zu$CFrG3m^4x-d@&= z^fH-fkIoY66E?Y~64`4K*wmo%qI$0f-alY-JHXt+Ov%V9;Qv5pMN`kd(e%4&gyc9B zt>|W^WU)yUkvigX9N|i9-lJP$L#c>vKY>Gb`dTHqvCqIaa!*&2>}(~qums+$D#ac8 zX#)x3-SF*(0%cUy(1&N&n|!owB^yLc-jsNG7{RO<8hE+lt4h<~@^qGcTHKabyV23{7w z$$taq!~{HZ+5YnnWDOu8oqCwY8bsMY5K&_WRtgep_Fiii$J>q{7lSK?`+OiLFJ|~& z8ESK_ej-rmzf&gmCdH$zo`?0YKU$%9RoU{YJ=4>dc zxODm%FQqq1;h3FIu=L7_ZLLj?Z4IlJSC~kk01Ee@5a4PLp^_SJIKA;@gKh7<(9ln< ztQo3K@+roOnYPgyN{Otx-afZOk*sU2;(m31H4}}-I8j!d8SY)Ze91?68@}ec?7|dZ z0y?cFx#7K@7IjJa#hxX zgwH+6yeO33MJ@%MO$afxqQ-ZXgGYbL@6DO<^O!EK8w3U|g~fIypviC1CQ$(^D+Wcg z3qbOTJ+zRdZoNewnb?#P<~sy0;C;&>a(Q)Yb$G%<*@Tw?geo+`o;rsvkQ2Gwv;yMo zfov9*;N6g9-ebr>Bq&^x!6|$amAf+1X7d}i$o0u}_A@gIh>2B839er#9W7DQa4Ur= zdwED=$is_0d%9l*bE*9HT%uRLj~Mu%lfP7ZJoyE#wPi%px(v+Tz2$(l zo|3dek1mo~AILST#H}LXdB^h2th18JhUgzM@Mq|-;8FR^&ppuSETjSlVYl#v&{eds z(B=8&b31PYZteDG{4N;`LNaGg)2#VrCr7)6jB}=byf%uLAyia}Itxg&_q*3u9H^fW zwfvE0!ihG=%-Vbi0OIwl0jHhvc6NeM<_;^CbUuQw_vUm-gz>#t?vb|Tn)?*a5RG%23Q$?>}R_&cU>Zkn9!(JvLn=qd1xsDe2CKMSG3YgF+QX8#vn=0!A`UqUCMe8t^&ehNLBkA`teZion#O zixP?QV1YyCGiO3zWG6}02slU*gp_d zSzMuwGnvCmd`I1&XdmHF9qOme>|#@xZZ%VkRyi|XJO-xq3N6irebZa!9y^VIz1uf* zvBfvjcg~ckKODV4-2?!UW4ORius0U-E9Eu1eM+i?gbOs)M;*ru%YKiRg15 zHl8=4LX#2r?a(ZJ?|sA?B1fYnsecr+qy-JSa-!tIrq|gzCSlW@{C=) zAC#fr7EF)eTS7tBs)PuqW*O73?ns9zuX{)^VrA>P$ZA9ulbv{oa4A29HSd_BLNyEf z-5*-oKR+P_$~t;}wycIvv>p;?S(>UqQ-Tf04<3{mB{&HH>@$E`;0vWplElH@00(w) zjmqImApXNGL;#I=l8HzX>^hmd`Pd*x)FPjr$EUMg{nY)zH{opnixCxRu9M?x5|4-g zf{@rdXz0|re1uWZgp_a<+7F#8jGPdF*L$-`uL5ozpkYI6z;<4XhoM4N8wG0;v6H}i#quB}mtdEtW=BoC5~8zhWV}+U zb|$l%G6+wv6kPV?0n=1!p51SX{${YyeJg074F&m8)o8UOsbsh4ytaD@OVUAR zG9v`H9c^OFNDfyLZKWuM1?AHdCAHp!{?tDU`D<#D|<%DCB zsd)K|qVZq(zw*C|ee`_6^;5Y@0?6J*$YGIQbfD5J@a0K*{qJs83_o;-kT{+o<;5w1%Dr{8tVF zj@;T^{3;g2tbu9`Np>DgUn{J}9zUq>kIzayK9uAi@T1%qs@$}rMyv28R>=URQFAfY zE@+P|pSbu8<;sJ>X_G}!EyhZVm`eT#&e2L`?WG%Cfp77Hc;>7 zez@{p@RxRscBQ6Kfoh8k5IwymU9XdH7DE;brT`mR7Hee-Sv7gStE3u>`y*bd(G zF5~7P3b2M0zwRR|1ijtY8g}K(6h4LylQe;q)iw*I=>p(#i zfS&&Ugwjl;ZU{$o28@@CI&Wz(esJV5agmIU7!?AJ!HGon8GQ1Z2cnqc`a$sPT6gI zqp2-BK0bcQ{EyUJuRTOHmhk3$l2U<#WF^^>wEXmJr#kbzCRe%qg8fm?50mG_=MCXC z4N#I+NNzPdEy2-IK_DTcW!BrxwCZs8#8fj!}`t3$aTZBC+D-;K+L zpu+sbtKkjWT&Uo4rAv2JuNDaR&&=rFH9epNiv3Z<1*3_=YugE9@)LEeVyzx4>F!$^ zOd*a52~SdKVc~;>96@mXv5W6S;Eudwnj*i9$WHj= z%eQFuI+uN_Lxr)^iSZR;a0)i$b-oNy{SqjQI{S@1@_v(9&lxA7vYtA=*!Kn=_}63; z+3d)zLUbfutKFiNZyj$s%rPOvYtf$0caavZCqX~Uc#s#Vu_3@UI^(@JXL-kjy5Pmn z)~TE;LYzZH+ZtoVu1VsJlv$tY>Ohl7cG0>U> z(39TQyr?(qOci_N;unyeB9?t3`%-PV=!eOc!Aibax|O59egq=9Y+gA^g|rK*^ksF> zGwykyixXSTIq68G9^oDq1$c^LaEoG>21uKh>@T2@?+Hwz?e<`&drKj2=Jr`JUtIXT ztJf96-sWnDWA#t@TU~pMYx{FAu}k>Q2<7zG)xr?)p>N<+O?!7ubhr0Y`*o(hbiU(h zW$K^J$j3zGdDF+5YSy{oJoydcmR4xAN)axUkw^IkP||-P)~ch=m@YT=?j)we zB7>ASZ`<*|{bd|vLNw5n(Hkm$PTK+EC13+sL>c zGaR`Y#?7~KVbfP;3dicZWc z#ZRU9vHoS?Dnh38$Fx0$O#LZ;&WTf+e@MLDA4w9h_(SJM&*}%2A)=cnG>uSl8C%-^ zL$gABLVf@DyCyrQH79su`XI4MsVHtUfpC^Pzc7Li9aL0((IiaT$Y|2$+<2{Wl5w`> zeo+d;z1;$f#$Lb-76kiDB?!uqs~5xtjh>dXxBo>6li9jkGCw4sUZ5<&fobLH^m|0i zNGIl4N{-&W!u^!}?yQkPccZ)BX$SBjKmEq> zUWVTf{6lXU{gcPVRGTOrD|0sj#KVtg`j%TE5>`^h(cu~Qrfiz61G0}3y8AWHJx$dv zq^;PJnHO$)sVXaaNW3JJPh%*p?zR>ZZm~Bkxsrqr=v&IygF{<;ciL2OnGO$bB4@S+~|Jx?eqp z<84&`X8u71Tx(D$hH=1Lx@pRN6=iUCzi?nP(UkOg|C*1NUsM;_XW!>2=49Y`LDG#4 zVzHW4s9zIECBxKwMkJ@=Ov6%>vlh3H9~6_1a-5XW8rCe7!J1hR<m{Lu@m-_p3c4UOmTy%QO1 z8BE3;!?JkHkfyQLergp%5v+9}TJ3_BT%I;3HNn&xzXTKRxV649B0lv%SmGA@m9%J)3tHOC(5o$2!{VEX5z<}A<;#F4 zm{|y?OLd%|>i4BZquV0*tI`pLbNQE_58r6X6G3;zwI_s<(1aukTT)^PH@*lRPM0TT zxZ?@YsA8RD?tv2kg_4rA@b6R~!evN>0yF&o&$p>BGmP9SBf8e>#wU8m`?&!6XQid{ z%4NXVR~sVz<{(`sRJPQ1|6JsdrUmCUlOvxc6weC(>w2T|9z!; zF=ONcx}^k~MjCw8o_}LC%(o^g$fw4F1k?7a?@ZA4wV4!OXe+vT~dBo4RMi{EpmAQQSNSI zjmletG;RHm;N<2cUxl2E5%aM(vUa~8vt(&)(GZMA{wBD2=1*{f86y?b3W8uS1u+25<4Uiq8 zr2$3tj2Yia-)ev%r>BrW0Uav)Y;5`gdT{~NNaw^H*#^|l0t_Oq-+zJ^`lW6rMO-9o zk=;pz=$wM|F2U1kCWkLX{TJW>a4_U>T~pUn?rzl_vQ*VCb?SN*WD%)`B8XVcvzKH4 zB2wTP@wp??9W{f$81uwu|J8gL>4SiD)g7XR?u1z#eN47n;9hQ`DgCPtvkg^$=daoG zSS08!>Wu*W2G+)2xT0d2~UAJU?F=tkxZZz zvNmISIZ$m$&(u(@=Jr0J2nC0Xp?UIXAseRTW+wPH@zPXvkQ1cjH*ynt?RYF!_=fm*_Wj>{x(*T^z0OY1 zIv;%l1A_=QZA$sH2$k^>;e@q>(hFI<%t^h+@IGj-L{YzO=k~wj>9DhOB`I%vhe6?w zhrUI1X2LDIS~Ua$v)ik+fJk=Bd-J&cGFE_NjH7o>5%`RJ&y%V!LXKBo9}t@F+6$U8 z)#;O1znko8nm=1qb-$us>vHlWi_K9$_rlgb-(aF)5MiP_tH|j-3fMN^aJx16pGAM` zzYri(ZS~yq2gk1`>*@R}sRWjiNq-v}EiZLuCbN zNvn9T{R+ze1WUHX#jK*Zak^4RWJNi?%1oWKCENq1*Z2Vndmkk^%wp+@o|&*qT}(V* zT6ihr>EHh*-XGy{9B_c}Jz<_m-^>A6SX1-{|CetAn>ajjMHG0L1*fd%!SuN0lP7M~ z=X-Vh^4HW1SZWMl#C^-v_NnK|iV+X6vp|!A>P%tm?c5+D^PlXN4NGbmPT}#$unHa{ z6eR*Y+K7XZgL0`dj7+fn3SVJ`BR`LA-0#@ugS4dtuX0R9UFpFm^l9|&Y9c%s%0@UV zRuHQ+t}*-PnmW8DiY)IzL7(B^m(YA#vVF3%y~~X@{gYKf>%b3i`sim-cDXeA;7Gki z1?oU{nq|`;nW71J5W~>9u{qrL zkNoe?Q~j8`%6>j2cGoRUu&8h0bo@GSSx(y^UBzVhLp@>ZA@iL?;uBqag4*hUu55+K z@OzeTvg(vu8f`tW+OL$#&hEjUv%Tvt2NCoxnN?X(=hZC=lwsKZ;`cUppdt`)(DSLMc0dGp3 zW9nDo5W|OYr<$B1(bylVWJKTCg@}|rU3o@yYMI0Pubb2!<1_EhNW7QfQq~osdL9Wx zz(GVm@hgWPv@Zzbp?pQ1)hyA-w3YrXB4<&l0$7R_-XSc61)B7v!7WT(O zDf??*u5R0zp{Rf-epA!hPqnY9e(Rn)fXxPc0LrKzhqKCt=wHkJc~kW0KIg(2hhp#rx8|Hj0)PeO+Z2@jyM^GfGIg ztLt-d&p=BA15XtAGD0{ltwMo$tH|17xhBH-R_H%5gY})Ol>3aYfLo#pha4u(C*^a$ zfu9o;Gwegq>722l*IS6cXhW#`p374da3X7-U#s6reW`oVdz0Mqe0Ns3^1?W&3d$_Q zw^66B)uCV$HD~jbfsaF$n(~|Tb`&oxga6FTpl7C&uBdG)>Fuuv=Bgi=la6ozVE=NS zo(4ba7-v~XI%$berHoY##DyPD>_G-1H^P@Ds*4Ip^qIa#4#Ah`{)YM4k0q{}Z{~k` zwpg+`ZTOBC-hkCG+*N>_PIGM#R=c)=eUy}Zzkb$ItXeT}Y29>E{436h8krA&hXO>4 z$msTDpF1c|>80zG7307xZ9q`$UAjdWZphAV^<(HGHTZ~njdAvmZr@}zl%!b@q4fdu zU}P` ze(sEEkhzXj*|1Z-Cv$!k`L2ymG{m3VtN9Zb8E-#|eShu`l#uNFgSP)XHasotlS>6| zo|E-T`=I)`oNGj0aLy-!lV&to>-nk}ILwi*uo!8l^q+f>Y&bh^R0mA2%u~j|)O%HV z>#IUYp8T)i$ENeGe9d(@}tq>Ig7@X=(eIpYX2};b;Ui`{eC9tv=j%GX{qI14*I)8RTyvxkhEE;neml?r;yVO0 zrb!95odyb51xr6_c!GeGmU_#sRA%N@kWXK*cdY{LKTu5X^`4rQ;^3HB=do$6AxGHK zfIPSGNorz02(euxrr!xzBX%@lh-683s(Rmn_2vXL!BJr-JeaQfq&Cvm*uME&wF5BH zFin-~P_WHke-bcfvr@&Up0u2-tXpwiFeJOfja+&R{rd z#j;D}((O;}GUAr!Oi)qne*eaBGqc4X+8W=y*Z9@+O*(ufW0Y$0*b)Xmqk3F>&@$GM z0uKMlkrvoSmyyVmH44Jxb2L<%sAi_@n7Hl}apxMzEiKUX7nQvDvutOt{Vpe+_`ZT& z<5#IfcCkTcC;=|DHb*&e@x1s)Gi62d9>N~cu?jy#@IP&r5kZq0B^AG8R;lkTq;5OA zJn=yC zt`8FAYFSC=(^yg$Q#j|7K}W%P?^ib;I5cN7_sMdmQimi2-DwqeDTi7J+>nm)4ZTEC zmb|M?-~59j$^*Up^ob;usg$(dm%4~+43z4a`loI6$UZiih+WPp-bkKMMV&WQwIeV5 zwDT!fwxRn|wmDuTI4+62iD=}AF2stWkvc54;{v5{1m4Q{q=r95_8w3f@@u z{>C4Y@%Nu9Skw?q{7Prt>)JW^%B-ZF&13K4%q0=wLc9g`=ifLuJ+j+scS-U+)I?Y` zf$1DD4k;RuV)GD>XMZ_#QTg8k=@;;kGFY6|-ctFqKfgEu!^JA=*G_28~>I4(ZSlZsI17CmS`}k)8|5MB~8(w?EtUO+1A*;zRjss#>&jJ0c8EF~S8; z^v{uI3hYJStFoCgcDF7%MHF7lBG;|%vW~<&WgAjV1O(YPU&4<|tw-udIDMR0r@p{z zrPU&BPuXX~zAH_^WwX9;dMV`lMy1nYRpbxzBwEITa?>n15 z#Zs;cOLfL-0tss9B#%Fvv!tu-UP__sBjcsT8!q&R&2RY97-kc!axrBASFt}KIt5oO zA=?k~JXd!82co?Fl=o#gdi}lj>NWjSd=8cB=g1bj2+(?}8JxfAVmlst{zH5uS)^B( z)<~UsNTm*em;amhd2gkqT4s2H=H-GSqNQuHBud7a9@O#zpm7<+VOVXq^+=7`wQXNx zZ=cw2i%~}Znb^Mm>x}A(!2_awbK72ta^fSe>Su!f%3oGi`(oVta}5ljjat{1Jo>L_ zcHYeV10{wJa1I0Z;@`0JM~KX z6?iemWZ6*__Lj?{;p4p!tx~BMjmle^rQYz-+H9VJH$I$puY+O80L88 z59Ypo&}!}%P1b(YVary~RH8r!Q@*Vp?csvjN;0!-yxUHp@&%WcefD3kqv>#JuZVCD zNqi<3gLO1y$#!yMQ(k^_!~Eby%z5MNZ3rY;n8!}g{KAcwM2X;F{$<)|jiAW4X$?d0 zEKu+>4gO9;f@}W7mo|!KP>rJ2IwhG8H@uOi#}cWBAtC|3gF?OQ<6EC_8%HhAc<7ZY zfkk-CNp8&EXt;;`dp`9Ras zHPG`#;i=S$k@L5gIPLY+gDOV!2YUb4{)=_fB<61H`;-c~O47<5c+TsWlW2CH@xJrD z>bRe=$}{R_Uc#i4f4xu9VNyf(9mGsXpj0sqiDQ0v-GnipO%4=10PuYw^3Ou4@9mWJ zbXE^9BS?%vdAG-d$Ra3&|Ku*`BGI3d2%3?d>IkpqED2RHAig?gr~>?nyK_h>_TiIL zdbS=MOfht}=kIP#luH+&7D~7|1NcgP{e?^7j2dp(^(hmEF8fcD1Z4fnWpEmFYkc{- zh_`^KruTeuK~+}OHRdl-MT8sja`SWjd8Z>7vLtXcW^_)z8co>pJ+9nKw@f2~mI4}P z=67_vb{({MX8TlsBTws%9PwuKJMm%sSNtVLly*?pK(jQl9QpuVX<;ctT^9Gw+t{oA z*Ay%IPWHjNHE{7WKI`})gVI`iW2Cq)Om!wjtP-=t85Uzs=wD}OL8n9N%+<<&>~*ak z4mpI+-|%c?u@g%m80U&5#dC$?MfY(N{guZRuUwuQuAs6S&WJEc7g-(>Llm6fth~zm zGB#zj?6tX15emqG%CFezS>$8%(_H7LD-P<+L3Wo(e3DwM%3y3gp{dFyOMov)GT#_w zs}Qy34!@Lp<QOt?UcJimJKvANJe4ZW3u3jvHa2o|9N_5VyT=XEbA(2E-?lc)_b|=g|#jkWCfyg7ni@0~BCX|$@*pgLw1 zD0>4L=tA}x{zIx{J8gk`lnu}<;ZA_#s%@J*V_|LGVJE&f6{HA_2iqeQ>s~Eptc%fWYKEqKNWh zmrKT}5q`L58UZv+a^Bh;&udW3tH`f%kv3EK$!%`h4mAaUJ5w*~nr?$QQn+p~X?0VM*f{;mjd!bmf=7=hxRZT+jL`QMC5(w7Z1G z?PxvvpncKc#M7z!{tuSdKSgs6ASh|z{7C+5!#|&mpN@?g<0eehKhzfuVOwkoPt zPOqN;^!EXc=991Ghp<|KUuY`WWqG0*)ctET4#gG?bIsB!Vh};aE$`u7+KTvn_oH9O z7RwOLcFRO*+8#mJRS}VRmz~^lo0e9nRHSp@qgPebh)3vv}dH9;qd&iq#+|Zkti|i+4i%GJ)Qk$*Q)l zj|f~hHA;!0V&k(gsPiZ(TSJ2a*m(Jt)cos7Il`+8b{kzr>?xCW<^sQU(vKw*=jcgF zLrO)ed!v+$uT%)}BppD5R;l>@a~w{NelYpnBgjn*Cba~i|5&2lU+W4k#h7Zhss9gD zj!;N{iQy0uu6$!>x+;AN&h2?^N3>JHznOCJ1nQ4sUp+?py)maD&^`Rrwox9nMZ8|A z${M(woTseJA}9MW@733jwD7((b*P`5Yx6z-M?bh9nU$rsuJB1I(iIhrUOl{O^$dAD3z(Z=%ky=re>OH>n6wzKa`){APH8@S5Uc2Di%Ry>y(u8GE8Kfu@V#jV=ParR z1o7Ln+3ym+-h@I^3T8K7sJ%#0&Y%9B-q=c#B6m<(om1a`6+-n`)x(J)1v5zi&g;ls zQBnRz3JXU2y;P!zG6_5%uTAQ~j0{uhsIR&?{d&;+-+80|-$C!P_$ZM9*D72+_fn+d z$(YRE^5j3z+b>^EWJ^vV#t87=rvmqxb(`aRw~}UG%`?zf>UU z_2f(}jecD>-}OnN5{ml8I!ZaLb69-RG0FAoqUjz7^Y7LXOydq)@Dri5q0DVGKbhlr z43rjBqnF+7ZJH?MEE6D+!Kl;LP*{a>J6beNX?X3fm#gs_NPadjpX~uA0i)65(Hcw6 zoce)bEu~`D;wsvqf^s3g+=X*M2qZc1qNCRw;0Mc3(2Z-*YM2B2G+zb3B<$%R&evyl zpDr!#{^7{68r93~d&{Xl|9$(K>sD_4Z+24Ew%%9&g*ph6gMn81w5bz$Z)Qq5*^HyD zDMjP=4zIHAq{T18XTDMHxP{XGA-r(?edk95DSus{KI98PFeHR4#E4gGsKSiGeg^9{ z3<35Ih^b(mgJ=vmxu_&Yx!H`$gFyBD!MpZD316qrbRg3+-?PJZAZ1Tll4SS|jD z4sJU2T`yIz9lIp z6i&Vx-2(y!Nj8$=sJslBX9Y6Xohc=C;cPeBO_zHD;qzyDIG@jHj2_Jam)@V8KSz_3 z!xDt5L98+0quQeISmi#5?&TiiV1v`gARXIUlDp|XrX~^Af&vwC5Fel*u2A}b_?bG} z13zdwsX>}PjHnl8z-d7E=~;Z!9@|yeI`>*^I-vhi%`mIV(UZu?BRNyZNN`=XUkg(# z4!(%=*Q7zR(?S{k@97vY-$LJ*PuTwC#xTuMOvi=8m?`|#Tn4?oq z;LW!5RZdvQi#KJV^Rj_wHaNe$2d|*8h|c54eNVwtvrd2fr+RS0_T{#Z@kni?^S>KGnP=S3#$f>Wz)MkM?54bjFiM z({V5*jx+Ys6aK6E%hyysXA5&2p2!>r^PEc+*yu{Cc`wvpdE2TBaS(j|GR4t&Ta--K z&Eq(Io*TXtT{O5KOc>&pgX(+VTI5(ly8mM|>N;6hyvv2lNAcbHkIl}R84^1jGKCR) z!)ep&OeqO_k!RUnm?J);I=wH{#a5m-GqBo&+dp<%bUim&&gc5^SAEFl0xCHhp zR}E#W6cnmP_0G?axCClq!4UkG8xPPscdoo%BH@_G$1eI`keLO4k~U+xhm8ecHH|$f zH0r37=}thw#a147?9a%ALjqtu1sZ|8;!=UPZ$Z+x?1Jg8Ha@^>U`WncuSH8P<>Q8g-aYbF|O0@1`yuADNjXwirrNu{(-dE&&Ilm zR+4EP=3lks1MmFr=7ZYx>4JumSMcjy)fcq(^%A%8x+L^G&pdJ=0)gVxKwx3J#{v_TPx3-Pjqua zODZ)@Qx7aFsX&%mGSIc`Izrje?EB#Nt9f=(RnGnQIUDU5=V4k|a z6Xs(35)^Jk&m#0aB}HcN@VZ$*(k4~WzTIbE)te3W(<)h-%bX3OIg8!j*xxK}hni0M3#M z$=6uhzD6GMVLoP2ImVtjp+9l$%O~UE$^SqDlqlQB>9LWH9Of%dd5{_&4%RFvX=yyP zR_!FT-y$9AU89fT)5u__LlGol)!&j1);2wTFCCx;oHWGzVxFmEMdv&(>ptV;=n{O3 zb++v%>t4ucODQdjM!5F26Hhe(Tb%A|I(!V*WBOye#w;4$A)~hss=0;V^YkWDDjw64 zj4(cfG|?Eq(1Is~?z1v*mfq32Vl9i%g1bJBc=YE&!$}o#(wcOTWzjIQf4bZ#<7eF~ zW+6Tlg@6bLwM-D_aZHk&k+!sZ*eD2$4G!GBW477)LWqI`F_9FYvb@M^OZ(~|fs~oql=qkA&1*@TGhr^k10w7diGsoH!B_odLctXys3X#mff+K5as~ca0m?U%nfvM z>iB#Z%12h0nV$#Agrx3Oe`B+_Q{ee@_i4AZxy?v(sRQ+6t|# zT&~+3skyq@VZ`m6Ad- zF60UdbbjOK(B$bdp~jii`uSl(ae^r7Be9geXb|XJ=@EwWlNx4%*O3@Ho&k;wHa%s5 zC)WJ55^NBkUoDC}cxca-9v$hHqO!MiP-gnjcvobv*Y3w`CcpL}!?qsKL3`%lC>7II zRY$eREp5}TVAOjek)ataZ-1He1&c8EbQ@t&d%Ww#@4s^2q?!QW*2KKHKI+@HUptDDN#BwfbytO`mC>)_&AapG+f*4c z@A$|m%b6dDJ(EHX!d-HsbmeM4k>f=U#9E^lA|oYA_O=;NG&T zRoOj~6Z(8}2dETzH<3EH-TnCQ9MNz>|I5vZ8!la?nk^cIirx{BhQggQM80S2EtI5Nmp8?fa5=xPqwh z0Ba&RhH7uIt4h}Ex6BHvgQ|NXw`flGk8pHRieJLx*QeMFgf`eX5=g8pB|o~&pb~ut zNi^w3S0^{V9jSjWdXO7b^HcluxwVK8q z$(>P4WDc6HXxj{}Z=r(bZ=Qta6b0bpCMq9@?Vb`u1e*aLU8caKW0y z(boBOyf}9}G!o&uSMIQKBllQxL5S%6>RI=M4b^G2GjZ;t(@tW2eUV5r$&g4A5}p46 z4?*z0vfAtiij5XDepHZJ_$Qv8ef;0HreTbN90I`i0=2fkr;3|ULH8P2wkc8ifcFGf zzJkdH2aZe7)!rc*kGH7b2Dt-Du`4RK+(q485(kZK8Cx{8Pfx+ES537}5AqRS+IYCJ z92zPN&J+fJ*{ zR+yYb#Ui)V0={T~c>e$`T5MakMke(hV9L#ngY_22osv>VDg%okSQp&Y&?F5cV3NtA z3mXI5SV)>F0|#YgHW^6-A93^ZrD;ht!xrMxM??NI`rj+myS5C^xx<+X?XV?4q(rV2 ziRecKkdCgFwj_{ACcqr>T)w*uL@2l%JzzfJF3c3bb;hF05x7CCUGot`&{QnC~z3kof0f+!K> zYwN9}*SltCs<+LuXynDf+cunC&2wcck-QSd9F{CcLsW!-&wPC_~e37bXkj5;@<90(9vsF2(e7Xbr>z$jXX2z~On(^wPk=4=lGLhQ!Rs7HI zt{s#7ee}$prNfJD%2{@$Nn0*fQXG&eXb=b%d|0AMB8WXJVfDABx1G*Cvu@nP*>XZB zSpJ(1q#z!kNUjO#BJ40AiyFf?X2z~jF1X9HHq@i%`e^6}ll?SWx+e!7@d{{W;N3O29^vJW7R zLHvmCtxNd5>x>UVdMh_~o@{2$F_`eNWSgOX}APmrHnqJp#!UibJRefdTbIo1bj8Q?pYaGv&*<= z<;gi=)cI1hjMNQ=a!sEDx$W(zy<6&y+tfMfmA>asxJ?XQ5S*EsV+>)52(09_0?c_Q zzkVxJIWjB5&?Kr*-CZEBVnFlH1b4D^>U5fYk>uv&%Ws40Py7~omnvLC>0E3HXT%F6 zxidC-f5XVC3Nl1c1xW({LbD#FvH-Gs_pAL`>F-LyKel%)Y+2-nSzv})0yM%k>S`nq zqp$?fB!DcM*XEYXzGdzCab;s>O^uZp`z1zXVPL5MsRRNE2a&}* zeL=LdtiMA)`@*CUXW9!VJkh|n-qEldGWJNW<`>A%1aTl$057+F{zt7JQb5XF;=FW`rPDO{F;Tp|htlJ{hrAci25b`Jz=ef}SAJGNH& zw14I8+jrbOOpdXnyKqGizyKmM)}YHx)6^Q5q%Z)`Z6-`|j0=;DnfHGH5nzuXpX=~` zbrP%1U3~Y|R>hUL&9r05yW*TY{*trASQ>ChEGvK-x_|`GAX(F&RDaYzeR1BhXtp@m z#V^jX3g7bn=SrDHS64c~lE|m$+O&^blKYL}vpcqOZTntkb3)S$TzMxkp#h(v3l#*A z0X0JCbFYN`ef(ekC2#o$`%8Yx+L=|9V(qei8Yt1gBsW8KGjxzGi6gM1V_kp$02P14 zO}VyJ+Wjf(>DP0_%Y048Y}=)v>d4(jM*tEOj)I_(Y(W5xe4-{`>aGf^l221uVMd9* z_49YG-ikRT9n&#pp577EJp=q{_0OWWgEW4m%HMYAq;{7FHzl4dfE0p5NDPQgf+&JW z1d1eU?7!h3@d7Vi>;pOWT)mexDoFTQGApr-)G|vMS}hv_Kw_$F5nYM=;>Ule@<iSnnYPXDXpoJ=5)I{XaS20uaxF=RlYIz_1rsyG#GXM@{n{yJ{?!+e?@gJRyct-A{^ zA}F3{NXA-jpYCHt>4^Z006`$~d-W5^cOAz!J8>CONI_Hz>KThL3IR6VO=pr#@JXue zs3a|hM$+CE%z+qNw$qaGC0j6Y9#fKCL zEVoOjU7R*3_>{{Yo~`cd+lELky?6;!WCJeC8S0Qj@q`R%Q-O_W-X zA#%4D$dE&XvJ_AYx{$p@&?GNNzWfgQJ4O;YBX6b{$@JDiC?kPHk_8e!FbO=}a4oAJ z>f=cp%*sTFy(ASqEKRUIhl{gy!0vQR$1&lmW5yyg_hw~QDo9a44m^N3ARFhti`#o* zR^;C-Xl`(1#xWDGr4aQkj{FmR z5&LShE*arRL{*FsdYCb$7DpuUTvu~-rnZD*wdA8o(-=4Q{{V@Petqh=`8@HX;l)AF zH@3|FCScM)%w{FsK^DP*HcvKsiJ%Cs0M&zlWr{3l8Ba*-QcALb0XNC3usmHIRv}o9 zH$-JjWR+D0%LDe^-I8ckf1a#oj#!BL+{-Cmph+NK9VM&37H_v|<3?#9*@*y^7&L?x z6bg_)?r014K6~f|%>@=0{3HQmk0!meQ;#~MEO^9+zLKiOz`Hg80=ORB9ZnO89@=D( z$R}2{Te2#J8lhGg^Uov3l{yMQ3P&7uG=-gw(FAmkXnYR*={b~SI~c(P3uZPz=a1H} zO-nkPr2*^_V2~^V2OW(Y_UB0DOh8y8>9jOiMFM=-J^2@Z8h9smDCMUcu(00+75Iq#;R$6uha%_5frustAgetVz$*0=m$LTu0@%a^(3mOw)W3m7JW zAPOW3J?~6QwE8a^SA|t3$YmlmaMHI}01E=_p9i=4m#9-}F|qs>yPWXHEU3`p$uT9# zm0?1}sT4yHI208;~(kN*Hmg*uxAi3ds&M>NEM1>cK5mbdIZ<8IoLHE1V| z3X{_wGcWj8imI|~UZ}R6;UF`8ENrRel!m;CfK^}!`)CRT5G$Ik33%3$k0emWmohcX ze?jg*6P1^Rj#jt~WHwi*3IG6W=T{MWCuzq|t(B9RJ1IcHdQpDhYRCkRLH)*_mowBk zaD4>E#l&WCR#ufz_VH%V1P?lzYamtyX4Qur}$zn|c6b>)*{dD7cGi`|@200>~$>>#x5J>JQvk)q|?hdbq;k|A~ z{6}9g9={Z8YC8UJ@YmD%DVLWfVf|aeNOw1IKj)@TQ%M>5O5V5vL!NOgv;KMRBsQW}hD^p8gAWF0Y?o(w&8yr+_f5ctKa@3wy)xj`z9jbXYRX#g@{KKtCGrKP$(*@&Rl*C zGJdK50HjdklN!5jzWvUljr>I1_r1-rH_e^5j182WsV{XSs7R=&tj|G(6)GeIg2a+R zI^8chv=%jZbKE3 zSTIH)0vM10G&l!b{YT-qlQOwnUuvqqlV#A?rk@pF=SlSMsJ&~lZ8%$&CN|T9w@l?T zV%tpS2-zsKWX>5C%7b!!ppwCXAU2is@2RpecKmokdX5=(`6V-^L^zwb*Nd#O1&|ft zK#&GvSSSDzD!BH4sJ3jh+(vh%{Y{41lD*WRvY8$+JM8amgUglhWIS z0c6~LQ@29Itju<(=Y|j{D-yC7V^+l2By0pRVcJFh5!&klD#7NvM)>TzJ~N}1{O5gzKiuN zdD%%8Ghpr8lyW>dPDtqqD=WAps0^T~qu2{HyVtBghmma`Thg1p9J|DX%4MGzErZe> z57ttuPu%3G1ePF^SFLk--nQ?>$DND0;l}>}SLx+#*>jwna*Rs?AXOux!2|-4 zrSu1$Do~Y0dUBikSpNXlY?jt+o1gHa6vU5n+y4Ob7B&eCk1kfrB&{5ZNGj39OA2Aq zNm2m>*aFQy-~2K4HshNvCeY29EKZ9&GD9Xju&aSi$skrL2^T<`Aoe_2dQ13)>I}R| zG4|>GC-{skX`;b}WjM2;b3}kh3|Nw&QQ)4gpXS!pv3k$=ot5eL+9%q^7Fs*TlVV_( zC#Zr7$Yf~Qf$0=z00<=AYoC)rt;YO3bl=T(_peg;>R0A(gP3lfgZ0kcl42VsMC=QK zxUMH7ppe9>l0XGWvO9_ws=R%d)pG`D{WrVHibAt~1;_-0R%li9pWE`+ZrHOuSBsi) zbG<#e$svid7awkpJax$`PeZfDGn^bTg<^|AhpkCiO0 z#II2YsQ@8>4M(Jl0_>5jU+~>ZbEgRW?~l{C{{Zq3itc>cWPZP=E)0m^@~(`eadbf( z8X)uF-h>1)lTa|B_fW7s`Pb1HSbnkIutr;8#PW$^lR0-d2m(AZYFNq5irL=z)0fBK&wOm3pr!njSX+b(B`J0H1FWo z+9K*H$8zj(XNL*Dn1FnO0sjCk0PWZ^f)%4Y_U*2#gnbV-@=kZBqK9nBkghgDJpTYz zii#aEiA|~MyFkARuK$9V_^p$QG$>Pfnb0@Hb$y3eIK{(sgskm`m1l33I#?vS*bQExMM@I%>5i!kGAo{t!AT~7 zP%h2$L>jI|IJ6mNoTB*s0`ubRa#z@ARWzr)*0YJT&a#GNGzSL0b=5b&O8SRqD7%Ky zJTfztRg@?!R*3?MBvBMcf6t9l{RyOUzlI=%>uxNC_n~}z{=Kxn(&d`+)A>6a#K-Px z2NHF1-A9ik4tedU%Jatvj3{AT-QRw7whVY=`j7PKWA9z+=o;pQ@$OF=7~3PrUX_i5 z09%lG0A2e5!PRf4XWd(DFDxs$raQ_3AxI~JK;+h!mRYXIHQ%+L&s)Rnn4}w=Cow*v)CPN%djM*#~Yy`fS@=e_7`8iynQ$#zNd^3ITy$P(fxEk zq|3JUhS#~P;}jVR?pP}Q!hs}_$QR=KUyl0Ry(#Pc^V9yIi+aOUGDQK#SlO9@jH>_( z5=rST)H@3UOaB1n)(RbrY7Yx-$^QVK>#r`zQ~^ZUpl`px)mb!7YNZ=3$2SgQ$MZjk zp0CMSaa(bCu_le8cu)d5SoJZo2_%{%l1ZRD3e~i}uJtzNnA?6|sHMi*u@&OQMwOBz z3Z#PHO!XEfsI}Q7U0$dp+GJqL%11VMs`2`0_APQchNe1nJ0Du6}htne=%SpOoupo62C^g_!@MsR)c+hv9yFNT< z@LMW5;8rpKh_*=zEU@JN04U=4H|}pc(QTTPQooSzBiPi94=x!@M#O3fvH;+Cp5 zoXEf4#EK6}iX9*Z7EO`kTP9A?JJ?ks`5@ktlhfIg%1mJO8n6igfCuvP$LpE? zY}es|7{&svGLlK|dEix!c;ima-4O)_l!4LU0bbg%{>05mL~`PkC_^B+Ak_=^yZ)LS z+dkmKq2T8DBDm*GDXBCC283V_7zgSWEI!f=SGoS0yTZbGu#+UuCOlY+{{XoGjf$}# z0!U?bB!kHeXo|fr7SEj+Q}l1112F7Jv0AbJ0LuB(IdaObr|s*S#~v*9<4G<{G1~M# zs{a7O*Q;{3eS<$>-M5K%4E!1Y0QAz&Iy*caAOM6LU<#5=P`>1n2WCBE!Pmpz!|bnD zdP{vx-)h{kVU6*D_ZwgI6*y>`=wyQUfSN{MN{T1nK_Q2gYIYwGYW0DxL-HH`Z zO`5L6Rb8Gu8ruCmyx?z}PA=)TPxY~~P`pjRBnBYZ1knUh_SeLozZ*`Dk40yCuVc-{%E8T(6k)&AfW16%F(5JNU`HZ>s@3x7 zbCwkGzc;BKrEjLVHy`|5?KvB7tnsFoF>)f@k*9_s98nB)S0JZKfX!^hy4d~1nusC=23`9ktNCaQ>t9PVYW`^}3zPMlI0NOgd3nx{9LRB7#jQpge0` zlVZ#P8CozBz#)MK``Ew8Yqz4uJXn+^+~;SG>Dnl8hD39@k`U0!dYKuh0tui97hI7; z-(64mVf;~x(erO9w)$@w@OM4E6Z#-MQW{kt9KA&<5Ds z6W`BpKOi)K*z?Rk-62Tkm|I`SY!-3)4B^$ekjI<$xxE7vOsfmIRON> zS0o#;@=rE=5nNWbB=pYU*$o`B7*9tk(UC-VKWHS?-?;>u<4(uuIZCSKXT=($bgx1& z2FC$O09m8^{Oa}7byHi`H~N19Z-V1-qDcXh7C9qYPDn2HTDyuIP(6>g&FTH9V@C1} zxr%`hR14seK_CEm3v_z|dDiN_jKRfI1ekk>kdCA-^sPpS99Oyb<3#@e$xz8CjSSH- zZlJC}4y15H0DOA=BOL@@~$VP-Wl?;F{cn^%pHr$BMkOWRZt{?PZlotuGOj^hV}Uu zWWJ?uTY@jUe?yxONAL1&>nlNz7_%CalBAB4M#7SKs{J%PPepEd2wx{F9~>zvzhNYv zM}7x2U#_~D*f*JR87IqdBK}s1fTst5z^DXR_vBF==~;ai`;4W`vCIQ>GW|l|a2%dU zBKr#LY<^b5@W)W6xy62}F{3Pb(Gp1ko`3)XNj2NxSw8wa9-i1?gnezu zkXUs{7=;`QAOX*EIX*SgThMD0M3dl|SjrM2v3*$$gZ8qE9Xt_dfI+j)i3g?Tz{`>- zplQpkwk)o_3bqRaR!Ibo2X1VQSr5ZmoAXZoNJ(p8xluX3&9wSaWRYcfvZZw?2U%jh zK=4TI&tOlIHD>~0N7auG$~9E&$&Rs+(`Hx$Oji|Rr;Y26Hu6#>*q>~AwY6Gz#_XKp4&u;qY>Aw$YVI{Fg>aYBna_i@} z%_sg12>MMJ9F41TmNLW!hcBsZh#U(fI3t1yBzCINvHc$uZs|TYE;OOKTj6B0g8|UI30jiHVuFQ z1fQPs(#nXeLv}V;t&%;jp4zqA5=@V&Jed)*P81>>lp#r88CHl3 z-^jCFwDhn=jQH-D<04YvAW#)l*D9otNvb5UG&mQ=lPt6g$t0h{y0PN2%am&v{*=a4 zJxx5}MHhx4^?FD@&L~}Y_Ps*`V=%eN#}YI=7Y!9Ni=%2T`QVb&3BEP5PS9AS(Sij7^$FR<@k*6*hdPyXj0I?;ww%;cX}_(H9V zoW7s+CL{#?zlPlvjNK=eG0Pd~An*#YyEWTW+I?Z@9fi|3(|(uUWY3lfBD;V*^PR^y&yc_>1Vhq;qzV8~01w~w&?T1Q9e@D!Pyn8M`_&C|wH+@S zhlLqSYWTi>EYpuWZ*%U>mcFLr*Hc1Ju5 z?Xx@hX}v^oMia}Cl4q2CSnbr4V3tr=e4zbRG$}=^K0*C~%jzf`T3*j%kXXN2Wjg_B~JW;zyvC8Fz zwFYauvH;}ws`00?_qgU8XZK*HJ_=*V4Gy9i%Mo5lU_m_JzP(RG*LYFgo>tdyuj+I4 zm^?<57u_F3?%s*pA&g|c=Z2V!t&bK`$_!JWkO0;RMZUFHV9w108I+8YE$pZ)`lsmOO{ZR%m2M*eY8SOaL@g*dF!>6hPLayZTQv4j}ui%K$wjO5&AStboM! zBm#O*<_3wA>xF_+&@|a^(xy@+DyEHqT#F-%G$@|KRNkQVzWuuld{=cCP#}&ha;8Nj zf(uiY2F8pVE+JX&7ZWGaoD55jk&u^Ds>ey z_EKn$5kTq$v8t_f^5wxO?b%MuxZ{%dN?aU=H*)n(<+!xDxe{kjB^GyyWCRYx(6R@= zI({i~CCDmZ$AQ26iilNIQ7qjc@Bjc;=mr=?kopoUn5k zNx!}e<+e+fk~CEHrt!8&W83p#!HzhZB>X)jiYy+Wqki zMO|=s2Ui}Q{v~cLla%wn)|{-eAp8_zRDnoU)|;dQ(iDOXgUyh2WYgfAirE=^eE$GJ zd`WC?mG|>DoDI|0Q)BKsrp4(fCZf?Qrr8irwZQ3(0@w&p(Xv#VB=J;Uqs#Ti@c58_ z{61vdCtxQkWoc$AD3yn0NO6Xbsc5OuiB)7RNa6NHBUFIy+;0^4Ue*I zyL;fHNd_D+EUdA*h3RIAfMp;6I;?=lk`B1czOD5RV-?8BY>3^hl2ld=$7>?M6~F`! zI=x{-9=S;4S~|cl0}YIg$Cn|>plHt!`ODsxtL7CXt1&1 z3-t=}6@V&B0oBw<6?6c-a~!!h33o&jO_c;O@zjzqr5Du3i5viI{G0Dat7-KPZrhsq zJ0^C1(JYE1XUEE5S!jS9@nVf~4Ou#~FHU-9);O<)rVLV9DowMp`de!CjuZ`pzklWZ zrVN=HH(kdX87Go3

HDtQG|os)?W~feLP|>A2E(a^v(6o9dN$u`ws96*(Xyf~w>Y z09qYDjz#O7Y`d22Ecwlox@So~ObryKNtww-Akni{O@Zyn9Glfo;ba@Ijc#@h00JTb z76=2LIQj9aA4PLZCSEstar&1m_a_+o9aA$W(0SN`RLb=B*&@5UW0RK)AuI)slp;hc z(`pGI^^ssvWifw+l3+DdF*EMVFpMs{#l#Y!_<@BuE!WYzjx@;n!({XQ73~iGSaoyOf9=I@FRxlMnE=y8^NxLME z)a!l1htXS1F}m&fljKH2zIJphn7}%)Q_!dGB#RZ)2wp(C()oYH?W5D#W)Dxrv-Kn& zh%YP43N^7)3ZPTcLXMy)0!16XQ&Eo+i+4`2W!s6OJrIdUn7!y9B&`S z4WD$_GUw}+vTBM+C`Dp=RFqIbEoInPssNG**CO?A@dJI|u-6MOb<2|;8%T_)!ElCQ;Jc?xzco7k9_4;&BNB4C!>8Oh;jEl(oC$e2h@yW^to$c&;^is zNVC*H1aL2cb$Rz6M}KA+aPl&8=9VyiiN;vWECDPSGg}_ObecX5(AJf>=jBV2BTFO_ z^{7@cqLm;maX?Y72>@BU=bZ};pi&6ofaD*4$c=d|LzO;%WOQ-k?QFh_bypux8*Nks z9+^n$X0hzvIOm^w*4^m6w{8h0ZsjfziWMu74DzZoD<~n9vE&0lg#?q>9cb{%u2{Z% zp&-~$2|peAB%XdRPsZ5U2(x4==1vF$>L@D29>j1+?Z6|yCtPhz=F-~gz6Q09H2FI= z&*>elaA(QbHyjyRk)>!IA3(z{K@C6gBko-rj(Bw{OIIl|o0Mia#Dx2;X z57LwFYf&^!E+m%uSkU9;B?CZ%LPa1FNEco&i>H?g3=EmEH)q*$70n}zCW=QE0HOk^ zvt$54C!)G&B<lr?ig9cn-HXhfDCQBAUB$A@IDo@zGEo9In zkw(d{I=$O{Ik)6`KXs31+_B4O1XsL?h#UZmb&!p6xF?6~-d-BIKj zTuBH36fz(VrO0lv5J~=112Ff`em)MgnasL1ZFqEk>O(YA719b`^Wgq|n2Ejan05_@w z>dABEjrSea44iCNjacL3%8c5>HQMNgR0J+Bq2#fYGKfc?ks4seh&bG{BR^0DREX zTX(PI%>z4O^xk$`y(<~fBrvEf0Hsk@M<$qmFzf*r`Fr-~k+1~aw%l!`%BJD^jMH`{ zReqKA7UUZQP_79hOP8%<#hxlz92dzn{#D4Y7D{ff>d9;#mrUcABI8Vpid|)rdC?dJ zAQCzYP#lqTN#e&RMT^pSQv%qVUgIxM*)zm`&Z`6(EDaDrqDVGs`)OUTamm5-rW?ny z$&DU1Pf*30C&GnN$s{2pu_S^FfEKy~fK99Kc{{Gn0%C77ZPFQvpvIY8vVv#{6vu`_WQDexMvds%kk%+Lg?>u9w{{XxSRqR_(yBq_2 z9;QW;BooDvuZ!)^)3H=`#rfCY>Q{Pe8*23ovZf|4&{1s~%+WeX$^c{vq?ND%E=U*H z9&~?E&*@K1ZK55^4hS+OU;&CIWr+y4VC_MhngLA$IU>Q)@K$}hWPP(~i)}#yD2XP; zbW&YISR^SA--1cI=eC6y&Xzc(+-2EUA&3ngOw-8aiQ#OJpilrRiUYm#u67K4QO)?x zIQmfX%cotqV0N6iH&mNDYmKDaWp0%E*vs_g0>D%yh*l!W0{rkzY5X{_CEX;&lPhjX z<@$3n#8n*-0s$X?HU~=(05nH)TBgt2x6IcNVBu}}nG$tdmFu;>+0`#LW~l2m?TJwz&laouq>ddsHW7aZq1i>$yjB`cz&Bd*N&A`fWWe?upoe-Uv5YMk$HWVX zY$1WPCY3U48qS_I6h5 zfr}nvWkZjQf<~Uzgh}-JfmLQ9mZ*ctv%n|Ke)E?mHo=R!=k6LdaMlYDCT)c&Z&&T#Lu=DL9q6D}wSqBZ~!z6ft5SO(~W%~z}UEX~!IHYMF2 zC{OnjH%b8H9ub`V#0nGziY>_yTa}JZuLtL zrD%5Lp41X;*pSO&_zT>gEE~5Q-sihanKAAQgNh%bT)47h`ekTY6afu&V1q}GbFFh1 z2RjyN&R3_*IL{-=B!7$}B5tM(dElVx1lo%rn!Q+TJDyRUF?Rm|N94(Z?gPbxayu;$ z6uImGJ;=UK-DI71u<5lP9F|OOpU3&XECYD&wTh8v4Ar)kFs4ISXBzqC0pH9_A zDPnc+%YVzVEmjo#{{Xrx{Vgi)SYda(4Yw9)362Pn+&9!yMOY9`@JRyA3l=qu&%$J7 z;_f?KncH+wIF;dP!Z7J1bp>F-)KTWBfIDz?9F5}-2PQYl+w*cWItlz(RcVL^{0=UZ z3bAC@w{0=I%Y(a^rhI3@$Y_ekG_f#{2D0YVSSH9f!8Kj$Rb%O$PaNC0xW9u>{E_PP z@8SEDb3Wyrl^Xv5Y3leO7Cn&GkTj7Zi!GZiAa@{ zf+;{G012W;03Lf?)4VzRNedW?Jj0FjdXY-GhsQ~}Bh9N>zCi7u;AMzXI8I(_g=78X zV3#7nDg_(h009TLao=4$I$drYO=FBw_%{Cl&tj=h7D-!nZ1N|lv1b^#`8!T{i~zq^ zB;)jw0W4K4kb7BRIW@&-o8}hh2hhyT+X4COljI5n0e9WqpCfqQpr0FW+uQ5Lk;){NXXp%!2?LOT zkSt#Sf$yw&vGoW^WP5%p{?Tk@iK_lT=w}-vZbKjAcYH}Fba#|48!J2TRhdeGK|vtV zx;%m?uy>fZd1uDL-h@*|%*?5Y(mv`68C8V}s;)@`lgQOh_lvtGe3E75;bQI`46U}o z3oD}mOals12?vG*@F_#2({~4|Uuh@MS+5 znaYY{P^t)OG#l+>M)@QQ6le~0tYdn6a@{3)a`9PE5V;I8Nl2pv3vd{K05%q^kV)f> zC6VdPqc3uk4{XcF&BhM#u1uj-FDU< zfS^ITq2OM%+<#7D!<&ipSfqVbAj_2qYf@0Dp=eD4D#0g`4;I)PZvL30&eicv>&G`Yz=U159Hg+(l8v zMo4oQsQh0q=yLPxVRYU6JAS1GHq*N2$|uZK#*FrPk4+Brs6ONS3-WyHWy6;fWZLr| z2c*m(bu*AUi6Vd>^nys>UHK}l!eoR55No0+BN>aBJL9hpaZ1%4D&KBd7jzCFW z;<8Ldh*QULU607p%l7~XCiR|%yxK=dUurc=KSNgItmT4w>AQpQBs0?XE4oM)Mb+3gchgS!< zyVTPSq+%7o1DYqF%nezWS*n_?z>bp={{ZSgmFiitQPg2!Go1AiIWXR|X1q1@-uDg&=2F=%=!(ANtaAg7XT;x8t@-!kNdZ ziLyW{0T*ZT=Kcr1ud$=Xf*8V6W1$3qcw^iauH@IB%Uc(w{RtjU=RPb*BV~o!LzN?< zs8C5AMMV-65Ge3`>u1?NhDRq9Pq$^Pv4ssZSqc@VQdp4@pc!dEB!SJF0ZzKwNaNB) z%OtroXWcioBbw%9#JJ)j#oB-GWjvBr{?(vI9ooBcJ+&RXX>7S!ql`2PEsSaR3l;}G zkL~~j_}56We>R0-EZ2Pp3%CgNAK&&qjGyrC!M$i=?QjuQz-2Ex(Z%!oTY79Y} z6SO#@V2-3Q>QA`>nG~q77}#I{sydU^;+(umCfA@KoMB0$lpX2fB^NhOgt8g1cn7#hE2_o*0lcEku+pWOXu)b$%%Ve9T~{{Y)YZPOn+ZBL@<(=>}T##0?D52!oHpe+KV zk=*boYi<4|Z&+>Vh%)je#VwG*Qd2Q#nL`FAq*!2hRs;$H`~o;$7Ws=l>~g2eixy>q zFs#LuT2wcGZQmN@WMevaugN-Pz06yz~heEvsu$H z+LM)SDAQ-o=S^B>)BIH5@iKP^CXacSAwm%O0}uw4)x|VmlBHAty(I7`i|wvszV6ST zI=ZAlsQ&UrP^~jr0h~|)iqJK|pnH?5oV>S`kn%AWe$aRykkSn)RTr`oo@nF~M#c`vE$O>4n2KjE* zDE|PF7o}4sWIaDsnt|>|H(YW!?V`b#Az~WYfHVLdK%Xbxxc#-p%G)oE4`Zn7Q`86? zg{vfatN#E!J&i0-Z{r&X} zX)|KTQXXryLK=#TAf68cz4r6@>z$G=OOn+pFR;Y9JDd`2+1NPpwZ{;aDfW5d8!M!_E4)RQ^?KJE8W&VjfT;xZ1mRhgY*!=}1RCVh?)&^%LQ%SI zDKf-?Sx-n<{@@f7SHV5OAQR6zK4-1HM=VJkoBK+@C=K)ww;+n@3ueVwx+bp3y>c~r zY?-MhtMA|mq|V*x-O~$k&!5v3lij%?2fwR6&gdadk5ki8{drScBHgN&C1blgYRI4f{4Iv$Hq(U$28h&P^)~Gu`I@OI`n-X@sCmI*9p|q_vNp@ zV5$WxhFCnp@naof`u8_o}0y>?n^^#Z+ zZ>EJ3IU9~I@Y8bi{_h**NtKh0I1KxOnBF&4K-8s)>J-dafOuY!L=&#=kMW*dTE7!i z(}cYes{8gbW$9R+J+SU=n_s5!vbOfh!V%>KXqo553}xzeU_n4WzzWfdYB3F=o%)@mg4ZjFFJ!qM9X0Ac5eTv(4WFNF@8W;$vU! zOw4%|ghm^E~%`UFUfmk;TZdSF*qMSIQDQL`}`W4-yi^ zdYhaH^S0>uA*@ml#h%y5pI|ID+-pae)zv8bU?}es-ChD;7{)VTMmhOZ}veeBGR_DIC z!>-@%?Bt;1F6rFHXn{S9t#}6tg^EB{AVdws1cUc&`S{o?k{v0nPgV^|7D|Yc!%|Ex zr;J8{3XeKa=W=j5=W4O7!ZZ;pz2&24WQ zasRmlO%+Jbb4Kv*%bmtj`P+wcp{4Xn>9e7)sN9O`z?{ruO~9p^`}KGC4%T0kzmn++ z?b6ntNNTGypbV6(1SUdiX#fHR-_xEwciHK1lrei9oDgjW1Jn>j!7!w0>Wu-0JrRexYr3_!W_T`2-&4S3E@~Poja6yxcX&W?^bs0uSmVtC<`2QdGS*2h4kz_}kF zBb}0sotO=%(nx~gQJ2}}^V1(oix2N=F_MoX)~yyW^c@RXzLgJlYD_`cI_FW=aBCk0 zaG`HK=KJRfIyPrK3NxDs(?=g33V&GM{r&Oz!RvdUd`8AxZY*o}2&Q6tOY!b&=J27P zrDb#5g&Icl-|ntiVUH|v?Kf|iq)rQpghp~>z0nkRu=>QYw5MRv17JiywXaKGvsS8i zQT}?oxjTuR2c#z7a2c<#Q@>@vJ3zwm3%I@??2ejWZGITJ`oIOB9C&_ zgu3J>(Z9|vK2hhq!q4hT8&pg&=t}{|5@OiLARBMj$yfmM%bc$_|3+A^6bD4xC4gPX zh%7`?>0}wu^iGU6y#Q)=^hAr}P6R)J{~-YzvaL)$5U1319}R?Hc4D+Sm~`r&$X2Zt z@T*{gdFvGK@y>~u3og7WiaB0@6W7KS9M^}21)Jy<>5BdCxw}m%VmbASh#Q8n-=6MN zjOE;CVH&3-b6-YOEITBbmjKQzqPRj%o~-{0HY|Ga;UoF4sv-s5#o>GstHdc1({bVs zKY&o8P+V-IRoDLeyo~YA=karbK1vXcZ*VaUSRuRt=m~rbDJa*VKTU5fy`Pm;C`KoM zapt!3!B~Tk(91J@4iv3wp?)>e;yCI0$prsUqUuC3uHE6(MW9QQ7UQuKH#`nl~=fm2B4ib+M}S54`|*)qW@VaQSSrYuG9Ym-3>) z3u1tw+KPmEPyL?^Z?;bTMA1ZZpfXR>y)Za&G6UR!Tt;2>@S|I>H5W|I)8OBF`e1dI zlc^)wWThj8f*2_@N-v5UK*nji)}unr;`s~iv+Z*8^cU{(C?FH3F^7d!L$7$Sip`Bo zk@Wfo>n$$+pPZ5-t788(m37?rdg;jZ;+dI~gR>)Fwt+!v6LX$YD%gssGLCVfGLAwZ z`cc>D7@D1bdTMl({>@`;Cf^!Z?S{A@`qmJuSc2$=c(Fe}nPqDFuG!`?I6D{y9gf#v z#?&Y!(YE)x+$IQB$52y8*h~Ohn)inpqNRI80?=9Jl(cie7WXI!h`dFY$R=EP+uGk0 zZ+!SaK(ugW@a84o!PKP7i6ebbeb(xnQC1OE;>56qBw!627K4YkxLL``cG!o#aaCSg zYffFSrv#^R?6l<3BdGd*P&A3)H5r}`aqQbx3}&#hOaD%ZPxrAFb^e@06^G(&d*v=2%@T0E&Nz(b0TO?OSG#d2**rGF@jREz|j~#_kLx)1eQ*qS?RDrbi%W^5{eqc z5r@(-xtNk#J1-t(Xi+B0)9{^;Cr!5(}XKBHe`#9(HCUczbRaQk( zBK0CuDYT>irmti zOqEQ)nRc}=^9dneh@T;g@D=4V!;VX1A+FZ$)wXG|JWV=r+)%8do$ zpl+2^8zLs$9(A>2atb8?Na&}u5Jf3P;=}l6}@}&T} zt-$AglT*6@0(3)*2B!U#Jsj75tE_j>VpDSU#E>Wu!OT^yQl!ozLiFN{`X!@?l-I4h zfiI|;u8Xg@A_@*=nEo1FSH9NXV_Qcm8Sc-TSu z??G5VHX$+xMS=QS*JtV$jkeZ`A~0!)Dx|QcRJGi(&r3_hOCtwhk&4It>~aA_45X)u{o#x-UdJc={nT{z;tTTO z41KBH5qn4MmB#x}*XsKgS=ut*ojo5VMvP_akG~cYeiLlxP3QZg5@D}q!CAY(P>QW( z)w-gAN6mpLVls0TmNy=$4^8TSzfd6Iq4EnCiT+t!wUK-Mly{tbizkE#S8MI0`<7VWN*x^jmTlMdMB&y_zwSY@gda0S4X*)~OajelDGDdeCbCdedp(@I z*m^YA_LrUBC4vq5piLtp8$z_`Olg58NxTbWMUB*C^+y_C{ZI)=X0T!?cK@e|_^=1R zp0U1cQo)6PNrxnTx4lyK%rn!5(T#T+rSM@D+yw$5h?9q6C=z;RrStp$2`n13t(j;clorpyxnVapnc>L+M{;OvnLH`|dbwfA4t-+J z85{e44EJBUOm`}s&`n@}kxq~0J98_-MAh(EceBa_FhC<&I7;|u!&~nwDaWIb0>9mp zkO?LtF;Am<|1qj6$9bLQU;2bUu1g0;A-a#)ktOP? zwDUcddmVebTifcdpv{?+h+o{$L_r8~NIi)J;r-qHE%32H`kH#ew;v(T#pU^@St`n9 zEWRQi9%m^;M&535z*j%V00$I?z2~qZ7Z&r__q%vnHlN}pUF7-PHsWUi3kj14Y`#N_ zUesLb0XT}1j+pS)MQ;UjJm;Lx)2C4%Tm7m?ke19>zs7!!iqfDXfOBPl5AB)5o(l)8 z?2n9$ugbLzt>Z@Kbs4gTbq@?mc^0Rz z7Eib_nZKOm7X3IVM{&jcWS=iuCC1Go+Y_xApm-Bx^tvma> zj$EObJqZT$Vm=nFp#L{~25|0Bw}{2Te-?K2e;`G8VQSPVohRu%c|-xp!($bo+=}i);*O8 z&%@G001ISAIC?5deWxgJVeWD=&)3#ypW3#TE|{p}b;9@LhhF){jkUNj&ew6&RJ~w} zTOi3{EE)xeAn|pHxQMn2M zsZv?zOz**6AeZl!D*;8J(4^8w3mp&5cT(qB{NuZlnP{n+vc*~jYE0YP;1mc}CkA8R z0k8OYDX%+FVsOA7^rO+lo@qnQD0Rt@ANVH zmjuonKW}{^bwF0*vv-ovyZ2Eg`Es&l-ilp}{ADnl7Q2=&MnV?>ST6Il_}!x3C?dp5 zW8qu?b(nk^GsQ_a6*$I~^s7&JsEAhnAtuwgn~R$&T#4cyGMK0MVYSRAO5VzXS#3Kt zdiC^ko%5tC9}|e|7#?LT1N=Rg@o6seQmM!-3tCgYj^3poZT^mS-BHLoz{h3(v z#aOWYwh$JwV2TV9yl=?3IPZwnMevNQe$ z7t(5d{XOZpQO-K&&^D)6GQd?;%t9AH(n6B^BM#TCwnffj&UyDd%_x&@w9OhonhmC` zh;K=L<(jxlw<-x_D6Po`R=Fn`+3{Fv*h1WlSH*q2*8=H>{=%W%nYnis99>v z=h37RyIj1ssXxhFq%GL3e*5?!i=>(pQl#+l%k7Wo(ySC2SHczCZH9k}&RC#H#hEgcR%q@bvlyi2YT)`X=5w+@fH*5Ee#eOZ!}?F>Yn9%A6s${HOEQ z0~aty|IDnTEB|?7%DD2(>D^hkxBTDEKmXl3pExprut}pKISoU~FNV&jFhKLvr2|y(irzp~l zA)a*x`c@JQ4ueB^{+X249enUO3@QBwetgtAyfkMhW6spXGOCwIz8#B} zQ2+#w)TJ3Ddn)`*DCae+-*ff)uW(s%`~#iau-4p}UcOFCQ_GEC*! zW35kFd7Oeh-f%8W#4RHo3MfZXx6M=k zHQdgYi)CzZas(-rAr`WO;KF)KWKqQ=^6ACESwfh*j&6sS3SNgkj@WyJOO9_*@e|T$ z6Pp|)39!X7kpP7C6@`vj!%=NuA=Z*PY~jmosM?bztFUUs3FvH%6b zy4s7fs>)&$uM(eM-~J`f0sHmU{HB}UkU!P)`fK)GTMdRmSHBUH zryy5JQd)Aonpx%_l?n?!*k$Js&c@)Zo8PvH9MS;Gynm+Y5?ONYe|b1pEFLDg@3_-P z>2Pdn2s^~2n_zvApb6kqKENXO?alODUQZ^c?Zc{zm4d?x52hKVib_Wqk0K`GLY*%& zxr7W1(tUUEDedB%TFdO?1%c)JM$JZ=F{|8t=s*6Wg0%hzRg+UGt?6})l`<+9=gorY z$OBcvqO2L54En*hey2A3Op#uj3sxahE0}e3Hc1W!QN+W(T!YL}O5bjW`wq#@nrR>t z(&ep$=w-ZdIjM$@&C9kD5kELI$_@D9aA02f%6OQ4b${oZ*d-3J(DK!6u6y)lLhYIbR!@&r17RqNh+a^0{#<*`+;8{ zT%aZ+n#BRSKfLv5Dv6T3$xDDLsTk)-dXklNkR72@EJbdg6w;kP-c+XE^qUO?2N3n{ zq?^blo22b7oNhKxujR04HLu=Y$*M$tOFPe<%w6eGs*RbZ`kU0iYln%c`^`nj7^1+x zyVG4avBmy-|+2O(CzN9XiFGqDb0bzqQ&vSyt#$RKOpfza(~w z4ojItiAuyp%(x|^-gE9(KmHiB(N);cB57nfd0zZhO2H|;G#L>B>;l3G=Ts2cZQw+@ z&Pd!JY;tnMbo&0$mwOS2bGf`}*4ct0OZxGZGq&UCi25-YbhkI>-w@M!k|A**fI)ka zGS;ttboTeSu zNi**hxo1=YIv^=BXztiHfu%yu97N0`^Y7EDCrAj^!t681qEl{1WKJu)S+rS|%y1%+ zQQtYF&r{|6lYA|X&*j&rm_cc7a3a@2Heqd!w z9HstNhL$U0)zNER`uAk+g$Xoq_tl}g=u;>s#Q*^TzD2az-YBnVCebWU86Q#&olPs( z#Bv);ynmt+<;Kflpr4cE@ajH`qPkJSn-o4vfNY%iRskRe2%sdgrL7Ct(8;Hk?S2^k z`6IOv>~sCRpp+`L^-h{7 za_4_YWR?>!3QU;ph(i7QRMS;FgwVV`58)JLOa#Cw5{M)!67hS!@~iHN`MzPd3wu-l z7+3QMJ!1Rthh#~LD8Sc7ptlaf9YUz)vLFT7J{l%Mi-j%vt|Gp4$MyFPCuu!9g@#%a z%_*hWiSQ+&2E_woM6QMZzeFkgW{u-Tr=O(1-_6HSZhch-%5WW`%GY#oFqU@16V5Tm zce!-TRppRKej^?N3*!mkO>Wa%{<5^b{?3#q2_Bgas+2g5v^ldBmOZ~7733a z_Sw!Sv|gz~F0pQ)fe*`&#TV|?4ijmNGjnZE{;e*=z-0pf-|@s}${sH4#*CfgN&A_L zvaWjnaT>?;vHDEMyFZe}D->793}T%QP3yzpq?Krk7~?;IA5Wg2d{=R>eQls(V3gbM z=p;px4J}I;ze`##s%^E#t^d0T=H8*>3h~Dz$fB}-FnK1Mj2_$Nb4BF1A4a0|+a#o= z)RXEir`3sV)J-vopyez$ET0mND$g-1KU__z^(pY!nTn|NJu9in=UM3p*G+Rhba6)m z+Q`I!kj*sp=H4Bv0yXG8l}H_uB1>+v?5F}eSkKNBh| zZ%99lSH_(-T>l9^V6Xh=a-Ngbwf){VE{$v(_|mVaxY{iVim!gjuvZUaEjr=Jz+(hH ztcSZH51AZR#XDYfKC*`V_0x?77i)DxTwMXu-F3|10x$?(27pk`&D!rzbRD;6UZveZECq-i0nsN0uhAq$-PHD z!>>d1J4VNng%`7=Zyrif@2i&kdwyu;5vjYQVqZJ9;Ul=@nP0s(x521sqn+LCk!Z5&Pwz2S^tllrzzRyjPO$TX|LUkR+P zHl3KAOCck-Tg8>xpFEh(=^UQjHGn4nAoQD6W|eZs@mvoa=8CF_;bkT9pc}-_VOWgm zui-zpfAZ~xax#}x@Bg4)3a_ILni{KSh3@D_Q*6&|cZ4Nnq(d2JCB+x5+3#vqSEMzP4&#GC8`9@aaTe$P zc0Q(2Z!ADbwJ@y@6i^T~=a-!;cibRh8o^lO(YPN~4HF)7SKHthQ%JM45HH zb;GuS0^v&aAVaV+MOh2M#~^Y{H2T?C7^`M)J>!JxLq4tpeoY|CRyukbX22qw%=GW;zq1c+ z6X_P>8-jfVzCc1m)8wYSWaoQBzI8js9VdJ7-U%hTDoYtnVkZwOMA@P`TuDuh=Bjf- z;^~;QI(7=Ow_4D8ZvHSTtK8xM|r&;#Gj}^K1^+!}* z6B3>&_xkvsTN+66jg2`UrWU?tyflgSrUo(e!f4)}2YYP_2>7n289mkK!l1{v=43_$ zxC^c8x`Yy7N+IBkKA`r`mC)SI|6a5C?Kyj|uxl7}e%EN06G+RQMpa2vMB6=JiSnb# zKL zd9onGrdhqDU>*UvB^HHXQkOCruG;=LY5h$6aSm@J z5F*AWKL*a<;vp+9eir{iME>4%=-U2IULzPR$ew@(7L0jdkr1U0&1oI&QCj}}Awyc8 zSI&S+1tNviRJphC0O+GHB|=OFh=YNOs%oM1>RAUE$M{gmYfqbgEi6widkP*cuO63w zLWqrTk2a7-?`J$-)q0fRu-%Zs_S}-k`^Z4C z>xB-pavd3o@qh1)>r=ZwAL0Ptwv57B4~K?=WINL1yD`$w_Gba;!7^)=9~7Z zc(OBp$^EHx(Qe6ISC=#$9O;6)fDWoE6M!ID9pn0$@r-ky#nS9Qj^JVrSwz`=c9WS} zCQhNaIPm$@zo+;YQ{CWsN^9eEk@iV@}HiVEC2@(apE zn;!?-s?6hKBG~E@Pqg&g2W4 z`R@SvE;6-%CvA^Sl&bqTX}Bo14aPWsOt34g@H4P4RNvDZdWD3fNsKXtF2b-o`U0$G z35G3ks#;%&Vsv?w>S?Fjo9t#(%#3?SC>i)om9)P=Ev|XH=I9ajiRez$R*V~q@HF?3@7UI_ z;i_PygFAG@uSK6%e;f`oPjV(|iTys!eYJhXv9g!pRd|HnA)8ZYu8i5eamEmX;P2$u ziM|(YF{sJBw=>w&Yo;Lg0|MbE$RpKHPn6KR;>^uD)eND$vbO{abeo@P$Aac^Tp4A^ z7Vh*UFbT8S<&fm43h8C34Sb+QcR=8h*W zc0hoQ|N1raX47d6*9tpDj)QpYe-QE5h`@9qmpgq&rk-4C?ilsDttYdNmbuo6*fwDw=8 z+gl}2e6vE8^7FPH(H3i0=k?Oo*;Q&%2#^%Ih6!$3lB~k>#i5HMH=8wN#R7=(*7m7L zE+hLyATmV+nlaUDk~3FeadQp5-dpI0xxY@UM9Wn*d6*pSB%j-oLTMIl@BS`@4hHgV z`HqXf*J9MkoqHpcC_MI-_h;B8hH)3cA4^~On%LCzqzCxxNcrF4yS*YSqI$ZlF^F>7L5IBC)I<(-b_9|w#z zDJOseOykY8Z8fq>Xd+7`LlV$**P^-fw1bcaQxkN9aRgw4Re4^hd{;7oBKS;RCE)b9 z;w+d)ZNE6-BErW$xW0D&A@ejDMun04Q#l$yli9yOr<5S;)oTyWm!Unp$F+Vnm1LXa zia)@t#(+dn7a=Fc1*O#!SxoV;0KDahqlY*rwBT{$05$~lgBor>0b=ME`Kkt@(@Q2v zXTM16M$dfq>{ig2W`@wZTmkpK>I7F63Pojl=?vv0I;(C zBWUUL;J(TBmNzLWpHvQq`GYo`HdjVk8990(sw!p%lunW$qhsUrBK>JQnY!9{%*4px znqaz*!k_c$lrY!cY(YwyQFJH9f@66ji%%Uu=k_x*?AQESmC=DrkL`R`yS6VO?KnO@ zn_Z$b2Jq`8=sy8j;Eaab`LAWY*(#mEo(*#<^|G*%%okOZ5U4IY)ofADV+ZvzItD|J zc^B=TBS%kki(p@n*09K+gl4QEM{BHM)qDQG-v?4beQs|peQ5?cG-Guc@mzm~JobZ(y(enl)9Pf+d%KQRtbTzZ&gQ+5Ew zKmvUot>?vAN#_(x_Ph#o47OgSI!%~5s@{8gL??okG_|lsfqmR!ZsH9$rM)lz`$l5w zpqniv%_~q78er#46Tn5P0Xwiw!W{(0#$U2}R@rx)RAWOX_Zbmx_L{>7FP zvcXr(p7=r|=BQ_FS9GOOV0_@G8+oslt$}RrXf4b;Xzn!WS3%R^Jy<4?iY?ya00PqX zz#adU(xmXp@HTNCp|#X%-iNtp15u*HNP337XbtpRb+Ba5vh-bGn^z~}j`Mz_j#i_7 zq^q(nSn}l$NzfjTN&lP}VObXX(Ysu~$aIbMhL*!<`I(j1*LsD&w?W?y8{Wt`Rzw|l zO;)ZyxbG{qh_7JmZ3H&K{AxP5)>RNqO{+xrpFAR>_&kGWM(TP%>1x%*?I=D17nexu zwhiLle9P7@K=DIUSux&=H3MnDSrw$dKM4`!Y5hor&FdLRPfr)y8&UXy$Zd(X z!$yU-!66N^Cx8ZP`(w$StrllPu9y1(16+Q&`?yCCCSqVJ79a+c?`@GSxw-%4@#npC zo(-DyzbLx`@oo3c5$5ixM;+CpBs8%a0cB zge3p2g}hCuqtR!kPh<)VFFAYGDg23b1nXg?+^%Lc)iaiw#i=*BPL5V^^3JAWM>yJN z#Q?t99G~ND1ga-?mY&Y0Shk(p?9>qc8@zWBA9`olLt%gxmzYGjqk9btte_^*o8@@%&Q^WJ2$zhu?8FGPK$n zbnXm(xsjDFn$Bz*ZAN^Vo4btdy?~+QkkDk+INMx;%>Y1hW0(rpW*U580RS+iAwMF( zoY11xCj=(O?D$PH@+Z%5S>{>8aw^t3Qio$G8cRi&iF-l-^G&5hor+QxU3 zC(yHLceM7!+XTnzq!%%hW^njpzsX}ea!`lnA;C0mt6-DnZINlOm^TZBBaD9>Oz)V9`7 z@TNpZ&^f_>p#tAK^HBv|di(c_v`OVa`Ezp#{l)(Q%8g(xlZ^xk>fyc5!btio-}4)N zb`)sblYWkjaMDwNZagUzc)$Hw-d(MJ%TZobenHSlACk3&C1x}yQwg41#)vtHP0~l^ zYl$!FDR5;30GZT~iyyyAU4#DzSSWo(qc8csM68@nZEt(E7Z4?KhHR3-X4^#mt}E7~ zYTxfh6)kV47ghHRmJVe&sJ~cgc#S6d~?ztVxvE1@~O;u$|^^x48KGvEPjw5TG)RE zb=SFzxO=%EGAzqFQBqWLRiyU2!1HZ!A&HUFIBuu^gF>!}s6!pQHUJM4{HqcNjq$LZ zyaJ^N`3xIaM;-bJ47!Z$B}qfF*8{;is!-qp5EP}9xcPl}`hGgPwar^FAm^YWs&oqs zFcTGrn?QrW(Q;QL^99j~(YV&}9d3++c3#Zzl zgi%+1Qu=Q9L^-8EXtQJcg#6FTP{04$wR~Rz7pa1dS2SwuoqX1V=dhXy%fuZ9eL|+< z#GDZ#?rbKNKikv|G+DqMh(`6&x6cYrdi`~v^oA*&Nu8sIDU*FnqR@EAirF&l!phu1 z&#{dsr(BTTpvaA&-WMpIntq5z5$fS$C~sICs&jv9wt&Y=H@xBBY&aojM`Gq=Phhjg z!R(M;zOX8k#@}u(+J%e}FNv-{D|AkGp;|2+nxp{GKwVMea2N9hN%d%x zj&i_?%Ji4z_WQ7|F%C`TVWH_iiIsyBpI;-!OLjHt_Gm7_`yNwkb1ttK#ihtD8bhNLaIHMCl8|uexzZmi6ca;O*@*N?m3tw-+W$)Le;LV2 z4cdA;JVN(omR^*;#-RncxRYUxSLX`;vt#KTbfEPVlMQ4rPb!2pS}qf}kdgdYZq|vG zt$0%?AmlEX0YM5pz>(7YTOq7cuFG{ZM#7EB8qI2cpl=E-3@_t)_Ipr7o3@Sg$QLv; zWskFFBja<=>X&gR+^BZ)VQd!gMyvl3#nUk#Qvabpi%zpU8gYdcNiuRHF;i1kfaFhp zFAgyyT(5CyEhImkH0J68e@!!q_cGgg*uKciNT+(cTREb<%90m3FYDm1}6NoL2#rN zOgWAV|}5B%p{O!kZ9z%w5NM@p4Ox1Ut9XpBe~jv zQ9E*8+>&EHVn|n7L^WDY{A)VzJo?jahjL!z^?n+C)I|20!;7!}iev{W3&|TiD z?^+!NXI=)5_*(_qbS`S{Dihsp0g@mT!oLX?ipHp;B}`J2(9zfI@W=eyv{56*yyl8o z;`;InKJ>a|CHW>>l)KlbyFWzkpgdUW>z@As?*IK9yX4*J?cI0xKY*cKk;Kq46Zui( zJ^zcRmAEcsjxI+!*?lV$!K3`&EsCc#TIaCnLd|zo}%B5= zQjt4BsfFmvSgj~^{?6TN`QXnbxh=AEjUrDd41L3UOCyENCzKk$nYiQK4bm4r8(ynM z34e$P>(}{g$oGyFz6nlhR6Kn&X~Ku&5)T(_>;Mpq!N=$4Z%RV!UyeS~m=q0rlmNw? z_Y(cCBRGqHHhbEK_i4TQaoL*fv5O}+${1xmz6d;mKQcAIRX_Z8*g8!#GLx zBjtjvC(Yk?)b-bCw~Xm08=1#r+R2GdAb5|Wf5l-7`!|z&6R?r$Cn_B1}otns=CILb5QL~#qv74gVbAi%{!o!jxX`JT?b?mM3gC!nMpH29`Lrd2>>cB&N=?|~fehJp(sP}zds~BH&eh}RAg(}CSaRstcIR2!Hx5c zrO;S-k((9i=5V&8lV|r@g(4*#3j5ORvKLAegqg~?W`LKQlXCbw=J64#-8h$=GE`r` zKyAefJaa08$c$R(?pgT3kW;q7YYaan6}LVN7ej{vm^86v^fl5x3s;u$Akl|veSV~t zd#p|YEQ3FV{94p4a*GZd$@cKqPLgN(oSyM1ESN`875UCtg|eINi=rRSpt*b0>7Xr8 zE{tBC`l+J)=+eH!~mpCl45lHMqZwrb#0%)$A=0*7&??JW^ESG6zag=*Hc95O@WxYim%fD0B)KvCqXLeraPeL_i+-3Nn`3U{Upz*;hi1etIT|O`@QKf_JD){#j zS3&&jq1ITU^H{uViXvL_V_6mh+X5X-6sQegiUA%peqCWNdSl#g-067aqucN3H3}DF z%1+!npuA$E+knU$Be|A8@Gd<5e?JGZ<0jwznkvwOP0=svEIZ5`TJ2LGMF}Y7zv;U* zIwlFEN|n9-B|et+g=(ju&RFGGPGZ}iQisLWVSKJ>r@Cf;Dp{xxQXnUzTIrN7>i8l^ z6-FsA?0$4c%c|Q8$QTi@;%uC~JKbz?^1@FUk|R^Fqh!KIROI%{%MQc^M5z*gR@fNp zPVP}r4Vl-qAS`#KjAey=4k~X=dUuVxEA~6{38h zUf|=Ttr*3ni$DLpEA}2;YYFGUeG|IJZ!n{s%;Y>~<17mFiIcu~L`x zd1cE!x!quu#78fyU`n zPZa23_EU0jdWV~`LIJW*;WJeQb3Dl_4mm!n&{)^X_#OG6#~kZ@n~jXx#p{Nv%E1D=tN?c?3LfkpD6s1gq(XEj|3#Ki>`)<;oF z4yE+VnOln=%fjV!Za@3AuQxj;rRCd?Ry7e%SUCt&=Zp9W&E`+5xif5cxoJ_9Z1sC| ze+cGxthb!NBCat_IUj|q(SGcpm#qT;Elx|lS=WjD7W_@1YT+|;(25nm8=CF|w_OJU zR+?@CwE{$I3aN@ufA`-5&bA>B8p>XbI;GEZE`+ow7+^|pQg(S5%L-L{DmzlszSkhb z+16_Pe-B5-qow!an&mt_{Ve@w6NMb3!X8E0VWNoPDA45!Y|z6v{De#OKQj^`tdyKZug7S%fx`LhH|K~FT2(z8OR33*K0Dy9 z|D#pN)%q_rDW_@h^Gu_CmGuXGZ(xAH;)+ZMPtd{!9Q*BUouzFpfu6XJ_3C+6D`?!` z+e~FW%9n!OE1JZ0nL0|04~=61LO&lh8dnh%bYHbhy?5@jHQcc(h-S9d(eOaHbPh>b z*uI3FHdYm&%kcT1Vy_r{TLZ5oH1~JfH>EWh*~r!=yGo|g#TW#l@aWuLVvP-ex@8&J zQgg?@{h{Rh6i5d*$12Nl%2|$=@Z`mRL&fz?We7WB%9%-pbju3t^ z-vX9EOBrwyp05tVKpnjQs%XGMa(}GDYrJPz=4q^$+ys&$(2RtM-mnhva+6AIbl0ut zw4zvml~vwtd}LkjIx}->h}+O|W@%hx0tLy@?=Q6jf8MB3#6QY>^7bxQa9(oC zIz)-KN}Enj@d*~>f>E{<)h*sXLO_@9LSy|e*17vx3wT(6poRN| z_%Ty8lzK2T6qrHrgrr}&6AMn z6(&0;M`s6tmhnGb4DV9_k2K83 zz5YJ{?LZR0oKPP_!^ zA|iSIWgW;Sx@dMF`)ko*jAoRvG|`def^IYJTy0yK$-;Hq+YDhp4Uid0>KuZxpXXo= z9*`_>eZlgvFqiwxEIe?5c+G@@!oeYgX3;y7R1N3(1@kXG>CO=Q@ayD6p#(v>4ys^3D6hvR97mzq1h$Mr@I?jKsy+NMx z9IfXrM6=MLfK>#6*a2L3Bb(PVCaVr#%@o(g8s48!{{So6ShuGAKZ87hvLitdW@)FH zXC#Xwq9jti&mCom=77?9@ogwdoz`55q+)JZS$VQ~BdGrL29m_}7HmxTdGZXbc@Ij+ z$~uJ~@e2EgZs3psAowKQw&2nc#0)_ot+Z`^2a(wFEOIy+-KB;H7vRU{gshm~_hjtW zMij_ddgz-B2|SL(at^j%N#sqkoP7Lc0!T6>kvjQX2%y~&$8lCPyhUdpN<|l4D)u^* z{PXt@&WP}QX~~gc!2bZ#WJQvZM*U9-C2ZLwf&mw=Oyb-#EI?|pjk$>~wTSDy^vXYX2c58-+073qM{<>E;VUrdyF_EQ#jR}=) zZ`p|DPr>~xbFVp@pz0#`xY{?zTaC3FqM@N@C8HL??3Pdnz6s}oeTJ{L?T<4ac_YtA zv8N=)W1Z=hud!ZD*c=gjYUk2hcHY^zIhe|S5}<+gm#GsV02W06eaa2F2eANh0KJ#f zn=bkNs2|fg81wF5RKg}1AQzHLwMJoXSRP7U1_t@(R)?l6DdozkdRr^asogb>Jimdu z>|T+>^u8uOR_5DwdqV^>%Zg@3Ne9&c#!6cj1lt9m0aYNA)VTFlM$s&L0O3~T50 z7RK7tv}pPGQHEwlxeKTu)smot!6Xn!p?clFhxk69iDk>l$X(5_qx?=zKjEYZ>IEXJ zsReAXB(N4xs0R4vI5J9Q3lNj3Z;;hod-v_5Md}3l>xqwthF=tYXPOsow+IR73`t)k zk^tps9|uQL&Eep8Iu4T@XOf&wp}A)IZ-2pjX)~dTzZRI-bFLc1m~ydhl`^UUByJS5 z0ztK64c}Kb&)V}w(uHF=Ta2#{(ZzvSJecxE@&_QTk@lz*O;dGI8l!{M+lDu(=G=d@ zqsf*S%6&+kfqGIZg|HL}6l$+te6-EmG50L2_dqgU1$bGE_@F{cFi=1!SO8l3 zfCu&QGwQmG5_=`(_B&tF;h!!%mkY8!-;f8WcKz267=p28400n56RV|z54lfr$z%aw z5vpHMh6&Rl#8VWh(zVv3E@cxEv+-4u|cW1`I;S#V@k0oW2rreIhO;5Bv{s(E^t7B$5m zf;iK;xft`q7>^ZUm08TvBa*FT6{S2V0>uJBuz0N#Bl{Ljqv^$sn-=DwNtv=$qL6^y zKp;?8o|+_+K-uJ1I$Eb(mn?T>Td}eC0xN(G_wse-V!&}kdz-&*bQdK}5Po^q3)mxr zf9I;+X2_8~x+IzhinF2?X8Vfx?{qW{qh^H?Ir2}=yjzp^8XRzZetJicDFz3u(6Tw= zxC7r=3ZQpTNZ=1YzJz1~Aiv5BatCwmXIUgN-+DX_-Twf~RlI>no2ctO>%cwDd}<2R zdxOo;AM5k1hGuS*F>BZ~9$rL3z3BAKTZ#Rbli?z95iI8`;?laL<;={ zp8o*ps%J5xhMH-}jHKNv&C&q^h4V+fpPs~5v8g1o1qBEVT!b`8_XB}rpPSODBJ^-0 zD#NA4a8!^1uW&&57siV#H&@nR#Yfs%Pg1gi2o`$~N4I@toQqQ(5;gP}l5^C15C{}I z5y7)#vCuN%c4*cvl1;M?#4sLf$8lg)o_m9!nM+P3gde7Dx&@G@iyzj9<~@#va@6Fj zEJ27rXj4QVZ~(ji0AZ?@>$DpphbJVGpoMi+vM+#cfc-yx7D(nYv?bJip^wyJ0t46) zea~<^+3li1p2!OTQim1=1ALG3v+eJC21KyCnIEW?ey9Hcj%RYGJX$>j9a5D505FR>(_8kXF5Ci;rF z@(5lwMrKpe1zm!B@}T(b`)B_EW(SWNNP#r+lD#B?Xf1dq&Cx&Us;`=CCIPsFk;N;Z zT4s%HNHz`Kg(M$0Tu>Sy#S=pVnAQZ9*+G_TJaE=~o-43s*t$(YQF5h7KP z5!7qF@H#=OqCq|nV8ZABdS0f8y)8B>SZAdilRp(kPU_H+vMtanAxe7_~|5?S6g80y+AQ0hzEi}1b|Hw zUIEo|#Th$eMs&C><=r=Yu&!E3Qo0#{0f`IuD-uCq7r!7^1o+ifCxs_YE`>_I0*X|cvWM2;FMT~;+v#1an-y}JMhZb>HZogA(j&?lT-$ox^MYAp6Mi+=0%%w z6SUbb3;~O|Az73X)ER+r4-7%RZ&=4EILOAAD8(uR)BpjeTH~OBK(7R;7QmXiqCJTx z&&_OM{p3-=eyox*l97YSLP+W)kSTehC>~Cq9*P*F!YiI$O{;g`A%aOZM9JCW#+U4W z#X}=R57QMg$e@rFhuXnIab1lKXLQ?ANMoBCT%7!tc0%1ENW!QANH$nl=kB6KQ0I#u zN@4F_rO3nEv7q{yD0<`E31*%Mm4Y)jNF>GxAS)?0DM-3I$E>kEKeOh+9?JO zn3!w$c94J`IbbVsAGuf+0DaX!hGlOOI2y+uSzCL%8fT#PZO3++Y`o^n!P)ltRkIfq z{TW@26AA)ARx4+z$W>6xO$~1wPV4A_0?oO~!yqeu69!mvG6`pL(GaD+jFDQOx`^h; zx(As0k+I@~rx!j)N0Y1RGPG&YLX;q81P~U!>L3mc4JEd~GvtU2<->{t)Qvkk!w?6k z4y6T^NwIW5Ce0E~uAT*%Zf=VAGk5h);QpZ8N>Njl6)XPP=QmiP8vH{;B+xE@V25Gj9!Z?!|(I%0xB7tHI8M?yt{{VFf zBq0c}!LUGxII^Op;3 z+$O||Txq4nM{=Nav%4bM1pT4FDnMh!0Bf+0<%2Wl?HgtW7Ba>lhJ0+fB*uy~Ml5F$ zhaE(cNNOe6adlS4JC*L|;!WI?-lg>C;CBPLMg60Qb8^gBxl-kHMKNn3Oo3FXDpZ>_ z_Z~n7l+X1>;@A=Gx%oLWM9CrucNv=?!yuwr1c3B0p~z$4dmV0g&$8qCPk4tGDfbL~ zcs{0B$#M8>hhnZIh62q+5=36E7zqdf0Bb_aM&7fa%G_3D!;xcy8gX4ELa#~?3iOY; zNg}zRF2L68GT+4g0c<`7<2=&?jIa&DLlVOe(MjXW@6sMQRl<-}g@Mv+SOc9`OTX@8 zDrT9Yf)7VardY&c=pG{9PpMb# zK#dnl@;a76C@TR=kF(61R#)N{Nd$5T0vvdkCOHL#G=z04fO8!PEVbk`A zNhF)>K_QRqG%dd~Xw8HK-IE6(0n(WYLbnF~<*+J%zcvjHX`GRth~_MsVgj-_n3Yg( zq}q{IL85)V_2@9=#Vl#T?vKOyDBUg3(fmc_O~@csLm4K;B@%uGAD`Un>uucg#vE~E z;lr66UurzEI&`hqO{oCYfCqmZjV&(d(Bb09^0q|NhK^WV)RDM61z};7gJ6;k^#eo# zZuSk^8*9&t`zkp%edUEVOGI8AG-dmiA`dcvNHUND@(>gE>sCEZEN=11?)H2YWrVUX zI^aVojKs_V3IO`501pWxxUtHg1n@f=;OeJvUD7DtY$>FaaEmf3f-H_7kF@vT@JDOb z!L>@WPa3o;p%nEzWRgKV3Ore`wRCvBJDr`5(fu8w95|Gcf*Bl@oDSouxC~Dv7*$tE zAaUw7Se`}1n)w_^Wq72bqh^&B<)4hgOU9B#VBb(c01Q7W1bDjVTPx+hSEs)i@I>*6 zOsJ;Uq!6nrcOX+0Kb0RkR$Ytn%u2^5)gV1B6z@?J=b}#^{;kikI4c6uh${ zByurZb&WtQKsEs_WT+$pXeS)7#_(lm?1Iv6y3IauhPqTO<%gt%2V8uVJ059~pAs+TRrv z6nx0sPWyi-91CCvU@CyVa6FjvHz_CO&_Ckmwy)J?#T_>IuGao$J+qd0r{DMz-10uI@c+2VoLt~VLbkWwXON9rF;0>;50k=z5@w*tFq33GDJFvJr$$5}q8jJ2q8 zI(mRTi5wc^f$^YAKU9U+g2Sb&k;tNX_wV`Z=USetn>?G7;PklgLKRDqgFBL-HFvt~ zK5Ta5#+#B%C)uB+m}Lp$P^4I7D&>eiD2T-y?t50L!`Q1Jk?&WgqmEfIq$v|KhX#Np zkK4ro-?1e8Ynz){)$59(Fh5AH` zd^u2Pk=T$q9@c&J?U`{hw|p#p(n(hkxHA~dH$WE3whb`?fvyP#jaHX3Lo6Vt_hQLZ zB(Xw3;2$D@6nQ=Qt#jp)d7Ua5)w%pM%%~rE+1U$hw9kn=M5BzBun*biFd&liX1qj+jSUKWkTd zRtBrRU;FA*vZy~)f=~FCg`Nqqeg=n$M5_}dfk%rxpL)>;g#dweO?DpIEQ<=KL{}`f zOA$ha_6ywm+5Lu=c4i{UAa)0UK7Tz=62Vj&Dj+DL-9ychSN{NgVHjOqkZ5#^{=VA4 zVi2M!HYtzA`}=$Q>&wy@IiM_Efpj>aPZy+eAV*%B3o4Z&!BfZ{$K>k3G+k+xO96jDl8E^v7~YAosopo9r%!I!7UrBukh@grF#v z01{8JtKDN62%ml^U&y9 zQb!`dHDiku2lUXfUBusK{^2UfN#g5+L&!aczJ)Q3o<)#zM3X=kp}?W!k>}?~{M<3G zjtgn>pq%2sdROX&>U9M`U_cl7fO#JGs7V?@lN)s+8xC!1ldx0fg?RS9`mT;yA0R0} z7`l)GniWU4#eYppGFcjCn;}nC^)=Dt5)bG|Ih8UJml1)n~umK@~ zAW;7R;#7g}`RQpJ8Cj?3P{**VLQf{ZQ<&~MoB$HtBIOCtl4SB?XhNDkL zfUs-d#+oqqV((tXtogApQpyBfCd!I#!hs%nun*6$8eU0dF&BxYJxVN>Q&rdjR!16C zhasa8Fpx27=>&p1kLkvp!G;*6jCGP&fW#11?&yQy)qC^jQKb|cZH5h)sFKK|t%p;F zU`PY7BKQQG0CVJf>M%tN@T)DxRP_G^eYE1pNkcLQfz$&{XQZ(J z3N||rJPP87wXksBcr%)t>U1e0S^?Xv3JiD$?k2fB5$99f@mv`RoCky|k$okU1|3Gv z29T0D;E#P$)LWzGZLTY(BZunD9hCw1!XdWTR1068Lo2Kd$PPJD1Kc0?$$&ph8vODQBP zDe4Q&0zd$sO#lT0%$=%0ioQY1l`MGSTt^g=L^?nKxv)A|mlilTVA-%cSt?{?Lc-o= zGAnXH;3W$CkNCK^uwSzKX_@vNrn%Y=ahjiwee)e<83KDLfiIfIbf-1K#=7-oql{#Uyedos~!? zQ@{Y4BDzOOBpx_5TCB#xg^*8QMD%mjOc~3Ny*1#A@5PU6qh`+Pn6VczN%V?3zahTn z3Rz7NzykZ-5n_(3$hWPiXxinLxh~6u?#5|l$a5r_0eYN}K%#7bEVUC>c@;xd?KDwF zdSL64ISQ8`(X@o~Sk2hE{2o)IDoKjrZHSaIqXJ5>>I0+;c2Fb-sY(zS_ONuU5AEgRIaG1ogV zY+0MuhrpVwjl~p7I!M?)9-n$tSs!YjTvcWTdvNu!_ZkYS7-a&?C z7{)c|Za$o_xCIyx8o?lu!xO9TNS(WHidnGtkaJdFq^Y;h_vHx~f{z@jVMtXhRf-Tu zVRkjFZPUdD<326}K3e9axThK8Ayr?H1AW#*1t5_?s3e*PR@+{0ttZ-BX4^3yEJcO> zt3inzN>zAfo@P}lfRYJ!3&|fE%bFYGwSTYRi8jmK@MB@5IavE-n{-)Aa^XPmyc0$A z!?Q^eq6bnKbrfOHKm>xSM!me}OwThubeUMQ10*Yu-E5$M%Hi#)mC+T5WAzj%5?YlDWFNYL1ah}}uTOin&2lqTY#+mqQee%69>=`CD94G6__HZLh{uzv%EiUSd;U%@<*bb#W~sbpkf9GyTC z#4$V&JA+=gOyc)PvjkbVZdmyqquX~lcN~QovSGuGhZBe+c)p{F3Kv%BGqS4^#)AeR z1^YomYTGdJvW|Sw`df36R6>(Ukl?{5QmU#fYt%^SCAx=6EW*hIgW;z6x67TiZFsx3 z=T7oNwqoF9WT|pcs~7u$W>7?hhf<3G3oD}TKCa$!H;jCkJsp7--mnSG-`P0w0_vrT z67UHYN+b?L8Wgo>T$rq}w7Y!hZtNEGx+#ua#LLcH1Ccakroj!2@T`o>8BC@zn7}r@ zGyo(5EP+e7$>~o}VnC7Z_**7SLD91eusTjvdb-SUxiL4|s+7GX)vzQHvt?o8Y#14H z?ijlkd6`w9%l^a1Sh~n>uq?=`03chRw(5bh4M(N@Rf`*8KdEMiD;Mc?Lj*;3>=)^v z7&^pSRsfPhMpPCD?ci$sSrntc8nDy#HEq{#nC0#J)Hx3h9^#5+OiV}Vd0oP^i5rC| z99g9XoUl?iMBGp&jwsLc=-PSQCp?PJVU8V0PFnr z0`hqT>$`6CHrbA;yKESz6CoX)GFBPnlrS_=%w|}c&ny^GqC*P?$ZdmhknY%X%P^NG z6=K`w!d!U+g^{`?hBZjsfPe;2LkBECAdPKWe0Za7{{Ub0{=`!F7O;AgY}%juHFlgm zu6)?zO~VuLABlMcps8QIi+xhAg}@~Jz)_~EY*{DD!IRUQIK`hQ4rrup$z@kYl~~jY z7_ntk=^=+v>WCXE0Tf#{{FwQ(=YALaOL)&OBu14tjuMr1daf0{{r3b+YW) zKAM;C}1gUv+q09ct%*NQVGc$7`k}0y~ zhcae&a#@LGW(*XnSp-s&0OVQLcCD@8^+aivmloxQm_Lt=ld5EC6&%L1@Hi!CmI}ml zf&n8|drzyzR_l+MkrYyH^E9(B;ksiO@v@$%?2eZp0zhRdI*1)ajZ>czb5cs{kj6|7 z4(sWkRc$fFy5iu;y+-oE6v+XPAeV`n6V(}2VzU5;saUee2_UVVHPd+9w==t9P4x0D zW><|^0Z3n@f(c>}T@Y+|BV9B5OE+QlQ*Jr&O@)gzFk?!u0;WzdG4%a4jGh9${l>vn z3y$pmv;Wm$;D$HPAelS0u_;R5tM>UGCJ2~B!R&I-KWgsI*RiCzVERc zO&YG^NTtbCIrmC1^3h>^N_gk~~_gH1-qvEUP;Y@&Br;=tT--cSlA9%?#D z$d+g@v{T#w%mE~TF04C*n`$#;$Cmj?l@CiVPc0zn>Q`&E` zgJARWPMgK`fPhA?hS>`WfCRDzRVMffz|kG75J2L^Yf+7eaME8$;L$waHGY3B87GVC zWA(rYSpzYl_W(cuf!_HB{lV4=^{qnf*wqatC;5(^JxPz557WlN#)M_DmT1vjGDs@O z1&Ls65(k6sFI8Tymoqw0=$PZEFzJO%X)=NU1(u05!MX;y0P9FH^qEqLr==wFD3A~A z4>~4B=bZa!SIU`^8IhEiC6o}#Kx4=T#}{3_wZA7)#XT#u?!7;A6m)WiYlGwB8zVm+ zd;q;ldC(FZU=0{{ZR$9z22WIj5JS9RtUe6p?letz;i&6=44WpK+z+&p(C{ zLRnnMuFMS)({)GQ&ELS)8s4z7#kT3wRr6FX4I0P7=a3z0O@eQp+?xG=O$k{`1zx5k z)m7g;fE<&fWPg7d%2Yu_36vTNPxyeo0X_YX9f;JhWOxtOje(u5VhSv+@K{%#XdeFF z`tffwqpYH2;mWd=a=l7AofMMFJJIoD&pdh6m`n|>d2#dCJ13+iE-p$$io^oS#H$vf zNZ<~{=_#Sg#E=nj$g%*-BJ{Eg9FS}g$p@3g-v?9QdVjR?8 zs&Q+uZCR3$}t#&5xXp(?qdM zY=>X{x32v_*iwDR7wz9(%by=AAH$WBIiofVt<+kD3m^l2+ z16N0ad|1{I$RJg%^Ig~6jaZmth%k0p6@|vgNGfPu1IY)m2mbn2Sky5+Y6|x%P5z*d zZAFnXZD@l)pd^H&0@fbrAA&p|&x3vYY6VCwA3+Dm1CdsF9|J^L1U3nC8+Qdk1b8E! z;{O0+U9~9QIs!%|7#@}Y@$u%x_&kpqJDLJWQdK|&acg|)D{MMRp3~2 z`5+NoamXLjSse=<#zM0a0W1j~_1d*Ja7rf=NeK`}?2REEOiAtDsC?HR;9tk8Cl0Z! zq_G^eS*z#21GSQWT?JgLgDY9;=Y!t6-{>?}E0W~O!7T6;BQ!w>-n$3N$#4DuVY2&y8e{-aZla}>AI zpgQ!B2^J5UCz`JR02*z)3Z?Ed3uAwDUM`ZysL*OY+*!Za1826HpXfxy#sftn0s$4{ zliP~+$vQi}Gvo&~R(8RFiy+tT}Q*S#6;}6fqR0iQtk)zZ}>D+eG{_ zoF;aaWtWbi7&k@TRd)mdL=ZcQy4Sv}c~KDRBxF5pY-kfguaE&W00Pgyu(L5_T$WhV zq_`CtvHM9Q?4ki2kVW%VrA_*cN1|3(-bmd;3RWdS1+Kz?1@l~!+PUwh_JWYB%aaRA ztU>5e_c^`?ZUqBp*!+!G%OL_bDt@0+RHA~ranwhe;0yNr^%Czfl1UjtsG-t$QP=@M ziuU=@lpK&0l4HM(V*r|E6hVwp`-Kq1i?L>a{{T(~riqoAkS1`yPDdnw31SUh06Wni z6@D*S+n^tSo=k`pqYAXl0`wL&eDDbhdFH#=f^yfNKnpe zsw_lcs!8MOO59jl2c&RMdQd^9`;X)mw#xXjP(bh2hU z6k{k*jnot=HAEigumk`F&;#V$vSVS7D`T@siyH)aK(3}YU0!IFBv|IJgT}M8ZKojq zB6;J61YV-VbrM10LXJt|!2QS;Mz1PXR@-eBSWDLk5vlqBG=UVAXCNACsuV0;U2r+Q z8aVMMjixeWM&OYiG>}q@H-AtON6#SsV^Z8E87|o|IZRn4`xIDf76Jf1(g-Bb9ABO_ zC&`L5$okVt&VWQQ+5jkm0471okU$mzBmxh8WOn&Qs=Z3YbxGrmRsaQ-Vyei*4+P%? zfC#$2blx`TawdWqrjO|>C?TyG$^K?60Ss7@NInPvioFGLN8uTWn&e`SIz~R3zEuU# z1dvNH=70bI2{Flsap)5ne!47T#4pr%VtD{|2Du;${dH?e{$ix)d1aRrM!0#9yCk1Z zXMvcph?-K=0P3smZmQ20r7<2HShDj2$e9s_j~!Whn7e|7&35ThPjmMWd>to>k2Gaf zALyU)^pZtztZTB_=C}l&Me7;8MUhyLYX0g3006RkUl&7;bW{>_7binePY9gnPfH>y z73So3Q~>4U77a{&u*FWa`y~)qhuwc4I|ATP*N?304;(EV570VD!*sM ze5}!o_-w$HR*@xC2m#=pz6j>%(LI6I$+xuLmE1nQ;}_G)$cyR26j@Bu#;rr70HAcR zs#YagPinnamUU`9#HZZMIM}$VxER^_IQg#&C~0>jDI%qjVAd7XiM@@ zqe$24C;^L$S_Iv70eY+cCbyxsZMrS055w*&_DS_IIu|BD-9cnBwla$QO`u>wJlX25 zejP+-lD4}Gy0mkB(`wmqBab6!-?8@q_62D^d}JPQ<1!rylc8RQs$ z+{Y|N31aCD)fr;l3=brB7v6xQV)b{j9iALL!bLgBBgOv!qx??Yk34c9YLMHbeZbHa z)5)%&csl;!G<$|g&3B3k7^<=^I7CWN00BrAXz&0W5-RImXr(KRm6cbi8FJ;Cx?zq4 z4$MeUD#75A2T%l%0kS-5$862qdXj8&Dk7U=2>|dcg2W&k0YZos$kjR&RFkA0sN_}* zPf%65AOd^ca(^vGX{O0NWX&l{=`O^o4oM(#0Q1J3!8Jj%d&Bin#=_6VI8B+IltaSJ znevZZ(oulq-o3NoE%PLcm^-I(4iS^!_H^_|k4?A_SC67|+I%2&XEF6cHIN%s@a* zh5HncPdY~*d!0@$R@*x5>|-qn0w}=@#=2PxwFR~5b3lM;NabzkGil6<7_w%U3v(*6 zCQORNE|WV!m0 zDuS$}MylZu6)Z0K{%&#`R*HGR3)e3NClu!w&~P2uYb13gtw(K|MQ-^*KWi4dgkQfk6hTDy^rp35RkG9G-nepCqi*cSgGSQWo$s#qOLKLc(323EHZpT?8#+Guekn+gG>qwx0k#!D*2&0APg3NWNZ~m9u_J?S7>1?zz>`!wIEQ`}z#zmk7M|CgNKHJ)w5i0qP&v|`mGtD>#^{pcHt7ylFcM_GDlDxE)dGlu)b<0YspMBZtFm`< z7H&-Va55yJqJmQFz#(GbfI51JQb#rk28Xq7>$q-vzFb(_hVB+6aDgQL?j&X+$cYw^ z4haE#c|2=Oam}htBEIJ3o3cJO_nG*t>9KKe?k|B6vV9VA*zfmOdSEY6@MEa{}VYg&@Zaj=! zmPqqt87ff3Nn~Xz{Vb=es1l@roKXi@&4KZ)3i-Lp6ChkL=z^;QAS!JSJ&7bm4018q+oA(2S{+M1whh&tK6 zbFH=e-TuQTw#`H6NFAdy+=>{Kjmw3qut4ql6I!y_BE^p)IkNE~+#}?DIr4steD*dN zGXcrz6is*Wt&&}-Hw2S>^n|#X$`Hwyw$2LX;?cGgSea3Q=0rS#Y$>f3{cW-C&`E{5 z`b%X=O0%YT$(I@8usABVBmjX*RFVx7!6BuVZnnn#{m@iXUCkzK#9J9~pbgY)t1u*< z_DMgUvxB*qWokjt%hFYx^qS;fADA9R@u*~-zFA01OTL#KT_VR~407? zpoIjoFf4&UH(Z~~i$A8lGv^!<#}!L!qWgw9*%7BEP%OEKs4BS(C~yL`;)7*gt{kQ2!!!6%BV(&rJB z2_%{b)c*j8%C-FuKenTrAL4P*F=dFw8SYwyta#&|2pj-tkz{$N)oW*i1h-1Bh3VW# zV^W%;rdjd`JyJUh=8X^7ai}Yn1cC{^P3tScWh+EogJP)B^RG8S2dW|%c~%5|ppM^` zyqvPiPnL8NOR;gW?z=2l&xO0}qa|c(IdDwLkbw9Al8gtj0Q(WD{nHuX^ zk)!B!zRK(1{DML7b&PCJs07IwmKfQ7sZee(SPLWD$3A@Oa7FaqMoAZ`2}5J5$0D73 z*A>P1_SFs4uE)C*#+C7>Nmjj$t*ZmU1bGB-Mvak<%Eu!b(id(3VoDmml6&wu2gv8a zqfLlnxgwz%TV(1E6dxdq47caF>}!I3kC3prEg5*E`(;&Xs<6Qc2uNGCB=P~^ zd;?wUM|ypU^CCk=A{{TPw(Z0O$^+eecn6AiD0czuu=k>h? zK%Y#6yA5Q$3KiRebWpF{fcx9HvV5BV06k7jb~xrjNM#>tfn@W^BfuW|8g!Pjzf;+6 zf%f?$^3>Ux<`YoK>q*}5ZB2kiuoFI3`LJAmF0Gk)P)EI3lvXLGz}BT2CqTNkjWnY@1d1h04J?L z2KWRLE47a2-%?CD@-fy(&?tI0oS2BwETUF$ zSg0fsd;%!`VJl~tBrq=}TUAc7AhRUZ6<`g5$La~y!O#PRi>Nm49To_{WQ@2ePL!r7JpE5*YZ!=f7&M+I6wo(PH|gf^{)pyXl}%K_`L@ z8z7Je7i89ht=pHRpoYTFwYNhC<=CT1Ku7%IjgCi2}*u z$O;MV=7ysz5x>+_$YUo^3I`oT_XOWz?rN-i=u${vf1!|zV1ijiFd%jy)zy%Dd849| zY0)p0Wwr*#m6H_t5yp!IU)-sY!nm1%q#>$^reoTIljH&{JV2Rh{{Uo#i}aFhZ2=^a zS5yJAKqH+szixSRrWPhfP@W?Yo2_XA$s#2aV#x{>Y@Y{^4x8JIJ8l&4Nhp<_4_q$g z3%&HRlVXKf>IbnkWOJTUl8-*4sKv6nJW(^_$(CMhtl?^fNid@m(&Q3)ow+Irpec_8 zRB~4n=*b2-Vv6c|Vr%L(MVXtquqc2fSk1d(8o#qs(LJYN3*Uci?Hvz&ttJ~00NH*!oX z_q>d~A*>DnHUK8b0N4bZVq7MQ846F2g%(qXIP*#!6@sPzds!FV`#F+@-+Sv*X8ww3`K}a3qk~wjll{N_^t&%we`&CzKy-kgwTS=E} zA&m?;`SHO&4pvu@K_CisC3<>^-~vY$JDnkugPnzekCM3ZnDT9v*Y8$U0P;ns0NJC> z@@j^VX{2mlq``v3woUS-o4>`~P|^16nPbP1G1_R+-4c9+G|ObrEIR@&z&z0J;KmLr z$+m-JQ0U#v{e<%Qw zIg{1-o7+mh`x2W}FS_QRNkf%^jl5v(IWa2!BOee*KD4G@ujZ5qCnKZ+NeTm41Rivs zQu>c4HcXklPm3;mrJ4kcOmWp*GdM0Ivf)dy9jmB|yVm!$`gV7WZd*KFq>u2}ajdye z=EPt}A&XRsT1M$$#?X~L01^XO(msm2NxJ2(AcqzQV6wm@IZmVl)V)BrQF`oITa&$0A-PEHJLla`b2FN17 zx*wl?2`1>t4gKUTc0yPe-+&0A@vAAe!yIapvp^-MM#+bzNWL9iS%C(Kuqf7)eXeP< zWyi&FJn@z?qTQ0Fi5}z4@y9%BHmpAm|P!j9Dxc)e>wU-&1)J*2HTQ0mv3qk8ym1@pbuW(pBz3nddX*Ni)Aw z%*4pyD3&J4pbsSX1J7exDwi1K2-%`62@k@8I1B~wX!rK_)lXRPNj}%-^3;P84RR~n zk^1U5E+_`aw{Ab#QZ`I*VrB{-Zd3~@ErKZ6zImbu2eJ9v{U-Syr;~7paLL=SHrQel zWFb|IxLP4zRZ{AOfB{y^5(10oT+<#=)K5_?K@6j_51ZirU+b&?0809Uc-c2t@;150 zS65Msk{-GHmj3cQQ6wHfur-%H2IAaTA+xmXi|PDdOiQ+mXkf_0nB`(fVQidycL2vI zKo~rZSg~K{U?Eb$S%5VArq`E?yX9s+=<@A*r1BiJ*}k4uMjj%|I(?+KRAeKEBp#b9Wr^w}R;joAaf`KLZ|8Q} zB55X?Y;0+Br2s~<6=nn!SsXEb6^S5`Yz6Cy4-Pch*NfmmIZcn2!HxyZLw_Wa7jNjDtqycF9pnr9^yvGB}p=m{hHv^1oG3GN91n-RkU2d|A~%mlI`=Zx%)Lw9zT)ehr3YB;S2f z`fL9HC1lMe9$xd6wG6~~%ult*?uCHqRVd6DhbD9B5N7&~{WG9tpsSho1~%qB8* zKTyVUnVWWn{9*s>lT~ zvi1*sT*f7>H%5ofQwW}1e4B^6L~z#_W1om`&oYmU!*-hwr)R;^x}zSns_nt zGBR!=%fd#nDF#Tz(+;Ab(Igrg-10ZSN<---z}~ix?cI^!`uX_Fk`LjTiYS*JM^%vu z4wFh`4b;VggL>q<<_3I)Hw-qy$w={}4>M&(v6zqsQxiJ?03?o(p~H0o2{)^cPGNep zde~Amz}yUO%OtywN-8Wk#E?NUGKN%O#4|TZ{!jr6RnG!ZQ&RQj-`xzR=%Dqdrac>h zlDQs__2hZ5$`(j4^RQ-*DkXk8SY@R8q*X*!0@;Zq4mqLC{(jxDZhOYzv|+=$ zN0)~g!kaP-SR=-95~wQbSzIV$NMmf}td<;&t6$-HWp9sKU+9$EK7N1XR$gq7NKgkA zR4n*D!{YRPuReXdaf3brrbr}N7lB5*f;$jJf;@tCUOSJ=QvU!5{LZ`4cicqzMgIV< z<=bWTmhCpz7+tnpxn#vrUu~v(If92j+b+ccnxwAY-k`bys^20MGgT0T!IMd1QH0aXqvk5diD!q zz|skBNTg1N7ek)RK0y~p&z{Fuzr?ORO!1BqIHN>g3boh|1LIn{aE8CHVV(C20i^~D-$^kSkz&vm*TxeE!*;M}kdVsQkKb=7PfcGQ4dtb2E zw)b_m4#1?Lkc0fD`;TL*2jkR@Tvl!I{{ZYXu1yU_VV$<5!_CB>`~LvENL5s-6G4@g zhfAp!YIrwZHH^QZE`Qd>Mv#Ya(Zr<+iz3jHNm~B^3t1hkj&#oEiTGl@D_@MCiuheu zsUYMKYx~pN{{Y#vo|Zz&1uu>&KqLG)@g!Qg{Z+u;dX&%~`0PBP0?mc;YEx zdzEb3o1P0}2)QxB2Q55^-QsNdUbA`f2@W zRoJl3&XR06G2A-E5-NoZXb=Fpx>9;URnvLgaY8{iwFJBzP8Xs}tul1T}S$ko(AvZl%D zA18u+hv%Rt@+a&5T00VPMVtO#^EwiJh=DtWaTI7(2@F`9BvtZ#zBP!?O*bNFs}^(eOb%>%M|ybRcyWQY=~T;PL*Nu%DNs z&nNt}tjfPhcpiLwX;ZP8;uVUYroVF7QDpvOo<;Hc9Ty&Nr6`tESxTFyE?JxV1XhysW64S2<`#n zpKdfI{_p_AkO80t{-gHPXa4}$i}Gz^E_!dDxBYbfg0f%-kcH~DJo&CU(UJ#QK>LGV zO@IhCJA?8*JnB-a{aA$$<@Wd*xY-p-79bKMN;UcE9GXL@rYDak;f-hMGUJt}4s0+s zF1ufPHC8oOjB-uEd+Lc_Ocmfu`~R`qFSeoBefBD>qR4kMkct8cVff zJ_}r?#3Sf2RE-5ADj%kV@@|hl);T(@%~DBdzMOFiQ_`Ix{rDuFea@4eo80yueg==W z^CKzbb#~E;qzOAPoxw8okT|kv9{>+MyJ^f^*>Ty5GWD^ib^(oi3ZdWkqkL(6&*%RD z`G3%8N=T4%=STA{MO-oS9!5YF1k8kx#fUUd7HWayngjiG{x;Im{ambvS4aRey>fa; z>Rt&YzU2gfK(H*4s_nCvn)&;D>u22wOg*q6>8OF@kMYT@`Eoe$i(?eTvm_6+;fR#0 z2~2UoO|^;vdmf?E7VK4?1)T?RL?pmwj2I*OaxqX^Mp6$&fypdF`QZTYMy0d;`>5;t zzx5IK=if&3=pWlm)yfBCKlGdKJ+!INSof#)oXkuaG4~@DJXz6nh_WeuqXGyhNd(BI zg(#u^CLM|yjOmh+ZEoou1jov*nL1OcY&T^mxoZ{FdD9sPpZSXox>ov!HSwx#+nJL2 z>5Gq!G_bi!{mCv6n1SYztTfKHScV6yo=pR1j%;ySV-!jF=<&AoS#l)%QH>C$sPx#O zRBesb5-O~zwmXcalc~Dz`LCYd`q?)B0JjryVZrrACZHOW>mvAM^{ z&&C7}qWwe$>E?q`9PmLSx96jzO8A3s>VvL7z6D7^Q^D$DL9)ijjsk(e)ky>C$;Wg4 zr$pOH{7L8k0LI_sbdqknj*=UdrrRblNMJ0o0~CkuBc-m?_o6@qp5T63$&L2+8CcF` zXi+B)gf~H8qT7z)i4=Pt*H@#!VZ-U~-@2MVpiuf&< zNu8YXW@NZVawW)|l1%^r1d(J4=J-6GD_cjWbM|4mOD1kMUg8)t6h~Zm)(FsxX6b1N zRTdOQlE( zi-C=|!I8JcmpmsT1)1at8$yp8GdX5rS)?FX2cQ54CtKg6Jv+AVJAB(x&kMxjEM}du zmF0&DNj})rfIxnwVi1-zO%(-z<&Mm&hcdBQ7axZPm~_TEdHC_|t=rLRzxgUI2lw+Y z)#LvFbM0^D_x*Lu*IY4h%OI0uUbM`M)Bc%$8NMKdj zi0Ud0a&C^9vu?qpl6=pgKAtS`nO$3~$f~Lws3N*c_D~JkHb$@ga0H&BmPrR&jmHUk zo0DJOaew~+D*nUURDOf!)Eg|vnJvEm06)zBblP}F`gb?o@-9!zYRNtIgyMV?r(vSeTsGApQ8HbHb!whFST zBK6#@uW^D*Y^={t&$l5~lOiahF{IH)AnOr3l0$U#t0*LbK_G%a-Eb$LA2k*Uq=`oJ z6$E0V?{U}L{;C)6=T|HYj9#gix|GG_0(}ha{EYpCgTG z`+iPB{{RTGdU7QnUoC#MIsWpdQaZi=09|X2cH*c10PSAB<(`yLZrfH~UeAo}>6U?5 zEV1R|BmFs$f&#ZuW+ue~7*`;vAd#vZd?t*@vN`~0uW~+l@O)q7NY>rF=4H3=UuKQ6 zr(}glB>oxaVKzeCf;itJ)zB3}WQrGW8c{XsgwkS!ju zUO4P{zayRoy^u+r$v4lPTKXm!ay?Cr4n$GQ8(pKQWj|@~b*}ALropjh?%R%Zd&=V^ zpFkD-ep9A23gJLP#QluOX_ZB{7ewo7+Py!$`l47LcigwHQDM9yHOQI24}z^?fSVhflc#f$<^=h-Wakyb-tX4l2d@m9vO8F_+_ura(&Ac`WGiV{U71hce+o1@AFTchkq9mi`H=I+xLXJSb1Ps!7pB8eiIWC6!X z;f4PIgzKx0RT4=e({J5zHrTpPM7aozS(YfwK=hCREDNy;C{bQb*Z|$UKABy|B?2);C zv(#GV7k=~rzk%(ndf7Y)NDk!41Up<-}i zU$!vF2y@apo00;%mImd$Headq$uBqnhA$g4C@WxsK^%|O zu|x6`?JXlSnRf`jp<{h~4*vS)XVWY`Xgaadv0qVP z?(k!OXyait`(E>s&Sff-5@JvRS5*Os2dvTLf*X)*19ji=cf-D6Zac8cET(CGysZ&+ zC#pWRYbb3`-AX!${{Rm=PT@4agY`xq)qlfc?lFEI9;49>tA8T)U(;G$2{U480CUwR zEzg0i7&7mTG%H(Q2S)UsMt0M(ZW$<>Zr`WWj?XUa86gM6V*chPZ;W6;b{+jhK;2 zHQ!NB>TEpr$4rcFysnV3!x%-E>NsjrGVoj_l6y0Z7f# pKH@tQ^Qx`93HSLvu=>3jQ3UJfrsrF$?W}440Cn0==r?$u|Jg=G5UKzG literal 0 HcmV?d00001 diff --git a/test/assets/bad.png b/test/assets/bad.png new file mode 100644 index 0000000000000000000000000000000000000000..5392a7eff3713d00875dbecc0dcf99576cedbe84 GIT binary patch literal 534283 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

;I(RmL0m&k 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¤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

G3qXwFgqd#(K1~ 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 z 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

    C&+GaK#Y}0ujp}#rb>A1P4AgS`c(0>}>_BmZF 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 == 350); REQUIRE(bitmap->height() == 200); } + +TEST_CASE("bad jpeg file doesn't cause an overflow", "[image-decoder]") +{ + auto file = ReadFile("../../test/assets/bad.jpg"); + REQUIRE(file.size() == 88731); + + auto bitmap = Bitmap::decode(file.data(), file.size()); + + REQUIRE(bitmap != nullptr); + + REQUIRE(bitmap->width() == 24566); + REQUIRE(bitmap->height() == 58278); +} + +TEST_CASE("bad png file doesn't cause an overflow", "[image-decoder]") +{ + auto file = ReadFile("../../test/assets/bad.png"); + REQUIRE(file.size() == 534283); + + auto bitmap = Bitmap::decode(file.data(), file.size()); + + REQUIRE(bitmap == nullptr); +} From 6600bc3c4703e7ceed1ae85ea079c69732e6ea1c Mon Sep 17 00:00:00 2001 From: bodymovin Date: Tue, 9 Jul 2024 23:10:02 +0000 Subject: [PATCH 081/138] change how forAll iterates over children forAll was currently applying the predicate multiple times per element: - calling super on each component applying the predicate once - applying it again per child when calling forAll in a container component. Diffs= 8fbe13788 change how forAll iterates over children (#7546) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/component.hpp | 2 -- include/rive/container_component.hpp | 3 ++- src/animation/state_machine_instance.cpp | 4 ++-- src/component.cpp | 4 +--- src/container_component.cpp | 11 +++++++++-- 6 files changed, 15 insertions(+), 11 deletions(-) diff --git a/.rive_head b/.rive_head index 172e250f..026d8dfc 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -93fb6eb8365dba5c803d3132f7526dc1c888293e +8fbe13788fa0bd1050ce0b044beb210e1b14ab6a diff --git a/include/rive/component.hpp b/include/rive/component.hpp index ba06a694..7488dca9 100644 --- a/include/rive/component.hpp +++ b/include/rive/component.hpp @@ -57,8 +57,6 @@ class Component : public ComponentBase { return (m_Dirt & ComponentDirt::Collapsed) == ComponentDirt::Collapsed; } - - virtual bool forAll(std::function predicate); }; } // namespace rive diff --git a/include/rive/container_component.hpp b/include/rive/container_component.hpp index e340a17d..04cf246a 100644 --- a/include/rive/container_component.hpp +++ b/include/rive/container_component.hpp @@ -15,7 +15,8 @@ class ContainerComponent : public ContainerComponentBase // Returns true if it searched through all of its children. predicate can // return false to stop searching. - bool forAll(std::function predicate) override; + bool forAll(std::function predicate); + bool forEachChild(std::function predicate); private: std::vector m_children; diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 51f01f13..c6f7316f 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -667,9 +667,9 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, { auto listener = machine->listener(i); auto target = m_artboardInstance->resolve(listener->targetId()); - if (target != nullptr && target->is()) + if (target != nullptr && target->is()) { - target->as()->forAll([&](Component* component) { + target->as()->forAll([&](Component* component) { if (component->is()) { HitShape* hitShape; diff --git a/src/component.cpp b/src/component.cpp index b7fa0387..8765b9e6 100644 --- a/src/component.cpp +++ b/src/component.cpp @@ -89,6 +89,4 @@ bool Component::collapse(bool value) onDirty(m_Dirt); m_DependencyHelper.onComponentDirty(this); return true; -} - -bool Component::forAll(std::function predicate) { return predicate(this); } \ No newline at end of file +} \ No newline at end of file diff --git a/src/container_component.cpp b/src/container_component.cpp index af033486..2ed1bfe1 100644 --- a/src/container_component.cpp +++ b/src/container_component.cpp @@ -18,17 +18,24 @@ bool ContainerComponent::collapse(bool value) bool ContainerComponent::forAll(std::function predicate) { - if (!Super::forAll(predicate)) + if (!predicate(this)) { return false; } + forEachChild(predicate); + return true; +} + +bool ContainerComponent::forEachChild(std::function predicate) +{ for (Component* child : m_children) { if (!predicate(child)) { return false; } - if (child->is() && !child->as()->forAll(predicate)) + if (child->is() && + !child->as()->forEachChild(predicate)) { return false; } From fb37ec88b3600eb4a030a025f382fa1cbea5064b Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Wed, 10 Jul 2024 22:08:00 +0000 Subject: [PATCH 082/138] =?UTF-8?q?Fix=20crash=20when=20skinnable=20isn?= =?UTF-8?q?=E2=80=99t=20found.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/rive-app/rive/issues/7317 Diffs= 876a2dca5 Fix crash when skinnable isn’t found. (#7554) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- src/bones/skin.cpp | 8 +++++++- test/assets/bad_skin.riv | Bin 0 -> 291358 bytes test/file_test.cpp | 41 ++++++++++++++++++++++++++++++++++----- 4 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 test/assets/bad_skin.riv diff --git a/.rive_head b/.rive_head index 026d8dfc..f234bbf1 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8fbe13788fa0bd1050ce0b044beb210e1b14ab6a +876a2dca5228aa6a27e934c3e0f430853a157931 diff --git a/src/bones/skin.cpp b/src/bones/skin.cpp index 33a27c68..20418768 100644 --- a/src/bones/skin.cpp +++ b/src/bones/skin.cpp @@ -85,4 +85,10 @@ void Skin::deform(Span vertices) } void Skin::addTendon(Tendon* tendon) { m_Tendons.push_back(tendon); } -void Skin::onDirty(ComponentDirt dirt) { m_Skinnable->markSkinDirty(); } +void Skin::onDirty(ComponentDirt dirt) +{ + if (m_Skinnable != nullptr) + { + m_Skinnable->markSkinDirty(); + } +} diff --git a/test/assets/bad_skin.riv b/test/assets/bad_skin.riv new file mode 100644 index 0000000000000000000000000000000000000000..e5ba5d58f09676e26bd5ed690191e38808da4dfc GIT binary patch literal 291358 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 Fe*nI7rUn22 literal 0 HcmV?d00001 diff --git a/test/file_test.cpp b/test/file_test.cpp index 03ca35c6..69ec0422 100644 --- a/test/file_test.cpp +++ b/test/file_test.cpp @@ -1,8 +1,10 @@ -#include -#include -#include -#include -#include +#include "rive/file.hpp" +#include "rive/node.hpp" +#include "rive/shapes/rectangle.hpp" +#include "rive/shapes/shape.hpp" +#include "rive/assets/image_asset.hpp" +#include "rive/shapes/points_path.hpp" +#include "rive/shapes/mesh.hpp" #include "utils/no_op_renderer.hpp" #include "rive_file_reader.hpp" #include @@ -193,6 +195,35 @@ TEST_CASE("file with in-band images can have the stripped", "[file]") } } +TEST_CASE("file a bad skin (no parent skinnable) doesn't crash", "[file]") +{ + FILE* fp = fopen("../../test/assets/bad_skin.riv", "rb"); + REQUIRE(fp != nullptr); + + fseek(fp, 0, SEEK_END); + const size_t length = ftell(fp); + fseek(fp, 0, SEEK_SET); + std::vector bytes(length); + REQUIRE(fread(bytes.data(), 1, length, fp) == length); + fclose(fp); + + rive::ImportResult result; + auto file = rive::File::import(bytes, &gNoOpFactory, &result); + REQUIRE(result == rive::ImportResult::success); + REQUIRE(file.get() != nullptr); + REQUIRE(file->artboard() != nullptr); + + REQUIRE(file->artboard()->name() == "Illustration WOman.svg"); + auto artboard = file->artboardDefault(); + artboard->updateComponents(); + auto paths = artboard->find(); + for (auto path : paths) + { + path->markPathDirty(); + } + artboard->updateComponents(); +} + // TODO: // ShapePaint (fill/stroke) needs to be implemented in WASM (jsFill/jsStroke) in // order to create Paint objects as necessary. From c2c9ec75bbcc0126764d4ea3a0dc49d744a85d25 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Thu, 11 Jul 2024 17:50:32 +0000 Subject: [PATCH 083/138] Renderer in editor Starting to let tests run. Diffs= a0a6c0d3b Renderer in editor (#7495) Co-authored-by: Luigi Rosso Co-authored-by: hernan --- .rive_head | 2 +- build/premake5.lua | 9 +-- build/rive_build_config.lua | 2 +- .../rive/animation/nested_state_machine.hpp | 3 + .../state_machine_input_instance.hpp | 18 +++-- .../rive/animation/state_machine_instance.hpp | 13 ++++ include/rive/artboard.hpp | 25 +++++-- include/rive/core/binary_writer.hpp | 3 +- include/rive/layout_component.hpp | 4 +- include/rive/nested_animation.hpp | 17 ++--- include/rive/shapes/paint/trim_path.hpp | 3 +- src/animation/nested_state_machine.cpp | 11 +++ .../state_machine_input_instance.cpp | 22 ++++-- src/animation/state_machine_instance.cpp | 74 +++++++++++++++++-- .../transition_trigger_condition.cpp | 2 +- src/artboard.cpp | 70 ++++++++++++++---- src/core/binary_writer.cpp | 8 +- src/layout_component.cpp | 1 - src/shapes/paint/trim_path.cpp | 9 ++- test/clip_test.cpp | 2 +- 20 files changed, 228 insertions(+), 70 deletions(-) diff --git a/.rive_head b/.rive_head index f234bbf1..7510dfe4 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -876a2dca5228aa6a27e934c3e0f430853a157931 +a0a6c0d3bd385f32dd51e1fbcb75306332b9d1cc diff --git a/build/premake5.lua b/build/premake5.lua index 576761c5..52dd2a69 100644 --- a/build/premake5.lua +++ b/build/premake5.lua @@ -48,7 +48,7 @@ do harfbuzz .. '/src', sheenbidi .. '/Headers', miniaudio, - yoga + yoga, }) defines({ 'YOGA_EXPORT=' }) @@ -163,11 +163,6 @@ do objdir('%{cfg.system}/arm64/obj/%{cfg.buildcfg}') end - filter('system:emscripten') - do - buildoptions({ '-pthread' }) - end - filter('configurations:debug') do defines({ 'DEBUG' }) @@ -217,4 +212,4 @@ newoption({ newoption({ trigger = 'with_rive_layout', description = 'Compiles in layout features.', -}) \ No newline at end of file +}) diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index f6ff5103..b6138c43 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -141,7 +141,7 @@ newoption({ default = 'default', }) --- This is just to match our old windows config. Gamekit specifically sets +-- This is just to match our old windows config. Rive Native specifically sets -- static/dynamic and maybe we should do the same elsewhere. filter({ 'system:windows', 'options:windows_runtime=default' }) do diff --git a/include/rive/animation/nested_state_machine.hpp b/include/rive/animation/nested_state_machine.hpp index c76729aa..8c0476b3 100644 --- a/include/rive/animation/nested_state_machine.hpp +++ b/include/rive/animation/nested_state_machine.hpp @@ -28,6 +28,9 @@ class NestedStateMachine : public NestedStateMachineBase HitResult pointerDown(Vec2D position); HitResult pointerUp(Vec2D position); HitResult pointerExit(Vec2D position); +#ifdef WITH_RIVE_TOOLS + bool hitTest(Vec2D position) const; +#endif void addNestedInput(NestedInput* input); size_t inputCount() { return m_nestedInputs.size(); } diff --git a/include/rive/animation/state_machine_input_instance.hpp b/include/rive/animation/state_machine_input_instance.hpp index e5f732c1..8c82a71b 100644 --- a/include/rive/animation/state_machine_input_instance.hpp +++ b/include/rive/animation/state_machine_input_instance.hpp @@ -20,9 +20,6 @@ class SMIInput friend class StateMachineLayerInstance; private: - StateMachineInstance* m_MachineInstance; - const StateMachineInput* m_Input; - virtual void advanced() {} protected: @@ -32,10 +29,17 @@ class SMIInput public: virtual ~SMIInput() {} - const StateMachineInput* input() const { return m_Input; } + const StateMachineInput* input() const { return m_input; } const std::string& name() const; uint16_t inputCoreType() const; + +private: + StateMachineInstance* m_machineInstance; + const StateMachineInput* m_input; +#ifdef WITH_RIVE_TOOLS + uint64_t m_index = 0; +#endif }; class SMIBool : public SMIInput @@ -72,16 +76,16 @@ class SMITrigger : public SMIInput friend class TransitionTriggerCondition; private: - bool m_Fired = false; + bool m_fired = false; SMITrigger(const StateMachineTrigger* input, StateMachineInstance* machineInstance); - void advanced() override { m_Fired = false; } + void advanced() override { m_fired = false; } public: void fire(); #ifdef TESTING - bool didFire() { return m_Fired; } + bool didFire() { return m_fired; } #endif }; } // namespace rive diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 786366f7..c59ee178 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -32,6 +32,11 @@ class Event; class KeyedProperty; class EventReport; +#ifdef WITH_RIVE_TOOLS +class StateMachineInstance; +typedef void (*InputChanged)(StateMachineInstance*, uint64_t); +#endif + class StateMachineInstance : public Scene, public NestedEventNotifier, public NestedEventListener { friend class SMIInput; @@ -92,6 +97,9 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne HitResult pointerDown(Vec2D position) override; HitResult pointerUp(Vec2D position) override; HitResult pointerExit(Vec2D position) override; +#ifdef WITH_RIVE_TOOLS + bool hitTest(Vec2D position) const; +#endif float durationSeconds() const override { return -1; } Loop loop() const override { return Loop::oneShot; } @@ -131,6 +139,11 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne std::vector> m_hitComponents; StateMachineInstance* m_parentStateMachineInstance = nullptr; NestedArtboard* m_parentNestedArtboard = nullptr; +#ifdef WITH_RIVE_TOOLS +public: + void onInputChanged(InputChanged callback) { m_inputChangedCallback = callback; } + InputChanged m_inputChangedCallback = nullptr; +#endif }; } // namespace rive #endif diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 1051af9b..85353c17 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -44,6 +44,10 @@ class SMIInput; class SMINumber; class SMITrigger; +#ifdef WITH_RIVE_TOOLS +typedef void (*ArtboardCallback)(Artboard*); +#endif + class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer { friend class File; @@ -135,8 +139,8 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta } #endif - bool advance(double elapsedSeconds); - bool advanceInternal(double elapsedSeconds, bool isRoot); + bool advance(double elapsedSeconds, bool nested = true); + bool advanceInternal(double elapsedSeconds, bool isRoot, bool nested = true); bool hasChangedDrawOrderInLastUpdate() { return m_HasChangedDrawOrderInLastUpdate; }; Drawable* firstDrawable() { return m_FirstDrawable; }; @@ -161,9 +165,10 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta NestedArtboard* nestedArtboard(const std::string& name) const; NestedArtboard* nestedArtboardAtPath(const std::string& path) const; - float originalWidth() { return m_originalWidth; } - float originalHeight() { return m_originalHeight; } - + float originalWidth() const { return m_originalWidth; } + float originalHeight() const { return m_originalHeight; } + float layoutWidth() const; + float layoutHeight() const; AABB bounds() const; // Can we hide these from the public? (they use playable) @@ -341,8 +346,18 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta rcp audioEngine() const; void audioEngine(rcp audioEngine); #endif + +#ifdef WITH_RIVE_LAYOUT + void propagateSize() override; +#endif private: float m_volume = 1.0f; +#ifdef WITH_RIVE_TOOLS + ArtboardCallback m_layoutChangedCallback = nullptr; + +public: + void onLayoutChanged(ArtboardCallback callback) { m_layoutChangedCallback = callback; } +#endif }; class ArtboardInstance : public Artboard diff --git a/include/rive/core/binary_writer.hpp b/include/rive/core/binary_writer.hpp index 213e295a..8d87ceef 100644 --- a/include/rive/core/binary_writer.hpp +++ b/include/rive/core/binary_writer.hpp @@ -1,4 +1,3 @@ - #ifndef _RIVE_CORE_BINARY_WRITER_HPP_ #define _RIVE_CORE_BINARY_WRITER_HPP_ @@ -24,6 +23,8 @@ class BinaryWriter void write(const uint8_t* bytes, std::size_t length); void write(uint8_t value); void writeDouble(double value); + void write(uint16_t value); + void write(uint32_t value); void clear(); }; } // namespace rive diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index 6b6e31aa..c070587b 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -32,7 +32,7 @@ struct LayoutAnimationData class LayoutComponent : public LayoutComponentBase { -private: +protected: LayoutComponentStyle* m_style = nullptr; std::unique_ptr m_layoutData; @@ -66,7 +66,7 @@ class LayoutComponent : public LayoutComponentBase #ifdef WITH_RIVE_LAYOUT LayoutComponent(); void syncStyle(); - void propagateSize(); + virtual void propagateSize(); void updateLayoutBounds(); void update(ComponentDirt value) override; StatusCode onAddedDirty(CoreContext* context) override; diff --git a/include/rive/nested_animation.hpp b/include/rive/nested_animation.hpp index fc31df6c..70edc4d0 100644 --- a/include/rive/nested_animation.hpp +++ b/include/rive/nested_animation.hpp @@ -35,17 +35,14 @@ class NestedEventNotifier void notifyListeners(const std::vector& events) { - if (m_nestedArtboard != nullptr) + std::vector eventReports; + for (auto event : events) { - std::vector eventReports; - for (auto event : events) - { - eventReports.push_back(EventReport(event, 0)); - } - for (auto listener : m_nestedEventListeners) - { - listener->notify(eventReports, m_nestedArtboard); - } + eventReports.push_back(EventReport(event, 0)); + } + for (auto listener : m_nestedEventListeners) + { + listener->notify(eventReports, m_nestedArtboard); } } diff --git a/include/rive/shapes/paint/trim_path.hpp b/include/rive/shapes/paint/trim_path.hpp index d9374819..150af984 100644 --- a/include/rive/shapes/paint/trim_path.hpp +++ b/include/rive/shapes/paint/trim_path.hpp @@ -8,13 +8,12 @@ namespace rive { -enum class TrimPathMode : unsigned char +enum class TrimPathMode : uint8_t { sequential = 1, synchronized = 2 }; -class ContourMeasure; class TrimPath : public TrimPathBase, public StrokeEffect { diff --git a/src/animation/nested_state_machine.cpp b/src/animation/nested_state_machine.cpp index f9734299..6045b56c 100644 --- a/src/animation/nested_state_machine.cpp +++ b/src/animation/nested_state_machine.cpp @@ -39,6 +39,17 @@ StateMachineInstance* NestedStateMachine::stateMachineInstance() return m_StateMachineInstance.get(); } +#ifdef WITH_RIVE_TOOLS +bool NestedStateMachine::hitTest(Vec2D position) const +{ + if (m_StateMachineInstance != nullptr) + { + return m_StateMachineInstance->hitTest(position); + } + return false; +} +#endif + HitResult NestedStateMachine::pointerMove(Vec2D position) { if (m_StateMachineInstance != nullptr) diff --git a/src/animation/state_machine_input_instance.cpp b/src/animation/state_machine_input_instance.cpp index 5c2fb33a..d2e98d6e 100644 --- a/src/animation/state_machine_input_instance.cpp +++ b/src/animation/state_machine_input_instance.cpp @@ -7,14 +7,24 @@ using namespace rive; SMIInput::SMIInput(const StateMachineInput* input, StateMachineInstance* machineInstance) : - m_MachineInstance(machineInstance), m_Input(input) + m_machineInstance(machineInstance), m_input(input) {} -uint16_t SMIInput::inputCoreType() const { return m_Input->coreType(); } +uint16_t SMIInput::inputCoreType() const { return m_input->coreType(); } -const std::string& SMIInput::name() const { return m_Input->name(); } +const std::string& SMIInput::name() const { return m_input->name(); } -void SMIInput::valueChanged() { m_MachineInstance->markNeedsAdvance(); } +void SMIInput::valueChanged() +{ + m_machineInstance->markNeedsAdvance(); +#ifdef WITH_RIVE_TOOLS + auto callback = m_machineInstance->m_inputChangedCallback; + if (callback != nullptr) + { + callback(m_machineInstance, m_index); + } +#endif +} // bool @@ -54,10 +64,10 @@ SMITrigger::SMITrigger(const StateMachineTrigger* input, StateMachineInstance* m void SMITrigger::fire() { - if (m_Fired) + if (m_fired) { return; } - m_Fired = true; + m_fired = true; valueChanged(); } diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index c6f7316f..d564b870 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -430,6 +430,9 @@ class HitComponent {} virtual ~HitComponent() {} virtual HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) = 0; +#ifdef WITH_RIVE_TOOLS + virtual bool hitTest(Vec2D position) const = 0; +#endif protected: Component* m_component; @@ -451,8 +454,10 @@ class HitShape : public HitComponent std::vector listeners; bool hitTest(Vec2D position) const +#ifdef WITH_RIVE_TOOLS + override +#endif { - auto shape = m_component->as(); auto worldBounds = shape->worldBounds(); if (!worldBounds.contains(position)) @@ -516,6 +521,36 @@ class HitNestedArtboard : public HitComponent HitComponent(nestedArtboard, stateMachineInstance) {} ~HitNestedArtboard() override {} + +#ifdef WITH_RIVE_TOOLS + bool hitTest(Vec2D position) const override + { + auto nestedArtboard = m_component->as(); + if (nestedArtboard->isCollapsed()) + { + return false; + } + Vec2D nestedPosition; + if (!nestedArtboard->worldToLocal(position, &nestedPosition)) + { + // Mounted artboard isn't ready or has a 0 scale transform. + return false; + } + + for (auto nestedAnimation : nestedArtboard->nestedAnimations()) + { + if (nestedAnimation->is()) + { + auto nestedStateMachine = nestedAnimation->as(); + if (nestedStateMachine->hitTest(nestedPosition)) + { + return true; + } + } + } + return false; + } +#endif HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override { auto nestedArtboard = m_component->as(); @@ -589,7 +624,6 @@ HitResult StateMachineInstance::updateListeners(Vec2D position, ListenerType hit bool hitOpaque = false; for (const auto& hitShape : m_hitComponents) { - // TODO: quick reject. HitResult hitResult = hitShape->processEvent(position, hitType, !hitOpaque); @@ -605,6 +639,28 @@ HitResult StateMachineInstance::updateListeners(Vec2D position, ListenerType hit return hitSomething ? hitOpaque ? HitResult::hitOpaque : HitResult::hit : HitResult::none; } +#ifdef WITH_RIVE_TOOLS +bool StateMachineInstance::hitTest(Vec2D position) const +{ + if (m_artboardInstance->frameOrigin()) + { + position -= Vec2D(m_artboardInstance->originX() * m_artboardInstance->width(), + m_artboardInstance->originY() * m_artboardInstance->height()); + } + + for (const auto& hitShape : m_hitComponents) + { + // TODO: quick reject. + + if (hitShape->hitTest(position)) + { + return true; + } + } + return false; +} +#endif + HitResult StateMachineInstance::pointerMove(Vec2D position) { return updateListeners(position, ListenerType::move); @@ -650,6 +706,13 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, // Sanity check. break; } +#ifdef WITH_RIVE_TOOLS + auto instance = m_inputInstances[i]; + if (instance != nullptr) + { + instance->m_index = i; + } +#endif } m_layerCount = machine->layerCount(); @@ -958,12 +1021,9 @@ void StateMachineInstance::notifyEventListeners(const std::vector& } } // Bubble the event up to parent artboard state machines immediately - if (nestedArtboard() != nullptr) + for (auto listener : nestedEventListeners()) { - for (auto listener : nestedEventListeners()) - { - listener->notify(events, nestedArtboard()); - } + listener->notify(events, nestedArtboard()); } for (auto report : events) diff --git a/src/animation/transition_trigger_condition.cpp b/src/animation/transition_trigger_condition.cpp index a9ed142b..86391fe5 100644 --- a/src/animation/transition_trigger_condition.cpp +++ b/src/animation/transition_trigger_condition.cpp @@ -21,7 +21,7 @@ bool TransitionTriggerCondition::evaluate(const SMIInput* inputInstance) const } auto triggerInput = static_cast(inputInstance); - if (triggerInput->m_Fired) + if (triggerInput->m_fired) { return true; } diff --git a/src/artboard.cpp b/src/artboard.cpp index 25aa369d..a72cba26 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -86,6 +86,8 @@ StatusCode Artboard::initialize() // these will be re-built in update() -- are they needed here? m_BackgroundPath = factory()->makeEmptyRenderPath(); m_ClipPath = factory()->makeEmptyRenderPath(); + m_layoutSizeWidth = width(); + m_layoutSizeHeight = height(); #ifdef WITH_RIVE_LAYOUT markLayoutDirty(this); @@ -444,6 +446,37 @@ void Artboard::onComponentDirty(Component* component) void Artboard::onDirty(ComponentDirt dirt) { m_Dirt |= ComponentDirt::Components; } +#ifdef WITH_RIVE_LAYOUT +void Artboard::propagateSize() +{ + addDirt(ComponentDirt::Path); +#ifdef WITH_RIVE_TOOLS + if (m_layoutChangedCallback != nullptr) + { + m_layoutChangedCallback(this); + } +#endif +} +#endif + +float Artboard::layoutWidth() const +{ +#ifdef WITH_RIVE_LAYOUT + return m_layoutSizeWidth; +#else + return width(); +#endif +} + +float Artboard::layoutHeight() const +{ +#ifdef WITH_RIVE_LAYOUT + return m_layoutSizeHeight; +#else + return height(); +#endif +} + void Artboard::update(ComponentDirt value) { if (hasDirt(value, ComponentDirt::DrawOrder)) @@ -452,11 +485,14 @@ void Artboard::update(ComponentDirt value) } if (hasDirt(value, ComponentDirt::Path)) { - AABB bg = AABB::fromLTWH(-width() * originX(), -height() * originY(), width(), height()); + AABB bg = AABB::fromLTWH(-layoutWidth() * originX(), + -layoutHeight() * originY(), + layoutWidth(), + layoutHeight()); AABB clip; if (m_FrameOrigin) { - clip = {0.0f, 0.0f, width(), height()}; + clip = {0.0f, 0.0f, layoutWidth(), layoutHeight()}; } else { @@ -530,7 +566,7 @@ bool Artboard::updateComponents() return false; } -bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot) +bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot, bool nested) { bool didUpdate = false; m_HasChangedDrawOrderInLastUpdate = false; @@ -604,17 +640,23 @@ bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot) didUpdate = true; } } - for (auto nestedArtboard : m_NestedArtboards) + if (nested) { - if (nestedArtboard->advance((float)elapsedSeconds)) + for (auto nestedArtboard : m_NestedArtboards) { - didUpdate = true; + if (nestedArtboard->advance((float)elapsedSeconds)) + { + didUpdate = true; + } } } return didUpdate; } -bool Artboard::advance(double elapsedSeconds) { return advanceInternal(elapsedSeconds, true); } +bool Artboard::advance(double elapsedSeconds, bool nested) +{ + return advanceInternal(elapsedSeconds, true, nested); +} Core* Artboard::hitTest(HitInfo* hinfo, const Mat2D* xform) { @@ -626,7 +668,7 @@ Core* Artboard::hitTest(HitInfo* hinfo, const Mat2D* xform) auto mx = xform ? *xform : Mat2D(); if (m_FrameOrigin) { - mx *= Mat2D::fromTranslate(width() * originX(), height() * originY()); + mx *= Mat2D::fromTranslate(layoutWidth() * originX(), layoutHeight() * originY()); } Drawable* last = m_FirstDrawable; @@ -666,8 +708,8 @@ void Artboard::draw(Renderer* renderer, DrawOption option) if (m_FrameOrigin) { Mat2D artboardTransform; - artboardTransform[4] = width() * originX(); - artboardTransform[5] = height() * originY(); + artboardTransform[4] = layoutWidth() * originX(); + artboardTransform[5] = layoutHeight() * originY(); renderer->transform(artboardTransform); } @@ -709,9 +751,11 @@ void Artboard::addToRenderPath(RenderPath* path, const Mat2D& transform) AABB Artboard::bounds() const { - return m_FrameOrigin - ? AABB(0.0f, 0.0f, width(), height()) - : AABB::fromLTWH(-width() * originX(), -height() * originY(), width(), height()); + return m_FrameOrigin ? AABB(0.0f, 0.0f, layoutWidth(), layoutHeight()) + : AABB::fromLTWH(-layoutWidth() * originX(), + -layoutHeight() * originY(), + layoutWidth(), + layoutHeight()); } bool Artboard::isTranslucent() const diff --git a/src/core/binary_writer.cpp b/src/core/binary_writer.cpp index ef0fd686..323e5862 100644 --- a/src/core/binary_writer.cpp +++ b/src/core/binary_writer.cpp @@ -100,8 +100,6 @@ void BinaryWriter::write(const uint8_t* bytes, size_t length) m_Stream->write(bytes, length); } -void BinaryWriter::write(uint8_t value) { m_Stream->write(&value, 1); } - void BinaryWriter::writeDouble(double value) { auto bytes = reinterpret_cast(&value); @@ -117,4 +115,10 @@ void BinaryWriter::writeDouble(double value) } } +void BinaryWriter::write(uint8_t value) { m_Stream->write((const uint8_t*)&value, 1); } + +void BinaryWriter::write(uint16_t value) { m_Stream->write((const uint8_t*)&value, 2); } + +void BinaryWriter::write(uint32_t value) { m_Stream->write((const uint8_t*)&value, 4); } + void BinaryWriter::clear() { m_Stream->clear(); } \ No newline at end of file diff --git a/src/layout_component.cpp b/src/layout_component.cpp index 2f393e22..350b7cc2 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -236,7 +236,6 @@ void LayoutComponent::syncStyle() YGValue{m_style->maxWidth(), m_style->maxWidthUnits()}; ygStyle.maxDimensions()[YGDimensionHeight] = YGValue{m_style->maxHeight(), m_style->maxHeightUnits()}; - ygStyle.gap()[YGGutterColumn] = YGValue{m_style->gapHorizontal(), m_style->gapHorizontalUnits()}; ygStyle.gap()[YGGutterRow] = YGValue{m_style->gapVertical(), m_style->gapVerticalUnits()}; diff --git a/src/shapes/paint/trim_path.cpp b/src/shapes/paint/trim_path.cpp index 6b0e334f..8cdabd73 100644 --- a/src/shapes/paint/trim_path.cpp +++ b/src/shapes/paint/trim_path.cpp @@ -146,9 +146,12 @@ void TrimPath::invalidateEffect() void TrimPath::invalidateTrim() { m_renderPath = nullptr; - auto stroke = parent()->as(); - stroke->parent()->addDirt(ComponentDirt::Paint); - stroke->invalidateRendering(); + if (parent() != nullptr) + { + auto stroke = parent()->as(); + stroke->parent()->addDirt(ComponentDirt::Paint); + stroke->invalidateRendering(); + } } void TrimPath::startChanged() { invalidateTrim(); } diff --git a/test/clip_test.cpp b/test/clip_test.cpp index d31a3dd5..d4dbdeb3 100644 --- a/test/clip_test.cpp +++ b/test/clip_test.cpp @@ -60,7 +60,7 @@ TEST_CASE("artboard is clipped correctly", "[clipping]") auto artboard = file->artboard("Center"); REQUIRE(artboard != nullptr); - artboard->updateComponents(); + artboard->advance(0.0f); REQUIRE(artboard->originX() == 0.5); REQUIRE(artboard->originY() == 0.5); { From 3d37b510a742e7bb9be7de4558bd7c87d3127741 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Fri, 12 Jul 2024 01:48:21 +0000 Subject: [PATCH 084/138] Fixing windows build with rive_native. Diffs= 3bf0df5c0 Fixing windows build with rive_native. (#7575) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 7510dfe4..fe0b780d 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a0a6c0d3bd385f32dd51e1fbcb75306332b9d1cc +3bf0df5c0822e5db2764b9a1b65407baee1f6ad0 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index b6138c43..f3b57753 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -137,6 +137,7 @@ newoption({ { 'default', 'Use default runtime' }, { 'static', 'Use static runtime' }, { 'dynamic', 'Use dynamic runtime' }, + { 'dynamic_debug', 'Use dynamic runtime force debug' }, }, default = 'default', }) @@ -169,6 +170,12 @@ do runtime('Release') end +filter({ 'system:windows', 'options:windows_runtime=dynamic_debug' }) +do + staticruntime('off') + runtime('Debug') +end + filter('system:windows') do architecture('x64') From 39af1a4cd4bff5441ae030089fdfeecf88d0baaf Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Sat, 13 Jul 2024 00:07:43 +0000 Subject: [PATCH 085/138] add pic Diffs= c5eb69645 add pic (#7589) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index fe0b780d..ab1b79e4 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -3bf0df5c0822e5db2764b9a1b65407baee1f6ad0 +c5eb69645dfbb0219f18506d8575e67eb2350c13 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index f3b57753..96089e58 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -69,6 +69,11 @@ newoption({ description = 'don\'t disable rtti (nonstandard for Rive)', }) +newoption({ + trigger = 'with-pic', + description = 'enable position independent code', +}) + newoption({ trigger = 'with-exceptions', description = 'don\'t disable exceptions (nonstandard for Rive)', @@ -105,6 +110,13 @@ exceptionhandling('Off') filter({ 'options:with-exceptions' }) exceptionhandling('On') +filter({ 'options:with-pic' }) +do + pic('on') + buildoptions({ '-fPIC' }) + linkoptions({ '-fPIC' }) +end + filter('options:config=debug') do defines({ 'DEBUG' }) From ca928c1834880d6635887bcd7ff8a9f33e4b485a Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Sun, 14 Jul 2024 19:01:23 +0000 Subject: [PATCH 086/138] handle linux warnings Diffs= 2a1db3835 handle linux warnings (#7598) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- dependencies/premake5_sheenbidi_v2.lua | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index ab1b79e4..6f77a6b7 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -c5eb69645dfbb0219f18506d8575e67eb2350c13 +2a1db3835fc1873184daaf4ab02a3688a5b9568a diff --git a/dependencies/premake5_sheenbidi_v2.lua b/dependencies/premake5_sheenbidi_v2.lua index f7410050..891c963e 100644 --- a/dependencies/premake5_sheenbidi_v2.lua +++ b/dependencies/premake5_sheenbidi_v2.lua @@ -49,4 +49,12 @@ do defines({ 'SB_CONFIG_UNITY' }) optimize('Size') end + + filter({ 'system:linux' }) + do + buildoptions({ + '-Wno-unused-function', + '-Wno-unused-variable', + }) + end end From 1e21cf7e1ecc2d8183a259b0a7fa12574a585ca3 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Sun, 14 Jul 2024 22:21:01 +0000 Subject: [PATCH 087/138] explicit linux arch Diffs= 44fae6bfe explicit linux arch (#7606) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 6f77a6b7..ad978406 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -2a1db3835fc1873184daaf4ab02a3688a5b9568a +44fae6bfe787063af6cb7390fd83f5de167e79e0 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 96089e58..e8c2c31d 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -369,6 +369,21 @@ if _OPTIONS['os'] == 'android' then filter({}) end +filter('system:linux', 'options:arch=x64') +do + architecture('x64') +end + +filter('system:linux', 'options:arch=arm') +do + architecture('arm') +end + +filter('system:linux', 'options:arch=arm64') +do + architecture('arm64') +end + if os.host() == 'macosx' then iphoneos_sysroot = os.outputof('xcrun --sdk iphoneos --show-sdk-path') iphonesimulator_sysroot = os.outputof('xcrun --sdk iphonesimulator --show-sdk-path') From bd30190be73414b98c59253a5b0f932dae7f618a Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Mon, 15 Jul 2024 22:50:47 +0000 Subject: [PATCH 088/138] Fix build on web. Diffs= 8a67331a4 Fix build on web. (#7613) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index ad978406..61466a30 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -44fae6bfe787063af6cb7390fd83f5de167e79e0 +8a67331a40847538f893acddfcc57e249e21ec81 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index e8c2c31d..8de0e855 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -384,6 +384,8 @@ do architecture('arm64') end +filter({}) + if os.host() == 'macosx' then iphoneos_sysroot = os.outputof('xcrun --sdk iphoneos --show-sdk-path') iphonesimulator_sysroot = os.outputof('xcrun --sdk iphonesimulator --show-sdk-path') From d80d404464abd7ebdb12587985a4620e09a6aa40 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Tue, 16 Jul 2024 05:10:35 +0000 Subject: [PATCH 089/138] Use "python3" in make_viewer_skia.sh (instead of "python") "python" doesn't exist on all the hosted runners, so it was a game of runner-roulette whether the runtime_test_macos job will pass. Diffs= 63b6a13d3 Use "python3" in make_viewer_skia.sh (instead of "python") (#7597) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- dependencies/macosx/make_viewer_skia.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 61466a30..2db75dca 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8a67331a40847538f893acddfcc57e249e21ec81 +63b6a13d3a2adc1c555747fcd76234360bad7a1d diff --git a/dependencies/macosx/make_viewer_skia.sh b/dependencies/macosx/make_viewer_skia.sh index f0294366..507781e0 100755 --- a/dependencies/macosx/make_viewer_skia.sh +++ b/dependencies/macosx/make_viewer_skia.sh @@ -17,7 +17,7 @@ else cd skia fi -python tools/git-sync-deps +python3 tools/git-sync-deps CONFIG=debug RENDERER= From fa95d87a938b4d1320a3044d3ba1814372af5616 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Tue, 16 Jul 2024 14:56:30 +0000 Subject: [PATCH 090/138] Vulkan! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initial Vulkan implementation for PLS. Shaders use @PLS_IMPL_NONE, which is an incomplete implementation of pixel local storage, but it's enough to get started. Diffs= ca56d7565 Vulkan! (#7553) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> Co-authored-by: DragoÈ™ Tiselice --- .rive_head | 2 +- include/rive/refcnt.hpp | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.rive_head b/.rive_head index 2db75dca..f2c8502f 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -63b6a13d3a2adc1c555747fcd76234360bad7a1d +ca56d756514d50c68ea3306739e6ad177caee2ab diff --git a/include/rive/refcnt.hpp b/include/rive/refcnt.hpp index ed2b31bd..2b0b5e46 100644 --- a/include/rive/refcnt.hpp +++ b/include/rive/refcnt.hpp @@ -35,25 +35,23 @@ template class RefCnt public: RefCnt() : m_refcnt(1) {} - ~RefCnt() { assert(this->debugging_refcnt() == 1); } - void ref() const { (void)m_refcnt.fetch_add(+1, std::memory_order_relaxed); } void unref() const { if (1 == m_refcnt.fetch_add(-1, std::memory_order_acq_rel)) { -#ifndef NDEBUG - // we restore the "1" in debug builds just to make our destructor happy - (void)m_refcnt.fetch_add(+1, std::memory_order_relaxed); -#endif - delete static_cast(this); + static_cast(this)->onRefCntReachedZero(); } } // not reliable in actual threaded scenarios, but useful (perhaps) for debugging int32_t debugging_refcnt() const { return m_refcnt.load(std::memory_order_relaxed); } +protected: + // Can be overloaded in the subclass if specialized delete behavior is required. + void onRefCntReachedZero() const { delete static_cast(this); } + private: // mutable, so can be changed even on a const object mutable std::atomic m_refcnt; From 590a4fd38408e025933a66a65dd8527de845cdb3 Mon Sep 17 00:00:00 2001 From: dskuza Date: Tue, 16 Jul 2024 16:21:16 +0000 Subject: [PATCH 091/138] Set audio to mix on for iOS (simulator) and Catalyst Sets audio on iOS (simulator) and Catalyst to mix rather than duck (default). This builds on #7366 by attempting to clean the code up a little, as well as make the changes only have effect when building for Apple platforms. - [x] Update AudioEngine to contain a pointer to the engine context - This is not exposed via public getter since it's not used outside of the AudioEngine, but was required for memory management - [x] Configure the audio context to mix for Core Audio (only when building for Apple platforms) Tested on: - [x] iOS - [x] iPadOS - [x] macOS Catalyst - [x] macOS Diffs= 238bf2fe1 Set audio to mix on for iOS (simulator) and Catalyst (#7555) Co-authored-by: David Skuza --- .rive_head | 2 +- include/rive/audio/audio_engine.hpp | 4 ++- src/audio/audio_engine.cpp | 54 +++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index f2c8502f..58e5b308 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -ca56d756514d50c68ea3306739e6ad177caee2ab +238bf2fe1872740896a75629e8e349f53938b589 diff --git a/include/rive/audio/audio_engine.hpp b/include/rive/audio/audio_engine.hpp index 8bdf33c4..e709ec7e 100644 --- a/include/rive/audio/audio_engine.hpp +++ b/include/rive/audio/audio_engine.hpp @@ -13,6 +13,7 @@ typedef struct ma_engine ma_engine; typedef struct ma_sound ma_sound; typedef struct ma_device ma_device; typedef struct ma_node_base ma_node_base; +typedef struct ma_context ma_context; namespace rive { @@ -67,9 +68,10 @@ class AudioEngine : public RefCnt size_t playingSoundCount(); #endif private: - AudioEngine(ma_engine* engine); + AudioEngine(ma_engine* engine, ma_context* context); ma_device* m_device; ma_engine* m_engine; + ma_context* m_context; std::mutex m_mutex; void soundCompleted(rcp sound); diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index 8f957e84..da487029 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -163,10 +163,40 @@ void AudioEngine::stop() { ma_engine_stop(m_engine); } rcp AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate) { +// I _think_ MA_NO_DEVICE_IO is defined when building for Unity; otherwise, it seems to pass +// "standard" building When defined, pContext is unavailable, which causes build errors when +// building Unity for iOS. - David +#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) + // Used for configuration only, and isn't referenced past the usage of ma_context_init; thus, + // can be locally scoped. Uses the "logical" defaults from miniaudio, and updates only what we + // need. This should automatically set available backends in priority order based on the target + // it's built for, which in the case of Apple is Core Audio first. + ma_context_config contextConfig = ma_context_config_init(); + contextConfig.coreaudio.sessionCategoryOptions = ma_ios_session_category_option_mix_with_others; + + // We only need to initialize space for the context if we're targeting Apple platforms + ma_context* context = (ma_context*)malloc(sizeof(ma_context)); + + if (ma_context_init(NULL, 0, &contextConfig, context) != MA_SUCCESS) + { + free(context); + context = nullptr; + } +#else + ma_context* context = nullptr; +#endif + ma_engine_config engineConfig = ma_engine_config_init(); engineConfig.channels = numChannels; engineConfig.sampleRate = sampleRate; +#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) + if (context != nullptr) + { + engineConfig.pContext = context; + } +#endif + #ifdef EXTERNAL_RIVE_AUDIO_ENGINE engineConfig.noDevice = MA_TRUE; #endif @@ -175,19 +205,27 @@ rcp AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate) if (ma_engine_init(&engineConfig, engine) != MA_SUCCESS) { +#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) + if (context != nullptr) + { + ma_context_uninit(context); + free(context); + context = nullptr; + } +#endif fprintf(stderr, "AudioEngine::Make - failed to init engine\n"); delete engine; return nullptr; } - return rcp(new AudioEngine(engine)); + return rcp(new AudioEngine(engine, context)); } uint32_t AudioEngine::channels() const { return ma_engine_get_channels(m_engine); } uint32_t AudioEngine::sampleRate() const { return ma_engine_get_sample_rate(m_engine); } -AudioEngine::AudioEngine(ma_engine* engine) : - m_device(ma_engine_get_device(engine)), m_engine(engine) +AudioEngine::AudioEngine(ma_engine* engine, ma_context* context) : + m_device(ma_engine_get_device(engine)), m_engine(engine), m_context(context) {} rcp AudioEngine::play(rcp source, @@ -367,6 +405,16 @@ AudioEngine::~AudioEngine() } m_completedSounds.clear(); +#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) + // m_context is only set when Core Audio is available + if (m_context != nullptr) + { + ma_context_uninit(m_context); + free(m_context); + m_context = nullptr; + } +#endif + ma_engine_uninit(m_engine); delete m_engine; From 595ac88483b8778abdb32ad7d620306f74e54e8f Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Tue, 16 Jul 2024 20:53:30 +0000 Subject: [PATCH 092/138] Run tests, bench, gms, & goldens on a physical Pixel 8 on CI Still no diffing yet -- let's just generate the goldens on iOS and see how it does. Diffs= 8e1be1223 Run tests, bench, gms, & goldens on a physical Pixel 8 on CI (#7618) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.rive_head b/.rive_head index 58e5b308..b46f69f6 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -238bf2fe1872740896a75629e8e349f53938b589 +8e1be1223161ced9cfb80c0ec3671ffd25ee5cfb diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 8de0e855..d67e8496 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -284,9 +284,9 @@ filter({}) if _OPTIONS['os'] == 'android' then pic('on') -- Position-independent code is required for NDK libraries. - local ndk = os.getenv('NDK_PATH') - if not ndk or ndk == '' then - error('export $NDK_PATH') + local ndk = os.getenv('NDK_PATH') or os.getenv('ANDROID_NDK') + if not ndk then + error('export $NDK_PATH or $ANDROID_NDK') end local ndk_toolchain = ndk .. '/toolchains/llvm/prebuilt' From 88375e79c43001eadfefc5a7f18729865ad78d94 Mon Sep 17 00:00:00 2001 From: dskuza Date: Wed, 17 Jul 2024 19:27:42 +0000 Subject: [PATCH 093/138] Only set Core Audio session category for iOS targets Fixes a crash in the latest UAT desktop editor(s) on macOS by targeting setting iOS session category to mixing only for iOS / iPadOS / Catalyst targets. The desktop editor is _not_ any of these targets, so the code changes are not compiled. See [here](https://github.com/rive-app/rive/pull/7555/files#r1680306818) for more discussion. Diffs= 6c5c79b75 Only set Core Audio session category for iOS targets (#7624) Co-authored-by: David Skuza --- .rive_head | 2 +- src/audio/audio_engine.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index b46f69f6..fb5018fa 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8e1be1223161ced9cfb80c0ec3671ffd25ee5cfb +6c5c79b751c50fa4393fb0e44624635861bc3f3b diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index da487029..0bdd9f9d 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -166,7 +166,8 @@ rcp AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate) // I _think_ MA_NO_DEVICE_IO is defined when building for Unity; otherwise, it seems to pass // "standard" building When defined, pContext is unavailable, which causes build errors when // building Unity for iOS. - David -#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) +#if (TARGET_IPHONE_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_OS_IPHONE) && \ + !defined(MA_NO_DEVICE_IO) // Used for configuration only, and isn't referenced past the usage of ma_context_init; thus, // can be locally scoped. Uses the "logical" defaults from miniaudio, and updates only what we // need. This should automatically set available backends in priority order based on the target @@ -190,7 +191,8 @@ rcp AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate) engineConfig.channels = numChannels; engineConfig.sampleRate = sampleRate; -#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) +#if (TARGET_IPHONE_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_OS_IPHONE) && \ + !defined(MA_NO_DEVICE_IO) if (context != nullptr) { engineConfig.pContext = context; @@ -205,7 +207,8 @@ rcp AudioEngine::Make(uint32_t numChannels, uint32_t sampleRate) if (ma_engine_init(&engineConfig, engine) != MA_SUCCESS) { -#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) +#if (TARGET_IPHONE_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_OS_IPHONE) && \ + !defined(MA_NO_DEVICE_IO) if (context != nullptr) { ma_context_uninit(context); @@ -405,7 +408,8 @@ AudioEngine::~AudioEngine() } m_completedSounds.clear(); -#if defined(MA_HAS_COREAUDIO) && !defined(MA_NO_DEVICE_IO) +#if (TARGET_IPHONE_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_OS_IPHONE) && \ + !defined(MA_NO_DEVICE_IO) // m_context is only set when Core Audio is available if (m_context != nullptr) { From 332db4c2d9f26325be7875d74bae7bfb6c97e506 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Wed, 17 Jul 2024 20:47:40 +0000 Subject: [PATCH 094/138] update data bind mode to flags change how we store data bind mode. This will be helpful once we implement converters to identify whether a converter's main direction is "toSource" or "toTarget". It also cleans up how the modal works and saves changes in real time instead of doing it on "Save" data_bind_mode Diffs= 49cabe3cb update data bind mode to flags (#7612) Co-authored-by: hernan --- .rive_head | 2 +- dev/defs/data_bind/data_bind.json | 8 ++-- include/rive/data_bind/data_bind_context.hpp | 2 - include/rive/data_bind/data_bind_mode.hpp | 13 ------- include/rive/data_bind_flags.hpp | 29 ++++++++++++++ include/rive/generated/core_registry.hpp | 12 +++--- .../generated/data_bind/data_bind_base.hpp | 22 +++++------ src/artboard.cpp | 33 +++++++++------- src/data_bind/data_bind.cpp | 17 ++++---- src/data_bind/data_bind_context.cpp | 39 +------------------ 10 files changed, 79 insertions(+), 98 deletions(-) delete mode 100644 include/rive/data_bind/data_bind_mode.hpp create mode 100644 include/rive/data_bind_flags.hpp diff --git a/.rive_head b/.rive_head index fb5018fa..5cb2d554 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -6c5c79b751c50fa4393fb0e44624635861bc3f3b +49cabe3cbd9c9683bd704e0d72a455d698bfe061 diff --git a/dev/defs/data_bind/data_bind.json b/dev/defs/data_bind/data_bind.json index eaf9be27..c93b559c 100644 --- a/dev/defs/data_bind/data_bind.json +++ b/dev/defs/data_bind/data_bind.json @@ -26,15 +26,13 @@ }, "description": "The property that is targeted." }, - "modeValue": { + "flags": { "type": "uint", - "typeRuntime": "uint", "initialValue": "0", "key": { "int": 587, - "string": "modevalue" - }, - "description": "Backing enum value for the binding mode." + "string": "flags" + } } } } \ No newline at end of file diff --git a/include/rive/data_bind/data_bind_context.hpp b/include/rive/data_bind/data_bind_context.hpp index 113b7fb3..a6bdd46b 100644 --- a/include/rive/data_bind/data_bind_context.hpp +++ b/include/rive/data_bind/data_bind_context.hpp @@ -13,11 +13,9 @@ class DataBindContext : public DataBindContextBase std::vector m_SourcePathIdsBuffer; public: - void update(ComponentDirt value) override; void decodeSourcePathIds(Span value) override; void copySourcePathIds(const DataBindContextBase& object) override; void bind() override; - void updateSourceBinding() override; ViewModelInstanceValue* source() { return m_Source; }; }; } // namespace rive diff --git a/include/rive/data_bind/data_bind_mode.hpp b/include/rive/data_bind/data_bind_mode.hpp deleted file mode 100644 index 692e62dc..00000000 --- a/include/rive/data_bind/data_bind_mode.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _RIVE_DATA_BIND_MODE_HPP_ -#define _RIVE_DATA_BIND_MODE_HPP_ -namespace rive -{ -enum class DataBindMode : unsigned int -{ - oneWay = 0, - twoWay = 1, - oneWayToSource = 2, - once = 3, -}; -} -#endif \ No newline at end of file diff --git a/include/rive/data_bind_flags.hpp b/include/rive/data_bind_flags.hpp new file mode 100644 index 00000000..2d8561fd --- /dev/null +++ b/include/rive/data_bind_flags.hpp @@ -0,0 +1,29 @@ +#ifndef _RIVE_DATA_BIND_FLAGS_HPP_ +#define _RIVE_DATA_BIND_FLAGS_HPP_ + +#include "rive/enum_bitset.hpp" + +namespace rive +{ +enum class DataBindFlags : unsigned short +{ + /// Whether the main binding direction is to source (0) or to target (1) + Direction = 1 << 0, + + /// Whether the binding direction is twoWay + TwoWay = 1 << 1, + + /// Whether the binding happens only once + Once = 1 << 2, + + /// Flag if set to target + ToTarget = 0, + + /// Flag if set to source + ToSource = 1 << 0, + +}; + +RIVE_MAKE_ENUM_BITSET(DataBindFlags) +} // namespace rive +#endif diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 519c0641..eb3a240c 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -926,8 +926,8 @@ class CoreRegistry case DataBindBase::propertyKeyPropertyKey: object->as()->propertyKey(value); break; - case DataBindBase::modeValuePropertyKey: - object->as()->modeValue(value); + case DataBindBase::flagsPropertyKey: + object->as()->flags(value); break; case WeightBase::valuesPropertyKey: object->as()->values(value); @@ -1884,8 +1884,8 @@ class CoreRegistry return object->as()->targetId(); case DataBindBase::propertyKeyPropertyKey: return object->as()->propertyKey(); - case DataBindBase::modeValuePropertyKey: - return object->as()->modeValue(); + case DataBindBase::flagsPropertyKey: + return object->as()->flags(); case WeightBase::valuesPropertyKey: return object->as()->values(); case WeightBase::indicesPropertyKey: @@ -2472,7 +2472,7 @@ class CoreRegistry case OpenUrlEventBase::targetValuePropertyKey: case DataBindBase::targetIdPropertyKey: case DataBindBase::propertyKeyPropertyKey: - case DataBindBase::modeValuePropertyKey: + case DataBindBase::flagsPropertyKey: case WeightBase::valuesPropertyKey: case WeightBase::indicesPropertyKey: case TendonBase::boneIdPropertyKey: @@ -3010,7 +3010,7 @@ class CoreRegistry return object->is(); case DataBindBase::propertyKeyPropertyKey: return object->is(); - case DataBindBase::modeValuePropertyKey: + case DataBindBase::flagsPropertyKey: return object->is(); case WeightBase::valuesPropertyKey: return object->is(); diff --git a/include/rive/generated/data_bind/data_bind_base.hpp b/include/rive/generated/data_bind/data_bind_base.hpp index ed0d48db..4c73ffc4 100644 --- a/include/rive/generated/data_bind/data_bind_base.hpp +++ b/include/rive/generated/data_bind/data_bind_base.hpp @@ -30,12 +30,12 @@ class DataBindBase : public Component static const uint16_t targetIdPropertyKey = 585; static const uint16_t propertyKeyPropertyKey = 586; - static const uint16_t modeValuePropertyKey = 587; + static const uint16_t flagsPropertyKey = 587; private: uint32_t m_TargetId = -1; uint32_t m_PropertyKey = Core::invalidPropertyKey; - uint32_t m_ModeValue = 0; + uint32_t m_Flags = 0; public: inline uint32_t targetId() const { return m_TargetId; } @@ -60,15 +60,15 @@ class DataBindBase : public Component propertyKeyChanged(); } - inline uint32_t modeValue() const { return m_ModeValue; } - void modeValue(uint32_t value) + inline uint32_t flags() const { return m_Flags; } + void flags(uint32_t value) { - if (m_ModeValue == value) + if (m_Flags == value) { return; } - m_ModeValue = value; - modeValueChanged(); + m_Flags = value; + flagsChanged(); } Core* clone() const override; @@ -76,7 +76,7 @@ class DataBindBase : public Component { m_TargetId = object.m_TargetId; m_PropertyKey = object.m_PropertyKey; - m_ModeValue = object.m_ModeValue; + m_Flags = object.m_Flags; Component::copy(object); } @@ -90,8 +90,8 @@ class DataBindBase : public Component case propertyKeyPropertyKey: m_PropertyKey = CoreUintType::deserialize(reader); return true; - case modeValuePropertyKey: - m_ModeValue = CoreUintType::deserialize(reader); + case flagsPropertyKey: + m_Flags = CoreUintType::deserialize(reader); return true; } return Component::deserialize(propertyKey, reader); @@ -100,7 +100,7 @@ class DataBindBase : public Component protected: virtual void targetIdChanged() {} virtual void propertyKeyChanged() {} - virtual void modeValueChanged() {} + virtual void flagsChanged() {} }; } // namespace rive diff --git a/src/artboard.cpp b/src/artboard.cpp index a72cba26..47c5d045 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -4,7 +4,6 @@ #include "rive/dependency_sorter.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_bind_context.hpp" -#include "rive/data_bind/data_bind_mode.hpp" #include "rive/draw_rules.hpp" #include "rive/draw_target.hpp" #include "rive/audio_event.hpp" @@ -18,6 +17,7 @@ #include "rive/importers/backboard_importer.hpp" #include "rive/nested_artboard.hpp" #include "rive/joystick.hpp" +#include "rive/data_bind_flags.hpp" #include "rive/animation/nested_bool.hpp" #include "rive/animation/nested_number.hpp" #include "rive/animation/nested_trigger.hpp" @@ -1050,16 +1050,19 @@ void Artboard::buildDataBindDependencies(std::vector* dataBinds) for (auto component : *dataBinds) { auto dataBind = component->as(); - auto mode = static_cast(dataBind->modeValue()); + auto flags = static_cast(dataBind->flags()); // If the data bind reads from the target, we want to add it as dependent from any other - // data bind that writes into that target. - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + // parent data bind that writes into that target. + if (((flags & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((flags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { for (auto innerComponent : *dataBinds) { auto dataBindParent = innerComponent->as(); - auto parentMode = static_cast(dataBind->modeValue()); - if (dataBindParent != dataBind && (parentMode != DataBindMode::oneWayToSource) && + auto parentFlags = static_cast(dataBindParent->flags()); + if (dataBindParent != dataBind && + (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToTarget) || + ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) && dataBindParent->target() == dataBind->target() && dataBindParent->propertyKey() == dataBind->propertyKey()) { @@ -1071,23 +1074,23 @@ void Artboard::buildDataBindDependencies(std::vector* dataBinds) else { // If the data bind reads from a source we want to add it as dependent - // from any other data bind that writes into that source. + // from any other parent data bind that writes into that source. if (dataBind->is()) { for (auto innerComponent : *dataBinds) { - auto dataBindChild = innerComponent->as(); - if (dataBindChild != dataBind) + auto dataBindParent = innerComponent->as(); + if (dataBindParent != dataBind) { - auto childMode = static_cast(dataBind->modeValue()); - if (childMode == DataBindMode::oneWayToSource || - childMode == DataBindMode::twoWay) + auto parentFlags = static_cast(dataBindParent->flags()); + if (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { - if (dataBindChild->is() && - dataBindChild->as()->source() == + if (dataBindParent->is() && + dataBindParent->as()->source() == dataBind->as()->source()) { - dataBind->addDependent(dataBindChild); + dataBindParent->addDependent(dataBind); break; } } diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp index d6f3ce9a..adfa2764 100644 --- a/src/data_bind/data_bind.cpp +++ b/src/data_bind/data_bind.cpp @@ -1,6 +1,6 @@ #include "rive/data_bind/data_bind.hpp" -#include "rive/data_bind/data_bind_mode.hpp" #include "rive/artboard.hpp" +#include "rive/data_bind_flags.hpp" #include "rive/generated/core_registry.hpp" #include "rive/data_bind/context/context_value.hpp" #include "rive/data_bind/context/context_value_boolean.hpp" @@ -40,8 +40,9 @@ StatusCode DataBind::import(ImportStack& importStack) { return Super::import(imp void DataBind::buildDependencies() { Super::buildDependencies(); - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + auto flagsValue = static_cast(flags()); + if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { m_target->addDependent(this); } @@ -88,8 +89,9 @@ void DataBind::update(ComponentDirt value) { // TODO: @hernan review how dirt and mode work together. If dirt is not set for // certain modes, we might be able to skip the mode validation. - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay) + auto flagsValue = static_cast(flags()); + if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToTarget) || + ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { m_ContextValue->apply(m_target, propertyKey()); } @@ -100,8 +102,9 @@ void DataBind::update(ComponentDirt value) void DataBind::updateSourceBinding() { - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) + auto flagsValue = static_cast(flags()); + if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) || + ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { if (m_ContextValue != nullptr) { diff --git a/src/data_bind/data_bind_context.cpp b/src/data_bind/data_bind_context.cpp index a2492265..4bb86f61 100644 --- a/src/data_bind/data_bind_context.cpp +++ b/src/data_bind/data_bind_context.cpp @@ -1,5 +1,5 @@ +#include "rive/data_bind_flags.hpp" #include "rive/data_bind/data_bind_context.hpp" -#include "rive/data_bind/data_bind_mode.hpp" #include "rive/data_bind/context/context_value_number.hpp" #include "rive/data_bind/context/context_value_string.hpp" #include "rive/data_bind/context/context_value_enum.hpp" @@ -39,41 +39,4 @@ void DataBindContext::bind() Super::bind(); } } -} - -void DataBindContext::update(ComponentDirt value) -{ - if (m_Source != nullptr && m_ContextValue != nullptr) - { - - // Use the ComponentDirt::Components flag to indicate the viewmodel has added or removed - // an element to a list. - if ((value & ComponentDirt::Components) == ComponentDirt::Components) - { - m_ContextValue->update(m_target); - } - if ((value & ComponentDirt::Bindings) == ComponentDirt::Bindings) - { - // TODO: @hernan review how dirt and mode work together. If dirt is not set for - // certain modes, we might be able to skip the mode validation. - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay) - { - m_ContextValue->apply(m_target, propertyKey()); - } - } - } - Super::update(value); -} - -void DataBindContext::updateSourceBinding() -{ - auto mode = static_cast(modeValue()); - if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay) - { - if (m_ContextValue != nullptr) - { - m_ContextValue->applyToSource(m_target, propertyKey()); - } - } } \ No newline at end of file From 042a3f78a6fe7e60330538192536363aea8f6bc1 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 19 Jul 2024 13:44:45 +0000 Subject: [PATCH 095/138] fix spilled time for animations with speed applied to them when calculating the spilled time of an animation, we were not accounting for their speed, so it would calculate the remaining time incorrectly. It could end up returning a value larger than the elapsed time causing an exponential time loop. Diffs= 58a9574ce fix spilled time for animations with speed applied to them (#7630) Co-authored-by: hernan --- .rive_head | 2 +- src/animation/linear_animation_instance.cpp | 36 ++- test/animation_state_instance_test.cpp | 237 ++++++++++++++++++++ 3 files changed, 266 insertions(+), 9 deletions(-) diff --git a/.rive_head b/.rive_head index 5cb2d554..79e4087e 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -49cabe3cbd9c9683bd704e0d72a455d698bfe061 +58a9574ce1a8fd45a85ba8118ec14fa8fb0b4a22 diff --git a/src/animation/linear_animation_instance.cpp b/src/animation/linear_animation_instance.cpp index 1399912c..08ebd16b 100644 --- a/src/animation/linear_animation_instance.cpp +++ b/src/animation/linear_animation_instance.cpp @@ -86,14 +86,23 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte case Loop::oneShot: if (direction == 1 && frames > end) { - m_spilledTime = (frames - end) / fps; + // Account for the time dilation or contraction applied in the + // animation local time by its speed to calculate spilled time. + // Calculate the ratio of the time excess by the total elapsed + // time in local time (deltaFrames) and multiply the elapsed time + // by it. + auto deltaFrames = deltaSeconds * fps; + auto spilledFramesRatio = (frames - end) / deltaFrames; + m_spilledTime = spilledFramesRatio * elapsedSeconds; frames = (float)end; m_time = frames / fps; didLoop = true; } else if (direction == -1 && frames < start) { - m_spilledTime = (start - frames) / fps; + auto deltaFrames = std::abs(deltaSeconds * fps); + auto spilledFramesRatio = (start - frames) / deltaFrames; + m_spilledTime = spilledFramesRatio * elapsedSeconds; frames = (float)start; m_time = frames / fps; didLoop = true; @@ -102,9 +111,18 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte case Loop::loop: if (direction == 1 && frames >= end) { - m_spilledTime = (frames - end) / fps; - frames = m_time * fps; - frames = start + std::fmod(frames - start, (float)range); + // How spilled time has to be calculated, given that local time can be scaled + // to a factor of the regular time: + // - for convenience, calculate the local elapsed time in frames (deltaFrames) + // - get the remainder of current frame position (frames) by duration (range) + // - use that remainder as the ratio of the original time that was not consumed + // by the loop (spilledFramesRatio) + // - multiply the original elapsedTime by the ratio to set the spilled time + auto deltaFrames = deltaSeconds * fps; + auto remainder = std::fmod(frames - start, (float)range); + auto spilledFramesRatio = remainder / deltaFrames; + m_spilledTime = spilledFramesRatio * elapsedSeconds; + frames = start + remainder; m_time = frames / fps; didLoop = true; if (reporter != nullptr) @@ -114,9 +132,11 @@ bool LinearAnimationInstance::advance(float elapsedSeconds, KeyedCallbackReporte } else if (direction == -1 && frames <= start) { - m_spilledTime = (start - frames) / fps; - frames = m_time * fps; - frames = end - std::abs(std::fmod(start - frames, (float)range)); + auto deltaFrames = deltaSeconds * fps; + auto remainder = std::abs(std::fmod(start - frames, (float)range)); + auto spilledFramesRatio = std::abs(remainder / deltaFrames); + m_spilledTime = spilledFramesRatio * elapsedSeconds; + frames = end - remainder; m_time = frames / fps; didLoop = true; if (reporter != nullptr) diff --git a/test/animation_state_instance_test.cpp b/test/animation_state_instance_test.cpp index 29b85221..918f2e41 100644 --- a/test/animation_state_instance_test.cpp +++ b/test/animation_state_instance_test.cpp @@ -256,6 +256,243 @@ TEST_CASE("AnimationStateInstance with negative speed starts a negative animatio // backwards 2 seconds from 5. REQUIRE(animationStateInstance->animationInstance()->time() == 0.0); + delete animationStateInstance; + delete animationState; + delete linearAnimation; +} + +TEST_CASE("AnimationStateInstance spilledTime accounts for Nx speed with oneShot", "[animation]") +{ + + rive::NoOpFactory emptyFactory; + // For each of these tests, we cons up a dummy artboard/instance + // just to make the animations happy. + rive::Artboard ab(&emptyFactory); + auto abi = ab.instance(); + + rive::StateMachine machine; + rive::StateMachineInstance stateMachineInstance(&machine, abi.get()); + + rive::LinearAnimation* linearAnimation = new rive::LinearAnimation(); + // duration in seconds is 2 + linearAnimation->duration(4); + linearAnimation->fps(2); + linearAnimation->speed(2); + linearAnimation->loopValue(static_cast(rive::Loop::oneShot)); + + rive::AnimationState* animationState = new rive::AnimationState(); + animationState->animation(linearAnimation); + + rive::AnimationStateInstance* animationStateInstance = + new rive::AnimationStateInstance(animationState, abi.get()); + + // play from beginning. + animationStateInstance->advance(3.0, &stateMachineInstance); + + REQUIRE(animationStateInstance->animationInstance()->time() == 2.0); + REQUIRE(animationStateInstance->animationInstance()->totalTime() == 6.0); + // Duration is 2s but at a 2x speed it takes 1s to end + // When advancing 3s, there are still 2s remaining (spilled) + REQUIRE(animationStateInstance->animationInstance()->spilledTime() == 2.0); + + delete animationStateInstance; + delete animationState; + delete linearAnimation; +} + +TEST_CASE("AnimationStateInstance spilledTime accounts for 1/Nx speed with oneShot", "[animation]") +{ + + rive::NoOpFactory emptyFactory; + // For each of these tests, we cons up a dummy artboard/instance + // just to make the animations happy. + rive::Artboard ab(&emptyFactory); + auto abi = ab.instance(); + + rive::StateMachine machine; + rive::StateMachineInstance stateMachineInstance(&machine, abi.get()); + + rive::LinearAnimation* linearAnimation = new rive::LinearAnimation(); + // duration in seconds is 2 + linearAnimation->duration(4); + linearAnimation->fps(2); + linearAnimation->speed(0.5); + linearAnimation->loopValue(static_cast(rive::Loop::oneShot)); + + rive::AnimationState* animationState = new rive::AnimationState(); + animationState->animation(linearAnimation); + + rive::AnimationStateInstance* animationStateInstance = + new rive::AnimationStateInstance(animationState, abi.get()); + + // play from beginning. + animationStateInstance->advance(5.0, &stateMachineInstance); + + REQUIRE(animationStateInstance->animationInstance()->time() == 2.0); + REQUIRE(animationStateInstance->animationInstance()->totalTime() == 2.5); + // Duration is 2s but at a 0.5x speed it takes 4s to end + // When advancing 5.0s, there are still 1s remaining (spilled) + REQUIRE(animationStateInstance->animationInstance()->spilledTime() == 1.0); + + delete animationStateInstance; + delete animationState; + delete linearAnimation; +} + +TEST_CASE("AnimationStateInstance spilledTime accounts for Nx speed with loop", "[animation]") +{ + + rive::NoOpFactory emptyFactory; + // For each of these tests, we cons up a dummy artboard/instance + // just to make the animations happy. + rive::Artboard ab(&emptyFactory); + auto abi = ab.instance(); + + rive::StateMachine machine; + rive::StateMachineInstance stateMachineInstance(&machine, abi.get()); + + rive::LinearAnimation* linearAnimation = new rive::LinearAnimation(); + // duration in seconds is 2 + linearAnimation->duration(4); + linearAnimation->fps(2); + linearAnimation->speed(2); + linearAnimation->loopValue(static_cast(rive::Loop::loop)); + + rive::AnimationState* animationState = new rive::AnimationState(); + animationState->animation(linearAnimation); + + rive::AnimationStateInstance* animationStateInstance = + new rive::AnimationStateInstance(animationState, abi.get()); + + // play from beginning. + animationStateInstance->advance(5.5, &stateMachineInstance); + + REQUIRE(animationStateInstance->animationInstance()->time() == 1.0); + REQUIRE(animationStateInstance->animationInstance()->totalTime() == 11.0); + // Duration is 2s but at a 2x speed it takes 1s to loop + // When advancing 5.5s, there is still 0.5s remaining (spilled) + REQUIRE(animationStateInstance->animationInstance()->spilledTime() == 0.5); + + delete animationStateInstance; + delete animationState; + delete linearAnimation; +} + +TEST_CASE("AnimationStateInstance spilledTime accounts for 1/Nx speed with loop", "[animation]") +{ + rive::NoOpFactory emptyFactory; + // For each of these tests, we cons up a dummy artboard/instance + // just to make the animations happy. + rive::Artboard ab(&emptyFactory); + auto abi = ab.instance(); + + rive::StateMachine machine; + rive::StateMachineInstance stateMachineInstance(&machine, abi.get()); + + rive::LinearAnimation* linearAnimation = new rive::LinearAnimation(); + // duration in seconds is 2 + linearAnimation->duration(4); + linearAnimation->fps(2); + linearAnimation->speed(0.5); + linearAnimation->loopValue(static_cast(rive::Loop::loop)); + + rive::AnimationState* animationState = new rive::AnimationState(); + animationState->animation(linearAnimation); + + rive::AnimationStateInstance* animationStateInstance = + new rive::AnimationStateInstance(animationState, abi.get()); + + // play from beginning. + animationStateInstance->advance(10.0, &stateMachineInstance); + + REQUIRE(animationStateInstance->animationInstance()->time() == 1.0); + REQUIRE(animationStateInstance->animationInstance()->totalTime() == 5.0); + // Duration is 2s but at a 2x speed it takes 1s to loop + // When advancing 5.5s, there is still 0.5s remaining (spilled) + REQUIRE(animationStateInstance->animationInstance()->spilledTime() == 2.0); + + delete animationStateInstance; + delete animationState; + delete linearAnimation; +} + +TEST_CASE("AnimationStateInstance spilledTime accounts for -Nx speed with oneShot", "[animation]") +{ + + rive::NoOpFactory emptyFactory; + // For each of these tests, we cons up a dummy artboard/instance + // just to make the animations happy. + rive::Artboard ab(&emptyFactory); + auto abi = ab.instance(); + + rive::StateMachine machine; + rive::StateMachineInstance stateMachineInstance(&machine, abi.get()); + + rive::LinearAnimation* linearAnimation = new rive::LinearAnimation(); + // duration in seconds is 2 + linearAnimation->duration(4); + linearAnimation->fps(2); + linearAnimation->speed(-2); + linearAnimation->loopValue(static_cast(rive::Loop::oneShot)); + + rive::AnimationState* animationState = new rive::AnimationState(); + animationState->animation(linearAnimation); + + rive::AnimationStateInstance* animationStateInstance = + new rive::AnimationStateInstance(animationState, abi.get()); + + // play from beginning. + animationStateInstance->advance(3.0, &stateMachineInstance); + + REQUIRE(animationStateInstance->animationInstance()->time() == 0.0); + REQUIRE(animationStateInstance->animationInstance()->totalTime() == 6.0); + // Duration is 2s but at a -2x speed it takes 1s to end + // When advancing at negative speed, time starts at duration + // so starting at end and taking 1s to complete + // there are still 2s remaining (spilled) + REQUIRE(animationStateInstance->animationInstance()->spilledTime() == 2.0); + + delete animationStateInstance; + delete animationState; + delete linearAnimation; +} + +TEST_CASE("AnimationStateInstance spilledTime accounts for -Nx speed with loop", "[animation]") +{ + + rive::NoOpFactory emptyFactory; + // For each of these tests, we cons up a dummy artboard/instance + // just to make the animations happy. + rive::Artboard ab(&emptyFactory); + auto abi = ab.instance(); + + rive::StateMachine machine; + rive::StateMachineInstance stateMachineInstance(&machine, abi.get()); + + rive::LinearAnimation* linearAnimation = new rive::LinearAnimation(); + // duration in seconds is 2 + linearAnimation->duration(4); + linearAnimation->fps(2); + linearAnimation->speed(-2); + linearAnimation->loopValue(static_cast(rive::Loop::loop)); + + rive::AnimationState* animationState = new rive::AnimationState(); + animationState->animation(linearAnimation); + + rive::AnimationStateInstance* animationStateInstance = + new rive::AnimationStateInstance(animationState, abi.get()); + + // play from beginning. + animationStateInstance->advance(5.5, &stateMachineInstance); + + REQUIRE(animationStateInstance->animationInstance()->time() == 1.0); + REQUIRE(animationStateInstance->animationInstance()->totalTime() == 11.0); + // Duration is 2s but at a -2x speed it takes 1s to end + // When advancing at negative speed, time starts at duration + // so starting at end and taking 1s to complete, it loops 5 times + // there is still 0.5s remaining (spilled) + REQUIRE(animationStateInstance->animationInstance()->spilledTime() == 0.5); + delete animationStateInstance; delete animationState; delete linearAnimation; From 5fb0ffa40984ebcc6f2ce836c63a87d090e01647 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 22 Jul 2024 22:37:06 +0000 Subject: [PATCH 096/138] skip custom events when creating hitshapes this is a performance improvement that also fixes #7651 7651 Diffs= f55ebd34f skip custom events when creating hitshapes (#7577) Co-authored-by: hernan --- .rive_head | 2 +- src/animation/state_machine_instance.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 79e4087e..080a6806 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -58a9574ce1a8fd45a85ba8118ec14fa8fb0b4a22 +f55ebd34f3938bfe1e36ebf83bbc92c0e5d34a62 diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index d564b870..90bafbc3 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -729,6 +729,10 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, for (std::size_t i = 0; i < machine->listenerCount(); i++) { auto listener = machine->listener(i); + if (listener->listenerType() == ListenerType::event) + { + continue; + } auto target = m_artboardInstance->resolve(listener->targetId()); if (target != nullptr && target->is()) { From 2b9cfe13fc7a8a618ab658841162b636f835dc8c Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 22 Jul 2024 22:50:42 +0000 Subject: [PATCH 097/138] add bindable properties for state machines This PR sets the fundamental pieces for PRs that will be coming afterward to support data binding state machines. The most important parts are: - bindable properties that will be used as binding points for conditions, listeners, and blend animations - data bind objects don't extend from Component anymore to decouple them from artboards - because of that, now data bind objects are written in the context of their bound object so there is a unified way for setting data bind targets The rest is the usual boilerplate code from core objects and some inheritance changes Diffs= b5f342002 add bindable properties for state machines (#7640) Co-authored-by: hernan --- .rive_head | 2 +- dev/defs/data_bind/bindable_property.json | 20 +++++ .../data_bind/bindable_property_boolean.json | 19 ++++ .../data_bind/bindable_property_color.json | 19 ++++ .../data_bind/bindable_property_enum.json | 21 +++++ .../data_bind/bindable_property_number.json | 19 ++++ .../data_bind/bindable_property_string.json | 19 ++++ dev/defs/data_bind/data_bind.json | 6 +- .../rive/animation/nested_state_machine.hpp | 2 + include/rive/animation/state_machine.hpp | 5 ++ .../rive/animation/state_machine_instance.hpp | 9 ++ include/rive/artboard.hpp | 16 +++- include/rive/data_bind/bindable_property.hpp | 19 ++++ .../data_bind/bindable_property_boolean.hpp | 13 +++ .../data_bind/bindable_property_color.hpp | 13 +++ .../rive/data_bind/bindable_property_enum.hpp | 13 +++ .../data_bind/bindable_property_number.hpp | 13 +++ .../data_bind/bindable_property_string.hpp | 13 +++ .../rive/data_bind/context/context_value.hpp | 6 +- .../context/context_value_boolean.hpp | 4 +- .../data_bind/context/context_value_color.hpp | 4 +- .../data_bind/context/context_value_enum.hpp | 4 +- .../data_bind/context/context_value_list.hpp | 14 ++- .../context/context_value_number.hpp | 4 +- .../context/context_value_string.hpp | 4 +- include/rive/data_bind/data_bind.hpp | 14 ++- include/rive/data_bind/data_bind_context.hpp | 3 +- include/rive/generated/core_registry.hpp | 64 ++++++++++++-- .../data_bind/bindable_property_base.hpp | 37 ++++++++ .../bindable_property_boolean_base.hpp | 71 +++++++++++++++ .../bindable_property_color_base.hpp | 71 +++++++++++++++ .../data_bind/bindable_property_enum_base.hpp | 71 +++++++++++++++ .../bindable_property_number_base.hpp | 71 +++++++++++++++ .../bindable_property_string_base.hpp | 72 +++++++++++++++ .../generated/data_bind/data_bind_base.hpp | 28 +----- .../data_bind/data_bind_context_base.hpp | 1 - include/rive/importers/artboard_importer.hpp | 2 + .../importers/bindable_property_importer.hpp | 20 +++++ .../rive/importers/state_machine_importer.hpp | 2 + include/rive/nested_artboard.hpp | 4 + include/rive/scene.hpp | 3 + src/animation/nested_state_machine.cpp | 18 +++- src/animation/state_machine.cpp | 14 +++ src/animation/state_machine_instance.cpp | 27 ++++++ src/artboard.cpp | 87 +++---------------- .../context/context_value_boolean.cpp | 5 +- src/data_bind/context/context_value_color.cpp | 5 +- src/data_bind/context/context_value_enum.cpp | 10 ++- src/data_bind/context/context_value_list.cpp | 14 +-- .../context/context_value_number.cpp | 5 +- .../context/context_value_string.cpp | 5 +- src/data_bind/data_bind.cpp | 72 ++++++++++----- src/data_bind/data_bind_context.cpp | 5 +- src/file.cpp | 28 ++++++ .../bindable_property_boolean_base.cpp | 11 +++ .../bindable_property_color_base.cpp | 11 +++ .../data_bind/bindable_property_enum_base.cpp | 11 +++ .../bindable_property_number_base.cpp | 11 +++ .../bindable_property_string_base.cpp | 11 +++ src/importers/artboard_importer.cpp | 3 + src/importers/bindable_property_importer.cpp | 9 ++ src/importers/state_machine_importer.cpp | 6 ++ src/nested_artboard.cpp | 25 ++++++ src/scene.cpp | 1 + src/viewmodel/viewmodel_instance_enum.cpp | 2 +- 65 files changed, 1025 insertions(+), 186 deletions(-) create mode 100644 dev/defs/data_bind/bindable_property.json create mode 100644 dev/defs/data_bind/bindable_property_boolean.json create mode 100644 dev/defs/data_bind/bindable_property_color.json create mode 100644 dev/defs/data_bind/bindable_property_enum.json create mode 100644 dev/defs/data_bind/bindable_property_number.json create mode 100644 dev/defs/data_bind/bindable_property_string.json create mode 100644 include/rive/data_bind/bindable_property.hpp create mode 100644 include/rive/data_bind/bindable_property_boolean.hpp create mode 100644 include/rive/data_bind/bindable_property_color.hpp create mode 100644 include/rive/data_bind/bindable_property_enum.hpp create mode 100644 include/rive/data_bind/bindable_property_number.hpp create mode 100644 include/rive/data_bind/bindable_property_string.hpp create mode 100644 include/rive/generated/data_bind/bindable_property_base.hpp create mode 100644 include/rive/generated/data_bind/bindable_property_boolean_base.hpp create mode 100644 include/rive/generated/data_bind/bindable_property_color_base.hpp create mode 100644 include/rive/generated/data_bind/bindable_property_enum_base.hpp create mode 100644 include/rive/generated/data_bind/bindable_property_number_base.hpp create mode 100644 include/rive/generated/data_bind/bindable_property_string_base.hpp create mode 100644 include/rive/importers/bindable_property_importer.hpp create mode 100644 src/generated/data_bind/bindable_property_boolean_base.cpp create mode 100644 src/generated/data_bind/bindable_property_color_base.cpp create mode 100644 src/generated/data_bind/bindable_property_enum_base.cpp create mode 100644 src/generated/data_bind/bindable_property_number_base.cpp create mode 100644 src/generated/data_bind/bindable_property_string_base.cpp create mode 100644 src/importers/bindable_property_importer.cpp diff --git a/.rive_head b/.rive_head index 080a6806..518b856a 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f55ebd34f3938bfe1e36ebf83bbc92c0e5d34a62 +b5f342002be71c61608ad6c37835349eb4e7c719 diff --git a/dev/defs/data_bind/bindable_property.json b/dev/defs/data_bind/bindable_property.json new file mode 100644 index 00000000..dbc57e56 --- /dev/null +++ b/dev/defs/data_bind/bindable_property.json @@ -0,0 +1,20 @@ +{ + "name": "BindableProperty", + "key": { + "int": 9, + "string": "bindableproperty" + }, + "abstract": true, + "properties": { + "dataBindId": { + "type": "Id", + "initialValue": "Core.missingId", + "key": { + "int": 633, + "string": "databindid" + }, + "description": "Id of the data bind binded to this property", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/bindable_property_boolean.json b/dev/defs/data_bind/bindable_property_boolean.json new file mode 100644 index 00000000..78c24f2d --- /dev/null +++ b/dev/defs/data_bind/bindable_property_boolean.json @@ -0,0 +1,19 @@ +{ + "name": "BindablePropertyBoolean", + "key": { + "int": 472, + "string": "bindablepropertyboolean" + }, + "extends": "data_bind/bindable_property.json", + "properties": { + "propertyValue": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 634, + "string": "propertyvalue" + }, + "description": "A property of type bool that can be used for data binding." + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/bindable_property_color.json b/dev/defs/data_bind/bindable_property_color.json new file mode 100644 index 00000000..1dd5134b --- /dev/null +++ b/dev/defs/data_bind/bindable_property_color.json @@ -0,0 +1,19 @@ +{ + "name": "BindablePropertyColor", + "key": { + "int": 475, + "string": "bindablepropertycolor" + }, + "extends": "data_bind/bindable_property.json", + "properties": { + "propertyValue": { + "type": "Color", + "initialValue": "0xFF1D1D1D", + "key": { + "int": 638, + "string": "propertyvalue" + }, + "description": "A property of type int that can be used for data binding." + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/bindable_property_enum.json b/dev/defs/data_bind/bindable_property_enum.json new file mode 100644 index 00000000..b3faf032 --- /dev/null +++ b/dev/defs/data_bind/bindable_property_enum.json @@ -0,0 +1,21 @@ +{ + "name": "BindablePropertyEnum", + "key": { + "int": 474, + "string": "bindablepropertyenum" + }, + "extends": "data_bind/bindable_property.json", + "properties": { + "propertyValue": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 637, + "string": "propertyvalue" + }, + "description": "The id of the enum that can be used for data binding." + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/bindable_property_number.json b/dev/defs/data_bind/bindable_property_number.json new file mode 100644 index 00000000..a2ab667e --- /dev/null +++ b/dev/defs/data_bind/bindable_property_number.json @@ -0,0 +1,19 @@ +{ + "name": "BindablePropertyNumber", + "key": { + "int": 473, + "string": "bindablepropertynumber" + }, + "extends": "data_bind/bindable_property.json", + "properties": { + "propertyValue": { + "type": "double", + "initialValue": "0", + "key": { + "int": 636, + "string": "propertyvalue" + }, + "description": "A property of type double that can be used for data binding." + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/bindable_property_string.json b/dev/defs/data_bind/bindable_property_string.json new file mode 100644 index 00000000..aac63dff --- /dev/null +++ b/dev/defs/data_bind/bindable_property_string.json @@ -0,0 +1,19 @@ +{ + "name": "BindablePropertyString", + "key": { + "int": 471, + "string": "bindablepropertystring" + }, + "extends": "data_bind/bindable_property.json", + "properties": { + "propertyValue": { + "type": "String", + "initialValue": "''", + "key": { + "int": 635, + "string": "propertyvalue" + }, + "description": "A property of type String that can be used for data binding." + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/data_bind.json b/dev/defs/data_bind/data_bind.json index c93b559c..3e3124d5 100644 --- a/dev/defs/data_bind/data_bind.json +++ b/dev/defs/data_bind/data_bind.json @@ -4,18 +4,16 @@ "int": 446, "string": "databind" }, - "extends": "component.json", "properties": { "targetId": { "type": "Id", - "typeRuntime": "uint", "initialValue": "Core.missingId", - "initialValueRuntime": "-1", "key": { "int": 585, "string": "targetid" }, - "description": "Identifier used to track the object that is targetted." + "description": "Identifier used to track the object that is targetted.", + "runtime": false }, "propertyKey": { "type": "uint", diff --git a/include/rive/animation/nested_state_machine.hpp b/include/rive/animation/nested_state_machine.hpp index 8c0476b3..f3e557c1 100644 --- a/include/rive/animation/nested_state_machine.hpp +++ b/include/rive/animation/nested_state_machine.hpp @@ -36,6 +36,8 @@ class NestedStateMachine : public NestedStateMachineBase size_t inputCount() { return m_nestedInputs.size(); } NestedInput* input(size_t index); NestedInput* input(std::string name); + void dataContextFromInstance(ViewModelInstance* viewModelInstance); + void dataContext(DataContext* dataContext); }; } // namespace rive diff --git a/include/rive/animation/state_machine.hpp b/include/rive/animation/state_machine.hpp index 9899893b..258fe612 100644 --- a/include/rive/animation/state_machine.hpp +++ b/include/rive/animation/state_machine.hpp @@ -10,6 +10,7 @@ class StateMachineLayer; class StateMachineInput; class StateMachineListener; class StateMachineImporter; +class DataBind; class StateMachine : public StateMachineBase { friend class StateMachineImporter; @@ -18,10 +19,12 @@ class StateMachine : public StateMachineBase std::vector> m_Layers; std::vector> m_Inputs; std::vector> m_Listeners; + std::vector> m_dataBinds; void addLayer(std::unique_ptr); void addInput(std::unique_ptr); void addListener(std::unique_ptr); + void addDataBind(std::unique_ptr); public: StateMachine(); @@ -32,11 +35,13 @@ class StateMachine : public StateMachineBase size_t layerCount() const { return m_Layers.size(); } size_t inputCount() const { return m_Inputs.size(); } size_t listenerCount() const { return m_Listeners.size(); } + size_t dataBindCount() const { return m_dataBinds.size(); } const StateMachineInput* input(std::string name) const; const StateMachineInput* input(size_t index) const; const StateMachineLayer* layer(std::string name) const; const StateMachineLayer* layer(size_t index) const; + const DataBind* dataBind(size_t index) const; const StateMachineListener* listener(size_t index) const; StatusCode onAddedDirty(CoreContext* context) override; diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index c59ee178..679ade06 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "rive/animation/linear_animation_instance.hpp" #include "rive/animation/state_instance.hpp" #include "rive/animation/state_transition.hpp" @@ -31,6 +32,8 @@ class NestedEventNotifier; class Event; class KeyedProperty; class EventReport; +class DataBind; +class BindableProperty; #ifdef WITH_RIVE_TOOLS class StateMachineInstance; @@ -56,6 +59,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne double randomValue(); StateTransition* findRandomTransition(StateInstance* stateFromInstance, bool ignoreTriggers); StateTransition* findAllowedTransition(StateInstance* stateFromInstance, bool ignoreTriggers); + DataContext* m_DataContext; public: StateMachineInstance(const StateMachine* machine, ArtboardInstance* instance); @@ -78,6 +82,8 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne SMIBool* getBool(const std::string& name) const override; SMINumber* getNumber(const std::string& name) const override; SMITrigger* getTrigger(const std::string& name) const override; + void dataContextFromInstance(ViewModelInstance* viewModelInstance) override; + void dataContext(DataContext* dataContext); size_t currentAnimationCount() const; const LinearAnimationInstance* currentAnimationByIndex(size_t index) const; @@ -128,6 +134,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne /// Gets a reported event at an index < reportedEventCount(). const EventReport reportedEventAt(std::size_t index) const; bool playsAudio() override { return true; } + BindableProperty* bindablePropertyInstance(BindableProperty* bindableProperty); private: std::vector m_reportedEvents; @@ -139,6 +146,8 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne std::vector> m_hitComponents; StateMachineInstance* m_parentStateMachineInstance = nullptr; NestedArtboard* m_parentNestedArtboard = nullptr; + std::vector m_dataBinds; + std::unordered_map m_bindablePropertyInstances; #ifdef WITH_RIVE_TOOLS public: void onInputChanged(InputChanged callback) { m_inputChangedCallback = callback; } diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 85353c17..9411ceb4 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -182,9 +182,9 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta DataContext* parent, bool isRoot); void dataContextFromInstance(ViewModelInstance* viewModelInstance); - void populateDataBinds(std::vector* dataBinds); - void buildDataBindDependencies(std::vector* dataBinds); - void sortDataBinds(std::vector dataBinds); + void addDataBind(DataBind* dataBind); + void populateDataBinds(std::vector* dataBinds); + void sortDataBinds(std::vector dataBinds); bool hasAudio() const; template T* find(const std::string& name) @@ -284,6 +284,16 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta { auto object = *itr; cloneObjects.push_back(object == nullptr ? nullptr : object->clone()); + // For each object, clone its data bind objects and target their clones + for (auto dataBind : m_DataBinds) + { + if (dataBind->target() == object) + { + auto dataBindClone = static_cast(dataBind->clone()); + dataBindClone->target(cloneObjects.back()); + artboardClone->m_DataBinds.push_back(dataBindClone); + } + } } } diff --git a/include/rive/data_bind/bindable_property.hpp b/include/rive/data_bind/bindable_property.hpp new file mode 100644 index 00000000..3294401f --- /dev/null +++ b/include/rive/data_bind/bindable_property.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_HPP_ +#define _RIVE_BINDABLE_PROPERTY_HPP_ +#include "rive/generated/data_bind/bindable_property_base.hpp" +#include "rive/data_bind/data_bind.hpp" +#include +namespace rive +{ +class BindableProperty : public BindablePropertyBase +{ +public: + void dataBind(DataBind* value) { m_dataBind = value; }; + DataBind* dataBind() { return m_dataBind; }; + +private: + DataBind* m_dataBind; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/bindable_property_boolean.hpp b/include/rive/data_bind/bindable_property_boolean.hpp new file mode 100644 index 00000000..18037b6c --- /dev/null +++ b/include/rive/data_bind/bindable_property_boolean.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_BOOLEAN_HPP_ +#define _RIVE_BINDABLE_PROPERTY_BOOLEAN_HPP_ +#include "rive/generated/data_bind/bindable_property_boolean_base.hpp" +#include +namespace rive +{ +class BindablePropertyBoolean : public BindablePropertyBooleanBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/bindable_property_color.hpp b/include/rive/data_bind/bindable_property_color.hpp new file mode 100644 index 00000000..dd128ca2 --- /dev/null +++ b/include/rive/data_bind/bindable_property_color.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_COLOR_HPP_ +#define _RIVE_BINDABLE_PROPERTY_COLOR_HPP_ +#include "rive/generated/data_bind/bindable_property_color_base.hpp" +#include +namespace rive +{ +class BindablePropertyColor : public BindablePropertyColorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/bindable_property_enum.hpp b/include/rive/data_bind/bindable_property_enum.hpp new file mode 100644 index 00000000..48692c2b --- /dev/null +++ b/include/rive/data_bind/bindable_property_enum.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_ENUM_HPP_ +#define _RIVE_BINDABLE_PROPERTY_ENUM_HPP_ +#include "rive/generated/data_bind/bindable_property_enum_base.hpp" +#include +namespace rive +{ +class BindablePropertyEnum : public BindablePropertyEnumBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/bindable_property_number.hpp b/include/rive/data_bind/bindable_property_number.hpp new file mode 100644 index 00000000..38a72fdf --- /dev/null +++ b/include/rive/data_bind/bindable_property_number.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_NUMBER_HPP_ +#define _RIVE_BINDABLE_PROPERTY_NUMBER_HPP_ +#include "rive/generated/data_bind/bindable_property_number_base.hpp" +#include +namespace rive +{ +class BindablePropertyNumber : public BindablePropertyNumberBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/bindable_property_string.hpp b/include/rive/data_bind/bindable_property_string.hpp new file mode 100644 index 00000000..302caf07 --- /dev/null +++ b/include/rive/data_bind/bindable_property_string.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_STRING_HPP_ +#define _RIVE_BINDABLE_PROPERTY_STRING_HPP_ +#include "rive/generated/data_bind/bindable_property_string_base.hpp" +#include +namespace rive +{ +class BindablePropertyString : public BindablePropertyStringBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/context/context_value.hpp b/include/rive/data_bind/context/context_value.hpp index 1f08e45f..370f46f0 100644 --- a/include/rive/data_bind/context/context_value.hpp +++ b/include/rive/data_bind/context/context_value.hpp @@ -13,9 +13,9 @@ class DataBindContextValue public: DataBindContextValue(){}; virtual ~DataBindContextValue(){}; - virtual void applyToSource(Component* component, uint32_t propertyKey){}; - virtual void apply(Component* component, uint32_t propertyKey){}; - virtual void update(Component* component){}; + virtual void applyToSource(Core* component, uint32_t propertyKey){}; + virtual void apply(Core* component, uint32_t propertyKey){}; + virtual void update(Core* component){}; }; } // namespace rive diff --git a/include/rive/data_bind/context/context_value_boolean.hpp b/include/rive/data_bind/context/context_value_boolean.hpp index b7a963b9..82e9a7fa 100644 --- a/include/rive/data_bind/context/context_value_boolean.hpp +++ b/include/rive/data_bind/context/context_value_boolean.hpp @@ -8,8 +8,8 @@ class DataBindContextValueBoolean : public DataBindContextValue public: DataBindContextValueBoolean(ViewModelInstanceValue* value); - void apply(Component* component, uint32_t propertyKey) override; - virtual void applyToSource(Component* component, uint32_t propertyKey) override; + void apply(Core* component, uint32_t propertyKey) override; + virtual void applyToSource(Core* component, uint32_t propertyKey) override; private: bool m_Value; diff --git a/include/rive/data_bind/context/context_value_color.hpp b/include/rive/data_bind/context/context_value_color.hpp index c1c7f48c..22fe8f85 100644 --- a/include/rive/data_bind/context/context_value_color.hpp +++ b/include/rive/data_bind/context/context_value_color.hpp @@ -8,8 +8,8 @@ class DataBindContextValueColor : public DataBindContextValue public: DataBindContextValueColor(ViewModelInstanceValue* value); - void apply(Component* component, uint32_t propertyKey) override; - virtual void applyToSource(Component* component, uint32_t propertyKey) override; + void apply(Core* component, uint32_t propertyKey) override; + virtual void applyToSource(Core* component, uint32_t propertyKey) override; private: double m_Value; diff --git a/include/rive/data_bind/context/context_value_enum.hpp b/include/rive/data_bind/context/context_value_enum.hpp index e78a1b5a..98c21c46 100644 --- a/include/rive/data_bind/context/context_value_enum.hpp +++ b/include/rive/data_bind/context/context_value_enum.hpp @@ -8,8 +8,8 @@ class DataBindContextValueEnum : public DataBindContextValue public: DataBindContextValueEnum(ViewModelInstanceValue* value); - void apply(Component* component, uint32_t propertyKey) override; - virtual void applyToSource(Component* component, uint32_t propertyKey) override; + void apply(Core* component, uint32_t propertyKey) override; + virtual void applyToSource(Core* component, uint32_t propertyKey) override; private: int m_Value; diff --git a/include/rive/data_bind/context/context_value_list.hpp b/include/rive/data_bind/context/context_value_list.hpp index 3ee4f2dc..0c12f912 100644 --- a/include/rive/data_bind/context/context_value_list.hpp +++ b/include/rive/data_bind/context/context_value_list.hpp @@ -12,17 +12,15 @@ class DataBindContextValueList : public DataBindContextValue public: DataBindContextValueList(ViewModelInstanceValue* value); - void apply(Component* component, uint32_t propertyKey) override; - void update(Component* target) override; - virtual void applyToSource(Component* component, uint32_t propertyKey) override; + void apply(Core* component, uint32_t propertyKey) override; + void update(Core* target) override; + virtual void applyToSource(Core* component, uint32_t propertyKey) override; private: std::vector> m_ListItemsCache; - void insertItem(Component* target, - ViewModelInstanceListItem* viewModelInstanceListItem, - int index); - void swapItems(Component* target, int index1, int index2); - void popItem(Component* target); + void insertItem(Core* target, ViewModelInstanceListItem* viewModelInstanceListItem, int index); + void swapItems(Core* target, int index1, int index2); + void popItem(Core* target); std::unique_ptr createArtboard(Component* target, Artboard* artboard, ViewModelInstanceListItem* listItem) const; diff --git a/include/rive/data_bind/context/context_value_number.hpp b/include/rive/data_bind/context/context_value_number.hpp index da866d34..b2d850ab 100644 --- a/include/rive/data_bind/context/context_value_number.hpp +++ b/include/rive/data_bind/context/context_value_number.hpp @@ -8,8 +8,8 @@ class DataBindContextValueNumber : public DataBindContextValue public: DataBindContextValueNumber(ViewModelInstanceValue* value); - void apply(Component* component, uint32_t propertyKey) override; - virtual void applyToSource(Component* component, uint32_t propertyKey) override; + void apply(Core* component, uint32_t propertyKey) override; + virtual void applyToSource(Core* component, uint32_t propertyKey) override; private: double m_Value; diff --git a/include/rive/data_bind/context/context_value_string.hpp b/include/rive/data_bind/context/context_value_string.hpp index 52f2ac39..0b32528d 100644 --- a/include/rive/data_bind/context/context_value_string.hpp +++ b/include/rive/data_bind/context/context_value_string.hpp @@ -8,8 +8,8 @@ class DataBindContextValueString : public DataBindContextValue public: DataBindContextValueString(ViewModelInstanceValue* value); - void apply(Component* component, uint32_t propertyKey) override; - virtual void applyToSource(Component* component, uint32_t propertyKey) override; + void apply(Core* component, uint32_t propertyKey) override; + virtual void applyToSource(Core* component, uint32_t propertyKey) override; private: std::string m_Value; diff --git a/include/rive/data_bind/data_bind.hpp b/include/rive/data_bind/data_bind.hpp index 7efbcc81..0ccccb3b 100644 --- a/include/rive/data_bind/data_bind.hpp +++ b/include/rive/data_bind/data_bind.hpp @@ -1,8 +1,10 @@ #ifndef _RIVE_DATA_BIND_HPP_ #define _RIVE_DATA_BIND_HPP_ +#include "rive/component_dirt.hpp" #include "rive/generated/data_bind/data_bind_base.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/data_context.hpp" #include namespace rive { @@ -11,14 +13,18 @@ class DataBind : public DataBindBase public: StatusCode onAddedDirty(CoreContext* context) override; StatusCode import(ImportStack& importStack) override; - void buildDependencies() override; virtual void updateSourceBinding(); - void update(ComponentDirt value) override; - Component* target() { return m_target; }; + virtual void update(ComponentDirt value); + Core* target() const { return m_target; }; + void target(Core* value) { m_target = value; }; virtual void bind(); + ComponentDirt dirt() { return m_Dirt; }; + void dirt(ComponentDirt value) { m_Dirt = value; }; + bool addDirt(ComponentDirt value, bool recurse); protected: - Component* m_target; + ComponentDirt m_Dirt = ComponentDirt::Filthy; + Core* m_target; ViewModelInstanceValue* m_Source; std::unique_ptr m_ContextValue; }; diff --git a/include/rive/data_bind/data_bind_context.hpp b/include/rive/data_bind/data_bind_context.hpp index a6bdd46b..b7e2ad42 100644 --- a/include/rive/data_bind/data_bind_context.hpp +++ b/include/rive/data_bind/data_bind_context.hpp @@ -3,6 +3,7 @@ #include "rive/generated/data_bind/data_bind_context_base.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/data_context.hpp" #include "rive/refcnt.hpp" #include namespace rive @@ -15,7 +16,7 @@ class DataBindContext : public DataBindContextBase public: void decodeSourcePathIds(Span value) override; void copySourcePathIds(const DataBindContextBase& object) override; - void bind() override; + void bindFromContext(DataContext* dataContext); ViewModelInstanceValue* source() { return m_Source; }; }; } // namespace rive diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index eb3a240c..3096b791 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -100,6 +100,12 @@ #include "rive/custom_property_boolean.hpp" #include "rive/custom_property_number.hpp" #include "rive/custom_property_string.hpp" +#include "rive/data_bind/bindable_property.hpp" +#include "rive/data_bind/bindable_property_boolean.hpp" +#include "rive/data_bind/bindable_property_color.hpp" +#include "rive/data_bind/bindable_property_enum.hpp" +#include "rive/data_bind/bindable_property_number.hpp" +#include "rive/data_bind/bindable_property_string.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_bind_context.hpp" #include "rive/draw_rules.hpp" @@ -408,10 +414,20 @@ class CoreRegistry return new Backboard(); case OpenUrlEventBase::typeKey: return new OpenUrlEvent(); + case BindablePropertyBooleanBase::typeKey: + return new BindablePropertyBoolean(); case DataBindBase::typeKey: return new DataBind(); case DataBindContextBase::typeKey: return new DataBindContext(); + case BindablePropertyStringBase::typeKey: + return new BindablePropertyString(); + case BindablePropertyNumberBase::typeKey: + return new BindablePropertyNumber(); + case BindablePropertyEnumBase::typeKey: + return new BindablePropertyEnum(); + case BindablePropertyColorBase::typeKey: + return new BindablePropertyColor(); case WeightBase::typeKey: return new Weight(); case BoneBase::typeKey: @@ -542,6 +558,9 @@ class CoreRegistry case LayoutComponentBase::clipPropertyKey: object->as()->clip(value); break; + case BindablePropertyBooleanBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case TextModifierRangeBase::clampPropertyKey: object->as()->clamp(value); break; @@ -920,15 +939,15 @@ class CoreRegistry case OpenUrlEventBase::targetValuePropertyKey: object->as()->targetValue(value); break; - case DataBindBase::targetIdPropertyKey: - object->as()->targetId(value); - break; case DataBindBase::propertyKeyPropertyKey: object->as()->propertyKey(value); break; case DataBindBase::flagsPropertyKey: object->as()->flags(value); break; + case BindablePropertyEnumBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case WeightBase::valuesPropertyKey: object->as()->values(value); break; @@ -1019,6 +1038,9 @@ class CoreRegistry case GradientStopBase::colorValuePropertyKey: object->as()->colorValue(value); break; + case BindablePropertyColorBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; } } static void setString(Core* object, int propertyKey, std::string value) @@ -1052,6 +1074,9 @@ class CoreRegistry case OpenUrlEventBase::urlPropertyKey: object->as()->url(value); break; + case BindablePropertyStringBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case TextValueRunBase::textPropertyKey: object->as()->text(value); break; @@ -1427,6 +1452,9 @@ class CoreRegistry case JoystickBase::heightPropertyKey: object->as()->height(value); break; + case BindablePropertyNumberBase::propertyValuePropertyKey: + object->as()->propertyValue(value); + break; case BoneBase::lengthPropertyKey: object->as()->length(value); break; @@ -1625,6 +1653,8 @@ class CoreRegistry return object->as()->propertyValue(); case LayoutComponentBase::clipPropertyKey: return object->as()->clip(); + case BindablePropertyBooleanBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case TextModifierRangeBase::clampPropertyKey: return object->as()->clamp(); } @@ -1880,12 +1910,12 @@ class CoreRegistry return object->as()->handleSourceId(); case OpenUrlEventBase::targetValuePropertyKey: return object->as()->targetValue(); - case DataBindBase::targetIdPropertyKey: - return object->as()->targetId(); case DataBindBase::propertyKeyPropertyKey: return object->as()->propertyKey(); case DataBindBase::flagsPropertyKey: return object->as()->flags(); + case BindablePropertyEnumBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case WeightBase::valuesPropertyKey: return object->as()->values(); case WeightBase::indicesPropertyKey: @@ -1949,6 +1979,8 @@ class CoreRegistry return object->as()->colorValue(); case GradientStopBase::colorValuePropertyKey: return object->as()->colorValue(); + case BindablePropertyColorBase::propertyValuePropertyKey: + return object->as()->propertyValue(); } return 0; } @@ -1974,6 +2006,8 @@ class CoreRegistry return object->as()->value(); case OpenUrlEventBase::urlPropertyKey: return object->as()->url(); + case BindablePropertyStringBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case TextValueRunBase::textPropertyKey: return object->as()->text(); case CustomPropertyStringBase::propertyValuePropertyKey: @@ -2227,6 +2261,8 @@ class CoreRegistry return object->as()->width(); case JoystickBase::heightPropertyKey: return object->as()->height(); + case BindablePropertyNumberBase::propertyValuePropertyKey: + return object->as()->propertyValue(); case BoneBase::lengthPropertyKey: return object->as()->length(); case RootBoneBase::xPropertyKey: @@ -2345,6 +2381,7 @@ class CoreRegistry case ClippingShapeBase::isVisiblePropertyKey: case CustomPropertyBooleanBase::propertyValuePropertyKey: case LayoutComponentBase::clipPropertyKey: + case BindablePropertyBooleanBase::propertyValuePropertyKey: case TextModifierRangeBase::clampPropertyKey: return CoreBoolType::id; case ViewModelInstanceListItemBase::viewModelIdPropertyKey: @@ -2470,9 +2507,9 @@ class CoreRegistry case JoystickBase::joystickFlagsPropertyKey: case JoystickBase::handleSourceIdPropertyKey: case OpenUrlEventBase::targetValuePropertyKey: - case DataBindBase::targetIdPropertyKey: case DataBindBase::propertyKeyPropertyKey: case DataBindBase::flagsPropertyKey: + case BindablePropertyEnumBase::propertyValuePropertyKey: case WeightBase::valuesPropertyKey: case WeightBase::indicesPropertyKey: case TendonBase::boneIdPropertyKey: @@ -2502,6 +2539,7 @@ class CoreRegistry case KeyFrameColorBase::valuePropertyKey: case SolidColorBase::colorValuePropertyKey: case GradientStopBase::colorValuePropertyKey: + case BindablePropertyColorBase::propertyValuePropertyKey: return CoreColorType::id; case ViewModelComponentBase::namePropertyKey: case ViewModelInstanceStringBase::propertyValuePropertyKey: @@ -2512,6 +2550,7 @@ class CoreRegistry case StateMachineComponentBase::namePropertyKey: case KeyFrameStringBase::valuePropertyKey: case OpenUrlEventBase::urlPropertyKey: + case BindablePropertyStringBase::propertyValuePropertyKey: case TextValueRunBase::textPropertyKey: case CustomPropertyStringBase::propertyValuePropertyKey: case AssetBase::namePropertyKey: @@ -2636,6 +2675,7 @@ class CoreRegistry case JoystickBase::originYPropertyKey: case JoystickBase::widthPropertyKey: case JoystickBase::heightPropertyKey: + case BindablePropertyNumberBase::propertyValuePropertyKey: case BoneBase::lengthPropertyKey: case RootBoneBase::xPropertyKey: case RootBoneBase::yPropertyKey: @@ -2758,6 +2798,8 @@ class CoreRegistry return object->is(); case LayoutComponentBase::clipPropertyKey: return object->is(); + case BindablePropertyBooleanBase::propertyValuePropertyKey: + return object->is(); case TextModifierRangeBase::clampPropertyKey: return object->is(); case ViewModelInstanceListItemBase::viewModelIdPropertyKey: @@ -3006,12 +3048,12 @@ class CoreRegistry return object->is(); case OpenUrlEventBase::targetValuePropertyKey: return object->is(); - case DataBindBase::targetIdPropertyKey: - return object->is(); case DataBindBase::propertyKeyPropertyKey: return object->is(); case DataBindBase::flagsPropertyKey: return object->is(); + case BindablePropertyEnumBase::propertyValuePropertyKey: + return object->is(); case WeightBase::valuesPropertyKey: return object->is(); case WeightBase::indicesPropertyKey: @@ -3068,6 +3110,8 @@ class CoreRegistry return object->is(); case GradientStopBase::colorValuePropertyKey: return object->is(); + case BindablePropertyColorBase::propertyValuePropertyKey: + return object->is(); case ViewModelComponentBase::namePropertyKey: return object->is(); case ViewModelInstanceStringBase::propertyValuePropertyKey: @@ -3086,6 +3130,8 @@ class CoreRegistry return object->is(); case OpenUrlEventBase::urlPropertyKey: return object->is(); + case BindablePropertyStringBase::propertyValuePropertyKey: + return object->is(); case TextValueRunBase::textPropertyKey: return object->is(); case CustomPropertyStringBase::propertyValuePropertyKey: @@ -3332,6 +3378,8 @@ class CoreRegistry return object->is(); case JoystickBase::heightPropertyKey: return object->is(); + case BindablePropertyNumberBase::propertyValuePropertyKey: + return object->is(); case BoneBase::lengthPropertyKey: return object->is(); case RootBoneBase::xPropertyKey: diff --git a/include/rive/generated/data_bind/bindable_property_base.hpp b/include/rive/generated/data_bind/bindable_property_base.hpp new file mode 100644 index 00000000..b5d5f144 --- /dev/null +++ b/include/rive/generated/data_bind/bindable_property_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_BASE_HPP_ +#include "rive/core.hpp" +namespace rive +{ +class BindablePropertyBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 9; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + void copy(const BindablePropertyBase& object) {} + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { return false; } + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/bindable_property_boolean_base.hpp b/include/rive/generated/data_bind/bindable_property_boolean_base.hpp new file mode 100644 index 00000000..366b5512 --- /dev/null +++ b/include/rive/generated/data_bind/bindable_property_boolean_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_BOOLEAN_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_BOOLEAN_BASE_HPP_ +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/data_bind/bindable_property.hpp" +namespace rive +{ +class BindablePropertyBooleanBase : public BindableProperty +{ +protected: + typedef BindableProperty Super; + +public: + static const uint16_t typeKey = 472; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyBooleanBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 634; + +private: + bool m_PropertyValue = false; + +public: + inline bool propertyValue() const { return m_PropertyValue; } + void propertyValue(bool value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const BindablePropertyBooleanBase& object) + { + m_PropertyValue = object.m_PropertyValue; + BindableProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreBoolType::deserialize(reader); + return true; + } + return BindableProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/bindable_property_color_base.hpp b/include/rive/generated/data_bind/bindable_property_color_base.hpp new file mode 100644 index 00000000..a14617dd --- /dev/null +++ b/include/rive/generated/data_bind/bindable_property_color_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_COLOR_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_COLOR_BASE_HPP_ +#include "rive/core/field_types/core_color_type.hpp" +#include "rive/data_bind/bindable_property.hpp" +namespace rive +{ +class BindablePropertyColorBase : public BindableProperty +{ +protected: + typedef BindableProperty Super; + +public: + static const uint16_t typeKey = 475; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyColorBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 638; + +private: + int m_PropertyValue = 0xFF1D1D1D; + +public: + inline int propertyValue() const { return m_PropertyValue; } + void propertyValue(int value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const BindablePropertyColorBase& object) + { + m_PropertyValue = object.m_PropertyValue; + BindableProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreColorType::deserialize(reader); + return true; + } + return BindableProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/bindable_property_enum_base.hpp b/include/rive/generated/data_bind/bindable_property_enum_base.hpp new file mode 100644 index 00000000..30c6f445 --- /dev/null +++ b/include/rive/generated/data_bind/bindable_property_enum_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_ENUM_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_ENUM_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/data_bind/bindable_property.hpp" +namespace rive +{ +class BindablePropertyEnumBase : public BindableProperty +{ +protected: + typedef BindableProperty Super; + +public: + static const uint16_t typeKey = 474; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyEnumBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 637; + +private: + uint32_t m_PropertyValue = -1; + +public: + inline uint32_t propertyValue() const { return m_PropertyValue; } + void propertyValue(uint32_t value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const BindablePropertyEnumBase& object) + { + m_PropertyValue = object.m_PropertyValue; + BindableProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreUintType::deserialize(reader); + return true; + } + return BindableProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/bindable_property_number_base.hpp b/include/rive/generated/data_bind/bindable_property_number_base.hpp new file mode 100644 index 00000000..72596c12 --- /dev/null +++ b/include/rive/generated/data_bind/bindable_property_number_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_NUMBER_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_NUMBER_BASE_HPP_ +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/data_bind/bindable_property.hpp" +namespace rive +{ +class BindablePropertyNumberBase : public BindableProperty +{ +protected: + typedef BindableProperty Super; + +public: + static const uint16_t typeKey = 473; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyNumberBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 636; + +private: + float m_PropertyValue = 0.0f; + +public: + inline float propertyValue() const { return m_PropertyValue; } + void propertyValue(float value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const BindablePropertyNumberBase& object) + { + m_PropertyValue = object.m_PropertyValue; + BindableProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreDoubleType::deserialize(reader); + return true; + } + return BindableProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/bindable_property_string_base.hpp b/include/rive/generated/data_bind/bindable_property_string_base.hpp new file mode 100644 index 00000000..88d51219 --- /dev/null +++ b/include/rive/generated/data_bind/bindable_property_string_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_STRING_BASE_HPP_ +#define _RIVE_BINDABLE_PROPERTY_STRING_BASE_HPP_ +#include +#include "rive/core/field_types/core_string_type.hpp" +#include "rive/data_bind/bindable_property.hpp" +namespace rive +{ +class BindablePropertyStringBase : public BindableProperty +{ +protected: + typedef BindableProperty Super; + +public: + static const uint16_t typeKey = 471; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case BindablePropertyStringBase::typeKey: + case BindablePropertyBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyValuePropertyKey = 635; + +private: + std::string m_PropertyValue = ""; + +public: + inline const std::string& propertyValue() const { return m_PropertyValue; } + void propertyValue(std::string value) + { + if (m_PropertyValue == value) + { + return; + } + m_PropertyValue = value; + propertyValueChanged(); + } + + Core* clone() const override; + void copy(const BindablePropertyStringBase& object) + { + m_PropertyValue = object.m_PropertyValue; + BindableProperty::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyValuePropertyKey: + m_PropertyValue = CoreStringType::deserialize(reader); + return true; + } + return BindableProperty::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/data_bind_base.hpp b/include/rive/generated/data_bind/data_bind_base.hpp index 4c73ffc4..b900663f 100644 --- a/include/rive/generated/data_bind/data_bind_base.hpp +++ b/include/rive/generated/data_bind/data_bind_base.hpp @@ -1,13 +1,13 @@ #ifndef _RIVE_DATA_BIND_BASE_HPP_ #define _RIVE_DATA_BIND_BASE_HPP_ -#include "rive/component.hpp" +#include "rive/core.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { -class DataBindBase : public Component +class DataBindBase : public Core { protected: - typedef Component Super; + typedef Core Super; public: static const uint16_t typeKey = 446; @@ -19,7 +19,6 @@ class DataBindBase : public Component switch (typeKey) { case DataBindBase::typeKey: - case ComponentBase::typeKey: return true; default: return false; @@ -28,27 +27,14 @@ class DataBindBase : public Component uint16_t coreType() const override { return typeKey; } - static const uint16_t targetIdPropertyKey = 585; static const uint16_t propertyKeyPropertyKey = 586; static const uint16_t flagsPropertyKey = 587; private: - uint32_t m_TargetId = -1; uint32_t m_PropertyKey = Core::invalidPropertyKey; uint32_t m_Flags = 0; public: - inline uint32_t targetId() const { return m_TargetId; } - void targetId(uint32_t value) - { - if (m_TargetId == value) - { - return; - } - m_TargetId = value; - targetIdChanged(); - } - inline uint32_t propertyKey() const { return m_PropertyKey; } void propertyKey(uint32_t value) { @@ -74,19 +60,14 @@ class DataBindBase : public Component Core* clone() const override; void copy(const DataBindBase& object) { - m_TargetId = object.m_TargetId; m_PropertyKey = object.m_PropertyKey; m_Flags = object.m_Flags; - Component::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { switch (propertyKey) { - case targetIdPropertyKey: - m_TargetId = CoreUintType::deserialize(reader); - return true; case propertyKeyPropertyKey: m_PropertyKey = CoreUintType::deserialize(reader); return true; @@ -94,11 +75,10 @@ class DataBindBase : public Component m_Flags = CoreUintType::deserialize(reader); return true; } - return Component::deserialize(propertyKey, reader); + return false; } protected: - virtual void targetIdChanged() {} virtual void propertyKeyChanged() {} virtual void flagsChanged() {} }; diff --git a/include/rive/generated/data_bind/data_bind_context_base.hpp b/include/rive/generated/data_bind/data_bind_context_base.hpp index d1871d46..e8b772ac 100644 --- a/include/rive/generated/data_bind/data_bind_context_base.hpp +++ b/include/rive/generated/data_bind/data_bind_context_base.hpp @@ -21,7 +21,6 @@ class DataBindContextBase : public DataBind { case DataBindContextBase::typeKey: case DataBindBase::typeKey: - case ComponentBase::typeKey: return true; default: return false; diff --git a/include/rive/importers/artboard_importer.hpp b/include/rive/importers/artboard_importer.hpp index 1525803c..102bfd02 100644 --- a/include/rive/importers/artboard_importer.hpp +++ b/include/rive/importers/artboard_importer.hpp @@ -11,6 +11,7 @@ class LinearAnimation; class StateMachine; class TextValueRun; class Event; +class DataBind; class ArtboardImporter : public ImportStackObject { private: @@ -21,6 +22,7 @@ class ArtboardImporter : public ImportStackObject void addComponent(Core* object); void addAnimation(LinearAnimation* animation); void addStateMachine(StateMachine* stateMachine); + void addDataBind(DataBind* dataBind); StatusCode resolve() override; const Artboard* artboard() const { return m_Artboard; } diff --git a/include/rive/importers/bindable_property_importer.hpp b/include/rive/importers/bindable_property_importer.hpp new file mode 100644 index 00000000..002ebe7f --- /dev/null +++ b/include/rive/importers/bindable_property_importer.hpp @@ -0,0 +1,20 @@ +#ifndef _RIVE_BINDABLE_PROPERTY_IMPORTER_HPP_ +#define _RIVE_BINDABLE_PROPERTY_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class Core; +class BindableProperty; +class BindablePropertyImporter : public ImportStackObject +{ +private: + BindableProperty* m_bindableProperty; + +public: + BindablePropertyImporter(BindableProperty* bindableProperty); + BindableProperty* bindableProperty() { return m_bindableProperty; } +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/importers/state_machine_importer.hpp b/include/rive/importers/state_machine_importer.hpp index f00ae454..dc082365 100644 --- a/include/rive/importers/state_machine_importer.hpp +++ b/include/rive/importers/state_machine_importer.hpp @@ -9,6 +9,7 @@ class StateMachineInput; class StateMachineLayer; class StateMachineListener; class StateMachine; +class DataBind; class StateMachineImporter : public ImportStackObject { private: @@ -21,6 +22,7 @@ class StateMachineImporter : public ImportStackObject void addLayer(std::unique_ptr); void addInput(std::unique_ptr); void addListener(std::unique_ptr); + void addDataBind(std::unique_ptr); StatusCode resolve() override; bool readNullObject() override; diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index 9f57ec43..57598156 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp @@ -2,6 +2,8 @@ #define _RIVE_NESTED_ARTBOARD_HPP_ #include "rive/generated/nested_artboard_base.hpp" +#include "rive/data_bind/data_context.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/hit_info.hpp" #include "rive/span.hpp" #include @@ -97,6 +99,8 @@ class NestedArtboard : public NestedArtboardBase void decodeDataBindPathIds(Span value) override; void copyDataBindPathIds(const NestedArtboardBase& object) override; std::vector dataBindPathIds() { return m_DataBindPathIdsBuffer; }; + void dataContextFromInstance(ViewModelInstance* viewModelInstance, DataContext* parent); + void internalDataContext(DataContext* dataContext, DataContext* parent); }; } // namespace rive diff --git a/include/rive/scene.hpp b/include/rive/scene.hpp index fd96d8e9..7d36204d 100644 --- a/include/rive/scene.hpp +++ b/include/rive/scene.hpp @@ -13,6 +13,7 @@ namespace rive { class ArtboardInstance; class Renderer; +class ViewModelInstance; class SMIInput; class SMIBool; @@ -47,6 +48,8 @@ class Scene : public KeyedCallbackReporter, public CallbackContext void draw(Renderer*); + virtual void dataContextFromInstance(ViewModelInstance* viewModelInstance); + virtual HitResult pointerDown(Vec2D); virtual HitResult pointerMove(Vec2D); virtual HitResult pointerUp(Vec2D); diff --git a/src/animation/nested_state_machine.cpp b/src/animation/nested_state_machine.cpp index 6045b56c..81767572 100644 --- a/src/animation/nested_state_machine.cpp +++ b/src/animation/nested_state_machine.cpp @@ -107,4 +107,20 @@ NestedInput* NestedStateMachine::input(std::string name) return nullptr; } -void NestedStateMachine::addNestedInput(NestedInput* input) { m_nestedInputs.push_back(input); } \ No newline at end of file +void NestedStateMachine::addNestedInput(NestedInput* input) { m_nestedInputs.push_back(input); } + +void NestedStateMachine::dataContextFromInstance(ViewModelInstance* viewModelInstance) +{ + if (m_StateMachineInstance != nullptr) + { + m_StateMachineInstance->dataContextFromInstance(viewModelInstance); + } +} + +void NestedStateMachine::dataContext(DataContext* dataContext) +{ + if (m_StateMachineInstance != nullptr) + { + m_StateMachineInstance->dataContext(dataContext); + } +} \ No newline at end of file diff --git a/src/animation/state_machine.cpp b/src/animation/state_machine.cpp index 04506913..9b44672b 100644 --- a/src/animation/state_machine.cpp +++ b/src/animation/state_machine.cpp @@ -91,6 +91,11 @@ void StateMachine::addListener(std::unique_ptr listener) m_Listeners.push_back(std::move(listener)); } +void StateMachine::addDataBind(std::unique_ptr dataBind) +{ + m_dataBinds.push_back(std::move(dataBind)); +} + const StateMachineInput* StateMachine::input(std::string name) const { for (auto& input : m_Inputs) @@ -140,4 +145,13 @@ const StateMachineListener* StateMachine::listener(size_t index) const return m_Listeners[index].get(); } return nullptr; +} + +const DataBind* StateMachine::dataBind(size_t index) const +{ + if (index < m_dataBinds.size()) + { + return m_dataBinds[index].get(); + } + return nullptr; } \ No newline at end of file diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 90bafbc3..274ea78f 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -904,6 +904,23 @@ SMITrigger* StateMachineInstance::getTrigger(const std::string& name) const return getNamedInput(name); } +void StateMachineInstance::dataContextFromInstance(ViewModelInstance* viewModelInstance) +{ + dataContext(new DataContext(viewModelInstance)); +} + +void StateMachineInstance::dataContext(DataContext* dataContext) +{ + m_DataContext = dataContext; + for (auto dataBind : m_dataBinds) + { + if (dataBind->is()) + { + dataBind->as()->bindFromContext(dataContext); + } + } +} + size_t StateMachineInstance::stateChangedCount() const { size_t count = 0; @@ -1039,4 +1056,14 @@ void StateMachineInstance::notifyEventListeners(const std::vector& } } } +} + +BindableProperty* StateMachineInstance::bindablePropertyInstance(BindableProperty* bindableProperty) +{ + auto bindablePropertyInstance = m_bindablePropertyInstances.find(bindableProperty); + if (bindablePropertyInstance == m_bindablePropertyInstances.end()) + { + return nullptr; + } + return bindablePropertyInstance->second; } \ No newline at end of file diff --git a/src/artboard.cpp b/src/artboard.cpp index 47c5d045..3a0b299d 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -173,9 +173,6 @@ StatusCode Artboard::initialize() case NestedArtboardBase::typeKey: m_NestedArtboards.push_back(object->as()); break; - case DataBindContext::typeKey: - m_DataBinds.push_back(object->as()); - break; case JoystickBase::typeKey: { @@ -515,12 +512,12 @@ void Artboard::updateDataBinds() for (auto dataBind : m_AllDataBinds) { dataBind->updateSourceBinding(); - auto d = dataBind->m_Dirt; + auto d = dataBind->dirt(); if (d == ComponentDirt::None) { continue; } - dataBind->m_Dirt = ComponentDirt::None; + dataBind->dirt(ComponentDirt::None); dataBind->update(d); } } @@ -1004,102 +1001,38 @@ void Artboard::internalDataContext(DataContext* value, DataContext* parent, bool auto value = m_DataContext->getViewModelInstance(nestedArtboard->dataBindPathIds()); if (value != nullptr && value->is()) { - nestedArtboard->artboard()->dataContextFromInstance(value, m_DataContext, false); + nestedArtboard->dataContextFromInstance(value, m_DataContext); } else { - nestedArtboard->artboard()->internalDataContext(m_DataContext, - m_DataContext->parent(), - false); + nestedArtboard->internalDataContext(m_DataContext, m_DataContext->parent()); } } for (auto dataBind : m_DataBinds) { if (dataBind->is()) { - dataBind->as()->bind(); + dataBind->as()->bindFromContext(m_DataContext); } } if (isRoot) { - std::vector dataBinds; + std::vector dataBinds; populateDataBinds(&dataBinds); - buildDataBindDependencies(&dataBinds); sortDataBinds(dataBinds); } } -void Artboard::sortDataBinds(std::vector dataBinds) +void Artboard::sortDataBinds(std::vector dataBinds) { - DependencySorter sorter; // TODO: @hernan review this. Should not need to push to a component list to sort. - std::vector dbOrder; - sorter.sort(dataBinds, dbOrder); - for (auto dataBind : dbOrder) + for (auto dataBind : dataBinds) { m_AllDataBinds.push_back(dataBind->as()); } } -void Artboard::buildDataBindDependencies(std::vector* dataBinds) -{ - // TODO: @hernan review this dependency building - // Do we really need this? If a property is bound to a data bind, it can't be bound - // to a second data bind object. - for (auto component : *dataBinds) - { - auto dataBind = component->as(); - auto flags = static_cast(dataBind->flags()); - // If the data bind reads from the target, we want to add it as dependent from any other - // parent data bind that writes into that target. - if (((flags & DataBindFlags::Direction) == DataBindFlags::ToSource) || - ((flags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) - { - for (auto innerComponent : *dataBinds) - { - auto dataBindParent = innerComponent->as(); - auto parentFlags = static_cast(dataBindParent->flags()); - if (dataBindParent != dataBind && - (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToTarget) || - ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) && - dataBindParent->target() == dataBind->target() && - dataBindParent->propertyKey() == dataBind->propertyKey()) - { - dataBindParent->addDependent(dataBind); - break; - } - } - } - else - { - // If the data bind reads from a source we want to add it as dependent - // from any other parent data bind that writes into that source. - if (dataBind->is()) - { - for (auto innerComponent : *dataBinds) - { - auto dataBindParent = innerComponent->as(); - if (dataBindParent != dataBind) - { - auto parentFlags = static_cast(dataBindParent->flags()); - if (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToSource) || - ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) - { - if (dataBindParent->is() && - dataBindParent->as()->source() == - dataBind->as()->source()) - { - dataBindParent->addDependent(dataBind); - break; - } - } - } - } - } - } - } -} float Artboard::volume() const { return m_volume; } void Artboard::volume(float value) { @@ -1114,7 +1047,7 @@ void Artboard::volume(float value) } } -void Artboard::populateDataBinds(std::vector* dataBinds) +void Artboard::populateDataBinds(std::vector* dataBinds) { for (auto dataBind : m_DataBinds) { @@ -1129,6 +1062,8 @@ void Artboard::populateDataBinds(std::vector* dataBinds) } } +void Artboard::addDataBind(DataBind* dataBind) { m_DataBinds.push_back(dataBind); } + void Artboard::dataContext(DataContext* value, DataContext* parent) { internalDataContext(value, parent, true); diff --git a/src/data_bind/context/context_value_boolean.cpp b/src/data_bind/context/context_value_boolean.cpp index 3116aa90..b7b708b0 100644 --- a/src/data_bind/context/context_value_boolean.cpp +++ b/src/data_bind/context/context_value_boolean.cpp @@ -6,16 +6,17 @@ using namespace rive; DataBindContextValueBoolean::DataBindContextValueBoolean(ViewModelInstanceValue* value) { m_Source = value; + m_Value = m_Source->as()->propertyValue(); } -void DataBindContextValueBoolean::apply(Component* target, uint32_t propertyKey) +void DataBindContextValueBoolean::apply(Core* target, uint32_t propertyKey) { CoreRegistry::setBool(target, propertyKey, m_Source->as()->propertyValue()); } -void DataBindContextValueBoolean::applyToSource(Component* target, uint32_t propertyKey) +void DataBindContextValueBoolean::applyToSource(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getBool(target, propertyKey); if (m_Value != value) diff --git a/src/data_bind/context/context_value_color.cpp b/src/data_bind/context/context_value_color.cpp index 18d392f2..44a18575 100644 --- a/src/data_bind/context/context_value_color.cpp +++ b/src/data_bind/context/context_value_color.cpp @@ -6,16 +6,17 @@ using namespace rive; DataBindContextValueColor::DataBindContextValueColor(ViewModelInstanceValue* value) { m_Source = value; + m_Value = m_Source->as()->propertyValue(); } -void DataBindContextValueColor::apply(Component* target, uint32_t propertyKey) +void DataBindContextValueColor::apply(Core* target, uint32_t propertyKey) { CoreRegistry::setColor(target, propertyKey, m_Source->as()->propertyValue()); } -void DataBindContextValueColor::applyToSource(Component* target, uint32_t propertyKey) +void DataBindContextValueColor::applyToSource(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getColor(target, propertyKey); if (m_Value != value) diff --git a/src/data_bind/context/context_value_enum.cpp b/src/data_bind/context/context_value_enum.cpp index 8569ce9b..a0064bc7 100644 --- a/src/data_bind/context/context_value_enum.cpp +++ b/src/data_bind/context/context_value_enum.cpp @@ -6,17 +6,23 @@ using namespace rive; DataBindContextValueEnum::DataBindContextValueEnum(ViewModelInstanceValue* value) { m_Source = value; + m_Value = m_Source->as()->propertyValue(); } -void DataBindContextValueEnum::apply(Component* target, uint32_t propertyKey) +void DataBindContextValueEnum::apply(Core* target, uint32_t propertyKey) { auto enumSource = m_Source->as(); auto enumProperty = enumSource->viewModelProperty()->as(); auto enumValue = enumProperty->value(m_Source->as()->propertyValue()); + // TODO: @hernan decide which one makes more sense. Probably setUint, but setString was used to + // update text input with enum values. CoreRegistry::setString(target, propertyKey, enumValue); + CoreRegistry::setUint(target, + propertyKey, + m_Source->as()->propertyValue()); } -void DataBindContextValueEnum::applyToSource(Component* target, uint32_t propertyKey) +void DataBindContextValueEnum::applyToSource(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getString(target, propertyKey); auto enumSource = m_Source->as(); diff --git a/src/data_bind/context/context_value_list.cpp b/src/data_bind/context/context_value_list.cpp index 59f0f55d..f0aa427e 100644 --- a/src/data_bind/context/context_value_list.cpp +++ b/src/data_bind/context/context_value_list.cpp @@ -40,12 +40,12 @@ std::unique_ptr DataBindContextValueList::createStateMachi return nullptr; } -void DataBindContextValueList::insertItem(Component* target, +void DataBindContextValueList::insertItem(Core* target, ViewModelInstanceListItem* listItem, int index) { auto artboard = listItem->artboard(); - auto artboardCopy = createArtboard(target, artboard, listItem); + auto artboardCopy = createArtboard(target->as(), artboard, listItem); auto stateMachineInstance = createStateMachineInstance(artboardCopy.get()); std::unique_ptr cacheListItem = rivestd::make_unique(std::move(artboardCopy), @@ -61,14 +61,14 @@ void DataBindContextValueList::insertItem(Component* target, } } -void DataBindContextValueList::swapItems(Component* target, int index1, int index2) +void DataBindContextValueList::swapItems(Core* target, int index1, int index2) { std::iter_swap(m_ListItemsCache.begin() + index1, m_ListItemsCache.begin() + index2); } -void DataBindContextValueList::popItem(Component* target) { m_ListItemsCache.pop_back(); } +void DataBindContextValueList::popItem(Core* target) { m_ListItemsCache.pop_back(); } -void DataBindContextValueList::update(Component* target) +void DataBindContextValueList::update(Core* target) { if (target != nullptr) { @@ -125,9 +125,9 @@ void DataBindContextValueList::update(Component* target) } } -void DataBindContextValueList::apply(Component* target, uint32_t propertyKey) {} +void DataBindContextValueList::apply(Core* target, uint32_t propertyKey) {} -void DataBindContextValueList::applyToSource(Component* target, uint32_t propertyKey) +void DataBindContextValueList::applyToSource(Core* target, uint32_t propertyKey) { // TODO: @hernan does applyToSource make sense? Should we block it somehow? } \ No newline at end of file diff --git a/src/data_bind/context/context_value_number.cpp b/src/data_bind/context/context_value_number.cpp index ecc5b7f9..63fabf8e 100644 --- a/src/data_bind/context/context_value_number.cpp +++ b/src/data_bind/context/context_value_number.cpp @@ -6,16 +6,17 @@ using namespace rive; DataBindContextValueNumber::DataBindContextValueNumber(ViewModelInstanceValue* value) { m_Source = value; + m_Value = m_Source->as()->propertyValue(); } -void DataBindContextValueNumber::apply(Component* target, uint32_t propertyKey) +void DataBindContextValueNumber::apply(Core* target, uint32_t propertyKey) { CoreRegistry::setDouble(target, propertyKey, m_Source->as()->propertyValue()); } -void DataBindContextValueNumber::applyToSource(Component* target, uint32_t propertyKey) +void DataBindContextValueNumber::applyToSource(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getDouble(target, propertyKey); if (m_Value != value) diff --git a/src/data_bind/context/context_value_string.cpp b/src/data_bind/context/context_value_string.cpp index 6a62e753..9cf19f7f 100644 --- a/src/data_bind/context/context_value_string.cpp +++ b/src/data_bind/context/context_value_string.cpp @@ -6,16 +6,17 @@ using namespace rive; DataBindContextValueString::DataBindContextValueString(ViewModelInstanceValue* value) { m_Source = value; + m_Value = m_Source->as()->propertyValue(); } -void DataBindContextValueString::apply(Component* target, uint32_t propertyKey) +void DataBindContextValueString::apply(Core* target, uint32_t propertyKey) { CoreRegistry::setString(target, propertyKey, m_Source->as()->propertyValue()); } -void DataBindContextValueString::applyToSource(Component* target, uint32_t propertyKey) +void DataBindContextValueString::applyToSource(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getString(target, propertyKey); if (m_Value != value) diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp index adfa2764..a1ab7151 100644 --- a/src/data_bind/data_bind.cpp +++ b/src/data_bind/data_bind.cpp @@ -2,6 +2,11 @@ #include "rive/artboard.hpp" #include "rive/data_bind_flags.hpp" #include "rive/generated/core_registry.hpp" +#include "rive/data_bind/bindable_property_number.hpp" +#include "rive/data_bind/bindable_property_string.hpp" +#include "rive/data_bind/bindable_property_color.hpp" +#include "rive/data_bind/bindable_property_enum.hpp" +#include "rive/data_bind/bindable_property_boolean.hpp" #include "rive/data_bind/context/context_value.hpp" #include "rive/data_bind/context/context_value_boolean.hpp" #include "rive/data_bind/context/context_value_number.hpp" @@ -9,14 +14,12 @@ #include "rive/data_bind/context/context_value_enum.hpp" #include "rive/data_bind/context/context_value_list.hpp" #include "rive/data_bind/context/context_value_color.hpp" +#include "rive/animation/state_machine.hpp" +#include "rive/importers/artboard_importer.hpp" +#include "rive/importers/state_machine_importer.hpp" using namespace rive; -// StatusCode DataBind::onAddedClean(CoreContext* context) -// { -// return Super::onAddedClean(context); -// } - StatusCode DataBind::onAddedDirty(CoreContext* context) { StatusCode code = Super::onAddedDirty(context); @@ -24,28 +27,44 @@ StatusCode DataBind::onAddedDirty(CoreContext* context) { return code; } - auto coreObject = context->resolve(targetId()); - if (coreObject == nullptr || !coreObject->is()) - { - return StatusCode::MissingObject; - } - - m_target = static_cast(coreObject); return StatusCode::Ok; } -StatusCode DataBind::import(ImportStack& importStack) { return Super::import(importStack); } - -void DataBind::buildDependencies() +StatusCode DataBind::import(ImportStack& importStack) { - Super::buildDependencies(); - auto flagsValue = static_cast(flags()); - if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) || - ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) + if (target()) { - m_target->addDependent(this); + switch (target()->coreType()) + { + case BindablePropertyNumberBase::typeKey: + case BindablePropertyStringBase::typeKey: + case BindablePropertyBooleanBase::typeKey: + case BindablePropertyEnumBase::typeKey: + case BindablePropertyColorBase::typeKey: + { + auto stateMachineImporter = + importStack.latest(StateMachineBase::typeKey); + if (stateMachineImporter != nullptr) + { + stateMachineImporter->addDataBind(std::unique_ptr(this)); + return Super::import(importStack); + } + break; + } + default: + { + auto artboardImporter = importStack.latest(ArtboardBase::typeKey); + if (artboardImporter != nullptr) + { + artboardImporter->addDataBind(this); + return Super::import(importStack); + } + break; + } + } } + return Super::import(importStack); } void DataBind::bind() @@ -97,7 +116,6 @@ void DataBind::update(ComponentDirt value) } } } - Super::update(value); } void DataBind::updateSourceBinding() @@ -111,4 +129,16 @@ void DataBind::updateSourceBinding() m_ContextValue->applyToSource(m_target, propertyKey()); } } +} + +bool DataBind::addDirt(ComponentDirt value, bool recurse) +{ + if ((m_Dirt & value) == value) + { + // Already marked. + return false; + } + + m_Dirt |= value; + return true; } \ No newline at end of file diff --git a/src/data_bind/data_bind_context.cpp b/src/data_bind/data_bind_context.cpp index 4bb86f61..62eae73f 100644 --- a/src/data_bind/data_bind_context.cpp +++ b/src/data_bind/data_bind_context.cpp @@ -26,9 +26,8 @@ void DataBindContext::copySourcePathIds(const DataBindContextBase& object) m_SourcePathIdsBuffer = object.as()->m_SourcePathIdsBuffer; } -void DataBindContext::bind() +void DataBindContext::bindFromContext(DataContext* dataContext) { - auto dataContext = artboard()->dataContext(); if (dataContext != nullptr) { auto value = dataContext->getViewModelProperty(m_SourcePathIdsBuffer); @@ -36,7 +35,7 @@ void DataBindContext::bind() { value->addDependent(this); m_Source = value; - Super::bind(); + bind(); } } } \ No newline at end of file diff --git a/src/file.cpp b/src/file.cpp index 93bdf042..57fb4a72 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -8,6 +8,7 @@ #include "rive/generated/core_registry.hpp" #include "rive/importers/artboard_importer.hpp" #include "rive/importers/backboard_importer.hpp" +#include "rive/importers/bindable_property_importer.hpp" #include "rive/importers/enum_importer.hpp" #include "rive/importers/file_asset_importer.hpp" #include "rive/importers/import_stack.hpp" @@ -30,6 +31,12 @@ #include "rive/animation/animation_state.hpp" #include "rive/animation/blend_state_1d.hpp" #include "rive/animation/blend_state_direct.hpp" +#include "rive/data_bind/bindable_property.hpp" +#include "rive/data_bind/bindable_property_number.hpp" +#include "rive/data_bind/bindable_property_string.hpp" +#include "rive/data_bind/bindable_property_color.hpp" +#include "rive/data_bind/bindable_property_enum.hpp" +#include "rive/data_bind/bindable_property_boolean.hpp" #include "rive/assets/file_asset.hpp" #include "rive/assets/audio_asset.hpp" #include "rive/assets/file_asset_contents.hpp" @@ -204,6 +211,10 @@ std::unique_ptr File::import(Span bytes, ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) { ImportStack importStack; + // TODO: @hernan consider moving this to a special importer. It's not that + // simple because Core doesn't have a typeKey, so it should be treated as + // a special case. In any case, it's not that bad having it here for now. + Core* lastBindableObject; while (!reader.reachedEnd()) { auto object = readRuntimeObject(reader, header); @@ -212,6 +223,14 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) importStack.readNullObject(); continue; } + if (!object->is()) + { + lastBindableObject = object; + } + else if (lastBindableObject != nullptr) + { + object->as()->target(lastBindableObject); + } if (object->import(importStack) == StatusCode::Ok) { switch (object->coreType()) @@ -353,6 +372,15 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) object->as()); stackType = ViewModelInstanceList::typeKey; break; + case BindablePropertyNumber::typeKey: + case BindablePropertyString::typeKey: + case BindablePropertyColor::typeKey: + case BindablePropertyEnum::typeKey: + case BindablePropertyBoolean::typeKey: + stackObject = + rivestd::make_unique(object->as()); + stackType = BindablePropertyBase::typeKey; + break; } if (importStack.makeLatest(stackType, std::move(stackObject)) != StatusCode::Ok) { diff --git a/src/generated/data_bind/bindable_property_boolean_base.cpp b/src/generated/data_bind/bindable_property_boolean_base.cpp new file mode 100644 index 00000000..4e3dcc20 --- /dev/null +++ b/src/generated/data_bind/bindable_property_boolean_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_boolean_base.hpp" +#include "rive/data_bind/bindable_property_boolean.hpp" + +using namespace rive; + +Core* BindablePropertyBooleanBase::clone() const +{ + auto cloned = new BindablePropertyBoolean(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/bindable_property_color_base.cpp b/src/generated/data_bind/bindable_property_color_base.cpp new file mode 100644 index 00000000..fa64a071 --- /dev/null +++ b/src/generated/data_bind/bindable_property_color_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_color_base.hpp" +#include "rive/data_bind/bindable_property_color.hpp" + +using namespace rive; + +Core* BindablePropertyColorBase::clone() const +{ + auto cloned = new BindablePropertyColor(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/bindable_property_enum_base.cpp b/src/generated/data_bind/bindable_property_enum_base.cpp new file mode 100644 index 00000000..acd5be69 --- /dev/null +++ b/src/generated/data_bind/bindable_property_enum_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_enum_base.hpp" +#include "rive/data_bind/bindable_property_enum.hpp" + +using namespace rive; + +Core* BindablePropertyEnumBase::clone() const +{ + auto cloned = new BindablePropertyEnum(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/bindable_property_number_base.cpp b/src/generated/data_bind/bindable_property_number_base.cpp new file mode 100644 index 00000000..95b0453f --- /dev/null +++ b/src/generated/data_bind/bindable_property_number_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_number_base.hpp" +#include "rive/data_bind/bindable_property_number.hpp" + +using namespace rive; + +Core* BindablePropertyNumberBase::clone() const +{ + auto cloned = new BindablePropertyNumber(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/bindable_property_string_base.cpp b/src/generated/data_bind/bindable_property_string_base.cpp new file mode 100644 index 00000000..04133c7b --- /dev/null +++ b/src/generated/data_bind/bindable_property_string_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/bindable_property_string_base.hpp" +#include "rive/data_bind/bindable_property_string.hpp" + +using namespace rive; + +Core* BindablePropertyStringBase::clone() const +{ + auto cloned = new BindablePropertyString(); + cloned->copy(*this); + return cloned; +} diff --git a/src/importers/artboard_importer.cpp b/src/importers/artboard_importer.cpp index d0d93df2..f2957b01 100644 --- a/src/importers/artboard_importer.cpp +++ b/src/importers/artboard_importer.cpp @@ -2,6 +2,7 @@ #include "rive/importers/artboard_importer.hpp" #include "rive/animation/linear_animation.hpp" #include "rive/animation/state_machine.hpp" +#include "rive/data_bind/data_bind.hpp" #include "rive/text/text_value_run.hpp" #include "rive/event.hpp" #include "rive/artboard.hpp" @@ -22,6 +23,8 @@ void ArtboardImporter::addStateMachine(StateMachine* stateMachine) m_Artboard->addStateMachine(stateMachine); } +void ArtboardImporter::addDataBind(DataBind* dataBind) { m_Artboard->addDataBind(dataBind); } + StatusCode ArtboardImporter::resolve() { return m_Artboard->initialize(); } bool ArtboardImporter::readNullObject() diff --git a/src/importers/bindable_property_importer.cpp b/src/importers/bindable_property_importer.cpp new file mode 100644 index 00000000..1d992afc --- /dev/null +++ b/src/importers/bindable_property_importer.cpp @@ -0,0 +1,9 @@ +#include "rive/artboard.hpp" +#include "rive/importers/bindable_property_importer.hpp" +#include "rive/data_bind/bindable_property.hpp" + +using namespace rive; + +BindablePropertyImporter::BindablePropertyImporter(BindableProperty* bindableProperty) : + m_bindableProperty(bindableProperty) +{} \ No newline at end of file diff --git a/src/importers/state_machine_importer.cpp b/src/importers/state_machine_importer.cpp index 7994c37b..70a39858 100644 --- a/src/importers/state_machine_importer.cpp +++ b/src/importers/state_machine_importer.cpp @@ -3,6 +3,7 @@ #include "rive/animation/state_machine_listener.hpp" #include "rive/animation/state_machine_input.hpp" #include "rive/animation/state_machine_layer.hpp" +#include "rive/data_bind/data_bind.hpp" using namespace rive; @@ -23,6 +24,11 @@ void StateMachineImporter::addListener(std::unique_ptr lis m_StateMachine->addListener(std::move(listener)); } +void StateMachineImporter::addDataBind(std::unique_ptr dataBind) +{ + m_StateMachine->addDataBind(std::move(dataBind)); +} + bool StateMachineImporter::readNullObject() { // Hard assumption that we won't add new layer types... diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 6ef8cf36..19437dce 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -273,4 +273,29 @@ void NestedArtboard::decodeDataBindPathIds(Span value) void NestedArtboard::copyDataBindPathIds(const NestedArtboardBase& object) { m_DataBindPathIdsBuffer = object.as()->m_DataBindPathIdsBuffer; +} + +void NestedArtboard::internalDataContext(DataContext* value, DataContext* parent) +{ + artboard()->internalDataContext(value, parent, false); + for (auto animation : m_NestedAnimations) + { + if (animation->is()) + { + animation->as()->dataContext(value); + } + } +} + +void NestedArtboard::dataContextFromInstance(ViewModelInstance* viewModelInstance, + DataContext* parent) +{ + artboard()->dataContextFromInstance(viewModelInstance, parent, false); + for (auto animation : m_NestedAnimations) + { + if (animation->is()) + { + animation->as()->dataContextFromInstance(viewModelInstance); + } + } } \ No newline at end of file diff --git a/src/scene.cpp b/src/scene.cpp index a987dfec..679f33e2 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -25,6 +25,7 @@ SMIInput* Scene::input(size_t index) const { return nullptr; } SMIBool* Scene::getBool(const std::string&) const { return nullptr; } SMINumber* Scene::getNumber(const std::string&) const { return nullptr; } SMITrigger* Scene::getTrigger(const std::string&) const { return nullptr; } +void Scene::dataContextFromInstance(ViewModelInstance* viewModelInstance) {} void Scene::reportKeyedCallback(uint32_t objectId, uint32_t propertyKey, float elapsedSeconds) { diff --git a/src/viewmodel/viewmodel_instance_enum.cpp b/src/viewmodel/viewmodel_instance_enum.cpp index 0cdbc603..3b7a7556 100644 --- a/src/viewmodel/viewmodel_instance_enum.cpp +++ b/src/viewmodel/viewmodel_instance_enum.cpp @@ -8,7 +8,7 @@ using namespace rive; -void ViewModelInstanceEnum::propertyValueChanged() { addDirt(ComponentDirt::Components); } +void ViewModelInstanceEnum::propertyValueChanged() { addDirt(ComponentDirt::Bindings); } bool ViewModelInstanceEnum::value(std::string name) { From 93014af4d56bbda0524d1cb35d4d4f68abfd1f33 Mon Sep 17 00:00:00 2001 From: philter Date: Tue, 23 Jul 2024 15:56:13 +0000 Subject: [PATCH 098/138] Layout drawable - [x] Changes LayoutComponent to extend Drawable (implements ShapePaintContainer) - [x] Fixes some API naming conflicts - [x] Adds DrawableProxy to allow inserting custom draw commands into draw order (allows LayoutComponent fills to be drawn below children and strokes to be drawn above - [x] Works with Fill/Stroke inspectors - [x] Adds corner radius core props - [x] Clipping - [x] CPP Updates - [x] Clipping in CPP - [x] Deal with conflicting x/y properties in Node & Artboard (CPP) https://github.com/rive-app/rive/assets/186340/5aec1cd5-6b00-4627-bfce-9cdeec8e3e96 Showing clipping and blend modes / opacity https://github.com/user-attachments/assets/843b6c74-cec0-4333-8ef1-6fee9b910a59 Diffs= 114da4e39 Layout drawable (#7544) Co-authored-by: Philip Chung --- .rive_head | 2 +- dev/core_generator/lib/src/definition.dart | 23 +++ dev/core_generator/lib/src/key.dart | 31 +++- dev/defs/artboard.json | 18 --- dev/defs/layout/layout_component_style.json | 49 +++++++ dev/defs/layout_component.json | 2 +- dev/defs/node.json | 16 +- include/rive/artboard.hpp | 24 +-- include/rive/drawable.hpp | 21 ++- include/rive/generated/artboard_base.hpp | 39 +---- include/rive/generated/core_registry.hpp | 64 ++++++-- .../layout/layout_component_style_base.hpp | 90 ++++++++++++ .../rive/generated/layout_component_base.hpp | 13 +- include/rive/generated/node_base.hpp | 2 + .../rive/layout/layout_component_style.hpp | 9 +- include/rive/layout_component.hpp | 32 +++- include/rive/transform_component.hpp | 5 +- src/artboard.cpp | 67 +++++++-- src/drawable.cpp | 2 +- src/layout/layout_component_style.cpp | 6 +- src/layout_component.cpp | 137 +++++++++++++++--- src/nested_artboard.cpp | 4 +- src/shapes/image.cpp | 2 +- src/shapes/path.cpp | 4 + src/shapes/shape.cpp | 2 +- src/shapes/shape_paint_container.cpp | 3 + src/text/text.cpp | 2 +- src/transform_component.cpp | 4 + test/clip_test.cpp | 6 +- 29 files changed, 538 insertions(+), 141 deletions(-) diff --git a/.rive_head b/.rive_head index 518b856a..8cbe00c0 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -b5f342002be71c61608ad6c37835349eb4e7c719 +114da4e39ba61dd337e8f6f47c1c7b2fb2223915 diff --git a/dev/core_generator/lib/src/definition.dart b/dev/core_generator/lib/src/definition.dart index 5a04630f..bf94a2b7 100644 --- a/dev/core_generator/lib/src/definition.dart +++ b/dev/core_generator/lib/src/definition.dart @@ -183,6 +183,11 @@ class Definition { for (final property in properties) { code.writeln('static const uint16_t ${property.name}PropertyKey = ' '${property.key!.intValue};'); + for (final altKey in property.key!.alternates) { + code.writeln( + 'static const uint16_t ${altKey.stringValue}PropertyKey = ' + '${altKey.intValue};'); + } } if (storedProperties.any((prop) => !prop.isEncoded)) { code.writeln('private:'); @@ -486,6 +491,12 @@ class Definition { for (final property in properties) { ctxCode.writeln('case ${property.definition.name}Base' '::${property.name}PropertyKey:'); + if (property.key != null) { + for (final altKey in property.key!.alternates) { + ctxCode.writeln('case ${property.definition.name}Base' + '::${altKey.stringValue}PropertyKey:'); + } + } ctxCode.writeln('object->as<${property.definition.name}Base>()->' '${property.name}(value);'); ctxCode.writeln('break;'); @@ -506,6 +517,10 @@ class Definition { for (final property in properties) { ctxCode.writeln('case ${property.definition.name}Base' '::${property.name}PropertyKey:'); + for (final altKey in property.key!.alternates) { + ctxCode.writeln('case ${property.definition.name}Base' + '::${altKey.stringValue}PropertyKey:'); + } ctxCode .writeln('return object->as<${property.definition.name}Base>()->' '${property.name}();'); @@ -528,6 +543,10 @@ class Definition { for (final property in properties) { ctxCode.writeln('case ${property.definition.name}Base' '::${property.name}PropertyKey:'); + for (final altKey in property.key!.alternates) { + ctxCode.writeln('case ${property.definition.name}Base' + '::${altKey.stringValue}PropertyKey:'); + } } } ctxCode.writeln('return Core${fieldType.capitalizedName}Type::id;'); @@ -567,6 +586,10 @@ class Definition { for (final property in properties) { ctxCode.writeln('case ${property.definition.name}Base' '::${property.name}PropertyKey:'); + for (final altKey in property.key!.alternates) { + ctxCode.writeln('case ${property.definition.name}Base' + '::${altKey.stringValue}PropertyKey:'); + } ctxCode .writeln('return object->is<${property.definition.name}Base>();'); } diff --git a/dev/core_generator/lib/src/key.dart b/dev/core_generator/lib/src/key.dart index 8e1a8d0d..ca836847 100644 --- a/dev/core_generator/lib/src/key.dart +++ b/dev/core_generator/lib/src/key.dart @@ -4,6 +4,7 @@ import 'property.dart'; class Key { final String? stringValue; final int? intValue; + final List alternates = []; bool get isMissing => intValue == null; @@ -23,12 +24,36 @@ class Key { } dynamic iv = data['int']; dynamic sv = data['string']; + dynamic av = data['alternates']; if (iv is int && sv is String) { - return Key(sv, iv); + final key = Key(sv, iv); + if (av is List) { + for (final a in av) { + if (a is Map) { + dynamic altiv = a['int']; + dynamic altsv = a['string']; + key.alternates.add(Key(altsv, altiv)); + } + } + } + return key; } return null; } - Map serialize() => - {'int': intValue, 'string': stringValue}; + Map serialize() { + final json = {'int': intValue, 'string': stringValue}; + final altsJson = []; + for (final alt in alternates) { + final altJson = { + 'int': alt.intValue, + 'string': alt.stringValue + }; + altsJson.add(altJson); + } + if (altsJson.isNotEmpty) { + json['alternates'] = altsJson; + } + return json; + } } diff --git a/dev/defs/artboard.json b/dev/defs/artboard.json index 4079ccbe..bb527360 100644 --- a/dev/defs/artboard.json +++ b/dev/defs/artboard.json @@ -6,24 +6,6 @@ }, "extends": "layout_component.json", "properties": { - "x": { - "type": "double", - "initialValue": "0", - "key": { - "int": 9, - "string": "x" - }, - "description": "X coordinate in editor world space." - }, - "y": { - "type": "double", - "initialValue": "0", - "key": { - "int": 10, - "string": "y" - }, - "description": "Y coordinate in editor world space." - }, "originX": { "type": "double", "initialValue": "0", diff --git a/dev/defs/layout/layout_component_style.json b/dev/defs/layout/layout_component_style.json index 9bddf110..cb46d463 100644 --- a/dev/defs/layout/layout_component_style.json +++ b/dev/defs/layout/layout_component_style.json @@ -717,6 +717,55 @@ "string": "maxheightunitsvalue" }, "description": "" + }, + "linkCornerRadius": { + "type": "bool", + "initialValue": "true", + "key": { + "int": 639, + "string": "linkcornerradius" + }, + "description": "Whether the TL corner radius defines all the radiuses" + }, + "cornerRadiusTL": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 640, + "string": "cornerradiustl" + }, + "description": "Top left radius of the corners of this layout" + }, + "cornerRadiusTR": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 641, + "string": "cornerradiustr" + }, + "description": "Top right radius of the corners of this layout" + }, + "cornerRadiusBL": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 642, + "string": "cornerradiusbl" + }, + "description": "Bottom left radius of the corners of this layout" + }, + "cornerRadiusBR": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 643, + "string": "cornerradiusbr" + }, + "description": "Bottom right radius of the corners of this layout" } } } \ No newline at end of file diff --git a/dev/defs/layout_component.json b/dev/defs/layout_component.json index ac24d51d..8aca893a 100644 --- a/dev/defs/layout_component.json +++ b/dev/defs/layout_component.json @@ -4,7 +4,7 @@ "int": 409, "string": "layoutcomponent" }, - "extends": "world_transform_component.json", + "extends": "drawable.json", "properties": { "clip": { "type": "bool", diff --git a/dev/defs/node.json b/dev/defs/node.json index f604980a..90ff1820 100644 --- a/dev/defs/node.json +++ b/dev/defs/node.json @@ -14,7 +14,13 @@ "group": "position", "key": { "int": 13, - "string": "x" + "string": "x", + "alternates": [ + { + "int": 9, + "string": "xArtboard" + } + ] } }, "y": { @@ -25,7 +31,13 @@ "group": "position", "key": { "int": 14, - "string": "y" + "string": "y", + "alternates": [ + { + "int": 10, + "string": "yArtboard" + } + ] } }, "styleValue": { diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 9411ceb4..4b7cc3d9 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -13,7 +13,6 @@ #include "rive/hit_info.hpp" #include "rive/math/aabb.hpp" #include "rive/renderer.hpp" -#include "rive/shapes/shape_paint_container.hpp" #include "rive/text/text_value_run.hpp" #include "rive/event.hpp" #include "rive/audio/audio_engine.hpp" @@ -48,7 +47,7 @@ class SMITrigger; typedef void (*ArtboardCallback)(Artboard*); #endif -class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer +class Artboard : public ArtboardBase, public CoreContext { friend class File; friend class ArtboardImporter; @@ -71,8 +70,6 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta unsigned int m_DirtDepth = 0; RawPath m_backgroundRawPath; - rcp m_BackgroundPath; - rcp m_ClipPath; Factory* m_Factory = nullptr; Drawable* m_FirstDrawable = nullptr; bool m_IsInstance = false; @@ -88,8 +85,7 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta void sortDependencies(); void sortDrawOrder(); void updateDataBinds(); - - Artboard* getArtboard() override { return this; } + void performUpdate(ComponentDirt value) override; #ifdef TESTING public: @@ -114,15 +110,20 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta // EXPERIMENTAL -- for internal testing only for now. // DO NOT RELY ON THIS as it may change/disappear in the future. - Core* hitTest(HitInfo*, const Mat2D* = nullptr); + Core* hitTest(HitInfo*, const Mat2D&) override; void onComponentDirty(Component* component); /// Update components that depend on each other in DAG order. bool updateComponents(); - void update(ComponentDirt value) override; void onDirty(ComponentDirt dirt) override; + // Artboards don't update their world transforms in the same way + // as other TransformComponents so we override this. + // This is because LayoutComponent extends Drawable, but + // Artboard is a special type of LayoutComponent + void updateWorldTransform() override {} + void markLayoutDirty(LayoutComponent* layoutComponent) { m_dirtyLayout.insert(layoutComponent); @@ -150,12 +151,13 @@ class Artboard : public ArtboardBase, public CoreContext, public ShapePaintConta kHideBG, kHideFG, }; - void draw(Renderer* renderer, DrawOption = DrawOption::kNormal); + void draw(Renderer* renderer, DrawOption option); + void draw(Renderer* renderer) override; void addToRenderPath(RenderPath* path, const Mat2D& transform); #ifdef TESTING - RenderPath* clipPath() const { return m_ClipPath.get(); } - RenderPath* backgroundPath() const { return m_BackgroundPath.get(); } + RenderPath* clipPath() const { return m_clipPath.get(); } + RenderPath* backgroundPath() const { return m_backgroundPath.get(); } #endif const std::vector& objects() const { return m_Objects; } diff --git a/include/rive/drawable.hpp b/include/rive/drawable.hpp index ca5e9966..b4e79b81 100644 --- a/include/rive/drawable.hpp +++ b/include/rive/drawable.hpp @@ -28,7 +28,7 @@ class Drawable : public DrawableBase public: BlendMode blendMode() const { return (BlendMode)blendModeValue(); } - ClipResult clip(Renderer* renderer) const; + ClipResult applyClip(Renderer* renderer) const; virtual void draw(Renderer* renderer) = 0; virtual Core* hitTest(HitInfo*, const Mat2D&) = 0; void addClippingShape(ClippingShape* shape); @@ -49,6 +49,25 @@ class Drawable : public DrawableBase StatusCode onAddedDirty(CoreContext* context) override; }; + +class ProxyDrawing +{ +public: + virtual void drawProxy(Renderer* renderer) = 0; +}; + +class DrawableProxy : public Drawable +{ +private: + ProxyDrawing* m_proxyDrawing; + +public: + DrawableProxy(ProxyDrawing* proxy) : m_proxyDrawing(proxy) {} + + void draw(Renderer* renderer) override { m_proxyDrawing->drawProxy(renderer); } + + Core* hitTest(HitInfo*, const Mat2D&) override { return nullptr; } +}; } // namespace rive #endif diff --git a/include/rive/generated/artboard_base.hpp b/include/rive/generated/artboard_base.hpp index ff19a02a..b7ae1b94 100644 --- a/include/rive/generated/artboard_base.hpp +++ b/include/rive/generated/artboard_base.hpp @@ -21,6 +21,9 @@ class ArtboardBase : public LayoutComponent { case ArtboardBase::typeKey: case LayoutComponentBase::typeKey: + case DrawableBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: case WorldTransformComponentBase::typeKey: case ContainerComponentBase::typeKey: case ComponentBase::typeKey: @@ -32,44 +35,18 @@ class ArtboardBase : public LayoutComponent uint16_t coreType() const override { return typeKey; } - static const uint16_t xPropertyKey = 9; - static const uint16_t yPropertyKey = 10; static const uint16_t originXPropertyKey = 11; static const uint16_t originYPropertyKey = 12; static const uint16_t defaultStateMachineIdPropertyKey = 236; static const uint16_t viewModelIdPropertyKey = 583; private: - float m_X = 0.0f; - float m_Y = 0.0f; float m_OriginX = 0.0f; float m_OriginY = 0.0f; uint32_t m_DefaultStateMachineId = -1; uint32_t m_ViewModelId = -1; public: - inline float x() const { return m_X; } - void x(float value) - { - if (m_X == value) - { - return; - } - m_X = value; - xChanged(); - } - - inline float y() const { return m_Y; } - void y(float value) - { - if (m_Y == value) - { - return; - } - m_Y = value; - yChanged(); - } - inline float originX() const { return m_OriginX; } void originX(float value) { @@ -117,8 +94,6 @@ class ArtboardBase : public LayoutComponent Core* clone() const override; void copy(const ArtboardBase& object) { - m_X = object.m_X; - m_Y = object.m_Y; m_OriginX = object.m_OriginX; m_OriginY = object.m_OriginY; m_DefaultStateMachineId = object.m_DefaultStateMachineId; @@ -130,12 +105,6 @@ class ArtboardBase : public LayoutComponent { switch (propertyKey) { - case xPropertyKey: - m_X = CoreDoubleType::deserialize(reader); - return true; - case yPropertyKey: - m_Y = CoreDoubleType::deserialize(reader); - return true; case originXPropertyKey: m_OriginX = CoreDoubleType::deserialize(reader); return true; @@ -153,8 +122,6 @@ class ArtboardBase : public LayoutComponent } protected: - virtual void xChanged() {} - virtual void yChanged() {} virtual void originXChanged() {} virtual void originYChanged() {} virtual void defaultStateMachineIdChanged() {} diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 3096b791..abeae9a8 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -516,6 +516,9 @@ class CoreRegistry case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: object->as()->intrinsicallySizedValue(value); break; + case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: + object->as()->linkCornerRadius(value); + break; case NestedSimpleAnimationBase::isPlayingPropertyKey: object->as()->isPlaying(value); break; @@ -1147,9 +1150,11 @@ class CoreRegistry object->as()->scaleY(value); break; case NodeBase::xPropertyKey: + case NodeBase::xArtboardPropertyKey: object->as()->x(value); break; case NodeBase::yPropertyKey: + case NodeBase::yArtboardPropertyKey: object->as()->y(value); break; case LayoutComponentStyleBase::gapHorizontalPropertyKey: @@ -1236,6 +1241,18 @@ class CoreRegistry case LayoutComponentStyleBase::interpolationTimePropertyKey: object->as()->interpolationTime(value); break; + case LayoutComponentStyleBase::cornerRadiusTLPropertyKey: + object->as()->cornerRadiusTL(value); + break; + case LayoutComponentStyleBase::cornerRadiusTRPropertyKey: + object->as()->cornerRadiusTR(value); + break; + case LayoutComponentStyleBase::cornerRadiusBLPropertyKey: + object->as()->cornerRadiusBL(value); + break; + case LayoutComponentStyleBase::cornerRadiusBRPropertyKey: + object->as()->cornerRadiusBR(value); + break; case NestedLinearAnimationBase::mixPropertyKey: object->as()->mix(value); break; @@ -1416,12 +1433,6 @@ class CoreRegistry case LayoutComponentBase::heightPropertyKey: object->as()->height(value); break; - case ArtboardBase::xPropertyKey: - object->as()->x(value); - break; - case ArtboardBase::yPropertyKey: - object->as()->y(value); - break; case ArtboardBase::originXPropertyKey: object->as()->originX(value); break; @@ -1625,6 +1636,8 @@ class CoreRegistry return object->as()->offset(); case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: return object->as()->intrinsicallySizedValue(); + case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: + return object->as()->linkCornerRadius(); case NestedSimpleAnimationBase::isPlayingPropertyKey: return object->as()->isPlaying(); case KeyFrameBoolBase::valuePropertyKey: @@ -2058,8 +2071,10 @@ class CoreRegistry case TransformComponentBase::scaleYPropertyKey: return object->as()->scaleY(); case NodeBase::xPropertyKey: + case NodeBase::xArtboardPropertyKey: return object->as()->x(); case NodeBase::yPropertyKey: + case NodeBase::yArtboardPropertyKey: return object->as()->y(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->as()->gapHorizontal(); @@ -2117,6 +2132,14 @@ class CoreRegistry return object->as()->aspectRatio(); case LayoutComponentStyleBase::interpolationTimePropertyKey: return object->as()->interpolationTime(); + case LayoutComponentStyleBase::cornerRadiusTLPropertyKey: + return object->as()->cornerRadiusTL(); + case LayoutComponentStyleBase::cornerRadiusTRPropertyKey: + return object->as()->cornerRadiusTR(); + case LayoutComponentStyleBase::cornerRadiusBLPropertyKey: + return object->as()->cornerRadiusBL(); + case LayoutComponentStyleBase::cornerRadiusBRPropertyKey: + return object->as()->cornerRadiusBR(); case NestedLinearAnimationBase::mixPropertyKey: return object->as()->mix(); case NestedSimpleAnimationBase::speedPropertyKey: @@ -2237,10 +2260,6 @@ class CoreRegistry return object->as()->width(); case LayoutComponentBase::heightPropertyKey: return object->as()->height(); - case ArtboardBase::xPropertyKey: - return object->as()->x(); - case ArtboardBase::yPropertyKey: - return object->as()->y(); case ArtboardBase::originXPropertyKey: return object->as()->originX(); case ArtboardBase::originYPropertyKey: @@ -2367,6 +2386,7 @@ class CoreRegistry case FollowPathConstraintBase::orientPropertyKey: case FollowPathConstraintBase::offsetPropertyKey: case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: + case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: case NestedSimpleAnimationBase::isPlayingPropertyKey: case KeyFrameBoolBase::valuePropertyKey: case ListenerAlignTargetBase::preserveOffsetPropertyKey: @@ -2574,7 +2594,9 @@ class CoreRegistry case TransformComponentBase::scaleXPropertyKey: case TransformComponentBase::scaleYPropertyKey: case NodeBase::xPropertyKey: + case NodeBase::xArtboardPropertyKey: case NodeBase::yPropertyKey: + case NodeBase::yArtboardPropertyKey: case LayoutComponentStyleBase::gapHorizontalPropertyKey: case LayoutComponentStyleBase::gapVerticalPropertyKey: case LayoutComponentStyleBase::maxWidthPropertyKey: @@ -2603,6 +2625,10 @@ class CoreRegistry case LayoutComponentStyleBase::flexBasisPropertyKey: case LayoutComponentStyleBase::aspectRatioPropertyKey: case LayoutComponentStyleBase::interpolationTimePropertyKey: + case LayoutComponentStyleBase::cornerRadiusTLPropertyKey: + case LayoutComponentStyleBase::cornerRadiusTRPropertyKey: + case LayoutComponentStyleBase::cornerRadiusBLPropertyKey: + case LayoutComponentStyleBase::cornerRadiusBRPropertyKey: case NestedLinearAnimationBase::mixPropertyKey: case NestedSimpleAnimationBase::speedPropertyKey: case AdvanceableStateBase::speedPropertyKey: @@ -2663,8 +2689,6 @@ class CoreRegistry case CubicDetachedVertexBase::outDistancePropertyKey: case LayoutComponentBase::widthPropertyKey: case LayoutComponentBase::heightPropertyKey: - case ArtboardBase::xPropertyKey: - case ArtboardBase::yPropertyKey: case ArtboardBase::originXPropertyKey: case ArtboardBase::originYPropertyKey: case JoystickBase::xPropertyKey: @@ -2770,6 +2794,8 @@ class CoreRegistry return object->is(); case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: return object->is(); + case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: + return object->is(); case NestedSimpleAnimationBase::isPlayingPropertyKey: return object->is(); case KeyFrameBoolBase::valuePropertyKey: @@ -3175,8 +3201,10 @@ class CoreRegistry case TransformComponentBase::scaleYPropertyKey: return object->is(); case NodeBase::xPropertyKey: + case NodeBase::xArtboardPropertyKey: return object->is(); case NodeBase::yPropertyKey: + case NodeBase::yArtboardPropertyKey: return object->is(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->is(); @@ -3234,6 +3262,14 @@ class CoreRegistry return object->is(); case LayoutComponentStyleBase::interpolationTimePropertyKey: return object->is(); + case LayoutComponentStyleBase::cornerRadiusTLPropertyKey: + return object->is(); + case LayoutComponentStyleBase::cornerRadiusTRPropertyKey: + return object->is(); + case LayoutComponentStyleBase::cornerRadiusBLPropertyKey: + return object->is(); + case LayoutComponentStyleBase::cornerRadiusBRPropertyKey: + return object->is(); case NestedLinearAnimationBase::mixPropertyKey: return object->is(); case NestedSimpleAnimationBase::speedPropertyKey: @@ -3354,10 +3390,6 @@ class CoreRegistry return object->is(); case LayoutComponentBase::heightPropertyKey: return object->is(); - case ArtboardBase::xPropertyKey: - return object->is(); - case ArtboardBase::yPropertyKey: - return object->is(); case ArtboardBase::originXPropertyKey: return object->is(); case ArtboardBase::originYPropertyKey: diff --git a/include/rive/generated/layout/layout_component_style_base.hpp b/include/rive/generated/layout/layout_component_style_base.hpp index b62fa973..a6f0cb56 100644 --- a/include/rive/generated/layout/layout_component_style_base.hpp +++ b/include/rive/generated/layout/layout_component_style_base.hpp @@ -98,6 +98,11 @@ class LayoutComponentStyleBase : public Component static const uint16_t minHeightUnitsValuePropertyKey = 628; static const uint16_t maxWidthUnitsValuePropertyKey = 629; static const uint16_t maxHeightUnitsValuePropertyKey = 630; + static const uint16_t linkCornerRadiusPropertyKey = 639; + static const uint16_t cornerRadiusTLPropertyKey = 640; + static const uint16_t cornerRadiusTRPropertyKey = 641; + static const uint16_t cornerRadiusBLPropertyKey = 642; + static const uint16_t cornerRadiusBRPropertyKey = 643; private: float m_GapHorizontal = 0.0f; @@ -168,6 +173,11 @@ class LayoutComponentStyleBase : public Component uint32_t m_MinHeightUnitsValue = 0; uint32_t m_MaxWidthUnitsValue = 0; uint32_t m_MaxHeightUnitsValue = 0; + bool m_LinkCornerRadius = true; + float m_CornerRadiusTL = 0.0f; + float m_CornerRadiusTR = 0.0f; + float m_CornerRadiusBL = 0.0f; + float m_CornerRadiusBR = 0.0f; public: inline float gapHorizontal() const { return m_GapHorizontal; } @@ -918,6 +928,61 @@ class LayoutComponentStyleBase : public Component maxHeightUnitsValueChanged(); } + inline bool linkCornerRadius() const { return m_LinkCornerRadius; } + void linkCornerRadius(bool value) + { + if (m_LinkCornerRadius == value) + { + return; + } + m_LinkCornerRadius = value; + linkCornerRadiusChanged(); + } + + inline float cornerRadiusTL() const { return m_CornerRadiusTL; } + void cornerRadiusTL(float value) + { + if (m_CornerRadiusTL == value) + { + return; + } + m_CornerRadiusTL = value; + cornerRadiusTLChanged(); + } + + inline float cornerRadiusTR() const { return m_CornerRadiusTR; } + void cornerRadiusTR(float value) + { + if (m_CornerRadiusTR == value) + { + return; + } + m_CornerRadiusTR = value; + cornerRadiusTRChanged(); + } + + inline float cornerRadiusBL() const { return m_CornerRadiusBL; } + void cornerRadiusBL(float value) + { + if (m_CornerRadiusBL == value) + { + return; + } + m_CornerRadiusBL = value; + cornerRadiusBLChanged(); + } + + inline float cornerRadiusBR() const { return m_CornerRadiusBR; } + void cornerRadiusBR(float value) + { + if (m_CornerRadiusBR == value) + { + return; + } + m_CornerRadiusBR = value; + cornerRadiusBRChanged(); + } + Core* clone() const override; void copy(const LayoutComponentStyleBase& object) { @@ -989,6 +1054,11 @@ class LayoutComponentStyleBase : public Component m_MinHeightUnitsValue = object.m_MinHeightUnitsValue; m_MaxWidthUnitsValue = object.m_MaxWidthUnitsValue; m_MaxHeightUnitsValue = object.m_MaxHeightUnitsValue; + m_LinkCornerRadius = object.m_LinkCornerRadius; + m_CornerRadiusTL = object.m_CornerRadiusTL; + m_CornerRadiusTR = object.m_CornerRadiusTR; + m_CornerRadiusBL = object.m_CornerRadiusBL; + m_CornerRadiusBR = object.m_CornerRadiusBR; Component::copy(object); } @@ -1200,6 +1270,21 @@ class LayoutComponentStyleBase : public Component case maxHeightUnitsValuePropertyKey: m_MaxHeightUnitsValue = CoreUintType::deserialize(reader); return true; + case linkCornerRadiusPropertyKey: + m_LinkCornerRadius = CoreBoolType::deserialize(reader); + return true; + case cornerRadiusTLPropertyKey: + m_CornerRadiusTL = CoreDoubleType::deserialize(reader); + return true; + case cornerRadiusTRPropertyKey: + m_CornerRadiusTR = CoreDoubleType::deserialize(reader); + return true; + case cornerRadiusBLPropertyKey: + m_CornerRadiusBL = CoreDoubleType::deserialize(reader); + return true; + case cornerRadiusBRPropertyKey: + m_CornerRadiusBR = CoreDoubleType::deserialize(reader); + return true; } return Component::deserialize(propertyKey, reader); } @@ -1273,6 +1358,11 @@ class LayoutComponentStyleBase : public Component virtual void minHeightUnitsValueChanged() {} virtual void maxWidthUnitsValueChanged() {} virtual void maxHeightUnitsValueChanged() {} + virtual void linkCornerRadiusChanged() {} + virtual void cornerRadiusTLChanged() {} + virtual void cornerRadiusTRChanged() {} + virtual void cornerRadiusBLChanged() {} + virtual void cornerRadiusBRChanged() {} }; } // namespace rive diff --git a/include/rive/generated/layout_component_base.hpp b/include/rive/generated/layout_component_base.hpp index e0c508a9..680f0319 100644 --- a/include/rive/generated/layout_component_base.hpp +++ b/include/rive/generated/layout_component_base.hpp @@ -3,13 +3,13 @@ #include "rive/core/field_types/core_bool_type.hpp" #include "rive/core/field_types/core_double_type.hpp" #include "rive/core/field_types/core_uint_type.hpp" -#include "rive/world_transform_component.hpp" +#include "rive/drawable.hpp" namespace rive { -class LayoutComponentBase : public WorldTransformComponent +class LayoutComponentBase : public Drawable { protected: - typedef WorldTransformComponent Super; + typedef Drawable Super; public: static const uint16_t typeKey = 409; @@ -21,6 +21,9 @@ class LayoutComponentBase : public WorldTransformComponent switch (typeKey) { case LayoutComponentBase::typeKey: + case DrawableBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: case WorldTransformComponentBase::typeKey: case ContainerComponentBase::typeKey: case ComponentBase::typeKey: @@ -95,7 +98,7 @@ class LayoutComponentBase : public WorldTransformComponent m_Width = object.m_Width; m_Height = object.m_Height; m_StyleId = object.m_StyleId; - WorldTransformComponent::copy(object); + Drawable::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override @@ -115,7 +118,7 @@ class LayoutComponentBase : public WorldTransformComponent m_StyleId = CoreUintType::deserialize(reader); return true; } - return WorldTransformComponent::deserialize(propertyKey, reader); + return Drawable::deserialize(propertyKey, reader); } protected: diff --git a/include/rive/generated/node_base.hpp b/include/rive/generated/node_base.hpp index f27da202..38c4f60d 100644 --- a/include/rive/generated/node_base.hpp +++ b/include/rive/generated/node_base.hpp @@ -32,7 +32,9 @@ class NodeBase : public TransformComponent uint16_t coreType() const override { return typeKey; } static const uint16_t xPropertyKey = 13; + static const uint16_t xArtboardPropertyKey = 9; static const uint16_t yPropertyKey = 14; + static const uint16_t yArtboardPropertyKey = 10; private: float m_X = 0.0f; diff --git a/include/rive/layout/layout_component_style.hpp b/include/rive/layout/layout_component_style.hpp index 861545d5..63274144 100644 --- a/include/rive/layout/layout_component_style.hpp +++ b/include/rive/layout/layout_component_style.hpp @@ -10,8 +10,8 @@ namespace rive enum class LayoutAnimationStyle : uint8_t { none, - custom, - inherit + inherit, + custom }; enum class LayoutStyleInterpolation : uint8_t @@ -163,6 +163,11 @@ class LayoutComponentStyle : public LayoutComponentStyleBase void positionRightUnitsValueChanged() override; void positionTopUnitsValueChanged() override; void positionBottomUnitsValueChanged() override; + + void cornerRadiusTLChanged() override; + void cornerRadiusTRChanged() override; + void cornerRadiusBLChanged() override; + void cornerRadiusBRChanged() override; }; } // namespace rive diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index c070587b..976544c7 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -1,8 +1,12 @@ #ifndef _RIVE_LAYOUT_COMPONENT_HPP_ #define _RIVE_LAYOUT_COMPONENT_HPP_ +#include "rive/drawable.hpp" #include "rive/generated/layout_component_base.hpp" #include "rive/layout/layout_component_style.hpp" #include "rive/layout/layout_measure_mode.hpp" +#include "rive/math/raw_path.hpp" +#include "rive/shapes/rectangle.hpp" +#include "rive/shapes/shape_paint_container.hpp" #ifdef WITH_RIVE_LAYOUT #include "yoga/YGNode.h" #include "yoga/YGStyle.h" @@ -30,7 +34,7 @@ struct LayoutAnimationData AABB toBounds = AABB(); }; -class LayoutComponent : public LayoutComponentBase +class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public ShapePaintContainer { protected: LayoutComponentStyle* m_style = nullptr; @@ -45,6 +49,15 @@ class LayoutComponent : public LayoutComponentBase KeyFrameInterpolator* m_inheritedInterpolator; LayoutStyleInterpolation m_inheritedInterpolation = LayoutStyleInterpolation::hold; float m_inheritedInterpolationTime = 0; + Rectangle* m_backgroundRect = new Rectangle(); + rcp m_backgroundPath; + rcp m_clipPath; + DrawableProxy m_proxy; + + Artboard* getArtboard() override { return artboard(); } + +private: + virtual void performUpdate(ComponentDirt value); #ifdef WITH_RIVE_LAYOUT private: @@ -62,13 +75,21 @@ class LayoutComponent : public LayoutComponentBase public: LayoutComponentStyle* style() { return m_style; } void style(LayoutComponentStyle* style) { m_style = style; } + void draw(Renderer* renderer) override; + void drawProxy(Renderer* renderer) override; + Core* hitTest(HitInfo*, const Mat2D&) override; + DrawableProxy* proxy() { return &m_proxy; }; + void update(ComponentDirt value) override; #ifdef WITH_RIVE_LAYOUT - LayoutComponent(); + LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())), m_proxy(this) + { + layoutNode().getConfig()->setPointScaleFactor(0); + } + ~LayoutComponent() { delete m_backgroundRect; } void syncStyle(); virtual void propagateSize(); void updateLayoutBounds(); - void update(ComponentDirt value) override; StatusCode onAddedDirty(CoreContext* context) override; bool advance(double elapsedSeconds); @@ -97,6 +118,9 @@ class LayoutComponent : public LayoutComponentBase return m_layoutLocationX != 0 || m_layoutLocationY != 0 || m_layoutSizeWidth != 0 || m_layoutSizeHeight != 0; }; +#else + LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())), m_proxy(this) + {} #endif void buildDependencies() override; @@ -111,7 +135,7 @@ class LayoutComponent : public LayoutComponentBase Vec2D measureLayout(float width, LayoutMeasureMode widthMode, float height, - LayoutMeasureMode heightMode); + LayoutMeasureMode heightMode) override; }; } // namespace rive diff --git a/include/rive/transform_component.hpp b/include/rive/transform_component.hpp index 534165c2..151c31bc 100644 --- a/include/rive/transform_component.hpp +++ b/include/rive/transform_component.hpp @@ -18,6 +18,9 @@ class TransformComponent : public TransformComponentBase WorldTransformComponent* m_ParentTransformComponent = nullptr; std::vector m_Constraints; +protected: + void updateConstraints(); + public: bool collapse(bool value) override; const std::vector& constraints() const { return m_Constraints; } @@ -25,7 +28,7 @@ class TransformComponent : public TransformComponentBase void buildDependencies() override; void update(ComponentDirt value) override; void updateTransform(); - void updateWorldTransform(); + virtual void updateWorldTransform(); void markTransformDirty(); /// Opacity inherited by any child of this transform component. This'll diff --git a/src/artboard.cpp b/src/artboard.cpp index 3a0b299d..7cd9b029 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -15,6 +15,7 @@ #include "rive/shapes/paint/shape_paint.hpp" #include "rive/importers/import_stack.hpp" #include "rive/importers/backboard_importer.hpp" +#include "rive/layout_component.hpp" #include "rive/nested_artboard.hpp" #include "rive/joystick.hpp" #include "rive/data_bind_flags.hpp" @@ -84,8 +85,8 @@ StatusCode Artboard::initialize() StatusCode code; // these will be re-built in update() -- are they needed here? - m_BackgroundPath = factory()->makeEmptyRenderPath(); - m_ClipPath = factory()->makeEmptyRenderPath(); + m_backgroundPath = factory()->makeEmptyRenderPath(); + m_clipPath = factory()->makeEmptyRenderPath(); m_layoutSizeWidth = width(); m_layoutSizeHeight = height(); @@ -218,7 +219,7 @@ StatusCode Artboard::initialize() { object->as()->buildDependencies(); } - if (object->is()) + if (object->is() && object != this) { Drawable* drawable = object->as(); m_Drawables.push_back(drawable); @@ -235,6 +236,48 @@ StatusCode Artboard::initialize() } } } + // Iterate over the drawables in order to inject proxies for layouts + std::vector layouts; + for (int i = 0; i < m_Drawables.size(); i++) + { + auto drawable = m_Drawables[i]; + LayoutComponent* currentLayout; + bool isInCurrentLayout = true; + if (!layouts.empty()) + { + currentLayout = layouts.back(); + isInCurrentLayout = false; + } + for (ContainerComponent* parent = drawable; parent != nullptr; parent = parent->parent()) + { + if (parent == currentLayout) + { + isInCurrentLayout = true; + break; + } + } + // We inject a DrawableProxy after all of the children of a LayoutComponent + // so that we can draw a stroke above and background below the children + // This also allows us to clip the children + if (currentLayout != nullptr && !isInCurrentLayout) + { + // This is the first item in the list of drawables that isn't a child + // of the layout, so we insert a proxy before it + m_Drawables.insert(m_Drawables.begin() + i, currentLayout->proxy()); + layouts.pop_back(); + i += 1; + } + if (drawable->is()) + { + layouts.push_back(drawable->as()); + } + } + while (!layouts.empty()) + { + auto layout = layouts.back(); + m_Drawables.push_back(layout->proxy()); + layouts.pop_back(); + } sortDependencies(); @@ -474,7 +517,7 @@ float Artboard::layoutHeight() const #endif } -void Artboard::update(ComponentDirt value) +void Artboard::performUpdate(ComponentDirt value) { if (hasDirt(value, ComponentDirt::DrawOrder)) { @@ -495,11 +538,11 @@ void Artboard::update(ComponentDirt value) { clip = bg; } - m_ClipPath = factory()->makeRenderPath(clip); + m_clipPath = factory()->makeRenderPath(clip); m_backgroundRawPath.addRect(bg); - m_BackgroundPath->rewind(); - m_backgroundRawPath.addTo(m_BackgroundPath.get()); + m_backgroundPath->rewind(); + m_backgroundRawPath.addTo(m_backgroundPath.get()); } if (hasDirt(value, ComponentDirt::RenderOpacity)) { @@ -655,14 +698,14 @@ bool Artboard::advance(double elapsedSeconds, bool nested) return advanceInternal(elapsedSeconds, true, nested); } -Core* Artboard::hitTest(HitInfo* hinfo, const Mat2D* xform) +Core* Artboard::hitTest(HitInfo* hinfo, const Mat2D& xform) { if (clip()) { // TODO: can we get the rawpath for the clip? } - auto mx = xform ? *xform : Mat2D(); + auto mx = xform; if (m_FrameOrigin) { mx *= Mat2D::fromTranslate(layoutWidth() * originX(), layoutHeight() * originY()); @@ -694,12 +737,14 @@ Core* Artboard::hitTest(HitInfo* hinfo, const Mat2D* xform) return nullptr; } +void Artboard::draw(Renderer* renderer) { draw(renderer, DrawOption::kNormal); } + void Artboard::draw(Renderer* renderer, DrawOption option) { renderer->save(); if (clip()) { - renderer->clipPath(m_ClipPath.get()); + renderer->clipPath(m_clipPath.get()); } if (m_FrameOrigin) @@ -714,7 +759,7 @@ void Artboard::draw(Renderer* renderer, DrawOption option) { for (auto shapePaint : m_ShapePaints) { - shapePaint->draw(renderer, m_BackgroundPath.get(), &m_backgroundRawPath); + shapePaint->draw(renderer, m_backgroundPath.get(), &m_backgroundRawPath); } } diff --git a/src/drawable.cpp b/src/drawable.cpp index 2f01c79d..522bd5ff 100644 --- a/src/drawable.cpp +++ b/src/drawable.cpp @@ -40,7 +40,7 @@ StatusCode Drawable::onAddedDirty(CoreContext* context) void Drawable::addClippingShape(ClippingShape* shape) { m_ClippingShapes.push_back(shape); } -ClipResult Drawable::clip(Renderer* renderer) const +ClipResult Drawable::applyClip(Renderer* renderer) const { if (m_ClippingShapes.size() == 0) { diff --git a/src/layout/layout_component_style.cpp b/src/layout/layout_component_style.cpp index 8fe4a32b..a9310be9 100644 --- a/src/layout/layout_component_style.cpp +++ b/src/layout/layout_component_style.cpp @@ -196,4 +196,8 @@ void LayoutComponentStyle::paddingBottomUnitsValueChanged() { markLayoutNodeDirt void LayoutComponentStyle::positionLeftUnitsValueChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::positionRightUnitsValueChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::positionTopUnitsValueChanged() { markLayoutNodeDirty(); } -void LayoutComponentStyle::positionBottomUnitsValueChanged() { markLayoutNodeDirty(); } \ No newline at end of file +void LayoutComponentStyle::positionBottomUnitsValueChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::cornerRadiusTLChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::cornerRadiusTRChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::cornerRadiusBLChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::cornerRadiusBRChanged() { markLayoutNodeDirty(); } \ No newline at end of file diff --git a/src/layout_component.cpp b/src/layout_component.cpp index 350b7cc2..52040d41 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -1,8 +1,14 @@ #include "rive/animation/keyframe_interpolator.hpp" #include "rive/artboard.hpp" +#include "rive/drawable.hpp" +#include "rive/factory.hpp" #include "rive/layout_component.hpp" #include "rive/node.hpp" #include "rive/math/aabb.hpp" +#include "rive/shapes/paint/fill.hpp" +#include "rive/shapes/paint/shape_paint.hpp" +#include "rive/shapes/paint/stroke.hpp" +#include "rive/shapes/rectangle.hpp" #ifdef WITH_RIVE_LAYOUT #include "rive/transform_component.hpp" #include "yoga/YGEnums.h" @@ -19,14 +25,111 @@ void LayoutComponent::buildDependencies() { parent()->addDependent(this); } + // Set the blend mode on all the shape paints. If we ever animate this + // property, we'll need to update it in the update cycle/mark dirty when the + // blend mode changes. + for (auto paint : m_ShapePaints) + { + paint->blendMode(blendMode()); + } } -#ifdef WITH_RIVE_LAYOUT -LayoutComponent::LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())) +void LayoutComponent::drawProxy(Renderer* renderer) { - layoutNode().getConfig()->setPointScaleFactor(0); + if (clip()) + { + renderer->save(); + renderer->clipPath(m_clipPath.get()); + } + renderer->save(); + renderer->transform(worldTransform()); + for (auto shapePaint : m_ShapePaints) + { + if (!shapePaint->isVisible()) + { + continue; + } + if (shapePaint->is()) + { + shapePaint->draw(renderer, m_backgroundPath.get(), &m_backgroundRect->rawPath()); + } + } + renderer->restore(); +} + +void LayoutComponent::draw(Renderer* renderer) +{ + // Restore clip before drawing stroke so we don't clip the stroke + if (clip()) + { + renderer->restore(); + } + renderer->save(); + renderer->transform(worldTransform()); + for (auto shapePaint : m_ShapePaints) + { + if (!shapePaint->isVisible()) + { + continue; + } + if (shapePaint->is()) + { + shapePaint->draw(renderer, m_backgroundPath.get(), &m_backgroundRect->rawPath()); + } + } + renderer->restore(); +} + +Core* LayoutComponent::hitTest(HitInfo*, const Mat2D&) { return nullptr; } + +void LayoutComponent::update(ComponentDirt value) +{ + Super::update(value); + performUpdate(value); +} + +void LayoutComponent::performUpdate(ComponentDirt value) +{ + if (hasDirt(value, ComponentDirt::RenderOpacity)) + { + propagateOpacity(renderOpacity()); + } + if (hasDirt(value, ComponentDirt::Path)) + { + m_backgroundRect->width(m_layoutSizeWidth); + m_backgroundRect->height(m_layoutSizeHeight); + m_backgroundRect->linkCornerRadius(style()->linkCornerRadius()); + m_backgroundRect->cornerRadiusTL(style()->cornerRadiusTL()); + m_backgroundRect->cornerRadiusTR(style()->cornerRadiusTR()); + m_backgroundRect->cornerRadiusBL(style()->cornerRadiusBL()); + m_backgroundRect->cornerRadiusBR(style()->cornerRadiusBR()); + m_backgroundRect->update(value); + + m_backgroundPath->rewind(); + m_backgroundRect->rawPath().addTo(m_backgroundPath.get()); + AABB clipBounds = AABB::fromLTWH(worldTranslation().x, + worldTranslation().y, + worldTranslation().x + m_layoutSizeWidth, + worldTranslation().y + m_layoutSizeHeight); + m_clipPath = artboard()->factory()->makeRenderPath(clipBounds); + } + if (hasDirt(value, ComponentDirt::WorldTransform)) + { + Mat2D parentWorld = parent()->is() + ? (parent()->as())->worldTransform() + : Mat2D(); + auto transform = Mat2D(); + transform[4] = m_layoutLocationX; + transform[5] = m_layoutLocationY; + + auto multipliedTransform = Mat2D::multiply(parentWorld, transform); + m_WorldTransform = multipliedTransform; + + updateConstraints(); + } } +#ifdef WITH_RIVE_LAYOUT StatusCode LayoutComponent::onAddedDirty(CoreContext* context) { auto code = Super::onAddedDirty(context); @@ -48,25 +151,13 @@ StatusCode LayoutComponent::onAddedDirty(CoreContext* context) { parent()->as()->syncLayoutChildren(); } + m_backgroundPath = artboard()->factory()->makeEmptyRenderPath(); + m_clipPath = artboard()->factory()->makeEmptyRenderPath(); + m_backgroundRect->originX(0); + m_backgroundRect->originY(0); return StatusCode::Ok; } -void LayoutComponent::update(ComponentDirt value) -{ - if (hasDirt(value, ComponentDirt::WorldTransform)) - { - Mat2D parentWorld = parent()->is() - ? (parent()->as())->worldTransform() - : Mat2D(); - auto transform = Mat2D(); - transform[4] = m_layoutLocationX; - transform[5] = m_layoutLocationY; - - auto multipliedTransform = Mat2D::multiply(parentWorld, transform); - m_WorldTransform = multipliedTransform; - } -} - static YGSize measureFunc(YGNode* node, float width, YGMeasureMode widthMode, @@ -567,6 +658,14 @@ void LayoutComponent::markLayoutStyleDirty() } } #else +Vec2D LayoutComponent::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + return Vec2D(); +} + void LayoutComponent::markLayoutNodeDirty() {} void LayoutComponent::markLayoutStyleDirty() {} #endif diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 19437dce..95138b07 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -60,7 +60,7 @@ void NestedArtboard::draw(Renderer* renderer) { return; } - ClipResult clipResult = clip(renderer); + ClipResult clipResult = applyClip(renderer); if (clipResult == ClipResult::noClip) { // We didn't clip, so make sure to save as we'll be doing some @@ -83,7 +83,7 @@ Core* NestedArtboard::hitTest(HitInfo* hinfo, const Mat2D& xform) } hinfo->mounts.push_back(this); auto mx = xform * worldTransform() * makeTranslate(m_Artboard); - if (auto c = m_Artboard->hitTest(hinfo, &mx)) + if (auto c = m_Artboard->hitTest(hinfo, mx)) { return c; } diff --git a/src/shapes/image.cpp b/src/shapes/image.cpp index e7612307..d86687e3 100644 --- a/src/shapes/image.cpp +++ b/src/shapes/image.cpp @@ -24,7 +24,7 @@ void Image::draw(Renderer* renderer) return; } - ClipResult clipResult = clip(renderer); + ClipResult clipResult = applyClip(renderer); if (clipResult == ClipResult::noClip) { diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp index fd5af983..f5898feb 100644 --- a/src/shapes/path.cpp +++ b/src/shapes/path.cpp @@ -56,6 +56,10 @@ bool Path::isFlagged(PathFlags flags) const { return (int)(m_pathFlags & flags) bool Path::canDeferPathUpdate() { + if (m_Shape == nullptr) + { + return false; + } // A path cannot defer its update if the shapes requires an update. Note the // nuance here where we track that the shape may be marked for follow path // (meaning all child paths need to follow path). This doesn't mean the diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index 6a22160a..d69648be 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -91,7 +91,7 @@ void Shape::draw(Renderer* renderer) { return; } - ClipResult clipResult = clip(renderer); + ClipResult clipResult = applyClip(renderer); if (clipResult != ClipResult::emptyClip) { diff --git a/src/shapes/shape_paint_container.cpp b/src/shapes/shape_paint_container.cpp index 37e58538..6a702eb0 100644 --- a/src/shapes/shape_paint_container.cpp +++ b/src/shapes/shape_paint_container.cpp @@ -2,6 +2,7 @@ #include "rive/artboard.hpp" #include "rive/factory.hpp" #include "rive/component.hpp" +#include "rive/layout_component.hpp" #include "rive/shapes/paint/stroke.hpp" #include "rive/shapes/shape.hpp" #include "rive/text/text_style.hpp" @@ -14,6 +15,8 @@ ShapePaintContainer* ShapePaintContainer::from(Component* component) { case Artboard::typeKey: return component->as(); + case LayoutComponent::typeKey: + return component->as(); case Shape::typeKey: return component->as(); case TextStyle::typeKey: diff --git a/src/text/text.cpp b/src/text/text.cpp index 48624a56..59403c7a 100644 --- a/src/text/text.cpp +++ b/src/text/text.cpp @@ -509,7 +509,7 @@ const TextStyle* Text::styleFromShaperId(uint16_t id) const void Text::draw(Renderer* renderer) { - ClipResult clipResult = clip(renderer); + ClipResult clipResult = applyClip(renderer); if (clipResult == ClipResult::noClip) { // We didn't clip, so make sure to save as we'll be doing some diff --git a/src/transform_component.cpp b/src/transform_component.cpp index 0e9c1ab9..73bc031b 100644 --- a/src/transform_component.cpp +++ b/src/transform_component.cpp @@ -79,7 +79,11 @@ void TransformComponent::updateWorldTransform() { m_WorldTransform = m_Transform; } + updateConstraints(); +} +void TransformComponent::updateConstraints() +{ for (auto constraint : m_Constraints) { constraint->constrain(this); diff --git a/test/clip_test.cpp b/test/clip_test.cpp index d4dbdeb3..19ff1443 100644 --- a/test/clip_test.cpp +++ b/test/clip_test.cpp @@ -106,7 +106,7 @@ TEST_CASE("Shape does not have any clipping paths visible", "[clipping]") REQUIRE(clippedNode->is()); rive::Shape* clippedShape = static_cast(clippedNode); rive::NoOpRenderer renderer; - auto clipResult = clippedShape->clip(&renderer); + auto clipResult = clippedShape->applyClip(&renderer); REQUIRE(clipResult == rive::ClipResult::emptyClip); } @@ -128,7 +128,7 @@ TEST_CASE("Shape has at least a clipping path visible", "[clipping]") REQUIRE(clippedNode->is()); rive::Shape* clippedShape = static_cast(clippedNode); rive::NoOpRenderer renderer; - auto clipResult = clippedShape->clip(&renderer); + auto clipResult = clippedShape->applyClip(&renderer); REQUIRE(clipResult == rive::ClipResult::clip); } @@ -146,6 +146,6 @@ TEST_CASE("Shape returns an empty clip when one clipping shape is empty", "[clip rive::Shape* shape = static_cast(node); rive::NoOpRenderer renderer; - auto clipResult = shape->clip(&renderer); + auto clipResult = shape->applyClip(&renderer); REQUIRE(clipResult == rive::ClipResult::emptyClip); } From 8e0d982513cf07776766a13c692eabb85f9c3b8e Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Tue, 23 Jul 2024 19:09:14 +0000 Subject: [PATCH 099/138] Makeshadersinpremake Diffs= a01b0467e Makeshadersinpremake (#7660) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index 8cbe00c0..76eddc60 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -114da4e39ba61dd337e8f6f47c1c7b2fb2223915 +a01b0467e84045a47e1b9ccd9b4a84030d490e2e diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index d67e8496..c08ca59f 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -23,7 +23,7 @@ newoption({ description = 'Directory to generate build files', default = nil, }) -RIVE_BUILD_OUT = _OPTIONS['out'] or ('out/' .. RIVE_BUILD_CONFIG) +RIVE_BUILD_OUT = _WORKING_DIR .. '/' .. (_OPTIONS['out'] or ('out/' .. RIVE_BUILD_CONFIG)) newoption({ trigger = 'toolset', @@ -94,9 +94,9 @@ newoption({ description = 'Don\'t build with link time optimizations.', }) -location(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT) -targetdir(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT) -objdir(_WORKING_DIR .. '/' .. RIVE_BUILD_OUT .. '/obj') +location(RIVE_BUILD_OUT) +targetdir(RIVE_BUILD_OUT) +objdir(RIVE_BUILD_OUT .. '/obj') toolset(_OPTIONS['toolset'] or 'clang') language('C++') cppdialect('C++17') From 560a993838180d05490ebe93c9e5b8c3a134c369 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Tue, 23 Jul 2024 20:53:06 +0000 Subject: [PATCH 100/138] Xxxx improve hittest performance In certain scenarios, there is no need to perform a hit test, so we precompute the conditions and early out from calculating the hit test. If a shape has only listeners of type PointerDown and PointerUp, and is not an opaque target, it doesn't need to check for move events or exit events, which can save a lot of computations since it will skip most frames. Diffs= 50bc398c4 Xxxx improve hittest performance (#7584) Co-authored-by: hernan --- .rive_head | 2 +- .../rive/animation/state_machine_instance.hpp | 34 +++++++++ src/animation/state_machine_instance.cpp | 66 ++++++++++++------ test/assets/pointer_events.riv | Bin 0 -> 535 bytes test/hittest_test.cpp | 62 ++++++++++++++++ 5 files changed, 142 insertions(+), 22 deletions(-) create mode 100644 test/assets/pointer_events.riv diff --git a/.rive_head b/.rive_head index 76eddc60..9664e694 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a01b0467e84045a47e1b9ccd9b4a84030d490e2e +50bc398c464061bb2ab5ac51e42901053ae63f1f diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 679ade06..f7ffea16 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -26,6 +26,7 @@ class SMITrigger; class Shape; class StateMachineLayerInstance; class HitComponent; +class HitShape; class NestedArtboard; class NestedEventListener; class NestedEventNotifier; @@ -135,6 +136,17 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne const EventReport reportedEventAt(std::size_t index) const; bool playsAudio() override { return true; } BindableProperty* bindablePropertyInstance(BindableProperty* bindableProperty); +#ifdef TESTING + size_t hitComponentsCount() { return m_hitComponents.size(); }; + HitComponent* hitComponent(size_t index) + { + if (index < m_hitComponents.size()) + { + return m_hitComponents[index].get(); + } + return nullptr; + } +#endif private: std::vector m_reportedEvents; @@ -154,5 +166,27 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne InputChanged m_inputChangedCallback = nullptr; #endif }; + +class HitComponent +{ +public: + Component* component() const { return m_component; } + HitComponent(Component* component, StateMachineInstance* stateMachineInstance) : + m_component(component), m_stateMachineInstance(stateMachineInstance) + {} + virtual ~HitComponent() {} + virtual HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) = 0; +#ifdef WITH_RIVE_TOOLS + virtual bool hitTest(Vec2D position) const = 0; +#endif +#ifdef TESTING + int earlyOutCount = 0; +#endif + +protected: + Component* m_component; + StateMachineInstance* m_stateMachineInstance; +}; + } // namespace rive #endif diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 274ea78f..0b8a112d 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -421,24 +421,6 @@ class StateMachineLayerInstance float m_holdTime = 0.0f; }; -class HitComponent -{ -public: - Component* component() const { return m_component; } - HitComponent(Component* component, StateMachineInstance* stateMachineInstance) : - m_component(component), m_stateMachineInstance(stateMachineInstance) - {} - virtual ~HitComponent() {} - virtual HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) = 0; -#ifdef WITH_RIVE_TOOLS - virtual bool hitTest(Vec2D position) const = 0; -#endif - -protected: - Component* m_component; - StateMachineInstance* m_stateMachineInstance; -}; - /// Representation of a Shape from the Artboard Instance and all the listeners it /// triggers. Allows tracking hover and performing hit detection only once on /// shapes that trigger multiple listeners. @@ -447,8 +429,16 @@ class HitShape : public HitComponent public: HitShape(Component* shape, StateMachineInstance* stateMachineInstance) : HitComponent(shape, stateMachineInstance) - {} + { + if (shape->as()->isTargetOpaque()) + { + canEarlyOut = false; + } + } bool isHovered = false; + bool canEarlyOut = true; + bool hasDownListener = false; + bool hasUpListener = false; float hitRadius = 2; Vec2D previousPosition; std::vector listeners; @@ -474,6 +464,18 @@ class HitShape : public HitComponent HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override { + // If the shape doesn't have any ListenerType::move / enter / exit and the event + // being processed is not of the type it needs to handle. There is no need to perform + // a hitTest (which is relatively expensive and would be happening on every + // pointer move) so we early out. + if (canEarlyOut && (hitType != ListenerType::down || !hasDownListener) && + (hitType != ListenerType::up || !hasUpListener)) + { +#ifdef TESTING + earlyOutCount++; +#endif + return HitResult::none; + } auto shape = m_component->as(); bool isOver = canHit ? hitTest(position) : false; bool hoverChange = isHovered != isOver; @@ -513,6 +515,28 @@ class HitShape : public HitComponent return isOver ? shape->isTargetOpaque() ? HitResult::hitOpaque : HitResult::hit : HitResult::none; } + + void addListener(const StateMachineListener* stateMachineListener) + { + auto listenerType = stateMachineListener->listenerType(); + if (listenerType == ListenerType::enter || listenerType == ListenerType::exit || + listenerType == ListenerType::move) + { + canEarlyOut = false; + } + else + { + if (listenerType == ListenerType::down) + { + hasDownListener = true; + } + else if (listenerType == ListenerType::up) + { + hasUpListener = true; + } + } + listeners.push_back(stateMachineListener); + } }; class HitNestedArtboard : public HitComponent { @@ -753,7 +777,7 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, { hitShape = itr->second; } - hitShape->listeners.push_back(listener); + hitShape->addListener(listener); } return true; }); @@ -1066,4 +1090,4 @@ BindableProperty* StateMachineInstance::bindablePropertyInstance(BindablePropert return nullptr; } return bindablePropertyInstance->second; -} \ No newline at end of file +} diff --git a/test/assets/pointer_events.riv b/test/assets/pointer_events.riv new file mode 100644 index 0000000000000000000000000000000000000000..c65bea3c16a06e93ae80e67154e64f365b22d7a8 GIT binary patch literal 535 zcmZvX%}T>i5QS&V#FT(mYpvo&H!ictLW+pL)rH_n#C_0<1k$A5CQ5g@&0c*0AH;|7 z0aE&-{h?r&Zgi3;q~e8{yZ8=s&N)3kKhoeO#1HCHpGL}}<3zu=j}bO^h|t+){O2>XNs;$qwx$AnN+;~^f6N9O@p zE$e4?RXDaQ)=bzaQ@zT?wnCh?>xbU03!5QoCssp9#=EfpgbM7y9&A4#fDEx9#f5Kp zHS0PMhHuF$;YX-7aSDPKLYsdU{&{KxqP$c*{(07k*f4;xNo%Of<^!U literal 0 HcmV?d00001 diff --git a/test/hittest_test.cpp b/test/hittest_test.cpp index 87b14296..debc2d47 100644 --- a/test/hittest_test.cpp +++ b/test/hittest_test.cpp @@ -183,5 +183,67 @@ TEST_CASE("hit test on opaque nested artboard", "[hittest]") // nested toggle does not change because it's below shape REQUIRE(secondNestedBoolTarget->value() == true); + delete stateMachineInstance; +} + +TEST_CASE("early out on listeners", "[hittest]") +{ + auto file = ReadRiveFile("../../test/assets/pointer_events.riv"); + + auto artboard = file->artboard("art-1"); + auto artboardInstance = artboard->instance(); + auto stateMachine = artboard->stateMachine("sm-1"); + + REQUIRE(artboardInstance != nullptr); + REQUIRE(artboardInstance->stateMachineCount() == 1); + + REQUIRE(stateMachine != nullptr); + + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, artboardInstance.get()); + + stateMachineInstance->advance(0.0f); + artboardInstance->advance(0.0f); + REQUIRE(stateMachineInstance->needsAdvance() == true); + stateMachineInstance->advance(0.0f); + REQUIRE(stateMachineInstance->hitComponentsCount() == 4); + // Hit component with only pointer down and pointer up listeners + auto hitComponentWithEarlyOut = stateMachineInstance->hitComponent(0); + // Hit component that can't early out because it has a pointer enter event + auto hitComponentWithNoEarlyOut = stateMachineInstance->hitComponent(1); + // Hit component that can't early out because it is an opaque target + auto hitComponentOpaque = stateMachineInstance->hitComponent(2); + // Hit component that can early out on all and pointer up + auto hitComponentOnlyPointerDown = stateMachineInstance->hitComponent(3); + REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 0); + REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0); + REQUIRE(hitComponentOpaque->earlyOutCount == 0); + REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 0); + stateMachineInstance->pointerMove(rive::Vec2D(100.0f, 250.0f)); + REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 1); + REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0); + REQUIRE(hitComponentOpaque->earlyOutCount == 0); + REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 1); + stateMachineInstance->pointerExit(rive::Vec2D(100.0f, 250.0f)); + REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 2); + REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0); + REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 2); + REQUIRE(hitComponentOpaque->earlyOutCount == 0); + stateMachineInstance->pointerDown(rive::Vec2D(100.0f, 250.0f)); + REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 2); + REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0); + REQUIRE(hitComponentOpaque->earlyOutCount == 0); + REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 2); + stateMachineInstance->pointerUp(rive::Vec2D(100.0f, 250.0f)); + REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 2); + REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0); + REQUIRE(hitComponentOpaque->earlyOutCount == 0); + REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 3); + stateMachineInstance->pointerMove(rive::Vec2D(105.0f, 205.0f)); + REQUIRE(hitComponentWithEarlyOut->earlyOutCount == 3); + REQUIRE(hitComponentWithNoEarlyOut->earlyOutCount == 0); + REQUIRE(hitComponentOpaque->earlyOutCount == 0); + REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 4); + delete stateMachineInstance; } \ No newline at end of file From 9f0db02f31da8d0675aa66a174503cc593b7ba7d Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Wed, 24 Jul 2024 20:09:57 +0000 Subject: [PATCH 101/138] Nested artboard types: node, leaf, layout ~~Adding as a draft to start testing.~~ - [x] Add node, leaf, and layout types. - [x] Leaf supports fit and alignment. - [x] Leaf alignment is floating point instead of enum allowing for animation later. - [x] Layout allows external hosting artboards to take the nested layout node and host it in another hierarchy. - [x] Measure and control size for NestedArtboard from native. - [x] FFI changes for external layout node - [x] WASM changes for external layout node. - [x] Move layouts to RiveNative. CleanShot 2024-07-21 at 14 48 41@2x ~~For a follow up PR: I think it's time to move some of rive_common into rive_native. I think the layout stuff would be a good start. @philter take a look at how the rive_binding.cpp is shared in rive_native for both FFI and WASM. I think it would simplify our layout bindings to use this model too.~~ Nevermind, we need it for this PR or ```LayoutNode.fromExternal``` doesn't work. Diffs= 1a5f273bb Nested artboard types: node, leaf, layout (#7639) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- dev/defs/nested_artboard.json | 18 +- dev/defs/nested_artboard_layout.json | 8 + dev/defs/nested_artboard_leaf.json | 34 +++ include/rive/artboard.hpp | 36 +-- include/rive/generated/core_registry.hpp | 46 ++-- .../rive/generated/nested_artboard_base.hpp | 38 +-- .../generated/nested_artboard_layout_base.hpp | 42 ++++ .../generated/nested_artboard_leaf_base.hpp | 114 +++++++++ include/rive/layout_component.hpp | 35 ++- include/rive/nested_artboard.hpp | 41 +--- include/rive/nested_artboard_layout.hpp | 19 ++ include/rive/nested_artboard_leaf.hpp | 15 ++ include/rive/transform_component.hpp | 4 +- src/artboard.cpp | 225 ++++++++++++++---- src/generated/nested_artboard_layout_base.cpp | 11 + src/generated/nested_artboard_leaf_base.cpp | 11 + src/layout_component.cpp | 174 +++++++++----- src/nested_artboard.cpp | 23 +- src/nested_artboard_layout.cpp | 60 +++++ src/nested_artboard_leaf.cpp | 40 ++++ test/nested_artboard.cpp | 4 +- test/nested_artboard_opacity_test.cpp | 4 +- test/solo_test.cpp | 8 +- 24 files changed, 743 insertions(+), 269 deletions(-) create mode 100644 dev/defs/nested_artboard_layout.json create mode 100644 dev/defs/nested_artboard_leaf.json create mode 100644 include/rive/generated/nested_artboard_layout_base.hpp create mode 100644 include/rive/generated/nested_artboard_leaf_base.hpp create mode 100644 include/rive/nested_artboard_layout.hpp create mode 100644 include/rive/nested_artboard_leaf.hpp create mode 100644 src/generated/nested_artboard_layout_base.cpp create mode 100644 src/generated/nested_artboard_leaf_base.cpp create mode 100644 src/nested_artboard_layout.cpp create mode 100644 src/nested_artboard_leaf.cpp diff --git a/.rive_head b/.rive_head index 9664e694..fadf9ed6 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -50bc398c464061bb2ab5ac51e42901053ae63f1f +1a5f273bb6534a395d1c3cdcc11a1ba3cd80a96c diff --git a/dev/defs/nested_artboard.json b/dev/defs/nested_artboard.json index 112415c8..8a1ea487 100644 --- a/dev/defs/nested_artboard.json +++ b/dev/defs/nested_artboard.json @@ -17,29 +17,13 @@ }, "description": "Identifier used to track the Artboard nested." }, - "fit": { - "type": "uint", - "key": { - "int": 538, - "string": "fit" - }, - "description": "Fit type for the nested artboard's runtime artboard." - }, - "alignment": { - "type": "uint", - "key": { - "int": 539, - "string": "alignment" - }, - "description": "Alignment type for the nested artboard's runtime artboard." - }, "dataBindPathIds": { "type": "List", "typeRuntime": "Bytes", "encoded": true, "initialValue": "[]", "key": { - "int": 580, + "int": 582, "string": "databindpathids" }, "description": "Path to the selected property." diff --git a/dev/defs/nested_artboard_layout.json b/dev/defs/nested_artboard_layout.json new file mode 100644 index 00000000..b0579be4 --- /dev/null +++ b/dev/defs/nested_artboard_layout.json @@ -0,0 +1,8 @@ +{ + "name": "NestedArtboardLayout", + "key": { + "int": 452, + "string": "nestedartboardlayout" + }, + "extends": "nested_artboard.json" +} \ No newline at end of file diff --git a/dev/defs/nested_artboard_leaf.json b/dev/defs/nested_artboard_leaf.json new file mode 100644 index 00000000..cddf1585 --- /dev/null +++ b/dev/defs/nested_artboard_leaf.json @@ -0,0 +1,34 @@ +{ + "name": "NestedArtboardLeaf", + "key": { + "int": 451, + "string": "nested_artboard_leaf" + }, + "extends": "nested_artboard.json", + "properties": { + "fit": { + "type": "uint", + "key": { + "int": 538, + "string": "fit" + }, + "description": "Fit type for the nested artboard's runtime artboard." + }, + "alignmentX": { + "type": "double", + "key": { + "int": 644, + "string": "alignmentx" + }, + "description": "Alignment value on X." + }, + "alignmentY": { + "type": "double", + "key": { + "int": 645, + "string": "alignmenty" + }, + "description": "Alignment value on Y." + } + } +} \ No newline at end of file diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 4b7cc3d9..2e78c7e8 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -77,6 +77,10 @@ class Artboard : public ArtboardBase, public CoreContext std::unordered_set m_dirtyLayout; float m_originalWidth = 0; float m_originalHeight = 0; + bool m_updatesOwnLayout = true; + Artboard* parentArtboard() const; + NestedArtboard* m_host = nullptr; + bool sharesLayoutWithHost() const; #ifdef EXTERNAL_RIVE_AUDIO_ENGINE rcp m_audioEngine; @@ -85,8 +89,14 @@ class Artboard : public ArtboardBase, public CoreContext void sortDependencies(); void sortDrawOrder(); void updateDataBinds(); - void performUpdate(ComponentDirt value) override; + void updateRenderPath() override; + void update(ComponentDirt value) override; +public: + void host(NestedArtboard* nestedArtboard); + NestedArtboard* host() const; + +private: #ifdef TESTING public: Artboard(Factory* factory) : m_Factory(factory) {} @@ -96,7 +106,7 @@ class Artboard : public ArtboardBase, public CoreContext void addStateMachine(StateMachine* object); public: - Artboard() {} + Artboard(); ~Artboard() override; StatusCode initialize(); @@ -124,21 +134,10 @@ class Artboard : public ArtboardBase, public CoreContext // Artboard is a special type of LayoutComponent void updateWorldTransform() override {} - void markLayoutDirty(LayoutComponent* layoutComponent) - { - m_dirtyLayout.insert(layoutComponent); - } + void markLayoutDirty(LayoutComponent* layoutComponent); -#ifdef WITH_RIVE_LAYOUT - AABB layoutBounds() override - { - if (!hasLayoutMeasurements()) - { - return AABB(x(), y(), x() + width(), y() + height()); - } - return Super::layoutBounds(); - } -#endif + void* takeLayoutNode(); + bool syncStyleChanges(); bool advance(double elapsedSeconds, bool nested = true); bool advanceInternal(double elapsedSeconds, bool isRoot, bool nested = true); @@ -171,7 +170,10 @@ class Artboard : public ArtboardBase, public CoreContext float originalHeight() const { return m_originalHeight; } float layoutWidth() const; float layoutHeight() const; + float layoutX() const; + float layoutY() const; AABB bounds() const; + Vec2D origin() const; // Can we hide these from the public? (they use playable) bool isTranslucent() const; @@ -366,9 +368,11 @@ class Artboard : public ArtboardBase, public CoreContext float m_volume = 1.0f; #ifdef WITH_RIVE_TOOLS ArtboardCallback m_layoutChangedCallback = nullptr; + ArtboardCallback m_layoutDirtyCallback = nullptr; public: void onLayoutChanged(ArtboardCallback callback) { m_layoutChangedCallback = callback; } + void onLayoutDirty(ArtboardCallback callback) { m_layoutDirtyCallback = callback; } #endif }; diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index abeae9a8..7abe2d5a 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -117,6 +117,8 @@ #include "rive/layout_component.hpp" #include "rive/nested_animation.hpp" #include "rive/nested_artboard.hpp" +#include "rive/nested_artboard_layout.hpp" +#include "rive/nested_artboard_leaf.hpp" #include "rive/node.hpp" #include "rive/open_url_event.hpp" #include "rive/shapes/clipping_shape.hpp" @@ -258,6 +260,8 @@ class CoreRegistry return new NestedArtboard(); case SoloBase::typeKey: return new Solo(); + case NestedArtboardLayoutBase::typeKey: + return new NestedArtboardLayout(); case LayoutComponentStyleBase::typeKey: return new LayoutComponentStyle(); case ListenerFireEventBase::typeKey: @@ -428,6 +432,8 @@ class CoreRegistry return new BindablePropertyEnum(); case BindablePropertyColorBase::typeKey: return new BindablePropertyColor(); + case NestedArtboardLeafBase::typeKey: + return new NestedArtboardLeaf(); case WeightBase::typeKey: return new Weight(); case BoneBase::typeKey: @@ -639,12 +645,6 @@ class CoreRegistry case NestedArtboardBase::artboardIdPropertyKey: object->as()->artboardId(value); break; - case NestedArtboardBase::fitPropertyKey: - object->as()->fit(value); - break; - case NestedArtboardBase::alignmentPropertyKey: - object->as()->alignment(value); - break; case NestedAnimationBase::animationIdPropertyKey: object->as()->animationId(value); break; @@ -951,6 +951,9 @@ class CoreRegistry case BindablePropertyEnumBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; + case NestedArtboardLeafBase::fitPropertyKey: + object->as()->fit(value); + break; case WeightBase::valuesPropertyKey: object->as()->values(value); break; @@ -1466,6 +1469,12 @@ class CoreRegistry case BindablePropertyNumberBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; + case NestedArtboardLeafBase::alignmentXPropertyKey: + object->as()->alignmentX(value); + break; + case NestedArtboardLeafBase::alignmentYPropertyKey: + object->as()->alignmentY(value); + break; case BoneBase::lengthPropertyKey: object->as()->length(value); break; @@ -1721,10 +1730,6 @@ class CoreRegistry return object->as()->drawableFlags(); case NestedArtboardBase::artboardIdPropertyKey: return object->as()->artboardId(); - case NestedArtboardBase::fitPropertyKey: - return object->as()->fit(); - case NestedArtboardBase::alignmentPropertyKey: - return object->as()->alignment(); case NestedAnimationBase::animationIdPropertyKey: return object->as()->animationId(); case SoloBase::activeComponentIdPropertyKey: @@ -1929,6 +1934,8 @@ class CoreRegistry return object->as()->flags(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->as()->propertyValue(); + case NestedArtboardLeafBase::fitPropertyKey: + return object->as()->fit(); case WeightBase::valuesPropertyKey: return object->as()->values(); case WeightBase::indicesPropertyKey: @@ -2282,6 +2289,10 @@ class CoreRegistry return object->as()->height(); case BindablePropertyNumberBase::propertyValuePropertyKey: return object->as()->propertyValue(); + case NestedArtboardLeafBase::alignmentXPropertyKey: + return object->as()->alignmentX(); + case NestedArtboardLeafBase::alignmentYPropertyKey: + return object->as()->alignmentY(); case BoneBase::lengthPropertyKey: return object->as()->length(); case RootBoneBase::xPropertyKey: @@ -2426,8 +2437,6 @@ class CoreRegistry case DrawableBase::blendModeValuePropertyKey: case DrawableBase::drawableFlagsPropertyKey: case NestedArtboardBase::artboardIdPropertyKey: - case NestedArtboardBase::fitPropertyKey: - case NestedArtboardBase::alignmentPropertyKey: case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: case LayoutComponentStyleBase::scaleTypePropertyKey: @@ -2530,6 +2539,7 @@ class CoreRegistry case DataBindBase::propertyKeyPropertyKey: case DataBindBase::flagsPropertyKey: case BindablePropertyEnumBase::propertyValuePropertyKey: + case NestedArtboardLeafBase::fitPropertyKey: case WeightBase::valuesPropertyKey: case WeightBase::indicesPropertyKey: case TendonBase::boneIdPropertyKey: @@ -2700,6 +2710,8 @@ class CoreRegistry case JoystickBase::widthPropertyKey: case JoystickBase::heightPropertyKey: case BindablePropertyNumberBase::propertyValuePropertyKey: + case NestedArtboardLeafBase::alignmentXPropertyKey: + case NestedArtboardLeafBase::alignmentYPropertyKey: case BoneBase::lengthPropertyKey: case RootBoneBase::xPropertyKey: case RootBoneBase::yPropertyKey: @@ -2872,10 +2884,6 @@ class CoreRegistry return object->is(); case NestedArtboardBase::artboardIdPropertyKey: return object->is(); - case NestedArtboardBase::fitPropertyKey: - return object->is(); - case NestedArtboardBase::alignmentPropertyKey: - return object->is(); case NestedAnimationBase::animationIdPropertyKey: return object->is(); case SoloBase::activeComponentIdPropertyKey: @@ -3080,6 +3088,8 @@ class CoreRegistry return object->is(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->is(); + case NestedArtboardLeafBase::fitPropertyKey: + return object->is(); case WeightBase::valuesPropertyKey: return object->is(); case WeightBase::indicesPropertyKey: @@ -3412,6 +3422,10 @@ class CoreRegistry return object->is(); case BindablePropertyNumberBase::propertyValuePropertyKey: return object->is(); + case NestedArtboardLeafBase::alignmentXPropertyKey: + return object->is(); + case NestedArtboardLeafBase::alignmentYPropertyKey: + return object->is(); case BoneBase::lengthPropertyKey: return object->is(); case RootBoneBase::xPropertyKey: diff --git a/include/rive/generated/nested_artboard_base.hpp b/include/rive/generated/nested_artboard_base.hpp index a115ba29..a0c203ab 100644 --- a/include/rive/generated/nested_artboard_base.hpp +++ b/include/rive/generated/nested_artboard_base.hpp @@ -36,14 +36,10 @@ class NestedArtboardBase : public Drawable uint16_t coreType() const override { return typeKey; } static const uint16_t artboardIdPropertyKey = 197; - static const uint16_t fitPropertyKey = 538; - static const uint16_t alignmentPropertyKey = 539; - static const uint16_t dataBindPathIdsPropertyKey = 580; + static const uint16_t dataBindPathIdsPropertyKey = 582; private: uint32_t m_ArtboardId = -1; - uint32_t m_Fit = 0; - uint32_t m_Alignment = 0; public: inline uint32_t artboardId() const { return m_ArtboardId; } @@ -57,28 +53,6 @@ class NestedArtboardBase : public Drawable artboardIdChanged(); } - inline uint32_t fit() const { return m_Fit; } - void fit(uint32_t value) - { - if (m_Fit == value) - { - return; - } - m_Fit = value; - fitChanged(); - } - - inline uint32_t alignment() const { return m_Alignment; } - void alignment(uint32_t value) - { - if (m_Alignment == value) - { - return; - } - m_Alignment = value; - alignmentChanged(); - } - virtual void decodeDataBindPathIds(Span value) = 0; virtual void copyDataBindPathIds(const NestedArtboardBase& object) = 0; @@ -86,8 +60,6 @@ class NestedArtboardBase : public Drawable void copy(const NestedArtboardBase& object) { m_ArtboardId = object.m_ArtboardId; - m_Fit = object.m_Fit; - m_Alignment = object.m_Alignment; copyDataBindPathIds(object); Drawable::copy(object); } @@ -99,12 +71,6 @@ class NestedArtboardBase : public Drawable case artboardIdPropertyKey: m_ArtboardId = CoreUintType::deserialize(reader); return true; - case fitPropertyKey: - m_Fit = CoreUintType::deserialize(reader); - return true; - case alignmentPropertyKey: - m_Alignment = CoreUintType::deserialize(reader); - return true; case dataBindPathIdsPropertyKey: decodeDataBindPathIds(CoreBytesType::deserialize(reader)); return true; @@ -114,8 +80,6 @@ class NestedArtboardBase : public Drawable protected: virtual void artboardIdChanged() {} - virtual void fitChanged() {} - virtual void alignmentChanged() {} virtual void dataBindPathIdsChanged() {} }; } // namespace rive diff --git a/include/rive/generated/nested_artboard_layout_base.hpp b/include/rive/generated/nested_artboard_layout_base.hpp new file mode 100644 index 00000000..7c5ce6f6 --- /dev/null +++ b/include/rive/generated/nested_artboard_layout_base.hpp @@ -0,0 +1,42 @@ +#ifndef _RIVE_NESTED_ARTBOARD_LAYOUT_BASE_HPP_ +#define _RIVE_NESTED_ARTBOARD_LAYOUT_BASE_HPP_ +#include "rive/nested_artboard.hpp" +namespace rive +{ +class NestedArtboardLayoutBase : public NestedArtboard +{ +protected: + typedef NestedArtboard Super; + +public: + static const uint16_t typeKey = 452; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case NestedArtboardLayoutBase::typeKey: + case NestedArtboardBase::typeKey: + case DrawableBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/nested_artboard_leaf_base.hpp b/include/rive/generated/nested_artboard_leaf_base.hpp new file mode 100644 index 00000000..d72fa60b --- /dev/null +++ b/include/rive/generated/nested_artboard_leaf_base.hpp @@ -0,0 +1,114 @@ +#ifndef _RIVE_NESTED_ARTBOARD_LEAF_BASE_HPP_ +#define _RIVE_NESTED_ARTBOARD_LEAF_BASE_HPP_ +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/nested_artboard.hpp" +namespace rive +{ +class NestedArtboardLeafBase : public NestedArtboard +{ +protected: + typedef NestedArtboard Super; + +public: + static const uint16_t typeKey = 451; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case NestedArtboardLeafBase::typeKey: + case NestedArtboardBase::typeKey: + case DrawableBase::typeKey: + case NodeBase::typeKey: + case TransformComponentBase::typeKey: + case WorldTransformComponentBase::typeKey: + case ContainerComponentBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t fitPropertyKey = 538; + static const uint16_t alignmentXPropertyKey = 644; + static const uint16_t alignmentYPropertyKey = 645; + +private: + uint32_t m_Fit = 0; + float m_AlignmentX = 0.0f; + float m_AlignmentY = 0.0f; + +public: + inline uint32_t fit() const { return m_Fit; } + void fit(uint32_t value) + { + if (m_Fit == value) + { + return; + } + m_Fit = value; + fitChanged(); + } + + inline float alignmentX() const { return m_AlignmentX; } + void alignmentX(float value) + { + if (m_AlignmentX == value) + { + return; + } + m_AlignmentX = value; + alignmentXChanged(); + } + + inline float alignmentY() const { return m_AlignmentY; } + void alignmentY(float value) + { + if (m_AlignmentY == value) + { + return; + } + m_AlignmentY = value; + alignmentYChanged(); + } + + Core* clone() const override; + void copy(const NestedArtboardLeafBase& object) + { + m_Fit = object.m_Fit; + m_AlignmentX = object.m_AlignmentX; + m_AlignmentY = object.m_AlignmentY; + NestedArtboard::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case fitPropertyKey: + m_Fit = CoreUintType::deserialize(reader); + return true; + case alignmentXPropertyKey: + m_AlignmentX = CoreDoubleType::deserialize(reader); + return true; + case alignmentYPropertyKey: + m_AlignmentY = CoreDoubleType::deserialize(reader); + return true; + } + return NestedArtboard::deserialize(propertyKey, reader); + } + +protected: + virtual void fitChanged() {} + virtual void alignmentXChanged() {} + virtual void alignmentYChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index 976544c7..c0c4bdb4 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -12,7 +12,7 @@ #include "yoga/YGStyle.h" #include "yoga/Yoga.h" #endif -#include + namespace rive { @@ -57,15 +57,12 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public Artboard* getArtboard() override { return artboard(); } private: - virtual void performUpdate(ComponentDirt value); - #ifdef WITH_RIVE_LAYOUT -private: +protected: YGNode& layoutNode() { return m_layoutData->node; } YGStyle& layoutStyle() { return m_layoutData->style; } void syncLayoutChildren(); void propagateSizeToChildren(ContainerComponent* component); - AABB findMaxIntrinsicSize(ContainerComponent* component, AABB maxIntrinsicSize); bool applyInterpolation(double elapsedSeconds); protected: @@ -75,11 +72,25 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public public: LayoutComponentStyle* style() { return m_style; } void style(LayoutComponentStyle* style) { m_style = style; } + void draw(Renderer* renderer) override; void drawProxy(Renderer* renderer) override; Core* hitTest(HitInfo*, const Mat2D&) override; DrawableProxy* proxy() { return &m_proxy; }; + virtual void updateRenderPath(); void update(ComponentDirt value) override; + void onDirty(ComponentDirt value) override; + AABB layoutBounds() + { + return AABB::fromLTWH(m_layoutLocationX, + m_layoutLocationY, + m_layoutSizeWidth, + m_layoutSizeHeight); + } + AABB localBounds() const override + { + return AABB::fromLTWH(0.0f, 0.0f, m_layoutSizeWidth, m_layoutSizeHeight); + } #ifdef WITH_RIVE_LAYOUT LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())), m_proxy(this) @@ -91,6 +102,7 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public virtual void propagateSize(); void updateLayoutBounds(); StatusCode onAddedDirty(CoreContext* context) override; + StatusCode onAddedClean(CoreContext* context) override; bool advance(double elapsedSeconds); bool animates(); @@ -106,22 +118,9 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public KeyFrameInterpolator* inheritedInterpolator, float inheritedInterpolationTime); void clearInheritedInterpolation(); - virtual AABB layoutBounds() - { - return AABB(m_layoutLocationX, - m_layoutLocationY, - m_layoutLocationX + m_layoutSizeWidth, - m_layoutLocationY + m_layoutSizeHeight); - }; - bool hasLayoutMeasurements() - { - return m_layoutLocationX != 0 || m_layoutLocationY != 0 || m_layoutSizeWidth != 0 || - m_layoutSizeHeight != 0; - }; #else LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())), m_proxy(this) {} - #endif void buildDependencies() override; diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index 57598156..64577275 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp @@ -11,30 +11,6 @@ namespace rive { -enum class NestedArtboardFitType : uint8_t -{ - fill, // Default value - scales to fill available view without maintaining aspect ratio - contain, - cover, - fitWidth, - fitHeight, - resizeArtboard, - none, -}; - -enum class NestedArtboardAlignmentType : uint8_t -{ - center, // Default value - topLeft, - topCenter, - topRight, - centerLeft, - centerRight, - bottomLeft, - bottomCenter, - bottomRight, -}; - class ArtboardInstance; class NestedAnimation; class NestedInput; @@ -42,13 +18,10 @@ class NestedStateMachine; class StateMachineInstance; class NestedArtboard : public NestedArtboardBase { - -private: +protected: Artboard* m_Artboard = nullptr; // might point to m_Instance, and might not std::unique_ptr m_Instance; // may be null std::vector m_NestedAnimations; - float m_layoutScaleX = NAN; - float m_layoutScaleY = NAN; protected: std::vector m_DataBindPathIdsBuffer; @@ -62,8 +35,7 @@ class NestedArtboard : public NestedArtboardBase void addNestedAnimation(NestedAnimation* nestedAnimation); void nest(Artboard* artboard); - - ArtboardInstance* artboard() { return m_Instance.get(); } + ArtboardInstance* artboardInstance() { return m_Instance.get(); } StatusCode import(ImportStack& importStack) override; Core* clone() const override; @@ -77,14 +49,6 @@ class NestedArtboard : public NestedArtboardBase NestedInput* input(std::string name) const; NestedInput* input(std::string name, std::string stateMachineName) const; - NestedArtboardAlignmentType alignmentType() const - { - return (NestedArtboardAlignmentType)alignment(); - } - NestedArtboardFitType fitType() const { return (NestedArtboardFitType)fit(); } - float effectiveScaleX() { return std::isnan(m_layoutScaleX) ? scaleX() : m_layoutScaleX; } - float effectiveScaleY() { return std::isnan(m_layoutScaleY) ? scaleY() : m_layoutScaleY; } - Vec2D measureLayout(float width, LayoutMeasureMode widthMode, float height, @@ -96,6 +60,7 @@ class NestedArtboard : public NestedArtboardBase /// nested within. Returns true when the conversion succeeds, and false /// when one is not possible. bool worldToLocal(Vec2D world, Vec2D* local); + void syncStyleChanges(); void decodeDataBindPathIds(Span value) override; void copyDataBindPathIds(const NestedArtboardBase& object) override; std::vector dataBindPathIds() { return m_DataBindPathIdsBuffer; }; diff --git a/include/rive/nested_artboard_layout.hpp b/include/rive/nested_artboard_layout.hpp new file mode 100644 index 00000000..9a680747 --- /dev/null +++ b/include/rive/nested_artboard_layout.hpp @@ -0,0 +1,19 @@ +#ifndef _RIVE_NESTED_ARTBOARD_LAYOUT_HPP_ +#define _RIVE_NESTED_ARTBOARD_LAYOUT_HPP_ +#include "rive/generated/nested_artboard_layout_base.hpp" + +namespace rive +{ +class NestedArtboardLayout : public NestedArtboardLayoutBase +{ +public: +#ifdef WITH_RIVE_LAYOUT + void* layoutNode(); +#endif + Core* clone() const override; + void markNestedLayoutDirty(); + void update(ComponentDirt value) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/nested_artboard_leaf.hpp b/include/rive/nested_artboard_leaf.hpp new file mode 100644 index 00000000..a7fa3d57 --- /dev/null +++ b/include/rive/nested_artboard_leaf.hpp @@ -0,0 +1,15 @@ +#ifndef _RIVE_NESTED_ARTBOARD_LEAF_HPP_ +#define _RIVE_NESTED_ARTBOARD_LEAF_HPP_ +#include "rive/generated/nested_artboard_leaf_base.hpp" +#include +namespace rive +{ +class NestedArtboardLeaf : public NestedArtboardLeafBase +{ +public: + Core* clone() const override; + void update(ComponentDirt value) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/transform_component.hpp b/include/rive/transform_component.hpp index 151c31bc..36580a66 100644 --- a/include/rive/transform_component.hpp +++ b/include/rive/transform_component.hpp @@ -12,7 +12,7 @@ class WorldTransformComponent; class AABB; class TransformComponent : public TransformComponentBase { -private: +protected: Mat2D m_Transform; float m_RenderOpacity = 0.0f; WorldTransformComponent* m_ParentTransformComponent = nullptr; @@ -27,7 +27,7 @@ class TransformComponent : public TransformComponentBase StatusCode onAddedClean(CoreContext* context) override; void buildDependencies() override; void update(ComponentDirt value) override; - void updateTransform(); + virtual void updateTransform(); virtual void updateWorldTransform(); void markTransformDirty(); diff --git a/src/artboard.cpp b/src/artboard.cpp index 7cd9b029..263f683f 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -17,6 +17,8 @@ #include "rive/importers/backboard_importer.hpp" #include "rive/layout_component.hpp" #include "rive/nested_artboard.hpp" +#include "rive/nested_artboard_leaf.hpp" +#include "rive/nested_artboard_layout.hpp" #include "rive/joystick.hpp" #include "rive/data_bind_flags.hpp" #include "rive/animation/nested_bool.hpp" @@ -33,6 +35,8 @@ using namespace rive; +Artboard::Artboard() {} + Artboard::~Artboard() { #ifdef WITH_RIVE_AUDIO @@ -172,6 +176,8 @@ StatusCode Artboard::initialize() break; } case NestedArtboardBase::typeKey: + case NestedArtboardLeafBase::typeKey: + case NestedArtboardLayoutBase::typeKey: m_NestedArtboards.push_back(object->as()); break; @@ -336,6 +342,10 @@ StatusCode Artboard::initialize() m_DrawTargets.push_back(static_cast(*itr++)); } + // Some default layout dimensions. + m_layoutSizeWidth = width(); + m_layoutSizeHeight = height(); + return StatusCode::Ok; } @@ -490,6 +500,10 @@ void Artboard::onDirty(ComponentDirt dirt) { m_Dirt |= ComponentDirt::Components void Artboard::propagateSize() { addDirt(ComponentDirt::Path); + if (sharesLayoutWithHost()) + { + m_host->markTransformDirty(); + } #ifdef WITH_RIVE_TOOLS if (m_layoutChangedCallback != nullptr) { @@ -499,6 +513,38 @@ void Artboard::propagateSize() } #endif +bool Artboard::sharesLayoutWithHost() const +{ + return m_host != nullptr && m_host->is(); +} +void Artboard::host(NestedArtboard* nestedArtboard) +{ + m_host = nestedArtboard; +#ifdef WITH_RIVE_LAYOUT + if (!sharesLayoutWithHost()) + { + return; + } + Artboard* parent = parentArtboard(); + if (parent != nullptr) + { + parent->markLayoutDirty(this); + parent->syncLayoutChildren(); + } +#endif +} + +NestedArtboard* Artboard::host() const { return m_host; } + +Artboard* Artboard::parentArtboard() const +{ + if (m_host == nullptr) + { + return nullptr; + } + return m_host->artboard(); +} + float Artboard::layoutWidth() const { #ifdef WITH_RIVE_LAYOUT @@ -517,36 +563,52 @@ float Artboard::layoutHeight() const #endif } -void Artboard::performUpdate(ComponentDirt value) +float Artboard::layoutX() const { - if (hasDirt(value, ComponentDirt::DrawOrder)) +#ifdef WITH_RIVE_LAYOUT + return m_layoutLocationX; +#else + return 0.0f; +#endif +} + +float Artboard::layoutY() const +{ +#ifdef WITH_RIVE_LAYOUT + return m_layoutLocationY; +#else + return 0.0f; +#endif +} + +void Artboard::updateRenderPath() +{ + AABB bg = AABB::fromLTWH(-layoutWidth() * originX(), + -layoutHeight() * originY(), + layoutWidth(), + layoutHeight()); + AABB clip; + if (m_FrameOrigin) { - sortDrawOrder(); + clip = {0.0f, 0.0f, layoutWidth(), layoutHeight()}; } - if (hasDirt(value, ComponentDirt::Path)) + else { - AABB bg = AABB::fromLTWH(-layoutWidth() * originX(), - -layoutHeight() * originY(), - layoutWidth(), - layoutHeight()); - AABB clip; - if (m_FrameOrigin) - { - clip = {0.0f, 0.0f, layoutWidth(), layoutHeight()}; - } - else - { - clip = bg; - } - m_clipPath = factory()->makeRenderPath(clip); - - m_backgroundRawPath.addRect(bg); - m_backgroundPath->rewind(); - m_backgroundRawPath.addTo(m_backgroundPath.get()); + clip = bg; } - if (hasDirt(value, ComponentDirt::RenderOpacity)) + m_clipPath = factory()->makeRenderPath(clip); + m_backgroundRawPath.rewind(); + m_backgroundRawPath.addRect(bg); + m_backgroundPath->rewind(); + m_backgroundRawPath.addTo(m_backgroundPath.get()); +} + +void Artboard::update(ComponentDirt value) +{ + Super::update(value); + if (hasDirt(value, ComponentDirt::DrawOrder)) { - propagateOpacity(childOpacity()); + sortDrawOrder(); } } @@ -606,38 +668,97 @@ bool Artboard::updateComponents() return false; } -bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot, bool nested) +void* Artboard::takeLayoutNode() { - bool didUpdate = false; - m_HasChangedDrawOrderInLastUpdate = false; +#ifdef WITH_RIVE_LAYOUT + m_updatesOwnLayout = false; + return static_cast(&layoutNode()); +#else + return nullptr; +#endif +} + +void Artboard::markLayoutDirty(LayoutComponent* layoutComponent) +{ +#ifdef WITH_RIVE_TOOLS + if (m_dirtyLayout.empty() && m_layoutDirtyCallback != nullptr) + { + m_layoutDirtyCallback(this); + } +#endif + m_dirtyLayout.insert(layoutComponent); + if (sharesLayoutWithHost()) + { + m_host->as()->markNestedLayoutDirty(); + } +} + +bool Artboard::syncStyleChanges() +{ + bool updated = false; #ifdef WITH_RIVE_LAYOUT if (!m_dirtyLayout.empty()) { - syncStyle(); for (auto layout : m_dirtyLayout) { - layout->syncStyle(); + switch (layout->coreType()) + { + case ArtboardBase::typeKey: + { + auto artboard = layout->as(); + if (artboard == this) + { + artboard->syncStyle(); + } + else + { + // This is a nested artboard, sync its changes too. + artboard->syncStyleChanges(); + } + break; + } + + default: + layout->syncStyle(); + break; + } } m_dirtyLayout.clear(); + updated = true; + } +#endif + return updated; +} + +bool Artboard::advanceInternal(double elapsedSeconds, bool isRoot, bool nested) +{ + bool didUpdate = false; + m_HasChangedDrawOrderInLastUpdate = false; +#ifdef WITH_RIVE_LAYOUT + if (hasDirt(ComponentDirt::LayoutStyle)) + { + cascadeAnimationStyle(interpolation(), interpolator(), interpolationTime()); + } + + if (syncStyleChanges() && m_updatesOwnLayout) + { calculateLayout(); - if (hasDirt(ComponentDirt::LayoutStyle)) - { - cascadeAnimationStyle(interpolation(), interpolator(), interpolationTime()); - } - for (auto dep : m_DependencyOrder) + } + + for (auto dep : m_DependencyOrder) + { + if (dep->is()) { - if (dep->is()) + auto layout = dep->as(); + layout->updateLayoutBounds(); + if ((dep == this && Super::advance(elapsedSeconds)) || + (dep != this && layout->advance(elapsedSeconds))) { - auto layout = dep->as(); - layout->updateLayoutBounds(); - if ((dep == this && Super::advance(elapsedSeconds)) || - (dep != this && layout->advance(elapsedSeconds))) - { - didUpdate = true; - } + didUpdate = true; } } } + #endif if (m_JoysticksApplyBeforeUpdate) { @@ -791,6 +912,12 @@ void Artboard::addToRenderPath(RenderPath* path, const Mat2D& transform) } } +Vec2D Artboard::origin() const +{ + return m_FrameOrigin ? Vec2D(0.0f, 0.0f) + : Vec2D(-layoutWidth() * originX(), -layoutHeight() * originY()); +} + AABB Artboard::bounds() const { return m_FrameOrigin ? AABB(0.0f, 0.0f, layoutWidth(), layoutHeight()) @@ -823,7 +950,7 @@ bool Artboard::hasAudio() const } for (auto nestedArtboard : m_NestedArtboards) { - if (nestedArtboard->artboard()->hasAudio()) + if (nestedArtboard->artboardInstance()->hasAudio()) { return true; } @@ -954,7 +1081,7 @@ NestedArtboard* Artboard::nestedArtboardAtPath(const std::string& path) const } else { - auto artboard = nested->artboard(); + auto artboard = nested->artboardInstance(); return artboard->nestedArtboardAtPath(restOfPath); } } @@ -1039,7 +1166,7 @@ void Artboard::internalDataContext(DataContext* value, DataContext* parent, bool m_DataContext->parent(parent); for (auto nestedArtboard : m_NestedArtboards) { - if (nestedArtboard->artboard() == nullptr) + if (nestedArtboard->artboardInstance() == nullptr) { continue; } @@ -1084,7 +1211,7 @@ void Artboard::volume(float value) m_volume = value; for (auto nestedArtboard : m_NestedArtboards) { - auto artboard = nestedArtboard->artboard(); + auto artboard = nestedArtboard->artboardInstance(); if (artboard != nullptr) { artboard->volume(value); @@ -1100,9 +1227,9 @@ void Artboard::populateDataBinds(std::vector* dataBinds) } for (auto nestedArtboard : m_NestedArtboards) { - if (nestedArtboard->artboard() != nullptr) + if (nestedArtboard->artboardInstance() != nullptr) { - nestedArtboard->artboard()->populateDataBinds(dataBinds); + nestedArtboard->artboardInstance()->populateDataBinds(dataBinds); } } } @@ -1236,7 +1363,7 @@ void Artboard::audioEngine(rcp audioEngine) m_audioEngine = audioEngine; for (auto nestedArtboard : m_NestedArtboards) { - auto artboard = nestedArtboard->artboard(); + auto artboard = nestedArtboard->artboardInstance(); if (artboard != nullptr) { artboard->audioEngine(audioEngine); diff --git a/src/generated/nested_artboard_layout_base.cpp b/src/generated/nested_artboard_layout_base.cpp new file mode 100644 index 00000000..069c3746 --- /dev/null +++ b/src/generated/nested_artboard_layout_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/nested_artboard_layout_base.hpp" +#include "rive/nested_artboard_layout.hpp" + +using namespace rive; + +Core* NestedArtboardLayoutBase::clone() const +{ + auto cloned = new NestedArtboardLayout(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/nested_artboard_leaf_base.cpp b/src/generated/nested_artboard_leaf_base.cpp new file mode 100644 index 00000000..d025a17f --- /dev/null +++ b/src/generated/nested_artboard_leaf_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/nested_artboard_leaf_base.hpp" +#include "rive/nested_artboard_leaf.hpp" + +using namespace rive; + +Core* NestedArtboardLeafBase::clone() const +{ + auto cloned = new NestedArtboardLeaf(); + cloned->copy(*this); + return cloned; +} diff --git a/src/layout_component.cpp b/src/layout_component.cpp index 52040d41..872e88ef 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -9,6 +9,7 @@ #include "rive/shapes/paint/shape_paint.hpp" #include "rive/shapes/paint/stroke.hpp" #include "rive/shapes/rectangle.hpp" +#include "rive/nested_artboard_layout.hpp" #ifdef WITH_RIVE_LAYOUT #include "rive/transform_component.hpp" #include "yoga/YGEnums.h" @@ -82,51 +83,52 @@ void LayoutComponent::draw(Renderer* renderer) Core* LayoutComponent::hitTest(HitInfo*, const Mat2D&) { return nullptr; } -void LayoutComponent::update(ComponentDirt value) +void LayoutComponent::updateRenderPath() { - Super::update(value); - performUpdate(value); + m_backgroundRect->width(m_layoutSizeWidth); + m_backgroundRect->height(m_layoutSizeHeight); + m_backgroundRect->linkCornerRadius(style()->linkCornerRadius()); + m_backgroundRect->cornerRadiusTL(style()->cornerRadiusTL()); + m_backgroundRect->cornerRadiusTR(style()->cornerRadiusTR()); + m_backgroundRect->cornerRadiusBL(style()->cornerRadiusBL()); + m_backgroundRect->cornerRadiusBR(style()->cornerRadiusBR()); + m_backgroundRect->update(ComponentDirt::Path); + + m_backgroundPath->rewind(); + m_backgroundRect->rawPath().addTo(m_backgroundPath.get()); + + RawPath clipPath; + clipPath.addPath(m_backgroundRect->rawPath(), &m_WorldTransform); + m_clipPath = artboard()->factory()->makeRenderPath(clipPath, FillRule::nonZero); } -void LayoutComponent::performUpdate(ComponentDirt value) +void LayoutComponent::update(ComponentDirt value) { + Super::update(value); if (hasDirt(value, ComponentDirt::RenderOpacity)) { - propagateOpacity(renderOpacity()); + propagateOpacity(childOpacity()); } - if (hasDirt(value, ComponentDirt::Path)) - { - m_backgroundRect->width(m_layoutSizeWidth); - m_backgroundRect->height(m_layoutSizeHeight); - m_backgroundRect->linkCornerRadius(style()->linkCornerRadius()); - m_backgroundRect->cornerRadiusTL(style()->cornerRadiusTL()); - m_backgroundRect->cornerRadiusTR(style()->cornerRadiusTR()); - m_backgroundRect->cornerRadiusBL(style()->cornerRadiusBL()); - m_backgroundRect->cornerRadiusBR(style()->cornerRadiusBR()); - m_backgroundRect->update(value); - - m_backgroundPath->rewind(); - m_backgroundRect->rawPath().addTo(m_backgroundPath.get()); - AABB clipBounds = AABB::fromLTWH(worldTranslation().x, - worldTranslation().y, - worldTranslation().x + m_layoutSizeWidth, - worldTranslation().y + m_layoutSizeHeight); - m_clipPath = artboard()->factory()->makeRenderPath(clipBounds); - } - if (hasDirt(value, ComponentDirt::WorldTransform)) + if (parent() != nullptr && hasDirt(value, ComponentDirt::WorldTransform)) { Mat2D parentWorld = parent()->is() ? (parent()->as())->worldTransform() : Mat2D(); - auto transform = Mat2D(); - transform[4] = m_layoutLocationX; - transform[5] = m_layoutLocationY; - - auto multipliedTransform = Mat2D::multiply(parentWorld, transform); - m_WorldTransform = multipliedTransform; - + auto location = Vec2D(m_layoutLocationX, m_layoutLocationY); + if (parent()->is()) + { + auto art = parent()->as(); + location -= + Vec2D(art->layoutWidth() * art->originX(), art->layoutHeight() * art->originY()); + } + auto transform = Mat2D::fromTranslation(location); + m_WorldTransform = Mat2D::multiply(parentWorld, transform); updateConstraints(); } + if (hasDirt(value, ComponentDirt::Path)) + { + updateRenderPath(); + } } #ifdef WITH_RIVE_LAYOUT @@ -145,16 +147,24 @@ StatusCode LayoutComponent::onAddedDirty(CoreContext* context) } m_style = static_cast(coreStyle); addChild(m_style); - artboard()->markLayoutDirty(this); - markLayoutStyleDirty(); - if (parent() != nullptr && parent()->is()) + + return StatusCode::Ok; +} + +StatusCode LayoutComponent::onAddedClean(CoreContext* context) +{ + auto code = Super::onAddedClean(context); + if (code != StatusCode::Ok) { - parent()->as()->syncLayoutChildren(); + return code; } + artboard()->markLayoutDirty(this); + markLayoutStyleDirty(); m_backgroundPath = artboard()->factory()->makeEmptyRenderPath(); m_clipPath = artboard()->factory()->makeEmptyRenderPath(); m_backgroundRect->originX(0); m_backgroundRect->originY(0); + syncLayoutChildren(); return StatusCode::Ok; } @@ -185,6 +195,7 @@ Vec2D LayoutComponent::measureLayout(float width, { continue; } + // && child->is()->canMeasure() for nested artboard layout if (child->is()) { auto transformComponent = child->as(); @@ -368,27 +379,33 @@ void LayoutComponent::syncStyle() void LayoutComponent::syncLayoutChildren() { - YGNodeRemoveAllChildren(&layoutNode()); + auto ourNode = &layoutNode(); + YGNodeRemoveAllChildren(ourNode); int index = 0; - for (size_t i = 0; i < children().size(); i++) + for (auto child : children()) { - Component* child = children()[i]; - if (child->is()) + YGNode* node = nullptr; + switch (child->coreType()) + { + case LayoutComponentBase::typeKey: + node = &child->as()->layoutNode(); + break; + case NestedArtboardLayoutBase::typeKey: + node = static_cast(child->as()->layoutNode()); + break; + } + if (node != nullptr) { - YGNodeInsertChild(&layoutNode(), &child->as()->layoutNode(), index); - index += 1; + // YGNodeInsertChild(ourNode, node, index++); + ourNode->insertChild(node, index++); + node->setOwner(ourNode); + ourNode->markDirtyAndPropagate(); } } + markLayoutNodeDirty(); } -void LayoutComponent::propagateSize() -{ - if (artboard() == this) - { - return; - } - propagateSizeToChildren(this); -} +void LayoutComponent::propagateSize() { propagateSizeToChildren(this); } void LayoutComponent::propagateSizeToChildren(ContainerComponent* component) { @@ -415,6 +432,15 @@ void LayoutComponent::calculateLayout() YGNodeCalculateLayout(&layoutNode(), width(), height(), YGDirection::YGDirectionInherit); } +void LayoutComponent::onDirty(ComponentDirt value) +{ + Super::onDirty(value); + if ((value & ComponentDirt::WorldTransform) == ComponentDirt::WorldTransform && clip()) + { + addDirt(ComponentDirt::Path); + } +} + void LayoutComponent::updateLayoutBounds() { auto node = &layoutNode(); @@ -422,6 +448,22 @@ void LayoutComponent::updateLayoutBounds() auto top = YGNodeLayoutGetTop(node); auto width = YGNodeLayoutGetWidth(node); auto height = YGNodeLayoutGetHeight(node); + +#ifdef DEBUG + // Temporarily here to keep track of an issue. + if (left != left || top != top || width != width || height != height) + { + fprintf(stderr, + "Layout returned nan: %f %f %f %f | %p %s\n", + left, + top, + width, + height, + YGNodeGetParent(node), + name().c_str()); + return; + } +#endif if (animates()) { auto toBounds = m_animationData.toBounds; @@ -438,13 +480,21 @@ void LayoutComponent::updateLayoutBounds() markWorldTransformDirty(); } } - else if (left != m_layoutLocationX || top != m_layoutLocationY || width != m_layoutSizeWidth || - height != m_layoutSizeHeight) + else + + if (left != m_layoutLocationX || top != m_layoutLocationY || width != m_layoutSizeWidth || + height != m_layoutSizeHeight) { + if (m_layoutSizeWidth != width || m_layoutSizeHeight != height) + { + // Width changed, we need to rebuild the path. + addDirt(ComponentDirt::Path); + } m_layoutLocationX = left; m_layoutLocationY = top; m_layoutSizeWidth = width; m_layoutSizeHeight = height; + propagateSize(); markWorldTransformDirty(); } @@ -572,14 +622,25 @@ bool LayoutComponent::applyInterpolation(double elapsedSeconds) { return false; } + if (m_animationData.elapsedSeconds >= interpolationTime()) { m_layoutLocationX = m_animationData.toBounds.left(); m_layoutLocationY = m_animationData.toBounds.top(); - m_layoutSizeWidth = m_animationData.toBounds.width(); - m_layoutSizeHeight = m_animationData.toBounds.height(); + + float width = m_animationData.toBounds.width(); + float height = m_animationData.toBounds.height(); + if (width != m_layoutSizeWidth || height != m_layoutSizeHeight) + { + addDirt(ComponentDirt::Path); + } + m_layoutSizeWidth = width; + m_layoutSizeHeight = height; + m_animationData.elapsedSeconds = 0; + propagateSize(); markWorldTransformDirty(); + return false; } float f = 1; @@ -631,13 +692,13 @@ bool LayoutComponent::applyInterpolation(double elapsedSeconds) needsAdvance = true; m_layoutSizeWidth = width; m_layoutSizeHeight = height; + addDirt(ComponentDirt::Path); } m_animationData.elapsedSeconds = m_animationData.elapsedSeconds + (float)elapsedSeconds; if (needsAdvance) { propagateSize(); markWorldTransformDirty(); - markLayoutNodeDirty(); } return needsAdvance; } @@ -668,9 +729,10 @@ Vec2D LayoutComponent::measureLayout(float width, void LayoutComponent::markLayoutNodeDirty() {} void LayoutComponent::markLayoutStyleDirty() {} +void LayoutComponent::onDirty(ComponentDirt value) {} #endif void LayoutComponent::clipChanged() { markLayoutNodeDirty(); } void LayoutComponent::widthChanged() { markLayoutNodeDirty(); } void LayoutComponent::heightChanged() { markLayoutNodeDirty(); } -void LayoutComponent::styleIdChanged() { markLayoutNodeDirty(); } \ No newline at end of file +void LayoutComponent::styleIdChanged() { markLayoutNodeDirty(); } diff --git a/src/nested_artboard.cpp b/src/nested_artboard.cpp index 95138b07..6f30c4c1 100644 --- a/src/nested_artboard.cpp +++ b/src/nested_artboard.cpp @@ -45,7 +45,9 @@ void NestedArtboard::nest(Artboard* artboard) { m_Instance.reset(static_cast(artboard)); // take ownership } - m_Artboard->advanceInternal(0.0f, false); + // This allows for swapping after initial load (after onAddedClean has + // already been called). + m_Artboard->host(this); } static Mat2D makeTranslate(const Artboard* artboard) @@ -124,6 +126,7 @@ StatusCode NestedArtboard::onAddedClean(CoreContext* context) { animation->initializeAnimation(m_Instance.get()); } + m_Artboard->host(this); } return Super::onAddedClean(context); } @@ -247,19 +250,17 @@ Vec2D NestedArtboard::measureLayout(float width, m_Instance ? m_Instance->height() : 0.0f)); } -void NestedArtboard::controlSize(Vec2D size) +void NestedArtboard::syncStyleChanges() { - auto newScaleX = size.x / m_Artboard->originalWidth(); - auto newScaleY = size.y / m_Artboard->originalHeight(); - if (newScaleX != scaleX() || newScaleY != scaleY()) + if (m_Artboard == nullptr) { - // TODO: Support nested artboard fit & alignment - scaleX(newScaleX); - scaleY(newScaleY); - addDirt(ComponentDirt::WorldTransform, false); + return; } + m_Artboard->syncStyleChanges(); } +void NestedArtboard::controlSize(Vec2D size) {} + void NestedArtboard::decodeDataBindPathIds(Span value) { BinaryReader reader(value); @@ -277,7 +278,7 @@ void NestedArtboard::copyDataBindPathIds(const NestedArtboardBase& object) void NestedArtboard::internalDataContext(DataContext* value, DataContext* parent) { - artboard()->internalDataContext(value, parent, false); + artboardInstance()->internalDataContext(value, parent, false); for (auto animation : m_NestedAnimations) { if (animation->is()) @@ -290,7 +291,7 @@ void NestedArtboard::internalDataContext(DataContext* value, DataContext* parent void NestedArtboard::dataContextFromInstance(ViewModelInstance* viewModelInstance, DataContext* parent) { - artboard()->dataContextFromInstance(viewModelInstance, parent, false); + artboardInstance()->dataContextFromInstance(viewModelInstance, parent, false); for (auto animation : m_NestedAnimations) { if (animation->is()) diff --git a/src/nested_artboard_layout.cpp b/src/nested_artboard_layout.cpp new file mode 100644 index 00000000..eed115e4 --- /dev/null +++ b/src/nested_artboard_layout.cpp @@ -0,0 +1,60 @@ +#include "rive/nested_artboard_layout.hpp" +#include "rive/artboard.hpp" + +using namespace rive; + +Core* NestedArtboardLayout::clone() const +{ + NestedArtboardLayout* nestedArtboard = + static_cast(NestedArtboardLayoutBase::clone()); + if (m_Artboard == nullptr) + { + return nestedArtboard; + } + auto ni = m_Artboard->instance(); + nestedArtboard->nest(ni.release()); + return nestedArtboard; +} + +#ifdef WITH_RIVE_LAYOUT +void* NestedArtboardLayout::layoutNode() +{ + if (artboardInstance() == nullptr) + { + return nullptr; + } + return artboardInstance()->takeLayoutNode(); +} +#endif + +void NestedArtboardLayout::markNestedLayoutDirty() +{ + if (artboardInstance() != nullptr) + { + artboardInstance()->markLayoutNodeDirty(); + } +} + +void NestedArtboardLayout::update(ComponentDirt value) +{ + Super::update(value); + auto artboard = artboardInstance(); + if (hasDirt(value, ComponentDirt::WorldTransform) && artboard != nullptr) + { + auto layoutPosition = Vec2D(artboard->layoutX(), artboard->layoutY()); + + if (parent()->is()) + { + auto parentArtboard = parent()->as(); + auto correctedArtboardSpace = + Mat2D::fromTranslation(parentArtboard->origin() + layoutPosition); + m_WorldTransform = correctedArtboardSpace * m_WorldTransform; + } + else + { + m_WorldTransform = Mat2D::fromTranslation(layoutPosition) * m_WorldTransform; + } + auto back = Mat2D::fromTranslation(-artboard->origin()); + m_WorldTransform = back * m_WorldTransform; + } +} \ No newline at end of file diff --git a/src/nested_artboard_leaf.cpp b/src/nested_artboard_leaf.cpp new file mode 100644 index 00000000..2ae92b6e --- /dev/null +++ b/src/nested_artboard_leaf.cpp @@ -0,0 +1,40 @@ +#include "rive/nested_artboard_leaf.hpp" +#include "rive/renderer.hpp" +#include "rive/layout_component.hpp" +#include "rive/artboard.hpp" + +using namespace rive; + +Core* NestedArtboardLeaf::clone() const +{ + NestedArtboardLeaf* nestedArtboard = + static_cast(NestedArtboardLeafBase::clone()); + if (m_Artboard == nullptr) + { + return nestedArtboard; + } + auto ni = m_Artboard->instance(); + nestedArtboard->nest(ni.release()); + return nestedArtboard; +} + +void NestedArtboardLeaf::update(ComponentDirt value) +{ + Super::update(value); + auto artboard = artboardInstance(); + if (hasDirt(value, ComponentDirt::WorldTransform) && artboard != nullptr) + { + auto p = parent(); + + AABB bounds = p != nullptr && p->is() + ? p->as()->localBounds() + : AABB(); + + auto viewTransform = computeAlignment((Fit)fit(), + Alignment(alignmentX(), alignmentY()), + bounds, + artboard->bounds()); + + m_WorldTransform *= viewTransform; + } +} diff --git a/test/nested_artboard.cpp b/test/nested_artboard.cpp index db0c21cb..fa886261 100644 --- a/test/nested_artboard.cpp +++ b/test/nested_artboard.cpp @@ -27,13 +27,13 @@ TEST_CASE("collapsed nested artboards do not advance", "[solo]") // if checking whether the time of each artboard has advanced // Unfortunately there is no way of accessing the time of the animations directly auto redNestedArtboard = stateMachine->artboard()->find("red-artboard"); - auto redNestedArtboardArtboard = redNestedArtboard->artboard(); + auto redNestedArtboardArtboard = redNestedArtboard->artboardInstance(); auto movingShapes = redNestedArtboardArtboard->find(); auto redRect = movingShapes.at(0); REQUIRE(redRect->x() > 50); auto greenNestedArtboard = stateMachine->artboard()->find("green-artboard"); - auto greenNestedArtboardArtboard = greenNestedArtboard->artboard(); + auto greenNestedArtboardArtboard = greenNestedArtboard->artboardInstance(); auto greenMovingShapes = greenNestedArtboardArtboard->find(); auto greenRect = greenMovingShapes.at(0); REQUIRE(greenRect->x() == 50); diff --git a/test/nested_artboard_opacity_test.cpp b/test/nested_artboard_opacity_test.cpp index 5fdd19e5..209f2092 100644 --- a/test/nested_artboard_opacity_test.cpp +++ b/test/nested_artboard_opacity_test.cpp @@ -16,8 +16,8 @@ TEST_CASE("Nested artboard background renders with opacity", "[file]") REQUIRE(artboard->find("Nested artboard container") != nullptr); auto nestedArtboardContainer = artboard->find("Nested artboard container"); - REQUIRE(nestedArtboardContainer->artboard() != nullptr); - auto nestedArtboard = nestedArtboardContainer->artboard(); + REQUIRE(nestedArtboardContainer->artboardInstance() != nullptr); + auto nestedArtboard = nestedArtboardContainer->artboardInstance(); nestedArtboard->updateComponents(); auto paints = nestedArtboard->shapePaints(); REQUIRE(paints.size() == 1); diff --git a/test/solo_test.cpp b/test/solo_test.cpp index e53b2509..30d57b01 100644 --- a/test/solo_test.cpp +++ b/test/solo_test.cpp @@ -237,9 +237,9 @@ TEST_CASE("hit test on nested artboards in solos", "[solo]") REQUIRE(artboard->is()); REQUIRE(artboard->find("Nested-Artboard-Active") != nullptr); auto nestedArtboardActive = artboard->find("Nested-Artboard-Active"); - REQUIRE(nestedArtboardActive->artboard() != nullptr); + REQUIRE(nestedArtboardActive->artboardInstance() != nullptr); - auto nestedArtboardActiveArtboardInstance = nestedArtboardActive->artboard(); + auto nestedArtboardActiveArtboardInstance = nestedArtboardActive->artboardInstance(); auto activeRect = nestedArtboardActiveArtboardInstance->find("Clickable-Rectangle"); REQUIRE(activeRect != nullptr); @@ -250,8 +250,8 @@ TEST_CASE("hit test on nested artboards in solos", "[solo]") REQUIRE(artboard->find("Nested-Artboard-Inactive") != nullptr); auto nestedArtboardInactive = artboard->find("Nested-Artboard-Inactive"); - REQUIRE(nestedArtboardInactive->artboard() != nullptr); - auto nestedArtboardInactiveArtboardInstance = nestedArtboardInactive->artboard(); + REQUIRE(nestedArtboardInactive->artboardInstance() != nullptr); + auto nestedArtboardInactiveArtboardInstance = nestedArtboardInactive->artboardInstance(); auto inactiveRect = nestedArtboardInactiveArtboardInstance->find("Clickable-Rectangle"); REQUIRE(inactiveRect != nullptr); From d42be0a1027f597331bb48ef3dd0ef70b6226f65 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Thu, 25 Jul 2024 01:04:43 +0000 Subject: [PATCH 102/138] Make an HBFont from a CTFontRef. By including ```rive/text/font_hb.hpp``` in iOS you'll get access to ```HBFont::FromSystem``` along with the ```HBFont::Decode``` (which we've been using so far to generate Font objects to put into the fallback list). You can get a UIFont with [this API](https://developer.apple.com/documentation/uikit/uifont/1619027-systemfontofsize?language=objc). You should be able to cast that to a CTFontRef: ``` CTFontRef ctFont = (__bridge CTFontRef)uiFont; auto fallbackFont = HBFont::FromSystem((void*)ctFont); ``` You can then use that in a fallback font procedure (like the example from the editor below) to load on demand/cache/provide from a list etc: https://github.com/rive-app/rive/blob/b5b930f88f18280afa44683c5756066abaa9b1dc/packages/rive_common/macos/rive_text/rive_text.cpp#L153-L175 Diffs= da1bb7745 Make an HBFont from a CTFontRef. (#7661) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/premake5.lua | 5 +++++ dependencies/premake5_harfbuzz.lua | 6 ++++++ dependencies/premake5_harfbuzz_v2.lua | 6 ++++++ dev/test/premake5.lua | 9 +++++++++ include/rive/text/font_hb.hpp | 1 + premake5_v2.lua | 7 ++++++- src/text/font_hb.cpp | 4 ++++ src/text/font_hb_apple.mm | 18 ++++++++++++++++++ 9 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/text/font_hb_apple.mm diff --git a/.rive_head b/.rive_head index fadf9ed6..0ec88f50 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -1a5f273bb6534a395d1c3cdcc11a1ba3cd80a96c +da1bb77455deeafd48012a8eea5ea946a718fb77 diff --git a/build/premake5.lua b/build/premake5.lua index 52dd2a69..66c7d20b 100644 --- a/build/premake5.lua +++ b/build/premake5.lua @@ -128,6 +128,11 @@ do objdir('%{cfg.system}_sim/obj/%{cfg.buildcfg}') end + filter('system:macosx or system:ios') + do + files({ '../src/text/font_hb_apple.mm' }) + end + filter({ 'system:android', 'configurations:release' }) do buildoptions({ '-flto=full' }) diff --git a/dependencies/premake5_harfbuzz.lua b/dependencies/premake5_harfbuzz.lua index 1123265c..9c161731 100644 --- a/dependencies/premake5_harfbuzz.lua +++ b/dependencies/premake5_harfbuzz.lua @@ -349,4 +349,10 @@ do targetdir('%{cfg.system}/cache/arm64/bin/%{cfg.buildcfg}') objdir('%{cfg.system}/cache/arm64/obj/%{cfg.buildcfg}') end + + filter('system:macosx or system:ios') + do + defines({'HAVE_CORETEXT'}) + files({harfbuzz .. '/src/hb-coretext.cc'}) + end end diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua index 428aa156..92655552 100644 --- a/dependencies/premake5_harfbuzz_v2.lua +++ b/dependencies/premake5_harfbuzz_v2.lua @@ -274,4 +274,10 @@ do includedirs({ './' }) forceincludes({ 'rive_harfbuzz_renames.h' }) end + + filter('system:macosx or system:ios') + do + defines({'HAVE_CORETEXT'}) + files({harfbuzz .. '/src/hb-coretext.cc'}) + end end diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index 318aeba4..0cbd9062 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -62,4 +62,13 @@ do }) forceincludes({ 'rive_yoga_renames.h' }) end + + filter({ 'system:macosx'} ) + do + links({ + 'Foundation.framework', + 'CoreGraphics.framework', + 'CoreText.framework' + }) + end end diff --git a/include/rive/text/font_hb.hpp b/include/rive/text/font_hb.hpp index 95346110..ea112b6e 100644 --- a/include/rive/text/font_hb.hpp +++ b/include/rive/text/font_hb.hpp @@ -32,6 +32,7 @@ class HBFont : public rive::Font bool hasGlyph(rive::Span) const override; static rive::rcp Decode(rive::Span); + static rive::rcp FromSystem(void* systemFont); hb_font_t* font() const { return m_font; } private: diff --git a/premake5_v2.lua b/premake5_v2.lua index 3d6c8aa5..5abc30ed 100644 --- a/premake5_v2.lua +++ b/premake5_v2.lua @@ -140,6 +140,11 @@ do architecture('x64') defines({ '_USE_MATH_DEFINES' }) end + + filter('system:macosx or system:ios') + do + files({ 'src/text/font_hb_apple.mm' }) + end end newoption({ @@ -177,4 +182,4 @@ newoption({ newoption({ trigger = 'with_rive_layout', description = 'Compiles in layout features.', -}) \ No newline at end of file +}) diff --git a/src/text/font_hb.cpp b/src/text/font_hb.cpp index 8bd2324d..4c477085 100644 --- a/src/text/font_hb.cpp +++ b/src/text/font_hb.cpp @@ -48,6 +48,10 @@ rive::rcp HBFont::Decode(rive::Span span) return nullptr; } +#ifndef __APPLE__ +rive::rcp HBFont::FromSystem(void* systemFont) { return nullptr; } +#endif + ////////////// constexpr int kStdScale = 2048; diff --git a/src/text/font_hb_apple.mm b/src/text/font_hb_apple.mm new file mode 100644 index 00000000..0277d74d --- /dev/null +++ b/src/text/font_hb_apple.mm @@ -0,0 +1,18 @@ +#include "rive/text_engine.hpp" + +#ifdef WITH_RIVE_TEXT +#include "rive/text/font_hb.hpp" +#import + +#include "hb-coretext.h" + +rive::rcp HBFont::FromSystem(void* systemFont) +{ + auto font = hb_coretext_font_create((CTFontRef)systemFont); + if (font) + { + return rive::rcp(new HBFont(font)); + } + return nullptr; +} +#endif From 46df7e5c3ad544c0b7f0bc01f297c2514dccf51a Mon Sep 17 00:00:00 2001 From: philter Date: Thu, 25 Jul 2024 18:51:12 +0000 Subject: [PATCH 103/138] Implement layout scale type in CPP runtime This PR includes 2 updates: 1. Break out the layout scaleType bitfield property into seperate width and height scale properties. This will allow us to animate these properties easily in the future 2. Implement the logic based on scale type in CPP runtime. @alxgibsn This fixes the issues you observed in runtimes where the` fill` scale type wasn't working properly and layout children sizing wasn't consistent between editor and runtimes. Diffs= 1c067cba8 Implement layout scale type in CPP runtime (#7665) Co-authored-by: Philip Chung --- .rive_head | 2 +- dev/defs/layout/layout_component_style.json | 14 +++- include/rive/generated/core_registry.hpp | 20 +++-- .../layout/layout_component_style_base.hpp | 40 +++++++--- .../rive/layout/layout_component_style.hpp | 11 +++ include/rive/layout_component.hpp | 14 ++++ src/layout/layout_component_style.cpp | 12 +++ src/layout_component.cpp | 76 +++++++++++++++++-- 8 files changed, 161 insertions(+), 28 deletions(-) diff --git a/.rive_head b/.rive_head index 0ec88f50..2080b430 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -da1bb77455deeafd48012a8eea5ea946a718fb77 +1c067cba8e291859c02a6d00dfe68033cf3cda8f diff --git a/dev/defs/layout/layout_component_style.json b/dev/defs/layout/layout_component_style.json index cb46d463..d96f7afb 100644 --- a/dev/defs/layout/layout_component_style.json +++ b/dev/defs/layout/layout_component_style.json @@ -317,12 +317,20 @@ }, "runtime": false }, - "scaleType": { + "layoutWidthScaleType": { "type": "uint", "initialValue": "0", "key": { - "int": 546, - "string": "scaletype" + "int": 655, + "string": "layoutwidthscaletype" + } + }, + "layoutHeightScaleType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 656, + "string": "layoutheightscaletype" } }, "layoutAlignmentType": { diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 7abe2d5a..9563b202 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -651,8 +651,11 @@ class CoreRegistry case SoloBase::activeComponentIdPropertyKey: object->as()->activeComponentId(value); break; - case LayoutComponentStyleBase::scaleTypePropertyKey: - object->as()->scaleType(value); + case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: + object->as()->layoutWidthScaleType(value); + break; + case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: + object->as()->layoutHeightScaleType(value); break; case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: object->as()->layoutAlignmentType(value); @@ -1734,8 +1737,10 @@ class CoreRegistry return object->as()->animationId(); case SoloBase::activeComponentIdPropertyKey: return object->as()->activeComponentId(); - case LayoutComponentStyleBase::scaleTypePropertyKey: - return object->as()->scaleType(); + case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: + return object->as()->layoutWidthScaleType(); + case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: + return object->as()->layoutHeightScaleType(); case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: return object->as()->layoutAlignmentType(); case LayoutComponentStyleBase::animationStyleTypePropertyKey: @@ -2439,7 +2444,8 @@ class CoreRegistry case NestedArtboardBase::artboardIdPropertyKey: case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: - case LayoutComponentStyleBase::scaleTypePropertyKey: + case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: + case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: case LayoutComponentStyleBase::animationStyleTypePropertyKey: case LayoutComponentStyleBase::interpolationTypePropertyKey: @@ -2888,7 +2894,9 @@ class CoreRegistry return object->is(); case SoloBase::activeComponentIdPropertyKey: return object->is(); - case LayoutComponentStyleBase::scaleTypePropertyKey: + case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: + return object->is(); + case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: return object->is(); case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: return object->is(); diff --git a/include/rive/generated/layout/layout_component_style_base.hpp b/include/rive/generated/layout/layout_component_style_base.hpp index a6f0cb56..13003f5b 100644 --- a/include/rive/generated/layout/layout_component_style_base.hpp +++ b/include/rive/generated/layout/layout_component_style_base.hpp @@ -57,7 +57,8 @@ class LayoutComponentStyleBase : public Component static const uint16_t flexShrinkPropertyKey = 522; static const uint16_t flexBasisPropertyKey = 523; static const uint16_t aspectRatioPropertyKey = 524; - static const uint16_t scaleTypePropertyKey = 546; + static const uint16_t layoutWidthScaleTypePropertyKey = 655; + static const uint16_t layoutHeightScaleTypePropertyKey = 656; static const uint16_t layoutAlignmentTypePropertyKey = 632; static const uint16_t animationStyleTypePropertyKey = 589; static const uint16_t interpolationTypePropertyKey = 590; @@ -132,7 +133,8 @@ class LayoutComponentStyleBase : public Component float m_FlexShrink = 1.0f; float m_FlexBasis = 1.0f; float m_AspectRatio = 0.0f; - uint32_t m_ScaleType = 0; + uint32_t m_LayoutWidthScaleType = 0; + uint32_t m_LayoutHeightScaleType = 0; uint32_t m_LayoutAlignmentType = 0; uint32_t m_AnimationStyleType = 0; uint32_t m_InterpolationType = 0; @@ -477,15 +479,26 @@ class LayoutComponentStyleBase : public Component aspectRatioChanged(); } - inline uint32_t scaleType() const { return m_ScaleType; } - void scaleType(uint32_t value) + inline uint32_t layoutWidthScaleType() const { return m_LayoutWidthScaleType; } + void layoutWidthScaleType(uint32_t value) { - if (m_ScaleType == value) + if (m_LayoutWidthScaleType == value) { return; } - m_ScaleType = value; - scaleTypeChanged(); + m_LayoutWidthScaleType = value; + layoutWidthScaleTypeChanged(); + } + + inline uint32_t layoutHeightScaleType() const { return m_LayoutHeightScaleType; } + void layoutHeightScaleType(uint32_t value) + { + if (m_LayoutHeightScaleType == value) + { + return; + } + m_LayoutHeightScaleType = value; + layoutHeightScaleTypeChanged(); } inline uint32_t layoutAlignmentType() const { return m_LayoutAlignmentType; } @@ -1013,7 +1026,8 @@ class LayoutComponentStyleBase : public Component m_FlexShrink = object.m_FlexShrink; m_FlexBasis = object.m_FlexBasis; m_AspectRatio = object.m_AspectRatio; - m_ScaleType = object.m_ScaleType; + m_LayoutWidthScaleType = object.m_LayoutWidthScaleType; + m_LayoutHeightScaleType = object.m_LayoutHeightScaleType; m_LayoutAlignmentType = object.m_LayoutAlignmentType; m_AnimationStyleType = object.m_AnimationStyleType; m_InterpolationType = object.m_InterpolationType; @@ -1147,8 +1161,11 @@ class LayoutComponentStyleBase : public Component case aspectRatioPropertyKey: m_AspectRatio = CoreDoubleType::deserialize(reader); return true; - case scaleTypePropertyKey: - m_ScaleType = CoreUintType::deserialize(reader); + case layoutWidthScaleTypePropertyKey: + m_LayoutWidthScaleType = CoreUintType::deserialize(reader); + return true; + case layoutHeightScaleTypePropertyKey: + m_LayoutHeightScaleType = CoreUintType::deserialize(reader); return true; case layoutAlignmentTypePropertyKey: m_LayoutAlignmentType = CoreUintType::deserialize(reader); @@ -1317,7 +1334,8 @@ class LayoutComponentStyleBase : public Component virtual void flexShrinkChanged() {} virtual void flexBasisChanged() {} virtual void aspectRatioChanged() {} - virtual void scaleTypeChanged() {} + virtual void layoutWidthScaleTypeChanged() {} + virtual void layoutHeightScaleTypeChanged() {} virtual void layoutAlignmentTypeChanged() {} virtual void animationStyleTypeChanged() {} virtual void interpolationTypeChanged() {} diff --git a/include/rive/layout/layout_component_style.hpp b/include/rive/layout/layout_component_style.hpp index 63274144..cab31c99 100644 --- a/include/rive/layout/layout_component_style.hpp +++ b/include/rive/layout/layout_component_style.hpp @@ -38,6 +38,13 @@ enum class LayoutAlignmentType : uint8_t spaceBetweenEnd }; +enum class LayoutScaleType : uint8_t +{ + fixed, + fill, + hug +}; + class KeyFrameInterpolator; class LayoutComponentStyle : public LayoutComponentStyleBase { @@ -57,6 +64,8 @@ class LayoutComponentStyle : public LayoutComponentStyleBase YGDisplay display(); YGPositionType positionType(); LayoutAlignmentType alignmentType(); + LayoutScaleType widthScaleType(); + LayoutScaleType heightScaleType(); YGFlexDirection flexDirection(); YGDirection direction(); @@ -100,6 +109,8 @@ class LayoutComponentStyle : public LayoutComponentStyleBase void markLayoutStyleDirty(); void layoutAlignmentTypeChanged() override; + void layoutWidthScaleTypeChanged() override; + void layoutHeightScaleTypeChanged() override; void displayValueChanged() override; void positionTypeValueChanged() override; void overflowValueChanged() override; diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index c0c4bdb4..b39a9c3e 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -56,6 +56,20 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public Artboard* getArtboard() override { return artboard(); } + LayoutComponent* layoutParent() + { + auto p = parent(); + while (p != nullptr) + { + if (p->is()) + { + return p->as(); + } + p = p->parent(); + } + return nullptr; + } + private: #ifdef WITH_RIVE_LAYOUT protected: diff --git a/src/layout/layout_component_style.cpp b/src/layout/layout_component_style.cpp index a9310be9..504a5bb0 100644 --- a/src/layout/layout_component_style.cpp +++ b/src/layout/layout_component_style.cpp @@ -25,6 +25,16 @@ LayoutAlignmentType LayoutComponentStyle::alignmentType() return LayoutAlignmentType(layoutAlignmentType()); } +LayoutScaleType LayoutComponentStyle::widthScaleType() +{ + return LayoutScaleType(layoutWidthScaleType()); +} + +LayoutScaleType LayoutComponentStyle::heightScaleType() +{ + return LayoutScaleType(layoutHeightScaleType()); +} + YGDisplay LayoutComponentStyle::display() { return YGDisplay(displayValue()); } YGPositionType LayoutComponentStyle::positionType() { return YGPositionType(positionTypeValue()); } @@ -133,6 +143,8 @@ void LayoutComponentStyle::markLayoutStyleDirty() {} #endif void LayoutComponentStyle::layoutAlignmentTypeChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::layoutWidthScaleTypeChanged() { markLayoutNodeDirty(); } +void LayoutComponentStyle::layoutHeightScaleTypeChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::displayValueChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::positionTypeValueChanged() { markLayoutNodeDirty(); } void LayoutComponentStyle::overflowValueChanged() { markLayoutNodeDirty(); } diff --git a/src/layout_component.cpp b/src/layout_component.cpp index 872e88ef..a032d8a3 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -241,6 +241,75 @@ void LayoutComponent::syncStyle() ygStyle.dimensions()[YGDimensionHeight] = YGValueAuto; } + if (layoutParent() != nullptr) + { + bool isRow = layoutParent()->style()->flexDirection() == YGFlexDirectionRow || + layoutParent()->style()->flexDirection() == YGFlexDirectionRowReverse; + switch (m_style->widthScaleType()) + { + case LayoutScaleType::fixed: + if (isRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + break; + case LayoutScaleType::fill: + if (isRow) + { + ygStyle.flexGrow() = YGFloatOptional(1); + } + else + { + ygStyle.alignSelf() = YGAlignStretch; + } + break; + case LayoutScaleType::hug: + if (isRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + else + { + ygStyle.alignSelf() = YGAlignAuto; + } + break; + default: + break; + } + bool isColumn = !isRow; + switch (m_style->heightScaleType()) + { + case LayoutScaleType::fixed: + if (isColumn) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + break; + case LayoutScaleType::fill: + if (isColumn) + { + ygStyle.flexGrow() = YGFloatOptional(1); + } + else + { + ygStyle.alignSelf() = YGAlignStretch; + } + break; + case LayoutScaleType::hug: + if (isColumn) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + else + { + ygStyle.alignSelf() = YGAlignAuto; + } + break; + default: + break; + } + } + bool isRowForAlignment = m_style->flexDirection() == YGFlexDirectionRow || m_style->flexDirection() == YGFlexDirectionRowReverse; switch (m_style->alignmentType()) @@ -364,15 +433,8 @@ void LayoutComponent::syncStyle() ygStyle.display() = m_style->display(); ygStyle.positionType() = m_style->positionType(); ygStyle.flex() = YGFloatOptional(m_style->flex()); - ygStyle.flexGrow() = YGFloatOptional(m_style->flexGrow()); - ygStyle.flexShrink() = YGFloatOptional(m_style->flexShrink()); - // ygStyle.flexBasis() = m_style->flexBasis(); ygStyle.flexDirection() = m_style->flexDirection(); ygStyle.flexWrap() = m_style->flexWrap(); - // ygStyle.alignItems() = m_style->alignItems(); - // ygStyle.alignContent() = m_style->alignContent(); - ygStyle.alignSelf() = m_style->alignSelf(); - // ygStyle.justifyContent() = m_style->justifyContent(); ygNode.setStyle(ygStyle); } From ef86d92f52bd20995ccd8cdee860cf06555b8869 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 26 Jul 2024 15:58:56 +0000 Subject: [PATCH 104/138] viewmodel transitions runtime adds support for viewmodel based transition conditions. added some comments on the most relevant parts. The rest is mostly boilerplate code from core objects. Diffs= d25b9097d viewmodel transitions runtime (#7680) Co-authored-by: hernan --- .rive_head | 2 +- dev/defs/animation/transition_comparator.json | 8 + dev/defs/animation/transition_condition.json | 13 +- .../animation/transition_input_condition.json | 22 +++ .../transition_property_comparator.json | 9 + ...nsition_property_viewmodel_comparator.json | 19 +++ .../transition_trigger_condition.json | 2 +- .../transition_value_boolean_comparator.json | 18 ++ .../transition_value_color_comparator.json | 18 ++ .../transition_value_comparator.json | 9 + .../animation/transition_value_condition.json | 2 +- .../transition_value_enum_comparator.json | 21 +++ .../transition_value_number_comparator.json | 18 ++ .../transition_value_string_comparator.json | 18 ++ .../transition_viewmodel_condition.json | 41 +++++ .../rive/animation/state_machine_instance.hpp | 2 + .../rive/animation/transition_comparator.hpp | 28 +++ .../rive/animation/transition_condition.hpp | 2 - .../animation/transition_input_condition.hpp | 16 ++ .../transition_property_comparator.hpp | 13 ++ ...ansition_property_viewmodel_comparator.hpp | 26 +++ .../transition_value_boolean_comparator.hpp | 16 ++ .../transition_value_color_comparator.hpp | 16 ++ .../animation/transition_value_comparator.hpp | 13 ++ .../transition_value_enum_comparator.hpp | 11 ++ .../transition_value_number_comparator.hpp | 16 ++ .../transition_value_string_comparator.hpp | 16 ++ .../transition_viewmodel_condition.hpp | 35 ++++ .../transition_bool_condition_base.hpp | 1 + .../animation/transition_comparator_base.hpp | 37 ++++ .../animation/transition_condition_base.hpp | 34 +--- .../transition_input_condition_base.hpp | 70 ++++++++ .../transition_number_condition_base.hpp | 1 + .../transition_property_comparator_base.hpp | 34 ++++ ...ion_property_viewmodel_comparator_base.hpp | 37 ++++ .../transition_trigger_condition_base.hpp | 7 +- ...ansition_value_boolean_comparator_base.hpp | 72 ++++++++ ...transition_value_color_comparator_base.hpp | 72 ++++++++ .../transition_value_comparator_base.hpp | 34 ++++ .../transition_value_condition_base.hpp | 11 +- .../transition_value_enum_comparator_base.hpp | 72 ++++++++ ...ransition_value_number_comparator_base.hpp | 72 ++++++++ ...ransition_value_string_comparator_base.hpp | 73 ++++++++ .../transition_viewmodel_condition_base.hpp | 107 ++++++++++++ include/rive/generated/core_registry.hpp | 103 +++++++++++- ...ransition_viewmodel_condition_importer.hpp | 23 +++ include/rive/viewmodel/viewmodel_instance.hpp | 1 + src/animation/state_machine_instance.cpp | 48 ++++++ src/animation/state_transition.cpp | 26 ++- src/animation/transition_comparator.cpp | 101 +++++++++++ src/animation/transition_condition.cpp | 17 -- src/animation/transition_input_condition.cpp | 26 +++ .../transition_property_comparator.cpp | 3 + ...ansition_property_viewmodel_comparator.cpp | 159 ++++++++++++++++++ .../transition_value_boolean_comparator.cpp | 16 ++ .../transition_value_color_comparator.cpp | 16 ++ .../transition_value_enum_comparator.cpp | 4 + .../transition_value_number_comparator.cpp | 16 ++ .../transition_value_string_comparator.cpp | 16 ++ .../transition_viewmodel_condition.cpp | 18 ++ src/data_bind/data_bind.cpp | 2 + src/file.cpp | 7 + ...ion_property_viewmodel_comparator_base.cpp | 11 ++ ...ansition_value_boolean_comparator_base.cpp | 11 ++ ...transition_value_color_comparator_base.cpp | 11 ++ .../transition_value_enum_comparator_base.cpp | 11 ++ ...ransition_value_number_comparator_base.cpp | 11 ++ ...ransition_value_string_comparator_base.cpp | 11 ++ .../transition_viewmodel_condition_base.cpp | 11 ++ ...ransition_viewmodel_condition_importer.cpp | 16 ++ src/viewmodel/viewmodel_instance.cpp | 25 +++ 71 files changed, 1799 insertions(+), 85 deletions(-) create mode 100644 dev/defs/animation/transition_comparator.json create mode 100644 dev/defs/animation/transition_input_condition.json create mode 100644 dev/defs/animation/transition_property_comparator.json create mode 100644 dev/defs/animation/transition_property_viewmodel_comparator.json create mode 100644 dev/defs/animation/transition_value_boolean_comparator.json create mode 100644 dev/defs/animation/transition_value_color_comparator.json create mode 100644 dev/defs/animation/transition_value_comparator.json create mode 100644 dev/defs/animation/transition_value_enum_comparator.json create mode 100644 dev/defs/animation/transition_value_number_comparator.json create mode 100644 dev/defs/animation/transition_value_string_comparator.json create mode 100644 dev/defs/animation/transition_viewmodel_condition.json create mode 100644 include/rive/animation/transition_comparator.hpp create mode 100644 include/rive/animation/transition_input_condition.hpp create mode 100644 include/rive/animation/transition_property_comparator.hpp create mode 100644 include/rive/animation/transition_property_viewmodel_comparator.hpp create mode 100644 include/rive/animation/transition_value_boolean_comparator.hpp create mode 100644 include/rive/animation/transition_value_color_comparator.hpp create mode 100644 include/rive/animation/transition_value_comparator.hpp create mode 100644 include/rive/animation/transition_value_enum_comparator.hpp create mode 100644 include/rive/animation/transition_value_number_comparator.hpp create mode 100644 include/rive/animation/transition_value_string_comparator.hpp create mode 100644 include/rive/animation/transition_viewmodel_condition.hpp create mode 100644 include/rive/generated/animation/transition_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_input_condition_base.hpp create mode 100644 include/rive/generated/animation/transition_property_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_property_viewmodel_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_value_boolean_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_value_color_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_value_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_value_enum_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_value_number_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_value_string_comparator_base.hpp create mode 100644 include/rive/generated/animation/transition_viewmodel_condition_base.hpp create mode 100644 include/rive/importers/transition_viewmodel_condition_importer.hpp create mode 100644 src/animation/transition_comparator.cpp create mode 100644 src/animation/transition_input_condition.cpp create mode 100644 src/animation/transition_property_comparator.cpp create mode 100644 src/animation/transition_property_viewmodel_comparator.cpp create mode 100644 src/animation/transition_value_boolean_comparator.cpp create mode 100644 src/animation/transition_value_color_comparator.cpp create mode 100644 src/animation/transition_value_enum_comparator.cpp create mode 100644 src/animation/transition_value_number_comparator.cpp create mode 100644 src/animation/transition_value_string_comparator.cpp create mode 100644 src/animation/transition_viewmodel_condition.cpp create mode 100644 src/generated/animation/transition_property_viewmodel_comparator_base.cpp create mode 100644 src/generated/animation/transition_value_boolean_comparator_base.cpp create mode 100644 src/generated/animation/transition_value_color_comparator_base.cpp create mode 100644 src/generated/animation/transition_value_enum_comparator_base.cpp create mode 100644 src/generated/animation/transition_value_number_comparator_base.cpp create mode 100644 src/generated/animation/transition_value_string_comparator_base.cpp create mode 100644 src/generated/animation/transition_viewmodel_condition_base.cpp create mode 100644 src/importers/transition_viewmodel_condition_importer.cpp diff --git a/.rive_head b/.rive_head index 2080b430..fd8e8678 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -1c067cba8e291859c02a6d00dfe68033cf3cda8f +d25b9097d65eecd2bb8ff35d84b98ad4e2803d30 diff --git a/dev/defs/animation/transition_comparator.json b/dev/defs/animation/transition_comparator.json new file mode 100644 index 00000000..5d01f6e2 --- /dev/null +++ b/dev/defs/animation/transition_comparator.json @@ -0,0 +1,8 @@ +{ + "name": "TransitionComparator", + "key": { + "int": 477, + "string": "transitioncomparator" + }, + "abstract": true +} \ No newline at end of file diff --git a/dev/defs/animation/transition_condition.json b/dev/defs/animation/transition_condition.json index 83365b50..660dbfcc 100644 --- a/dev/defs/animation/transition_condition.json +++ b/dev/defs/animation/transition_condition.json @@ -1,7 +1,7 @@ { "name": "TransitionCondition", "key": { - "int": 67, + "int": 476, "string": "transitioncondition" }, "abstract": true, @@ -28,17 +28,6 @@ }, "description": "Order value for condition in a transition.", "runtime": false - }, - "inputId": { - "type": "Id", - "typeRuntime": "uint", - "initialValue": "Core.missingId", - "initialValueRuntime": "-1", - "key": { - "int": 155, - "string": "inputid" - }, - "description": "Id of the StateMachineInput referenced." } } } \ No newline at end of file diff --git a/dev/defs/animation/transition_input_condition.json b/dev/defs/animation/transition_input_condition.json new file mode 100644 index 00000000..6a6331f7 --- /dev/null +++ b/dev/defs/animation/transition_input_condition.json @@ -0,0 +1,22 @@ +{ + "name": "TransitionInputCondition", + "key": { + "int": 67, + "string": "transitioninputcondition" + }, + "abstract": true, + "extends": "animation/transition_condition.json", + "properties": { + "inputId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 155, + "string": "inputid" + }, + "description": "Id of the StateMachineInput referenced." + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/transition_property_comparator.json b/dev/defs/animation/transition_property_comparator.json new file mode 100644 index 00000000..ee708a20 --- /dev/null +++ b/dev/defs/animation/transition_property_comparator.json @@ -0,0 +1,9 @@ +{ + "name": "TransitionPropertyComparator", + "key": { + "int": 478, + "string": "transitionpropertycomparator" + }, + "abstract": true, + "extends": "animation/transition_comparator.json" +} \ No newline at end of file diff --git a/dev/defs/animation/transition_property_viewmodel_comparator.json b/dev/defs/animation/transition_property_viewmodel_comparator.json new file mode 100644 index 00000000..94b11fb7 --- /dev/null +++ b/dev/defs/animation/transition_property_viewmodel_comparator.json @@ -0,0 +1,19 @@ +{ + "name": "TransitionPropertyViewModelComparator", + "key": { + "int": 479, + "string": "transitionpropertyviewmodelcomparator" + }, + "extends": "animation/transition_property_comparator.json", + "properties": { + "bindablePropertyId": { + "type": "Id", + "key": { + "int": 646, + "string": "bindablepropertyid" + }, + "description": "Id of the bindable property used as comparator", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/transition_trigger_condition.json b/dev/defs/animation/transition_trigger_condition.json index 63c9e494..855dc655 100644 --- a/dev/defs/animation/transition_trigger_condition.json +++ b/dev/defs/animation/transition_trigger_condition.json @@ -4,5 +4,5 @@ "int": 68, "string": "transitiontriggercondition" }, - "extends": "animation/transition_condition.json" + "extends": "animation/transition_input_condition.json" } \ No newline at end of file diff --git a/dev/defs/animation/transition_value_boolean_comparator.json b/dev/defs/animation/transition_value_boolean_comparator.json new file mode 100644 index 00000000..c2ee3bf3 --- /dev/null +++ b/dev/defs/animation/transition_value_boolean_comparator.json @@ -0,0 +1,18 @@ +{ + "name": "TransitionValueBooleanComparator", + "key": { + "int": 481, + "string": "transitionvaluebooleancomparator" + }, + "extends": "animation/transition_value_comparator.json", + "properties": { + "value": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 647, + "string": "value" + } + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/transition_value_color_comparator.json b/dev/defs/animation/transition_value_color_comparator.json new file mode 100644 index 00000000..ec5d41f8 --- /dev/null +++ b/dev/defs/animation/transition_value_color_comparator.json @@ -0,0 +1,18 @@ +{ + "name": "TransitionValueColorComparator", + "key": { + "int": 483, + "string": "transitionvaluecolorcomparator" + }, + "extends": "animation/transition_value_comparator.json", + "properties": { + "value": { + "type": "Color", + "initialValue": "0xFF1D1D1D", + "key": { + "int": 651, + "string": "value" + } + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/transition_value_comparator.json b/dev/defs/animation/transition_value_comparator.json new file mode 100644 index 00000000..d428fadb --- /dev/null +++ b/dev/defs/animation/transition_value_comparator.json @@ -0,0 +1,9 @@ +{ + "name": "TransitionValueComparator", + "key": { + "int": 480, + "string": "transitionvaluecomparator" + }, + "abstract": true, + "extends": "animation/transition_comparator.json" +} \ No newline at end of file diff --git a/dev/defs/animation/transition_value_condition.json b/dev/defs/animation/transition_value_condition.json index 8f5a8834..381326f7 100644 --- a/dev/defs/animation/transition_value_condition.json +++ b/dev/defs/animation/transition_value_condition.json @@ -5,7 +5,7 @@ "string": "transitionvaluecondition" }, "abstract": true, - "extends": "animation/transition_condition.json", + "extends": "animation/transition_input_condition.json", "properties": { "opValue": { "type": "uint", diff --git a/dev/defs/animation/transition_value_enum_comparator.json b/dev/defs/animation/transition_value_enum_comparator.json new file mode 100644 index 00000000..54c364c6 --- /dev/null +++ b/dev/defs/animation/transition_value_enum_comparator.json @@ -0,0 +1,21 @@ +{ + "name": "TransitionValueEnumComparator", + "key": { + "int": 485, + "string": "transitionvalueenumcomparator" + }, + "extends": "animation/transition_value_comparator.json", + "properties": { + "value": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 653, + "string": "value" + }, + "description": "The id of the enum to compare the condition to" + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/transition_value_number_comparator.json b/dev/defs/animation/transition_value_number_comparator.json new file mode 100644 index 00000000..7ad7656d --- /dev/null +++ b/dev/defs/animation/transition_value_number_comparator.json @@ -0,0 +1,18 @@ +{ + "name": "TransitionValueNumberComparator", + "key": { + "int": 484, + "string": "transitionvaluenumbercomparator" + }, + "extends": "animation/transition_value_comparator.json", + "properties": { + "value": { + "type": "double", + "initialValue": "0", + "key": { + "int": 652, + "string": "value" + } + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/transition_value_string_comparator.json b/dev/defs/animation/transition_value_string_comparator.json new file mode 100644 index 00000000..7f7cdd78 --- /dev/null +++ b/dev/defs/animation/transition_value_string_comparator.json @@ -0,0 +1,18 @@ +{ + "name": "TransitionValueStringComparator", + "key": { + "int": 486, + "string": "transitionvaluestringcomparator" + }, + "extends": "animation/transition_value_comparator.json", + "properties": { + "value": { + "type": "String", + "initialValue": "''", + "key": { + "int": 654, + "string": "value" + } + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/transition_viewmodel_condition.json b/dev/defs/animation/transition_viewmodel_condition.json new file mode 100644 index 00000000..714abb19 --- /dev/null +++ b/dev/defs/animation/transition_viewmodel_condition.json @@ -0,0 +1,41 @@ +{ + "name": "TransitionViewModelCondition", + "key": { + "int": 482, + "string": "transitionviewmodelcondition" + }, + "extends": "animation/transition_condition.json", + "properties": { + "leftComparatorId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 648, + "string": "leftcomparatorid" + }, + "description": "The id of the left comaprand to use for this condition" + }, + "rightComparatorId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 649, + "string": "rightcomparatorid" + }, + "description": "The id of the right comaprand to use for this condition" + }, + "opValue": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 650, + "string": "opvalue" + }, + "description": "Integer representation of the StateMachineOp enum." + } + } +} \ No newline at end of file diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index f7ffea16..a2c86008 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -147,6 +147,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne return nullptr; } #endif + void updateDataBinds(); private: std::vector m_reportedEvents; @@ -160,6 +161,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne NestedArtboard* m_parentNestedArtboard = nullptr; std::vector m_dataBinds; std::unordered_map m_bindablePropertyInstances; + #ifdef WITH_RIVE_TOOLS public: void onInputChanged(InputChanged callback) { m_inputChangedCallback = callback; } diff --git a/include/rive/animation/transition_comparator.hpp b/include/rive/animation/transition_comparator.hpp new file mode 100644 index 00000000..5757ad2c --- /dev/null +++ b/include/rive/animation/transition_comparator.hpp @@ -0,0 +1,28 @@ +#ifndef _RIVE_TRANSITION_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_comparator_base.hpp" +#include "rive/animation/transition_condition_op.hpp" +#include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/viewmodel/viewmodel_instance_value.hpp" +#include +namespace rive +{ +class StateMachineInstance; +class TransitionComparator : public TransitionComparatorBase +{ +public: + StatusCode import(ImportStack& importStack) override; + virtual bool compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance); + +protected: + bool compareNumbers(float left, float right, TransitionConditionOp op); + bool compareBooleans(bool left, bool right, TransitionConditionOp op); + bool compareEnums(uint16_t left, uint16_t right, TransitionConditionOp op); + bool compareColors(int left, int right, TransitionConditionOp op); + bool compareStrings(std::string left, std::string right, TransitionConditionOp op); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_condition.hpp b/include/rive/animation/transition_condition.hpp index 51980138..5336f4d8 100644 --- a/include/rive/animation/transition_condition.hpp +++ b/include/rive/animation/transition_condition.hpp @@ -15,8 +15,6 @@ class TransitionCondition : public TransitionConditionBase StatusCode import(ImportStack& importStack) override; - virtual bool evaluate(const SMIInput* inputInstance) const { return true; } - protected: virtual bool validateInputType(const StateMachineInput* input) const { return true; } }; diff --git a/include/rive/animation/transition_input_condition.hpp b/include/rive/animation/transition_input_condition.hpp new file mode 100644 index 00000000..b6c65174 --- /dev/null +++ b/include/rive/animation/transition_input_condition.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_TRANSITION_INPUT_CONDITION_HPP_ +#define _RIVE_TRANSITION_INPUT_CONDITION_HPP_ +#include "rive/generated/animation/transition_input_condition_base.hpp" +#include +namespace rive +{ +class TransitionInputCondition : public TransitionInputConditionBase +{ +public: + virtual bool evaluate(const SMIInput* inputInstance) const { return true; } + + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_property_comparator.hpp b/include/rive/animation/transition_property_comparator.hpp new file mode 100644 index 00000000..e2d9914a --- /dev/null +++ b/include/rive/animation/transition_property_comparator.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_PROPERTY_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_property_comparator_base.hpp" +#include +namespace rive +{ +class TransitionPropertyComparator : public TransitionPropertyComparatorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_property_viewmodel_comparator.hpp b/include/rive/animation/transition_property_viewmodel_comparator.hpp new file mode 100644 index 00000000..6dec8ed1 --- /dev/null +++ b/include/rive/animation/transition_property_viewmodel_comparator.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_VIEW_MODEL_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_PROPERTY_VIEW_MODEL_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_property_viewmodel_comparator_base.hpp" +#include "rive/data_bind/bindable_property.hpp" +#include +namespace rive +{ +class TransitionPropertyViewModelComparator : public TransitionPropertyViewModelComparatorBase +{ +public: + StatusCode import(ImportStack& importStack) override; + bool compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) override; + float propertyValueNumber(StateMachineInstance* stateMachineInstance); + std::string propertyValueString(StateMachineInstance* stateMachineInstance); + int propertyValueColor(StateMachineInstance* stateMachineInstance); + bool propertyValueBoolean(StateMachineInstance* stateMachineInstance); + uint16_t propertyValueEnum(StateMachineInstance* stateMachineInstance); + +protected: + BindableProperty* m_bindableProperty; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_value_boolean_comparator.hpp b/include/rive/animation/transition_value_boolean_comparator.hpp new file mode 100644 index 00000000..de5590bb --- /dev/null +++ b/include/rive/animation/transition_value_boolean_comparator.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_TRANSITION_VALUE_BOOLEAN_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_BOOLEAN_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_boolean_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueBooleanComparator : public TransitionValueBooleanComparatorBase +{ +public: + bool compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_value_color_comparator.hpp b/include/rive/animation/transition_value_color_comparator.hpp new file mode 100644 index 00000000..6e13bb1c --- /dev/null +++ b/include/rive/animation/transition_value_color_comparator.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_TRANSITION_VALUE_COLOR_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_COLOR_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_color_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueColorComparator : public TransitionValueColorComparatorBase +{ +public: + bool compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_value_comparator.hpp b/include/rive/animation/transition_value_comparator.hpp new file mode 100644 index 00000000..4ebba61b --- /dev/null +++ b/include/rive/animation/transition_value_comparator.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_TRANSITION_VALUE_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueComparator : public TransitionValueComparatorBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_value_enum_comparator.hpp b/include/rive/animation/transition_value_enum_comparator.hpp new file mode 100644 index 00000000..62bd13d3 --- /dev/null +++ b/include/rive/animation/transition_value_enum_comparator.hpp @@ -0,0 +1,11 @@ +#ifndef _RIVE_TRANSITION_VALUE_ENUM_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_ENUM_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_enum_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueEnumComparator : public TransitionValueEnumComparatorBase +{}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_value_number_comparator.hpp b/include/rive/animation/transition_value_number_comparator.hpp new file mode 100644 index 00000000..cd882076 --- /dev/null +++ b/include/rive/animation/transition_value_number_comparator.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_TRANSITION_VALUE_NUMBER_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_NUMBER_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_number_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueNumberComparator : public TransitionValueNumberComparatorBase +{ +public: + bool compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_value_string_comparator.hpp b/include/rive/animation/transition_value_string_comparator.hpp new file mode 100644 index 00000000..ac0136dd --- /dev/null +++ b/include/rive/animation/transition_value_string_comparator.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_TRANSITION_VALUE_STRING_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_VALUE_STRING_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_value_string_comparator_base.hpp" +#include +namespace rive +{ +class TransitionValueStringComparator : public TransitionValueStringComparatorBase +{ +public: + bool compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_viewmodel_condition.hpp b/include/rive/animation/transition_viewmodel_condition.hpp new file mode 100644 index 00000000..2d5efb9e --- /dev/null +++ b/include/rive/animation/transition_viewmodel_condition.hpp @@ -0,0 +1,35 @@ +#ifndef _RIVE_TRANSITION_VIEW_MODEL_CONDITION_HPP_ +#define _RIVE_TRANSITION_VIEW_MODEL_CONDITION_HPP_ +#include "rive/generated/animation/transition_viewmodel_condition_base.hpp" +#include "rive/animation/transition_comparator.hpp" +#include "rive/animation/transition_condition_op.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include +namespace rive +{ +class TransitionViewModelCondition : public TransitionViewModelConditionBase +{ +protected: + TransitionComparator* m_leftComparator; + TransitionComparator* m_rightComparator; + +public: + bool evaluateCondition(StateMachineInstance* stateMachineInstance); + TransitionComparator* leftComparator() { return m_leftComparator; }; + TransitionComparator* rightComparator() { return m_rightComparator; }; + void comparator(TransitionComparator* value) + { + if (m_leftComparator == nullptr) + { + m_leftComparator = value; + } + else + { + m_rightComparator = value; + } + }; + TransitionConditionOp op() const { return (TransitionConditionOp)opValue(); } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_bool_condition_base.hpp b/include/rive/generated/animation/transition_bool_condition_base.hpp index 8567f376..c9783eab 100644 --- a/include/rive/generated/animation/transition_bool_condition_base.hpp +++ b/include/rive/generated/animation/transition_bool_condition_base.hpp @@ -19,6 +19,7 @@ class TransitionBoolConditionBase : public TransitionValueCondition { case TransitionBoolConditionBase::typeKey: case TransitionValueConditionBase::typeKey: + case TransitionInputConditionBase::typeKey: case TransitionConditionBase::typeKey: return true; default: diff --git a/include/rive/generated/animation/transition_comparator_base.hpp b/include/rive/generated/animation/transition_comparator_base.hpp new file mode 100644 index 00000000..7b66f88f --- /dev/null +++ b/include/rive/generated/animation/transition_comparator_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_TRANSITION_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_COMPARATOR_BASE_HPP_ +#include "rive/core.hpp" +namespace rive +{ +class TransitionComparatorBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 477; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + void copy(const TransitionComparatorBase& object) {} + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { return false; } + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_condition_base.hpp b/include/rive/generated/animation/transition_condition_base.hpp index e0ec5daa..23145d54 100644 --- a/include/rive/generated/animation/transition_condition_base.hpp +++ b/include/rive/generated/animation/transition_condition_base.hpp @@ -1,7 +1,6 @@ #ifndef _RIVE_TRANSITION_CONDITION_BASE_HPP_ #define _RIVE_TRANSITION_CONDITION_BASE_HPP_ #include "rive/core.hpp" -#include "rive/core/field_types/core_uint_type.hpp" namespace rive { class TransitionConditionBase : public Core @@ -10,7 +9,7 @@ class TransitionConditionBase : public Core typedef Core Super; public: - static const uint16_t typeKey = 67; + static const uint16_t typeKey = 476; /// Helper to quickly determine if a core object extends another without RTTI /// at runtime. @@ -27,38 +26,11 @@ class TransitionConditionBase : public Core uint16_t coreType() const override { return typeKey; } - static const uint16_t inputIdPropertyKey = 155; + void copy(const TransitionConditionBase& object) {} -private: - uint32_t m_InputId = -1; - -public: - inline uint32_t inputId() const { return m_InputId; } - void inputId(uint32_t value) - { - if (m_InputId == value) - { - return; - } - m_InputId = value; - inputIdChanged(); - } - - void copy(const TransitionConditionBase& object) { m_InputId = object.m_InputId; } - - bool deserialize(uint16_t propertyKey, BinaryReader& reader) override - { - switch (propertyKey) - { - case inputIdPropertyKey: - m_InputId = CoreUintType::deserialize(reader); - return true; - } - return false; - } + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { return false; } protected: - virtual void inputIdChanged() {} }; } // namespace rive diff --git a/include/rive/generated/animation/transition_input_condition_base.hpp b/include/rive/generated/animation/transition_input_condition_base.hpp new file mode 100644 index 00000000..1440bf7b --- /dev/null +++ b/include/rive/generated/animation/transition_input_condition_base.hpp @@ -0,0 +1,70 @@ +#ifndef _RIVE_TRANSITION_INPUT_CONDITION_BASE_HPP_ +#define _RIVE_TRANSITION_INPUT_CONDITION_BASE_HPP_ +#include "rive/animation/transition_condition.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class TransitionInputConditionBase : public TransitionCondition +{ +protected: + typedef TransitionCondition Super; + +public: + static const uint16_t typeKey = 67; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionInputConditionBase::typeKey: + case TransitionConditionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t inputIdPropertyKey = 155; + +private: + uint32_t m_InputId = -1; + +public: + inline uint32_t inputId() const { return m_InputId; } + void inputId(uint32_t value) + { + if (m_InputId == value) + { + return; + } + m_InputId = value; + inputIdChanged(); + } + + void copy(const TransitionInputConditionBase& object) + { + m_InputId = object.m_InputId; + TransitionCondition::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case inputIdPropertyKey: + m_InputId = CoreUintType::deserialize(reader); + return true; + } + return TransitionCondition::deserialize(propertyKey, reader); + } + +protected: + virtual void inputIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_number_condition_base.hpp b/include/rive/generated/animation/transition_number_condition_base.hpp index 5d4cc796..82e1a81b 100644 --- a/include/rive/generated/animation/transition_number_condition_base.hpp +++ b/include/rive/generated/animation/transition_number_condition_base.hpp @@ -20,6 +20,7 @@ class TransitionNumberConditionBase : public TransitionValueCondition { case TransitionNumberConditionBase::typeKey: case TransitionValueConditionBase::typeKey: + case TransitionInputConditionBase::typeKey: case TransitionConditionBase::typeKey: return true; default: diff --git a/include/rive/generated/animation/transition_property_comparator_base.hpp b/include/rive/generated/animation/transition_property_comparator_base.hpp new file mode 100644 index 00000000..33497c27 --- /dev/null +++ b/include/rive/generated/animation/transition_property_comparator_base.hpp @@ -0,0 +1,34 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_PROPERTY_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_comparator.hpp" +namespace rive +{ +class TransitionPropertyComparatorBase : public TransitionComparator +{ +protected: + typedef TransitionComparator Super; + +public: + static const uint16_t typeKey = 478; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionPropertyComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_property_viewmodel_comparator_base.hpp b/include/rive/generated/animation/transition_property_viewmodel_comparator_base.hpp new file mode 100644 index 00000000..d7d2168b --- /dev/null +++ b/include/rive/generated/animation/transition_property_viewmodel_comparator_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_VIEW_MODEL_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_PROPERTY_VIEW_MODEL_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_property_comparator.hpp" +namespace rive +{ +class TransitionPropertyViewModelComparatorBase : public TransitionPropertyComparator +{ +protected: + typedef TransitionPropertyComparator Super; + +public: + static const uint16_t typeKey = 479; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionPropertyViewModelComparatorBase::typeKey: + case TransitionPropertyComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_trigger_condition_base.hpp b/include/rive/generated/animation/transition_trigger_condition_base.hpp index b10c5590..902f1a42 100644 --- a/include/rive/generated/animation/transition_trigger_condition_base.hpp +++ b/include/rive/generated/animation/transition_trigger_condition_base.hpp @@ -1,12 +1,12 @@ #ifndef _RIVE_TRANSITION_TRIGGER_CONDITION_BASE_HPP_ #define _RIVE_TRANSITION_TRIGGER_CONDITION_BASE_HPP_ -#include "rive/animation/transition_condition.hpp" +#include "rive/animation/transition_input_condition.hpp" namespace rive { -class TransitionTriggerConditionBase : public TransitionCondition +class TransitionTriggerConditionBase : public TransitionInputCondition { protected: - typedef TransitionCondition Super; + typedef TransitionInputCondition Super; public: static const uint16_t typeKey = 68; @@ -18,6 +18,7 @@ class TransitionTriggerConditionBase : public TransitionCondition switch (typeKey) { case TransitionTriggerConditionBase::typeKey: + case TransitionInputConditionBase::typeKey: case TransitionConditionBase::typeKey: return true; default: diff --git a/include/rive/generated/animation/transition_value_boolean_comparator_base.hpp b/include/rive/generated/animation/transition_value_boolean_comparator_base.hpp new file mode 100644 index 00000000..bdbcf289 --- /dev/null +++ b/include/rive/generated/animation/transition_value_boolean_comparator_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_TRANSITION_VALUE_BOOLEAN_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_BOOLEAN_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_value_comparator.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +namespace rive +{ +class TransitionValueBooleanComparatorBase : public TransitionValueComparator +{ +protected: + typedef TransitionValueComparator Super; + +public: + static const uint16_t typeKey = 481; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueBooleanComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 647; + +private: + bool m_Value = false; + +public: + inline bool value() const { return m_Value; } + void value(bool value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const TransitionValueBooleanComparatorBase& object) + { + m_Value = object.m_Value; + TransitionValueComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreBoolType::deserialize(reader); + return true; + } + return TransitionValueComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_value_color_comparator_base.hpp b/include/rive/generated/animation/transition_value_color_comparator_base.hpp new file mode 100644 index 00000000..f44d2be8 --- /dev/null +++ b/include/rive/generated/animation/transition_value_color_comparator_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_TRANSITION_VALUE_COLOR_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_COLOR_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_value_comparator.hpp" +#include "rive/core/field_types/core_color_type.hpp" +namespace rive +{ +class TransitionValueColorComparatorBase : public TransitionValueComparator +{ +protected: + typedef TransitionValueComparator Super; + +public: + static const uint16_t typeKey = 483; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueColorComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 651; + +private: + int m_Value = 0xFF1D1D1D; + +public: + inline int value() const { return m_Value; } + void value(int value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const TransitionValueColorComparatorBase& object) + { + m_Value = object.m_Value; + TransitionValueComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreColorType::deserialize(reader); + return true; + } + return TransitionValueComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_value_comparator_base.hpp b/include/rive/generated/animation/transition_value_comparator_base.hpp new file mode 100644 index 00000000..aced3729 --- /dev/null +++ b/include/rive/generated/animation/transition_value_comparator_base.hpp @@ -0,0 +1,34 @@ +#ifndef _RIVE_TRANSITION_VALUE_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_comparator.hpp" +namespace rive +{ +class TransitionValueComparatorBase : public TransitionComparator +{ +protected: + typedef TransitionComparator Super; + +public: + static const uint16_t typeKey = 480; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_value_condition_base.hpp b/include/rive/generated/animation/transition_value_condition_base.hpp index 9fe2c464..e9c680e8 100644 --- a/include/rive/generated/animation/transition_value_condition_base.hpp +++ b/include/rive/generated/animation/transition_value_condition_base.hpp @@ -1,13 +1,13 @@ #ifndef _RIVE_TRANSITION_VALUE_CONDITION_BASE_HPP_ #define _RIVE_TRANSITION_VALUE_CONDITION_BASE_HPP_ -#include "rive/animation/transition_condition.hpp" +#include "rive/animation/transition_input_condition.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { -class TransitionValueConditionBase : public TransitionCondition +class TransitionValueConditionBase : public TransitionInputCondition { protected: - typedef TransitionCondition Super; + typedef TransitionInputCondition Super; public: static const uint16_t typeKey = 69; @@ -19,6 +19,7 @@ class TransitionValueConditionBase : public TransitionCondition switch (typeKey) { case TransitionValueConditionBase::typeKey: + case TransitionInputConditionBase::typeKey: case TransitionConditionBase::typeKey: return true; default: @@ -48,7 +49,7 @@ class TransitionValueConditionBase : public TransitionCondition void copy(const TransitionValueConditionBase& object) { m_OpValue = object.m_OpValue; - TransitionCondition::copy(object); + TransitionInputCondition::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override @@ -59,7 +60,7 @@ class TransitionValueConditionBase : public TransitionCondition m_OpValue = CoreUintType::deserialize(reader); return true; } - return TransitionCondition::deserialize(propertyKey, reader); + return TransitionInputCondition::deserialize(propertyKey, reader); } protected: diff --git a/include/rive/generated/animation/transition_value_enum_comparator_base.hpp b/include/rive/generated/animation/transition_value_enum_comparator_base.hpp new file mode 100644 index 00000000..ec9bb455 --- /dev/null +++ b/include/rive/generated/animation/transition_value_enum_comparator_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_TRANSITION_VALUE_ENUM_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_ENUM_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_value_comparator.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class TransitionValueEnumComparatorBase : public TransitionValueComparator +{ +protected: + typedef TransitionValueComparator Super; + +public: + static const uint16_t typeKey = 485; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueEnumComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 653; + +private: + uint32_t m_Value = -1; + +public: + inline uint32_t value() const { return m_Value; } + void value(uint32_t value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const TransitionValueEnumComparatorBase& object) + { + m_Value = object.m_Value; + TransitionValueComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreUintType::deserialize(reader); + return true; + } + return TransitionValueComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_value_number_comparator_base.hpp b/include/rive/generated/animation/transition_value_number_comparator_base.hpp new file mode 100644 index 00000000..7fc7e7cd --- /dev/null +++ b/include/rive/generated/animation/transition_value_number_comparator_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_TRANSITION_VALUE_NUMBER_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_NUMBER_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_value_comparator.hpp" +#include "rive/core/field_types/core_double_type.hpp" +namespace rive +{ +class TransitionValueNumberComparatorBase : public TransitionValueComparator +{ +protected: + typedef TransitionValueComparator Super; + +public: + static const uint16_t typeKey = 484; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueNumberComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 652; + +private: + float m_Value = 0.0f; + +public: + inline float value() const { return m_Value; } + void value(float value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const TransitionValueNumberComparatorBase& object) + { + m_Value = object.m_Value; + TransitionValueComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreDoubleType::deserialize(reader); + return true; + } + return TransitionValueComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_value_string_comparator_base.hpp b/include/rive/generated/animation/transition_value_string_comparator_base.hpp new file mode 100644 index 00000000..ecd1740c --- /dev/null +++ b/include/rive/generated/animation/transition_value_string_comparator_base.hpp @@ -0,0 +1,73 @@ +#ifndef _RIVE_TRANSITION_VALUE_STRING_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_VALUE_STRING_COMPARATOR_BASE_HPP_ +#include +#include "rive/animation/transition_value_comparator.hpp" +#include "rive/core/field_types/core_string_type.hpp" +namespace rive +{ +class TransitionValueStringComparatorBase : public TransitionValueComparator +{ +protected: + typedef TransitionValueComparator Super; + +public: + static const uint16_t typeKey = 486; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionValueStringComparatorBase::typeKey: + case TransitionValueComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 654; + +private: + std::string m_Value = ""; + +public: + inline const std::string& value() const { return m_Value; } + void value(std::string value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + Core* clone() const override; + void copy(const TransitionValueStringComparatorBase& object) + { + m_Value = object.m_Value; + TransitionValueComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreStringType::deserialize(reader); + return true; + } + return TransitionValueComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_viewmodel_condition_base.hpp b/include/rive/generated/animation/transition_viewmodel_condition_base.hpp new file mode 100644 index 00000000..7c156a47 --- /dev/null +++ b/include/rive/generated/animation/transition_viewmodel_condition_base.hpp @@ -0,0 +1,107 @@ +#ifndef _RIVE_TRANSITION_VIEW_MODEL_CONDITION_BASE_HPP_ +#define _RIVE_TRANSITION_VIEW_MODEL_CONDITION_BASE_HPP_ +#include "rive/animation/transition_condition.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class TransitionViewModelConditionBase : public TransitionCondition +{ +protected: + typedef TransitionCondition Super; + +public: + static const uint16_t typeKey = 482; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionViewModelConditionBase::typeKey: + case TransitionConditionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t leftComparatorIdPropertyKey = 648; + static const uint16_t rightComparatorIdPropertyKey = 649; + static const uint16_t opValuePropertyKey = 650; + +private: + uint32_t m_LeftComparatorId = -1; + uint32_t m_RightComparatorId = -1; + uint32_t m_OpValue = 0; + +public: + inline uint32_t leftComparatorId() const { return m_LeftComparatorId; } + void leftComparatorId(uint32_t value) + { + if (m_LeftComparatorId == value) + { + return; + } + m_LeftComparatorId = value; + leftComparatorIdChanged(); + } + + inline uint32_t rightComparatorId() const { return m_RightComparatorId; } + void rightComparatorId(uint32_t value) + { + if (m_RightComparatorId == value) + { + return; + } + m_RightComparatorId = value; + rightComparatorIdChanged(); + } + + inline uint32_t opValue() const { return m_OpValue; } + void opValue(uint32_t value) + { + if (m_OpValue == value) + { + return; + } + m_OpValue = value; + opValueChanged(); + } + + Core* clone() const override; + void copy(const TransitionViewModelConditionBase& object) + { + m_LeftComparatorId = object.m_LeftComparatorId; + m_RightComparatorId = object.m_RightComparatorId; + m_OpValue = object.m_OpValue; + TransitionCondition::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case leftComparatorIdPropertyKey: + m_LeftComparatorId = CoreUintType::deserialize(reader); + return true; + case rightComparatorIdPropertyKey: + m_RightComparatorId = CoreUintType::deserialize(reader); + return true; + case opValuePropertyKey: + m_OpValue = CoreUintType::deserialize(reader); + return true; + } + return TransitionCondition::deserialize(propertyKey, reader); + } + +protected: + virtual void leftComparatorIdChanged() {} + virtual void rightComparatorIdChanged() {} + virtual void opValueChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 9563b202..65a3ac90 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -59,10 +59,21 @@ #include "rive/animation/state_machine_trigger.hpp" #include "rive/animation/state_transition.hpp" #include "rive/animation/transition_bool_condition.hpp" +#include "rive/animation/transition_comparator.hpp" #include "rive/animation/transition_condition.hpp" +#include "rive/animation/transition_input_condition.hpp" #include "rive/animation/transition_number_condition.hpp" +#include "rive/animation/transition_property_comparator.hpp" +#include "rive/animation/transition_property_viewmodel_comparator.hpp" #include "rive/animation/transition_trigger_condition.hpp" +#include "rive/animation/transition_value_boolean_comparator.hpp" +#include "rive/animation/transition_value_color_comparator.hpp" +#include "rive/animation/transition_value_comparator.hpp" #include "rive/animation/transition_value_condition.hpp" +#include "rive/animation/transition_value_enum_comparator.hpp" +#include "rive/animation/transition_value_number_comparator.hpp" +#include "rive/animation/transition_value_string_comparator.hpp" +#include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/artboard.hpp" #include "rive/assets/asset.hpp" #include "rive/assets/audio_asset.hpp" @@ -290,6 +301,8 @@ class CoreRegistry return new KeyedProperty(); case StateMachineListenerBase::typeKey: return new StateMachineListener(); + case TransitionPropertyViewModelComparatorBase::typeKey: + return new TransitionPropertyViewModelComparator(); case KeyFrameIdBase::typeKey: return new KeyFrameId(); case KeyFrameBoolBase::typeKey: @@ -300,6 +313,8 @@ class CoreRegistry return new ListenerAlignTarget(); case TransitionNumberConditionBase::typeKey: return new TransitionNumberCondition(); + case TransitionValueBooleanComparatorBase::typeKey: + return new TransitionValueBooleanComparator(); case AnyStateBase::typeKey: return new AnyState(); case CubicInterpolatorComponentBase::typeKey: @@ -310,6 +325,8 @@ class CoreRegistry return new KeyFrameString(); case ListenerNumberChangeBase::typeKey: return new ListenerNumberChange(); + case TransitionViewModelConditionBase::typeKey: + return new TransitionViewModelCondition(); case CubicEaseInterpolatorBase::typeKey: return new CubicEaseInterpolator(); case StateTransitionBase::typeKey: @@ -330,10 +347,14 @@ class CoreRegistry return new LinearAnimation(); case StateMachineTriggerBase::typeKey: return new StateMachineTrigger(); + case TransitionValueColorComparatorBase::typeKey: + return new TransitionValueColorComparator(); case ListenerTriggerChangeBase::typeKey: return new ListenerTriggerChange(); case BlendStateDirectBase::typeKey: return new BlendStateDirect(); + case TransitionValueNumberComparatorBase::typeKey: + return new TransitionValueNumberComparator(); case NestedStateMachineBase::typeKey: return new NestedStateMachine(); case ElasticInterpolatorBase::typeKey: @@ -344,8 +365,12 @@ class CoreRegistry return new NestedNumber(); case BlendState1DBase::typeKey: return new BlendState1D(); + case TransitionValueEnumComparatorBase::typeKey: + return new TransitionValueEnumComparator(); case KeyFrameCallbackBase::typeKey: return new KeyFrameCallback(); + case TransitionValueStringComparatorBase::typeKey: + return new TransitionValueStringComparator(); case NestedRemapAnimationBase::typeKey: return new NestedRemapAnimation(); case TransitionBoolConditionBase::typeKey: @@ -534,6 +559,9 @@ class CoreRegistry case ListenerAlignTargetBase::preserveOffsetPropertyKey: object->as()->preserveOffset(value); break; + case TransitionValueBooleanComparatorBase::valuePropertyKey: + object->as()->value(value); + break; case NestedBoolBase::nestedValuePropertyKey: object->as()->nestedValue(value); break; @@ -813,8 +841,8 @@ class CoreRegistry case BlendAnimationDirectBase::blendSourcePropertyKey: object->as()->blendSource(value); break; - case TransitionConditionBase::inputIdPropertyKey: - object->as()->inputId(value); + case TransitionInputConditionBase::inputIdPropertyKey: + object->as()->inputId(value); break; case KeyedPropertyBase::propertyKeyPropertyKey: object->as()->propertyKey(value); @@ -840,6 +868,15 @@ class CoreRegistry case TransitionValueConditionBase::opValuePropertyKey: object->as()->opValue(value); break; + case TransitionViewModelConditionBase::leftComparatorIdPropertyKey: + object->as()->leftComparatorId(value); + break; + case TransitionViewModelConditionBase::rightComparatorIdPropertyKey: + object->as()->rightComparatorId(value); + break; + case TransitionViewModelConditionBase::opValuePropertyKey: + object->as()->opValue(value); + break; case StateTransitionBase::stateToIdPropertyKey: object->as()->stateToId(value); break; @@ -888,6 +925,9 @@ class CoreRegistry case BlendState1DBase::inputIdPropertyKey: object->as()->inputId(value); break; + case TransitionValueEnumComparatorBase::valuePropertyKey: + object->as()->value(value); + break; case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: object->as()->exitBlendAnimationId(value); break; @@ -1041,6 +1081,9 @@ class CoreRegistry case KeyFrameColorBase::valuePropertyKey: object->as()->value(value); break; + case TransitionValueColorComparatorBase::valuePropertyKey: + object->as()->value(value); + break; case SolidColorBase::colorValuePropertyKey: object->as()->colorValue(value); break; @@ -1080,6 +1123,9 @@ class CoreRegistry case KeyFrameStringBase::valuePropertyKey: object->as()->value(value); break; + case TransitionValueStringComparatorBase::valuePropertyKey: + object->as()->value(value); + break; case OpenUrlEventBase::urlPropertyKey: object->as()->url(value); break; @@ -1310,6 +1356,9 @@ class CoreRegistry case LinearAnimationBase::speedPropertyKey: object->as()->speed(value); break; + case TransitionValueNumberComparatorBase::valuePropertyKey: + object->as()->value(value); + break; case ElasticInterpolatorBase::amplitudePropertyKey: object->as()->amplitude(value); break; @@ -1656,6 +1705,8 @@ class CoreRegistry return object->as()->value(); case ListenerAlignTargetBase::preserveOffsetPropertyKey: return object->as()->preserveOffset(); + case TransitionValueBooleanComparatorBase::valuePropertyKey: + return object->as()->value(); case NestedBoolBase::nestedValuePropertyKey: return object->as()->nestedValue(); case LinearAnimationBase::enableWorkAreaPropertyKey: @@ -1845,8 +1896,8 @@ class CoreRegistry return object->as()->inputId(); case BlendAnimationDirectBase::blendSourcePropertyKey: return object->as()->blendSource(); - case TransitionConditionBase::inputIdPropertyKey: - return object->as()->inputId(); + case TransitionInputConditionBase::inputIdPropertyKey: + return object->as()->inputId(); case KeyedPropertyBase::propertyKeyPropertyKey: return object->as()->propertyKey(); case StateMachineListenerBase::targetIdPropertyKey: @@ -1863,6 +1914,12 @@ class CoreRegistry return object->as()->targetId(); case TransitionValueConditionBase::opValuePropertyKey: return object->as()->opValue(); + case TransitionViewModelConditionBase::leftComparatorIdPropertyKey: + return object->as()->leftComparatorId(); + case TransitionViewModelConditionBase::rightComparatorIdPropertyKey: + return object->as()->rightComparatorId(); + case TransitionViewModelConditionBase::opValuePropertyKey: + return object->as()->opValue(); case StateTransitionBase::stateToIdPropertyKey: return object->as()->stateToId(); case StateTransitionBase::flagsPropertyKey: @@ -1895,6 +1952,8 @@ class CoreRegistry return object->as()->easingValue(); case BlendState1DBase::inputIdPropertyKey: return object->as()->inputId(); + case TransitionValueEnumComparatorBase::valuePropertyKey: + return object->as()->value(); case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: return object->as()->exitBlendAnimationId(); case StrokeBase::capPropertyKey: @@ -2000,6 +2059,8 @@ class CoreRegistry return object->as()->propertyValue(); case KeyFrameColorBase::valuePropertyKey: return object->as()->value(); + case TransitionValueColorComparatorBase::valuePropertyKey: + return object->as()->value(); case SolidColorBase::colorValuePropertyKey: return object->as()->colorValue(); case GradientStopBase::colorValuePropertyKey: @@ -2029,6 +2090,8 @@ class CoreRegistry return object->as()->name(); case KeyFrameStringBase::valuePropertyKey: return object->as()->value(); + case TransitionValueStringComparatorBase::valuePropertyKey: + return object->as()->value(); case OpenUrlEventBase::urlPropertyKey: return object->as()->url(); case BindablePropertyStringBase::propertyValuePropertyKey: @@ -2186,6 +2249,8 @@ class CoreRegistry return object->as()->value(); case LinearAnimationBase::speedPropertyKey: return object->as()->speed(); + case TransitionValueNumberComparatorBase::valuePropertyKey: + return object->as()->value(); case ElasticInterpolatorBase::amplitudePropertyKey: return object->as()->amplitude(); case ElasticInterpolatorBase::periodPropertyKey: @@ -2406,6 +2471,7 @@ class CoreRegistry case NestedSimpleAnimationBase::isPlayingPropertyKey: case KeyFrameBoolBase::valuePropertyKey: case ListenerAlignTargetBase::preserveOffsetPropertyKey: + case TransitionValueBooleanComparatorBase::valuePropertyKey: case NestedBoolBase::nestedValuePropertyKey: case LinearAnimationBase::enableWorkAreaPropertyKey: case LinearAnimationBase::quantizePropertyKey: @@ -2498,7 +2564,7 @@ class CoreRegistry case BlendAnimationBase::animationIdPropertyKey: case BlendAnimationDirectBase::inputIdPropertyKey: case BlendAnimationDirectBase::blendSourcePropertyKey: - case TransitionConditionBase::inputIdPropertyKey: + case TransitionInputConditionBase::inputIdPropertyKey: case KeyedPropertyBase::propertyKeyPropertyKey: case StateMachineListenerBase::targetIdPropertyKey: case StateMachineListenerBase::listenerTypeValuePropertyKey: @@ -2507,6 +2573,9 @@ class CoreRegistry case ListenerBoolChangeBase::valuePropertyKey: case ListenerAlignTargetBase::targetIdPropertyKey: case TransitionValueConditionBase::opValuePropertyKey: + case TransitionViewModelConditionBase::leftComparatorIdPropertyKey: + case TransitionViewModelConditionBase::rightComparatorIdPropertyKey: + case TransitionViewModelConditionBase::opValuePropertyKey: case StateTransitionBase::stateToIdPropertyKey: case StateTransitionBase::flagsPropertyKey: case StateTransitionBase::durationPropertyKey: @@ -2523,6 +2592,7 @@ class CoreRegistry case LinearAnimationBase::workEndPropertyKey: case ElasticInterpolatorBase::easingValuePropertyKey: case BlendState1DBase::inputIdPropertyKey: + case TransitionValueEnumComparatorBase::valuePropertyKey: case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: case StrokeBase::capPropertyKey: case StrokeBase::joinPropertyKey: @@ -2573,6 +2643,7 @@ class CoreRegistry return CoreUintType::id; case ViewModelInstanceColorBase::propertyValuePropertyKey: case KeyFrameColorBase::valuePropertyKey: + case TransitionValueColorComparatorBase::valuePropertyKey: case SolidColorBase::colorValuePropertyKey: case GradientStopBase::colorValuePropertyKey: case BindablePropertyColorBase::propertyValuePropertyKey: @@ -2585,6 +2656,7 @@ class CoreRegistry case AnimationBase::namePropertyKey: case StateMachineComponentBase::namePropertyKey: case KeyFrameStringBase::valuePropertyKey: + case TransitionValueStringComparatorBase::valuePropertyKey: case OpenUrlEventBase::urlPropertyKey: case BindablePropertyStringBase::propertyValuePropertyKey: case TextValueRunBase::textPropertyKey: @@ -2662,6 +2734,7 @@ class CoreRegistry case ListenerNumberChangeBase::valuePropertyKey: case KeyFrameDoubleBase::valuePropertyKey: case LinearAnimationBase::speedPropertyKey: + case TransitionValueNumberComparatorBase::valuePropertyKey: case ElasticInterpolatorBase::amplitudePropertyKey: case ElasticInterpolatorBase::periodPropertyKey: case NestedNumberBase::nestedValuePropertyKey: @@ -2820,6 +2893,8 @@ class CoreRegistry return object->is(); case ListenerAlignTargetBase::preserveOffsetPropertyKey: return object->is(); + case TransitionValueBooleanComparatorBase::valuePropertyKey: + return object->is(); case NestedBoolBase::nestedValuePropertyKey: return object->is(); case LinearAnimationBase::enableWorkAreaPropertyKey: @@ -3002,8 +3077,8 @@ class CoreRegistry return object->is(); case BlendAnimationDirectBase::blendSourcePropertyKey: return object->is(); - case TransitionConditionBase::inputIdPropertyKey: - return object->is(); + case TransitionInputConditionBase::inputIdPropertyKey: + return object->is(); case KeyedPropertyBase::propertyKeyPropertyKey: return object->is(); case StateMachineListenerBase::targetIdPropertyKey: @@ -3020,6 +3095,12 @@ class CoreRegistry return object->is(); case TransitionValueConditionBase::opValuePropertyKey: return object->is(); + case TransitionViewModelConditionBase::leftComparatorIdPropertyKey: + return object->is(); + case TransitionViewModelConditionBase::rightComparatorIdPropertyKey: + return object->is(); + case TransitionViewModelConditionBase::opValuePropertyKey: + return object->is(); case StateTransitionBase::stateToIdPropertyKey: return object->is(); case StateTransitionBase::flagsPropertyKey: @@ -3052,6 +3133,8 @@ class CoreRegistry return object->is(); case BlendState1DBase::inputIdPropertyKey: return object->is(); + case TransitionValueEnumComparatorBase::valuePropertyKey: + return object->is(); case BlendStateTransitionBase::exitBlendAnimationIdPropertyKey: return object->is(); case StrokeBase::capPropertyKey: @@ -3150,6 +3233,8 @@ class CoreRegistry return object->is(); case KeyFrameColorBase::valuePropertyKey: return object->is(); + case TransitionValueColorComparatorBase::valuePropertyKey: + return object->is(); case SolidColorBase::colorValuePropertyKey: return object->is(); case GradientStopBase::colorValuePropertyKey: @@ -3172,6 +3257,8 @@ class CoreRegistry return object->is(); case KeyFrameStringBase::valuePropertyKey: return object->is(); + case TransitionValueStringComparatorBase::valuePropertyKey: + return object->is(); case OpenUrlEventBase::urlPropertyKey: return object->is(); case BindablePropertyStringBase::propertyValuePropertyKey: @@ -3322,6 +3409,8 @@ class CoreRegistry return object->is(); case LinearAnimationBase::speedPropertyKey: return object->is(); + case TransitionValueNumberComparatorBase::valuePropertyKey: + return object->is(); case ElasticInterpolatorBase::amplitudePropertyKey: return object->is(); case ElasticInterpolatorBase::periodPropertyKey: diff --git a/include/rive/importers/transition_viewmodel_condition_importer.hpp b/include/rive/importers/transition_viewmodel_condition_importer.hpp new file mode 100644 index 00000000..7cf92bdc --- /dev/null +++ b/include/rive/importers/transition_viewmodel_condition_importer.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_TRANSITION_VIEWMODEL_CONDITION_IMPORTER_HPP_ +#define _RIVE_TRANSITION_VIEWMODEL_CONDITION_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class TransitionViewModelCondition; +class TransitionComparator; +class DataBind; + +class TransitionViewModelConditionImporter : public ImportStackObject +{ +private: + TransitionViewModelCondition* m_TransitionViewModelCondition; + +public: + TransitionViewModelConditionImporter( + TransitionViewModelCondition* transitionViewModelCondition); + void setComparator(TransitionComparator* comparator); +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/viewmodel/viewmodel_instance.hpp b/include/rive/viewmodel/viewmodel_instance.hpp index f5ecd5ad..3a6375a9 100644 --- a/include/rive/viewmodel/viewmodel_instance.hpp +++ b/include/rive/viewmodel/viewmodel_instance.hpp @@ -18,6 +18,7 @@ class ViewModelInstance : public ViewModelInstanceBase ViewModelInstanceValue* propertyValue(const uint32_t id); ViewModelInstanceValue* propertyValue(const std::string& name); std::vector propertyValues(); + ViewModelInstanceValue* propertyFromPath(std::vector* path, size_t index); void viewModel(ViewModel* value); ViewModel* viewModel() const; void onComponentDirty(Component* component); diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 0b8a112d..6f006f74 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -20,7 +20,11 @@ #include "rive/animation/state_machine.hpp" #include "rive/animation/state_transition.hpp" #include "rive/animation/transition_condition.hpp" +#include "rive/animation/transition_comparator.hpp" +#include "rive/animation/transition_property_viewmodel_comparator.hpp" +#include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/animation/state_machine_fire_event.hpp" +#include "rive/data_bind_flags.hpp" #include "rive/event_report.hpp" #include "rive/hit_result.hpp" #include "rive/math/aabb.hpp" @@ -746,6 +750,36 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, m_layers[i].init(this, machine->layer(i), m_artboardInstance); } + // Initialize dataBinds. All databinds are cloned for the state machine instance. + // That enables binding each instance to its own context without polluting the rest. + auto dataBindCount = machine->dataBindCount(); + for (size_t i = 0; i < dataBindCount; i++) + { + auto dataBind = machine->dataBind(i); + auto dataBindClone = static_cast(dataBind->clone()); + m_dataBinds.push_back(dataBindClone); + if (dataBind->target()->is()) + { + auto bindableProperty = dataBind->target()->as(); + auto bindablePropertyInstance = m_bindablePropertyInstances.find(bindableProperty); + BindableProperty* bindablePropertyClone; + if (bindablePropertyInstance == m_bindablePropertyInstances.end()) + { + bindablePropertyClone = bindableProperty->clone()->as(); + m_bindablePropertyInstances[bindableProperty] = bindablePropertyClone; + } + else + { + bindablePropertyClone = bindablePropertyInstance->second; + } + dataBindClone->target(bindablePropertyClone); + if (static_cast(dataBindClone->flags()) == DataBindFlags::ToSource) + { + bindablePropertyClone->dataBind(dataBindClone); + } + } + } + // Initialize listeners. Store a lookup table of shape id to hit shape // representation (an object that stores all the listeners triggered by the // shape producing a listener). @@ -855,8 +889,22 @@ void StateMachineInstance::sortHitComponents() } } +void StateMachineInstance::updateDataBinds() +{ + for (auto dataBind : m_dataBinds) + { + auto d = dataBind->dirt(); + if (d != ComponentDirt::None) + { + dataBind->dirt(ComponentDirt::None); + dataBind->update(d); + } + } +} + bool StateMachineInstance::advance(float seconds) { + updateDataBinds(); if (m_artboardInstance->hasChangedDrawOrderInLastUpdate()) { sortHitComponents(); diff --git a/src/animation/state_transition.cpp b/src/animation/state_transition.cpp index 1d9bf088..560f82ce 100644 --- a/src/animation/state_transition.cpp +++ b/src/animation/state_transition.cpp @@ -8,7 +8,10 @@ #include "rive/animation/state_transition.hpp" #include "rive/animation/transition_condition.hpp" #include "rive/animation/transition_trigger_condition.hpp" +#include "rive/animation/transition_input_condition.hpp" +#include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/transition_property_viewmodel_comparator.hpp" #include "rive/importers/import_stack.hpp" #include "rive/importers/layer_state_importer.hpp" @@ -147,13 +150,26 @@ AllowTransition StateTransition::allowed(StateInstance* stateFrom, for (auto condition : m_Conditions) { - // N.B. state machine instance sanitizes these for us... - auto input = stateMachineInstance->input(condition->inputId()); + if (condition->is()) + { + auto inputCondition = condition->as(); + // N.B. state machine instance sanitizes these for us... + auto input = stateMachineInstance->input(inputCondition->inputId()); - if ((ignoreTriggers && condition->is()) || - !condition->evaluate(input)) + if ((ignoreTriggers && inputCondition->is()) || + !inputCondition->evaluate(input)) + { + return AllowTransition::no; + } + } + else if (condition->is()) { - return AllowTransition::no; + auto transitionViewModelCondition = condition->as(); + + if (!transitionViewModelCondition->evaluateCondition(stateMachineInstance)) + { + return AllowTransition::no; + } } } diff --git a/src/animation/transition_comparator.cpp b/src/animation/transition_comparator.cpp new file mode 100644 index 00000000..73b9db9b --- /dev/null +++ b/src/animation/transition_comparator.cpp @@ -0,0 +1,101 @@ +#include "rive/animation/transition_comparator.hpp" +#include "rive/animation/transition_viewmodel_condition.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/importers/transition_viewmodel_condition_importer.hpp" + +using namespace rive; + +StatusCode TransitionComparator::import(ImportStack& importStack) +{ + auto transitionViewModelConditionImporter = + importStack.latest( + TransitionViewModelCondition::typeKey); + if (transitionViewModelConditionImporter == nullptr) + { + return StatusCode::MissingObject; + } + transitionViewModelConditionImporter->setComparator(this); + return Super::import(importStack); +} + +bool TransitionComparator::compareNumbers(float left, float right, TransitionConditionOp op) +{ + switch (op) + { + case TransitionConditionOp::equal: + return left == right; + case TransitionConditionOp::notEqual: + return left != right; + case TransitionConditionOp::lessThanOrEqual: + return left <= right; + case TransitionConditionOp::lessThan: + return left < right; + case TransitionConditionOp::greaterThanOrEqual: + return left >= right; + case TransitionConditionOp::greaterThan: + return left > right; + default: + return false; + } +} + +bool TransitionComparator::compareStrings(std::string left, + std::string right, + TransitionConditionOp op) +{ + switch (op) + { + case TransitionConditionOp::equal: + return left == right; + case TransitionConditionOp::notEqual: + return left != right; + default: + return false; + } +} + +bool TransitionComparator::compareBooleans(bool left, bool right, TransitionConditionOp op) +{ + switch (op) + { + case TransitionConditionOp::equal: + return left == right; + case TransitionConditionOp::notEqual: + return left != right; + default: + return false; + } +} + +bool TransitionComparator::compareEnums(uint16_t left, uint16_t right, TransitionConditionOp op) +{ + switch (op) + { + case TransitionConditionOp::equal: + return left == right; + case TransitionConditionOp::notEqual: + return left != right; + default: + return false; + } +} + +bool TransitionComparator::compareColors(int left, int right, TransitionConditionOp op) +{ + switch (op) + { + case TransitionConditionOp::equal: + return left == right; + case TransitionConditionOp::notEqual: + return left != right; + default: + return false; + } +} + +bool TransitionComparator::compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) +{ + return false; +} \ No newline at end of file diff --git a/src/animation/transition_condition.cpp b/src/animation/transition_condition.cpp index 23b0fe68..6385f289 100644 --- a/src/animation/transition_condition.cpp +++ b/src/animation/transition_condition.cpp @@ -1,8 +1,6 @@ #include "rive/animation/transition_bool_condition.hpp" #include "rive/animation/state_transition.hpp" #include "rive/importers/state_transition_importer.hpp" -#include "rive/importers/state_machine_importer.hpp" -#include "rive/animation/state_machine.hpp" using namespace rive; @@ -12,21 +10,6 @@ StatusCode TransitionCondition::onAddedClean(CoreContext* context) { return Stat StatusCode TransitionCondition::import(ImportStack& importStack) { - auto stateMachineImporter = importStack.latest(StateMachine::typeKey); - if (stateMachineImporter == nullptr) - { - return StatusCode::MissingObject; - } - - // Make sure the inputId doesn't overflow the input buffer. - if ((size_t)inputId() >= stateMachineImporter->stateMachine()->inputCount()) - { - return StatusCode::InvalidObject; - } - if (!validateInputType(stateMachineImporter->stateMachine()->input((size_t)inputId()))) - { - return StatusCode::InvalidObject; - } auto transitionImporter = importStack.latest(StateTransition::typeKey); if (transitionImporter == nullptr) diff --git a/src/animation/transition_input_condition.cpp b/src/animation/transition_input_condition.cpp new file mode 100644 index 00000000..52fd89e3 --- /dev/null +++ b/src/animation/transition_input_condition.cpp @@ -0,0 +1,26 @@ +#include "rive/animation/transition_input_condition.hpp" +#include "rive/importers/state_machine_importer.hpp" +#include "rive/animation/state_machine.hpp" + +using namespace rive; + +StatusCode TransitionInputCondition::import(ImportStack& importStack) +{ + auto stateMachineImporter = importStack.latest(StateMachine::typeKey); + if (stateMachineImporter == nullptr) + { + return StatusCode::MissingObject; + } + + // Make sure the inputId doesn't overflow the input buffer. + if ((size_t)inputId() >= stateMachineImporter->stateMachine()->inputCount()) + { + return StatusCode::InvalidObject; + } + if (!validateInputType(stateMachineImporter->stateMachine()->input((size_t)inputId()))) + { + return StatusCode::InvalidObject; + } + + return Super::import(importStack); +} \ No newline at end of file diff --git a/src/animation/transition_property_comparator.cpp b/src/animation/transition_property_comparator.cpp new file mode 100644 index 00000000..05d25ae2 --- /dev/null +++ b/src/animation/transition_property_comparator.cpp @@ -0,0 +1,3 @@ +#include "rive/animation/transition_property_comparator.hpp" + +using namespace rive; \ No newline at end of file diff --git a/src/animation/transition_property_viewmodel_comparator.cpp b/src/animation/transition_property_viewmodel_comparator.cpp new file mode 100644 index 00000000..8d931523 --- /dev/null +++ b/src/animation/transition_property_viewmodel_comparator.cpp @@ -0,0 +1,159 @@ +#include "rive/animation/transition_property_viewmodel_comparator.hpp" +#include "rive/animation/transition_value_number_comparator.hpp" +#include "rive/animation/transition_value_string_comparator.hpp" +#include "rive/animation/transition_value_color_comparator.hpp" +#include "rive/animation/transition_value_boolean_comparator.hpp" +#include "rive/animation/transition_value_enum_comparator.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/importers/bindable_property_importer.hpp" +#include "rive/data_bind/bindable_property_number.hpp" +#include "rive/data_bind/bindable_property_string.hpp" +#include "rive/data_bind/bindable_property_color.hpp" +#include "rive/data_bind/bindable_property_enum.hpp" +#include "rive/data_bind/bindable_property_boolean.hpp" + +using namespace rive; + +StatusCode TransitionPropertyViewModelComparator::import(ImportStack& importStack) +{ + auto bindablePropertyImporter = + importStack.latest(BindablePropertyBase::typeKey); + if (bindablePropertyImporter == nullptr) + { + return StatusCode::MissingObject; + } + m_bindableProperty = bindablePropertyImporter->bindableProperty(); + + return Super::import(importStack); +} + +float TransitionPropertyViewModelComparator::propertyValueNumber( + StateMachineInstance* stateMachineInstance) +{ + auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + return bindableInstance->as()->propertyValue(); +} + +std::string TransitionPropertyViewModelComparator::propertyValueString( + StateMachineInstance* stateMachineInstance) +{ + auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + return bindableInstance->as()->propertyValue(); +} + +int TransitionPropertyViewModelComparator::propertyValueColor( + StateMachineInstance* stateMachineInstance) +{ + auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + return bindableInstance->as()->propertyValue(); +} + +bool TransitionPropertyViewModelComparator::propertyValueBoolean( + StateMachineInstance* stateMachineInstance) +{ + auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + return bindableInstance->as()->propertyValue(); +} + +uint16_t TransitionPropertyViewModelComparator::propertyValueEnum( + StateMachineInstance* stateMachineInstance) +{ + auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + return bindableInstance->as()->propertyValue(); +} + +bool TransitionPropertyViewModelComparator::compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) +{ + switch (m_bindableProperty->coreType()) + { + case BindablePropertyNumber::typeKey: + if (comparand->is()) + { + auto rightValue = + comparand->as()->propertyValueNumber( + stateMachineInstance); + return compareNumbers(propertyValueNumber(stateMachineInstance), + rightValue, + operation); + } + else if (comparand->is()) + { + auto rightValue = comparand->as()->value(); + return compareNumbers(propertyValueNumber(stateMachineInstance), + rightValue, + operation); + } + break; + case BindablePropertyString::typeKey: + if (comparand->is()) + { + auto rightValue = + comparand->as()->propertyValueString( + stateMachineInstance); + return compareStrings(propertyValueString(stateMachineInstance), + rightValue, + operation); + } + else if (comparand->is()) + { + auto rightValue = comparand->as()->value(); + return compareStrings(propertyValueString(stateMachineInstance), + rightValue, + operation); + } + break; + case BindablePropertyColor::typeKey: + if (comparand->is()) + { + auto rightValue = + comparand->as()->propertyValueColor( + stateMachineInstance); + return compareColors(propertyValueColor(stateMachineInstance), + rightValue, + operation); + } + else if (comparand->is()) + { + auto rightValue = comparand->as()->value(); + return compareColors(propertyValueColor(stateMachineInstance), + rightValue, + operation); + } + break; + case BindablePropertyBoolean::typeKey: + if (comparand->is()) + { + auto rightValue = + comparand->as()->propertyValueBoolean( + stateMachineInstance); + return compareBooleans(propertyValueBoolean(stateMachineInstance), + rightValue, + operation); + } + else if (comparand->is()) + { + auto rightValue = comparand->as()->value(); + return compareBooleans(propertyValueBoolean(stateMachineInstance), + rightValue, + operation); + } + break; + case BindablePropertyEnum::typeKey: + if (comparand->is()) + { + auto rightValue = + comparand->as()->propertyValueEnum( + stateMachineInstance); + return compareEnums(propertyValueEnum(stateMachineInstance), rightValue, operation); + } + else if (comparand->is()) + { + auto rightValue = comparand->as()->value(); + return compareEnums(propertyValueEnum(stateMachineInstance), rightValue, operation); + } + break; + } + return false; +} \ No newline at end of file diff --git a/src/animation/transition_value_boolean_comparator.cpp b/src/animation/transition_value_boolean_comparator.cpp new file mode 100644 index 00000000..e26f8682 --- /dev/null +++ b/src/animation/transition_value_boolean_comparator.cpp @@ -0,0 +1,16 @@ +#include "rive/animation/transition_value_boolean_comparator.hpp" + +using namespace rive; + +bool TransitionValueBooleanComparator::compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) +{ + if (comparand->is()) + { + return compareBooleans(value(), + comparand->as()->value(), + operation); + } + return false; +} \ No newline at end of file diff --git a/src/animation/transition_value_color_comparator.cpp b/src/animation/transition_value_color_comparator.cpp new file mode 100644 index 00000000..c4fe60e6 --- /dev/null +++ b/src/animation/transition_value_color_comparator.cpp @@ -0,0 +1,16 @@ +#include "rive/animation/transition_value_color_comparator.hpp" + +using namespace rive; + +bool TransitionValueColorComparator::compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) +{ + if (comparand->is()) + { + return compareColors(value(), + comparand->as()->value(), + operation); + } + return false; +} \ No newline at end of file diff --git a/src/animation/transition_value_enum_comparator.cpp b/src/animation/transition_value_enum_comparator.cpp new file mode 100644 index 00000000..8742e37d --- /dev/null +++ b/src/animation/transition_value_enum_comparator.cpp @@ -0,0 +1,4 @@ +#include "rive/animation/transition_value_enum_comparator.hpp" +#include "rive/viewmodel/viewmodel_instance_enum.hpp" + +using namespace rive; \ No newline at end of file diff --git a/src/animation/transition_value_number_comparator.cpp b/src/animation/transition_value_number_comparator.cpp new file mode 100644 index 00000000..c4f05d55 --- /dev/null +++ b/src/animation/transition_value_number_comparator.cpp @@ -0,0 +1,16 @@ +#include "rive/animation/transition_value_number_comparator.hpp" + +using namespace rive; + +bool TransitionValueNumberComparator::compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) +{ + if (comparand->is()) + { + return compareNumbers(value(), + comparand->as()->value(), + operation); + } + return false; +} \ No newline at end of file diff --git a/src/animation/transition_value_string_comparator.cpp b/src/animation/transition_value_string_comparator.cpp new file mode 100644 index 00000000..d62a1a34 --- /dev/null +++ b/src/animation/transition_value_string_comparator.cpp @@ -0,0 +1,16 @@ +#include "rive/animation/transition_value_string_comparator.hpp" + +using namespace rive; + +bool TransitionValueStringComparator::compare(TransitionComparator* comparand, + TransitionConditionOp operation, + StateMachineInstance* stateMachineInstance) +{ + if (comparand->is()) + { + return compareStrings(value(), + comparand->as()->value(), + operation); + } + return false; +} \ No newline at end of file diff --git a/src/animation/transition_viewmodel_condition.cpp b/src/animation/transition_viewmodel_condition.cpp new file mode 100644 index 00000000..40d2a078 --- /dev/null +++ b/src/animation/transition_viewmodel_condition.cpp @@ -0,0 +1,18 @@ +#include "rive/animation/transition_viewmodel_condition.hpp" +#include "rive/animation/state_transition.hpp" +#include "rive/importers/state_transition_importer.hpp" +#include "rive/importers/state_machine_importer.hpp" +#include "rive/animation/state_machine.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/component_dirt.hpp" + +using namespace rive; + +bool TransitionViewModelCondition::evaluateCondition(StateMachineInstance* stateMachineInstance) +{ + if (leftComparator() != nullptr && rightComparator() != nullptr) + { + return leftComparator()->compare(rightComparator(), op(), stateMachineInstance); + } + return false; +} \ No newline at end of file diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp index a1ab7151..9877f5b8 100644 --- a/src/data_bind/data_bind.cpp +++ b/src/data_bind/data_bind.cpp @@ -14,6 +14,7 @@ #include "rive/data_bind/context/context_value_enum.hpp" #include "rive/data_bind/context/context_value_list.hpp" #include "rive/data_bind/context/context_value_color.hpp" +#include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/animation/state_machine.hpp" #include "rive/importers/artboard_importer.hpp" #include "rive/importers/state_machine_importer.hpp" @@ -42,6 +43,7 @@ StatusCode DataBind::import(ImportStack& importStack) case BindablePropertyBooleanBase::typeKey: case BindablePropertyEnumBase::typeKey: case BindablePropertyColorBase::typeKey: + case TransitionPropertyViewModelComparatorBase::typeKey: { auto stateMachineImporter = importStack.latest(StateMachineBase::typeKey); diff --git a/src/file.cpp b/src/file.cpp index 57fb4a72..96da6840 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -21,6 +21,7 @@ #include "rive/importers/layer_state_importer.hpp" #include "rive/importers/state_transition_importer.hpp" #include "rive/importers/state_machine_layer_component_importer.hpp" +#include "rive/importers/transition_viewmodel_condition_importer.hpp" #include "rive/importers/viewmodel_importer.hpp" #include "rive/importers/viewmodel_instance_importer.hpp" #include "rive/importers/viewmodel_instance_list_importer.hpp" @@ -31,6 +32,7 @@ #include "rive/animation/animation_state.hpp" #include "rive/animation/blend_state_1d.hpp" #include "rive/animation/blend_state_direct.hpp" +#include "rive/animation/transition_property_viewmodel_comparator.hpp" #include "rive/data_bind/bindable_property.hpp" #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" @@ -372,6 +374,11 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) object->as()); stackType = ViewModelInstanceList::typeKey; break; + case TransitionViewModelCondition::typeKey: + stackObject = rivestd::make_unique( + object->as()); + stackType = TransitionViewModelCondition::typeKey; + break; case BindablePropertyNumber::typeKey: case BindablePropertyString::typeKey: case BindablePropertyColor::typeKey: diff --git a/src/generated/animation/transition_property_viewmodel_comparator_base.cpp b/src/generated/animation/transition_property_viewmodel_comparator_base.cpp new file mode 100644 index 00000000..8c0c2d64 --- /dev/null +++ b/src/generated/animation/transition_property_viewmodel_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_property_viewmodel_comparator_base.hpp" +#include "rive/animation/transition_property_viewmodel_comparator.hpp" + +using namespace rive; + +Core* TransitionPropertyViewModelComparatorBase::clone() const +{ + auto cloned = new TransitionPropertyViewModelComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/transition_value_boolean_comparator_base.cpp b/src/generated/animation/transition_value_boolean_comparator_base.cpp new file mode 100644 index 00000000..3e9a2ef7 --- /dev/null +++ b/src/generated/animation/transition_value_boolean_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_boolean_comparator_base.hpp" +#include "rive/animation/transition_value_boolean_comparator.hpp" + +using namespace rive; + +Core* TransitionValueBooleanComparatorBase::clone() const +{ + auto cloned = new TransitionValueBooleanComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/transition_value_color_comparator_base.cpp b/src/generated/animation/transition_value_color_comparator_base.cpp new file mode 100644 index 00000000..a199f5fe --- /dev/null +++ b/src/generated/animation/transition_value_color_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_color_comparator_base.hpp" +#include "rive/animation/transition_value_color_comparator.hpp" + +using namespace rive; + +Core* TransitionValueColorComparatorBase::clone() const +{ + auto cloned = new TransitionValueColorComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/transition_value_enum_comparator_base.cpp b/src/generated/animation/transition_value_enum_comparator_base.cpp new file mode 100644 index 00000000..dad87896 --- /dev/null +++ b/src/generated/animation/transition_value_enum_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_enum_comparator_base.hpp" +#include "rive/animation/transition_value_enum_comparator.hpp" + +using namespace rive; + +Core* TransitionValueEnumComparatorBase::clone() const +{ + auto cloned = new TransitionValueEnumComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/transition_value_number_comparator_base.cpp b/src/generated/animation/transition_value_number_comparator_base.cpp new file mode 100644 index 00000000..8ebecac8 --- /dev/null +++ b/src/generated/animation/transition_value_number_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_number_comparator_base.hpp" +#include "rive/animation/transition_value_number_comparator.hpp" + +using namespace rive; + +Core* TransitionValueNumberComparatorBase::clone() const +{ + auto cloned = new TransitionValueNumberComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/transition_value_string_comparator_base.cpp b/src/generated/animation/transition_value_string_comparator_base.cpp new file mode 100644 index 00000000..07db01d5 --- /dev/null +++ b/src/generated/animation/transition_value_string_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_value_string_comparator_base.hpp" +#include "rive/animation/transition_value_string_comparator.hpp" + +using namespace rive; + +Core* TransitionValueStringComparatorBase::clone() const +{ + auto cloned = new TransitionValueStringComparator(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/transition_viewmodel_condition_base.cpp b/src/generated/animation/transition_viewmodel_condition_base.cpp new file mode 100644 index 00000000..a0d3b254 --- /dev/null +++ b/src/generated/animation/transition_viewmodel_condition_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_viewmodel_condition_base.hpp" +#include "rive/animation/transition_viewmodel_condition.hpp" + +using namespace rive; + +Core* TransitionViewModelConditionBase::clone() const +{ + auto cloned = new TransitionViewModelCondition(); + cloned->copy(*this); + return cloned; +} diff --git a/src/importers/transition_viewmodel_condition_importer.cpp b/src/importers/transition_viewmodel_condition_importer.cpp new file mode 100644 index 00000000..97d4cb0a --- /dev/null +++ b/src/importers/transition_viewmodel_condition_importer.cpp @@ -0,0 +1,16 @@ +#include "rive/importers/transition_viewmodel_condition_importer.hpp" +#include "rive/animation/transition_viewmodel_condition.hpp" +#include "rive/animation/transition_comparator.hpp" +#include "rive/data_bind/data_bind.hpp" + +using namespace rive; + +TransitionViewModelConditionImporter::TransitionViewModelConditionImporter( + TransitionViewModelCondition* transitionViewModelCondition) : + m_TransitionViewModelCondition(transitionViewModelCondition) +{} + +void TransitionViewModelConditionImporter::setComparator(TransitionComparator* comparator) +{ + m_TransitionViewModelCondition->comparator(comparator); +} \ No newline at end of file diff --git a/src/viewmodel/viewmodel_instance.cpp b/src/viewmodel/viewmodel_instance.cpp index f3e741d5..b2656b52 100644 --- a/src/viewmodel/viewmodel_instance.cpp +++ b/src/viewmodel/viewmodel_instance.cpp @@ -5,6 +5,7 @@ #include "rive/viewmodel/viewmodel_instance.hpp" #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp" #include "rive/importers/viewmodel_importer.hpp" #include "rive/core_context.hpp" @@ -88,3 +89,27 @@ StatusCode ViewModelInstance::import(ImportStack& importStack) viewModelImporter->addInstance(this); return StatusCode::Ok; } + +ViewModelInstanceValue* ViewModelInstance::propertyFromPath(std::vector* path, + size_t index) +{ + if (index < path->size()) + { + auto propertyId = (*path)[index]; + auto property = propertyValue(propertyId); + if (property != nullptr) + { + if (index == path->size() - 1) + { + return property; + } + if (property->is()) + { + auto propertyViewModel = property->as(); + auto viewModelInstance = propertyViewModel->referenceViewModelInstance(); + return viewModelInstance->propertyFromPath(path, index + 1); + } + } + } + return nullptr; +} \ No newline at end of file From adb2822177bcc606a01c0a4f54c3a2acce2f068d Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Fri, 26 Jul 2024 20:23:29 +0000 Subject: [PATCH 105/138] Add a build_rive.sh script to unify the premake5 build process Attempts to unify the build process across all projects with a "build_rive.sh" script. Rather than scattering custom build scripts all around the repo, the idea here is that our "premake5.lua" scripts will all conform to the same protocol, which we can then build using one single, global script. To use this build_rive.sh: 1) add packages/runtime/build to $PATH 2) cd to directory with a premake5.lua 3) run build_rive.sh with desired flags (in any order) Build for the host machine: ``` build_rive.sh # debug build build_rive.sh release # release build build_rive.sh release clean # clean, followed by a release build build_rive.sh ninja # use ninja (experimental) for a debug build build_rive.sh ninja release # use ninja (experimental) for a release build build_rive.sh ninja --with_vulkan # extra parameters get forwarded to premake ``` Generate `compile_commands.json` for code completion engines: ``` build_rive.sh compdb # code completion for a host build build_rive.sh compdb android --with_vulkan # code completion for android with vulkan enabled ``` Specify build targets after "--": ``` build_rive.sh -- gms goldens build_rive.sh ninja release -- imagediff ``` Build for android: ``` build_rive.sh android # debug build, defaults to arm64 build_rive.sh ninja android arm # release arm32 build using ninja ``` Build for ios: ``` build_rive.sh ios # debug build, arm64 only build_rive.sh ios release # release build, arm64 only build_rive.sh iossim # debug build, defaults to "universal" (x64 and arm64) architecture ``` Build for wasm: ``` build_rive.sh ninja release wasm # release build build_rive.sh ninja release wasm --with-webgpu # release build, also enable webgpu ``` Incremental builds: ``` build_rive.sh # initial build build_rive.sh # any repeat command does an incremental build build_rive.sh --with_vulkan <- FAILS!! # a repeat build with different arguments fails build_rive.sh clean --with_vulkan # a clean build with different arguments is OK build_rive.sh rebuild out/debug # use "rebuild" on a specific OUT directory to relaunch the # build with whatever args it got configured with initially build_rive.sh rebuild out/debug gms goldens # args after OUT get forwarded to the buildsystem ``` Diffs= 0a11e599f Add a build_rive.sh script to unify the premake5 build process (#7691) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/build_rive.sh | 280 ++++++++++++++++++++++++++++++++++++ build/dependency.lua | 4 +- build/rive_build_config.lua | 8 ++ 4 files changed, 290 insertions(+), 4 deletions(-) create mode 100755 build/build_rive.sh diff --git a/.rive_head b/.rive_head index fd8e8678..49e224cf 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -d25b9097d65eecd2bb8ff35d84b98ad4e2803d30 +0a11e599f81bdff08afe8365b0e25115431eba8c diff --git a/build/build_rive.sh b/build/build_rive.sh new file mode 100755 index 00000000..9329927d --- /dev/null +++ b/build/build_rive.sh @@ -0,0 +1,280 @@ +#!/bin/bash + +# build_rive.sh: build any standard Rive sub-project. +# +# To use this script: +# +# 1) add packages/runtime/build to $PATH +# 2) cd to directory with a premake5.lua +# 3) run build_rive.sh with desired flags (in any order) +# +# Build for the host machine: +# +# build_rive.sh # debug build +# build_rive.sh release # release build +# build_rive.sh release clean # clean, followed by a release build +# build_rive.sh ninja # use ninja (experimental) for a debug build +# build_rive.sh ninja release # use ninja (experimental) for a release build +# build_rive.sh ninja --with_vulkan # extra parameters get forwarded to premake +# +# Generate compile_commands.json for code completion engines: +# +# build_rive.sh compdb # code completion for a host build +# build_rive.sh compdb android --with_vulkan # code completion for android with vulkan enabled +# +# Specify build targets after "--": +# +# build_rive.sh -- gms goldens +# build_rive.sh ninja release -- imagediff +# +# Build for android: +# +# build_rive.sh android # debug build, defaults to arm64 +# build_rive.sh ninja android arm # release arm32 build using ninja +# +# Build for ios: +# +# build_rive.sh ios # debug build, arm64 only +# build_rive.sh ios release # release build, arm64 only +# build_rive.sh iossim # debug build, defaults to "universal" (x64 and arm64) architecture +# +# Build for wasm: +# +# build_rive.sh ninja release wasm # release build +# build_rive.sh ninja release wasm --with-webgpu # release build, also enable webgpu +# +# Incremental builds: +# +# build_rive.sh # initial build +# build_rive.sh # any repeat command does an incremental build +# build_rive.sh --with_vulkan <- FAILS!! # a repeat build with different arguments fails +# build_rive.sh clean --with_vulkan # a clean build with different arguments is OK +# build_rive.sh rebuild out/debug # use "rebuild" on a specific OUT directory to relaunch the +# # build with whatever args it got configured with initially +# build_rive.sh rebuild out/debug gms goldens # args after OUT get forwarded to the buildsystem + +set -e + +# Detect where build_rive.sh is located on disk. +# https://stackoverflow.com/questions/59895/how-do-i-get-the-directory-where-a-bash-script-is-located-from-within-the-script +SOURCE=${BASH_SOURCE[0]} +while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd ) + SOURCE=$(readlink "$SOURCE") + # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located + [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE +done +SCRIPT_DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd ) + +case "$(uname -s)" in + Darwin*) + if [[ $(arch) = "arm64" ]]; then + HOST_MACHINE="mac_arm64" + else + HOST_MACHINE="mac_x64" + fi + NUM_CORES=$(($(sysctl -n hw.physicalcpu) + 1)) + ;; + MINGW*) + HOST_MACHINE="windows" + NUM_CORES=$NUMBER_OF_PROCESSORS + # Try to find MSBuild.exe + export PATH="$PATH:$PROGRAMFILES/Microsoft Visual Studio/2022/Enterprise/Msbuild/Current/Bin" + export PATH="$PATH:$PROGRAMFILES/Microsoft Visual Studio/2022/Community/Msbuild/Current/Bin" + ;; + Linux*) + HOST_MACHINE="linux" + NUM_CORES=$(grep -c processor /proc/cpuinfo) + ;; +esac + +if [[ "$1" = "rebuild" ]]; then + # Load args from an existing build. + RIVE_OUT=$2 + shift + shift + + if [ ! -d $RIVE_OUT ]; then + echo "OUT directory '$RIVE_OUT' not found." + exit -1 + fi + + ARGS_FILE=$RIVE_OUT/.rive_premake_args + if [ ! -f $ARGS_FILE ]; then + echo "Premake args file '$ARGS_FILE' not found." + exit -1 + fi + + RIVE_PREMAKE_ARGS="$(< $ARGS_FILE)" + RIVE_BUILD_SYSTEM="$(awk '{print $1}' $ARGS_FILE)" # RIVE_BUILD_SYSTEM is the first word in the args. + if grep -e "--arch=" $ARGS_FILE > /dev/null; then + RIVE_ARCH="$(sed -r 's/^.*--arch=([^ ]*).*$/\1/' $ARGS_FILE)" + fi +else + # New build. Parse arguments into premake options. + RIVE_PREMAKE_FILE="${RIVE_PREMAKE_FILE:-./premake5.lua}" + if [ ! -f "$RIVE_PREMAKE_FILE" ]; then + echo "Premake file "$RIVE_PREMAKE_FILE" not found" + exit -1 + fi + + # Only use default arguments if RIVE_PREMAKE_ARGS is unset (not just empty). + if [ -z "${RIVE_PREMAKE_ARGS+null_detector_string}" ]; then + RIVE_PREMAKE_ARGS="--with_rive_text --with_rive_layout" + fi + + while [[ $# -gt 0 ]]; do + case "$1" in + "release") RIVE_CONFIG="${RIVE_CONFIG:-release}" ;; + "ios") RIVE_OS="${RIVE_OS:-ios}" ;; + "iossim") + RIVE_OS=${RIVE_OS:-ios} + RIVE_VARIANT="${RIVE_VARIANT:-emulator}" + RIVE_ARCH="${RIVE_ARCH:-universal}" # The simulator requires universal builds. + ;; + "android") RIVE_OS="${RIVE_OS:-android}" ;; + "arm") RIVE_ARCH="${RIVE_ARCH:-arm}" ;; + "arm64") RIVE_ARCH="${RIVE_ARCH:-arm64}" ;; + "x64") RIVE_ARCH="${RIVE_ARCH:-x64}" ;; + "universal") RIVE_ARCH="${RIVE_ARCH:-universal}" ;; + "wasm") RIVE_ARCH="${RIVE_ARCH:-wasm}" ;; + "ninja") RIVE_BUILD_SYSTEM="${RIVE_BUILD_SYSTEM:-ninja}" ;; + "clean") RIVE_CLEAN="${RIVE_CLEAN:-true}" ;; + "compdb") + RIVE_BUILD_SYSTEM="${RIVE_BUILD_SYSTEM:-export-compile-commands}" + RIVE_OUT="${RIVE_OUT:-out/compdb}" + ;; + "--") + shift + break + ;; + *) RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS $1" ;; + esac + shift + done + + # Android requires an architecture. Default to arm64 if not specified. + if [[ $RIVE_OS = "android" ]]; then + RIVE_ARCH="${RIVE_ARCH:-arm64}" + fi + + RIVE_CONFIG="${RIVE_CONFIG:-debug}" + + if [ -z "$RIVE_OUT" ]; then + RIVE_OUT="$RIVE_CONFIG" + if [ ! -z "$RIVE_ARCH" ]; then + RIVE_OUT="${RIVE_ARCH}_$RIVE_OUT" + fi + if [[ $RIVE_VARIANT = "emulator" ]]; then + RIVE_OUT="${RIVE_OS}sim_$RIVE_OUT" + elif [ ! -z "$RIVE_OS" ]; then + RIVE_OUT="${RIVE_OS}_$RIVE_OUT" + fi + RIVE_OUT="out/$RIVE_OUT" + fi + + if [[ "$HOST_MACHINE" = "windows" ]]; then + RIVE_BUILD_SYSTEM="${RIVE_BUILD_SYSTEM:-vs2022}" + else + RIVE_BUILD_SYSTEM="${RIVE_BUILD_SYSTEM:-gmake2}" + fi + + RIVE_PREMAKE_ARGS="$RIVE_BUILD_SYSTEM --file=$RIVE_PREMAKE_FILE --config=$RIVE_CONFIG --out=$RIVE_OUT $RIVE_PREMAKE_ARGS" + if [ ! -z "$RIVE_OS" ]; then RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS --os=$RIVE_OS"; fi + if [ ! -z "$RIVE_VARIANT" ]; then RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS --variant=$RIVE_VARIANT"; fi + if [ ! -z "$RIVE_ARCH" ]; then RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS --arch=$RIVE_ARCH"; fi + + if [[ "$RIVE_CLEAN" = true ]]; then + rm -fr "./$RIVE_OUT" + fi +fi + +mkdir -p "$SCRIPT_DIR/dependencies" +pushd "$SCRIPT_DIR/dependencies" > /dev/null + +# Setup premake5. +if [ ! -d premake-core ]; then + echo Building Premake... + git clone https://github.com/premake/premake-core.git + pushd premake-core > /dev/null + case "$HOST_MACHINE" in + mac_arm64) make -f Bootstrap.mak osx PLATFORM=ARM ;; + mac_x64) make -f Bootstrap.mak osx ;; + windows) ./Bootstrap.bat ;; + *) make -f Bootstrap.mak linux ;; + esac + popd > /dev/null +fi +export PATH="$SCRIPT_DIR/dependencies/premake-core/bin/release/:$PATH" +export PREMAKE_PATH="$SCRIPT_DIR" + +# Setup premake-ninja. +if [[ $RIVE_BUILD_SYSTEM = "ninja" ]]; then + if [ ! -d premake-ninja ]; then + git clone --branch rive_modifications https://github.com/rive-app/premake-ninja.git + fi + export PREMAKE_PATH="$SCRIPT_DIR/dependencies/premake-ninja:$PREMAKE_PATH" +fi + +# Setup premake-export-compile-commands. +if [[ $RIVE_BUILD_SYSTEM = "export-compile-commands" ]]; then + if [ ! -d premake-export-compile-commands ]; then + git clone --branch more_cpp_support https://github.com/rive-app/premake-export-compile-commands.git + fi + export PREMAKE_PATH="$SCRIPT_DIR/dependencies/premake-export-compile-commands:$PREMAKE_PATH" +fi + +# Setup emscripten. +if [[ $RIVE_ARCH = "wasm" ]]; then + if [ ! -d emsdk ]; then + git clone https://github.com/emscripten-core/emsdk.git + emsdk/emsdk install 3.1.61 + emsdk/emsdk activate 3.1.61 + fi + source emsdk/emsdk_env.sh +fi + +popd > /dev/null # leave "$SCRIPT_DIR/dependencies" + +if [ -d "$RIVE_OUT" ]; then + if [[ "$RIVE_PREMAKE_ARGS" != "$(< $RIVE_OUT/.rive_premake_args)" ]]; then + echo "error: premake5 arguments for current build do not match previous arguments" + echo " previous command: premake5 $(< $RIVE_OUT/.rive_premake_args)" + echo " current command: premake5 $RIVE_PREMAKE_ARGS" + echo "If you wish to overwrite the existing build, please use 'clean'" + exit -1 + fi +else + mkdir -p "$RIVE_OUT" + echo "$RIVE_PREMAKE_ARGS" > "$RIVE_OUT/.rive_premake_args" +fi + +echo premake5 $RIVE_PREMAKE_ARGS +premake5 $RIVE_PREMAKE_ARGS | grep -v '^Done ([1-9]*ms).$' + +case "$RIVE_BUILD_SYSTEM" in + export-compile-commands) + rm -f ./compile_commands.json + cp $RIVE_OUT/compile_commands/default.json compile_commands.json + wc ./compile_commands.json + ;; + gmake2) + echo make -C $RIVE_OUT -j$NUM_CORES $@ + make -C $RIVE_OUT -j$NUM_CORES $@ + ;; + ninja) + echo ninja -C $RIVE_OUT $@ + ninja -C $RIVE_OUT $@ + ;; + vs2022) + for TARGET in $@; do + RIVE_MSVC_TARGETS="$RIVE_MSVC_TARGETS -t:$TARGET" + done + echo msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $RIVE_MSVC_TARGETS + msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $RIVE_MSVC_TARGETS + ;; + *) + print "Unsupported buildsystem $RIVE_BUILD_SYSTEM" + exit -1 + ;; +esac diff --git a/build/dependency.lua b/build/dependency.lua index fe609d25..95f68269 100644 --- a/build/dependency.lua +++ b/build/dependency.lua @@ -42,7 +42,7 @@ function m.github(project, tag) and progress, } ) - print('Downloaded ' .. project .. '.') + print('Downloaded ' .. project .. ' to ' .. dependencies .. '/' .. hash) zip.extract(downloadFilename, dependencies .. '/' .. hash) os.remove(downloadFilename) end @@ -50,8 +50,6 @@ function m.github(project, tag) local iter = pairs(dirs) local currentKey, currentValue = iter(dirs) - print('Dependency ' .. project .. ' located at:') - print(' ' .. currentValue) return currentValue end return m diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index c08ca59f..8396eeb2 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -1,3 +1,11 @@ +if _ACTION == 'ninja' then + require "ninja" +end + +if _ACTION == 'export-compile-commands' then + require "export-compile-commands" +end + workspace('rive') newoption({ From 9915759585793b51983a30ccd4f588407650f577 Mon Sep 17 00:00:00 2001 From: philter Date: Fri, 26 Jul 2024 21:43:56 +0000 Subject: [PATCH 106/138] Fix for nested events in CPP Fixes nested events not propagating up to the parent artboard due to a recent naming change from `artboard()` to `artboardInstance()`. Diffs= 657f65e1c Fix for nested events in CPP (#7708) Co-authored-by: Philip Chung --- .rive_head | 2 +- src/animation/state_machine_instance.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 49e224cf..75cf4716 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -0a11e599f81bdff08afe8365b0e25115431eba8c +657f65e1c0b0c63524c65e2b5e1fbe6459e1ae69 diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 6f006f74..9bbe8756 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -1089,7 +1089,8 @@ void StateMachineInstance::notifyEventListeners(const std::vector& { for (const auto event : events) { - auto sourceArtboard = source == nullptr ? artboard() : source->artboard(); + auto sourceArtboard = + source == nullptr ? artboard() : source->artboardInstance(); // listener->eventId() can point to an id from an event in the context of this // artboard or the context of a nested artboard. Because those ids belong to From 15101782a0e888cfc74353db96dcb14f4041d1ab Mon Sep 17 00:00:00 2001 From: philter Date: Fri, 26 Jul 2024 22:56:47 +0000 Subject: [PATCH 107/138] Add a test for nested events triggering listener in parent Diffs= d6d79132b Add a test for nested events triggering listener in parent (#7709) Co-authored-by: Philip Chung --- .rive_head | 2 +- test/assets/nested_event_test.riv | Bin 0 -> 626 bytes test/state_machine_event_test.cpp | 61 ++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 test/assets/nested_event_test.riv diff --git a/.rive_head b/.rive_head index 75cf4716..69a431e2 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -657f65e1c0b0c63524c65e2b5e1fbe6459e1ae69 +d6d79132b5c6aa46c1919918a14de28f1cbf93a4 diff --git a/test/assets/nested_event_test.riv b/test/assets/nested_event_test.riv new file mode 100644 index 0000000000000000000000000000000000000000..75c4cc08ddecf33639786b06279fe5c107c8cf55 GIT binary patch literal 626 zcma))&r4KM6vw~cx##v~3MYsWv5m8tO}kf^NTuT&C4y{W5kWz{^pXS98<=jtc5V_G z1XmGM3l|an8-Ysyg(GUE4g`AgRLUG}A8 z4rQBf%sPL_fwZ{84gQoi+p@)7*^?E6lgr!SCV4Liy4_=Pcue-*cQHKDf6G1dZtk{^ zy(><~v-9bq5LcSaMfG~k#feU%O$ImP*RG*`8RHnk#5)SEe;_`peI3l70oUGY3@t>X z$?QbKKd#4(xfYeCT`|P-ZDNNRun%QBnFkiiYlLDfrWjYFj^5-9_50~{DUw&8Oh%e#?#E~#T`>5nl?A% TW__GIsks(2Tbl8UekreportedEventAt(0).secondsDelay() == Approx(0.1f)); } + +TEST_CASE("events from a nested artboard propagate to a listener on a parent", "[events]") +{ + auto file = ReadRiveFile("../../test/assets/nested_event_test.riv"); + + auto artboard = file->artboard()->instance(); + REQUIRE(artboard != nullptr); + REQUIRE(artboard->stateMachineCount() == 1); + + auto stateMachineInstance = artboard->stateMachineAt(0); + REQUIRE(stateMachineInstance != nullptr); + REQUIRE(stateMachineInstance->stateMachine()->inputCount() == 1); + + // Input is on the main artboard + auto input = stateMachineInstance->getBool("Boolean 1"); + REQUIRE(input->value() == false); + + artboard->advance(0.0f); + stateMachineInstance->advance(0.0f); + + auto nested = artboard->find(); + REQUIRE(nested.size() == 1); + auto nestedArtboard = nested[0]->artboardInstance(); + auto nestedStateMachineInstance = + nested[0]->nestedAnimations()[0]->as()->stateMachineInstance(); + REQUIRE(nestedStateMachineInstance != nullptr); + auto events = nestedArtboard->find(); + REQUIRE(events.size() == 1); + + // Validate listener on the nested artboard + REQUIRE(nestedStateMachineInstance->stateMachine()->listenerCount() == 1); + auto listener1 = nestedStateMachineInstance->stateMachine()->listener(0); + auto target1 = nestedArtboard->resolve(listener1->targetId()); + REQUIRE(target1->is()); + REQUIRE(listener1->actionCount() == 1); + auto fireEvent1 = listener1->action(0); + REQUIRE(fireEvent1 != nullptr); + REQUIRE(fireEvent1->is()); + REQUIRE(fireEvent1->as()->eventId() != 0); + auto event = nestedArtboard->resolve(fireEvent1->as()->eventId()); + REQUIRE(event->is()); + REQUIRE(event->as()->name() == "NestedEvent"); + + // Validate the event is reported to the nested artboard + REQUIRE(nestedStateMachineInstance->reportedEventCount() == 0); + stateMachineInstance->pointerDown(rive::Vec2D(250.0f, 100.0f)); + REQUIRE(nestedStateMachineInstance->reportedEventCount() == 1); + auto nestedReportedEvent1 = nestedStateMachineInstance->reportedEventAt(0); + REQUIRE(nestedReportedEvent1.event()->name() == "NestedEvent"); + + artboard->advance(0.0f); + + // Validate the input on the main artboard updates as a result of the event + // from the nested artboard + REQUIRE(input->value() == true); + + // After advancing again the reportedEventCount should return to 0. + stateMachineInstance->advance(0.0f); + REQUIRE(stateMachineInstance->reportedEventCount() == 0); +} From 7b2347c9df351c17c0f8e4e29f9bb26f0d7112c5 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Fri, 26 Jul 2024 23:10:22 +0000 Subject: [PATCH 108/138] Simple procedural text rendering API This adds `rive::RawText` can be used to append text runs with different styles and set layout rules for the text. It's pretty full featured. Simple example (trimmed for brevity): ``` auto roboto = loadFont("RobotoFlex.ttf"); // setup text object rive::RawText text(RiveFactory()); text.append("Hello world! ", roboto); // later during rendering text.render(renderer); ``` CleanShot 2024-07-25 at 21 59 43@2x A few more complex examples: ``` auto roboto = loadFont("RobotoFlex.ttf"); auto montserrat = loadFont("Montserrat.ttf"); rive::RawText text(RiveFactory()); text.append("Hello world! ", roboto, 72.0f); text.append("Moon's cool too. ", montserrat, 64.0f); ``` CleanShot 2024-07-25 at 22 01 28@2x Because `RawText` represents one contiguous styled block of text, you can apply rules like overflow, sizing, alignment, different paint, etc: ``` rive::RawText text(RiveFactory()); text.maxWidth(450.0f); text.maxHeight(330.0f); text.sizing(rive::TextSizing::fixed); text.overflow(rive::TextOverflow::ellipsis); text.append("Hello world! ", roboto, 72.0f); text.append("Moon's cool too. ", montserrat, 64.0f); auto paint = RiveFactory()->makeRenderPaint(); paint->color(0x88ff0000); text.append("Mars is red.", roboto, 72.0f, paint); ``` CleanShot 2024-07-25 at 22 03 01@2x You can also supply an override paint during rendering to force paint the whole thing with one color: ``` auto paint = RiveFactory()->makeRenderPaint(); paint->color(0xff00ff00); text.render(renderer, paint); ``` CleanShot 2024-07-25 at 22 04 44@2x Diffs= a56419984 Simple procedural text rendering API (#7701) Co-authored-by: Chris Dalton Co-authored-by: Luigi Rosso --- .rive_head | 2 +- include/rive/text/raw_text.hpp | 96 +++++++++ include/rive/text/text.hpp | 3 + src/factory.cpp | 1 + src/text/raw_text.cpp | 344 +++++++++++++++++++++++++++++++++ src/text/text.cpp | 15 +- 6 files changed, 452 insertions(+), 9 deletions(-) create mode 100644 include/rive/text/raw_text.hpp create mode 100644 src/text/raw_text.cpp diff --git a/.rive_head b/.rive_head index 69a431e2..fdd6112f 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -d6d79132b5c6aa46c1919918a14de28f1cbf93a4 +a56419984ccdd39989f7c059a8af2ebbceb379a0 diff --git a/include/rive/text/raw_text.hpp b/include/rive/text/raw_text.hpp new file mode 100644 index 00000000..2d76fb8c --- /dev/null +++ b/include/rive/text/raw_text.hpp @@ -0,0 +1,96 @@ +#ifndef _RIVE_RENDER_TEXT_HPP_ +#define _RIVE_RENDER_TEXT_HPP_ + +#ifdef WITH_RIVE_TEXT + +#include "rive/text/text.hpp" + +namespace rive +{ +class Factory; + +class RawText +{ +public: + RawText(Factory* factory); + + /// Returns true if the text object contains no text. + bool empty() const; + + /// Appends a run to the text object. + void append(const std::string& text, + rcp paint, + rcp font, + float size = 16.0f, + float lineHeight = -1.0f, + float letterSpacing = 0.0f); + + /// Resets the text object to empty state (no text). + void clear(); + + /// Draw the text using renderer. Second argument is optional to override + /// all paints provided with run styles + void render(Renderer* renderer, rcp paint = nullptr); + + TextSizing sizing() const; + TextOverflow overflow() const; + TextAlign align() const; + float maxWidth() const; + float maxHeight() const; + float paragraphSpacing() const; + + void sizing(TextSizing value); + + /// How text that overflows when TextSizing::fixed is used. + void overflow(TextOverflow value); + + /// How text aligns within the bounds. + void align(TextAlign value); + + /// The width at which the text will wrap when using any sizing but TextSizing::auto. + void maxWidth(float value); + + /// The height at which the text will overflow when using TextSizing::fixed. + void maxHeight(float value); + + /// The vertical space between paragraphs delineated by a return character. + void paragraphSpacing(float value); + + /// Returns the bounds of the text object (helpful for aligning multiple + /// text objects/procredurally drawn shapes). + AABB bounds(); + +private: + void update(); + struct RenderStyle + { + rcp paint; + rcp path; + bool isEmpty; + }; + SimpleArray m_shape; + SimpleArray> m_lines; + + StyledText m_styled; + Factory* m_factory; + std::vector m_styles; + std::vector m_renderStyles; + bool m_dirty = false; + float m_paragraphSpacing = 0.0f; + + TextOrigin m_origin = TextOrigin::top; + TextSizing m_sizing = TextSizing::autoWidth; + TextOverflow m_overflow = TextOverflow::visible; + TextAlign m_align = TextAlign::left; + float m_maxWidth = 0.0f; + float m_maxHeight = 0.0f; + std::vector m_orderedLines; + GlyphRun m_ellipsisRun; + AABB m_bounds; + rcp m_clipRenderPath; +}; +} // namespace rive + +#endif // WITH_RIVE_TEXT + +#endif diff --git a/include/rive/text/text.hpp b/include/rive/text/text.hpp index 7d0ae9ac..b0267aba 100644 --- a/include/rive/text/text.hpp +++ b/include/rive/text/text.hpp @@ -200,6 +200,9 @@ class Text : public TextBase float effectiveHeight() { return std::isnan(m_layoutHeight) ? height() : m_layoutHeight; } #ifdef WITH_RIVE_TEXT const std::vector& runs() const { return m_runs; } + static SimpleArray> BreakLines(const SimpleArray& paragraphs, + float width, + TextAlign align); #endif bool haveModifiers() const diff --git a/src/factory.cpp b/src/factory.cpp index 07e352ac..09c670a9 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -5,6 +5,7 @@ #include "rive/factory.hpp" #include "rive/math/aabb.hpp" #include "rive/math/raw_path.hpp" +#include "rive/text/raw_text.hpp" #ifdef WITH_RIVE_TEXT #include "rive/text/font_hb.hpp" #endif diff --git a/src/text/raw_text.cpp b/src/text/raw_text.cpp new file mode 100644 index 00000000..abc7bba5 --- /dev/null +++ b/src/text/raw_text.cpp @@ -0,0 +1,344 @@ +#ifdef WITH_RIVE_TEXT +#include "rive/text/raw_text.hpp" +#include "rive/text_engine.hpp" +#include "rive/factory.hpp" + +using namespace rive; + +RawText::RawText(Factory* factory) : m_factory(factory) {} +bool RawText::empty() const { return m_styled.empty(); } + +void RawText::append(const std::string& text, + rcp paint, + rcp font, + float size, + float lineHeight, + float letterSpacing) +{ + int styleIndex = 0; + for (RenderStyle& style : m_styles) + { + if (style.paint == paint) + { + break; + } + styleIndex++; + } + if (styleIndex == m_styles.size()) + { + m_styles.push_back({paint, m_factory->makeEmptyRenderPath(), true}); + } + m_styled.append(font, size, lineHeight, letterSpacing, text, styleIndex); + m_dirty = true; +} + +void RawText::clear() +{ + m_styled.clear(); + m_dirty = true; +} + +TextSizing RawText::sizing() const { return m_sizing; } + +TextOverflow RawText::overflow() const { return m_overflow; } + +TextAlign RawText::align() const { return m_align; } + +float RawText::maxWidth() const { return m_maxWidth; } + +float RawText::maxHeight() const { return m_maxHeight; } + +float RawText::paragraphSpacing() const { return m_paragraphSpacing; } + +void RawText::sizing(TextSizing value) +{ + if (m_sizing != value) + { + m_sizing = value; + m_dirty = true; + } +} + +void RawText::overflow(TextOverflow value) +{ + if (m_overflow != value) + { + m_overflow = value; + m_dirty = true; + } +} + +void RawText::align(TextAlign value) +{ + if (m_align != value) + { + m_align = value; + m_dirty = true; + } +} + +void RawText::paragraphSpacing(float value) +{ + if (m_paragraphSpacing != value) + { + m_paragraphSpacing = value; + m_dirty = true; + } +} + +void RawText::maxWidth(float value) +{ + if (m_maxWidth != value) + { + m_maxWidth = value; + m_dirty = true; + } +} + +void RawText::maxHeight(float value) +{ + if (m_maxHeight != value) + { + m_maxHeight = value; + m_dirty = true; + } +} + +void RawText::update() +{ + for (RenderStyle& style : m_styles) + { + style.path->rewind(); + style.isEmpty = true; + } + m_renderStyles.clear(); + if (m_styled.empty()) + { + return; + } + auto runs = m_styled.runs(); + m_shape = runs[0].font->shapeText(m_styled.unichars(), runs); + m_lines = + Text::BreakLines(m_shape, m_sizing == TextSizing::autoWidth ? -1.0f : m_maxWidth, m_align); + + m_orderedLines.clear(); + m_ellipsisRun = {}; + + // build render styles. + if (m_shape.empty()) + { + m_bounds = AABB(0.0f, 0.0f, 0.0f, 0.0f); + return; + } + + // Build up ordered runs as we go. + int paragraphIndex = 0; + float y = 0.0f; + float minY = 0.0f; + float measuredWidth = 0.0f; + if (m_origin == TextOrigin::baseline && !m_lines.empty() && !m_lines[0].empty()) + { + y -= m_lines[0][0].baseline; + minY = y; + } + + int ellipsisLine = -1; + bool isEllipsisLineLast = false; + // Find the line to put the ellipsis on (line before the one that + // overflows). + bool wantEllipsis = m_overflow == TextOverflow::ellipsis && m_sizing == TextSizing::fixed; + + int lastLineIndex = -1; + for (const SimpleArray& paragraphLines : m_lines) + { + const Paragraph& paragraph = m_shape[paragraphIndex++]; + for (const GlyphLine& line : paragraphLines) + { + const GlyphRun& endRun = paragraph.runs[line.endRunIndex]; + const GlyphRun& startRun = paragraph.runs[line.startRunIndex]; + float width = endRun.xpos[line.endGlyphIndex] - startRun.xpos[line.startGlyphIndex] - + endRun.letterSpacing; + if (width > measuredWidth) + { + measuredWidth = width; + } + lastLineIndex++; + if (wantEllipsis && y + line.bottom <= m_maxHeight) + { + ellipsisLine++; + } + } + + if (!paragraphLines.empty()) + { + y += paragraphLines.back().bottom; + } + y += m_paragraphSpacing; + } + if (wantEllipsis && ellipsisLine == -1) + { + // Nothing fits, just show the first line and ellipse it. + ellipsisLine = 0; + } + isEllipsisLineLast = lastLineIndex == ellipsisLine; + + int lineIndex = 0; + paragraphIndex = 0; + switch (m_sizing) + { + case TextSizing::autoWidth: + m_bounds = AABB(0.0f, minY, measuredWidth, std::max(minY, y - m_paragraphSpacing)); + break; + case TextSizing::autoHeight: + m_bounds = AABB(0.0f, minY, m_maxWidth, std::max(minY, y - m_paragraphSpacing)); + break; + case TextSizing::fixed: + m_bounds = AABB(0.0f, minY, m_maxWidth, minY + m_maxHeight); + break; + } + + // Build the clip path if we want it. + if (m_overflow == TextOverflow::clipped) + { + if (m_clipRenderPath == nullptr) + { + m_clipRenderPath = m_factory->makeEmptyRenderPath(); + } + else + { + m_clipRenderPath->rewind(); + } + + m_clipRenderPath->addRect(m_bounds.minX, + m_bounds.minY, + m_bounds.width(), + m_bounds.height()); + } + else + { + m_clipRenderPath = nullptr; + } + + y = 0; + if (m_origin == TextOrigin::baseline && !m_lines.empty() && !m_lines[0].empty()) + { + y -= m_lines[0][0].baseline; + } + paragraphIndex = 0; + + for (const SimpleArray& paragraphLines : m_lines) + { + const Paragraph& paragraph = m_shape[paragraphIndex++]; + for (const GlyphLine& line : paragraphLines) + { + switch (m_overflow) + { + case TextOverflow::hidden: + if (m_sizing == TextSizing::fixed && y + line.bottom > m_maxHeight) + { + return; + } + break; + case TextOverflow::clipped: + if (m_sizing == TextSizing::fixed && y + line.top > m_maxHeight) + { + return; + } + break; + default: + break; + } + + if (lineIndex >= m_orderedLines.size()) + { + // We need to still compute this line's ordered runs. + m_orderedLines.emplace_back(OrderedLine(paragraph, + line, + m_maxWidth, + ellipsisLine == lineIndex, + isEllipsisLineLast, + &m_ellipsisRun)); + } + + const OrderedLine& orderedLine = m_orderedLines[lineIndex]; + float x = line.startX; + float renderY = y + line.baseline; + for (auto glyphItr : orderedLine) + { + const GlyphRun* run = std::get<0>(glyphItr); + size_t glyphIndex = std::get<1>(glyphItr); + + const Font* font = run->font.get(); + const Vec2D& offset = run->offsets[glyphIndex]; + + GlyphID glyphId = run->glyphs[glyphIndex]; + float advance = run->advances[glyphIndex]; + + RawPath path = font->getPath(glyphId); + + path.transformInPlace( + Mat2D(run->size, 0.0f, 0.0f, run->size, x + offset.x, renderY + offset.y)); + + x += advance; + + assert(run->styleId < m_styles.size()); + RenderStyle* style = &m_styles[run->styleId]; + assert(style != nullptr); + path.addTo(style->path.get()); + + if (style->isEmpty) + { + // This was the first path added to the style, so let's mark + // it in our draw list. + style->isEmpty = false; + + m_renderStyles.push_back(style); + } + } + if (lineIndex == ellipsisLine) + { + return; + } + lineIndex++; + } + if (!paragraphLines.empty()) + { + y += paragraphLines.back().bottom; + } + y += m_paragraphSpacing; + } +} + +AABB RawText::bounds() +{ + if (m_dirty) + { + update(); + m_dirty = false; + } + return m_bounds; +} + +void RawText::render(Renderer* renderer, rcp paint) +{ + if (m_dirty) + { + update(); + m_dirty = false; + } + + if (m_overflow == TextOverflow::clipped && m_clipRenderPath) + { + renderer->save(); + renderer->clipPath(m_clipRenderPath.get()); + } + for (auto style : m_renderStyles) + { + renderer->drawPath(style->path.get(), paint ? paint.get() : style->paint.get()); + } + if (m_overflow == TextOverflow::clipped && m_clipRenderPath) + { + renderer->restore(); + } +} +#endif diff --git a/src/text/text.cpp b/src/text/text.cpp index 59403c7a..03a47efd 100644 --- a/src/text/text.cpp +++ b/src/text/text.cpp @@ -269,7 +269,7 @@ void Text::buildRenderStyles() style->rewindPath(); } m_renderStyles.clear(); - if (m_shape.size() == 0) + if (m_shape.empty()) { m_bounds = AABB(0.0f, 0.0f, 0.0f, 0.0f); return; @@ -508,7 +508,6 @@ const TextStyle* Text::styleFromShaperId(uint16_t id) const void Text::draw(Renderer* renderer) { - ClipResult clipResult = applyClip(renderer); if (clipResult == ClipResult::noClip) { @@ -646,9 +645,9 @@ bool Text::makeStyled(StyledText& styledText, bool withModifiers) const return !styledText.empty(); } -static SimpleArray> breakLines(const SimpleArray& paragraphs, - float width, - TextAlign align) +SimpleArray> Text::BreakLines(const SimpleArray& paragraphs, + float width, + TextAlign align) { bool autoWidth = width == -1.0f; float paragraphWidth = width; @@ -706,7 +705,7 @@ void Text::update(ComponentDirt value) auto runs = m_modifierStyledText.runs(); m_modifierShape = runs[0].font->shapeText(m_modifierStyledText.unichars(), runs); m_modifierLines = - breakLines(m_modifierShape, + BreakLines(m_modifierShape, effectiveSizing() == TextSizing::autoWidth ? -1.0f : effectiveWidth(), (TextAlign)alignValue()); m_glyphLookup.compute(m_modifierStyledText.unichars(), m_modifierShape); @@ -725,7 +724,7 @@ void Text::update(ComponentDirt value) auto runs = m_styledText.runs(); m_shape = runs[0].font->shapeText(m_styledText.unichars(), runs); m_lines = - breakLines(m_shape, + BreakLines(m_shape, effectiveSizing() == TextSizing::autoWidth ? -1.0f : effectiveWidth(), (TextAlign)alignValue()); if (!precomputeModifierCoverage && haveModifiers()) @@ -776,7 +775,7 @@ Vec2D Text::measure(Vec2D maxSize) const float paragraphSpace = paragraphSpacing(); auto runs = m_styledText.runs(); auto shape = runs[0].font->shapeText(m_styledText.unichars(), runs); - auto lines = breakLines(shape, + auto lines = BreakLines(shape, std::min(maxSize.x, sizing() == TextSizing::autoWidth ? std::numeric_limits::max() From 2e513d2dd0a785299f1aae1cf65fc85cae7dc6b1 Mon Sep 17 00:00:00 2001 From: philter Date: Mon, 29 Jul 2024 17:11:54 +0000 Subject: [PATCH 109/138] Improve layout animation This adds an improvement to layout animation. When updating layout bounds (for example when a parent layout resizes), we were initially setting elapsedSeconds to 0. This restarts the animation, however in cases when the layout bounds is constantly updating (see attached videos), the animation would never progress until the layout bounds stopped updating. An alternative was to not reset elapsedSeconds which was also tested, but in that case the result was odd visual issues like snapping to the new layout bounds (in cases where elapsedSeconds was close to the animation duration). An interim solution (until we find a better one) is to only reset elapsedSeconds to 0 if it is greater than some arbitrary time, thus the animation will continue to progress relatively smoothly. Here are the scenarios. This PR implements the 3rd option. **Always set elapsedSeconds to 0 when updating layout bounds** https://github.com/user-attachments/assets/d430edba-37f4-408d-843f-9f67abfb101d **Never set elapsedSeconds to 0 when updating layout bounds** https://github.com/user-attachments/assets/a8abae5b-647a-437e-9c0f-09d681d6716e **Set elapsedSeconds to 0 after some time has elapsed** https://github.com/user-attachments/assets/3d63cb14-2977-4ea5-b38d-3fcca1f1a666 Diffs= 4732c37b5 Improve layout animation (#7712) Co-authored-by: Philip Chung --- .rive_head | 2 +- src/layout_component.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index fdd6112f..43294622 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -a56419984ccdd39989f7c059a8af2ebbceb379a0 +4732c37b5e8afae84ec54d662682380598292ac3 diff --git a/src/layout_component.cpp b/src/layout_component.cpp index a032d8a3..c361048b 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -532,12 +532,15 @@ void LayoutComponent::updateLayoutBounds() if (left != toBounds.left() || top != toBounds.top() || width != toBounds.width() || height != toBounds.height()) { - m_animationData.elapsedSeconds = 0; m_animationData.fromBounds = AABB(m_layoutLocationX, m_layoutLocationY, m_layoutLocationX + this->width(), m_layoutLocationY + this->height()); m_animationData.toBounds = AABB(left, top, left + width, top + height); + if (m_animationData.elapsedSeconds > 0.1) + { + m_animationData.elapsedSeconds = 0; + } propagateSize(); markWorldTransformDirty(); } From 5dd8cd9483f61cdde26d38d04582040f9c08f905 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 29 Jul 2024 18:39:24 +0000 Subject: [PATCH 110/138] add click event support this PR adds click support to listeners. Click is a new event type (like pointer down, pointer move). It encompasses two stages (pointer down + pointer up) in the same object or group of objects that belong to the listener. It processes all the phases of a click gesture this PR also: - guarantees that the click gesture is applied only once per frame (no double actions from overlapping shapes) - supports starting the click gesture in one shape and ending it in another shape of the same listener (by promoting the hover state to the group and not on individual shapes) Diffs= 405ca998b add click event support (#7668) Co-authored-by: hernan --- .rive_head | 2 +- .../rive/animation/state_machine_instance.hpp | 4 + include/rive/gesture_click_phase.hpp | 12 ++ include/rive/listener_type.hpp | 1 + src/animation/state_machine_instance.cpp | 197 ++++++++++++++---- test/assets/click_event.riv | Bin 0 -> 802 bytes test/hittest_test.cpp | 137 ++++++++++++ 7 files changed, 316 insertions(+), 37 deletions(-) create mode 100644 include/rive/gesture_click_phase.hpp create mode 100644 test/assets/click_event.riv diff --git a/.rive_head b/.rive_head index 43294622..e4ff0e3d 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -4732c37b5e8afae84ec54d662682380598292ac3 +405ca998b7729cb4f84448fe681e9c4a82243099 diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index a2c86008..093d05bb 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -27,6 +27,7 @@ class Shape; class StateMachineLayerInstance; class HitComponent; class HitShape; +class ListenerGroup; class NestedArtboard; class NestedEventListener; class NestedEventNotifier; @@ -146,6 +147,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne } return nullptr; } + const LayerState* layerState(size_t index); #endif void updateDataBinds(); @@ -157,6 +159,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne size_t m_layerCount; StateMachineLayerInstance* m_layers; std::vector> m_hitComponents; + std::vector> m_listenerGroups; StateMachineInstance* m_parentStateMachineInstance = nullptr; NestedArtboard* m_parentNestedArtboard = nullptr; std::vector m_dataBinds; @@ -178,6 +181,7 @@ class HitComponent {} virtual ~HitComponent() {} virtual HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) = 0; + virtual void prepareEvent(Vec2D position, ListenerType hitType) = 0; #ifdef WITH_RIVE_TOOLS virtual bool hitTest(Vec2D position) const = 0; #endif diff --git a/include/rive/gesture_click_phase.hpp b/include/rive/gesture_click_phase.hpp new file mode 100644 index 00000000..2daf21ae --- /dev/null +++ b/include/rive/gesture_click_phase.hpp @@ -0,0 +1,12 @@ +#ifndef _RIVE_GESTURE_CLICK_PHASE_HPP_ +#define _RIVE_GESTURE_CLICK_PHASE_HPP_ +namespace rive +{ +enum class GestureClickPhase : int +{ + out = 0, + down = 1, + clicked = 2, +}; +} +#endif \ No newline at end of file diff --git a/include/rive/listener_type.hpp b/include/rive/listener_type.hpp index d79f68cc..7fab8095 100644 --- a/include/rive/listener_type.hpp +++ b/include/rive/listener_type.hpp @@ -10,6 +10,7 @@ enum class ListenerType : int up = 3, move = 4, event = 5, + click = 6, }; } #endif \ No newline at end of file diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 9bbe8756..219200f3 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -26,6 +26,7 @@ #include "rive/animation/state_machine_fire_event.hpp" #include "rive/data_bind_flags.hpp" #include "rive/event_report.hpp" +#include "rive/gesture_click_phase.hpp" #include "rive/hit_result.hpp" #include "rive/math/aabb.hpp" #include "rive/math/hit_test.hpp" @@ -190,7 +191,6 @@ class StateMachineLayerInstance { uint32_t totalWeight = 0; auto stateFrom = stateFromInstance->state(); - // printf("stateFrom->transitionCount(): %zu\n", stateFrom->transitionCount()); for (size_t i = 0, length = stateFrom->transitionCount(); i < length; i++) { auto transition = stateFrom->transition(i); @@ -425,6 +425,45 @@ class StateMachineLayerInstance float m_holdTime = 0.0f; }; +class ListenerGroup +{ +public: + ListenerGroup(const StateMachineListener* listener) : m_listener(listener) {} + void consume() { m_isConsumed = true; } + // + void hover() { m_isHovered = true; } + void reset() + { + m_isConsumed = false; + m_prevIsHovered = m_isHovered; + m_isHovered = false; + if (m_clickPhase == GestureClickPhase::clicked) + { + m_clickPhase = GestureClickPhase::out; + } + } + bool isConsumed() { return m_isConsumed; } + bool isHovered() { return m_isHovered; } + bool prevHovered() { return m_prevIsHovered; } + void clickPhase(GestureClickPhase value) { m_clickPhase = value; } + GestureClickPhase clickPhase() { return m_clickPhase; } + const StateMachineListener* listener() const { return m_listener; }; + // A vector storing the previous position for this specific listener gorup + Vec2D previousPosition; + +private: + // Consumed listeners aren't processed again in the current frame + bool m_isConsumed = false; + // This variable holds the hover status of the the listener itself so it can + // be shared between all shapes that target it + bool m_isHovered = false; + // Variable storing the previous hovered state to check for hover changes + bool m_prevIsHovered = false; + // A click gesture is composed of three phases and is shared between all shapes + GestureClickPhase m_clickPhase = GestureClickPhase::out; + const StateMachineListener* m_listener; +}; + /// Representation of a Shape from the Artboard Instance and all the listeners it /// triggers. Allows tracking hover and performing hit detection only once on /// shapes that trigger multiple listeners. @@ -444,8 +483,7 @@ class HitShape : public HitComponent bool hasDownListener = false; bool hasUpListener = false; float hitRadius = 2; - Vec2D previousPosition; - std::vector listeners; + std::vector listeners; bool hitTest(Vec2D position) const #ifdef WITH_RIVE_TOOLS @@ -466,6 +504,29 @@ class HitShape : public HitComponent return shape->hitTest(hitArea); } + void prepareEvent(Vec2D position, ListenerType hitType) override + { + if (canEarlyOut && (hitType != ListenerType::down || !hasDownListener) && + (hitType != ListenerType::up || !hasUpListener)) + { +#ifdef TESTING + earlyOutCount++; +#endif + return; + } + isHovered = hitTest(position); + + // // iterate all listeners associated with this hit shape + if (isHovered) + { + for (auto listenerGroup : listeners) + { + + listenerGroup->hover(); + } + } + } + HitResult processEvent(Vec2D position, ListenerType hitType, bool canHit) override { // If the shape doesn't have any ListenerType::move / enter / exit and the event @@ -475,53 +536,90 @@ class HitShape : public HitComponent if (canEarlyOut && (hitType != ListenerType::down || !hasDownListener) && (hitType != ListenerType::up || !hasUpListener)) { -#ifdef TESTING - earlyOutCount++; -#endif return HitResult::none; } auto shape = m_component->as(); - bool isOver = canHit ? hitTest(position) : false; - bool hoverChange = isHovered != isOver; - isHovered = isOver; - if (hoverChange && isHovered) - { - previousPosition.x = position.x; - previousPosition.y = position.y; - } // // iterate all listeners associated with this hit shape - for (auto listener : listeners) + for (auto listenerGroup : listeners) { - // Always update hover states regardless of which specific listener type - // we're trying to trigger. - if (hoverChange) + if (listenerGroup->isConsumed()) + { + continue; + } + + bool isGroupHovered = canHit ? listenerGroup->isHovered() : false; + bool hoverChange = listenerGroup->prevHovered() != isGroupHovered; + // If hover has changes, it means that the element is hovered for the + // first time. Previous positions need to be reset to avoid jumps. + if (hoverChange && isGroupHovered) { - if (isOver && listener->listenerType() == ListenerType::enter) + listenerGroup->previousPosition.x = position.x; + listenerGroup->previousPosition.y = position.y; + } + + // Handle click gesture phases. A click gesture has two phases. + // First one attached to a pointer down actions, second one attached to a + // pointer up action. Both need to act on a shape of the listener group. + if (isGroupHovered) + { + if (hitType == ListenerType::down) { - listener->performChanges(m_stateMachineInstance, position, previousPosition); - m_stateMachineInstance->markNeedsAdvance(); + listenerGroup->clickPhase(GestureClickPhase::down); } - else if (!isOver && listener->listenerType() == ListenerType::exit) + else if (hitType == ListenerType::up && + listenerGroup->clickPhase() == GestureClickPhase::down) { - listener->performChanges(m_stateMachineInstance, position, previousPosition); - m_stateMachineInstance->markNeedsAdvance(); + listenerGroup->clickPhase(GestureClickPhase::clicked); } } - if (isOver && hitType == listener->listenerType()) + else { - listener->performChanges(m_stateMachineInstance, position, previousPosition); + if (hitType == ListenerType::down || hitType == ListenerType::up) + { + listenerGroup->clickPhase(GestureClickPhase::out); + } + } + auto listener = listenerGroup->listener(); + // Always update hover states regardless of which specific listener type + // we're trying to trigger. + // If hover has changed and: + // - it's hovering and the listener is of type enter + // - it's not hovering and the listener is of type exit + if (hoverChange && + ((isGroupHovered && listener->listenerType() == ListenerType::enter) || + (!isGroupHovered && listener->listenerType() == ListenerType::exit))) + { + listener->performChanges(m_stateMachineInstance, + position, + listenerGroup->previousPosition); m_stateMachineInstance->markNeedsAdvance(); + listenerGroup->consume(); } + // Perform changes if: + // - the click gesture is complete and the listener is of type click + // - the event type matches the listener type and it is hovering the group + if ((listenerGroup->clickPhase() == GestureClickPhase::clicked && + listener->listenerType() == ListenerType::click) || + (isGroupHovered && hitType == listener->listenerType())) + { + listener->performChanges(m_stateMachineInstance, + position, + listenerGroup->previousPosition); + m_stateMachineInstance->markNeedsAdvance(); + listenerGroup->consume(); + } + listenerGroup->previousPosition.x = position.x; + listenerGroup->previousPosition.y = position.y; } - previousPosition.x = position.x; - previousPosition.y = position.y; - return isOver ? shape->isTargetOpaque() ? HitResult::hitOpaque : HitResult::hit - : HitResult::none; + return (isHovered && canHit) + ? shape->isTargetOpaque() ? HitResult::hitOpaque : HitResult::hit + : HitResult::none; } - void addListener(const StateMachineListener* stateMachineListener) + void addListener(ListenerGroup* listenerGroup) { + auto stateMachineListener = listenerGroup->listener(); auto listenerType = stateMachineListener->listenerType(); if (listenerType == ListenerType::enter || listenerType == ListenerType::exit || listenerType == ListenerType::move) @@ -530,16 +628,16 @@ class HitShape : public HitComponent } else { - if (listenerType == ListenerType::down) + if (listenerType == ListenerType::down || listenerType == ListenerType::click) { hasDownListener = true; } - else if (listenerType == ListenerType::up) + if (listenerType == ListenerType::up || listenerType == ListenerType::click) { hasUpListener = true; } } - listeners.push_back(stateMachineListener); + listeners.push_back(listenerGroup); } }; class HitNestedArtboard : public HitComponent @@ -615,6 +713,7 @@ class HitNestedArtboard : public HitComponent case ListenerType::enter: case ListenerType::exit: case ListenerType::event: + case ListenerType::click: break; } } @@ -630,6 +729,7 @@ class HitNestedArtboard : public HitComponent case ListenerType::enter: case ListenerType::exit: case ListenerType::event: + case ListenerType::click: break; } } @@ -637,7 +737,9 @@ class HitNestedArtboard : public HitComponent } return hitResult; } + void prepareEvent(Vec2D position, ListenerType hitType) override {} }; + } // namespace rive HitResult StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) @@ -647,9 +749,19 @@ HitResult StateMachineInstance::updateListeners(Vec2D position, ListenerType hit position -= Vec2D(m_artboardInstance->originX() * m_artboardInstance->width(), m_artboardInstance->originY() * m_artboardInstance->height()); } - + // First reset all listener groups before processing the events + for (const auto& listenerGroup : m_listenerGroups) + { + listenerGroup.get()->reset(); + } + // Next prepare the event to set the common hover status for each group + for (const auto& hitShape : m_hitComponents) + { + hitShape->prepareEvent(position, hitType); + } bool hitSomething = false; bool hitOpaque = false; + // Finally process the events for (const auto& hitShape : m_hitComponents) { // TODO: quick reject. @@ -706,6 +818,17 @@ HitResult StateMachineInstance::pointerExit(Vec2D position) return updateListeners(position, ListenerType::exit); } +#ifdef TESTING +const LayerState* StateMachineInstance::layerState(size_t index) +{ + if (index < m_machine->layerCount()) + { + return m_layers[index].currentState(); + } + return nullptr; +} +#endif + StateMachineInstance::StateMachineInstance(const StateMachine* machine, ArtboardInstance* instance) : Scene(instance), m_machine(machine) @@ -791,6 +914,7 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, { continue; } + auto listenerGroup = rivestd::make_unique(listener); auto target = m_artboardInstance->resolve(listener->targetId()); if (target != nullptr && target->is()) { @@ -811,11 +935,12 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, { hitShape = itr->second; } - hitShape->addListener(listener); + hitShape->addListener(listenerGroup.get()); } return true; }); } + m_listenerGroups.push_back(std::move(listenerGroup)); } for (auto nestedArtboard : instance->nestedArtboards()) diff --git a/test/assets/click_event.riv b/test/assets/click_event.riv new file mode 100644 index 0000000000000000000000000000000000000000..583f6b4e490f9155b45691bd86e7ecc7b85bbcc1 GIT binary patch literal 802 zcma*kyGjE=6b9h`?3~G}Xw(od5k#AmB5MdiM59KDf|Z5X3NBV&STA5_W23cLXldbF z*jng27?OAmf;NIpJiF^-Mf z*QmxNs`3Nluh9jvf%ig#zdWnv8iDnaw>98kkJxf|G+=2YuCM0uP}*t%E+^yu0$Zyj zFjMI87bJ9x%(ir0#%FM*AVJx(wH*n@CDRxTs5`G1}w5hT#*oLvFwkO}Gse?YB>Q?od=eu4VI05p(~MS_O>KO7S}9-1e$C77{KQ0ogc_6wAweyL1D zv|)f6J0YlX)&w09(5>}i@C{L1p;aiJ5PW0~s?)$ZAA*ZIOmiy9?sl0_kuNd+;-~om DFw?2I literal 0 HcmV?d00001 diff --git a/test/hittest_test.cpp b/test/hittest_test.cpp index debc2d47..6c12c9f8 100644 --- a/test/hittest_test.cpp +++ b/test/hittest_test.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "rive_file_reader.hpp" #include @@ -245,5 +246,141 @@ TEST_CASE("early out on listeners", "[hittest]") REQUIRE(hitComponentOpaque->earlyOutCount == 0); REQUIRE(hitComponentOnlyPointerDown->earlyOutCount == 4); + delete stateMachineInstance; +} + +TEST_CASE("click event", "[hittest]") +{ + // This test has two rectangles of size [200, 200] + // positioned at [100,100] and [200, 200] + // they overlap between coordinates [100,100]-[200, 200] + // they are inside a group that has a listener attached to it + // that listener should fire an event on "Click" + auto file = ReadRiveFile("../../test/assets/click_event.riv"); + + auto artboard = file->artboard("art-1"); + auto artboardInstance = artboard->instance(); + auto stateMachine = artboard->stateMachine("sm-1"); + + REQUIRE(artboardInstance != nullptr); + REQUIRE(artboardInstance->stateMachineCount() == 1); + + REQUIRE(stateMachine != nullptr); + + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, artboardInstance.get()); + + stateMachineInstance->advance(0.0f); + artboardInstance->advance(0.0f); + REQUIRE(stateMachineInstance->needsAdvance() == true); + stateMachineInstance->advance(0.0f); + // There is a single listener with two shapes in it + REQUIRE(stateMachineInstance->hitComponentsCount() == 2); + auto layerCount = stateMachine->layerCount(); + REQUIRE(layerCount == 1); + REQUIRE(stateMachineInstance->reportedEventCount() == 0); + // Click in place should trigger a click event + stateMachineInstance->pointerDown(rive::Vec2D(75.0f, 75.0f)); + stateMachineInstance->pointerUp(rive::Vec2D(75.0f, 75.0f)); + REQUIRE(stateMachineInstance->reportedEventCount() == 1); + // Pointer down inside shape but Pointer up outside the shape + // should not trigger a click event + stateMachineInstance->pointerDown(rive::Vec2D(75.0f, 75.0f)); + stateMachineInstance->pointerUp(rive::Vec2D(300.0f, 75.0f)); + REQUIRE(stateMachineInstance->reportedEventCount() == 1); + // Pointer down outside shape but Pointer up inside the shape + // should not trigger a click event + stateMachineInstance->pointerDown(rive::Vec2D(300.0f, 75.0f)); + stateMachineInstance->pointerUp(rive::Vec2D(75.0f, 75.0f)); + REQUIRE(stateMachineInstance->reportedEventCount() == 1); + // Pointer down in shape 1 Pointer up in shape 2 of the same group + // should trigger a click event + stateMachineInstance->pointerDown(rive::Vec2D(75.0f, 75.0f)); + stateMachineInstance->pointerUp(rive::Vec2D(225.0f, 225.0f)); + REQUIRE(stateMachineInstance->reportedEventCount() == 2); + // Pointer down and up in area where both shapes overlap + // should trigger a single click event + stateMachineInstance->pointerDown(rive::Vec2D(150.0f, 150.0f)); + stateMachineInstance->pointerUp(rive::Vec2D(150.0f, 150.0f)); + REQUIRE(stateMachineInstance->reportedEventCount() == 3); + + delete stateMachineInstance; +} + +TEST_CASE("multiple shapes with mouse movement behavior", "[hittest]") +{ + // This test has two rectangles of size [200, 200] + // positioned at [100,100] and [100, 200] + // they overlap between coordinates [100,0]-[200, 200] + // they are inside a group that has a Pointer enter and a Pointer out + // listeners that toggle between two states (red and green) + // starting at "red" + auto file = ReadRiveFile("../../test/assets/click_event.riv"); + + auto artboard = file->artboard("art-2"); + auto artboardInstance = artboard->instance(); + auto stateMachine = artboard->stateMachine("sm-1"); + + REQUIRE(artboardInstance != nullptr); + REQUIRE(artboardInstance->stateMachineCount() == 1); + + REQUIRE(stateMachine != nullptr); + + rive::StateMachineInstance* stateMachineInstance = + new rive::StateMachineInstance(stateMachine, artboardInstance.get()); + + stateMachineInstance->advance(0.0f); + artboardInstance->advance(0.0f); + REQUIRE(stateMachineInstance->needsAdvance() == true); + stateMachineInstance->advance(0.0f); + // There is a single listener with two shapes in it + REQUIRE(stateMachineInstance->hitComponentsCount() == 2); + auto layerCount = stateMachine->layerCount(); + REQUIRE(layerCount == 1); + // Move over the first shape + stateMachineInstance->pointerMove(rive::Vec2D(75.0f, 75.0f)); + artboardInstance->advance(0.0f); + stateMachineInstance->advanceAndApply(0.0f); + + { + auto state = stateMachineInstance->layerState(0); + REQUIRE(state->is()); + auto animation = state->as()->animation(); + REQUIRE(animation->name() == "green"); + } + // Move over the second shape, nothing should change + stateMachineInstance->pointerMove(rive::Vec2D(200.0f, 75.0f)); + artboardInstance->advance(0.0f); + stateMachineInstance->advanceAndApply(0.0f); + + { + auto state = stateMachineInstance->layerState(0); + REQUIRE(state->is()); + auto animation = state->as()->animation(); + REQUIRE(animation->name() == "green"); + } + // Move out of the second shape, should go back to red + stateMachineInstance->pointerMove(rive::Vec2D(400.0f, 75.0f)); + artboardInstance->advance(0.0f); + stateMachineInstance->advanceAndApply(0.0f); + + { + auto state = stateMachineInstance->layerState(0); + REQUIRE(state->is()); + auto animation = state->as()->animation(); + REQUIRE(animation->name() == "red"); + } + // Move back into the second shape, should go to green + stateMachineInstance->pointerMove(rive::Vec2D(200.0f, 75.0f)); + artboardInstance->advance(0.0f); + stateMachineInstance->advanceAndApply(0.0f); + + { + auto state = stateMachineInstance->layerState(0); + REQUIRE(state->is()); + auto animation = state->as()->animation(); + REQUIRE(animation->name() == "green"); + } + delete stateMachineInstance; } \ No newline at end of file From 8a1d9a481b215cfd9d1bc39fac742b9d268f50e7 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Mon, 29 Jul 2024 22:50:18 +0000 Subject: [PATCH 111/138] Buildsystem fixes for build_rive.sh and PLS shaders build_rive.sh wasn't catching all the build errors with just 'set -e'. Add 'set -o pipefail' to catch the errors being piped into 'grep -v'. The complicated logic in premake5_pls_renderer.lua that was being executed as a bash "if" had an issue. Rewrite this logic in Lua. Diffs= fbfa3b545 Buildsystem fixes for build_rive.sh and PLS shaders (#7716) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/build_rive.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index e4ff0e3d..ed516e7c 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -405ca998b7729cb4f84448fe681e9c4a82243099 +fbfa3b545dbfbe5616ee725f0dbb59b2626c603c diff --git a/build/build_rive.sh b/build/build_rive.sh index 9329927d..48ad9503 100755 --- a/build/build_rive.sh +++ b/build/build_rive.sh @@ -54,6 +54,7 @@ # build_rive.sh rebuild out/debug gms goldens # args after OUT get forwarded to the buildsystem set -e +set -o pipefail # Detect where build_rive.sh is located on disk. # https://stackoverflow.com/questions/59895/how-do-i-get-the-directory-where-a-bash-script-is-located-from-within-the-script From 7a409bd0d028a559f77e337d78ba633d877bf429 Mon Sep 17 00:00:00 2001 From: philter Date: Wed, 31 Jul 2024 01:19:30 +0000 Subject: [PATCH 112/138] Fix alignment when flex wrap enabled Fixes an issue where layout alignment wasn't working when flex wrap was enabled. **Before:** https://github.com/user-attachments/assets/0486c436-0049-49d8-8483-b6fdbf1cf2d5 **After:** https://github.com/user-attachments/assets/0014e624-6b83-4417-a93d-6e1adea41bd3 Diffs= dcb165130 Fix alignment when flex wrap enabled (#7722) Co-authored-by: Philip Chung --- .rive_head | 2 +- src/layout_component.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index ed516e7c..791ad29e 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -fbfa3b545dbfbe5616ee725f0dbb59b2626c603c +dcb1651300467e52124259dcdf0f61acf34148b4 diff --git a/src/layout_component.cpp b/src/layout_component.cpp index c361048b..3bd963df 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -321,6 +321,7 @@ void LayoutComponent::syncStyle() if (isRowForAlignment) { ygStyle.alignItems() = YGAlignFlexStart; + ygStyle.alignContent() = YGAlignFlexStart; } else { @@ -334,6 +335,7 @@ void LayoutComponent::syncStyle() if (isRowForAlignment) { ygStyle.alignItems() = YGAlignCenter; + ygStyle.alignContent() = YGAlignCenter; } else { @@ -347,6 +349,7 @@ void LayoutComponent::syncStyle() if (isRowForAlignment) { ygStyle.alignItems() = YGAlignFlexEnd; + ygStyle.alignContent() = YGAlignFlexEnd; } else { @@ -366,6 +369,7 @@ void LayoutComponent::syncStyle() else { ygStyle.alignItems() = YGAlignFlexStart; + ygStyle.alignContent() = YGAlignFlexStart; } break; case LayoutAlignmentType::topCenter: @@ -378,6 +382,7 @@ void LayoutComponent::syncStyle() else { ygStyle.alignItems() = YGAlignCenter; + ygStyle.alignContent() = YGAlignCenter; } break; case LayoutAlignmentType::topRight: @@ -390,6 +395,7 @@ void LayoutComponent::syncStyle() else { ygStyle.alignItems() = YGAlignFlexEnd; + ygStyle.alignContent() = YGAlignFlexEnd; } break; case LayoutAlignmentType::spaceBetweenStart: From 4afdae650937701a4c0564606b9b9e542b4fbc35 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Thu, 1 Aug 2024 01:10:57 +0000 Subject: [PATCH 113/138] add listener actions support for databind adds support for manipulating view model values from state machines through listener actions https://github.com/user-attachments/assets/7ddd4cd2-a04d-4d33-98de-b1f29aa24755 Diffs= d9f5701ec add listener actions support for databind (#7710) Co-authored-by: hernan --- .rive_head | 2 +- .../animation/listener_viewmodel_change.json | 38 +++++++++++++++++++ .../animation/listener_viewmodel_change.hpp | 21 ++++++++++ .../rive/animation/state_machine_instance.hpp | 2 + include/rive/data_bind/bindable_property.hpp | 9 +---- .../listener_viewmodel_change_base.hpp | 36 ++++++++++++++++++ include/rive/generated/core_registry.hpp | 3 ++ src/animation/listener_viewmodel_change.cpp | 37 ++++++++++++++++++ src/animation/state_machine_instance.cpp | 14 ++++++- .../listener_viewmodel_change_base.cpp | 11 ++++++ 10 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 dev/defs/animation/listener_viewmodel_change.json create mode 100644 include/rive/animation/listener_viewmodel_change.hpp create mode 100644 include/rive/generated/animation/listener_viewmodel_change_base.hpp create mode 100644 src/animation/listener_viewmodel_change.cpp create mode 100644 src/generated/animation/listener_viewmodel_change_base.cpp diff --git a/.rive_head b/.rive_head index 791ad29e..a891ec73 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -dcb1651300467e52124259dcdf0f61acf34148b4 +d9f5701ec10c0d0eecb0e3d2f5b0ee80499c746d diff --git a/dev/defs/animation/listener_viewmodel_change.json b/dev/defs/animation/listener_viewmodel_change.json new file mode 100644 index 00000000..96ffb5b5 --- /dev/null +++ b/dev/defs/animation/listener_viewmodel_change.json @@ -0,0 +1,38 @@ +{ + "name": "ListenerViewModelChange", + "key": { + "int": 487, + "string": "listenerviewmodelchange" + }, + "extends": "animation/listener_action.json", + "properties": { + "bindablePropertyId": { + "type": "Id", + "key": { + "int": 657, + "string": "bindablepropertyid" + }, + "description": "Id of the bindable property", + "runtime": false + }, + "fromViewModelProperty": { + "type": "bool", + "key": { + "int": 658, + "string": "fromviewmodelproperty" + }, + "description": "Whether it is using another view model property as the value", + "runtime": false + }, + "fromDataBindId": { + "type": "Id", + "initialValue": "Core.missingId", + "key": { + "int": 659, + "string": "fromdatabindid" + }, + "description": "Id of the data bind used if the value is taken from another view model property (only needed if fromViewModelProperty is true)", + "runtime": false + } + } +} \ No newline at end of file diff --git a/include/rive/animation/listener_viewmodel_change.hpp b/include/rive/animation/listener_viewmodel_change.hpp new file mode 100644 index 00000000..a9b82a1d --- /dev/null +++ b/include/rive/animation/listener_viewmodel_change.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_LISTENER_VIEW_MODEL_CHANGE_HPP_ +#define _RIVE_LISTENER_VIEW_MODEL_CHANGE_HPP_ +#include "rive/generated/animation/listener_viewmodel_change_base.hpp" +#include "rive/data_bind/bindable_property.hpp" +#include +namespace rive +{ +class ListenerViewModelChange : public ListenerViewModelChangeBase +{ +public: + void perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const override; + StatusCode import(ImportStack& importStack) override; + +private: + BindableProperty* m_bindableProperty; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index 093d05bb..ce34a035 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -137,6 +137,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne const EventReport reportedEventAt(std::size_t index) const; bool playsAudio() override { return true; } BindableProperty* bindablePropertyInstance(BindableProperty* bindableProperty); + DataBind* bindableDataBind(BindableProperty* bindableProperty); #ifdef TESTING size_t hitComponentsCount() { return m_hitComponents.size(); }; HitComponent* hitComponent(size_t index) @@ -164,6 +165,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne NestedArtboard* m_parentNestedArtboard = nullptr; std::vector m_dataBinds; std::unordered_map m_bindablePropertyInstances; + std::unordered_map m_bindableDataBinds; #ifdef WITH_RIVE_TOOLS public: diff --git a/include/rive/data_bind/bindable_property.hpp b/include/rive/data_bind/bindable_property.hpp index 3294401f..cbfb148b 100644 --- a/include/rive/data_bind/bindable_property.hpp +++ b/include/rive/data_bind/bindable_property.hpp @@ -6,14 +6,7 @@ namespace rive { class BindableProperty : public BindablePropertyBase -{ -public: - void dataBind(DataBind* value) { m_dataBind = value; }; - DataBind* dataBind() { return m_dataBind; }; - -private: - DataBind* m_dataBind; -}; +{}; } // namespace rive #endif \ No newline at end of file diff --git a/include/rive/generated/animation/listener_viewmodel_change_base.hpp b/include/rive/generated/animation/listener_viewmodel_change_base.hpp new file mode 100644 index 00000000..4171141c --- /dev/null +++ b/include/rive/generated/animation/listener_viewmodel_change_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_LISTENER_VIEW_MODEL_CHANGE_BASE_HPP_ +#define _RIVE_LISTENER_VIEW_MODEL_CHANGE_BASE_HPP_ +#include "rive/animation/listener_action.hpp" +namespace rive +{ +class ListenerViewModelChangeBase : public ListenerAction +{ +protected: + typedef ListenerAction Super; + +public: + static const uint16_t typeKey = 487; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case ListenerViewModelChangeBase::typeKey: + case ListenerActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 65a3ac90..592e41ba 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -39,6 +39,7 @@ #include "rive/animation/listener_input_change.hpp" #include "rive/animation/listener_number_change.hpp" #include "rive/animation/listener_trigger_change.hpp" +#include "rive/animation/listener_viewmodel_change.hpp" #include "rive/animation/nested_bool.hpp" #include "rive/animation/nested_input.hpp" #include "rive/animation/nested_linear_animation.hpp" @@ -353,6 +354,8 @@ class CoreRegistry return new ListenerTriggerChange(); case BlendStateDirectBase::typeKey: return new BlendStateDirect(); + case ListenerViewModelChangeBase::typeKey: + return new ListenerViewModelChange(); case TransitionValueNumberComparatorBase::typeKey: return new TransitionValueNumberComparator(); case NestedStateMachineBase::typeKey: diff --git a/src/animation/listener_viewmodel_change.cpp b/src/animation/listener_viewmodel_change.cpp new file mode 100644 index 00000000..5047ee53 --- /dev/null +++ b/src/animation/listener_viewmodel_change.cpp @@ -0,0 +1,37 @@ +#include "rive/animation/listener_viewmodel_change.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/data_bind/bindable_property.hpp" +#include "rive/importers/bindable_property_importer.hpp" + +using namespace rive; + +StatusCode ListenerViewModelChange::import(ImportStack& importStack) +{ + + auto bindablePropertyImporter = + importStack.latest(BindablePropertyBase::typeKey); + if (bindablePropertyImporter == nullptr) + { + return StatusCode::MissingObject; + } + m_bindableProperty = bindablePropertyImporter->bindableProperty(); + + return Super::import(importStack); +} + +// Note: perform works the same way whether the value comes from a direct value assignment or from +// another view model. In the case of coming from another view model, the state machine instance +// method "updataDataBinds" will handle updating the value of the bound object. That's the benefit +// of binding the same bindable property with two data binding objects. +void ListenerViewModelChange::perform(StateMachineInstance* stateMachineInstance, + Vec2D position, + Vec2D previousPosition) const +{ + // Get the bindable property instance from the state machine instance context + auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + // Get the data bound object (that goes from target to source) from this bindable instance + auto dataBind = stateMachineInstance->bindableDataBind(bindableInstance); + // Apply the change that will assign the value of the bindable property to the view model + // property instance + dataBind->updateSourceBinding(); +} \ No newline at end of file diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index 219200f3..c49745fe 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -896,9 +896,11 @@ StateMachineInstance::StateMachineInstance(const StateMachine* machine, bindablePropertyClone = bindablePropertyInstance->second; } dataBindClone->target(bindablePropertyClone); + // We are only storing in this unordered map data binds that are targetting the source. + // For now, this is only the case for listener actions. if (static_cast(dataBindClone->flags()) == DataBindFlags::ToSource) { - bindablePropertyClone->dataBind(dataBindClone); + m_bindableDataBinds[bindablePropertyClone] = dataBindClone; } } } @@ -1265,3 +1267,13 @@ BindableProperty* StateMachineInstance::bindablePropertyInstance(BindablePropert } return bindablePropertyInstance->second; } + +DataBind* StateMachineInstance::bindableDataBind(BindableProperty* bindableProperty) +{ + auto dataBind = m_bindableDataBinds.find(bindableProperty); + if (dataBind == m_bindableDataBinds.end()) + { + return nullptr; + } + return dataBind->second; +} diff --git a/src/generated/animation/listener_viewmodel_change_base.cpp b/src/generated/animation/listener_viewmodel_change_base.cpp new file mode 100644 index 00000000..96d9e9a2 --- /dev/null +++ b/src/generated/animation/listener_viewmodel_change_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/listener_viewmodel_change_base.hpp" +#include "rive/animation/listener_viewmodel_change.hpp" + +using namespace rive; + +Core* ListenerViewModelChangeBase::clone() const +{ + auto cloned = new ListenerViewModelChange(); + cloned->copy(*this); + return cloned; +} From 62025f9f3024e2c7c7743c797a0fb0c89122d56c Mon Sep 17 00:00:00 2001 From: bodymovin Date: Sat, 3 Aug 2024 02:24:40 +0000 Subject: [PATCH 114/138] add data converter and data types for conversion First PR for converters support. It adds the abstract data_converter class And adds new data value objects that can be passed between converters to easily transform one type of data to another https://github.com/user-attachments/assets/e8a0fdee-8845-4d0d-a894-c948c2b0a209 Diffs= 4bf7c7545 add data converter and data types for conversion (#7734) Co-authored-by: hernan --- .rive_head | 2 +- .../data_bind/converters/data_converter.json | 30 +++++ dev/defs/data_bind/data_bind.json | 11 ++ include/rive/artboard.hpp | 1 + .../rive/data_bind/context/context_value.hpp | 37 +++++- .../context/context_value_boolean.hpp | 9 +- .../data_bind/context/context_value_color.hpp | 9 +- .../data_bind/context/context_value_enum.hpp | 9 +- .../data_bind/context/context_value_list.hpp | 8 +- .../context/context_value_number.hpp | 9 +- .../context/context_value_string.hpp | 9 +- .../data_bind/converters/data_converter.hpp | 18 +++ include/rive/data_bind/data_bind.hpp | 6 + .../rive/data_bind/data_values/data_type.hpp | 30 +++++ .../rive/data_bind/data_values/data_value.hpp | 21 +++ .../data_values/data_value_boolean.hpp | 23 ++++ .../data_values/data_value_color.hpp | 23 ++++ .../data_bind/data_values/data_value_enum.hpp | 26 ++++ .../data_values/data_value_number.hpp | 23 ++++ .../data_values/data_value_string.hpp | 22 ++++ include/rive/generated/core_registry.hpp | 17 +++ .../converters/data_converter_base.hpp | 66 ++++++++++ .../generated/data_bind/data_bind_base.hpp | 18 +++ include/rive/importers/backboard_importer.hpp | 6 + src/data_bind/context/context_value.cpp | 122 ++++++++++++++++++ .../context/context_value_boolean.cpp | 26 ++-- src/data_bind/context/context_value_color.cpp | 26 ++-- src/data_bind/context/context_value_enum.cpp | 41 +++--- src/data_bind/context/context_value_list.cpp | 16 ++- .../context/context_value_number.cpp | 26 ++-- .../context/context_value_string.cpp | 26 ++-- src/data_bind/converters/data_converter.cpp | 18 +++ src/data_bind/data_bind.cpp | 75 ++++++++--- src/importers/backboard_importer.cpp | 21 +++ 34 files changed, 684 insertions(+), 146 deletions(-) create mode 100644 dev/defs/data_bind/converters/data_converter.json create mode 100644 include/rive/data_bind/converters/data_converter.hpp create mode 100644 include/rive/data_bind/data_values/data_type.hpp create mode 100644 include/rive/data_bind/data_values/data_value.hpp create mode 100644 include/rive/data_bind/data_values/data_value_boolean.hpp create mode 100644 include/rive/data_bind/data_values/data_value_color.hpp create mode 100644 include/rive/data_bind/data_values/data_value_enum.hpp create mode 100644 include/rive/data_bind/data_values/data_value_number.hpp create mode 100644 include/rive/data_bind/data_values/data_value_string.hpp create mode 100644 include/rive/generated/data_bind/converters/data_converter_base.hpp create mode 100644 src/data_bind/context/context_value.cpp create mode 100644 src/data_bind/converters/data_converter.cpp diff --git a/.rive_head b/.rive_head index a891ec73..b0804700 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -d9f5701ec10c0d0eecb0e3d2f5b0ee80499c746d +4bf7c75453f0fc3fec1519a9a3dfe7a4ed63a054 diff --git a/dev/defs/data_bind/converters/data_converter.json b/dev/defs/data_bind/converters/data_converter.json new file mode 100644 index 00000000..b5a0c49e --- /dev/null +++ b/dev/defs/data_bind/converters/data_converter.json @@ -0,0 +1,30 @@ +{ + "name": "DataConverter", + "key": { + "int": 488, + "string": "dataconverter" + }, + "abstract": true, + "properties": { + "order": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "initialValueRuntime": "0", + "key": { + "int": 661, + "string": "order" + }, + "description": "Order value for sorting data converters", + "runtime": false + }, + "name": { + "type": "String", + "initialValue": "''", + "key": { + "int": 662, + "string": "name" + }, + "description": "Non-unique identifier, used to give friendly names to data converters." + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/data_bind.json b/dev/defs/data_bind/data_bind.json index 3e3124d5..3ec525b6 100644 --- a/dev/defs/data_bind/data_bind.json +++ b/dev/defs/data_bind/data_bind.json @@ -31,6 +31,17 @@ "int": 587, "string": "flags" } + }, + "converterId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 660, + "string": "converterid" + }, + "description": "Identifier used to link to a data converter." } } } \ No newline at end of file diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 2e78c7e8..e3cf8027 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -295,6 +295,7 @@ class Artboard : public ArtboardBase, public CoreContext { auto dataBindClone = static_cast(dataBind->clone()); dataBindClone->target(cloneObjects.back()); + dataBindClone->converter(dataBind->converter()); artboardClone->m_DataBinds.push_back(dataBindClone); } } diff --git a/include/rive/data_bind/context/context_value.hpp b/include/rive/data_bind/context/context_value.hpp index 370f46f0..c26730b2 100644 --- a/include/rive/data_bind/context/context_value.hpp +++ b/include/rive/data_bind/context/context_value.hpp @@ -1,21 +1,48 @@ #ifndef _RIVE_DATA_BIND_CONTEXT_VALUE_HPP_ #define _RIVE_DATA_BIND_CONTEXT_VALUE_HPP_ -#include "rive/refcnt.hpp" #include "rive/viewmodel/viewmodel_instance_value.hpp" +#include "rive/data_bind/converters/data_converter.hpp" #include namespace rive { class DataBindContextValue { protected: - ViewModelInstanceValue* m_Source; + ViewModelInstanceValue* m_source; + DataConverter* m_converter; + DataValue* m_dataValue; public: - DataBindContextValue(){}; + DataBindContextValue(ViewModelInstanceValue* source, DataConverter* converter); virtual ~DataBindContextValue(){}; - virtual void applyToSource(Core* component, uint32_t propertyKey){}; - virtual void apply(Core* component, uint32_t propertyKey){}; + virtual void applyToSource(Core* component, uint32_t propertyKey, bool isMainDirection); + virtual void apply(Core* component, uint32_t propertyKey, bool isMainDirection){}; virtual void update(Core* component){}; + virtual DataValue* getTargetValue(Core* target, uint32_t propertyKey) { return nullptr; }; + void updateSourceValue(); + template U getDataValue(DataValue* input) + { + auto dataValue = m_converter != nullptr ? m_converter->convert(input) : input; + if (dataValue->is()) + { + return dataValue->as()->value(); + } + return (new T())->value(); + }; + template U getReverseDataValue(DataValue* input) + { + auto dataValue = m_converter != nullptr ? m_converter->reverseConvert(input) : input; + if (dataValue->is()) + { + return dataValue->as()->value(); + } + return (new T())->value(); + }; + template + U calculateValue(DataValue* input, bool isMainDirection) + { + return isMainDirection ? getDataValue(input) : getReverseDataValue(input); + }; }; } // namespace rive diff --git a/include/rive/data_bind/context/context_value_boolean.hpp b/include/rive/data_bind/context/context_value_boolean.hpp index 82e9a7fa..678e7fc5 100644 --- a/include/rive/data_bind/context/context_value_boolean.hpp +++ b/include/rive/data_bind/context/context_value_boolean.hpp @@ -7,12 +7,9 @@ class DataBindContextValueBoolean : public DataBindContextValue { public: - DataBindContextValueBoolean(ViewModelInstanceValue* value); - void apply(Core* component, uint32_t propertyKey) override; - virtual void applyToSource(Core* component, uint32_t propertyKey) override; - -private: - bool m_Value; + DataBindContextValueBoolean(ViewModelInstanceValue* source, DataConverter* converter); + void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; + DataValue* getTargetValue(Core* target, uint32_t propertyKey) override; }; } // namespace rive diff --git a/include/rive/data_bind/context/context_value_color.hpp b/include/rive/data_bind/context/context_value_color.hpp index 22fe8f85..207062a8 100644 --- a/include/rive/data_bind/context/context_value_color.hpp +++ b/include/rive/data_bind/context/context_value_color.hpp @@ -7,12 +7,9 @@ class DataBindContextValueColor : public DataBindContextValue { public: - DataBindContextValueColor(ViewModelInstanceValue* value); - void apply(Core* component, uint32_t propertyKey) override; - virtual void applyToSource(Core* component, uint32_t propertyKey) override; - -private: - double m_Value; + DataBindContextValueColor(ViewModelInstanceValue* source, DataConverter* converter); + void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; + DataValue* getTargetValue(Core* target, uint32_t propertyKey) override; }; } // namespace rive diff --git a/include/rive/data_bind/context/context_value_enum.hpp b/include/rive/data_bind/context/context_value_enum.hpp index 98c21c46..dd097b23 100644 --- a/include/rive/data_bind/context/context_value_enum.hpp +++ b/include/rive/data_bind/context/context_value_enum.hpp @@ -7,12 +7,9 @@ class DataBindContextValueEnum : public DataBindContextValue { public: - DataBindContextValueEnum(ViewModelInstanceValue* value); - void apply(Core* component, uint32_t propertyKey) override; - virtual void applyToSource(Core* component, uint32_t propertyKey) override; - -private: - int m_Value; + DataBindContextValueEnum(ViewModelInstanceValue* source, DataConverter* converter); + void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; + DataValue* getTargetValue(Core* target, uint32_t propertyKey) override; }; } // namespace rive diff --git a/include/rive/data_bind/context/context_value_list.hpp b/include/rive/data_bind/context/context_value_list.hpp index 0c12f912..5dd95861 100644 --- a/include/rive/data_bind/context/context_value_list.hpp +++ b/include/rive/data_bind/context/context_value_list.hpp @@ -11,10 +11,12 @@ class DataBindContextValueList : public DataBindContextValue { public: - DataBindContextValueList(ViewModelInstanceValue* value); - void apply(Core* component, uint32_t propertyKey) override; + DataBindContextValueList(ViewModelInstanceValue* source, DataConverter* converter); + void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; void update(Core* target) override; - virtual void applyToSource(Core* component, uint32_t propertyKey) override; + virtual void applyToSource(Core* component, + uint32_t propertyKey, + bool isMainDirection) override; private: std::vector> m_ListItemsCache; diff --git a/include/rive/data_bind/context/context_value_number.hpp b/include/rive/data_bind/context/context_value_number.hpp index b2d850ab..f3a56fa2 100644 --- a/include/rive/data_bind/context/context_value_number.hpp +++ b/include/rive/data_bind/context/context_value_number.hpp @@ -7,12 +7,9 @@ class DataBindContextValueNumber : public DataBindContextValue { public: - DataBindContextValueNumber(ViewModelInstanceValue* value); - void apply(Core* component, uint32_t propertyKey) override; - virtual void applyToSource(Core* component, uint32_t propertyKey) override; - -private: - double m_Value; + DataBindContextValueNumber(ViewModelInstanceValue* source, DataConverter* converter); + void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; + DataValue* getTargetValue(Core* target, uint32_t propertyKey) override; }; } // namespace rive diff --git a/include/rive/data_bind/context/context_value_string.hpp b/include/rive/data_bind/context/context_value_string.hpp index 0b32528d..fb8f3cfc 100644 --- a/include/rive/data_bind/context/context_value_string.hpp +++ b/include/rive/data_bind/context/context_value_string.hpp @@ -7,12 +7,9 @@ class DataBindContextValueString : public DataBindContextValue { public: - DataBindContextValueString(ViewModelInstanceValue* value); - void apply(Core* component, uint32_t propertyKey) override; - virtual void applyToSource(Core* component, uint32_t propertyKey) override; - -private: - std::string m_Value; + DataBindContextValueString(ViewModelInstanceValue* source, DataConverter* converter); + void apply(Core* component, uint32_t propertyKey, bool isMainDirection) override; + DataValue* getTargetValue(Core* target, uint32_t propertyKey) override; }; } // namespace rive diff --git a/include/rive/data_bind/converters/data_converter.hpp b/include/rive/data_bind/converters/data_converter.hpp new file mode 100644 index 00000000..bf6deb68 --- /dev/null +++ b/include/rive/data_bind/converters/data_converter.hpp @@ -0,0 +1,18 @@ +#ifndef _RIVE_DATA_CONVERTER_HPP_ +#define _RIVE_DATA_CONVERTER_HPP_ +#include "rive/generated/data_bind/converters/data_converter_base.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include +namespace rive +{ +class DataConverter : public DataConverterBase +{ +public: + virtual DataValue* convert(DataValue* value) { return value; }; + virtual DataValue* reverseConvert(DataValue* value) { return value; }; + virtual DataType outputType() { return DataType::none; }; + StatusCode import(ImportStack& importStack) override; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_bind.hpp b/include/rive/data_bind/data_bind.hpp index 0ccccb3b..a62cfd66 100644 --- a/include/rive/data_bind/data_bind.hpp +++ b/include/rive/data_bind/data_bind.hpp @@ -5,6 +5,8 @@ #include "rive/viewmodel/viewmodel_instance_value.hpp" #include "rive/data_bind/context/context_value.hpp" #include "rive/data_bind/data_context.hpp" +#include "rive/data_bind/converters/data_converter.hpp" +#include "rive/data_bind/data_values/data_type.hpp" #include namespace rive { @@ -21,12 +23,16 @@ class DataBind : public DataBindBase ComponentDirt dirt() { return m_Dirt; }; void dirt(ComponentDirt value) { m_Dirt = value; }; bool addDirt(ComponentDirt value, bool recurse); + DataConverter* converter() const { return m_dataConverter; }; + void converter(DataConverter* value) { m_dataConverter = value; }; protected: ComponentDirt m_Dirt = ComponentDirt::Filthy; Core* m_target; ViewModelInstanceValue* m_Source; std::unique_ptr m_ContextValue; + DataConverter* m_dataConverter; + DataType outputType(); }; } // namespace rive diff --git a/include/rive/data_bind/data_values/data_type.hpp b/include/rive/data_bind/data_values/data_type.hpp new file mode 100644 index 00000000..c1740b5d --- /dev/null +++ b/include/rive/data_bind/data_values/data_type.hpp @@ -0,0 +1,30 @@ +#ifndef _RIVE_DATA_TYPE_HPP_ +#define _RIVE_DATA_TYPE_HPP_ +namespace rive +{ +/// Data types used for converters. +enum class DataType : unsigned int +{ + /// None. + none = 0, + + /// String. + string = 1, + + /// Number. + number = 2, + + /// Bool. + boolean = 3, + + /// Color. + color = 4, + + /// List. + list = 5, + + /// Enum. + enumType = 6 +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_values/data_value.hpp b/include/rive/data_bind/data_values/data_value.hpp new file mode 100644 index 00000000..e4121836 --- /dev/null +++ b/include/rive/data_bind/data_values/data_value.hpp @@ -0,0 +1,21 @@ +#ifndef _RIVE_DATA_VALUE_HPP_ +#define _RIVE_DATA_VALUE_HPP_ +#include "rive/data_bind/data_values/data_type.hpp" + +#include +namespace rive +{ +class DataValue +{ +public: + virtual bool isTypeOf(DataType dataType) const { return false; } + template inline bool is() const { return isTypeOf(T::typeKey); } + template inline T* as() + { + assert(is()); + return static_cast(this); + } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_values/data_value_boolean.hpp b/include/rive/data_bind/data_values/data_value_boolean.hpp new file mode 100644 index 00000000..4fd85750 --- /dev/null +++ b/include/rive/data_bind/data_values/data_value_boolean.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_DATA_VALUE_BOOLEAN_HPP_ +#define _RIVE_DATA_VALUE_BOOLEAN_HPP_ +#include "rive/data_bind/data_values/data_value.hpp" + +#include +namespace rive +{ +class DataValueBoolean : public DataValue +{ +private: + bool m_value = false; + +public: + DataValueBoolean(bool value) : m_value(value){}; + DataValueBoolean(){}; + static const DataType typeKey = DataType::boolean; + bool isTypeOf(DataType typeKey) const override { return typeKey == DataType::boolean; } + bool value() { return m_value; }; + void value(bool value) { m_value = value; }; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_values/data_value_color.hpp b/include/rive/data_bind/data_values/data_value_color.hpp new file mode 100644 index 00000000..fdc88b5b --- /dev/null +++ b/include/rive/data_bind/data_values/data_value_color.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_DATA_VALUE_COLOR_HPP_ +#define _RIVE_DATA_VALUE_COLOR_HPP_ +#include "rive/data_bind/data_values/data_value.hpp" + +#include +namespace rive +{ +class DataValueColor : public DataValue +{ +private: + int m_value = false; + +public: + DataValueColor(int value) : m_value(value){}; + DataValueColor(){}; + static const DataType typeKey = DataType::color; + bool isTypeOf(DataType typeKey) const override { return typeKey == DataType::color; } + int value() { return m_value; }; + void value(int value) { m_value = value; }; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_values/data_value_enum.hpp b/include/rive/data_bind/data_values/data_value_enum.hpp new file mode 100644 index 00000000..9c2dbe5f --- /dev/null +++ b/include/rive/data_bind/data_values/data_value_enum.hpp @@ -0,0 +1,26 @@ +#ifndef _RIVE_DATA_VALUE_ENUM_HPP_ +#define _RIVE_DATA_VALUE_ENUM_HPP_ +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/viewmodel/data_enum.hpp" + +#include +namespace rive +{ +class DataValueEnum : public DataValue +{ +private: + uint32_t m_value = 0; + DataEnum* m_dataEnum; + +public: + DataValueEnum(uint32_t value, DataEnum* dataEnum) : m_value(value), m_dataEnum(dataEnum){}; + DataValueEnum(){}; + static const DataType typeKey = DataType::enumType; + bool isTypeOf(DataType typeKey) const override { return typeKey == DataType::enumType; }; + uint32_t value() { return m_value; }; + void value(uint32_t value) { m_value = value; }; + DataEnum* dataEnum() { return m_dataEnum; }; + void dataEnum(DataEnum* value) { m_dataEnum = value; }; +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_values/data_value_number.hpp b/include/rive/data_bind/data_values/data_value_number.hpp new file mode 100644 index 00000000..90a3b5dd --- /dev/null +++ b/include/rive/data_bind/data_values/data_value_number.hpp @@ -0,0 +1,23 @@ +#ifndef _RIVE_DATA_VALUE_NUMBER_HPP_ +#define _RIVE_DATA_VALUE_NUMBER_HPP_ +#include "rive/data_bind/data_values/data_value.hpp" + +#include +namespace rive +{ +class DataValueNumber : public DataValue +{ +private: + float m_value = 0; + +public: + DataValueNumber(float value) : m_value(value){}; + DataValueNumber(){}; + static const DataType typeKey = DataType::number; + bool isTypeOf(DataType typeKey) const override { return typeKey == DataType::number; } + float value() { return m_value; }; + void value(float value) { m_value = value; }; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/data_values/data_value_string.hpp b/include/rive/data_bind/data_values/data_value_string.hpp new file mode 100644 index 00000000..7bf2676c --- /dev/null +++ b/include/rive/data_bind/data_values/data_value_string.hpp @@ -0,0 +1,22 @@ +#ifndef _RIVE_DATA_VALUE_STRING_HPP_ +#define _RIVE_DATA_VALUE_STRING_HPP_ +#include "rive/data_bind/data_values/data_value.hpp" + +#include +namespace rive +{ +class DataValueString : public DataValue +{ +private: + std::string m_value = ""; + +public: + DataValueString(std::string value) : m_value(value){}; + DataValueString(){}; + static const DataType typeKey = DataType::string; + bool isTypeOf(DataType typeKey) const override { return typeKey == DataType::string; }; + std::string value() { return m_value; }; + void value(std::string value) { m_value = value; }; +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 592e41ba..d8e9eb9b 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -118,6 +118,7 @@ #include "rive/data_bind/bindable_property_enum.hpp" #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" +#include "rive/data_bind/converters/data_converter.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_bind_context.hpp" #include "rive/draw_rules.hpp" @@ -994,6 +995,9 @@ class CoreRegistry case DataBindBase::flagsPropertyKey: object->as()->flags(value); break; + case DataBindBase::converterIdPropertyKey: + object->as()->converterId(value); + break; case BindablePropertyEnumBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -1132,6 +1136,9 @@ class CoreRegistry case OpenUrlEventBase::urlPropertyKey: object->as()->url(value); break; + case DataConverterBase::namePropertyKey: + object->as()->name(value); + break; case BindablePropertyStringBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -1999,6 +2006,8 @@ class CoreRegistry return object->as()->propertyKey(); case DataBindBase::flagsPropertyKey: return object->as()->flags(); + case DataBindBase::converterIdPropertyKey: + return object->as()->converterId(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->as()->propertyValue(); case NestedArtboardLeafBase::fitPropertyKey: @@ -2097,6 +2106,8 @@ class CoreRegistry return object->as()->value(); case OpenUrlEventBase::urlPropertyKey: return object->as()->url(); + case DataConverterBase::namePropertyKey: + return object->as()->name(); case BindablePropertyStringBase::propertyValuePropertyKey: return object->as()->propertyValue(); case TextValueRunBase::textPropertyKey: @@ -2617,6 +2628,7 @@ class CoreRegistry case OpenUrlEventBase::targetValuePropertyKey: case DataBindBase::propertyKeyPropertyKey: case DataBindBase::flagsPropertyKey: + case DataBindBase::converterIdPropertyKey: case BindablePropertyEnumBase::propertyValuePropertyKey: case NestedArtboardLeafBase::fitPropertyKey: case WeightBase::valuesPropertyKey: @@ -2661,6 +2673,7 @@ class CoreRegistry case KeyFrameStringBase::valuePropertyKey: case TransitionValueStringComparatorBase::valuePropertyKey: case OpenUrlEventBase::urlPropertyKey: + case DataConverterBase::namePropertyKey: case BindablePropertyStringBase::propertyValuePropertyKey: case TextValueRunBase::textPropertyKey: case CustomPropertyStringBase::propertyValuePropertyKey: @@ -3180,6 +3193,8 @@ class CoreRegistry return object->is(); case DataBindBase::flagsPropertyKey: return object->is(); + case DataBindBase::converterIdPropertyKey: + return object->is(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->is(); case NestedArtboardLeafBase::fitPropertyKey: @@ -3264,6 +3279,8 @@ class CoreRegistry return object->is(); case OpenUrlEventBase::urlPropertyKey: return object->is(); + case DataConverterBase::namePropertyKey: + return object->is(); case BindablePropertyStringBase::propertyValuePropertyKey: return object->is(); case TextValueRunBase::textPropertyKey: diff --git a/include/rive/generated/data_bind/converters/data_converter_base.hpp b/include/rive/generated/data_bind/converters/data_converter_base.hpp new file mode 100644 index 00000000..737b5679 --- /dev/null +++ b/include/rive/generated/data_bind/converters/data_converter_base.hpp @@ -0,0 +1,66 @@ +#ifndef _RIVE_DATA_CONVERTER_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_BASE_HPP_ +#include +#include "rive/core.hpp" +#include "rive/core/field_types/core_string_type.hpp" +namespace rive +{ +class DataConverterBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 488; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t namePropertyKey = 662; + +private: + std::string m_Name = ""; + +public: + inline const std::string& name() const { return m_Name; } + void name(std::string value) + { + if (m_Name == value) + { + return; + } + m_Name = value; + nameChanged(); + } + + void copy(const DataConverterBase& object) { m_Name = object.m_Name; } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case namePropertyKey: + m_Name = CoreStringType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void nameChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/data_bind_base.hpp b/include/rive/generated/data_bind/data_bind_base.hpp index b900663f..77db0216 100644 --- a/include/rive/generated/data_bind/data_bind_base.hpp +++ b/include/rive/generated/data_bind/data_bind_base.hpp @@ -29,10 +29,12 @@ class DataBindBase : public Core static const uint16_t propertyKeyPropertyKey = 586; static const uint16_t flagsPropertyKey = 587; + static const uint16_t converterIdPropertyKey = 660; private: uint32_t m_PropertyKey = Core::invalidPropertyKey; uint32_t m_Flags = 0; + uint32_t m_ConverterId = -1; public: inline uint32_t propertyKey() const { return m_PropertyKey; } @@ -57,11 +59,23 @@ class DataBindBase : public Core flagsChanged(); } + inline uint32_t converterId() const { return m_ConverterId; } + void converterId(uint32_t value) + { + if (m_ConverterId == value) + { + return; + } + m_ConverterId = value; + converterIdChanged(); + } + Core* clone() const override; void copy(const DataBindBase& object) { m_PropertyKey = object.m_PropertyKey; m_Flags = object.m_Flags; + m_ConverterId = object.m_ConverterId; } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override @@ -74,6 +88,9 @@ class DataBindBase : public Core case flagsPropertyKey: m_Flags = CoreUintType::deserialize(reader); return true; + case converterIdPropertyKey: + m_ConverterId = CoreUintType::deserialize(reader); + return true; } return false; } @@ -81,6 +98,7 @@ class DataBindBase : public Core protected: virtual void propertyKeyChanged() {} virtual void flagsChanged() {} + virtual void converterIdChanged() {} }; } // namespace rive diff --git a/include/rive/importers/backboard_importer.hpp b/include/rive/importers/backboard_importer.hpp index f2379312..c92454f7 100644 --- a/include/rive/importers/backboard_importer.hpp +++ b/include/rive/importers/backboard_importer.hpp @@ -12,6 +12,8 @@ class NestedArtboard; class Backboard; class FileAsset; class FileAssetReferencer; +class DataConverter; +class DataBind; class BackboardImporter : public ImportStackObject { private: @@ -20,6 +22,8 @@ class BackboardImporter : public ImportStackObject std::vector m_NestedArtboards; std::vector m_FileAssets; std::vector m_FileAssetReferencers; + std::vector m_DataConverters; + std::vector m_DataConverterReferencers; int m_NextArtboardId; public: @@ -29,6 +33,8 @@ class BackboardImporter : public ImportStackObject void addNestedArtboard(NestedArtboard* artboard); void addFileAsset(FileAsset* asset); void addFileAssetReferencer(FileAssetReferencer* referencer); + void addDataConverterReferencer(DataBind* referencer); + void addDataConverter(DataConverter* converter); StatusCode resolve() override; const Backboard* backboard() const { return m_Backboard; } diff --git a/src/data_bind/context/context_value.cpp b/src/data_bind/context/context_value.cpp new file mode 100644 index 00000000..5a129540 --- /dev/null +++ b/src/data_bind/context/context_value.cpp @@ -0,0 +1,122 @@ +#include "rive/data_bind/context/context_value.hpp" +#include "rive/data_bind/context/context_value_color.hpp" +#include "rive/data_bind/data_values/data_type.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" +#include "rive/data_bind/data_values/data_value_enum.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" +#include "rive/data_bind/data_values/data_value_boolean.hpp" +#include "rive/generated/core_registry.hpp" + +using namespace rive; + +DataBindContextValue::DataBindContextValue(ViewModelInstanceValue* source, + DataConverter* converter) : + m_source(source), m_converter(converter) +{ + if (m_source != nullptr) + { + switch (m_source->coreType()) + { + case ViewModelInstanceNumberBase::typeKey: + m_dataValue = + new DataValueNumber(m_source->as()->propertyValue()); + break; + case ViewModelInstanceStringBase::typeKey: + m_dataValue = + new DataValueString(m_source->as()->propertyValue()); + break; + case ViewModelInstanceColorBase::typeKey: + m_dataValue = + new DataValueColor(m_source->as()->propertyValue()); + break; + case ViewModelInstanceBooleanBase::typeKey: + m_dataValue = + new DataValueBoolean(m_source->as()->propertyValue()); + break; + case ViewModelInstanceEnumBase::typeKey: + { + auto viewmodelInstanceEnum = m_source->as(); + auto viewModelPropertyEnum = + viewmodelInstanceEnum->viewModelProperty()->as(); + m_dataValue = new DataValueEnum(viewmodelInstanceEnum->propertyValue(), + viewModelPropertyEnum->dataEnum()); + } + break; + default: + m_dataValue = new DataValue(); + } + } +} + +void DataBindContextValue::updateSourceValue() +{ + if (m_source != nullptr) + { + switch (m_source->coreType()) + { + case ViewModelInstanceNumberBase::typeKey: + m_dataValue->as()->value( + m_source->as()->propertyValue()); + break; + case ViewModelInstanceStringBase::typeKey: + m_dataValue->as()->value( + m_source->as()->propertyValue()); + break; + case ViewModelInstanceColorBase::typeKey: + m_dataValue->as()->value( + m_source->as()->propertyValue()); + break; + case ViewModelInstanceBooleanBase::typeKey: + m_dataValue->as()->value( + m_source->as()->propertyValue()); + break; + case ViewModelInstanceEnumBase::typeKey: + m_dataValue->as()->value( + m_source->as()->propertyValue()); + break; + } + } +} + +void DataBindContextValue::applyToSource(Core* component, + uint32_t propertyKey, + bool isMainDirection) +{ + auto targetValue = getTargetValue(component, propertyKey); + switch (m_source->coreType()) + { + case ViewModelInstanceNumberBase::typeKey: + { + + auto value = calculateValue(targetValue, isMainDirection); + m_source->as()->propertyValue(value); + } + break; + case ViewModelInstanceStringBase::typeKey: + { + auto value = calculateValue(targetValue, isMainDirection); + m_source->as()->propertyValue(value); + } + break; + case ViewModelInstanceColorBase::typeKey: + { + auto value = calculateValue(targetValue, isMainDirection); + m_source->as()->propertyValue(value); + } + break; + case ViewModelInstanceBooleanBase::typeKey: + { + auto value = calculateValue(targetValue, isMainDirection); + m_source->as()->propertyValue(value); + } + break; + case ViewModelInstanceEnumBase::typeKey: + { + auto value = calculateValue(targetValue, isMainDirection); + m_source->as()->propertyValue(value); + } + break; + } +} \ No newline at end of file diff --git a/src/data_bind/context/context_value_boolean.cpp b/src/data_bind/context/context_value_boolean.cpp index b7b708b0..b08b8f5a 100644 --- a/src/data_bind/context/context_value_boolean.cpp +++ b/src/data_bind/context/context_value_boolean.cpp @@ -1,27 +1,23 @@ #include "rive/data_bind/context/context_value_boolean.hpp" +#include "rive/data_bind/data_values/data_value_boolean.hpp" #include "rive/generated/core_registry.hpp" using namespace rive; -DataBindContextValueBoolean::DataBindContextValueBoolean(ViewModelInstanceValue* value) -{ - m_Source = value; - m_Value = m_Source->as()->propertyValue(); -} +DataBindContextValueBoolean::DataBindContextValueBoolean(ViewModelInstanceValue* source, + DataConverter* converter) : + DataBindContextValue(source, converter) +{} -void DataBindContextValueBoolean::apply(Core* target, uint32_t propertyKey) +void DataBindContextValueBoolean::apply(Core* target, uint32_t propertyKey, bool isMainDirection) { - CoreRegistry::setBool(target, - propertyKey, - m_Source->as()->propertyValue()); + updateSourceValue(); + auto value = calculateValue(m_dataValue, isMainDirection); + CoreRegistry::setBool(target, propertyKey, value); } -void DataBindContextValueBoolean::applyToSource(Core* target, uint32_t propertyKey) +DataValue* DataBindContextValueBoolean::getTargetValue(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getBool(target, propertyKey); - if (m_Value != value) - { - m_Value = value; - m_Source->as()->propertyValue(value); - } + return new DataValueBoolean(value); } \ No newline at end of file diff --git a/src/data_bind/context/context_value_color.cpp b/src/data_bind/context/context_value_color.cpp index 44a18575..c66171dd 100644 --- a/src/data_bind/context/context_value_color.cpp +++ b/src/data_bind/context/context_value_color.cpp @@ -1,27 +1,23 @@ #include "rive/data_bind/context/context_value_color.hpp" +#include "rive/data_bind/data_values/data_value_color.hpp" #include "rive/generated/core_registry.hpp" using namespace rive; -DataBindContextValueColor::DataBindContextValueColor(ViewModelInstanceValue* value) -{ - m_Source = value; - m_Value = m_Source->as()->propertyValue(); -} +DataBindContextValueColor::DataBindContextValueColor(ViewModelInstanceValue* source, + DataConverter* converter) : + DataBindContextValue(source, converter) +{} -void DataBindContextValueColor::apply(Core* target, uint32_t propertyKey) +void DataBindContextValueColor::apply(Core* target, uint32_t propertyKey, bool isMainDirection) { - CoreRegistry::setColor(target, - propertyKey, - m_Source->as()->propertyValue()); + updateSourceValue(); + auto value = calculateValue(m_dataValue, isMainDirection); + CoreRegistry::setColor(target, propertyKey, value); } -void DataBindContextValueColor::applyToSource(Core* target, uint32_t propertyKey) +DataValue* DataBindContextValueColor::getTargetValue(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getColor(target, propertyKey); - if (m_Value != value) - { - m_Value = value; - m_Source->as()->propertyValue(value); - } + return new DataValueColor(value); } \ No newline at end of file diff --git a/src/data_bind/context/context_value_enum.cpp b/src/data_bind/context/context_value_enum.cpp index a0064bc7..dac59203 100644 --- a/src/data_bind/context/context_value_enum.cpp +++ b/src/data_bind/context/context_value_enum.cpp @@ -1,36 +1,27 @@ #include "rive/data_bind/context/context_value_enum.hpp" +#include "rive/data_bind/data_values/data_value_enum.hpp" #include "rive/generated/core_registry.hpp" using namespace rive; -DataBindContextValueEnum::DataBindContextValueEnum(ViewModelInstanceValue* value) -{ - m_Source = value; - m_Value = m_Source->as()->propertyValue(); -} +DataBindContextValueEnum::DataBindContextValueEnum(ViewModelInstanceValue* source, + DataConverter* converter) : + DataBindContextValue(source, converter) +{} -void DataBindContextValueEnum::apply(Core* target, uint32_t propertyKey) +void DataBindContextValueEnum::apply(Core* target, uint32_t propertyKey, bool isMainDirection) { - auto enumSource = m_Source->as(); - auto enumProperty = enumSource->viewModelProperty()->as(); - auto enumValue = enumProperty->value(m_Source->as()->propertyValue()); - // TODO: @hernan decide which one makes more sense. Probably setUint, but setString was used to - // update text input with enum values. - CoreRegistry::setString(target, propertyKey, enumValue); - CoreRegistry::setUint(target, - propertyKey, - m_Source->as()->propertyValue()); + + updateSourceValue(); + auto value = calculateValue(m_dataValue, isMainDirection); + CoreRegistry::setUint(target, propertyKey, value); } -void DataBindContextValueEnum::applyToSource(Core* target, uint32_t propertyKey) +DataValue* DataBindContextValueEnum::getTargetValue(Core* target, uint32_t propertyKey) { - auto value = CoreRegistry::getString(target, propertyKey); - auto enumSource = m_Source->as(); - auto enumProperty = enumSource->viewModelProperty()->as(); - auto valueIndex = enumProperty->valueIndex(value); - if (valueIndex != -1 && m_Value != valueIndex) - { - m_Value = valueIndex; - m_Source->as()->value(static_cast(valueIndex)); - } + auto value = CoreRegistry::getUint(target, propertyKey); + auto viewmodelInstanceEnum = m_source->as(); + auto viewModelPropertyEnum = + viewmodelInstanceEnum->viewModelProperty()->as(); + return new DataValueEnum(value, viewModelPropertyEnum->dataEnum()); } \ No newline at end of file diff --git a/src/data_bind/context/context_value_list.cpp b/src/data_bind/context/context_value_list.cpp index f0aa427e..92fc2fd0 100644 --- a/src/data_bind/context/context_value_list.cpp +++ b/src/data_bind/context/context_value_list.cpp @@ -5,10 +5,10 @@ using namespace rive; -DataBindContextValueList::DataBindContextValueList(ViewModelInstanceValue* value) -{ - m_Source = value; -} +DataBindContextValueList::DataBindContextValueList(ViewModelInstanceValue* source, + DataConverter* converter) : + DataBindContextValue(source, converter) +{} std::unique_ptr DataBindContextValueList::createArtboard( Component* target, @@ -72,7 +72,7 @@ void DataBindContextValueList::update(Core* target) { if (target != nullptr) { - auto sourceList = m_Source->as(); + auto sourceList = m_source->as(); auto listItems = sourceList->listItems(); int listIndex = 0; @@ -125,9 +125,11 @@ void DataBindContextValueList::update(Core* target) } } -void DataBindContextValueList::apply(Core* target, uint32_t propertyKey) {} +void DataBindContextValueList::apply(Core* target, uint32_t propertyKey, bool isMainDirection) {} -void DataBindContextValueList::applyToSource(Core* target, uint32_t propertyKey) +void DataBindContextValueList::applyToSource(Core* target, + uint32_t propertyKey, + bool isMainDirection) { // TODO: @hernan does applyToSource make sense? Should we block it somehow? } \ No newline at end of file diff --git a/src/data_bind/context/context_value_number.cpp b/src/data_bind/context/context_value_number.cpp index 63fabf8e..4f40997d 100644 --- a/src/data_bind/context/context_value_number.cpp +++ b/src/data_bind/context/context_value_number.cpp @@ -1,27 +1,23 @@ #include "rive/data_bind/context/context_value_number.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" #include "rive/generated/core_registry.hpp" using namespace rive; -DataBindContextValueNumber::DataBindContextValueNumber(ViewModelInstanceValue* value) -{ - m_Source = value; - m_Value = m_Source->as()->propertyValue(); -} +DataBindContextValueNumber::DataBindContextValueNumber(ViewModelInstanceValue* source, + DataConverter* converter) : + DataBindContextValue(source, converter) +{} -void DataBindContextValueNumber::apply(Core* target, uint32_t propertyKey) +void DataBindContextValueNumber::apply(Core* target, uint32_t propertyKey, bool isMainDirection) { - CoreRegistry::setDouble(target, - propertyKey, - m_Source->as()->propertyValue()); + updateSourceValue(); + auto value = calculateValue(m_dataValue, isMainDirection); + CoreRegistry::setDouble(target, propertyKey, value); } -void DataBindContextValueNumber::applyToSource(Core* target, uint32_t propertyKey) +DataValue* DataBindContextValueNumber::getTargetValue(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getDouble(target, propertyKey); - if (m_Value != value) - { - m_Value = value; - m_Source->as()->propertyValue(value); - } + return new DataValueNumber(value); } \ No newline at end of file diff --git a/src/data_bind/context/context_value_string.cpp b/src/data_bind/context/context_value_string.cpp index 9cf19f7f..2c73dc89 100644 --- a/src/data_bind/context/context_value_string.cpp +++ b/src/data_bind/context/context_value_string.cpp @@ -1,27 +1,23 @@ #include "rive/data_bind/context/context_value_string.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" #include "rive/generated/core_registry.hpp" using namespace rive; -DataBindContextValueString::DataBindContextValueString(ViewModelInstanceValue* value) -{ - m_Source = value; - m_Value = m_Source->as()->propertyValue(); -} +DataBindContextValueString::DataBindContextValueString(ViewModelInstanceValue* source, + DataConverter* converter) : + DataBindContextValue(source, converter) +{} -void DataBindContextValueString::apply(Core* target, uint32_t propertyKey) +void DataBindContextValueString::apply(Core* target, uint32_t propertyKey, bool isMainDirection) { - CoreRegistry::setString(target, - propertyKey, - m_Source->as()->propertyValue()); + updateSourceValue(); + auto value = calculateValue(m_dataValue, isMainDirection); + CoreRegistry::setString(target, propertyKey, value); } -void DataBindContextValueString::applyToSource(Core* target, uint32_t propertyKey) +DataValue* DataBindContextValueString::getTargetValue(Core* target, uint32_t propertyKey) { auto value = CoreRegistry::getString(target, propertyKey); - if (m_Value != value) - { - m_Value = value; - m_Source->as()->propertyValue(value); - } + return new DataValueString(value); } \ No newline at end of file diff --git a/src/data_bind/converters/data_converter.cpp b/src/data_bind/converters/data_converter.cpp new file mode 100644 index 00000000..d9645b9a --- /dev/null +++ b/src/data_bind/converters/data_converter.cpp @@ -0,0 +1,18 @@ +#include "rive/data_bind/converters/data_converter.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/backboard_importer.hpp" +#include "rive/backboard.hpp" + +using namespace rive; + +StatusCode DataConverter::import(ImportStack& importStack) +{ + auto backboardImporter = importStack.latest(Backboard::typeKey); + if (backboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + backboardImporter->addDataConverter(this); + + return Super::import(importStack); +} \ No newline at end of file diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp index 9877f5b8..e4c52c97 100644 --- a/src/data_bind/data_bind.cpp +++ b/src/data_bind/data_bind.cpp @@ -14,10 +14,12 @@ #include "rive/data_bind/context/context_value_enum.hpp" #include "rive/data_bind/context/context_value_list.hpp" #include "rive/data_bind/context/context_value_color.hpp" +#include "rive/data_bind/data_values/data_type.hpp" #include "rive/animation/transition_viewmodel_condition.hpp" #include "rive/animation/state_machine.hpp" #include "rive/importers/artboard_importer.hpp" #include "rive/importers/state_machine_importer.hpp" +#include "rive/importers/backboard_importer.hpp" using namespace rive; @@ -34,6 +36,13 @@ StatusCode DataBind::onAddedDirty(CoreContext* context) StatusCode DataBind::import(ImportStack& importStack) { + + auto backboardImporter = importStack.latest(Backboard::typeKey); + if (backboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + backboardImporter->addDataConverterReferencer(this); if (target()) { switch (target()->coreType()) @@ -66,31 +75,61 @@ StatusCode DataBind::import(ImportStack& importStack) } } } + return Super::import(importStack); } -void DataBind::bind() +DataType DataBind::outputType() { + if (converter()) + { + return converter()->outputType(); + } switch (m_Source->coreType()) { case ViewModelInstanceNumberBase::typeKey: - m_ContextValue = rivestd::make_unique(m_Source); - break; + return DataType::number; case ViewModelInstanceStringBase::typeKey: - m_ContextValue = rivestd::make_unique(m_Source); - break; + return DataType::string; case ViewModelInstanceEnumBase::typeKey: - m_ContextValue = rivestd::make_unique(m_Source); - break; + return DataType::enumType; + case ViewModelInstanceColorBase::typeKey: + return DataType::color; + case ViewModelInstanceBooleanBase::typeKey: + return DataType::boolean; case ViewModelInstanceListBase::typeKey: - m_ContextValue = rivestd::make_unique(m_Source); - m_ContextValue->update(m_target); + return DataType::list; + } + return DataType::none; +} + +void DataBind::bind() +{ + switch (outputType()) + { + case DataType::number: + m_ContextValue = + rivestd::make_unique(m_Source, converter()); break; - case ViewModelInstanceColorBase::typeKey: - m_ContextValue = rivestd::make_unique(m_Source); + case DataType::string: + m_ContextValue = + rivestd::make_unique(m_Source, converter()); break; - case ViewModelInstanceBooleanBase::typeKey: - m_ContextValue = rivestd::make_unique(m_Source); + case DataType::boolean: + m_ContextValue = + rivestd::make_unique(m_Source, converter()); + break; + case DataType::color: + m_ContextValue = rivestd::make_unique(m_Source, converter()); + break; + case DataType::enumType: + m_ContextValue = rivestd::make_unique(m_Source, converter()); + break; + case DataType::list: + m_ContextValue = rivestd::make_unique(m_Source, converter()); + m_ContextValue->update(m_target); + break; + default: break; } } @@ -114,7 +153,10 @@ void DataBind::update(ComponentDirt value) if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToTarget) || ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) { - m_ContextValue->apply(m_target, propertyKey()); + m_ContextValue->apply(m_target, + propertyKey(), + (flagsValue & DataBindFlags::Direction) == + DataBindFlags::ToTarget); } } } @@ -128,7 +170,10 @@ void DataBind::updateSourceBinding() { if (m_ContextValue != nullptr) { - m_ContextValue->applyToSource(m_target, propertyKey()); + m_ContextValue->applyToSource(m_target, + propertyKey(), + (flagsValue & DataBindFlags::Direction) == + DataBindFlags::ToSource); } } } diff --git a/src/importers/backboard_importer.cpp b/src/importers/backboard_importer.cpp index 286f133a..845c5362 100644 --- a/src/importers/backboard_importer.cpp +++ b/src/importers/backboard_importer.cpp @@ -7,6 +7,8 @@ #include "rive/assets/file_asset.hpp" #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" +#include "rive/data_bind/converters/data_converter.hpp" +#include "rive/data_bind/data_bind.hpp" #include using namespace rive; @@ -85,6 +87,25 @@ StatusCode BackboardImporter::resolve() auto asset = m_FileAssets[index]; referencer->setAsset(asset); } + for (auto referencer : m_DataConverterReferencers) + { + auto index = (size_t)referencer->converterId(); + if (index >= m_DataConverters.size() || index < 0) + { + continue; + } + referencer->converter(m_DataConverters[index]); + } return StatusCode::Ok; +} + +void BackboardImporter::addDataConverter(DataConverter* dataConverter) +{ + m_DataConverters.push_back(dataConverter); +} + +void BackboardImporter::addDataConverterReferencer(DataBind* dataBind) +{ + m_DataConverterReferencers.push_back(dataBind); } \ No newline at end of file From 33d096eeb6f4b759903c748f8d6bf4950e49bd40 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Mon, 5 Aug 2024 22:46:28 +0000 Subject: [PATCH 115/138] Add a premake message when Xcode command line tools isn't installed Diffs= 949c70600 Add a premake message when Xcode command line tools isn't installed (#7756) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/rive_build_config.lua | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index b0804700..17eacd61 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -4bf7c75453f0fc3fec1519a9a3dfe7a4ed63a054 +949c70600a6c30bfe3ef6e59685235407af1a323 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 8396eeb2..cfac7082 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -396,7 +396,14 @@ filter({}) if os.host() == 'macosx' then iphoneos_sysroot = os.outputof('xcrun --sdk iphoneos --show-sdk-path') + if iphoneos_sysroot == nil then + error('Unable to locate iphoneos sdk. Please ensure Xcode Command Line Tools are installed.') + end + iphonesimulator_sysroot = os.outputof('xcrun --sdk iphonesimulator --show-sdk-path') + if iphonesimulator_sysroot == nil then + error('Unable to locate iphonesimulator sdk. Please ensure Xcode Command Line Tools are installed.') + end filter('system:ios') do From 076f1a22ae08ec08041ce962089a4caaabfdd539 Mon Sep 17 00:00:00 2001 From: philter Date: Tue, 6 Aug 2024 21:04:43 +0000 Subject: [PATCH 116/138] Fix layout shape hug in CPP Diffs= 35a52873c Fix layout shape hug in CPP (#7770) Co-authored-by: Philip Chung --- .rive_head | 2 +- include/rive/shapes/parametric_path.hpp | 1 + include/rive/shapes/path.hpp | 2 +- include/rive/shapes/points_path.hpp | 2 +- include/rive/shapes/shape.hpp | 4 ++ src/shapes/parametric_path.cpp | 65 +++++++++++++++---------- src/shapes/path.cpp | 2 +- src/shapes/points_path.cpp | 2 +- src/shapes/shape.cpp | 14 ++++++ 9 files changed, 63 insertions(+), 31 deletions(-) diff --git a/.rive_head b/.rive_head index 17eacd61..db3938fc 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -949c70600a6c30bfe3ef6e59685235407af1a323 +35a52873cf0adabbda2670673762a36c91822e96 diff --git a/include/rive/shapes/parametric_path.hpp b/include/rive/shapes/parametric_path.hpp index 477b9e2d..a7469fe9 100644 --- a/include/rive/shapes/parametric_path.hpp +++ b/include/rive/shapes/parametric_path.hpp @@ -12,6 +12,7 @@ class ParametricPath : public ParametricPathBase float height, LayoutMeasureMode heightMode) override; void controlSize(Vec2D size) override; + void markPathDirty(bool sendToLayout = true) override; protected: void widthChanged() override; diff --git a/include/rive/shapes/path.hpp b/include/rive/shapes/path.hpp index 59cc59b5..0984138a 100644 --- a/include/rive/shapes/path.hpp +++ b/include/rive/shapes/path.hpp @@ -58,7 +58,7 @@ class Path : public PathBase bool canDeferPathUpdate(); void addVertex(PathVertex* vertex); - virtual void markPathDirty(); + virtual void markPathDirty(bool sendToLayout = true); virtual bool isPathClosed() const { return true; } void onDirty(ComponentDirt dirt) override; inline bool isHidden() const { return (pathFlags() & 0x1) == 0x1; } diff --git a/include/rive/shapes/points_path.hpp b/include/rive/shapes/points_path.hpp index fd91881c..743bf9ca 100644 --- a/include/rive/shapes/points_path.hpp +++ b/include/rive/shapes/points_path.hpp @@ -10,7 +10,7 @@ class PointsPath : public PointsPathBase, public Skinnable bool isPathClosed() const override { return isClosed(); } void buildDependencies() override; void update(ComponentDirt value) override; - void markPathDirty() override; + void markPathDirty(bool sendToLayout = true) override; void markSkinDirty() override; const Mat2D& pathTransform() const override; }; diff --git a/include/rive/shapes/shape.hpp b/include/rive/shapes/shape.hpp index e55f7946..cfb2d26a 100644 --- a/include/rive/shapes/shape.hpp +++ b/include/rive/shapes/shape.hpp @@ -69,6 +69,10 @@ class Shape : public ShapeBase, public ShapePaintContainer AABB computeWorldBounds(const Mat2D* xform = nullptr) const; AABB computeLocalBounds() const; + Vec2D measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) override; }; } // namespace rive diff --git a/src/shapes/parametric_path.cpp b/src/shapes/parametric_path.cpp index b854cdfc..aa39cf32 100644 --- a/src/shapes/parametric_path.cpp +++ b/src/shapes/parametric_path.cpp @@ -1,5 +1,8 @@ +#include "rive/layout_component.hpp" #include "rive/math/aabb.hpp" +#include "rive/node.hpp" #include "rive/shapes/parametric_path.hpp" +#include "rive/shapes/shape.hpp" using namespace rive; @@ -8,32 +11,13 @@ Vec2D ParametricPath::measureLayout(float width, float height, LayoutMeasureMode heightMode) { - float measuredWidth, measuredHeight; - switch (widthMode) - { - case LayoutMeasureMode::atMost: - measuredWidth = std::max(ParametricPath::width(), width); - break; - case LayoutMeasureMode::exactly: - measuredWidth = width; - break; - case LayoutMeasureMode::undefined: - measuredWidth = ParametricPath::width(); - break; - } - switch (heightMode) - { - case LayoutMeasureMode::atMost: - measuredHeight = std::max(ParametricPath::height(), height); - break; - case LayoutMeasureMode::exactly: - measuredHeight = height; - break; - case LayoutMeasureMode::undefined: - measuredHeight = ParametricPath::height(); - break; - } - return Vec2D(measuredWidth, measuredHeight); + return Vec2D( + std::min( + (widthMode == LayoutMeasureMode::undefined ? std::numeric_limits::max() : width), + ParametricPath::width()), + std::min((heightMode == LayoutMeasureMode::undefined ? std::numeric_limits::max() + : height), + ParametricPath::height())); } void ParametricPath::controlSize(Vec2D size) @@ -41,6 +25,35 @@ void ParametricPath::controlSize(Vec2D size) width(size.x); height(size.y); markWorldTransformDirty(); + markPathDirty(false); +} + +void ParametricPath::markPathDirty(bool sendToLayout) +{ + Super::markPathDirty(); +#ifdef WITH_RIVE_LAYOUT + if (sendToLayout) + { + for (ContainerComponent* p = parent(); p != nullptr; p = p->parent()) + { + if (p->is()) + { + p->as()->markLayoutNodeDirty(); + break; + } + // If we're in a group we break out because objects in groups do + // not affect nor are affected by parent LayoutComponents + if (p->is()) + { + if (p->is() && p->as() == shape()) + { + continue; + } + break; + } + } + } +#endif } void ParametricPath::widthChanged() { markPathDirty(); } diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp index f5898feb..44784db5 100644 --- a/src/shapes/path.cpp +++ b/src/shapes/path.cpp @@ -228,7 +228,7 @@ void Path::buildPath(RawPath& rawPath) const } } -void Path::markPathDirty() +void Path::markPathDirty(bool sendToLayout) { addDirt(ComponentDirt::Path); if (m_Shape != nullptr) diff --git a/src/shapes/points_path.cpp b/src/shapes/points_path.cpp index a23b0ca3..57953575 100644 --- a/src/shapes/points_path.cpp +++ b/src/shapes/points_path.cpp @@ -37,7 +37,7 @@ void PointsPath::update(ComponentDirt value) Super::update(value); } -void PointsPath::markPathDirty() +void PointsPath::markPathDirty(bool sendToLayout) { if (skin() != nullptr) { diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index d69648be..68ccf590 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp @@ -302,4 +302,18 @@ AABB Shape::computeLocalBounds() const const Mat2D& world = worldTransform(); Mat2D inverseWorld = world.invertOrIdentity(); return computeWorldBounds(&inverseWorld); +} + +Vec2D Shape::measureLayout(float width, + LayoutMeasureMode widthMode, + float height, + LayoutMeasureMode heightMode) +{ + Vec2D size = Vec2D(); + for (auto path : m_Paths) + { + Vec2D measured = path->measureLayout(width, widthMode, height, heightMode); + size = Vec2D(std::max(size.x, measured.x), std::max(size.y, measured.y)); + } + return size; } \ No newline at end of file From eb1e57650883019ef7ea83bc316b7db204362aed Mon Sep 17 00:00:00 2001 From: bodymovin Date: Tue, 6 Aug 2024 23:06:28 +0000 Subject: [PATCH 117/138] refactor conditions refactor code: - adds template for comparing view models - unifies evaluate method for view model and input conditions Diffs= 1131f30e6 refactor conditions (#7747) Co-authored-by: hernan --- .rive_head | 2 +- .../rive/animation/state_machine_instance.hpp | 4 +- .../animation/transition_bool_condition.hpp | 2 +- .../rive/animation/transition_comparator.hpp | 2 +- .../rive/animation/transition_condition.hpp | 3 + .../animation/transition_input_condition.hpp | 2 - .../animation/transition_number_condition.hpp | 2 +- ...ansition_property_viewmodel_comparator.hpp | 19 ++-- .../transition_trigger_condition.hpp | 2 +- .../transition_value_boolean_comparator.hpp | 2 +- .../transition_value_color_comparator.hpp | 2 +- .../transition_value_number_comparator.hpp | 2 +- .../transition_value_string_comparator.hpp | 2 +- .../transition_viewmodel_condition.hpp | 6 +- src/animation/state_machine_instance.cpp | 3 +- src/animation/state_transition.cpp | 22 +--- src/animation/transition_bool_condition.cpp | 3 +- src/animation/transition_comparator.cpp | 2 +- src/animation/transition_condition.cpp | 3 +- src/animation/transition_number_condition.cpp | 3 +- ...ansition_property_viewmodel_comparator.cpp | 100 ++++++------------ .../transition_trigger_condition.cpp | 3 +- .../transition_value_boolean_comparator.cpp | 2 +- .../transition_value_color_comparator.cpp | 2 +- .../transition_value_number_comparator.cpp | 2 +- .../transition_value_string_comparator.cpp | 2 +- .../transition_viewmodel_condition.cpp | 2 +- 27 files changed, 82 insertions(+), 119 deletions(-) diff --git a/.rive_head b/.rive_head index db3938fc..2edbc198 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -35a52873cf0adabbda2670673762a36c91822e96 +1131f30e6a45bee5c0561de3a35b19985bf46820 diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index ce34a035..5921adf6 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -115,7 +115,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne /// Allow anything referencing a concrete StateMachineInstace access to /// the backing artboard (explicitly not allowed on Scenes). - Artboard* artboard() { return m_artboardInstance; } + Artboard* artboard() const { return m_artboardInstance; } void setParentStateMachineInstance(StateMachineInstance* instance) { @@ -136,7 +136,7 @@ class StateMachineInstance : public Scene, public NestedEventNotifier, public Ne /// Gets a reported event at an index < reportedEventCount(). const EventReport reportedEventAt(std::size_t index) const; bool playsAudio() override { return true; } - BindableProperty* bindablePropertyInstance(BindableProperty* bindableProperty); + BindableProperty* bindablePropertyInstance(BindableProperty* bindableProperty) const; DataBind* bindableDataBind(BindableProperty* bindableProperty); #ifdef TESTING size_t hitComponentsCount() { return m_hitComponents.size(); }; diff --git a/include/rive/animation/transition_bool_condition.hpp b/include/rive/animation/transition_bool_condition.hpp index 3a41a166..fa5a03e5 100644 --- a/include/rive/animation/transition_bool_condition.hpp +++ b/include/rive/animation/transition_bool_condition.hpp @@ -7,7 +7,7 @@ namespace rive class TransitionBoolCondition : public TransitionBoolConditionBase { public: - bool evaluate(const SMIInput* inputInstance) const override; + bool evaluate(const StateMachineInstance* stateMachineInstance) const override; protected: bool validateInputType(const StateMachineInput* input) const override; diff --git a/include/rive/animation/transition_comparator.hpp b/include/rive/animation/transition_comparator.hpp index 5757ad2c..38aab796 100644 --- a/include/rive/animation/transition_comparator.hpp +++ b/include/rive/animation/transition_comparator.hpp @@ -14,7 +14,7 @@ class TransitionComparator : public TransitionComparatorBase StatusCode import(ImportStack& importStack) override; virtual bool compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance); + const StateMachineInstance* stateMachineInstance); protected: bool compareNumbers(float left, float right, TransitionConditionOp op); diff --git a/include/rive/animation/transition_condition.hpp b/include/rive/animation/transition_condition.hpp index 5336f4d8..9fc8db6a 100644 --- a/include/rive/animation/transition_condition.hpp +++ b/include/rive/animation/transition_condition.hpp @@ -1,6 +1,7 @@ #ifndef _RIVE_TRANSITION_CONDITION_HPP_ #define _RIVE_TRANSITION_CONDITION_HPP_ #include "rive/generated/animation/transition_condition_base.hpp" +#include "rive/animation/state_machine_instance.hpp" namespace rive { @@ -15,6 +16,8 @@ class TransitionCondition : public TransitionConditionBase StatusCode import(ImportStack& importStack) override; + virtual bool evaluate(const StateMachineInstance* stateMachineInstance) const { return true; } + protected: virtual bool validateInputType(const StateMachineInput* input) const { return true; } }; diff --git a/include/rive/animation/transition_input_condition.hpp b/include/rive/animation/transition_input_condition.hpp index b6c65174..90ab05a7 100644 --- a/include/rive/animation/transition_input_condition.hpp +++ b/include/rive/animation/transition_input_condition.hpp @@ -7,8 +7,6 @@ namespace rive class TransitionInputCondition : public TransitionInputConditionBase { public: - virtual bool evaluate(const SMIInput* inputInstance) const { return true; } - StatusCode import(ImportStack& importStack) override; }; } // namespace rive diff --git a/include/rive/animation/transition_number_condition.hpp b/include/rive/animation/transition_number_condition.hpp index e8c88d93..d7940970 100644 --- a/include/rive/animation/transition_number_condition.hpp +++ b/include/rive/animation/transition_number_condition.hpp @@ -10,7 +10,7 @@ class TransitionNumberCondition : public TransitionNumberConditionBase bool validateInputType(const StateMachineInput* input) const override; public: - bool evaluate(const SMIInput* inputInstance) const override; + bool evaluate(const StateMachineInstance* stateMachineInstance) const override; }; } // namespace rive diff --git a/include/rive/animation/transition_property_viewmodel_comparator.hpp b/include/rive/animation/transition_property_viewmodel_comparator.hpp index 6dec8ed1..6c5bd87c 100644 --- a/include/rive/animation/transition_property_viewmodel_comparator.hpp +++ b/include/rive/animation/transition_property_viewmodel_comparator.hpp @@ -2,6 +2,7 @@ #define _RIVE_TRANSITION_PROPERTY_VIEW_MODEL_COMPARATOR_HPP_ #include "rive/generated/animation/transition_property_viewmodel_comparator_base.hpp" #include "rive/data_bind/bindable_property.hpp" +#include "rive/animation/state_machine_instance.hpp" #include namespace rive { @@ -11,12 +12,18 @@ class TransitionPropertyViewModelComparator : public TransitionPropertyViewModel StatusCode import(ImportStack& importStack) override; bool compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) override; - float propertyValueNumber(StateMachineInstance* stateMachineInstance); - std::string propertyValueString(StateMachineInstance* stateMachineInstance); - int propertyValueColor(StateMachineInstance* stateMachineInstance); - bool propertyValueBoolean(StateMachineInstance* stateMachineInstance); - uint16_t propertyValueEnum(StateMachineInstance* stateMachineInstance); + const StateMachineInstance* stateMachineInstance) override; + template + U value(const StateMachineInstance* stateMachineInstance) + { + if (m_bindableProperty->is()) + { + auto bindableInstance = + stateMachineInstance->bindablePropertyInstance(m_bindableProperty); + return bindableInstance->as()->propertyValue(); + } + return (new T())->propertyValue(); + }; protected: BindableProperty* m_bindableProperty; diff --git a/include/rive/animation/transition_trigger_condition.hpp b/include/rive/animation/transition_trigger_condition.hpp index cb535668..7ad999fd 100644 --- a/include/rive/animation/transition_trigger_condition.hpp +++ b/include/rive/animation/transition_trigger_condition.hpp @@ -7,7 +7,7 @@ namespace rive class TransitionTriggerCondition : public TransitionTriggerConditionBase { public: - bool evaluate(const SMIInput* inputInstance) const override; + bool evaluate(const StateMachineInstance* stateMachineInstance) const override; protected: bool validateInputType(const StateMachineInput* input) const override; diff --git a/include/rive/animation/transition_value_boolean_comparator.hpp b/include/rive/animation/transition_value_boolean_comparator.hpp index de5590bb..fc8b51ce 100644 --- a/include/rive/animation/transition_value_boolean_comparator.hpp +++ b/include/rive/animation/transition_value_boolean_comparator.hpp @@ -9,7 +9,7 @@ class TransitionValueBooleanComparator : public TransitionValueBooleanComparator public: bool compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) override; + const StateMachineInstance* stateMachineInstance) override; }; } // namespace rive diff --git a/include/rive/animation/transition_value_color_comparator.hpp b/include/rive/animation/transition_value_color_comparator.hpp index 6e13bb1c..c75c0627 100644 --- a/include/rive/animation/transition_value_color_comparator.hpp +++ b/include/rive/animation/transition_value_color_comparator.hpp @@ -9,7 +9,7 @@ class TransitionValueColorComparator : public TransitionValueColorComparatorBase public: bool compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) override; + const StateMachineInstance* stateMachineInstance) override; }; } // namespace rive diff --git a/include/rive/animation/transition_value_number_comparator.hpp b/include/rive/animation/transition_value_number_comparator.hpp index cd882076..daf644ce 100644 --- a/include/rive/animation/transition_value_number_comparator.hpp +++ b/include/rive/animation/transition_value_number_comparator.hpp @@ -9,7 +9,7 @@ class TransitionValueNumberComparator : public TransitionValueNumberComparatorBa public: bool compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) override; + const StateMachineInstance* stateMachineInstance) override; }; } // namespace rive diff --git a/include/rive/animation/transition_value_string_comparator.hpp b/include/rive/animation/transition_value_string_comparator.hpp index ac0136dd..c634db8f 100644 --- a/include/rive/animation/transition_value_string_comparator.hpp +++ b/include/rive/animation/transition_value_string_comparator.hpp @@ -9,7 +9,7 @@ class TransitionValueStringComparator : public TransitionValueStringComparatorBa public: bool compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) override; + const StateMachineInstance* stateMachineInstance) override; }; } // namespace rive diff --git a/include/rive/animation/transition_viewmodel_condition.hpp b/include/rive/animation/transition_viewmodel_condition.hpp index 2d5efb9e..508807d6 100644 --- a/include/rive/animation/transition_viewmodel_condition.hpp +++ b/include/rive/animation/transition_viewmodel_condition.hpp @@ -14,9 +14,9 @@ class TransitionViewModelCondition : public TransitionViewModelConditionBase TransitionComparator* m_rightComparator; public: - bool evaluateCondition(StateMachineInstance* stateMachineInstance); - TransitionComparator* leftComparator() { return m_leftComparator; }; - TransitionComparator* rightComparator() { return m_rightComparator; }; + bool evaluate(const StateMachineInstance* stateMachineInstance) const override; + TransitionComparator* leftComparator() const { return m_leftComparator; }; + TransitionComparator* rightComparator() const { return m_rightComparator; }; void comparator(TransitionComparator* value) { if (m_leftComparator == nullptr) diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index c49745fe..dcc6ff67 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -1258,7 +1258,8 @@ void StateMachineInstance::notifyEventListeners(const std::vector& } } -BindableProperty* StateMachineInstance::bindablePropertyInstance(BindableProperty* bindableProperty) +BindableProperty* StateMachineInstance::bindablePropertyInstance( + BindableProperty* bindableProperty) const { auto bindablePropertyInstance = m_bindablePropertyInstances.find(bindableProperty); if (bindablePropertyInstance == m_bindablePropertyInstances.end()) diff --git a/src/animation/state_transition.cpp b/src/animation/state_transition.cpp index 560f82ce..f419c4b5 100644 --- a/src/animation/state_transition.cpp +++ b/src/animation/state_transition.cpp @@ -150,26 +150,10 @@ AllowTransition StateTransition::allowed(StateInstance* stateFrom, for (auto condition : m_Conditions) { - if (condition->is()) + if ((ignoreTriggers && condition->is()) || + !condition->evaluate(stateMachineInstance)) { - auto inputCondition = condition->as(); - // N.B. state machine instance sanitizes these for us... - auto input = stateMachineInstance->input(inputCondition->inputId()); - - if ((ignoreTriggers && inputCondition->is()) || - !inputCondition->evaluate(input)) - { - return AllowTransition::no; - } - } - else if (condition->is()) - { - auto transitionViewModelCondition = condition->as(); - - if (!transitionViewModelCondition->evaluateCondition(stateMachineInstance)) - { - return AllowTransition::no; - } + return AllowTransition::no; } } diff --git a/src/animation/transition_bool_condition.cpp b/src/animation/transition_bool_condition.cpp index 14eb732e..f50a84e8 100644 --- a/src/animation/transition_bool_condition.cpp +++ b/src/animation/transition_bool_condition.cpp @@ -13,8 +13,9 @@ bool TransitionBoolCondition::validateInputType(const StateMachineInput* input) return input == nullptr || input->is(); } -bool TransitionBoolCondition::evaluate(const SMIInput* inputInstance) const +bool TransitionBoolCondition::evaluate(const StateMachineInstance* stateMachineInstance) const { + auto inputInstance = stateMachineInstance->input(inputId()); if (inputInstance == nullptr) { return true; diff --git a/src/animation/transition_comparator.cpp b/src/animation/transition_comparator.cpp index 73b9db9b..b14254aa 100644 --- a/src/animation/transition_comparator.cpp +++ b/src/animation/transition_comparator.cpp @@ -95,7 +95,7 @@ bool TransitionComparator::compareColors(int left, int right, TransitionConditio bool TransitionComparator::compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) + const StateMachineInstance* stateMachineInstance) { return false; } \ No newline at end of file diff --git a/src/animation/transition_condition.cpp b/src/animation/transition_condition.cpp index 6385f289..94865162 100644 --- a/src/animation/transition_condition.cpp +++ b/src/animation/transition_condition.cpp @@ -1,4 +1,4 @@ -#include "rive/animation/transition_bool_condition.hpp" +#include "rive/animation/transition_condition.hpp" #include "rive/animation/state_transition.hpp" #include "rive/importers/state_transition_importer.hpp" @@ -10,7 +10,6 @@ StatusCode TransitionCondition::onAddedClean(CoreContext* context) { return Stat StatusCode TransitionCondition::import(ImportStack& importStack) { - auto transitionImporter = importStack.latest(StateTransition::typeKey); if (transitionImporter == nullptr) { diff --git a/src/animation/transition_number_condition.cpp b/src/animation/transition_number_condition.cpp index 102d6314..da820e39 100644 --- a/src/animation/transition_number_condition.cpp +++ b/src/animation/transition_number_condition.cpp @@ -13,8 +13,9 @@ bool TransitionNumberCondition::validateInputType(const StateMachineInput* input return input == nullptr || input->is(); } -bool TransitionNumberCondition::evaluate(const SMIInput* inputInstance) const +bool TransitionNumberCondition::evaluate(const StateMachineInstance* stateMachineInstance) const { + auto inputInstance = stateMachineInstance->input(inputId()); if (inputInstance == nullptr) { return true; diff --git a/src/animation/transition_property_viewmodel_comparator.cpp b/src/animation/transition_property_viewmodel_comparator.cpp index 8d931523..80f92ecb 100644 --- a/src/animation/transition_property_viewmodel_comparator.cpp +++ b/src/animation/transition_property_viewmodel_comparator.cpp @@ -27,61 +27,26 @@ StatusCode TransitionPropertyViewModelComparator::import(ImportStack& importStac return Super::import(importStack); } -float TransitionPropertyViewModelComparator::propertyValueNumber( - StateMachineInstance* stateMachineInstance) -{ - auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); - return bindableInstance->as()->propertyValue(); -} - -std::string TransitionPropertyViewModelComparator::propertyValueString( - StateMachineInstance* stateMachineInstance) -{ - auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); - return bindableInstance->as()->propertyValue(); -} - -int TransitionPropertyViewModelComparator::propertyValueColor( - StateMachineInstance* stateMachineInstance) -{ - auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); - return bindableInstance->as()->propertyValue(); -} - -bool TransitionPropertyViewModelComparator::propertyValueBoolean( - StateMachineInstance* stateMachineInstance) -{ - auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); - return bindableInstance->as()->propertyValue(); -} - -uint16_t TransitionPropertyViewModelComparator::propertyValueEnum( - StateMachineInstance* stateMachineInstance) -{ - auto bindableInstance = stateMachineInstance->bindablePropertyInstance(m_bindableProperty); - return bindableInstance->as()->propertyValue(); -} - -bool TransitionPropertyViewModelComparator::compare(TransitionComparator* comparand, - TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) +bool TransitionPropertyViewModelComparator::compare( + TransitionComparator* comparand, + TransitionConditionOp operation, + const StateMachineInstance* stateMachineInstance) { switch (m_bindableProperty->coreType()) { case BindablePropertyNumber::typeKey: if (comparand->is()) { - auto rightValue = - comparand->as()->propertyValueNumber( - stateMachineInstance); - return compareNumbers(propertyValueNumber(stateMachineInstance), + auto rightValue = comparand->as() + ->value(stateMachineInstance); + return compareNumbers(value(stateMachineInstance), rightValue, operation); } else if (comparand->is()) { auto rightValue = comparand->as()->value(); - return compareNumbers(propertyValueNumber(stateMachineInstance), + return compareNumbers(value(stateMachineInstance), rightValue, operation); } @@ -90,34 +55,35 @@ bool TransitionPropertyViewModelComparator::compare(TransitionComparator* compar if (comparand->is()) { auto rightValue = - comparand->as()->propertyValueString( - stateMachineInstance); - return compareStrings(propertyValueString(stateMachineInstance), - rightValue, - operation); + comparand->as() + ->value(stateMachineInstance); + return compareStrings( + value(stateMachineInstance), + rightValue, + operation); } else if (comparand->is()) { auto rightValue = comparand->as()->value(); - return compareStrings(propertyValueString(stateMachineInstance), - rightValue, - operation); + return compareStrings( + value(stateMachineInstance), + rightValue, + operation); } break; case BindablePropertyColor::typeKey: if (comparand->is()) { - auto rightValue = - comparand->as()->propertyValueColor( - stateMachineInstance); - return compareColors(propertyValueColor(stateMachineInstance), + auto rightValue = comparand->as() + ->value(stateMachineInstance); + return compareColors(value(stateMachineInstance), rightValue, operation); } else if (comparand->is()) { auto rightValue = comparand->as()->value(); - return compareColors(propertyValueColor(stateMachineInstance), + return compareColors(value(stateMachineInstance), rightValue, operation); } @@ -125,17 +91,16 @@ bool TransitionPropertyViewModelComparator::compare(TransitionComparator* compar case BindablePropertyBoolean::typeKey: if (comparand->is()) { - auto rightValue = - comparand->as()->propertyValueBoolean( - stateMachineInstance); - return compareBooleans(propertyValueBoolean(stateMachineInstance), + auto rightValue = comparand->as() + ->value(stateMachineInstance); + return compareBooleans(value(stateMachineInstance), rightValue, operation); } else if (comparand->is()) { auto rightValue = comparand->as()->value(); - return compareBooleans(propertyValueBoolean(stateMachineInstance), + return compareBooleans(value(stateMachineInstance), rightValue, operation); } @@ -143,15 +108,18 @@ bool TransitionPropertyViewModelComparator::compare(TransitionComparator* compar case BindablePropertyEnum::typeKey: if (comparand->is()) { - auto rightValue = - comparand->as()->propertyValueEnum( - stateMachineInstance); - return compareEnums(propertyValueEnum(stateMachineInstance), rightValue, operation); + auto rightValue = comparand->as() + ->value(stateMachineInstance); + return compareEnums(value(stateMachineInstance), + rightValue, + operation); } else if (comparand->is()) { auto rightValue = comparand->as()->value(); - return compareEnums(propertyValueEnum(stateMachineInstance), rightValue, operation); + return compareEnums(value(stateMachineInstance), + rightValue, + operation); } break; } diff --git a/src/animation/transition_trigger_condition.cpp b/src/animation/transition_trigger_condition.cpp index 86391fe5..15be1a62 100644 --- a/src/animation/transition_trigger_condition.cpp +++ b/src/animation/transition_trigger_condition.cpp @@ -13,8 +13,9 @@ bool TransitionTriggerCondition::validateInputType(const StateMachineInput* inpu return input == nullptr || input->is(); } -bool TransitionTriggerCondition::evaluate(const SMIInput* inputInstance) const +bool TransitionTriggerCondition::evaluate(const StateMachineInstance* stateMachineInstance) const { + auto inputInstance = stateMachineInstance->input(inputId()); if (inputInstance == nullptr) { return true; diff --git a/src/animation/transition_value_boolean_comparator.cpp b/src/animation/transition_value_boolean_comparator.cpp index e26f8682..74778288 100644 --- a/src/animation/transition_value_boolean_comparator.cpp +++ b/src/animation/transition_value_boolean_comparator.cpp @@ -4,7 +4,7 @@ using namespace rive; bool TransitionValueBooleanComparator::compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) + const StateMachineInstance* stateMachineInstance) { if (comparand->is()) { diff --git a/src/animation/transition_value_color_comparator.cpp b/src/animation/transition_value_color_comparator.cpp index c4fe60e6..9e29e26f 100644 --- a/src/animation/transition_value_color_comparator.cpp +++ b/src/animation/transition_value_color_comparator.cpp @@ -4,7 +4,7 @@ using namespace rive; bool TransitionValueColorComparator::compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) + const StateMachineInstance* stateMachineInstance) { if (comparand->is()) { diff --git a/src/animation/transition_value_number_comparator.cpp b/src/animation/transition_value_number_comparator.cpp index c4f05d55..5c88856a 100644 --- a/src/animation/transition_value_number_comparator.cpp +++ b/src/animation/transition_value_number_comparator.cpp @@ -4,7 +4,7 @@ using namespace rive; bool TransitionValueNumberComparator::compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) + const StateMachineInstance* stateMachineInstance) { if (comparand->is()) { diff --git a/src/animation/transition_value_string_comparator.cpp b/src/animation/transition_value_string_comparator.cpp index d62a1a34..fe6ac06e 100644 --- a/src/animation/transition_value_string_comparator.cpp +++ b/src/animation/transition_value_string_comparator.cpp @@ -4,7 +4,7 @@ using namespace rive; bool TransitionValueStringComparator::compare(TransitionComparator* comparand, TransitionConditionOp operation, - StateMachineInstance* stateMachineInstance) + const StateMachineInstance* stateMachineInstance) { if (comparand->is()) { diff --git a/src/animation/transition_viewmodel_condition.cpp b/src/animation/transition_viewmodel_condition.cpp index 40d2a078..5c6ebbf9 100644 --- a/src/animation/transition_viewmodel_condition.cpp +++ b/src/animation/transition_viewmodel_condition.cpp @@ -8,7 +8,7 @@ using namespace rive; -bool TransitionViewModelCondition::evaluateCondition(StateMachineInstance* stateMachineInstance) +bool TransitionViewModelCondition::evaluate(const StateMachineInstance* stateMachineInstance) const { if (leftComparator() != nullptr && rightComparator() != nullptr) { From 9039350bfccee7aa15720c7e760db7026f3ab976 Mon Sep 17 00:00:00 2001 From: philter Date: Wed, 7 Aug 2024 18:39:13 +0000 Subject: [PATCH 118/138] Add width/height overrides for NestedArtboardLayout Adds the ability to override width and height for NestedArtboardLayout. This allows each NestedArtboardLayout instance to respond to be sized differently. This is not supported in the NestedArtboard Node and Leaf types, since those are resized using differently (Node uses scale and Leaf uses a combination of scale/fit/alignment). Implemented via FFI as discussed with @luigi-rosso because NestedArtboardLayout modifying the "taken" layoutNode directly could result in race conditions and other conflicts. https://github.com/user-attachments/assets/c323a94f-f392-4c10-ac01-af112f70a256 Diffs= 0dc0b435f Add width/height overrides for NestedArtboardLayout (#7736) Co-authored-by: Philip Chung --- .rive_head | 2 +- dev/defs/nested_artboard_layout.json | 68 +++++- include/rive/artboard.hpp | 1 + include/rive/generated/core_registry.hpp | 48 ++++ .../generated/nested_artboard_layout_base.hpp | 126 ++++++++++ include/rive/layout_component.hpp | 14 ++ include/rive/nested_artboard_layout.hpp | 16 ++ src/artboard.cpp | 5 +- src/layout_component.cpp | 228 ++++++++++++------ src/nested_artboard_layout.cpp | 80 +++++- 10 files changed, 500 insertions(+), 88 deletions(-) diff --git a/.rive_head b/.rive_head index 2edbc198..eb57b2c0 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -1131f30e6a45bee5c0561de3a35b19985bf46820 +0dc0b435ffb0df61de0afcdc2cea0c69bb8fedd4 diff --git a/dev/defs/nested_artboard_layout.json b/dev/defs/nested_artboard_layout.json index b0579be4..4730f94f 100644 --- a/dev/defs/nested_artboard_layout.json +++ b/dev/defs/nested_artboard_layout.json @@ -1,8 +1,66 @@ { - "name": "NestedArtboardLayout", - "key": { - "int": 452, - "string": "nestedartboardlayout" + "name": "NestedArtboardLayout", + "key": { + "int": 452, + "string": "nestedartboardlayout" + }, + "extends": "nested_artboard.json", + "properties": { + "instanceWidth": { + "type": "double", + "initialValue": "-1", + "animates": true, + "key": { + "int": 663, + "string": "instancewidth" + }, + "description": "Width value in points or percent of this nested artboard instance." }, - "extends": "nested_artboard.json" + "instanceHeight": { + "type": "double", + "initialValue": "-1", + "animates": true, + "key": { + "int": 664, + "string": "instanceheight" + }, + "description": "Height value in points or percent of this nested artboard instance" + }, + "instanceWidthUnitsValue": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 665, + "string": "instancewidthunitsvalue" + }, + "description": "Whether to display width in points or percent" + }, + "instanceHeightUnitsValue": { + "type": "uint", + "initialValue": "1", + "key": { + "int": 666, + "string": "instanceheightunitsvalue" + }, + "description": "Whether to display height in points or percent" + }, + "instanceWidthScaleType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 667, + "string": "instancewidthscaletype" + }, + "description": "Width scale type fixed | fill" + }, + "instanceHeightScaleType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 668, + "string": "instanceheightscaletype" + }, + "description": "Height scale type fixed | fill" + } + } } \ No newline at end of file diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index e3cf8027..6c9df53f 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -138,6 +138,7 @@ class Artboard : public ArtboardBase, public CoreContext void* takeLayoutNode(); bool syncStyleChanges(); + bool canHaveOverrides() override { return true; } bool advance(double elapsedSeconds, bool nested = true); bool advanceInternal(double elapsedSeconds, bool isRoot, bool nested = true); diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index d8e9eb9b..3d23e26e 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -683,6 +683,18 @@ class CoreRegistry case SoloBase::activeComponentIdPropertyKey: object->as()->activeComponentId(value); break; + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + object->as()->instanceWidthUnitsValue(value); + break; + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + object->as()->instanceHeightUnitsValue(value); + break; + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + object->as()->instanceWidthScaleType(value); + break; + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: + object->as()->instanceHeightScaleType(value); + break; case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: object->as()->layoutWidthScaleType(value); break; @@ -1219,6 +1231,12 @@ class CoreRegistry case NodeBase::yArtboardPropertyKey: object->as()->y(value); break; + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + object->as()->instanceWidth(value); + break; + case NestedArtboardLayoutBase::instanceHeightPropertyKey: + object->as()->instanceHeight(value); + break; case LayoutComponentStyleBase::gapHorizontalPropertyKey: object->as()->gapHorizontal(value); break; @@ -1798,6 +1816,14 @@ class CoreRegistry return object->as()->animationId(); case SoloBase::activeComponentIdPropertyKey: return object->as()->activeComponentId(); + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + return object->as()->instanceWidthUnitsValue(); + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + return object->as()->instanceHeightUnitsValue(); + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + return object->as()->instanceWidthScaleType(); + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: + return object->as()->instanceHeightScaleType(); case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: return object->as()->layoutWidthScaleType(); case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: @@ -2165,6 +2191,10 @@ class CoreRegistry case NodeBase::yPropertyKey: case NodeBase::yArtboardPropertyKey: return object->as()->y(); + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + return object->as()->instanceWidth(); + case NestedArtboardLayoutBase::instanceHeightPropertyKey: + return object->as()->instanceHeight(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->as()->gapHorizontal(); case LayoutComponentStyleBase::gapVerticalPropertyKey: @@ -2524,6 +2554,10 @@ class CoreRegistry case NestedArtboardBase::artboardIdPropertyKey: case NestedAnimationBase::animationIdPropertyKey: case SoloBase::activeComponentIdPropertyKey: + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: @@ -2701,6 +2735,8 @@ class CoreRegistry case NodeBase::xArtboardPropertyKey: case NodeBase::yPropertyKey: case NodeBase::yArtboardPropertyKey: + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + case NestedArtboardLayoutBase::instanceHeightPropertyKey: case LayoutComponentStyleBase::gapHorizontalPropertyKey: case LayoutComponentStyleBase::gapVerticalPropertyKey: case LayoutComponentStyleBase::maxWidthPropertyKey: @@ -2985,6 +3021,14 @@ class CoreRegistry return object->is(); case SoloBase::activeComponentIdPropertyKey: return object->is(); + case NestedArtboardLayoutBase::instanceWidthUnitsValuePropertyKey: + return object->is(); + case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: + return object->is(); + case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: + return object->is(); + case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: + return object->is(); case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: return object->is(); case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: @@ -3331,6 +3375,10 @@ class CoreRegistry case NodeBase::yPropertyKey: case NodeBase::yArtboardPropertyKey: return object->is(); + case NestedArtboardLayoutBase::instanceWidthPropertyKey: + return object->is(); + case NestedArtboardLayoutBase::instanceHeightPropertyKey: + return object->is(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->is(); case LayoutComponentStyleBase::gapVerticalPropertyKey: diff --git a/include/rive/generated/nested_artboard_layout_base.hpp b/include/rive/generated/nested_artboard_layout_base.hpp index 7c5ce6f6..8bfa18dd 100644 --- a/include/rive/generated/nested_artboard_layout_base.hpp +++ b/include/rive/generated/nested_artboard_layout_base.hpp @@ -1,5 +1,7 @@ #ifndef _RIVE_NESTED_ARTBOARD_LAYOUT_BASE_HPP_ #define _RIVE_NESTED_ARTBOARD_LAYOUT_BASE_HPP_ +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" #include "rive/nested_artboard.hpp" namespace rive { @@ -33,9 +35,133 @@ class NestedArtboardLayoutBase : public NestedArtboard uint16_t coreType() const override { return typeKey; } + static const uint16_t instanceWidthPropertyKey = 663; + static const uint16_t instanceHeightPropertyKey = 664; + static const uint16_t instanceWidthUnitsValuePropertyKey = 665; + static const uint16_t instanceHeightUnitsValuePropertyKey = 666; + static const uint16_t instanceWidthScaleTypePropertyKey = 667; + static const uint16_t instanceHeightScaleTypePropertyKey = 668; + +private: + float m_InstanceWidth = -1.0f; + float m_InstanceHeight = -1.0f; + uint32_t m_InstanceWidthUnitsValue = 1; + uint32_t m_InstanceHeightUnitsValue = 1; + uint32_t m_InstanceWidthScaleType = 0; + uint32_t m_InstanceHeightScaleType = 0; + +public: + inline float instanceWidth() const { return m_InstanceWidth; } + void instanceWidth(float value) + { + if (m_InstanceWidth == value) + { + return; + } + m_InstanceWidth = value; + instanceWidthChanged(); + } + + inline float instanceHeight() const { return m_InstanceHeight; } + void instanceHeight(float value) + { + if (m_InstanceHeight == value) + { + return; + } + m_InstanceHeight = value; + instanceHeightChanged(); + } + + inline uint32_t instanceWidthUnitsValue() const { return m_InstanceWidthUnitsValue; } + void instanceWidthUnitsValue(uint32_t value) + { + if (m_InstanceWidthUnitsValue == value) + { + return; + } + m_InstanceWidthUnitsValue = value; + instanceWidthUnitsValueChanged(); + } + + inline uint32_t instanceHeightUnitsValue() const { return m_InstanceHeightUnitsValue; } + void instanceHeightUnitsValue(uint32_t value) + { + if (m_InstanceHeightUnitsValue == value) + { + return; + } + m_InstanceHeightUnitsValue = value; + instanceHeightUnitsValueChanged(); + } + + inline uint32_t instanceWidthScaleType() const { return m_InstanceWidthScaleType; } + void instanceWidthScaleType(uint32_t value) + { + if (m_InstanceWidthScaleType == value) + { + return; + } + m_InstanceWidthScaleType = value; + instanceWidthScaleTypeChanged(); + } + + inline uint32_t instanceHeightScaleType() const { return m_InstanceHeightScaleType; } + void instanceHeightScaleType(uint32_t value) + { + if (m_InstanceHeightScaleType == value) + { + return; + } + m_InstanceHeightScaleType = value; + instanceHeightScaleTypeChanged(); + } + Core* clone() const override; + void copy(const NestedArtboardLayoutBase& object) + { + m_InstanceWidth = object.m_InstanceWidth; + m_InstanceHeight = object.m_InstanceHeight; + m_InstanceWidthUnitsValue = object.m_InstanceWidthUnitsValue; + m_InstanceHeightUnitsValue = object.m_InstanceHeightUnitsValue; + m_InstanceWidthScaleType = object.m_InstanceWidthScaleType; + m_InstanceHeightScaleType = object.m_InstanceHeightScaleType; + NestedArtboard::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case instanceWidthPropertyKey: + m_InstanceWidth = CoreDoubleType::deserialize(reader); + return true; + case instanceHeightPropertyKey: + m_InstanceHeight = CoreDoubleType::deserialize(reader); + return true; + case instanceWidthUnitsValuePropertyKey: + m_InstanceWidthUnitsValue = CoreUintType::deserialize(reader); + return true; + case instanceHeightUnitsValuePropertyKey: + m_InstanceHeightUnitsValue = CoreUintType::deserialize(reader); + return true; + case instanceWidthScaleTypePropertyKey: + m_InstanceWidthScaleType = CoreUintType::deserialize(reader); + return true; + case instanceHeightScaleTypePropertyKey: + m_InstanceHeightScaleType = CoreUintType::deserialize(reader); + return true; + } + return NestedArtboard::deserialize(propertyKey, reader); + } protected: + virtual void instanceWidthChanged() {} + virtual void instanceHeightChanged() {} + virtual void instanceWidthUnitsValueChanged() {} + virtual void instanceHeightUnitsValueChanged() {} + virtual void instanceWidthScaleTypeChanged() {} + virtual void instanceHeightScaleTypeChanged() {} }; } // namespace rive diff --git a/include/rive/layout_component.hpp b/include/rive/layout_component.hpp index b39a9c3e..18d8999e 100644 --- a/include/rive/layout_component.hpp +++ b/include/rive/layout_component.hpp @@ -71,6 +71,12 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public } private: + float m_widthOverride = NAN; + int m_widthUnitValueOverride = -1; + float m_heightOverride = NAN; + int m_heightUnitValueOverride = -1; + bool m_parentIsRow = true; + #ifdef WITH_RIVE_LAYOUT protected: YGNode& layoutNode() { return m_layoutData->node; } @@ -106,6 +112,14 @@ class LayoutComponent : public LayoutComponentBase, public ProxyDrawing, public return AABB::fromLTWH(0.0f, 0.0f, m_layoutSizeWidth, m_layoutSizeHeight); } + // We provide a way for nested artboards (or other objects) to override this layout's + // width/height and unit values. + void widthOverride(float width, int unitValue = 1, bool isRow = true); + void heightOverride(float height, int unitValue = 1, bool isRow = true); + virtual bool canHaveOverrides() { return false; } + bool mainAxisIsRow(); + bool mainAxisIsColumn(); + #ifdef WITH_RIVE_LAYOUT LayoutComponent() : m_layoutData(std::unique_ptr(new LayoutData())), m_proxy(this) { diff --git a/include/rive/nested_artboard_layout.hpp b/include/rive/nested_artboard_layout.hpp index 9a680747..f6876ea3 100644 --- a/include/rive/nested_artboard_layout.hpp +++ b/include/rive/nested_artboard_layout.hpp @@ -13,6 +13,22 @@ class NestedArtboardLayout : public NestedArtboardLayoutBase Core* clone() const override; void markNestedLayoutDirty(); void update(ComponentDirt value) override; + StatusCode onAddedClean(CoreContext* context) override; + + float actualInstanceWidth(); + float actualInstanceHeight(); + +protected: + void instanceWidthChanged() override; + void instanceHeightChanged() override; + void instanceWidthUnitsValueChanged() override; + void instanceHeightUnitsValueChanged() override; + void instanceWidthScaleTypeChanged() override; + void instanceHeightScaleTypeChanged() override; + +private: + void updateWidthOverride(); + void updateHeightOverride(); }; } // namespace rive diff --git a/src/artboard.cpp b/src/artboard.cpp index 263f683f..67a5a1b7 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -689,7 +689,10 @@ void Artboard::markLayoutDirty(LayoutComponent* layoutComponent) m_dirtyLayout.insert(layoutComponent); if (sharesLayoutWithHost()) { - m_host->as()->markNestedLayoutDirty(); + // TODO: Follow up with Luigi + // This only gets called when the NestedArtboardLayout is in the runtime + // but seems to cause an infinite loop in certain cases + // m_host->as()->markNestedLayoutDirty(); } } diff --git a/src/layout_component.cpp b/src/layout_component.cpp index 3bd963df..c72a6140 100644 --- a/src/layout_component.cpp +++ b/src/layout_component.cpp @@ -131,6 +131,22 @@ void LayoutComponent::update(ComponentDirt value) } } +void LayoutComponent::widthOverride(float width, int unitValue, bool isRow) +{ + m_widthOverride = width; + m_widthUnitValueOverride = unitValue; + m_parentIsRow = isRow; + markLayoutNodeDirty(); +} + +void LayoutComponent::heightOverride(float height, int unitValue, bool isRow) +{ + m_heightOverride = height; + m_heightUnitValueOverride = unitValue; + m_parentIsRow = isRow; + markLayoutNodeDirty(); +} + #ifdef WITH_RIVE_LAYOUT StatusCode LayoutComponent::onAddedDirty(CoreContext* context) { @@ -207,6 +223,18 @@ Vec2D LayoutComponent::measureLayout(float width, return size; } +bool LayoutComponent::mainAxisIsRow() +{ + return style()->flexDirection() == YGFlexDirectionRow || + style()->flexDirection() == YGFlexDirectionRowReverse; +} + +bool LayoutComponent::mainAxisIsColumn() +{ + return style()->flexDirection() == YGFlexDirectionColumn || + style()->flexDirection() == YGFlexDirectionColumnReverse; +} + void LayoutComponent::syncStyle() { if (m_style == nullptr) @@ -224,94 +252,131 @@ void LayoutComponent::syncStyle() { ygNode.setMeasureFunc(nullptr); } - if (m_style->widthUnits() != YGUnitAuto) - { - ygStyle.dimensions()[YGDimensionWidth] = YGValue{width(), m_style->widthUnits()}; - } - else - { - ygStyle.dimensions()[YGDimensionWidth] = YGValueAuto; - } - if (m_style->heightUnits() != YGUnitAuto) - { - ygStyle.dimensions()[YGDimensionHeight] = YGValue{height(), m_style->heightUnits()}; - } - else - { - ygStyle.dimensions()[YGDimensionHeight] = YGValueAuto; - } - if (layoutParent() != nullptr) + auto realWidth = width(); + auto realWidthUnits = m_style->widthUnits(); + auto realWidthScaleType = m_style->widthScaleType(); + auto realHeight = height(); + auto realHeightUnits = m_style->heightUnits(); + auto realHeightScaleType = m_style->heightScaleType(); + auto parentIsRow = layoutParent() != nullptr ? layoutParent()->mainAxisIsRow() : true; + + // If we have override width/height values, use those. + // Currently we only use these for Artboards that are part of a NestedArtboardLayout + // but perhaps there will be other use cases for overriding in the future? + if (canHaveOverrides()) { - bool isRow = layoutParent()->style()->flexDirection() == YGFlexDirectionRow || - layoutParent()->style()->flexDirection() == YGFlexDirectionRowReverse; - switch (m_style->widthScaleType()) + if (!std::isnan(m_widthOverride)) { - case LayoutScaleType::fixed: - if (isRow) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - break; - case LayoutScaleType::fill: - if (isRow) - { - ygStyle.flexGrow() = YGFloatOptional(1); - } - else - { - ygStyle.alignSelf() = YGAlignStretch; - } - break; - case LayoutScaleType::hug: - if (isRow) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - else - { - ygStyle.alignSelf() = YGAlignAuto; - } - break; - default: - break; + realWidth = m_widthOverride; } - bool isColumn = !isRow; - switch (m_style->heightScaleType()) + if (!std::isnan(m_heightOverride)) { - case LayoutScaleType::fixed: - if (isColumn) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - break; - case LayoutScaleType::fill: - if (isColumn) - { - ygStyle.flexGrow() = YGFloatOptional(1); - } - else - { - ygStyle.alignSelf() = YGAlignStretch; - } - break; - case LayoutScaleType::hug: - if (isColumn) - { - ygStyle.flexGrow() = YGFloatOptional(0); - } - else - { - ygStyle.alignSelf() = YGAlignAuto; - } - break; - default: - break; + realHeight = m_heightOverride; + } + parentIsRow = m_parentIsRow; + + if (m_widthUnitValueOverride != -1) + { + realWidthUnits = YGUnit(m_widthUnitValueOverride); + switch (realWidthUnits) + { + case YGUnitPoint: + case YGUnitPercent: + realWidthScaleType = LayoutScaleType::fixed; + break; + case YGUnitAuto: + realWidthScaleType = LayoutScaleType::fill; + break; + default: + break; + } + } + if (m_heightUnitValueOverride != -1) + { + realHeightUnits = YGUnit(m_heightUnitValueOverride); + switch (realHeightUnits) + { + case YGUnitPoint: + case YGUnitPercent: + realHeightScaleType = LayoutScaleType::fixed; + break; + case YGUnitAuto: + realHeightScaleType = LayoutScaleType::fill; + break; + default: + break; + } } } + ygStyle.dimensions()[YGDimensionWidth] = YGValue{realWidth, realWidthUnits}; + ygStyle.dimensions()[YGDimensionHeight] = YGValue{realHeight, realHeightUnits}; - bool isRowForAlignment = m_style->flexDirection() == YGFlexDirectionRow || - m_style->flexDirection() == YGFlexDirectionRowReverse; + switch (realWidthScaleType) + { + case LayoutScaleType::fixed: + if (parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + break; + case LayoutScaleType::fill: + if (parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(1); + } + else + { + ygStyle.alignSelf() = YGAlignStretch; + } + break; + case LayoutScaleType::hug: + if (parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + else + { + ygStyle.alignSelf() = YGAlignAuto; + } + break; + default: + break; + } + + switch (realHeightScaleType) + { + case LayoutScaleType::fixed: + if (!parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + break; + case LayoutScaleType::fill: + if (!parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(1); + } + else + { + ygStyle.alignSelf() = YGAlignStretch; + } + break; + case LayoutScaleType::hug: + if (!parentIsRow) + { + ygStyle.flexGrow() = YGFloatOptional(0); + } + else + { + ygStyle.alignSelf() = YGAlignAuto; + } + break; + default: + break; + } + + bool isRowForAlignment = mainAxisIsRow(); switch (m_style->alignmentType()) { case LayoutAlignmentType::topLeft: @@ -801,6 +866,9 @@ Vec2D LayoutComponent::measureLayout(float width, void LayoutComponent::markLayoutNodeDirty() {} void LayoutComponent::markLayoutStyleDirty() {} void LayoutComponent::onDirty(ComponentDirt value) {} +bool LayoutComponent::mainAxisIsRow() { return true; } + +bool LayoutComponent::mainAxisIsColumn() { return false; } #endif void LayoutComponent::clipChanged() { markLayoutNodeDirty(); } diff --git a/src/nested_artboard_layout.cpp b/src/nested_artboard_layout.cpp index eed115e4..501ffd67 100644 --- a/src/nested_artboard_layout.cpp +++ b/src/nested_artboard_layout.cpp @@ -16,6 +16,16 @@ Core* NestedArtboardLayout::clone() const return nestedArtboard; } +float NestedArtboardLayout::actualInstanceWidth() +{ + return instanceWidth() == -1.0f ? artboardInstance()->originalWidth() : instanceWidth(); +} + +float NestedArtboardLayout::actualInstanceHeight() +{ + return instanceHeight() == -1.0f ? artboardInstance()->originalHeight() : instanceHeight(); +} + #ifdef WITH_RIVE_LAYOUT void* NestedArtboardLayout::layoutNode() { @@ -57,4 +67,72 @@ void NestedArtboardLayout::update(ComponentDirt value) auto back = Mat2D::fromTranslation(-artboard->origin()); m_WorldTransform = back * m_WorldTransform; } -} \ No newline at end of file +} + +StatusCode NestedArtboardLayout::onAddedClean(CoreContext* context) +{ + StatusCode code = Super::onAddedClean(context); + if (code != StatusCode::Ok) + { + return code; + } + + updateWidthOverride(); + updateHeightOverride(); + + return StatusCode::Ok; +} + +void NestedArtboardLayout::updateWidthOverride() +{ + if (artboardInstance() == nullptr) + { + return; + } + auto isRow = + parent()->is() ? parent()->as()->mainAxisIsRow() : true; + if (instanceWidthScaleType() == 0) // LayoutScaleType::fixed + { + // If we're set to fixed, pass the unit value (points|percent) + artboardInstance()->widthOverride(actualInstanceWidth(), instanceWidthUnitsValue(), isRow); + } + else if (instanceWidthScaleType() == 1) // LayoutScaleType::fill + { + // If we're set to fill, pass auto + artboardInstance()->widthOverride(actualInstanceWidth(), 3, isRow); + } +} + +void NestedArtboardLayout::updateHeightOverride() +{ + if (artboardInstance() == nullptr) + { + return; + } + auto isRow = + parent()->is() ? parent()->as()->mainAxisIsRow() : true; + if (instanceHeightScaleType() == 0) // LayoutScaleType::fixed + { + // If we're set to fixed, pass the unit value (points|percent) + artboardInstance()->heightOverride(actualInstanceHeight(), + instanceHeightUnitsValue(), + isRow); + } + else if (instanceHeightScaleType() == 1) // LayoutScaleType::fill + { + // If we're set to fill, pass auto + artboardInstance()->heightOverride(actualInstanceHeight(), 3, isRow); + } +} + +void NestedArtboardLayout::instanceWidthChanged() { updateWidthOverride(); } + +void NestedArtboardLayout::instanceHeightChanged() { updateHeightOverride(); } + +void NestedArtboardLayout::instanceWidthUnitsValueChanged() { updateWidthOverride(); } + +void NestedArtboardLayout::instanceHeightUnitsValueChanged() { updateHeightOverride(); } + +void NestedArtboardLayout::instanceWidthScaleTypeChanged() { updateWidthOverride(); } + +void NestedArtboardLayout::instanceHeightScaleTypeChanged() { updateHeightOverride(); } \ No newline at end of file From a0283f94891a638d9a979f1ecc7431bdf625f4d9 Mon Sep 17 00:00:00 2001 From: rivessamr Date: Thu, 8 Aug 2024 00:39:26 +0000 Subject: [PATCH 119/138] Added support for xcode builds Diffs= c12b0bb24 Added support for xcode builds (#7774) Co-authored-by: rivessamr --- .rive_head | 2 +- dependencies/premake5_libpng_v2.lua | 5 +++-- dependencies/premake5_sheenbidi_v2.lua | 11 ++++++++++- dependencies/premake5_yoga_v2.lua | 8 ++++++++ include/rive/animation/animation_reset.hpp | 4 ++-- include/rive/math/math_types.hpp | 8 ++++++++ premake5_v2.lua | 8 ++++++++ 7 files changed, 40 insertions(+), 6 deletions(-) diff --git a/.rive_head b/.rive_head index eb57b2c0..b7f15159 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -0dc0b435ffb0df61de0afcdc2cea0c69bb8fedd4 +c12b0bb24d1abff5b8df6f9b3a4053fbc5096668 diff --git a/dependencies/premake5_libpng_v2.lua b/dependencies/premake5_libpng_v2.lua index ea26a9e9..75e0c8c7 100644 --- a/dependencies/premake5_libpng_v2.lua +++ b/dependencies/premake5_libpng_v2.lua @@ -12,7 +12,7 @@ do kind('StaticLib') os.copyfile(libpng .. '/scripts/pnglibconf.h.prebuilt', libpng .. '/pnglibconf.h') includedirs({ libpng, zlib }) - optimize("Speed") -- Always optimize image encoding/decoding, even in debug builds. + optimize('Speed') -- Always optimize image encoding/decoding, even in debug builds. files({ libpng .. '/png.c', libpng .. '/pngerror.c', @@ -45,7 +45,7 @@ do kind('StaticLib') defines({ 'ZLIB_IMPLEMENTATION' }) includedirs({ zlib }) - optimize("Speed") -- Always optimize image encoding/decoding, even in debug builds. + optimize('Speed') -- Always optimize image encoding/decoding, even in debug builds. files({ zlib .. '/adler32.c', zlib .. '/compress.c', @@ -70,6 +70,7 @@ do buildoptions({ '-Wno-unknown-warning-option', '-Wno-deprecated-non-prototype', + '-Wno-shorten-64-to-32', }) end diff --git a/dependencies/premake5_sheenbidi_v2.lua b/dependencies/premake5_sheenbidi_v2.lua index 891c963e..147f983d 100644 --- a/dependencies/premake5_sheenbidi_v2.lua +++ b/dependencies/premake5_sheenbidi_v2.lua @@ -2,6 +2,7 @@ dofile('rive_build_config.lua') local dependency = require('dependency') sheenbidi = dependency.github('Tehreer/SheenBidi', 'v2.6') +Headers = sheenbidi .. '/Headers' project('rive_sheenbidi') do @@ -9,7 +10,15 @@ do language('C') warnings('Off') - includedirs({ sheenbidi .. '/Headers' }) + includedirs({ Headers }) + + filter('action:xcode4') + do + -- xcode doesnt like angle brackets except for -isystem + -- should use externalincludedirs but GitHub runners dont have latest premake5 binaries + buildoptions({ '-isystem' .. Headers }) + end + filter({}) buildoptions({ '-Wall', '-ansi', '-pedantic' }) diff --git a/dependencies/premake5_yoga_v2.lua b/dependencies/premake5_yoga_v2.lua index 30d8284f..68de64ae 100644 --- a/dependencies/premake5_yoga_v2.lua +++ b/dependencies/premake5_yoga_v2.lua @@ -17,6 +17,14 @@ do includedirs({ yoga }) + filter('action:xcode4') + do + -- xcode doesnt like angle brackets except for -isystem + -- should use externalincludedirs but GitHub runners dont have latest premake5 binaries + buildoptions({ '-isystem' .. yoga }) + end + filter({}) + files({ yoga .. '/yoga/Utils.cpp', yoga .. '/yoga/YGConfig.cpp', diff --git a/include/rive/animation/animation_reset.hpp b/include/rive/animation/animation_reset.hpp index b501a834..2828da32 100644 --- a/include/rive/animation/animation_reset.hpp +++ b/include/rive/animation/animation_reset.hpp @@ -3,7 +3,7 @@ #include #include "rive/artboard.hpp" -#include +#include "rive/animation/animation_reset.hpp" #include "rive/core/binary_writer.hpp" #include "rive/core/vector_binary_writer.hpp" #include "rive/core/binary_data_reader.hpp" @@ -29,4 +29,4 @@ class AnimationReset void clear(); }; } // namespace rive -#endif \ No newline at end of file +#endif diff --git a/include/rive/math/math_types.hpp b/include/rive/math/math_types.hpp index 17dfaeab..b706afd1 100644 --- a/include/rive/math/math_types.hpp +++ b/include/rive/math/math_types.hpp @@ -61,6 +61,14 @@ template Dst bit_cast(const Src& src) return dst; } +// Lossless cast function that asserts on overflow +template T lossless_numeric_cast(U u) +{ + T t = static_cast(u); + assert(static_cast(t) == u); + return t; +} + // Attempt to generate a "clz" assembly instruction. RIVE_ALWAYS_INLINE static int clz32(uint32_t x) { diff --git a/premake5_v2.lua b/premake5_v2.lua index 5abc30ed..35acb878 100644 --- a/premake5_v2.lua +++ b/premake5_v2.lua @@ -46,6 +46,14 @@ do yoga, }) + filter('action:xcode4') + do + -- xcode doesnt like angle brackets except for -isystem + -- should use externalincludedirs but GitHub runners dont have latest premake5 binaries + buildoptions({ '-isystem' .. yoga }) + end + filter({}) + defines({ 'YOGA_EXPORT=' }) files({ 'src/**.cpp' }) From 725788de33f42f4d471fc4656ab764e6648f6dae Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Thu, 8 Aug 2024 16:24:27 +0000 Subject: [PATCH 120/138] Add Xcode support to build_rive.sh Add an "xcode" option that generates and builds an xcode workspace. Add -Wshorten-64-to-32 to non-Xcode builds and fix more warnings. Diffs= f0da6a7a0 Add Xcode support to build_rive.sh (#7780) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/build_rive.sh | 23 +++++++++++++++++++---- include/rive/math/math_types.hpp | 4 ++-- skia/renderer/include/to_skia.hpp | 3 ++- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/.rive_head b/.rive_head index b7f15159..5ee07534 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -c12b0bb24d1abff5b8df6f9b3a4053fbc5096668 +f0da6a7a097a782df5839390097254bbfb8d9a00 diff --git a/build/build_rive.sh b/build/build_rive.sh index 48ad9503..9bef073c 100755 --- a/build/build_rive.sh +++ b/build/build_rive.sh @@ -13,6 +13,7 @@ # build_rive.sh # debug build # build_rive.sh release # release build # build_rive.sh release clean # clean, followed by a release build +# build_rive.sh xcode # generate and build an xcode workspace # build_rive.sh ninja # use ninja (experimental) for a debug build # build_rive.sh ninja release # use ninja (experimental) for a release build # build_rive.sh ninja --with_vulkan # extra parameters get forwarded to premake @@ -140,6 +141,7 @@ else "universal") RIVE_ARCH="${RIVE_ARCH:-universal}" ;; "wasm") RIVE_ARCH="${RIVE_ARCH:-wasm}" ;; "ninja") RIVE_BUILD_SYSTEM="${RIVE_BUILD_SYSTEM:-ninja}" ;; + "xcode") RIVE_BUILD_SYSTEM="${RIVE_BUILD_SYSTEM:-xcode4}" ;; "clean") RIVE_CLEAN="${RIVE_CLEAN:-true}" ;; "compdb") RIVE_BUILD_SYSTEM="${RIVE_BUILD_SYSTEM:-export-compile-commands}" @@ -267,15 +269,28 @@ case "$RIVE_BUILD_SYSTEM" in echo ninja -C $RIVE_OUT $@ ninja -C $RIVE_OUT $@ ;; + xcode4) + if [[ $# = 0 ]]; then + echo 'No targets specified for xcode: Attempting to grok them from "xcodebuild -list".' + XCODE_SCHEMES=$(for f in $(xcodebuild -list -workspace $RIVE_OUT/rive.xcworkspace | grep '^ '); do printf " $f"; done) + echo " -> groked:$XCODE_SCHEMES" + else + XCODE_SCHEMES="$@" + fi + for SCHEME in $XCODE_SCHEMES; do + echo xcodebuild -workspace $RIVE_OUT/rive.xcworkspace -scheme $SCHEME + xcodebuild -workspace $RIVE_OUT/rive.xcworkspace -scheme $SCHEME + done + ;; vs2022) for TARGET in $@; do - RIVE_MSVC_TARGETS="$RIVE_MSVC_TARGETS -t:$TARGET" + MSVC_TARGETS="$MSVC_TARGETS -t:$TARGET" done - echo msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $RIVE_MSVC_TARGETS - msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $RIVE_MSVC_TARGETS + echo msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $MSVC_TARGETS + msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $MSVC_TARGETS ;; *) - print "Unsupported buildsystem $RIVE_BUILD_SYSTEM" + echo "Unsupported buildsystem $RIVE_BUILD_SYSTEM" exit -1 ;; esac diff --git a/include/rive/math/math_types.hpp b/include/rive/math/math_types.hpp index b706afd1..b34adc35 100644 --- a/include/rive/math/math_types.hpp +++ b/include/rive/math/math_types.hpp @@ -114,11 +114,11 @@ RIVE_ALWAYS_INLINE static uint32_t rotateleft32(uint32_t x, int y) // Returns x rounded up to the next multiple of N. // If x is already a multiple of N, returns x. -template RIVE_ALWAYS_INLINE constexpr size_t round_up_to_multiple_of(size_t x) +template RIVE_ALWAYS_INLINE constexpr T round_up_to_multiple_of(T x) { static_assert(N != 0 && (N & (N - 1)) == 0, "math::round_up_to_multiple_of<> only supports powers of 2."); - return (x + (N - 1)) & ~(N - 1); + return (x + (N - 1)) & ~static_cast(N - 1); } // Behaves better with NaN than std::clamp(). (Matching simd::clamp().) diff --git a/skia/renderer/include/to_skia.hpp b/skia/renderer/include/to_skia.hpp index cc49d249..0cf8920d 100644 --- a/skia/renderer/include/to_skia.hpp +++ b/skia/renderer/include/to_skia.hpp @@ -12,6 +12,7 @@ #include "include/core/SkPathTypes.h" #include "include/core/SkTileMode.h" +#include "rive/math/math_types.hpp" #include "rive/math/mat2d.hpp" #include "rive/math/raw_path.hpp" #include "rive/math/vec2d.hpp" @@ -89,7 +90,7 @@ class ToSkia const auto pts = rp.points(); const auto vbs = rp.verbsU8(); return SkPath::Make((const SkPoint*)pts.data(), pts.size(), - vbs.data(), vbs.size(), + vbs.data(), math::lossless_numeric_cast(vbs.size()), nullptr, 0, SkPathFillType::kWinding); } // clang-format off From 5b70b81cd25b20a6b929a717ad178e6882960bf8 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Thu, 8 Aug 2024 18:38:26 +0000 Subject: [PATCH 121/138] Better premake support for Visual Studio * Add a "windows_runtime=dynamic_release" option for Unreal * Enable parallel building Diffs= 66d9f1725 Better premake support for Visual Studio (#7779) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/build_rive.sh | 4 ++-- build/rive_build_config.lua | 12 ++++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.rive_head b/.rive_head index 5ee07534..2f45f73f 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f0da6a7a097a782df5839390097254bbfb8d9a00 +66d9f1725eca90876a29f029de002b2a4f919a19 diff --git a/build/build_rive.sh b/build/build_rive.sh index 9bef073c..b3c4f87c 100755 --- a/build/build_rive.sh +++ b/build/build_rive.sh @@ -286,8 +286,8 @@ case "$RIVE_BUILD_SYSTEM" in for TARGET in $@; do MSVC_TARGETS="$MSVC_TARGETS -t:$TARGET" done - echo msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $MSVC_TARGETS - msbuild.exe "./$RIVE_OUT/rive.sln" -p:UseMultiToolTask=true -m:$NUM_CORES $MSVC_TARGETS + echo msbuild.exe "./$RIVE_OUT/rive.sln" $MSVC_TARGETS + msbuild.exe "./$RIVE_OUT/rive.sln" $MSVC_TARGETS ;; *) echo "Unsupported buildsystem $RIVE_BUILD_SYSTEM" diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index cfac7082..55ebd5c7 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -158,6 +158,7 @@ newoption({ { 'static', 'Use static runtime' }, { 'dynamic', 'Use dynamic runtime' }, { 'dynamic_debug', 'Use dynamic runtime force debug' }, + { 'dynamic_release', 'Use dynamic runtime force release' }, }, default = 'default', }) @@ -196,6 +197,12 @@ do runtime('Debug') end +filter({ 'system:windows', 'options:windows_runtime=dynamic_release' }) +do + staticruntime('off') + runtime('Release') +end + filter('system:windows') do architecture('x64') @@ -285,6 +292,11 @@ do }) end +filter({ 'action:vs2022' }) +do + flags({ 'MultiProcessorCompile' }) +end + filter({}) -- Don't use filter() here because we don't want to generate the "android_ndk" toolset if not From b58380143f432a9c220ba325932dc76f9291b6fc Mon Sep 17 00:00:00 2001 From: blakdragan7 Date: Fri, 9 Aug 2024 04:39:22 +0000 Subject: [PATCH 122/138] added a blt command for render targets that do not support VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT Currently, render targets that do not have the VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT flag will not work and just cause a crash. This adds an offscreen texture that can be used as an input attachment in its place and then a copy command to update the render target at the end. Diffs= 8c7ac0329 added a blt command for render targets that do not support VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT (#7757) Co-authored-by: Jonathon Copeland --- .rive_head | 2 +- build/build_rive.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index 2f45f73f..16f26cbd 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -66d9f1725eca90876a29f029de002b2a4f919a19 +8c7ac03294339ae2ad856b541c730dc16cec018d diff --git a/build/build_rive.sh b/build/build_rive.sh index b3c4f87c..cb1a3054 100755 --- a/build/build_rive.sh +++ b/build/build_rive.sh @@ -77,7 +77,7 @@ case "$(uname -s)" in fi NUM_CORES=$(($(sysctl -n hw.physicalcpu) + 1)) ;; - MINGW*) + MINGW*|MSYS*) HOST_MACHINE="windows" NUM_CORES=$NUMBER_OF_PROCESSORS # Try to find MSBuild.exe From 9e26b7620e0f0c8494818f74df4fe31ba264be3b Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 9 Aug 2024 22:23:15 +0000 Subject: [PATCH 123/138] add two data converters this PR adds the UI to create converters in the editor, and includes the first two: - a rounder that accepts a property for rounding - a toString converter that can convert for now numbers and enum. It could be extended to colors and booleans in the future. https://github.com/user-attachments/assets/2946d8ea-0fdf-4039-83d4-79b5fdfc6169 https://github.com/user-attachments/assets/ec60b523-ecb2-4453-9280-c99822706b2e Diffs= 2c0927fc5 add two data converters (#7742) Co-authored-by: hernan --- .rive_head | 2 +- .../converters/data_converter_rounder.json | 20 ++++++ .../converters/data_converter_to_string.json | 8 +++ dev/defs/node.json | 6 +- .../converters/data_converter_rounder.hpp | 16 +++++ .../converters/data_converter_to_string.hpp | 15 ++++ include/rive/generated/core_registry.hpp | 14 ++++ .../data_converter_rounder_base.hpp | 71 +++++++++++++++++++ .../data_converter_to_string_base.hpp | 36 ++++++++++ .../converters/data_converter_rounder.cpp | 19 +++++ .../converters/data_converter_to_string.cpp | 36 ++++++++++ .../data_converter_rounder_base.cpp | 11 +++ .../data_converter_to_string_base.cpp | 11 +++ 13 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 dev/defs/data_bind/converters/data_converter_rounder.json create mode 100644 dev/defs/data_bind/converters/data_converter_to_string.json create mode 100644 include/rive/data_bind/converters/data_converter_rounder.hpp create mode 100644 include/rive/data_bind/converters/data_converter_to_string.hpp create mode 100644 include/rive/generated/data_bind/converters/data_converter_rounder_base.hpp create mode 100644 include/rive/generated/data_bind/converters/data_converter_to_string_base.hpp create mode 100644 src/data_bind/converters/data_converter_rounder.cpp create mode 100644 src/data_bind/converters/data_converter_to_string.cpp create mode 100644 src/generated/data_bind/converters/data_converter_rounder_base.cpp create mode 100644 src/generated/data_bind/converters/data_converter_to_string_base.cpp diff --git a/.rive_head b/.rive_head index 16f26cbd..c15f5b7f 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -8c7ac03294339ae2ad856b541c730dc16cec018d +2c0927fc5e9a5c420305a81446ac41eb5b896b2c diff --git a/dev/defs/data_bind/converters/data_converter_rounder.json b/dev/defs/data_bind/converters/data_converter_rounder.json new file mode 100644 index 00000000..30dfbfd1 --- /dev/null +++ b/dev/defs/data_bind/converters/data_converter_rounder.json @@ -0,0 +1,20 @@ +{ + "name": "DataConverterRounder", + "key": { + "int": 489, + "string": "dataconverterrounder" + }, + "extends": "data_bind/converters/data_converter.json", + "properties": { + "decimals": { + "type": "uint", + "typeRuntime": "uint", + "initialValue": "0", + "key": { + "int": 669, + "string": "decimals" + }, + "description": "Number of decimals to round to" + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/converters/data_converter_to_string.json b/dev/defs/data_bind/converters/data_converter_to_string.json new file mode 100644 index 00000000..5584ce4e --- /dev/null +++ b/dev/defs/data_bind/converters/data_converter_to_string.json @@ -0,0 +1,8 @@ +{ + "name": "DataConverterToString", + "key": { + "int": 490, + "string": "dataconvertertostring" + }, + "extends": "data_bind/converters/data_converter.json" +} \ No newline at end of file diff --git a/dev/defs/node.json b/dev/defs/node.json index 90ff1820..36a1ea32 100644 --- a/dev/defs/node.json +++ b/dev/defs/node.json @@ -21,7 +21,8 @@ "string": "xArtboard" } ] - } + }, + "bindable": true }, "y": { "type": "double", @@ -38,7 +39,8 @@ "string": "yArtboard" } ] - } + }, + "bindable": true }, "styleValue": { "type": "uint", diff --git a/include/rive/data_bind/converters/data_converter_rounder.hpp b/include/rive/data_bind/converters/data_converter_rounder.hpp new file mode 100644 index 00000000..063d38c5 --- /dev/null +++ b/include/rive/data_bind/converters/data_converter_rounder.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_DATA_CONVERTER_ROUND_HPP_ +#define _RIVE_DATA_CONVERTER_ROUND_HPP_ +#include "rive/generated/data_bind/converters/data_converter_rounder_base.hpp" +#include "rive/data_bind/data_values/data_value.hpp" +#include +namespace rive +{ +class DataConverterRounder : public DataConverterRounderBase +{ +public: + DataValue* convert(DataValue* value) override; + DataType outputType() override { return DataType::number; }; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/converters/data_converter_to_string.hpp b/include/rive/data_bind/converters/data_converter_to_string.hpp new file mode 100644 index 00000000..0757e60f --- /dev/null +++ b/include/rive/data_bind/converters/data_converter_to_string.hpp @@ -0,0 +1,15 @@ +#ifndef _RIVE_DATA_CONVERTER_TO_STRING_HPP_ +#define _RIVE_DATA_CONVERTER_TO_STRING_HPP_ +#include "rive/generated/data_bind/converters/data_converter_to_string_base.hpp" +#include +namespace rive +{ +class DataConverterToString : public DataConverterToStringBase +{ +public: + DataValue* convert(DataValue* value) override; + DataType outputType() override { return DataType::string; }; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 3d23e26e..d38b4517 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -119,6 +119,8 @@ #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" #include "rive/data_bind/converters/data_converter.hpp" +#include "rive/data_bind/converters/data_converter_rounder.hpp" +#include "rive/data_bind/converters/data_converter_to_string.hpp" #include "rive/data_bind/data_bind.hpp" #include "rive/data_bind/data_bind_context.hpp" #include "rive/draw_rules.hpp" @@ -451,6 +453,10 @@ class CoreRegistry return new BindablePropertyBoolean(); case DataBindBase::typeKey: return new DataBind(); + case DataConverterRounderBase::typeKey: + return new DataConverterRounder(); + case DataConverterToStringBase::typeKey: + return new DataConverterToString(); case DataBindContextBase::typeKey: return new DataBindContext(); case BindablePropertyStringBase::typeKey: @@ -1010,6 +1016,9 @@ class CoreRegistry case DataBindBase::converterIdPropertyKey: object->as()->converterId(value); break; + case DataConverterRounderBase::decimalsPropertyKey: + object->as()->decimals(value); + break; case BindablePropertyEnumBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -2034,6 +2043,8 @@ class CoreRegistry return object->as()->flags(); case DataBindBase::converterIdPropertyKey: return object->as()->converterId(); + case DataConverterRounderBase::decimalsPropertyKey: + return object->as()->decimals(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->as()->propertyValue(); case NestedArtboardLeafBase::fitPropertyKey: @@ -2663,6 +2674,7 @@ class CoreRegistry case DataBindBase::propertyKeyPropertyKey: case DataBindBase::flagsPropertyKey: case DataBindBase::converterIdPropertyKey: + case DataConverterRounderBase::decimalsPropertyKey: case BindablePropertyEnumBase::propertyValuePropertyKey: case NestedArtboardLeafBase::fitPropertyKey: case WeightBase::valuesPropertyKey: @@ -3239,6 +3251,8 @@ class CoreRegistry return object->is(); case DataBindBase::converterIdPropertyKey: return object->is(); + case DataConverterRounderBase::decimalsPropertyKey: + return object->is(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->is(); case NestedArtboardLeafBase::fitPropertyKey: diff --git a/include/rive/generated/data_bind/converters/data_converter_rounder_base.hpp b/include/rive/generated/data_bind/converters/data_converter_rounder_base.hpp new file mode 100644 index 00000000..b1098fbd --- /dev/null +++ b/include/rive/generated/data_bind/converters/data_converter_rounder_base.hpp @@ -0,0 +1,71 @@ +#ifndef _RIVE_DATA_CONVERTER_ROUNDER_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_ROUNDER_BASE_HPP_ +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/data_bind/converters/data_converter.hpp" +namespace rive +{ +class DataConverterRounderBase : public DataConverter +{ +protected: + typedef DataConverter Super; + +public: + static const uint16_t typeKey = 489; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterRounderBase::typeKey: + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t decimalsPropertyKey = 669; + +private: + uint32_t m_Decimals = 0; + +public: + inline uint32_t decimals() const { return m_Decimals; } + void decimals(uint32_t value) + { + if (m_Decimals == value) + { + return; + } + m_Decimals = value; + decimalsChanged(); + } + + Core* clone() const override; + void copy(const DataConverterRounderBase& object) + { + m_Decimals = object.m_Decimals; + DataConverter::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case decimalsPropertyKey: + m_Decimals = CoreUintType::deserialize(reader); + return true; + } + return DataConverter::deserialize(propertyKey, reader); + } + +protected: + virtual void decimalsChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/converters/data_converter_to_string_base.hpp b/include/rive/generated/data_bind/converters/data_converter_to_string_base.hpp new file mode 100644 index 00000000..c919cbad --- /dev/null +++ b/include/rive/generated/data_bind/converters/data_converter_to_string_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_DATA_CONVERTER_TO_STRING_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_TO_STRING_BASE_HPP_ +#include "rive/data_bind/converters/data_converter.hpp" +namespace rive +{ +class DataConverterToStringBase : public DataConverter +{ +protected: + typedef DataConverter Super; + +public: + static const uint16_t typeKey = 490; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterToStringBase::typeKey: + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/src/data_bind/converters/data_converter_rounder.cpp b/src/data_bind/converters/data_converter_rounder.cpp new file mode 100644 index 00000000..86422ff4 --- /dev/null +++ b/src/data_bind/converters/data_converter_rounder.cpp @@ -0,0 +1,19 @@ +#include "rive/math/math_types.hpp" +#include "rive/data_bind/converters/data_converter_rounder.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" + +using namespace rive; + +DataValue* DataConverterRounder::convert(DataValue* input) +{ + auto output = new DataValueNumber(); + if (input->is()) + { + float value = input->as()->value(); + auto numberOfPlaces = decimals(); + // TODO: @hernan review this way of rounding + float rounder = pow(10.0f, (float)numberOfPlaces); + output->value(std::round(value * rounder) / rounder); + } + return output; +} \ No newline at end of file diff --git a/src/data_bind/converters/data_converter_to_string.cpp b/src/data_bind/converters/data_converter_to_string.cpp new file mode 100644 index 00000000..6c62f38a --- /dev/null +++ b/src/data_bind/converters/data_converter_to_string.cpp @@ -0,0 +1,36 @@ +#include "rive/math/math_types.hpp" +#include "rive/data_bind/converters/data_converter_to_string.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_enum.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" + +using namespace rive; + +DataValue* DataConverterToString::convert(DataValue* input) +{ + auto output = new DataValueString(); + if (input->is()) + { + float value = input->as()->value(); + std::string str = std::to_string(value); + if (str.find('.') != std::string::npos) + { + // Remove trailing zeroes + str = str.substr(0, str.find_last_not_of('0') + 1); + // If the decimal point is now the last character, remove that as well + if (str.find('.') == str.size() - 1) + { + str = str.substr(0, str.size() - 1); + } + } + output->value(str); + } + else if (input->is()) + { + auto dataEnum = input->as()->dataEnum(); + auto index = input->as()->value(); + auto enumValue = dataEnum->value(index); + output->value(enumValue); + } + return output; +} \ No newline at end of file diff --git a/src/generated/data_bind/converters/data_converter_rounder_base.cpp b/src/generated/data_bind/converters/data_converter_rounder_base.cpp new file mode 100644 index 00000000..e6a03a31 --- /dev/null +++ b/src/generated/data_bind/converters/data_converter_rounder_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/converters/data_converter_rounder_base.hpp" +#include "rive/data_bind/converters/data_converter_rounder.hpp" + +using namespace rive; + +Core* DataConverterRounderBase::clone() const +{ + auto cloned = new DataConverterRounder(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/converters/data_converter_to_string_base.cpp b/src/generated/data_bind/converters/data_converter_to_string_base.cpp new file mode 100644 index 00000000..c600a8d8 --- /dev/null +++ b/src/generated/data_bind/converters/data_converter_to_string_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/converters/data_converter_to_string_base.hpp" +#include "rive/data_bind/converters/data_converter_to_string.hpp" + +using namespace rive; + +Core* DataConverterToStringBase::clone() const +{ + auto cloned = new DataConverterToString(); + cloned->copy(*this); + return cloned; +} From 4a3beb7cb0c28c2f3ac7207b384f50751047a41b Mon Sep 17 00:00:00 2001 From: damzobridge Date: Mon, 12 Aug 2024 20:43:00 +0000 Subject: [PATCH 124/138] feat: add nested text run getters and setters in Unity This PR introduces new methods to get and set text run values in nested artboards in Unity ### Unity - Added to `Artboard` class in Unity: - `GetTextRunValue(string runName)` - `SetTextRunValueAtPath(string runName, string path, string value)` - `GetTextRunValueAtPath(string runName, string path)` ### rive-cpp - Exposed in `Artboard` class: - `TextValueRun* getTextRun(const std::string& name) const;` Diffs= 55de8286c feat: add nested text run getters and setters in Unity (#7808) Co-authored-by: Adam <67035612+damzobridge@users.noreply.github.com> --- .rive_head | 2 +- include/rive/artboard.hpp | 1 + include/rive/nested_artboard.hpp | 2 +- src/artboard.cpp | 22 ++++++++ test/assets/runtime_nested_text_runs.riv | Bin 0 -> 806323 bytes test/nested_text_run_test.cpp | 61 +++++++++++++++++++++++ 6 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 test/assets/runtime_nested_text_runs.riv create mode 100644 test/nested_text_run_test.cpp diff --git a/.rive_head b/.rive_head index c15f5b7f..27941d26 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -2c0927fc5e9a5c420305a81446ac41eb5b896b2c +55de8286c5ba680de950a3a0aac26e13bb890d6b diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 6c9df53f..b054943f 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp @@ -408,6 +408,7 @@ class ArtboardInstance : public Artboard SMIBool* getBool(const std::string& name, const std::string& path); SMINumber* getNumber(const std::string& name, const std::string& path); SMITrigger* getTrigger(const std::string& name, const std::string& path); + TextValueRun* getTextRun(const std::string& name, const std::string& path); }; } // namespace rive diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index 64577275..6b977080 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp @@ -69,4 +69,4 @@ class NestedArtboard : public NestedArtboardBase }; } // namespace rive -#endif +#endif \ No newline at end of file diff --git a/src/artboard.cpp b/src/artboard.cpp index 67a5a1b7..b0576d96 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -1359,6 +1359,28 @@ SMITrigger* ArtboardInstance::getTrigger(const std::string& name, const std::str return getNamedInput(name, path); } +TextValueRun* ArtboardInstance::getTextRun(const std::string& name, const std::string& path) +{ + if (path.empty()) + { + return nullptr; + } + + auto nestedArtboard = nestedArtboardAtPath(path); + if (nestedArtboard == nullptr) + { + return nullptr; + } + + auto artboardInstance = nestedArtboard->artboardInstance(); + if (artboardInstance == nullptr) + { + return nullptr; + } + + return artboardInstance->find(name); +} + #ifdef EXTERNAL_RIVE_AUDIO_ENGINE rcp Artboard::audioEngine() const { return m_audioEngine; } void Artboard::audioEngine(rcp audioEngine) diff --git a/test/assets/runtime_nested_text_runs.riv b/test/assets/runtime_nested_text_runs.riv new file mode 100644 index 0000000000000000000000000000000000000000..b7535a09bd7ddbaf68599516c6236b57f9ff0d05 GIT binary patch literal 806323 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 z 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%0DFZ7G}otuntO#60NM>)>N_J)HOb78O1? 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�ex?01)Wd-g*W{0m(X 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%0D@7}+E|2yyXI*jAkY~$1} zD=Kn0g84jAJdp{>JxeCnFnbypQjc(QQ6NuCLfhSwCKMlx;&SiX+0ljh_^x8zR|C?S0uyQcKIDtgynRo_FSK@ zyoDb}dAWmBh^_nf@7s4^D?f2UbAu1+(WK$mh>$R%*c&@WawGnkkuL^67cp|Nzm$S2 z#og}dgi6?vn#~{Ski$EET?AolM55S1;jszmsFM(|jD*HU+mdTkc%S!;r4xd_z7(ZmJvPn0GV6W zAWr6gc)S&oC7(dE$_c5@X?7%w1fy})Q-oOkR;{PB&Cc1BNp_@00j+0zw9=y*WxZN0 zg%PbAe)^sozu>DQr4X&RFBq@hYu+ z>>jqxV#E@*fa!J;5*fhxraJ%l&Y_sfnK-qybkb<6I^NS6^y!9zZkkOkDXwA`)=I6T z&;n|O3$4%)~W{Id$Y51fA4XXS5g{$+@j+^yE~0x=d(`Y(-OPG zXx2%xAuJA81H7-owq>KUyC$6Qv2|DLF|qPis7C%+CbdI=L*sfa;;05f>opHda5uT| zzEl{JQ$^8Pw`ORSszP&cRjQn`TiBQ_TwT6imC|H|W4l(m$!r6vZ7QA1%E@P?0@2{Z zBFdK-VT1poI~zv&qi(}v@V|THqx2kZWe#6v4t30-hB+)^4wpEKCsFTmOtz!62v6kn z>9(HVH*R#FSJ>6j0{`-Q%g!Cu9h-=uY05d19e==hfh)-GFV<9|@2#$$-h=N)qOQv^ zQ!J{OF_ot&o6BERTIx`ZjlWi7qj9Othn^boicqo3)}Sk zuGW`-h1$}(tF^VcNj_@be}XIgr=h-YZR|k4030Jy2vVDKA%vJ(!)I z+Mn=J5bra^!700Tv3NJky12Z2CK}F6@MO*nOC&D3)Cj*!k(76h;#rGjAuSaZZfhW~ zpvV{;;+}E5AAb7<++`8IGcJS>>NI5&$L zdQ?WHH;vt47)c6g4k#3clHyVH31qngmLam?qzBeIOG4Q#Nacy3e=;^K8UUAH;aP6#g8Bw$SI02kQj$Nl<5c?^Uo8SFsY}eUm(c%UOxD zqgI?H?z61XSGP4+T%kwy{D_$8#`cJFR%OexzaazEUu=PfNvkPfzlg%A*SZqD%|Pqt z?d|V{&UPmIsMmie>8Plse&kW-w54cK%gUVki#w`5GhKNoOvStnBT)2Cd;3lx+`bS&n22?P~fG6BdwxUjPhaPUq_#i zZEzOjIz)8iu|vJoB2`9Fi3{n~#zlr713rf4BEf0|HL+5ueoVn>j9v&FuLF*?JbgBB zoGlo=sjRGg+F9fr77=SV+U_Vids=x}8J{LPn|(gtcXxCSoK+@d3tiV`3FO%eROA>y z9X{CJ?$0-I`NG73AA{Lj4+O_A@91dX+l%*xGT}WmsZaFpZSUw<-r1SuCFI5@NA|6= zz0Uql@Y1V1E->zpmVi0ClZ9nCtacSI<1xU0OP$?m83R zzW}p4)L!~J?GS8-3pn`v2mG}IA?gRpXIuH%s;UJy+>TW_s13%}Xz>&D-IU^MF%vt3 zQ^W^q%^^W{n0A{wus;z8b7Q30p!OwVhx@2GI|wv`S}wLg(8!*mG@v$QS0IN( z6WLb3o%#U~AP}1v&V;{!lE+7nDU4k-OVKwL=oSadp;3d!{= zd&noSIXk7;YO>|oZ_bG>XTFLW$==@n7^^}Dy#yB{)UtmfX0D{Lv;!NmI>@9*tBX0=C$$2y9O(dLx}4~YoHhSgXPol!B&3R%{5=@rO$9Hy}X z61y;g6&SN+i+G31$3)+JX6vq(pm+FRYz$)rH;*A?m7%lQ(Yk=XVYveP$aC4cuW{Tj)CACM36me1;yCpo+AUAHm=l z0`maB<+YoFl1Dm)94ud6GtFy5qRH~kUOqw=^aa%88B6rNx8lnn-R1VS zwtitYiI_ebV2Z?PG+9kgA!IygEU)``y?rWm5Px@O*G)4ZiKmtTYE z@)$*MAjG=wX9YAJ(GYW zhR7&Lga@U6Z{l8@a+aYO^f*5OBexfgro$MrNjzXr`w0A&RDsji^6t|TT4g@Ud?ITn^gVEwc8_&wSS$Wfk#u7ICaN~pQ zY)s0@?j3*AhgMg&;?^6M-_A;~hF0;RRgC!1j=|SY^`ULlyxyx#9ByIv69#V{FHm6E z>m~OUTfI=`9qP$ogH!74;tu7XP7pxC$S!e=&JI4Hj;|Ywd7XdCk}o}!0of3xwvRFI zwTi838QHCq+?wgZl(}Vg>;D!HX6Zsf4>ZUqHsK-kG6{x~L+AaV>X(!on6aLh7!0uz z*#Y8)C{Ik8&o%mxjg;Z2$_Wv&A3z?>rjj^Qv4Bu(C}?a8fHv7_4*V%@DftH#j9+TI zl(9AwN?DN?Wmk!0oLyRq50>V$-7i5hUc$}kKWkUN`LOy2NNN1{*0QqPFs|7xe+Xxn z1t+xOlC3cEk4I@@lo)DjD@mdaBug&C8-1B7_xttAaq(agTXWT_&sB*J_fp8yrLK5K z(Dc;hyR#1UzV}`)QN}nB+}D`)!1VkL$PVIQdj3-6_dWz>8!e+445%3zg>;Qa53!y6 z#_;>cVpvT1S_dj*u5xxfVAE{`ei(w9=vqR^vdOs^=W-Q}b@(x|^1pyBE|t6Qv(ms3 zhz|^Y*-LDrb?B??4SxH$a-EJ#pUn*NAn{U^P44q)=KX2reIxUh2+A4EyU_H4 zKl1$z-+yr9hWpm6zkkGX3Jq~2JGMg+q2<=DpMp&i7^*u+U$+o$g9sQ8SUq!L`PHRV z;+W5y1>R7h=_g-)>xwVlx?;s0t5;_%3lP+B%6mO0VI7To7D53?!U^d33Ig=5!Y!q8 z0@m&q5%^x{^jmv(^5)rgz*b}K`!o%B%Y6SElfoj4bG(JJ(a5alAshS~0Yojt;{Tg! zIQfZCh!;^s8UXnNYB(soY^2^8_Ju5-95^X8}FXgCRA1 zKl4PoR`E4cKsrO^A`Zc%p{Ky_4fFlqrlC?Qoh@Tzk9LgB4L+=_L0g7~=J;tx1%?hrdk+Z> zy@xNMv1uHg3vN|{TQ`7PB6D5^ZcU09rZ#0n_U$6FZr8p@?iGs{FP?6T>}^7=YT8SQ zO#g(8K9xdFv#1Rleu74HE%tQ`Z7_u_r76?sI_q9ELWfv=o}Y@n5%Z zZ+Q-qzU|rV&pxqHKH2zE*qB;TQQ-*h`S*=TVPa1>NZglkv|pic`{}g+| z?^ui<9|)@OH9)@uv8e^|3D+j?58~2fEpnDulzKcD&aSQwSEx|dt+Og;U%zsmse}E} zJn?}qE)~sX3a(S;5qXjiMr& zn2N@6(zJk?1LKCd(`#6jT2@8+E>*EAm8{CSq7#=*b~*~2r;5j>PQ3FGpU?Nbou*Q} z%T$Wpxq&=NSbwM#7nn-%^(Be!e@|=0C8ky!Moh=kAzE=fd{QeuDgS1Fxx!S7D@?Vx zTWm)|gQng3o6RtBg?O6Q#6i5MC_xVd#g!zW$%Pe zI{$t`7-z_~>Sh{<-FOF!gEpGI2A#~*j4{?Gl47_Co@=8MOMykVlLSokWr4$HrQtQM z(V{V~v15wtwqZn64ZV{a#D)Tzn9+bOnZlwU8>wW%3aK%IMbT(4bszhqbTEwKt%*jD z#r<{^r$c}4={^vS#!~b}97f$q-$(j0Bq{s~mKgDbO^E+UU4#o+ABhN)8WV2Tr-b!E z+eMW9!H;+RZ2R`kH{R%cL0BF!$As%L7OTCId56G94(;=mA!kQNUET68R9DQow#MT* zzjU6kv}%7K8($w#jz>-Nu;C-8b;k%FOKWMbqT`BG_(yXeJU?PCds1!Gy(aIl+^sC4 z(~<`%aq}@}F?lIiEP)Q}XpPCj)~v~k87GDk;V=sA2NAfud}r!umNZ@XEHjiS(p#9J zSe6$u!>JqHqr%-gnB`Nunk7EqM=y4qnCjW^@N*p^93n7HK!&&VG}GqV?&}5YPqi8O6YWLW#tA2;uOYCI)*dLM zG4mQ-SRck4w0#IO$~QU@g7{(02vDIK%AtwXAxBT-iTIkZWv!bUjUGuvh6Z9Mpe&AT z19vNSX~Uo}h@JjKR#Tux*d2-rZCCWX<_XC3L+=|phV6h2eGL9PM0r1zldhVOks8Dw zJc*Tbvyx*rZF0MX$Uooq$}4RxKmUDC0p^u9M!0-=Ab;00P>8$hV`L|#20Q6)TG!Rp z3CW&aR`#j#s=4QvoS?W~IVW%27|5@@5uxl`tL-`2hL&3zoC{W_Z3!S;{^IKSm9wg< z%Fey0blQyC;CM#bp{$~5@pcoi;}aQU_A*N+$j)b)hQ&JrOg z$Lp=Cno(MM{(|M^-`OjdE~uGKfmZY(o~xS+%OO zb2SabAsnGuaKTL>$;L1Bnp%`rL-=lo=t%eavl&otFG3FQ`9O1(jCi&s_xxO*bRIAi z-BofbMoll>(B0+T*wy82SnuxYX+%#5NGr8kzxf*_jU^6^YVTU*DeYY8_H?XR-COEj zhJ7huCcgX46M~e3PE|m=Ob}^OSOw6Xd@U=JAkr-+)vAYHg?zM4>h6y5lfY(H;u4Bg z5AKKP>Xx9z4L`hzb$7`O>ZPE$i3O9G!6ardju}WkzjRd48`??cUrofS&)Ht@neJ6h zexKUSZuYBMG4biky-_MJsExL}dc3Q;cD12R_+;Usg-!epNwU)hemX$4($eLnr6^wQ zK{|#4L-w=_r;rhRAm2dc;)AGs25=uRM|24z%HZYMjA$YwD(D;>Ry~nCrrh&)#j_=IB@`wLE-Oa^ZB!KRQUb=sNb5P zJuto~(G)S`W01caW4bGa5=0_DE3n13n9_uft^ZI~`6Ld>ZOk0d?`mT*auwiXj;< z*}M9wMA5&CbXwZ>rB>R0xT}|aeMmk4&cM7;t@lHsWj7WkNle?Y;g81o4Cj2~j~jy7 z<@tz4j`EvltB@SFo6ASjZfdmDp7zP1FP75NWQL%97UH9htzKQGeur-IJ9WY8pzb;M zbMsi8U#sI-FouzUHW;5fcgEaX<-=y&l~P*tc_I;3TppwYIIIPRp#`w_69oaRt#OOc zkP`v>aQNN0${FV@<{310)GeroY10pFAF=;n2lPSx>9>B&sw{R_VU8L`V?M4d9`kH0 zhDA|3RktHq((>gVCg3om={}n!Gk=_wKex zq=%LBuyT(+y34gz5sywBk3{!Kl)aitMZ*V7N$kB%V&wiZ<#SeIk>}$3eWI?&KJP6 z7uwn)0qa0_=W9E5bypyV-E~(;E3H_BQ1FO)3ZmAEF7Ymw?t?@=?BMU$)d%?aqkKmC z7$U@@YOQr8xn8B9VF2%=Ztje@ne&Czwtk|4-i0?ZugF!HXS3%N+O0VlLWto-$b?Y% zNry13crximh21I(_hvGdSns2oJN41c$i^6Ifz_V_O&}vT28M^I&vhb!9ROcJmcHJE zr^F*kc9(Q-|1|Kd2A&s&)r4tf8z0;q9*v5Y-R*XF8>aXF*Nu(z42t!%Q?aD!nXOxY z2$Z*zU*`9ZkCBwq0xSGwcQ&U2$zji2AYDmMLtIQ*4ws9}4SE6%4u>vu>F@4oU-8we zT!&g)TZi0TU2YxMe$;izvSsb6UhzhoI&BN8W^HwcDeUb9Vb=ISAPnfJ2m>Xv=x%IQ}ws{7}gMNH#pgr{u=^0F>R zh}}Ab*<3=9_7KWCfKMXIXKk$1)0`!lc_Hf^%NCYTWp(a`aOIg9g`!U&zq0_Cxs$Qz zQ0VMf0x?YuACXq4!sjs^BGVCViQUg?vD*FAZMES7#PVs)qaF@-i${;I(UZopH8^bo zS@t3cM3q!Ldv>VEo|}z6f)%Qyz{c*1;j;D{$0>V&pA-vv94ne7Kt)T#>U0HVV79dy zPD^DK4-h*2Ao_d2(jU#(%BQiq(^y@p2P63=5}A@+Qc}^;VXudAK(@rQYBTdyeT3&} zWi4<4;AP#>+FGXUU2C(uyIVb;$V#LYKDJ;gj7d7W&!_7AT3Z!dh71C0byZcHig?#* zHOuGV;)#mbE3UPg(#3VNr=zcMO6kT2|Dz*@nlRAu+h1 zQIa+viyhnBd*En7FS4T^_#FucNHugk8si&mG=R~M)mpR(41bvRhU;+{DlKG5B!`p! zQPvZ5`K0S^`0z1Yo~UI8hNFb8k?m;}wRVjv5_>(Fh`54=61Lo|GzI?>&=!B%YM^~1 z(3W`m3)}Z6#vuTw_I5P+e9m#lI-Z07uDgF@{Tdk4_g-i}i1h7L`*&}z_tpPs7gkw+ zmNtAW+<7oync{ZOA7O3d&xahq{fO%yNGV*mdr-L`eV$nFGaG|>W#{Hfl7LZGHdiDO zd!)}^_SvtlSozJbuK32cM{Z&N$^vh(@FCq(zVPc6%4e*+c_ziZ{pSxJ8FtQ))Q(gn z@@qyFt*xzsJX|=%U6iF(uU=YSqKj#$+d2L7tAj?_g_l)-Z4uJiR#ac<_I!}6Pay-p zXZ!c6_Xwr0XY)S}8EE2%?C6{oi$7IXe#JG*BzzuQI|rfrmQ~Adyn+I4MCOPy&4QBv z9qdF5#|ibBAaa=5tP+B4!GJkH)0TvPR5B4u<=Q7f1hUU^jJ08R^N%sDZpnDGe}E7a zN-t9PHWBIP#&kCjqmHEqoR!=2-mtPoutAun1nhrCq9CNvwfTH}6y)=2$(S0Z5qI2f zgV2cIoJ0?2QNGPc4h|-wxcl>+f;?HecpVutt(tiNu0ETo;~P*QlFiUfdlI3vR^$RF zs77RR^;~d5YH?djs;gZtVjJmP58?OetC7pp>X5a!xw*HuriQf<>DQwIZCAn$j+uW~Vi)h~m~XFJ^hrtKcm&S&GZWSOR1b*X zg>^z=86H9?x5L^rcv=$C4|f(O;Q$y7PKsf{G;QM13=rC2PzlQXSS(9qe~NQh3!K9r zVrI~jk-kWhP^(;GqLPWhqfrXE*z(3Xiwbh#XFO<_XchdrgjR#kDH~zDMj~m`lL1Q# ze?L#K+Q4^2)mX@75U{S;K;jZfl1Mv%6~Xk*`On7q?8I4a=*RlP{ewv?sy0U+5A2Eb z_C;gKQRH1P)@0CcZ?lL3^+_OsccqS-Nz$fe^!Ch#=fN*R+5p;ox zSb|psQ4*A40J?UE6?XwE2O3%JIic|q7@0z>1p%TM$Z2U7jm8WcP73H}A@b5#C-f=; zA5^%&xNmlDb^_Zs5+suaKaxUXEhnOpc+g@ka5%sl?W>zvXNX;|t1SpzRNBV>iT9bo^dq0SR@SvL!3s|xZe2FB#*^BZRZz5_9 z>NaOqC`}8?z>JH)4Drl+pi3Sw!-79DD*fheNv+a-KA)(DUr5y%(VP-W6BIfJQD727 z>% zp@<)=e$tK6$5^pOl!n_cwZ`MFr9qz-kNXKaRSBSs77#4dQw3xd4Ku(TyPnLpa7v-e zPu~T@K5!`R*P_G0!X#F`BuZa0Mp_bz0_Wsd(BHLOdw(C+91EU8Q~L5UUoZ3Za=XdQ zcQW%e1x9;)Q~AXn@PA5qc@r5BumPFtdE@Q&(z1z8Jsd;SPX)y!Qg2_iqs}fJi}*a%0go37>yX7beS`P`cE*!$1s*l z7ZqF@4rZB^rR#_-6n#ii&FMrCx)Xq@(c0XGN$xOnjGag(W7K$2Sw<4)C{{9SfYzGe z6aftC$jA&O`(vy--DyIqRU&$F0V2MxYZD2v{J%3vrUdT|Sg68ZFk%~%XBCY+OE{_2s~mZj?kdLHe`l&e zt(Rv}`)A}?gy2P2t@3Hr%}l<8l7J*L5l#gYM>Wps>vOqi*G;C0-99itQiOa6x0YJE zqj{2KJ7nrCk37jJ-CEMpVeBg1QJ#6Y(OKJ5RP9!(Vip?EZmnXq6q9JsSL1ZN zHwQJ;u*IUZf#r{=A{N3BJ=ULoT0T$9=V=lTfDzlYE~d+cwv=?}WjoS61@x*OufDsI zsF01?D$rnqk6W+Hic+YC+pf!ErZ#T5E{%Da8AvbaGiNZPVMarTvB}kOvLAxcy1aFH zsj;M|bi10vxVJ-~HfGhXTv91&OD!x)W1AGl;$NB+*_pvS+MP z=Bo56h2_K&b5(t^q9Sy%x<1)8ndfBiAbrISIjQO-9-MJ*=I&{n*(K*rAG!O7WBRL@ zlfJ4|uBtfsguj7lr#xlGDd+Q~^sdRw;Pg?M_b>m8QPHaD^s6%SPCsR%jB4d6Px*^k ze8f}Iv-l9QCV2nWQ?|%cXdL_TyX+KLojUiEqnfKURmo2KG+6TAF5+W0InN7H%W~H? zzOa8F8v9dAoHQojwepLf3e5RPe9L&8mx2%fS9+ZDckh1fjh@c-T|2jJ zX==J>A^xZ3R3E6KjKS5ZFY?!F>W18G79CxYTAlA-zj4#!+gdvhhQn_|*~B*Vf4QeQ ziyeI`Urys!o2+}9nh9SX!K{q$_Ci+s|0Cb6UQZ=FmZJ*Uzm8>)Tvw8mEum<%z7kpP z7L$|SDaiT1$BUbRM`j!ya*)3{^ZVso&j`)fFMmvyUs6f@GzsAJne@szj*+WA z2Eyqv?UpOflmq_C$kJDAk}K*?eTL1S!R;)S-UpdcrRm>RxgxzD|G+A4k*k)Rgx1IM z=Tl~qmV%l8>99I|HCp8UX}b8dPDfB#t0Flvx{uR1yQGvJxI_y3>gp1wjI zGG6b%Vs*$-L#0Ork z()JGVflHUx>|K=mbeS&iv=6+|^nt&(D^uhm;{(TM93W*S$JWsBrYgf|Ri@r-2%hD! zVhYIdT!jtwDo+lsnDqM@?0i4Y46Et*RyhCFo7i@{)Va%0)hkl}bKKUhoaxgq%;|c@ z*YMqzuHi`@&v4hz8z5loBmg7r=}x3@a}Qh9Fy4+pLA-$!oSDi7 zDyGeVZn^^l{ZeV~8$Pu;cY}!>HW=?EoEhSJx42r8YMuWG*Oi%@RWf zbw9;7Zm%iN?dxd+>aTQm4hC!=^mP7aPh@#r9WvHx*T#;0F~ji*x4V!)4zj26WBu>6 zN${R&{lR~2iIdnM@qjo-rdYRt4NoCX0{ns8JcmF8adBefvXD}gyFN{YGM?+}fRuQyYk|~- zVSN(Gotu6e9*cviu(zb7HwUw3e)zYfyj|?p!+To@Lw>fUye1SJQB5?L_CgouAPbA?ylOKytWAE<+(dM-8y#GxZ}cwRbBg! zI!dNqft|H_@!~~9oJ^l6@!;5#{G&Zfmo7cuahQ-opqCT=!;?=w*(Kiu@{af8EF!EI z_r4aoaDDy5o13>ceYgIhtu4F$(9zM`{VssVa_lf{&hyI4uJ9J9BUJm@`{MS^_XY%# zW}YE28MvO;=$KgVF}P#jFk$Gi@L($Bhz=Yl?{lc1V8Cb`CqxXhC$TBE0s;eY3KABJ z=|0DwO@JrS-?CANbzOsxnu@tB#yv)MfxXD$m+owYD3HTw1nkx#R}o<&DQqb=-EWUa zV)5hL2!}W+6uH#aObx4KPJwwdl7Ml8TgBABCd)#uLOi|>8!(*(63Q|_-+=VKngZ5; z0<4!VN>aIziW6#->8G}V!69tAHlGi}x>nYTe;T~C;xZ{yj;^(%dU|#{osrtw6)Uip zMVBojvQz7t;kVV-SI(G0Uk%UNoJ}oM-Eff4-Uz}PTbgC}J)C2YC6v=ekOU#Vv9%BT z93-_x>A7g<*_e<8QSYI$ph*ogzUWICpV)FtUvzt4!DP?IjX!OVV%YC(f3;<+rwm_o z)0XCcYk1@#JOYosVEUp54|H_wAX4J@k#Qj9f*O3$wEMN=OOFsV8#xj3xE+HBdunf* z@76K&XP1;tE$iy4sF+?|vtZWrdDntV6<+ZqNlqwr4C?AGw7tb_UhD4l+c#~J@K?9n zN#v0hn(SNqP*ZdBmPa<+_wBZ493FmlR!w#H*ADZgm?mHKx_~^SOaaREW?moNY((J%@IlBbF8~`tCBq|Ri|VR zU(oTcD#q(TZ9ch2zd+Rqm{%f_}?>}#tl-L6w zFplva&kTZ2E`hbcX=qM2m{LLv^4XPBlD#`O1uyVSDH_6;S5WSqwS1L2p66XqQ&W3u zZB@-zX%=EpA~uUux;i=YbNYv1+$hfzY$kq`BZn2L3N4C zN=^t}b$M^B3!Wbe-u=U0c1FjSm0be%j-FgvI@H( z8skoP)E3D^?AumEKixtv99OlgIkelSld0i9`C+6jQc>si=?$AU`g442pz?B*c?`2Y zp=ExH!;CP^PJ|^BIBc4{p$e@Eqwgb9qPD&hnJCh|>Ah}#olI#p#?ofw8GC0S(AX-E@%(B*3R99aHdR**w=;G2H za7>=d1?M;E!5-2c*h5tYzgvODN15(X*J0!)iM|YIgm6s1u zaiy{G_dP@9#K7K_`gZX>joV*@NE{fljXm$;vP->VZ9{mcJA@%X+|JtY&=0pZx4zx6 zw{1uB6W=%4$5hYMLUp_wm#FyWNIY9(AxDV>TZ^nJEFlP49}0ny#$; zH4Hlt*IhhDiCNN}1Nd(W%;=R6!LNiho0)G!yvte;m5{*Yqxnmc8d({IRzvHF^dG~; zYqb%*OPqHPq|C`|2!|jVVwhkCLN9b(Dnbn7?SnLd$fJ1PAczlT8XM4$sN-oqBQnEM z@JDjPYQdk+fIri^ez*M*@Zst9&Y^S2RefFvOv%}2m3XFzcQ?}Yvf$H;-4SQ0dsIIJ zCz}ylN4ZKIfl2Rmb^V-6Uj^}qgyA1)vvqaXPH}{B?(T^@XVwL$QQ4su+A`DSw*9HI zdeKZb95Qw=W+bG9#DJsp(yQs(bb-s-cQ7`3vPp6Z&vL|CUt`z#Cr*XhCmS06jhKSA zz1;-4ZQAscJv}3 zLC;cy!?}=|pxLxAaum{oZ?BNpl|eWOQE|CBx{3}2%}g7z(}nQFOt);p>cY)wflaa6 zIJ>nG%9F`R&1Xe39;mG9s_o6tl66_#-7c5BnVq_m9It))TIJ-^rB83ZfdUijXf4C@ z(IQM9pABwggBw=vgv7~@_;%JK90bKSK^}y@o0CJPm=xl|llt&SU%5Gb<l|U3@C3c@ax06s&I-@;p1v5`e zUpMkJ_o+|&JFhuygnxNWMte_VN;}>gU~iY_RHP<;=$T3{+i4?|E5+Y<=9P|u_&=mUOQiS<9FGybM5S1LDiwgzx^#$*HKI-j zU*P?-MESf9X!ofeK9l-c6dfWiV=ZdeikrxHgDU(#pm?5+ z9hseVihWY{hf`ZmjW zfa6v5GRyyn85O^oK(6l_-?*jrO7DLU<)uQhkGI>dx0MmaQ*TD`5X>bamfV=zuFEpRY>4Yg@2kuVq~E(lSDiY8 z=?&8x+KonMXVu9Wv{koNyNt>ncdHr2Bc-A@T9&L@wFEP%H4>%CZNf(HViF=^QNJ!J zt0UB1;_{{-wMkswCwR_ek!f5myBU}Fh1AM)T;4YcY#}bs?t=dnmXu8NcnUOo$=Ko& zr?dF1;HYpoyJYn@ZX>Aot9Pv~NrqvMK5Z(ob5l#Ls(<%uey#ri!FVC{1W~h6Q@Tg} ziVU8Rb>)I7PN(;lpbxE^7)S*BXbejU!Fbe`AxlGQE@|cJH`}Xfgz<9 z-CxVi@$1RsgMKY1o<76Kwo)L;MzmfggHs~$WQJ0~D>FkgVZ$EUipLgvJd?%-N7dC;mv`h)Xq{0`0alVyHw z;%VA`eA*Pp&eOKaqvF%~rHG*1H zAdp1GJPrhio%Bg@YHK3Jwy=?&Vzm;ik0QzLIq=guEW5s!VO6p`6` zr(d;MXv0+5dt8OQ?H57Y{B=65KmDo?B>}Gb2ua|hpVcOJ77vd+3n}^U^Q3N(6HUJI z*cp5!^OV!6-BvkYd}?as{FBt~qtE}4I{vluGjmTDN|xK_97gTb|ihwNULf31l# zxhj1JnM)?y(5G*HOwmP{Q!G=bsO#jlA4N`HizruZzK#VUkYWVyGNU;49w$dJJJ~0r z*o2a}*61Ika5b+6ewh+pCsT`g0k@O8i1sOSIrT1D;x$V9e#5_3E62=Q%@q!7R0d+~ zcj+<^Ek4nY_c?tBkmU)BjLaN?T%XMd z1aBllE?c1KDOb7vHJ05`l91PE;b?G;M*X%m7Dqp*y2iXtV3>Qx$SuvgwgST?{=`cxkevvlEz;&1#RDA9ip6zft>fnpEO6eyavG43L)Ty8U&Zc0;6nZsYg zAcnnPU@!xxwZNcA77rNou(bsSRMZ%`-u4kNBzYmKnmDnX(6BmQiv|l+0k4vcHNdM> zwbL{6Xy6XbK;v6{cr#GE87NK>qs~z0PbJB5(__zfo*3i8{``l|1K6fZ-|2jf7?5b> zjphgEnq9OcCTDf(PUGR`KOTYiNV~G-IX`aRDYXCR%}>)VAj{)kPjV42_y+z?JW`Prv9g`~{a?WS^eE+mx7Yr-S^8s&(R} zs`|>+1du<0O(R`Yy@z*Ckj4F#`Q?>rmwE7K)*UtcyJI$|ZdSVjma$jXer+y%OA36; z@u=~&+RI0)k!C?Tt7>OrM=hCId%FbcE?qhc@$eB}h3XE zGq@3-Y3+Cqv)_9QU_2X{$1ch4=h(%23Lsfm)mBtg)FROEhw%-}sNay@I~$o)y7J!U zv~@?V4c?=)kkY9A9?1N^-)D;+J$lsq@n5D<@lFFV2Kyt2Nur@xepb?EAXzDm-!_V- z+H&A$wi83dkK2rbBFCr#u@-S-To$PYP3nV7`*SUzwEJ;wVRfeb27K-~*l?VRY1w>W zCDWBZ3D37k^9>2GCpUpi2mEpvzU*0k+X?wz*Wro}oA;vC9s}p5Yty$j_vm{Jwg9Z$ z3|4LgD>s0ZXR|`14!1q`xM1bu&$S&MRf4DKrMB0(uYGUZOB?2lB>vo+_w^;0kCRWw zUbgt3XVIE{Ll%Cb&n*7J9JsrArqcL-T1ci?mj;8XiY*b$Q^ggLN$Jx4bqJ|oRdwlpd7zhG-xR1H_jpI z;T*s57K`)N$9(&r+B_u>Y&&i9y!(+m?97w?i#rVasW?To$CUPXW`nWQPVTY8hok-? z*<-2XX?x6nRkZ&wd+;!s$yrvuw^*Vo$sVMw@^SXy(8umULrk`mJz<+tkmWKz zJ}KY-k?;Td?#(rKZ-4*50I?H{0?P29xouB>|Cc*jt71pr#*S`dM>n#gTSsFhE!a(1^P~?mC+r=y)ewpxTH%?T?LS2o z&iSj1?{u0{cqYkNXFxPQ|1IH*>yg|tJZ_Wxt$*wDe@QZy2+4T%B*}P$nKwZ~-X@6NLC&h zcC=xUqnN*6J~@fqoIgRkR69v>G>I(vKSy%@_PsxvoB!7c(yu8(*2&MWGc146tcqES zGAw`TlBM66H^TCN4%7d++WgTH#hLW(L%+{Q(JeOZ4^9;iK9Y2uB0hZTBS;&eA|#}d zye;Ab)i`YwgteVG9y=!D!)QlQf%;JVIP0UXH=R)lsA}pl{+~v}9#p9xIK$x&J~$K( z_kTb@1Ful4aQLWyLh5KZeDIH*67wzJ_k~Bk=LEhFWXsp|D>*1K3N2c4MFu$z2|g|| zNG|0a{b!vxM$x*DzC1s3InM0};{WM{?Nowy8j)LX(n6*JQ%K85>(bg541;9)bd{0M zLH8uDRtnsI+Hk_~=qcSS|Fnm&E~-(O0O zx?EmwxMaqv&W>3kQW#B5U0t+pw5MEjI;%>p&=J|^(Cu#-NuS@aK)TmUKc-q*1ZpWm zYk1((d{@h<$~^46^P~!?^1#8nD$)x#p=+)7`?S_pKh1*Hm$tS%imiEjM|fN@<`@Ww2eVrYDe7n2*-R`$L5xE}x zxRP~g%**J88U0x7`#wu&2T7~wv>rEc)N6z4Rrz%(pC}`g)~ipw&W!YQk6gEX=B(J%J?jOF16n;kMvm*y;uY= zKk?Sqi*j$i6$?XV9NF9{6LIRZbl52O#T~q@M5i-^GO;W8^>EtWVbtJ(Tbmw9Av@2` z&dYVDueUM}bxVc1M|*j1(Bg45-8x0IIZ=`Y&bzOtp(=lctl7NttQ&bPtQumQ`bQ;+Wi)K9Y=!- zKEFe&*X+IuY?c-$VRpee2p6J0Y)ZpsfDl^x3~+l{E$KkAfcwtpzL}`$`AB*1X>K_v zFw&~Nt7B)bP~Y|Cox_`R)EkYBjc*`7wfYU0>+Ke_8cJ_P4- zsE{0&^Zwg9C5Y#-!#6>1(m5$#w{Cg?GVy}B7UPj>2Q{^&%IVW>X=qT5ep|0Wuv<$@cW-buMRQ_Q z&XY92yiBJ`u`8IwYWAll1ih?=8dhrp_C8K{Z8uY37Jw8Q? z6svVjy}4^HWfbL%;u1!2E~B`BQJmFOGPN+O?1hDn@f9^)FYh;UvJ;1UU*86C8CP3- z7O~X7l9JL-Y~A_+2C=K8WY~?taUNRQMzV@aa$`epb(LQ<-jN+Wbj&u&6C}Fss!!L{ z%)8X#Hm5x>)wBWab$mUY?AJ!~*n%)F)ks^^mf#P@ z5i3lb=rI`6k%4G5N%y_H0t&0rt6p?c4cUj^K`N8l`7|%bMn_n>0N@`=(s552K@2^9 zL_PDzkX8&@x*FSbAR+w|1QO=~3CX&sNZsigQ189E_rQDa9Xv92%CnoA_r3G>o|kq$ z6~e$dZpo5K1fjn2bI8Dto12dj+dqF1bme~p?ROLxUo`Xj<+m-KH~+k;6)KSXom-bK zntl148$N#rpf;w$3&?iGNdT_n7|E>`3HL z`%kyB2gvH0Ej2ATrjwxScDqwSb=_NoU*)b+gL;$oWAV-d9KV37tW?#Z`WDeFc#YHMy@ zZk}zVE2Ncii?tl3gCiZ+qetP`A=>Q7x`xvK(vXwN6BB`4w)?}XtXahC;hEIma;=#K z&se6pS}IbDwHDfkYXDK0@@JfP&7n$R4?i($hl>l_0N>8;g<;@nfPVH zywn|Z);2|VUhmKv?jErcXRmMgHyGCz_Cc9H%jrD+QWI?^uSu1f$2E>n(@V#lJ9cbo zdW>oRu<74+1V6)|o7u!|=8-P9xQXD0bj6kX+3s7^y*jq^c^E~vsFzGC)uUd5j@6J3 z55+HjSkS#1g zk~76C`OSahCwuocte=&-DRq-|{o`97doc765Y;=Mqa*r~)RLTg{=IYk=B-;FTCYYq zu+P!mQ@W$1fAktcfbIcSKS3(^39pZtCZflA_pC`1f1=fBT}S=)_q%L4@ps?oc)dTK zt!~nEH3W?)(Mq*XYL`JfuGFS$=kd3LZ&K#Xi}*`g&z57|n8N!ajc!(!!m-YrfD!BO z`yfWiN>L{*Ym57bPDJ{8!;$y@d?*qfJTgd2nDG0(2MIQs8y>botmV=7Yz@!Y)k!G zsfPf99z-i)i3d#fctG_CV~m6ocmk-3MG(O~1nolsOm}&jH%c!1btAh*I;Biv9NJ`k zE{#_2VVVm6e3S7th|Jd(Vv>4OQ)Wu?_3Oj*qu4?> ziYcg-Q;fHH|F$s|<~cQ}RZXu@-33e9f1l_2#LY`?{)DUG_lrL(&0{uk>$hNsZ}GZ` z@Q=?z2nb$r&k`fN%blR)cWFVQ51!no3VC0oq}BEjwo9uyMk(0;E7SHxF?8NPGs0A# zIpcHata)q=K0ZEv@L-%p>+h$;W)3}&M&8p3Gsg&Gag{xA>MwRrvCZwqA1vkVlx(2* z$a})V(MA&f$Iaa$H8C#(qLbMzE+9&_hEn}=Q@0T#5=#9OzyB%cdEGXi+YiQB^BRA^ zo(LP`Z>%K-#Xe!q^dPOY9H<=-=1%-uu1D6A%OH zwWVkZsb{MbbQ{s>n?R})Jvs{uY>G@YiMt;sp9C9xbWT7=*2o~sND4>^6}4M-1hIig zui>?-oJOL4+Rx2_%}eKON01&oWIK%LZ&_TO#nq?sRw849MAvvEU_<_;X>JK;mT;!z z;)*UTz0v0zcUU{Jl9mJ7fF)^}tkngxMZq?e?D=Y&-eS2;TaXw?RwwrluMK94!fh(u z^VMclZj|oKt27Wt`!+T3d*=`L4&Oh#YIwiy&~GCLuh>lAO^>30QHY1|q;}6Jv=YZG zwM~-<9H%p+we`%RFFVvl`ayv;`YcrKO@2#PcXt=FHkD#?Ur1!`_)}(Nb91lRHFHTj zd6wMP70LUPy{AlQZt~@1PwEkhn9NAs?jxx9Z_kIiYZNELqHwRExY-ZNe5%A@fBSdPYYVaY}$sbz(HmyxbWm$0x#}MfBv13u`E&KMowwDz&@3esNU(NVW*S$Mn zL8eKau4f(UDV_AN3iVW;^K#x??tCA~;{D*?r*~JR&ceXRkva>^U8>{Ro6nZIi~i1)sYecPz8Z!!HTh1m8!6-F)aUpM0_$TJ=GWGiv2V+2YrlxE zblFK6IqiN*%gEy4m1B2WM&`cA$jHMKaP*rJ&^=}wux!aMh7izNJ&g+z73eu->>}F> z-goQ&;(le8ut>jQbI+`-B<^j!Q3HRdnQc<8bvoXiSwhChx4I#`zRdQyD&#u#aYMsSQ^rcf<6bOg@eM{ORN`lDm?- zQx{ktZFuy%8`KPcVMT?Zk#64IO=go+Ob>n(!WFYlZ-TSI?Wf}lFJx{JHT1^kvY`|RU63e^bx41YUK*JObE!Ca1d=Rb4^BD<19`w z3o(@Yu_u_Y7~w0K9xKujLAqNO%2Oi!TIuKKvESlUk>869{!289IjNfDa4I+Tb>oP= z^(PMimelpBnxIi%|Jc?a&Vw$M;%9KB3R1R|O(0&Om1f`NJh#eIwy#|j7eDw&X)JP9Lkk|RzoBhKv(rDj%t25}cX!&Cb{g&LqJWD9A%xTG@ths&E zxKES?(;XAw6sN7Wz(>^y+g$8Zm8WZ@g6C36Q{*q{6GHP(pt#BEnt18i6DQE8w3#e~ zcEqV?O;uxSuu$Ta-#=9VtDp_juHC;SP4eFPNKaL%NrDj^ktDY28Gaa_KX+IWn^aYG zMQOe@r1^XwBYG9098fvJO0U6`t{ZtYzD&zrbQV&nlp?Ivo|kLWQlWHpa?uYajNq$S z&P@FPWAQR$wy7KK(i5enL7T(taM-%LZ4Q=umFBCTEh2f!t9L9}5;VFR>4xLiI=g~Z zEYv)HT&ZGM%2Iy2Pz|gFMKlvmu-C+9W{dVo&=8SD!TR(b6ACR9V-k=Q3x+^4>(WOb zeP!Yev(=9=Gmg!=^UgbNy6RF);t|)4vq2z^>~kWK0f^;c!9Yv+&~NX%8tKz}l0+}X zjdfej{s4K1l0y4Kq@yl(ob@%TT{hu;wRlY(p0+pl{f_qUHwyq+MfJ`*SJXZ^@-7F6r{5Sfo<-v0t!suo4YBlZg&=01CEEu_%eYgGI=y0{7>GoVgnJJL z$DInuQ{M;2b##zpI%Ud~{6x5;v$J0nO`SS*l!|o9H6H@_)b}6K#5`b~@ySU9uv!wt zr9zmb59z5wH3ch@yM%st`K2xM(eFOZCr+iOLW6~`sO3R31Flxc99@w@A!?+COxMu} zRTbG#`i+WRRk}r2$yFs1__$fE(^jmO;DU7=>(#^Xjop^onK#^3q5N6jS@q>**GvhH z{`R-$(B$pV+k5ux`TgF#<0$8G>%Yu_hRP8PeiqTj;P_wcy$g6$)wwsm*4}$AnM{Tu zgb+fELkKa(h=`P?G^LX(5mQWUv}mbKIXN`7l=4~hP)l|1*%L%WZbn5#j1-Ylq!Fpo z9K?t@7-^&_O)-Ut5yu!p2qADGwEhxi^fdZ4YTeVR@fd$~VzK2=(HrC4o?PgGpw^NY6RAtPbU1t%*y|2Bc<+CHc zo;@$De{RzoK)5>GZn8EN^Fm8)0eF=A4TX^Q6EJ8CaPz79l?m3VP`@(O7r(E$FxN4( z)#EZj1x;#a4kV<0InXoWHphV%yiR|2y*h?Y#Lyp3NBkRqBD5D3d=1~gU&3Ppe~~}W z*W-GQKa1xL_~j`m#8&cEd@ZguxGHFJu*h{`HVL&u0&OPKnP3LgLB_`+q|OyT6SpOU zk;M7}_ZB{j$&%T`B>eJs{DNhMCr(cknnwnOFj!J%yXpHSL%-MCWGnDJ;a&Ei}6 zR(W($ZEX=|WmIa*SpWI;^lRI|unL7vcTwKn_xc9*N+;OC&0KR?*uN{aFq6x`}+cpt-jzrl5D0cIu( z6lx=HXfR%7dRTXXBdix|yxCES@_(wV>cfi>VJAvHIvj ziUncuj|$W`C5Y^hyfam>=I09zzaJ57GGkqJ+RmJU;Y z9w0GF$1x|Braxo%r?P~hLuC&NiSw}?!mq>l)9)I_zjl-V({mNFPPMM`2Hk8^AN~sr}#}w*02X zgCEqsyX*DsufM*%q2a^#Yv0{n`yU@RH0<78{Vr1#g=t&#XgyJn{jzLc@hnIwXWc!o zY*8Mtlk_N0l1#~2Ts-$DWk3H_S?S#3;-yO;`ZTd2;0}M3@HI3SHJmLU`*am zkpXCKGE!;y{o5fIh$4UOg>-9;`4bX&Z2zmAJwLedGj`I+^=#uhU|Se zO70Zaz7m8@j|$GiW3p0m3O_zuRXBcIkF)OMuITO-EO;bsc46v&vCm=NI=l)<8X~g= zZk~euB84r$UiIwk**kYGEYH^RAu@PD$qv2{tkv>Cf90F%Hg23ZZ#q_j*CelOm(tu> z*q*nsSe%sz`rt%mzsug$Vl9VKUuE6p7Dr-Br^6MK=;bMskSo{N3BN)gDyR<&uGokD z)CXuMuFwaY${a)c;79DfVSSjaBFp;VZa^}IFdRr`dkGx=2m4@NwDd@)BY6qr$6odb zC;SYUp*CpZ`vz!1&N4r9|l%%*{Md6q3yEQ8pet4~mXCdb2ex)ELt z54MvwE1{0jEP>d%6#E5vRlGiFJl4SedDC%YN1XF1S?ERhGmC-$NBsB}sfeD6awG^b ziOj%%sa+LQ(w)*%#(DC8Z_i1-?Q$6sCW;h89J?4FpAZk(jp)0}<54|X#JckX8E$U& zB2pDdWc(eQ?&dC@{DPZ3%eR2lEa3Tj+`+v}AOnL&veD*Uhw&rggRJyGl-z4g^R9&1 znd$g(ThD>6kd!IhdJOhDihDt=^BoCp)?sS(wYEO`sLC@A=-~wK;;pgoGa3RFD*kA!!T4fPBISVQ`lZ@Q1}td^~1=*G<#= z0q(EwA`D(grWu%ijAkIW8oiL&edq<6kC?w@i^o%3Ttl4@{kFC?74{x0MSE{zq5{$I zw9xpIF!whxBfoDv#(y2g4>}+#c!c&p4_lDMQw(}Q1U<08BVr$@PytqV4%^4)2Vc-; z2sNxGN1G9RfzN0A)TkQf-aBvJUN@`B-ncP)@POfNV|z5kVy`sF1cf;~aK|KKK_pR- zNA$Z4f&sj$2j)!JMx%O}EtrxVw6R{{NHd8|dhxYh4F*$0N&eqIf~lAT(q!L=*-ykA zBw-F{_oY1#-h81`pC8E2VLt5u&VL`vH}*g8Falu67D)7&JcJnFv#X%kW3#z{=c?hG zqE5_RnK~HUABETukvEi1(059&PAur#rPrVs0pTLMpepN>305Xvy;dwSW5KC%R(LUH(PG4T zN`}R$**GqFb}I2PGS)nw67Av9Q@ks!Lf!FRq4#(lHfMbug}QeLMn|JX)n) zz~B(P*1`3SR%zAKevn1`ffw1Zh1&FJ*d7bf>9zPoZ656O@Xmv1GnkQR3)&JhfsyO4?!9i6?-O#Em!}5jYVdd4=gHAna4t_} zUK~8ggutr~WN9U=mLt&;jBXag@VXYJT?eYvwTjr;fP}YV^yG$4?^=5girY8cLw7Z(1 zEh`e{&FjsACOK2Fovq!nkp|7OL2*F3_>KD(-p*9EIV2jORD#V=fIKBGoHIFE$$|NI z4D66r^HI;M&kJB))mR6#Yv+T4$v(pAgxKyvP(X??2SN_QE=8@3ght+J)BIO zEuVgI#;;L^;jUgg>$L$TxkBA7C*MXLCPcxH2Ns8^=l>2b{VbeUYS=F6p3GS2N&i`1 zT0l<(^n~KPg{3Ma^uWmJ1$zRWm_tjEq?ojI`mZQO(e3odWhIB*FXn3ZyLzdwz~_85 zUaO)q7&oIh3u3vwNQV7S^IDhB)J1*|QVWC6(PbQAo(~%l-T!8(uZACAy>C~& z->?x3E9C_4(y2$;%}8%ZXMri9$``lYr<$hLt*M>52=N!)tddW~^9JaNc|{ox7+zKZ zb4^u9NUsM&$(QU>A-`lulZklt0YnS}hDZvtdQEjrzUI0b1laU5L}Uuh1NplUM$oDt z?N$t0wfKq?s$9iwRjPRrtIJrFQ3u6!J~UWxjMwV5xiJ2y1cFQ!q(vL(Wy2yw`Po$i zg9%~jE@(%VLr*MA2$zk};}$#OZNMg8!Z&^-b@P{7Y8qSW8)}<;s)b@r^|R^!Rm?!lHGRF`qwSCFsJPD@KA)#6j9 zVk*!;jj{~(AaK)7Lp!v)#0{B8q9bg8sDROA2S3s3*xNFCiGgeg{smesmXM2q&4s{q zu2!UX8a*iFP+hBe##q_Q+9niKndtQhDMxO=yCB{*rZni^=`9lF5|9284>w4;bk%Ln z3Vy=g2J=r1l4T3ORpkkD(Kau`X$_Yv00~`z8BOp{m;wMxkpJ{YH`|3JH~@)K(~%T? zF(RX)Fy)q``nSdo8iN+cqDA6a?HFTJ2%ZH6?%*F~zy~^uGkk>C0P9NL)a2#{u%J9h z3m%4@whm`)4bJWx(A4RUPCS2ntB7a2BTB`zLq0FuQZMtKGe(;PR~jYJXVfO~$pU5r zsq5IsTCU!zJ9tKR^ARd$Cx=zCHqFJ_^f~glc^XK#!>T@4LfVF#p#VZ#G0`LO{Fi|n z@eKC_JWmt;hUXCutQ(rm321c!T1`Q#VLi0!_+;C*ZJ)3S_uO;Ogc&TIKH^PzFc*f9S( zLU8!N-rqYMx=D2vdRp#*yM&p+kMaz1m5#vj@eW$I;x~c30?cNM)l8}1hyG^h z)NVzuDLV9Tr1c+I)9=hjWPrV}MsBktAh8VrfpBo}9y zE{1I10?PxmiOz|zjz%mLol;>FpoEumLi)!CdF3%UrvX%3#R>eASF&KTKgS*!Lo}ZL z$GOZ<;z8~E+P%UntRx5I$?w=|R+0q*ZL3g{r2jZadr>FrM(X)}?0`z0KOJE8mDXkL<^HsX`FH(_aTkSQ1sp36n* z@#8wlBAf6QR2mdMK_#Bvq0dK-ettS2TB5H*Sm%V1X5QE7I|^+ORPlJIWU9zQ=aE6R*QY*XwqHNZoiV}TG553_*t@^E+bffP zkUR;Qtn0n77a1NV4nWrd=+a&v)}9F5Bw(A+v7ea7jzbVDu-Kn&gT1AIfNzIU))p_j{k7G?RRw`S_9JCcXd1qGh< zt(Ro{t$4kftXqEv>p1%1&v>^%*tO$jb)6WOoC4p|6V1)%y=zT<=Yqk=7+8aE->Je~K8e{MH^6z{1e(+^?bnHa@-qw7iOBKf?Cr21|0r`MQK43Bv zFrg@UHv%T&p4qeaToW*2OG{bVe*zsx6c@nD48lj;I`1kFVmorQ7}{vruFIfgS+r>O z?Eey^o*fD)r09-`xeQ#-4h5G;e$-chnSzDz72#H0SXg~+xUFCBa{aS#+kF33;Fb%Y z!n>{pH?!I2`yYT?SC`rRpTKR>B&YK$!A++#u(qwhx3C8>_81fIYEkspxXG|FN8(48 z%B_Z*uq4Yw`-FD{7qHX>;zYtu3ooFq7H{|yOkCq8dvn-kmdiGCtB_g?p~iB0fq|;F z71HOe_OOj*JaC@QO0roZxq>d$rQ2n*gW4G_MmPgMdB`e`LMJd$MO4hVxNI$+jp1X2 zF_ihtt#O=A@H$G(H~I=0X(yYg%~Mq|UTfue8Hg4;@q!f88eYVc!C1VE)=qNc+`Jb( zp!^+le%y^7Ovb9y2ZSzowJvRL_`~v{A7p$e9rlZij)K-)fbOh8x61HZfmiyxGW1&E zg=}3P!4e$Ud%_=<4*jqgA9fG>MaDQ)(9wXvTtMPVuccmIoBAD)v#A0sK1In~0JFFv z%?A&Uo`H;kvVqC?9dlqx?MN+2&CRE2!SpP^qXl+KYHq+aU>)!eSXmcZamqPDm*A)C zX-qHv@?ps?vGtk{n{%?ZXp~P%*1yLqA%H}mRdQOf=A(oaVH~We;Y44f^$bY#i_^;J z1+QL=qEgNUd7gkh-A9f_fi|y@!0;5ud|p7Y6j0lYhd$W#`ib#>Fi(`%{%4q{8JMR+ z^k@yA_%DXh^K$85CbAY$mzy&gseBR=5bq>L zjl@&T;3ttjskAbuM6*+Wfj!M%PO<1IxhNJB(}6lZy}1*R$*a=7ICxPD}js>G3NLwQq83_wl_D?A&Kv zv8nwKefvN*D31dSsdGSUfLtK50dHY%0H?iISC44<^khFX$4*F28f{^HCyuF+6l~Xy zY(f-u_mWR*Arymh#{&`zlA+CVB0&Pjt^pMWi)y$p4Ztn-Jo2!JmPnW@lJTSjOHe$~ zC$b5pPjDnwn6_HL?TD5XULB+k?!a8%jkzZ3U<&4XwPkP;uQa7kUvt`GFPXN%iMi4= zJw1FHhJPAy>7@J*Ov2`;uLbNkWydAp{m;NzWzbl;K+#-4u@q3G`0w8U6f4*-vO!zF z!dBXTeka=r>E3Mi#?$0l^ds#-wpM)_UP98^DpvH10=?KOwg}|xBDkKu!k&_TQN*g& zsufJhh8IM>cE3$|RlDy|=6RLReJq>(7Q(zu>@nPfY0_hJwcpAGda)mBk7;H+sLBr| z`M28K$5hb8Ldx_-g=`Bd9fVijLA-9(-!~(eLp9rCUNk-B+1qkao$S+f!w)#sjwXg=U~#uvsrdmC`u9xHh^@;@=4PEzTAD1U zsVl@3mXe~d6ud(Qfx`+rj98gE#7Krd9c>eJLe@PbbBeU-YHec4xFFv?*nuPPgS5ib z6&(t91FzzOl{6DOwUH9eVse2azp+P z-0bf#pVy$4qkdab%+Vd4F_w||j;qE9EQfnejvjU5%x8KzV=UjnSiXa?q=jZb0b?N# zYm9>abml6A2 zO()t>Ni!q|?*JnE0Fk4B$S%z84nQR1>xdlyC5H(@9RdkV-1QfHLFx|!RzgS@0)8Fp zAySG!Kg4{>bw_4^`ES^{6OIPsyX>)5vG%U6@tHe!HuO%IabyjwTBJ27LT^T_sVZ4o zGUcNwB}=DNeU!PgYn=6XQ*~}`3=%^n?oN#H-yPK(bbS48 z*vELyWz+w@`|s1s$X~6DehTIvUtgWerhN?^rul@zYVZy94Ij{Z{Rim65Fx=NLJA|| z4{rp)ad^-6?R#3cx9-97d8aE!x6X!Iif>(?4TsyU+Cp*tR(gNGhTkGxF6a5f+g;A> ztuALCzMHC-!7JbTe6}`~xwPW13DKF~ng8&L70)+z27{fo!P?GX9!A&IMCPnv#l@51};MR?*T^j~SGrr#-DOU20L zkH7f#zWUbwK-<2zH!P<<(suotNF-r}WHKXX+;YimK^zKI>IZSw|G4q8O1_1xec`)L z2^u4$6S@&_x&HhF5Sj4` zDM0;$?8zhbUtkydRK5FV6b`*xrHmFVwy2S#qN5QBj3Sg% zbp$iwVv&rQ@^F%Nf<5D5Kl8Gm;n~eTR;8R8=6(lE*|&rmR+FWD3%nC zZq*CL4&aZ>a4<#+V6=!?Vfxh1`aV0Xnn3#Y@*qxilDd*ao9yvOD=`|ajYey#(HyuJ z1&_g2tzaqK;g&NMQjiX5pG=`hyi~<|`w-{`=}YIS%h8R9*gzl_jy{ql2ExKnU%+ab zTaNYwdOta&4t7ZI&o9xRh3LA{u$9g6+&Uxoj@h$kfBV+ycV!mL!`~Fg zg#&wMeeWCQ;PC?o4%~Ckec%12EvW!*Aw_oju zZO5xG;IFZ}|K@2s-uPQ*rvuXEO`A4teYgAAAMwM6${l-?r%#{mM8%@i@==mC>DKh? z;^JbRcHcWNlHRzdwvDoHHY?GMjVF*{Fq<{(dTVcOZ9^ZDiK=4y`t(HXkz*2DT24tZ zuG_wSd!f4k0U>_;tECVBw4@YXfiFUBvWk_93+DKIit}V6jN{{yGtzIKHg&oyCh`Q_ zf0=b94+853kO1xp*0anKKmY@2fQ|6xS+b@3`nUP#1T=B_twFO$F@h-J@c`mqM~<>Z z+0EvGUc{>EBX4)XYHMvh)hF1Z?TE+0gWdfqi^>uo>G#W7$XfWgg3OFiSbMM|Kf%sF z!R*T{NKzLFnC&Mi*PI#odV$hd;Wm@xiuWY-o#^nNgTKNBtJ6W^7W6zSCf33HJ%ZNb zZ{?CDMFsz40TG3zi}ZEpJ;sjC&_g^pKv zYpcTI=@ZNp6z*~`anFKtgz7WM4mis7?0e4G_uM&k@fZ?DJAn`?O5C~(n;JsJj zh=j?dvd3kk4~Dsg{@zO>=NuR#=;n;l8hnz`Rzz#7jm5|Jves5FKH=nI2wA{fE_|Z( zOB7y?i!nF)F$wF1;&w&ZiI=4lGYW^NBu%TYp9a$1?Ey&mr{e(>k-maPO$QYFRPUTT z!eLYsU~(dYY~bt;H~WV$^G~?BtQaxvQvtyH_}Y)%+703#XZ}g{aP0=@ceu7T3!def zBr>lPrX`ky0o#ZyR)1no#(gKvdf-J_R$e?{NlSBlT8-?>)yGDp9w+#F8bjb-6HW?<3JeK#I-vD+KNamRs z_68*k9PFyRxXT{N!@$A4hr&cy`*BMaJj;M4VTfcCM6`ImWlFA&UjGRsatRWM%DR`k z)aMO&JkH|RIQ!4Ex3;#P>;?oz#KtE&g6i|e_#el>ox=xyq}!^l89MC8ja~jmjC*Ei z++HbF8;0){QK7DHsU!NY0^CqUK$QviV7ysLPG!$!BHfJ8tlD$Z{N6TStw zS}QF27&CvLmML?Wix7%1`Ue08%Vv~B;8kH!Do`(;PuXHNW*=&%CqatnM+L_FV)Vbw z3?an710i%YnVZF3Y_GbKK#XI4g#$U-N0?aunUerS`sbtfD;$A#I0k~zBdku_g2=sF^t_X)1xDv-C|Z-D6~N45fS?-m z(THhsU5lHo5+1I57%yVWmMs`2>B}%08UzX5T3fMm(HGQpj36;FkwJqN8bd0^;Kq!M z#~8wN&d7p-+S=_UCEGJH;PQ+oq;iClJ!#M|9~K%0{i}TC%6xeF&Sq{H%)Ef-diXb! zVVq+{Ro0tz?Vu%E9urUWXsOjCCG6CnYg|NC4FncnWL_=z%rXP?y)?(<-ehxhhk0qSSo#eQDW z$HD#?dR$3eb+KQtd|Gv}PcS50rT1q7`ZMvW{o$K84}%}nf{IuO2wvjzVWK&MK`to>?gvUT2BcULF05eUA z1!Z+r1jvI#NlFBnQt@e74!y*ys#8gYZj`hm_1_``9#; zyuSpt%P5(`XQM+1?j)83OM;O0p~sI1&CPrB5j^scws&w9tP-WZJ_$6Mz5-T>h#?oP z@Ms%NK7y=H&7TNGIFVoT?3DVOKX=SurtBMMDh2czPcnQQxC9)Cu zqlVScBGm(10*V_-8Lvx27!a5+!9i21i_6T61Mr-z%hA*0pa(v+vAFiQxOSM)c7?Hy zJUf!nub~tv&&&ieqbC?{nPLMz7w+0sSX2c=8okTti~!?@62wQyf=IeXM|>If1_-=K z=vIfV!<0rnsKYn7>Zm7OY-ms781;gB6YdG^X_L_t!m=yvX)@a|6NhOHL}hIVL`JU} zGL}Vkwj$IN4BP&AO(FJ9A?3j~;2=+V5PP0mE0MF&<#uhF1own>j6LdREv82sdwUx( z$Jpm2IdR5}M0K458bDG2!HJ03dwcEprcG#T2?kpz3RaiH(FIwWzAnN&PPj^s`381b zk0Vk$IyR?wbZnb4yvKz#m-ZOFs$`Yo!fKY_Mzr`?hSX%{rlz>*)8neMa56OU>Umj= z;uy?B7p=h{%z~}R;uo}bgPvO_o8iL~9o>VJMrJ7~Neb=466V{)hRf4g5yfkmqlSd) z`q;i|xgyLO*&#g+7*KwI`>{8Sie_U4Vyz$FjhnqB2YNl&9Ib;L0sWWoGocguVTA}#-`Sc$nCKHe3S$r

    t6++Vazknuit7wTrWXcf{qQ@GbnA#`1dIMgm_xy!G zP)SAXOfv*laDE5>sSR8>-;3y==lc-@1yOfx;He|b!oaz+-Dg$Bq7A^H>3rXSY5`*v zfnP+`I?#W*Eis?!Z87XPJ&3sV*wv%g4LQ(Zs2+W z@aAinXR=&!VV+4RFcy)Ehy5K|<%jrTj(^pmJjA>(LRwh0pO6)k9vNMHJLy;fMW@v- zvEW$J+k|)EJcpVwW#i|4uq68>!Y%wV7e~}SFk`snNZdQV_0O>4`*Umjk1$<+1kRYu zlQE(9hpsH1j2Ij=m3~YlUCCM+PebhEjLJdkde9~j-w@*k(nP9(Q z>S=~~k|h%Hdd0qT=Ptl}2{wW@Dc~o|41YkfIn>`8&@iDp7OWyrZg?0L>b$r}MO0o4 z6ak2OyyYyzTVBp=-r+UK?tQR^4K-LFfq-HOOhKJ!JoNQ<#TM*TzFsfS+ELORdJL;E ztc6;tfpFkP3z;b2ipQ|>!^Y4@BH?xz~IPz%FjB3uR`2bD$a z8-h@G=VsgKRO9&I-I?=hr3tD$hDsk9EDe|ryYsM-PNA|OJ*Y3u zxGRm8W^GuFVSQ;v4IFg_EOBqDF|72k`%~#KB=ZP8O@b^=^PDWu@3cvL+(#)3@<+nGMUr@ z_%4EcJW3JEB4w=wgIZ%@BAGl_XRBB_N(MDgW2Gx{@j$&A^dZWn>*eEUyc@%_h8mZa9tNGs`rQ`{_MKX|Y~>ECv4rj)+N;7dkaQ_L zht=qy8ll~x6(!U0xb_;;*Knu?LDY`NWwRU}wZ5NBqBhQ{729@7pU#g4PvlPz)@dLN#_9HR%2|cpQe4(p2`o-9`#@F(*Lj;1SdM3^!cXUj5rm76UK~IE^A>JT=m@#nrbRfGe?iBu4=sn zeH~R8HNqz*Vee&q8r(NrdY{VlHfYQQCwdI4L1P#^V*@m91J5x88pYMiCQ{js5KJ#G zJ8ZPn6K0$YtN}fseUH}Bu)ANi2Em3-h?K8fgCI%wzYHs`+6L7iy6CI-D%{3pHNu#r z&)SfYhgQR7vpj4DhLs-4099gW0NXYldG#?pP5blIZwB zdl&5-SL}&CQhndvIoOlS`#o%=U9>BOco4!pI@RfM#rx~n@c$d-9EPDjN}|@7{o*LE zeIDx&zc$rOcMq>*o znMOc;x#Br6xbOV;sphMWSI41Csb+#_5*~8+{GgQ^hLB!kDAgRM0g)G_vA5Bv zueiR3wV_kZp&Ha9!V9V?U$s{=2seh%&2(51eq2@~d}{L9R3o&jU>umYYva;1DvyA1 zbj(sooB{0GD?(p!{~66ZY}`7{Z0uWl?`b!>3_pg|xDwTT?HRw6YNpw^tc_voRHvE^ z*aAw_r^{LxR(?3uO!vO_x~8*l2+gebhFXy?o$bN7(@)C~)eO8quddy~m1t()HCrJ1 zi&PRc+eQml9P{8V@V`MZ6HExNue}n6P>!Ii{vX8*D)3q~aGQ=kVH%ZaziX9_(@SF# zb?4>C}!(Wia86Tr?^{5paX6I({I)i0^1_ZtlFUU`@f?rP&A`vxcn|eps+Z_2{}R%kt&RU#M>Q_!Oe-7#hW&o7Oj& zkvl>aSFW5hM_1cfm+uf@vMuab4zql1Ik@DMkj%ai-ce9$TNRI<2S`tyww*mIE-aoN zgY0}pAfMMw3yafWvj*di!FYP35W;wp;QQc3Mc%ym)wdgc!SODay1_F#F0Qk)^~>(w z^UTEB+P?hqRBsS|@#^DJA1s6WyrS0EGqB7P(bVK}C5|2Cj1-j!boRO!r==gEFg6&F zw7HD<6DGieBH|K-0R57{i2y)N-v zv^R(MDOu=Yd(aTNk9dBUM-{$QQ-`>7iWk-(ir4rvdX?%jEC(n`6~zc7Yh2yJ(J%&K zJx+6Qu4)4wWxTLn;e}OXsWzls0iVoDcm^tW!Nrh43scX%a}>UE5rR}HVusI` zLE%hf8P8&7TwEqiyKV!CR3m=7-A~Q+Ivns~i5JwTN7{Wp#4!m3oNaB+Kw~4UmleYT z=61}&_W?!1Yx4LeydJr3RW))w20PwaMJ8427A{;xfwr%M2IqPtomwiaVyhL8<z4TU)lF(dYO3gj)&V`Pjz?z`4JN0EpM^ci_)@rpzm;>D>T3b~QnV3srg=e(M?u?F0 zNJwaFv)f&Ojm;SY6GU}`O#9c9=*&yNkXe8WMK6d@}<;d@Z8PU7+00RZijJW=e_mrbl zLY9lktcKMHD_1f%Pf%ESHFo(M4>yZ{rn`3zo=`6nd)3#@_;lr4# z&5@?Ye!6W{E^=B;)~|B9~1oy1~;m-za| zM)N3-6hEf@+081PbRq(Q3y9nnxM}`x$k-F<~zrNr8el6KEzYo-S*|KPS7jD*z&2f+7k%V){+L8FN>$uOiIR|C~bd{Q4 ztvxy(iebeJy>Km`@~;%T#6Y#%6%JE!F)lq>@|s+(@n8SZBl&3iT?Pj!Ts7=D{s<6e zoxX`x!OrK2F-v|rd&Z0zQ>VgRJ+iC$gYA`-mHUny`O~Uw@~P1tk)C?H$?`RI_f)5I zbX>H}Y$C0@WHyh)J`g_=p_JhK8$_H3;7y?a%$IF#a8of^PzZK2-974VRTx0J$PoiL z)VhuxJJx!pw~yk`D3J(5)61;Rap)xs=}aaMTuRIoZ+^GFGtkLr$Br4sp23qZzXz#f z^@B@GWs8yEm%@z!he)l2@LmR8WCj+I%x>t(gM(*UMai{oZEfcyyESq| z9CIn6-QN6E4&18f`Zvq=LnkL98*)Q7HjGME3FAmPs-gMFU+WK^lFT?K#0ZtuX2as6 zo4qdN+CR)iEth`%ACZ@IbY#&Y5Nm1{FE)siciFl~WK)=zpAy$|U=L1cURs)m9rpul zM|AyBoHwO^YrgJ@w*;1-l+h;+*8a&+n5qkj8R@YWw3;wWymqwkPwkq28(|?ihzuoL9Ik&ns$OH+0~y=oQ)Yn zvQQbb3Ih}bJ_(woQwQt+dZf7l)2PtTmF%#kp`_&Qi6;+j&p~QQecFYmn(b<2(f4Ov zALu-|6H5*Bw!U&Q+JKZ#hKirUvCM8)`n~#+;}a4#^WfRm4N0f zvFRC!7m!&D^QRcunc^^~x@)PpwSUUIJod-Xyng^3C`J0Ud>oL|^@&Qrgni%qZA-1IjBn!qJ-tkpU6U{)L%!}eDpb4 zwS4)HhTpDOwKD&kLc@kU-Sa?qcG2#&Rn+|9i<_rTMZS%v6zgVxdnfV&4QL7<81P6V z#>K_moeg7fT>POa3O@jIYnTJ#Bw8drv(xR~tQy3^E*!G!Z42g11<8|eV|MX<*&rHr z<4mY}J+62rOxI3@?Q+;T_N;ZmJ?6UldZJMfw#`yxXUIAw2_8`R9%-DjscAzFVFRvT ziH9UMEf*20$k4f#JtxgCX=^J|WnuG%aQf-Q^#?kflYflF6Z74vscsw*dCAU>!*2qw zwp8tEZuV|V>5<@kC|N9ck>I?~C8Rfxb|of`iIRlA&bIb;q|1iwBr;+n6oCR)25ile z2Ov&)P32w#fMLuJPkWIRgQ^x=o*xwV0FN zV_oH8PQH&hq4V6f0-Vs%UE7{swQ5pp^|o|%B8k@7 z?$e!JXHK0&ns4x^L3o-n6kCyq|!4moe$!kGVnb#WiY@J*}>VnVsMlE{I{NVYV?QF-{|qsQ7V zIL-aNou3^zP=GCe1b&FbWk;gSSfobZ@z?r4zqf~d2VZo;J-8pHoE)jt+JmjZqrv8& z4}L0<@bGwFcjS9Zcy?pe9YE-}fY#MmlUqPFR_fO)Y!ioBBzrK2?T3@R#vSaK!rm)F z4zGK(+kzhlx3UhcDtH*dJ+iSC6_B5aaq&RV%L_BIkxP6#uXHZWn0)h1>9>46|LapG zr{7vy`tV#3!IfAh+dwJoL6L39%=Ih&01VRa#Zt-OmAsMvgSYZ-!6w*w2mc(G57%*C zCA$SDya8R>Tw#t>mlZ4m=^gDqu=}OlQ10hN+9H{}oF5>A$<;`4wG=Lk!uu~d1GJw=UsE%Y*R#A^MU=lu&Y)g)Z?Srz?Q;Shrc}4mC(`IotTh# z{kZtCV5P>yk+*j+!IhMn1{%5N%i~8ss!i#xZ~WxgXITENt$_j1Kgu&K_;Pf!500L@ zeG>2O=>(DZWgAwFX-wRh*q9b&`#{@#EnM8(ICjgMdU41%FBE#$2*54iNN zz@_QHC6X?D6S(B4t2=lUt@w^L)P4xB|18=t#D9%Bu%-ZHS=dl@smJQNMq`CksfKJ*x2}fF1QTi z1b$fjEWL3|HoS4b%)lZaWmQ&5!2h-M@~76qelY5rYl8_j){pB&1Rcx^5k2`+lAm+2q*%9RuoBQX0gA| zY{KwkM`=h`=|9ub%eb{qN=Qq#+mjJZ*tN6s_e4t(EBRgc z13o-z|Dgc(!*j=Xw%+``;(MZYwY;!(FXb0V)ykx{$&=Zu3gUF8PP!oprFQS$-Q!*o z;xWt!0dO)HGg6gW_q_A^T7-X*#b9UM=3Jm;XnBrU+t{0koN3Nh1j|lHaKi1n)HyGY zy`Xa`FCor>VlSRLwW#y;?Z5xjSvu972iJwa>Ez!B6m_Tg(GbZq>Y*PmSrpfZgwe;X zxfA?At7ta_6ng;wQeK8&u>mo?stPl_9=#ox8sq;ABp!^J`|8$`qX#ZC!Uvq~mCUMb z+~m6!FI~*e*z(Hq!0Hq8K-X)+4=4LVVZ9`0334POHL4R-75q-nr@ibs+tPW{AtH6V z-6gP@U#qhoJIvFjO|v%deR?*~gsxvBM8!O8TY1_y!7ImO|CkDa(fml2R%=!LvB0>5 zgaST=+whozy&7ydpUkJI?|PI>O@RG3ZTj8aXM?s;W8>nmJ^@T7{&9z~uy6;m}h^ z^xIj3A|t|qXzzlc1xW{CVzN9;EVH-}pB(GrY>aDoMspKle<+UM?biST})nD)WTC z1)af)5yiHL!S|KbdMtEY(y@tnpREdOef&wVK+J^~eTC4;eyQb!EM(vWg{XNuOCNr& zPegBSKySuiJ&{zG@(Dv)OM*>$uwH~666KW{71@~kO>C0l=5CKWSW6<^aG^Zbr?mo| znzdcb!w>9tvmHn~G{xiQD~Y2v$?~*mGK8rzllg%I_=ddJg=rZoKTzlOa3qE1a07#D zzO;Kcp+au16!K(Wg|RFHoU_ooEcEUc^loBIOkG_?MOj%~TwNW#&(6tq-B zVjP=o=3qYLdz%3Ejr!#gr~94t`G~Sb+(!wvkrIeQg?>0&sHT>d=H>+pbfMyPSb)v+ zxozJ@1XiecX7@$wfyZBnq&I4z=DD)*9Dv3&cVs{{oq@{x5O1Iwm^G53A9*H5tEOd@O!N0 zNRxk=$A1+2Bb^0v&8xN~PebOg90&(>`EaiOnIh#EIODe1bH$SBq2sVn<0zx1a z^CkK^m3-jHfsoAjgV5&>hI}R* zTE?b$gwe^PJ!}eGeG%?W*Fc$@-ob)>=L#Q$rfMLwehLdutPjg1_}Xf9O9XOscC{b& zwRdzWv0W$sajf%17qfQth*9PfJUS-X#`<~@^v0g;*wLTYe_2SR?)G-L~NkKk+$;qRT4Yn1Ft`#bgQOVhq@?E=4*v-I?e8A)A zVjl{#*zPQFSS>P6L^o^UE>{j~(Hg>G+Q0-6dp!R2nP?A0;mpv2K8CgO)qxZeP zAKe}Zv`ewE5`t6-#M49KgTq%D5tPQHrrj{c9K6u_@!_K<`&Gzw5ET?U9nm8pic^2U zgJr4O;4h!*Z))-f;9F-3^aTV_Q$~tHpyxAyBCIbOXI6i&&lkS|!rvK~ul1NO8LR4E z%-7=Jf#5-0hj5)lMra#c+l~h7=`uE0EgAIKK(HftSm%T9$7<8J(BLlpYSEl}wqj;T zwDEicqV+8^)ETIQOS2&;!hCJ1={?9U{crpL)S^>!;+LNWlS9|N!Hw9u|AOyzu_r#! z^)$Zg4ow2n#$rQHP{!BQ(TV@fZ%qH@P3dlTT+93W_SODJT}to3K=AP4pgrwt>~?)i z|2?bL4{W`&+7eTRBvtG=>EXwq-YQ{xge4Pk@@!T3#3fm5k5k9i6IA)j-}^#i_$FXPW3iXSBEkWkST6S|!E)(!+R zzO_PwjI``@c(C1kjeacvX>4b;rn|sCIE#J&x5QjrD|kR~8y64YQ!aP0SzzUhAe1)Z9Mbb62wW-4avt8u`qwg?%<%@QpkhZ0h?fk-)Uu;u!Cg4lr%+S}DwT)vgtxY*`2u8sdO*ui zODSP=NTfah$lwz$3ECABvj+g7bp1-kLUlr0wnvu>HtWAOV?%upi>F?n)pC2O?|p2E zdz&*eoA;~>FS&I!zS5bXjNa0VksA3e@ZY7rns5pG+C5ZbFRH%pgCBW0+p50%Lb~6N z_-=aqWN@rDp`Vn2hy;Zs(#TYT5W8lC3K^f|JN`xM7wsL&4IO8LAd7_Fc2^AVPY`IC z`Z@z5mQqg#6FS;_t-jBFspAu{K@NDpr0~Fi2fT)Y{naatNJW%24^OpAoM|=a`GJ-borf3F}>G+OsDI>~1o6H5c-73@rH-vN zhsVsCHEZ3vbxO_WO-=Bj4(`yeQ&3zKY5yv|SX)~=ld9nwk8f14e)F&>dlge=W=l&Z zLRbaL0%Za%GvP$FapFD{T1rdw6Sn$Go@ZJ~R~68Bi}DmRs8 z>693;>U9d_Sl+1i{Z*UR0a+kUsNN6`uU0fBeXF(XheAnK_NLA366DR zx+u9O0Ud+=I)(1BP!J^e)r@TG_~Jy5Xk{_M zo>QmK`!8r*T@eMu#9i<=(1$qfUXDaGuy}Bdb=o`@Xdp%+LV)OfNynT!0Eb+_fgxPP`mC^~-M zb`xwu8X6i}piMljsn!xHVQGfTg`q?B_mew|?!0$NYN{*uu^eONGcPX&E^JVu>gw!v z2@!Ds%BiViJyuA_GLsYR*ns)crCB&5>Um6z{%VDesi63W3l_klfZ~a)H2u1y$ekRc zz62ptFMjh})%Tcy2A)+#O69-@E6D0w_!uhOS>g=!^Fezl+GmU-aMhZlz_OYKpV( zsgqzKzlgtuswIk4Sonk6$9qhmRHgIhf#hx&G|dDo27z)T$elVKlZt>V z!jghU&@_FT&EYOdB z-sQ{EinRh&C@%ha9^@uay z|CmYxyAt{;NdCVz!ftm)3Vr^5(X3ed0-UuR`}~aJaEx=g#*cMct%&N?=ZuAF6%;k8 zR6Tm^J^{=sJ_dtNrgU_iIeVtFvol~31SradN$J-k#mvB|W5+%{_IY<#V-q+EA2j6< z{;$2r?>x#FE5JM!VIHT_K6m`{4iF9TaXBI7e$n;6Z;hC_5P$b&METo&Er;3YIBQqi zq2H~--=;b&bsW|+3ij+NE`H=TuR;*DTgcTL?5 zyBz0xyyAm-qqxEw8*{;S1lRxswa>&XE)pOpuJ69?mW1HGZ8dwg{PE=EqM1NqQl}c% zHde0h3yLu6hE!d3Aa32dJsDGsvz4yx;+XBl=VxNl(n87#8-%%&#q>B66eAHg6>opX z=hX#EBP+j%nLOEUH=le5GKTjqBux9>o!})ZL1*m5<8`(L@ArWO{0r=A4AoAR^pj}` zry-JGsy+c>z$=n1BEk`?B*n!g*t*+0J5CSSgSP8#`ugSpzY}2 z8~=W|so4za0#KBh?Ooj$f~p5WZ^1deV$7!n>yjkD!>n~-2znUuQa9T!vqBP_&VijW zUH~UD)g@Uf*-|b+-KSCa4&cIFAzT|)U)=OgGj`eIpPL)n`oRW|OHRHwTVK!H zq{X8e9DDL`XxxpUcg5Q6FjJ`5+Y_ZC0~*%<(h)c?wr}ut^z*w#pR;eF?wBCpGwfFDD##FD!`Pf5WfRtz(c8`~!lUVqphqAyx zJB7^g7LVBeQEhE5!ao}ZfWPAB+_!^_=WGBJkQ1a@8VL4-OyOg@)R`C~BH;nC=V?FH zeu>CJt6r!%7dr#%erE_T_Og{A_(+{-$flmN{>zM5?MTh;jS$o<0h{?fsLs;V*PTM^ z3B;GdD(yHe2>yOpO2l&5#6iU}K8Ar<|M)|n^>kb3Ic`!tR*SVCjD>l8l7e~0bYs~g zaO(vnBHm>edbQJieFI)OH6b2~iTHS@W7PObHnaa!$Emaa-rjaZ>}?6!Cf$^FQ~IPS zHztiX4XEXa=ZGz2(?yJlbQ#irqKe2~Mi#8B%Fsabwxw>3$-0ePdAW?_zvUO}g(dSB ztuuF1Jy|GaOGz>>Bkdr)5O&=O?D_$)>jq#KS?Z2MI~3YsD#Yb*NwRh9T>}Pg-FqNI z^sg-)%r$lD*EsoQ%Q#vTSvS*{2krC`KJpSf{VYsBBF@|0tcJVtb206PX6OYm-<6!4 zMVzh0Xp1ro_8}y_#9)8WZrhfdn|rh1+y6W|tCPYJAUob_ z^pOru-5B2<9WQire9_v~)2m5XrGeJgFTQB+A)_31nbZ%fi2lb7%YE6_)WlF}T#VB$ zdC7D?F~%7ID@S#s4ll9|xKxKD^CpHR1_<*KV0YVa?Z;K<+eJj*^0?vjt=)CeFJP#Z z6oUirA~39^FJT#|M$m`JEh&B^dcr$n{^z29|AP4>3gBCq&&ili)4mTo5N$jsbWkoG zvv0%$_**>hp1Fu9ogUx20)Man8A?86bTQdTYqcjV{CZEy#}5BoXdYf;uqd#2*qu10 zMJdVx-Nf8m8E_+8XG_|gkIwxDc(>XB>;9s?zVm|go4nA;KXiV&BPtFT-O z!D+Dl>sc<0yYC^a!*#1R8H4h$KT%A*-05SD<3M=k15oHd9COEhV9Ndu+GbwXMO{_c zd?_Eu=J?{ zRl~nm#}tw*FTzZaWO*WHVj^Y&$ z^-guDTxxVSrVWyLEVg201T>I+z~A%1Xq%>i@(5Y;iqAJke>;bHa46zZq%J{d>r#1J zTOqAItqpqNZR`kv(jaTrG!W`3XNoWZo)-Fxr%H!m}DW|%qi zp7(v;=Y9Tsp69_*GJ$1eEqR;-#@7Ik0S1wCI8e})gO(AT5loiem<$4?o2WB}8^R27 z(d=Qt7(L||iHWF2gg+4<3Uy|9*grVv^>iaJ0R>(LP9OW8{IRh83%vA(vJS#NC#L28tn*LRO|L8 zVF!h6S(TQCa2c3KG;rs4NdQ~|&ZjT(K#J9GBIjpy{BD)qo z^&;GB?5su#?^?dRwRO1*cj%2i>4k7_0J=l~C2NIlLFk4_)@0XuJj{f9za8N~FUUPz zkDjhWPk)V`64K~u&=+uXJizVQFxMAg=e`AEt}4(^O$EIMaVR->e+Cdmuv&BL){(H> z%T<6f@XuP6WDb%m9RUv9X_;=hH!T9ri;jz zYl2U3HQ2!*IoO!ht_7FO#=YJSJ4&?8))tO9v9#-A&bHy0z|Lk}U)yZ_0Qu%xpizGf z=b0$NDaXgiPpTA~Ek&wH$K6X^PDAf^o0xOJ@#E%H@lvE?n>sy%D zYRv0g%<<(L-X2*yvNlj0D7K~hpRlW3D^|El z|9?!l?COS2T|$uv1b0u6EOlO~S!+abyWV@sGFy1ZUUg180`qvEGcR5~D zGxIT=hg*waoN`#76F30L040Ns8^q?fv#&FNTGOzvOaI?UL5}(&*Q*VuYa_xi5Md;b z>nFk(k_qGV|AH{;$ijDEdMvgU65e3TB^vR`G@=2Gj5k3<{I4{!<|j0wBHv1>&U20k zWoY;U5lW{_D82uMP+-aO+t;854pmJID)CmSpqZJV8H$^;fMzIeE+cp&G~sq6TFB&E zE7#9LM#O&FNVv_l8CdClnI8c}$R2mHhaEyyZf;et9dSF9Q?h`w=FGv?Q43Ub3|E5% zn~hdfG>e`?%g|(JxlWer5YpP))0*r+766lh@yx;+`Z{QXtc_=_jbi7R&E|Z`Xn;*P zz{hBK<|YJ=9Uy(m(9*d|;c6_(4y~9Oai^Tq@``v#UJ<#tx*Q7whf}P6B%@{p8Ur=5 zKNeZJVfns2uq{wT+DTvsE)v``P!cEzR0pcT8RCe(l|2;Y2UJx#IaSh6uNuL2q`zOh z;RVkx1lJL{@ zzZsOjs{C0C?O!Iu!jRJw8;hNc4@j#o9UGOLh5P45NU?;C>X)NfAtfg3W^CZl zFCjay5**0rAVu{5QCA>YcJy0{j$u>2#p*)eDj@mNH~K(21I6(C9F{*LxHMq1lZ=|d z26!8`Rv92WMBgPq|G)h%wxrN^xhDC$2#{C4cJaG6f({m-zhwO-dmmvr#+NbUx%RI9 zbLTw4gp|g&0f#x|`ljW>4Y-PNd3obuu=xA?h^Km^rsg!#z~8a}_>_Ajvf6QT|GbcG z1(CYh33h~?h64LNjQPvBYv79Qgej;3ShP(LeK*_Ex#jk8dOqX!g$uJ&r%%5&aYm-z z-F>`22!SP98gDQq!k(Nt6X&0mlbsBsRt$wd048dGb$paj1DWkSvX-9nApQ$Qw!=-x z#tCe*9TMhhS!~3kG+tn1<0r<)Mvoa2HFo?&(Ld}Ds z3aGUDugADtfpMYg29!gcEyAA6?L1(`CYplmuth zPqU+S5M3USRAm)4b@K!6Ko6YN36RYeLt=VU5$&XTm zA0;wlVkTO!5kw&EZA9q02nVRab&+f;;JUE%8N?Xb;jxw!LU3UxOOO;j0$Kz9{}V~p ziVv(GO>_L?YSv$JR?26U4jdd#mX3tnEXmF+_y%)JPCfzRnR0gOi~1*L55;E3U9Ov6 z+Utvc8n#OAb<5~S z^10zLQf|s8{~Nu#5Wkzw8txXQqp`lb>>3 zHNIuzYr$JeZCnBdpNuZ-R^nsg=mYVe4k5&f8U?F--`{6a99}B*3s=Js-fzV4o=2Fnymt7YXwP};|GZq@1l1U-0sVPkg zODX?2Vs7@_h>y!FDzZsrgWL46;PuEjZN~i`Re1`$OOSTzZEUIizcb9}luQck+1c%q z22#|>*L54SVV6UgBq~wCT?!=%&9JJft_5b)oRX3pSOd4j?ce`t(}AzsjzG2UI7}9V z&%f?C*4f$p_1E1j1p%{ias|aivnCGimHF26v=joVC&TA*t2KRQQc_Z4T3RALtk`MB zU`C@Y3_L@@oYEL0zzLiBECe-}u#%VCSh0N+{tC%@bHIv#2rLwvgG3*)d%MtMdajb5 zoddfk`5BCMV+evS1%jS*2dFA~kjX zpEBW%*v|CqKZyx%_zO&pdcOAg#nQ!c)Yo`sh=7Aa;N=n)qn zizxIoDz5N%!%+JWEC>r=sRLyc7Iu(|*Czqdg1-39}PQx^ybVb}x_-0DO!ca|T|oIlK#Wv~^z=JIFDT3$aVOhk8ovVLIR!LM+5AUqNN9$dA8shu zcSE949jS&3kD1bgg4&1RM4t~w%p|F-X>lvCyW5zBN|qPpV=W;ygu5_1+wIQIE_6$r zV9g+F7Gy@{*(ylS>4bymG%SM$>4o29K)MHbef$WFy4ahk=nYu~s5gXQRwXB!&FSzg z!%cxFW=8F^y*=ryT=1Gx4;s>gk4kfC2LxCk7h-d+e2iyXIv)d_&}yph>Z)NTtHkA& zQ0bU5b)lG3oS%#iXuSTIfS@1Z-KhMkHwYfT-@^n07-y(I#M?&s)#whw(j@Tq^gyG; z4oJ9a>=1t3y|~NQkbv*}^ct8sowEqI5L^O>a9Xp(B?66I&iCxar9H|U4yFQqkPB`g zUx>V+x6lQJE~2a6WbLw=V8!5a3n>((R$U?{=NISDMFe8}Uct=|>FFZ;9>L&;20+S- zQq7iTc=AtXSbVs7sJx+DUwuTDTICt$F3vEPlS$&^(yX{TVTFa|7h#TV$^^G56WoRg z)?heMoQTtCl;;wS^c=@0*|A{kToO+cjH-+@!H8g2`tlU|@_Y2|6H%c%*!OJZNF%?d#juL<(O>sgf}1JQ`Be1VRW#`(N1 zh^|LYyAOPEuti)^T-V&(b~dSCWfpvyO2lw0TNhDy&Dpm7%?-sX#Kx~roCEW-se`Do zs1_WmNw*diNu2s06jmiiY6Oe;{e~k@9_h7q=Cr}F{J*Wl+ZsoJmL>r81(m^KHJ?%2&kB`YNYp9iNespIfM`% z>KqX4ngmNk@H`N~utN{_pBqA+1T~7z+j)W_3qdt3@(vY{hdv3V>IF{X1wa@Rc@9z} z4~roKphbJ(^l^ZrJWL-0IWGoFh5>Kx8RFFFE(S*kGw9G?_ecYB2W`m zl1M-y#n)a~^X9%UK5J-f{_dOF_jbIqa^=%`WBN}utaYw>vF^*SFU(z;9xM!tii(OB zxpQvM_wR3+1$!&3!YJ3mw%Em%!!AUE`wy;}6&xREg&)N}$_;2)$^Q;}MT|n9%Y_Hou0geKOCMuXl%(dPkkpQH)^o&oSI z&Ks~tLObg_#R91I8bH}tSmOe#usJ$dpp^E=E4+SRz+@R4W(YU%{s7`Z1m^diJ@I|} z_h)dC>M;{zCq_DqZVD*u>JkvjJ2KD%d&$rxwfjI zp{l8^a&24N+O=&>Ybzm>uCyca!R0c?xZP5i%N=9>Z(gbBf0CxeYAs2NTZT=9i;Gjt zfpKY>;Cag+;}#Tve{gvzv{h7dDR`!xI0bnYs_{+*w{$6>He7Kw*^(Q%Y&^qn#AO#} zfHo>YP3?AVQ&VcHt35FZ0&8NsOL>(+P);%=MKPOJ%)TsD|RY zJT(J-spPCl%5Nt@8mMIDCe&NI{Ih__L3<+&&M$@GnGs-4z#XrANP~hSM*maMD}0!0 zz7e8MfB$eWbzLb}(W9upnvMmZTJj&6(0mv2&o_P#U=5a-#<{C{3m!j%yj^}IN zeEZYExNEOL2v18*4a|*yf@}Rx!9M|{2^{nvgHMmG+)>lMdF%Gtz3l_>*)i_#I==g~ zrp7s2@gV`sJsl!viRPuZ-`@7wSF$gKw^0?EX}Pnby!_PZ0lQ||vi!{Jv{kdgH}b*S z2+fio{4M848TsFaUOlXPnH40*U6+}^Y?)nDO}|nl%(&<7s~r$Ld28YCGMU7jFdY0x z?v;ok`lR-i42n&P-}d^uJ9oDQ;;+xS`>wll3axm$>$aO>*_p3)?|k?5ZL}ReCB9Po ziHjMo%>9o{It5PjJH!SW<3ugTg1V?EegCmO?~pydyX%x^;LKUCIAO|^$rdrrf@l;= zTx<+KFyJ}W)omAtynS8$`Y};DGJSl4oNUe%ZFm?T;Iw33Fpr5urjdcp$RJ0KzjM~*3WVhoBUQYb)t!#_7D5(#A zEFFfm$&Qj(pYCb%A~o0Gk(OFdq$9Gcz5nn(pbR%|_M2hL`bX2wS=jlgA#(a;Vsv{Z zMU({RsJ664tqkp;s+Cb~HYCN7H2L}IQT;7QCnv}52wQtB$>`As3~pYuHuR|qwWaY6(0IH4nkTOl>xC*7j z$u{5_>}8}YM@UB*Y6&wg6OIYSW7_37;94>ljl?oM|d_XB) zyfU%_)0L4O_-C$c?xj}-2E8p96^!}WE5nRmys~EvqgVFGUkt9ibm#zdVHk{)pw5$m zpvTbb|9@QCh7If1g)VJ1sKIF$DErXJ=;g^*cQ;0bu-_!lkcEY?-`3!wz}~=KL=--u z{>QXwIL$0f+hPC{rit6%esyE{hOJwW4QQSmIAp*cGY!|;YoB=eEc*R@1H(eh)k(hd z0sUAM6(bjSFT~py#T?bnT2oYVP6-q|Q*nRGR|ne;9`Ef{4nlNzzzi>Xn~$11G-Dv8qV`jS;F96 zMAQ+o^&p2AL_ReP<-DL$@u4x>1aiQ54XuJy57?S-7{F$xTD?^sH}Ve5#kgIIak~-Y z7DL?Fm(Dimen0El>(g($WCT?nq5~@GsJx#C9RiRKf6}XeG78jpTQ?fM0%&6-DiH9B+|cxfAFh zYIh)1ZXv8(cVTHRf_+MP?=}DwX=8w=6IQQWL>va6gO$t~;dXbQ=m9#Z=R`M9)n|ts z{LsKj=@n(QBx78z#kfquxQxTNkat17?dF?jFJ56KZGnsD;@JoMV(m656ZC+rJUm!> zCb&CZ2)S7Ps1@O!2bwy@S3%=uknms0Iey9zqE} zf-ATSSFj+oBCfy{fc^uA(T7{K8+#Tm+_meyjkB>EJ`r>RX_SUOu2iosTfMHV4064; zasS)vU*5PD(&h@pXg`TvW2!yD>kS9KC*14pMkc@RExW&l=L$fhc$0Ccd-v|$HLpIm z?)krBh1jr*eaD`ioIBm4JFzjXOr7TzR8~-XHhKB6Yy!O z5<=WqqsGMYDjqf~WC;W$5@9Z^*fILH8jiH~TC+N_w>B}ccRqv|GRH=PUg$Yz^tJT7 z1g9X2TK#+&at{XvG{E=cIh4=fPEf^zpo(ANca!nED2B^eA))Lk#L32Ny1x`=rKMF? zemNEIZVD~GHR^&y4AWGJ)T8n+L~>{_BN{l3csXQg~zc@CCrT;$iS}dZ@u#aR`@L6bs{7inem%V}i5U`{j!c4z1 z?Qr6D;dP6&1&Mogc1ngO@b+*G(4PTM-|>#aM|%3aPLh)P zKo@qHuaUXp;td8=B<;W|sK&mYjEi&wM^F!+vd^v~(}8l6h=mDg#3=_5jLR=eY5-7yt&o^!Ha5vPCg5=yxJ8`wtk$jZAJM>Xi$g(- zF^fLLsXQyw_C);lMEo{c=S>zB#zTM(TSM%dh>rsN=v2RgA{|fiBP#k zGwy=4R_+7IaaQ!<8uTFv*B>qSfyCCAG)327=97yu5DeXDV~f+-9)8M{=uC*-P@*Ms zR|CNCpLFS<7wC+8jK+AQaf(s0q8kZ7lEY2HS5#EYMu1EqUM7G$76o(om>A?|WCSUp zwQf$n5s>3wCI13p=f4mW(68QJvnb_(6fejdxyUZynB;6~T_Dt2nOvK((Gu{rMXE3j zdEMPT7lxQA%EfLwXppm@gp@QmxUGV7uTDO}V;4$zBQa4;=Hggn$VXN5uu85Tt{ zqLG+_ks!$km1d#yVHbqYOKzM{4B$PN6gLa&h$1I8sb*+22-?}i_G=8d|%p>fwYr(Df-Z~kph!mmtUH6usY!(a-6!B{lf*h#=~7L-}rx7Fbnh1%ucahEc<$Uq^FfK0l(YoNlA>x1{9r`0&Qd+ zoRT}C)Hc9wR0~CxlDjp?fi<1%3{LnrB;I<46SWSQD4da^0m|t3Xu`EHzuV=}4gotI z43zT2e#8t7o^wW`4lfG-4qot!K{1ja^czHc-FLykUGOPaOnd2nMIKFo5?pHID!?lV zxFq9#5MhcV!nlu)FMaRQJ=n%q$nJ7EjwbhV>^<2+3>M|{TJS0I(334BgS#=<%6XLI zfQjXT21`ph^eVsv`RA1ROvF1xO;pKywAMK{bT~U`4D#A zAqJXZkpKj_D2XC78G1#F2{7yRK+Tb|pf}amn@r87%KG|BX&y$ID2tXvBks+zQJpG` z%Z|_}cCfAOptR1$c|3NtkM(;z7i*ngjeaGD`bGXoBd#kuP!U)jv|^Rk!Sh=Lo#mC8^>gGER)vh`uh6WKz|>i@to`Q@T4Kfw%_OR_|RRNr+Mh#E$H8M7&pqg zOL_6Ffg_MhS0YR&lk4uxl=qos!iFtd{}}MZlC{$sdo)IRy~$MX z@ict2r{=BAn_F7GYIYrSNq2?DyjdRk4vc-HJP*gffCiv?`55-HenXS(;9<{3ZVeCwTUs?sIupL4MY>VeTKGY6_2xvEvx7OqBKL^bmH^{+KC`!Hv zqjDccg)joN&Zk&tRC)q?XiS1r_h!T6HBQf;Vi?_fLZc6bv2g(Ba!H4RsW*hnPakyOi< zY~JHsv!i1tGO;8kn)NYFJ6^ANwqE#1LC#?o^V!X{p4m`zroq)6aA~d#9m_g!^Y7kV*o+FfE{YE8<7M$i* zyS~VM?%OYYIoC(`7D=R`YWSGt>FhaGad9DNWj%Z)`6#5Z;kEMe+QaZ>Q1zyHSS8i4 zPJ9KKq8HM^=TKOxpt7u^cmV$pZw%7}qG)3buF)fH!Wq!%NT0h)3ejpDdY2IDT?BeZ z+F^Kn{0%wtX0O@s>T7@9!nz>AYoo^s4xTfFJJm=E+1=~O0^crUe+Ff|5TZ7l>fE94 z{Ss}hT+z}wka7Nw6$v>9j}2@C_xmDby$u9;IcF({4US$8pGV?SSUbVkLRzC5{ZZ2p z$_=(w^e3I|lbq>D394wdPGw~fwOkSE`RJagm7!S4^~lj$NX>>7qSto}jd%j7GmI`h zVZp{;eZ2)K>=HDvx8AteGxRS7-v`A2({1#!xX1VQ%%9}MPc zs`q@}+|1JL`h@I-_fd}utO@_7M@B&(rqf47g=>sI+oNy`IFaRYAB^mG;SJ@Ld=p9x zKq%)~e+Kw)75Fm51C==?#SH(8!RG@jQW-23JSijo2uA!-jCdwyB@?tlkv{5{Gn3MD z*1~{bcz$<_j|4y;e|F#242b1_QkP}VIMw_~7Q87+t&D`=WBez~iRgXGAo@GumFDJ; zzIB8Ta#LF`Aaj9Wo|ckQJWJ-|mF!v7^{rD6kk6|~60)y7`$;_|$=J#^hW#Ng3z_>3 zhRGSZ4`w3W{8nU3soxu81t#DNFmt)VeEk$Cr^>GQBmSy_{V+jNdxuQ@8a>L#bl29d znnjL(w8vBp{ifNnmL}!MK!^FD9?DQawFYA4mKOY@YNI%9iQ;r~8cM84&{tSkI6Ge4 zD6h+#v81@Qj4PYc+jm|KyDOj|;o;^OU`Grl0Ij2<;-=3?vPAGPVdqa_K}LVu=M5S;IL{u?4xZ$k86~_4T=t@AJf9KnNdi!H*G&txTDj z>u||rai4;jiN?&BFf)-eR;^mqHs!jxOY(1ziTmY@8Eh~533Xm$dl#aLCXj`_dkJ_5 zwa3VSR83+#TKK)D;cx2ezxZoYQ*|}KiJ4^7f{=ENbGB^zPz_J@8(DSOKq!^u3W0?rOY(k9mqH+~C;3~)x zN_bL|*61ptJvG&vHf{QwN7!D{$!e;-t>_1`) zS3hxo>KGvC6f@Ox`g?S)y7%^dkBF@zJFY~RBsOfQ6na`ZM7)yt#>x$}U1sAlu$u&n zdE43=aM_ODem=@i{1X6bolSvwK8kS1nut& z0ELPyqBi9n&dCZm7cZ<}tV)h=11xp5sw)7H;A%kMfj?CCJ%E!igGv_lQOQN!z4Y-N zwHqb%T?cpVa!12vY3JdtkklrYnu>1{w``YjWpE2h&!|Nth4KV&K(GgBUy5h>W}Nxg zI5XK9C{~;-F4%HmKVC_0CBZWe$lNSt2T&e0?Zem^7>cNg?lZ$`vE`FKBo?}O=+qY$ z-aqH2Tz~g>9UWQNKC6(M@_7_i*sRXJ7Ks5tHr4oQe`osxg zyRg62ur+*1;j%gK#&3tBPO`woH)oB$DZMgQ6tp@d`WvRSN4{a?=k}Z-!5rlff+&Z8 zK#I|WQk&Kf_&y8`LypkVh4ZDa$aM4uu74-4pK2HtCFN zxP8|Eu0EJ-ms!W7{H{1S85`j$d^xsgX5zGQ;MvhvC8nA^e)G7=(g!U$9CRYZzp`0(wU;cZ1WCeT}uVLtvwukjVBv0WMBLGurk8vBg zR_-|0g7zV|1My##IDt)W?=jTrL5AgJcu#3I96tn;W)f7U8q&QGR14-$u^)}<71rF8 zSc4s#og-pgT5fJ4w(ba%>FVpQ{$;+M?XdzHu51N=VEgT&;n%r$fH}-GA*%yn76~=J z5SHb~gUiRR`}iairWUMNv7%tAz}&kl%3oN&e)TLMOCCfZb+#=^h|9!xGve^ihT2-X z?j8vqlx-~d>^)Q3W`Vh31OurwV;~eN^0(DG9ORdcBeF zKXcyexgbcA`s~5)89*JpIb4tgwUHsai#ixM{P+DmcHXF0IkcP(kPM^+aX>+l?4rdo zd0d1EKj9dIvPW7ia>r;uH3D`Uov1a~HD36lx=;J;BCj`uN17tTROlqRbR}pv4)m3A zs~M+QSxF`nL2sAKWOb0q0<9Fh5)#W~+PoK^C5`(we0m0G^9Il+H`|C3Y203(XQCUM^KmXqbvnbV||}%UuC1#T5A-&4uGVdf$lmue|(ysg&0v6BO_5_aYlz=*T&t zv$wa?JJ{FL-PzrBqR(^QJBVc7IPU2?dmdjIf-#lXh+2t^P?&weIYB>dn*Max5AM_M zu9MwA96f#-V4G7XyG|Z=9YHPyQ4ANs8GPrE(Kl@LFeLxpkCDFnl98s$Cv(7izDJ}a zW&ivh$ItN~MJNzqzKJ-P==%cpBb^AQ}Uzmd}&qy&GXDgOx0{L9|r z@zyMCisTVUkjR^o6-s-Fokp_;n)jM&NOO7AH1_I!kp2*ypB5CkmUc<#?;n?XM@W4X z??@d7t>?!#wDd+2ETGc8P+#5$zuX5?UmKvFbl(ea%lq>CyYc>4KY8CrsUHCuwg1d4 zluhV6-Q9WQ@R5$A-Mwe}P9seMjytF*@+|h@y1n)D#sJ=j1Fak_yqA|CAjE zEqJcOWxWao>Qy}d^nEhXRgja3b&({_{PL3bbJzugYZ&*kMRTEd;JnrtpO|1V4IFPj za_roYJ{A@J1`fkeMaC*g0H+cK2e!x&;LNlDM;m~xW=94f{|?|mviOmMEC}$a59zQ* zkB8yxH9>4f)C5Ed#vwNOWrZhMIJN|{l!aL$y(Iy&G!AYn#UBBFr(kdCHOG;2252L7 zY+qmOtw_uFHYQ>lKhrof9XUtjIpY${gxRdHjXhFb{oR!a{JB!7t`_q1JJxrgB2U+X zKs{PNoD^Xgb!sAvp{E1&Bz%jNH6LRcd|ZQ4EG5`hLavQW#kFCB55wY*#2gs?CxE-} zVNp1aVyBQb;Z(|UnAH*!Q&TV*_0X;roaEne47<48{`TL!&spG$wooJY2R%zw77gzi z@FK%;Ol-7npwD%r^X$N&py3C*4|essk*Bj49w2D_m;?tej7CZ75DFT)Nw!Jk$L86E z^S<*J*d@oZe+-OWl&Tc@@^%mc@hY-7-hdgnl6Hl-_ysVVpb`gKB>II-TW;^LBitA+ zO-M~Ov|mgyT-9z!l_r!oG?X7}Kq=k^*=eRZ{)y~BBdd^3;?{zhQC_GV%BQArzVu1s zCoec=V@1pdIAjdMhjN02JYWa2P#}YnQjC$Ig8=_Jfy7L?xC#uq@sly?K<#4{7{Hx8 zka!yL_)|*%A65Y2KS1#7CJgxeUN(HX_l%#3QPC!?d>mxzu`y$`2tY+3KxmM)qoJr8 zX@X!f2|idxf+K*@K+70C9`+3n;mkzciq#<(W1EMurTiNy7~4r0TdO?PKGp=+D!?LC zgSCkba+dJCyhKkU;4qDz#5_YEoNk;b*`h(m)!#9Nl8@r}s4x}V#nf3KVeH8PzqBCG zfabxPiwNmN5pY4C4Kxr4P^_+N#JEXQ$vrY9kNuI7Q)6OM zF|Pl2B8Hm+r2EYgM=U{wyy3w|2VjN$N9g*M}ItKEiKM_vFVQmRw$9Xj=K?%P`W2@6Yw6r zABXp^|H=EX)1f&p+uue-nX(Bx-rc@!%cd=xU)x^uw;k_RZ`+LHZQI}aTiNE#Wk0`( zHhzd2X?yDT?5=z7!^RJHH8h5f_wL@c=dvHUxQWW#ndtY{pNzRpe%>OS+ zqWTbzqimqj(}QCvX$-&~V}r(^k-PCmX@QO?7RU^YSCjwNLgOJ-CKDqoASQ*Gd zO850t1x48?c|IEjyNDl_VGWlB`*BnQDX@ek%lVcH zBE9J3P^43cjb$-0rFh|T+3_i0j!GrU57ZiZRQgP~!RernF&4#JH5q+o1y=mFlIyWd zTQCFcXGU|gTo09&;1Bhv6d*4_)eH4MT(;sK1Au$7+!h2M(>(XlM;|@6cCB0zS~9-> z{*mEWs0p#dN8YC;1*?Mr5&?tnx>4R=8=YYrU)Z?mwb!<6t=#l75*@BU?NU5q$WRO?5=`?AY|(zUpv{l$VW60GeMZS3=*w%>FG7? zaQnB{pjM}Be_{?e?Wb^Wzl}#BElu6=K?q8%`k+IdCUH)uVyJouviW$qWd$D+O5c0$ zy;3Q{Ra4`7@x?vg4P9}?6+_?cc~MdoS*=CSzZl`HsBmt1Wy`iV-`xII^|seug?ci2 z4X|l!f&G31c86ulvN6yQ=OFY^dlSdcuw|oHLD9`IpeM2$5%wn>R}l(j7EI-_YpR6i z?B=-9x0stSA2HZ&Hw%US!ZxPu@cTQe{r+kodkkK$LGXG7AbVh9XFkNz0$~{PPXR;% zzscnqsEvUwE`!ERwbWPJU?by_xK^nB%j~O_n?gUM@kg{j&PE?e_Lxd>F$bP_+@d-4 zK0;RBJE6JqzLigY-TIYVGv$|n9bP|4Kk%=AQk*#iEBrv7U9)4}yd4HZekf0~P;Bvc zZV9D$;9mTeigr148nypC0a(=HYAf`a1`xq!ZUwh&>3otOz=T(Flw7EpvjNiSL9&lZ z?svtv!)~#dyBde02lE?@0^WlcIjL?Fy)AL7ZTm>#3stBSt#2jl7jd1 zdsy~tdFwpMS^2hj;F0tR6Y@El$}jv^~kQf7mt&WU54ACm8MPfJVP`Vbun zo7>sc2SSEzZfQ2o7l%azd7&m2wknQx=Scc2$mIVRs#QC)4d zA`BH1;p=h78To*7O#0+uuVB6D8smk-@bWbGP0E`68!A!upR$I8@2L?ppq-gN2mWxP z9;MYHf~|<9(~t7vPW^C0zzYj`(bmgse!r2p*ampRZLuj zlcpK*_X#i5G`{65fAzx-Phi}Qb8_=;N}6monfv>NtMVRO{%GDb|3Lc=u(PMhIT3AV z;SNsJ;Wzaf2iJ9^l!SHS0$ufr}y|gMx%fn z%|euJh@qOdmNMG*_1M`t2j@F)=Y3wJv5lKjD%ZU0KW*m`j_XYH#Z1=uVl2N-ydqj; zfm5!|V;zG!oQU=JGnLV7947$ppiv{>Hgq!3n4Le1)I`+WMpscl58)cBA8|cI zMQY5l8ndj%EZg`@BzP)?j)z?Hr;ZzXB;OF$p9@J&Lk5?@wBi2K%Q zn+tBU1UA6m$T;$c6oXY*dv{NN*Xi?p=kXz>ep5F049GPX7E=+{&R!gFab^80qWt`4?tRc~nl2N_XhUzv3D_Cx*asL6dS<*Ns(AQ81K4N60 z?vnY&D6KWXdc7W2baHtiJtWW|qYV*JAUqpfVzYy>((98BMr(mD3HYPOBcyC>^uYl3 zzRsgZJCC}%rzUg{qT)8wJ_9E&q9~qW!%iFL8+M36zv~#nNKeC>#R;mzCF#ftla7L)Vo_CGT{b6VU#(nIW z2<|4|>hO5ItD|+#fzS3f{~gH#TkYw=Si|;RN8v>C9NGUW>OEuzZwPEd=+@yizUkAa z5ANTFbnVnsHJvBkr3BRxFo4G*?=-L!@(j+td+|~VfR+j$*s4uB-mW0 z-iktNF87cKsAr5dH@Cj+pRgi#`#88Trl(Aaj=3T!$>pN?9{S0AORR1#%=>qtJSl~y zS%TMsi4_E&R3YN*+1tSdtg?KcGv9o_J?+)*1o-%|_zjN{LXMu32y`Xw@ac-D&8>>QMLTZ&<754%656*?wgoKsr zxf_V#@X6OMo(Bt&3jo&#QK_e#dy!ir+gsk_9=L7+7{E~w;USRWw-7(Npt=xVsuxJj zW00jx_H5X#3RnsD9L2DQM-5f}b4@D&Btzr;5?%e$c_%I)8QHqXOwbVMhOLosENCa@sZ&_0YbS#v~z4=MbYD7i zAd}~cx!{czu+1rq3*ZI3S_QfEy=yE{{fO>6d7_85UeuS4ick#&M${2e;}Wi(HZ1{I zK3!zg*aXU~9A)I-jXuAYQ&TF25sI2e(7Y2~To!O%)7%v`p6UQ14<2q}RM+Vt*fTGj z>N?u?Mavg$-@8wqINtSx%k{$#;Aw8@#}u{l=L1_6e)b1Y)PtZXD=3PxqmqR>C*>Em}E?*&zy{sqUU0AHP7xQH*XRnexV>U@B$@e}@UccFDt3M%j^dvAChSaa1Iyqlp`nCiS+VglsFXCg1Kq-5l9ym-@)&&zijRC&yWaxmNw99!ZT zc+)3Z1c;X~@PLufcEq@l$D8Km8O+N~m>04MUyFGekGPXu+Cyf?2LArSTB|iI(EWF? z-kSaWS#p&qLWCeyGE$Pyktvsu6I4A4&jg4T_s!0VJKdEtE8d}sNK3nmf|ID(qaMrc z`t+lHfC<f zefZj(v+&{C@l) zO%9Y8e|tMXZT5GSwWY=!YA}bF>I!yj_fGIuAdWdm*$itq&Ddk zBrgB>%kA`-=(EWe_qB*l3kYJTMvPz7ScccHq0;W9t(m`sbH

    {~bvt>fG1%2R@AR-bJfHii>tN(LMF~t=kve5WsUUG`~c}2y`=aMIno1B~h0CEeG zfrX`E-=R|7)vVOCq;UF)-BndpUqzz^*825zU=4!u>Xi#D(Z>B$KxRPh_QPbF!QIeGK;|V=7)Bayx?Po)f-;_J9wU_prC*m z?4|0nJs$6c5pbGSl(CjuBLs%LX9m~Y2%wv%zx!;^Kjb~z>ppw_!r;Kbsh-n==leW* z-iT}my!UL^zYcuae$3-nBi>5%L`9*to86hn8BNfJWXVNT%hC&3$PhG+M@3BG0TX5s z;cIRbgf8Ys@*&^gc|ZL(z-fRzHAYX0*AHnl!9Y+nn&YQTnGzeJ6L}9xqKOzokb0>) zBHEzWs?gz8#3lo41XS&f3|k}9^#h=|CqQvjnf*#o+*D9pm~(yYf%cPt@ul4IfXrpU zWXe&O4#J12x;i`NKS5$;f9nXQ%%{wN;k*f{Zh4({NVssarxW`tu7R?{ZDHHRZWML7 z_o|`ZHz@1_jjwR=(kytM4#V8JN}V2m7~C-f0ZNNim6e+}D>?~`^!$nyaaqjCPEaTT zC$N8N{$P!5dt)<51xf6e79^q!ENA%Uy}j-2>A?hK+M%640c0SPgR0h)wla(TBeeg2 z35s1RF&ml7e;u4EH~2)O*1Y*mU;jYi%9V>2m0>+03TKAvgc#e@1S+Qw;Y-NALcqct!#gApS&3_61M$IoH%6` zup?PPtaD>|^;b{;_P^rXbq2nOEfmv5S@9C^?>QkS{DZ+#XoH2Q=^6(q(iioSW}%9W4KjEahhK!*%*Q>XtbZRYd| z+M(kxa=CTzG3ZZLWKTKT0KTj3-97hg=Ajp;Pco_?3`LJ zU59``z1|la>pg|EyaPjEl$<(X5Qm4(pAl1{gZ_XvOs|J`#XG{pG1ul?jrgwB<0(B7 zFv^_`teYc`FEg!-aF%n_V<8UVZWq6+)h zdHkRH;ve=740wDa=&Bc5%8$2^A+L9se_l3{4SSU=UvGk@UIk6vjFo&JXo|8VaoA+B zgC|o6jVvG(fs(F81mm}X^?_#twFr;A6HzMWz@VHoqCD_AN{>>?X{9jm#|Xgg4}2PE zhizyr$c*7zuORpKRPami0wwSEI(xWyRZhV}59X$2-;Csy_szi;Rs|uTO;$UA)QLzL z-+!QCS6lz7v)F~>f1LughI?jv~D#U162ab387#{C%%k}xz5ze$>h2map_2sm2gL0-cJty*hr&MujU2g_}JJhr%sz3XAD!F+~46v>NY_$|B)N@ed2YN&Xa@CH+V_s55it% zij9qcN`bny$StW;8I4-h5gzQnAgQ|#L1XN9Fmbg`KrHRRSr71|jtGQ{Q`llJEGobU zi5lpTL_b{D2F1qvg|gVOT-gcq9Q2{)NX| zv%p#w2YQ2ZwBKP%ysm!`(7Es4t@QcUXMxEmp4Qnxt7L3%|E9g|OC${(?D?u;pNs?j z2V~)QAo<$0*8uCAle6IQSzv?jVMD3{iP-Gp4JD6*u&y@6kd4?BVK5_ULX19XnZZB_ zebyj2CmV4+0Z+#v{dEy*JSCz|b= zn6a<~hXH~iOA1I22;2JQvNDGV$H0enXF98as-JL~9IV0Te~S6z`w>pz1hkB-ry=oL znWvw(+Cz!N4yIUKVWvpB)M`)X|7m~tLiRR#6D-2mt{?pYx%WUL%5}F%&dCEE%m5v5 z>wQ^}0MmoD*g7kME5dq(?Vo(#)6;XtFx@>H+^GyYw34V}p}2bcr#_#rr>SQS7@-M< z{oCVPn=a5FjVV}#lL;{{=)n3$jhB& zot2RtLuGrHBjD{-$lcYr+qrx2u?n2A9^qMloZ#R}JORiQo07Vqcv)g1i=CO1y8t9) z&7E_lFEMdNku?Q)R+Gf?WDkPD!;|Q=-zXscAROOi7;ctA&rxoH=jqO*4|OijAFkRq~7*=gpkC zF!P4%rlu+S5r}6K{Q?CP+7)@tH83HQ7ET?8$Ci*0%*u+ zG9gtATnJ*ARsiNXO!V7zCX~*ktsBd{R-Rqb&eT7lO*^z%ryV}8%jistPmbF4dC-9x zbYSC27?-Jx^H{hpXgVE~8ruPG_hYoK7Uw5#0DX(l?Ka*;-?H%@X2BC_bES9%o^CHy zX!80VfuWTPqhwcv+DeSI*+=o>n7+TT(I3+v_$YuBTU5CFr- zslhhdH7?iDPY#%uS~16zwF^zi?(YvXI&`T^mzs6AJhgJA%Z_MieO}>&eb{>{TYpiQ ziHPbWtXFMN8LrEHAPYv6QL~%G|E4f6gG|MUg$Kb@*#(Qm(uVRy%enpos3xztfP`mj zYC3@<(raL}SdL||ND&=ynaG#s5Teua3je%-ZH4Ea+F#|patrtzg#dRTUs{>2Fz=c{ zl74MAC)AF0vPi{qYb<{M*`Bk0gL#}eY77?3$OVt@{D{`zAJLj)V8_%=Y zrpSeOxt>G#u^h|=Ra~G#+mD7HIr4v*5`A56Zr%TOS~4KF7!0|&|BtgHTDrP0LI2ko zQZ-jrHveCz2^RT_)08j()A;{9RT`@N{Xb3DWaP%djQvkjw)*lZQ`XOeq4hHZb2bxm zMtiqdTwHYD-MKkAIV5sWTVar%K|-f3+NH5^YVZfFn$1Z~6x zjPZak{9?M-JJry8_+Q_;x=&vK1M#2t`Ocwogsc*&pZTKi$tU|HvHein7yI^nR9`<2 z8+Q#d$o&l)_D=Y~K9KK!RsYs{mHI5Ii#5RUx=DB>_sX+}zJO&_Z69L^_qh8s zH{`?nl013xFQ!>Yx(qYL7z{T)g5CbU8K6Dv9Zqf2mq&WM;$$EQ;bGIIOf`!mXAb=+ zRT|58x3=zi3k&DGd9_xDo8E5JYdFyUNFWHLD+~q>@tnKo*-RpHyPa<-<4zW=aLeVsPuYT% zzL86iEm+J4?g0;_&BoS}2h>Op7c2MOfqA1Szw0q?S76>IW8O^8y1MmiHxQGnYJrVz z$VWvOuh(t&Yi=TTIJF@I5KFVl?FQeANJ-ha@#Sw#0L6B~1gjgetLhvMM+Qv)zt>g^ z*>~N*Qc|1(DjX{e?iHEEy}~5*gL$*Ys|=aY0gkYBV&OFhw^mkeZM#}YM~$c_VtT0H zJ{s~{1xr#HkL)GL^&Fd<`{XQeF={VyRue=N^&&mWfwTkWRz%sd(9{o4Hx3=%N^wGH z#*Lq}x9@#@+v|I}hm2Rue<+1#9Z@3)(K*xYKH=)@^^1BH zR)ilP85)A9Hz76}8POyYIKJ63#WGIEM~5Tf%FvLrN|}v9j3(vAO2ueWjqEs#rqDZl zqOmj!N}b~HumqQe?{&MI-rao|T(N0q!&_D;$GOOX1IGv_Kt4ghhQ-3O;4hzoJi@ib zX2Sk}95;4V@awvkEQq7XLJyq{jl0*fdR)Q6hf0cI_A0n{ak0;r)O!%BMQ>R4vMlUD zpTW~(!XAmZWsGN?U2D1;3;gPvEu_ppp#h>FFKc1s3?_w{1SGa?I%XmkAZ6o=UL`LQ zP#x_I7GdqvkZ&>lE9asMHF&3$^~hoNK9~*KRV5{e#olHR0b%uNqGNpke8oESLmppj z+yoq&L_2cpAkDT7=@sEycok7F4y~vcTqhx`IrQf`I|Kk@k-9)wy-gX-g&57-Fq)Ll z;d+cFRbW!(+%i~4ph+ckX?b|1%~nzQA#4x3->u#8d?rFm)&{K*@T@kZoJE9v0c8P3 z3%_^D*-si97cRX0j?AfMfN*sYh!ARQlvL(Pvk}Vm77XBZxNl?mqzfBN6EYtteBjOn zdH3IyWd(h4si}Ch5mD;h9VkV6z=c%9aSmbfRER$g%|JIarnopMOZHVMu$~w6D;@!A z6pHpOOIA>jbOXkW+8)sIT9w(Hn=4hu@ut|AIHLwxEdZy82uD(8%33}`nv=&P(QrXf z87UQb6{7TL=*skz>%nsY+4uy(!KpQ+JaTuCon5L_M(z=e9BEQFV&o`mA&p!*6uyRC zIgk%>;c!xFD_oD``($@qLU5jDGZD^#GOE{iC0w6P6j#7C$ppz;EQoH92NFDXv#O=; z>!3Z8sFJAaU@#^dbkXoei%B z69|C%0zyaUIR^zcpLD^^jAXg1w<=>wXyL~&rj!Zt8jLCVkj9z-chvFtw6AYpMfr;r zn+xynt3buWJIUrEw-U{v6)S3Lz$v+|u1rXH4rW)+3XfU3G}R$QPL7Lvh|-}^`+&Wr zT^jTCr^lGfFLH47KdhRL2n;i>%{NwHV1v;v;=KJ9qyRox#KFZ{I`h5Q0G z$tl~jfrz})*9HN+?vFP<+w#bhN zGa8Zjh}YYTnky$gfnF~liK58k++@~MKCX;C^gqb+m+P|#(uekVF-?Gt@FbV&ncx+8 zEwKNhXUchy5+V9KKCKch#KRb@V?fud67 zSRjZpGqpf144r8CaNRseDwH>p(y9~!S~e5MP$;?e8?AW0A9I7I20i|;=j{yO0v3W{ zEw-yy2tvudi4GKpHDzPfd@RfDB)M0B>z1*b9BM9I5SA8=u0|(wNb15uQPgJ4gE6lW zWb_rB{EcYu15MBhYP&x_|L*&KZ^brHE-RtcVouKdC3&~saW|Gb znD!%}gpFl@$=6iE+K*^Paw3||x56;||FQNya8Z@n|M+w7+!=;pfB{Av5ph&fGBk3@ z(8vZvBqe2yTr)E>w%l@EE4OuBYv;}#m6Xg}Gb<``&G;x=WMt%0u|>w3Yi49*WP~G* zfH>kfj>B;0_dfT|r2X07>+}7-zVj&a@BW$l+~+yZIq!4M`w&HqGPm$I1;7B2A*xj& z&TuQ?blQmDs>-)FATQ14LY$FY`_x`yYo*slSp=OqF$#i8Bj`qs8etugmXbD<91>g{ zQcKN{r$a2rk^>lqWlnl|3&Y`UchDKFC`Xx)?R8lk(o$UssHjKfE24(0;&Fix78GNE%s*V(3|!hm zI5jU{5?x@ba!DPBJ30=3@#R;oU$wS+`!3)!y*`?lB;trv6!@K1FKtohF(F4k#epz~ z5h2q8D2OxJZ5%vp>Vw$@+{ZNRF&4cL$)Jx-A9b;{VPnO{hSm$C*qdUE_sh5H-ulv; z0OwctpLbtMMDJL5~t&GcnMjCLlU# z8%iDPO?nNA)Wle_?^R4B2|3eU7ckv|a&a*d-+l#Br%-83W#x-6)zt2;t=+l?!KQ!4 zT31S^67@0)`ecpE(xV&%ua{<1wh-)wYkpV?(-ozSk`+-MGlcvISo}|c>{Ic>h&oE- zGsVdGnCG5yXent&uV05bu6*!AUs3-?upRQ(+xaqfNa^2BRNW2t7L`_3_K0w?Av_v; zsTdO3N30zt5$FEFLfXdFGYH`2WE?4_BfXIrQCd@UI47Y=geTECp7g=U!EH~^ z2xZ7_RuyW4q>PkeK`})hiVY4x4&qv4skf*5V#d$}qduu*X+GNtt#@-YLJ1b7M*j){ z(G)8{tqGnX(u!#*spVE+kTi=D-|Bt406t4Kd0CxzTq@2JS0dDp_bz;T0#C_>M0GD-OJZ>MMPB^Tf7*mW)oSk~@VXTmt#tt{Nx6x=OhZ6rQX zWi7zkRe-zT#WhxiN;%$~A1Xu+k{JU8w_Q^@ch@eFo4?bkAOWx;3bpFRYi1u8u)Wx!YnNlW4m2`<8Y#`NCdSmI4sNAD`b1HziH+g{r@0FmfwcT zkd%atrI-Z^u1DFGU@-c+c_^CqJVn81n?AlYW$wx%sA9w}N9{fK7zJi2zDn4GHV{Xm zu9QhI8C9yGEd`*DP($?pqB)9!R{0q0m`12QgKZHMql|d%_BKDW-buwl985AjaP!EK z*|QN+XB)))o$tMZjc_5LQd_G8;8qNGGtH&*vS2cx<^edl^>KrTrVO=O1i8DT(;W!7 zB}7{ZB5o}*EP`v{rv@asWFyZ<;b9^@PZ6F+fIzkAh_z%-o_HNX%nuwm zV48uFABq~Og9JP0?dp@b`j_BL2XorTuRErOJ^W>Hd*s~v?z=C}g%Ht{6wHBJFf@zU z-@$;25LE{A2@=0fDN$6X{XLj?Cl<}d7Rxc$I+5d<&0Wt~p@ui3Cr@HzcH+Crn1^$7 zZ_Le}H$UHY^8-b+H9YGjTsoh@XJDCg^Gla98#f<6IAxT+zZU`&T3YXZ%moFdb!Z0U zKv0UxxMM{|V!>*}cdGGX<#CIqq_nrU$1RMDOO)lrI7yLYmcK45$;|*jhWh1$uAV&O z&iV7hb?L)*A{!YGcQd zoy%1s3^$}G05B$fzKgsu35F6r8-PI|rSzTal4YN#8>A+k=jG@GlSzpxC$}i}4poW? z07ZCkX9j~hpeg?Ir@Oiws9iodq)RaCG%;qXYckkmpt_d=;av)L@}4SpoER_bFkT{- z-FS=_g-HuUQkyZXIia^0vCWS|A10cpiHJg5gkeL<&ZD8n<2OC|N=@@wWAez%;pg}7 z+l?5W$3strR@>q1WXa@DZeS_g5>&V9V*|k!@4J^n!WW}!ke#g8gMxH)&iw^Y#9sn4 z#ItNOs`PMD9=C{F1O|!KHbhJWdrB~eQ1S&y1xIl2KZL3G4etLLKyq&M;(n~^74f&} z&$5CUvnMB;;(VRS4?|Yhid+Mfwt1n-5DY_0hRrr9YdR2EAILZ<-cM;D2uIJ|v^b{) zSkS}an}}PP@>s+CjOQM3}X4WD^U0AzrFNnBG?5xRX1?#+9+m+ztT-(y>&Z}#|&m;UqWj-4s+0Yf-C zvG^1xQka0?Nl86hYqw`)%=pcSW^mXb2tkUnz}y(&Zg_P%I`M8`1SD!G#Acax-TyT7 zfQRI{L7fM^7tW)6cRygiU{}wXGv|D45Ee-tA{i;R(Wyb`Q`DM4E(~A|3u=S`q-P-< zHx?0vE|;XTN13due;~s36^&j{nZ2Nx_`#51!m@&uf#;VRSMsh*q(Zrr`R)SE7hIc4Q~w8W}JZ-!XnnciS`N=14OsRw^gGO@I#Q* z%R=`R`H=J(iV~T_lKN12-tR15Q zAbl1!F1_A`7n0tTvAndTAU9*FjoC2@w}?oB(`0%)0I@tE`#0nF#uQ5ct@L0^$NL7VBPP>gRuj&@yl0_&diIg&GC`39WRAkuJ(z2_v zj#9#(pN^?;V;JK%qO{3G{IdUGN-Yq%e^usTVcewwl>9(GqWY`YCc~ZM#!M_KDldQX zozc@3x!3?1f(B{W&Q+D?K|x#~<#P+T1?(dY;)1egg0e;rI;gc=UAR5N&F3@_wZ+AM zorUGpNA6&y#RBcRiQ@5aM++jxe~vPiecRp7`_k=EN_ZBbRMeErsMVgV3kxE#e` zmc~c&eqwk>JC5$(0isGCyM|RjuFgfnYj1d@d;$4biOczOQObq(cB66h?8oSGDv{@_ zroQZe*T8k?jVh^nw3`VRdot5v^oF=WDJhAuv4}@P&6!?Jie*&RgljWKd(OB!q1s7& zFF9PG4Ql!W{R0vy{wUMqz=Vd^(FxsYc=J~fyx+IAww*YKT7!W8E_Hp|)_M>=l_RaG z>Ep7bYIWxS2|Y?H<2>Be>A0&mW1eZ|)zr+J3IjF`>tLDoseRb%6(X)3t=+lP<8ix- z$=oMBNj{0rqAoHclHyKu+hhFmJ1|ctz_LZ*KJb206P`XA82g7p618YXbQtCyW~v=j ztV2ec101epAOKB|^qQ(r1y_Z8I17%1Ap0MFCAg0<@%msU1F(jBuY^Py%#=E8R>gI2 z9_|QtnEMa66KiP}7mdZU9^-mB5QgQ;r@<>jw7S&Z(kvL=_3TgL)iL~vjIFH)|M70G zm%KCP(NKU;W&snv5FWgl;q1xM(2D5wFMohh?47q@fubVm7I{6rEw7aqLI&l8qh7~{ zCQDK@fKX^H6n3i419*1rLFT?e5KLxblY z7&{e#86Sf38RIsORxoZ;JL)8oM{%^~P;+&)VgN%wr;-ndh%vRbfoBhT>k_nVfXHy> zU_NXRI*~2jL*jjdjuc@b=y$4obZI#M5RAIW`KjVa|tGgFi<@feN7nFpCMf608Nzsi&Hg6*HddKGS?Bn&`18j|#pgO|(a7{Qwf(4aF?N8Ki!WV9oI7M6}q*$s@9WIa8*zQK(Oefmz9w{@+WipM{^3m%@(c&0dHkkny#GG+{CP@7z%r# zD{bTE&HLG;&f*rMWpQa3KQfnw$%T|%UuPiDiI<61Ya$=;$&xy&=@+D0e|c8tv3=Zl zZc17nmkPF-<^l!WX%4Ms`pCQ|(y3N%2Ykdiq19STPL9Rmo=$90xc_bFZ5o?IGtzV9 zNRO|*-G`U7uqm+|>iH=`*1%L$mo!bn5qKlQkKpX%dZ2Vxi>x{9_G9UiQ@ zo`ch19a3w?QoJK}Wl?rUPL4Is;yaBgFfBY(-={@dvwTVh`VBI?Yy;VlJs? zCS;h#=$F2Qd+)VIQhPN^Hv9$dO29(ls@_@u52=ZYp&1 z5-4bo+HIl5B9JPg`^*g8#7W0R?&NtV=W5C4i0fjDaC>aeY0p$pjv3fF=7%OFh>m;` zWb9pjN`J4&ee)ko97P4v*3|q*n0TM^n$LUB4gw+w@bcI|z}MP(_=|Rr&v!Q9lbo6X zs8%9(N#}HEGc$)lDZ;q9(oM=WCt&L& zT(iNdR@Km31;((-F40(g*hiCLwPrw-+rrv;#LCg$nug})22zzVv(qUr3kW3-WqKWt zI0ViU6qVzWWvj(;uk3x1Zjs1JB0oU=y=2!${8kY!l$|ffw&WMAv15Dqos^_6S`G$o&9(KlM1?)+y> z^+mwL$%#wtme6LoMQ+jT*s*gb+;}jkJ`z>h?B9hR1@o;TY0K;1V#0d|EG`a#hk|v^ zik&;D1o#W2YNM?cCb}$VpSOh;Ir3l^CL%;!C@r}Kaq4)N0Y0Xo>_GI=S;T9eIu7-$ z+3Q>)Y%F{ScE_o6OJ`v{X@l9NG~_)mMzWBf!zIF0J`63|1_FXY;3))W5un+GW#-Xq z9R#fti$DAOEzo;1p|aHCru-@lu&>e_^q4TN-egS(j<#_XE~mb#YUi$Cumr~t#e%{28v(<*52ip*N+}K zYGgW+JqICwj2q}Dc5|2yeeK6B*0y$_@n=!~DL!>1FKRkGGLK(?s2YS+bLvXffDYP^ zF+lv^DB*zUT7lgHX+9UZk3-}yaZkShSH*3hGkF$KQzYT3m4+VGzgYh^G6dgwXX9KY z5M>A`9M8c9LzB-VGt7X2QmUG-;0LGH4@F>32$hC@x2}X^qIGg6>O|3Q4q%7Iy2qh(aW=e5K1DqAAK&oy~goH+HdpN zb8u&@=zBq;88GN z)S*>_F?Lw6ekQVT7unb?o$SM$#!$uu*r{=|@=kARJk4i#L zZtm)v98qUlzi1zR<0wc@o2VOgxrn1jSqk{%3%bg{-LxF=K* zYZ6G}&z|h;?Dh*Lu&XrK230ow7URo-@kKuCJdCd~7+;2*92h3g?4tymsbO$yu~7ahmf8Z@ zOAS`+-7(I;ZQHW-rB@rj8O+;L~`}~1P9l5 zT;l5LrqRqtBZi{qc$>|3yF$=C4{L~(8?AyKT&vP*xrO-51f;qR2FX4Eg&Ds^ik3VN#VyI~4YqxX6EzK-QNG}<_GjDy__LKcZ3YR-tX0fDVdq8S1bQx zdQQ4d_QYh)UiQZoe_S>@v%4Z6vS?oD4oyXOCgRKvVPywCzz*?$08=DGm_KF}u$*?z zPoT?@*zW*S0NjoadWQf|^_|nMYj0;nP9dU1C3tsj&rIJUW1)w~$H&j8eny!2K##oJ2F^fZP;rJy@5= z0_gl54_?AKa-Y&M+YPe}WFeYW%PJvNmD#R)k+$o+Z`}{{Meki_qg4-A9vk($NW2I7B5!e%y1IhmT$2Hr2aSN;N!$o79^s7%_&o&s5&>`mnh6@r zRosnSF_sW3wD3|8HFwuI(MQ~p3`mhY&^j@$px|~$mtIBIG-A=JfS=*vP$@Ghy7R+` zfvJEc^n)zI_9Tt=u$vuR#u6MW-MQ37zLxZJSFQT(jj6}> zf$vn2L&G=L9oDJRtKnGcq`9l+&YhHctU(cG`1}Xi6}@TSvD6!XyK4TDhYFYow_z1p zIsez+FT7p(RofBuz8!t|b{J;f11|-AvJ1VY#sX1(c%$^e^OG%dAQYG4@rA&Ep~XmM z0Z*s9v&WM%*n%M7WV5H|6xBRO0{#H6MRs$@mk2mAPJka*9HNhjHw6N5aj|j4h$I{0 z;&eR}I~@SWwGf}d29W)t(MS*tG4R=;_#r(=bfQiL=$dpI4U@Hk{2XGA^&LDPJl~US z(mIC6q-7cmnO9q_VD#_l>fk#%x_Xjnp&Lz~rx_e$qD;v>=Ytd_KR`uRzz2qG?7lwl zdCVI;_w}KspXVH+?LT4p1dy!w z6HDM89GUVAv#|A5kPBq_GvwDy1h%~99}t-xbq*O52#;Io>T=ua4Y;YjVvJLs|R zSjZBKs1~I1|AR_sDDy7#sHQ>RGqV6{I^EPNCKf z>}|uJO0W9j6^xJ8Yv)s5gqnMpS}?0@8a$ecz=w|Zgtja{J4u5J-68U&r6}a_qB8lK zSh*%Q-LsFPBuJIA32SR>JGBmNjLwtJ`vAF4;n2)Qicpd(PfRp09_j;vQd1Py9l}t z6x2$={Y*CKq za+$nHULY?3J5QP1thBR0{<5IoEaSIs-8x_XP-)%xXo1qZ6XnH9ds;pSvFTBlCh#gy zdmRB`sRZ%ZZ3C^Map6LqU$`(WEh~$Jpzflp1+SjJEFAI9b=hlzYBKS_YK{ zkPBex9N5to2%P17uF{5bZCnjRouKMSToc+y+;jM>j{5_)V!T&rpYp5tT<#S2EVqr@ z#xFvl9b0b{#=Cud`_S_;lcEb z(ITu|d0EJqAdK){Ri&={!m#u5=hB|>aftT@+oxbK1Z4rRTuc zln~7Y4X6--*uFl*p= z)Q`BqnW8>(wDJi+oIT2DF<`VrP(ZTF2?a!K8)$LJU&=Y5)n zL@VlaT7QgQ3efDJRun#7_&7gutpUM8S`gymK@eLJ{byD#%W8wZwiGIypIk=_G>^)9 zlSN>qPS?|gRJ1Ty2}B%)&o4`un6QK)w32W~G83Ug)@+_oYg6Tcc4I0%_I|9WrVzI~lm zgeY7;VZwy#C*cKZsS^uv7GQ+?LVqaL_E!JoWi`*x#y_N9nW`6dfgU-@Z!WGKfJ0FWf3_$G0Lk>Mr6n zQG&J`c?#7nz*UlcJ3^nsy6Nr6d@Bk59)54a0j{4Frbn^$C9ah+6QHZ zfEjA27X?h-1nc=)y!O-V<;uBoMXf=^X1;?TJ1bY@YTtM8pT7LI$e&L8bG~|~_&=we z7Ww#N2pdv_KL5n`gVrI+bZl8ZekGdj;S#IBzJaCpSBeO-Y<}A%urr_T!IJgnr)QWj zc+wo`e{&`chR#Z%LZPuBZVbu;eqV4PG=PXM`2U4a0IPD)cLw0B>-1SL=m@cchFAtC z83}Wtm~hkqr*H{SZ(kxiO60-bv<|aNDPgq^$1~_DnkyOr%-KF#;CoP$#m^@UOC6TL z`4Q}J@igkmbY0|>)b%&jdr!!1y!A4kABB4#Ms5p2?IEk3OIP1>OOX9nW#^hOOd^ai z>zGbt0B@OB1mpBN^@zWO^l92%a4f9hv$L>wwYUc1#bA>|?cX(2`ZpY>j!{S$Wh73W zVpxQU0WaGq+PPGZl+VqDX^b2pO|fXt13Rfq57bLQ6)8!*52^R#J5E=86L-%PmH8wV?A?cxneS zfOZ_41COJDP$RTxg|BHUhPM*-pyEcMVL*)*>$V{a`_1>54ac|V(eQN$lV^@iITTq0 z_qMmUXIWz$sD8%4EG;CNSag&_7h}!B7kk57X`eZjGIr)D-@%&rTd4P`@Ukg_2(bXv z9^xirh8$7_5TxNtmIfPS3J5EQ5Le%Mwqo*9Y ztfi0F*5*7GL6Ke%rt1Q+7Rko!+g-+bh|q#6GN{P5Y*0bs39s+LMX6u z6Q{xY30{R$Zui*%U6j!v?Xz>ey^c5p7VrrWq=O7zuQ}1+(DYw|mqF7XywvZA*C(32 zUc(?Fp)+DT0XvZ{OC0~SvXO`DryT$5Q?{743t6>rXGE4ZSl<>_7jolvJ2AG&vtifm z*ufO<#)c>qxa;lfGZ>@|(WyN>spRFr+N{EzYTLD<%WksOa- z6@`&ZQEXh(EF!KehdJ}1q&+$}*}ZqKq}{fuykgTf$u5}8C^9KcQR%wU7UF7IxIbY;1!V}AYl2i^Y+>hZ_j{klv(Ho*rgcGIQdqMt%WEaG* zuZarkEk@|O`mi^Yq(&5e0hBs4bzK9GABz*$Xh6+@^da?e`S%XR))s6_zc&`Y*O-fJ z{eQM&r3Qf(78(?aZ)`3%R@rQM!%Q_F?0uz*flgB2-0-ia`kL43nxq0n|EPnNC-E!F zmQi8dU8usj5j6ripC1DYsd8(1iwPk7D&%l%G2c{c?O=h$ZyKuL-GDj99r=H`}qa=@4s*E`~2`{edg=H zHgVmIYhn!1*UY#-yg>2yzYm*(7N^G&Uq*3^K;WAzx0e3IwE}hC#v36m7ICd`1A|Bc z7*-Z!%RiuR|AV^|uQ_~H#N7f7yqWXy)A#~@8t237=kVEo`@Eg|p1%$n`9}U*z7793 z;`MbLez~SXOgWgHjS$1^Y;Pi{eiFThG4l^QcZ0oWw{r$`0Tu4K7yP0xgjJ>&5?0)X zT=Ltl+yN-+VH$r+>Hs8^TMk>V#=)+(nlZx74IkrRA2-zEz_o=CNl&P96VGx-* z{6;;@dA$)NK=5${FJahRa-YLT=iDbD%I2nkpE;c`ed^}NA-O!> z-Qa|CeLM#4BJGBkYHKUuTDlX#2jgQWPo7#b@18$A`skzg%`2WPy=W&bMM?mU!HmYJ zP{2!6H|GMp5npNKOP6Fv0@N4Q({uJB5qua?8qnJ#y{KOQPRy%%T>l?&{SRYa-Hq#y zsX*yzl=_OdBpU$Gf&?WDX%GGrEUe}`G~uxP)AkG=M`#rNM7I?!b4Yx-#a{(sfK`P|lzP^&hC z!iZOmHG?t}W?G^-b9lU7MTWO_jWrh*Fc=<6lY~NZX3w*P4rB14ltD1V8aohlOjQ=v zcabS{_YJn`*z^c|ITVysjjP+FDJ@Ku9em=HvgwfBdlUq!5q}$4b#&R30gTxeZ4tg( z3kw2LTWO!N^^mqrB9e2CzFA%K_Gi7xnJoZ(2ek~DQ8d|>eX;2iK{(VH)L%GQUw_!+ z&?StwWuzK`Et9qJoMujj4UUYJVc5d%wPk=x3-bykUz5>B;?~{(`EzsVH&J3Eu^4}{ zh1f;Q&~JCa(>6UcE@tD#SO491qW6-_kGd$He!GMWV5cQNEX)p?Ew1u)`-Q%nNtDW1a7p#ihdIvmoe2@K$kHstF84C2rMFzZAu zQc(z9aD&)f2qBatl8?pcrMl#UFnY&e z^bW%4O&UG+!+#!e9ceq(*7#{xU|1G1pgP5bqK3-tukWpU>y14n^X{0xpy2v^DXFn3 zcWTkCC8e`VmoChvK+Rp{?Y3&Q-Z-wDE_U++pgkj-ICp8%}T@EhRdw= zOAH%VP%k}`VDJSmbai%}KHY1GiZVoN!4GPJ-&T3x$75;Zb%Ha>Z%#EM-vTUpAZY}r zJD`SV)LA$eQfRuB0YBoAEu?|hm153F3c=jq6f>Vf1Mq@N^Vvc(OqG|?(qcc^zWwki zuebB-gU1@-g(t)bbFLaI;6l)zPQWO74DS};{U6Cpf*HNQo|LE@RRd|E99cQK5{6UD z*2ey7jaHvv=*R6k107prmMr#?##k zE^(Q>&ziNv_f=Nzd;i~`Htwr$Xnd!>v1$Lm_J7jU*zj)s-VYl8)da<84R$zl(V;O7 zN`Q67liOTgI~>_&{sS#8SLfMFLGNi-`_Y44U2a!9DkC7h!wrwn8ckn!FLq17IYmPV z>P`qFA3YJaTdWvI7W6;Gs0>2?QwEwHpfKwfg*IT}$3@V^p%|==6LmJ5Rp)MMlA?4B z3j<`YC?E^j+^P!(_q8YIGB8-ogi){y@%O}OLDJxDysLuAzgc=(jG;Tqs5&!vD3E#v zFdx|lAyMb`_A?>IAgLLc5&i7StTXx%2o@vw0ij1Ic`P~c>;&zZioT4%RSdyZ498Uv z`a%{RYMUIxkV8GccTwd8p;4k;*VN?JS#36)TW4_MGUzJ!C|%1(J9d23g6qglZr>MV zZ1qemQCslCYj6Q{8FV@CMXi)d%~=g z?N`$F+3NP&uqACBjO-DIGsHoDT&V@azcdfiNDug=U0i3+hli(L z+?OUPEtomzTf72RQWaLD)nAAK%d|f^pVKJ zlx0K?s-8QN(|hIbwR5dlnX?cIL>MGj`D3mB|L52%{t_fMWavY9 z^jMIP=zjdC_7!sTs(CB(Ihapk)p-n#`B=N%jwm9;5gl%KA3!{hf?@zk-DXD4Ct^{K zL$bGh-{o<4`$5;@mo~yxw~kqz@W>$z1_Va}Wpxio+Y~8s1Fmo!u8^{eBkU7mobT%< z7ebw7t;QSBXJ-?U$x6gY5TPs!7Qhsmu6R;Qg=hVKSGPkW&-44&h)Le_L7&B9wI&7J z-2-Ox^5vOr6H?yX2$QPxY&_rI0S{CkxQI|m4}w}GC&RN> zknNI2_JmqpntuN@{QgKjmWA$60fP03ALRk+ocNraQATarrk8q;H&pf-*cQ<|!|m!m z(^{W8dEVW3+&as)@570v^)(U$wOteX{3O6Dcv+#xbTq%ys1%##vWk^wJ_~{Xv~7vC znK$3Q=)o0ibpG|RpI6t;EAp~DXw%!Id_e0iR2F|EW?eoag;P-@@IPZ7wy`&bVwbSg z1r?dA6mYMMflK}Uey=XZln6#v13(#}$0MyXQcwi4KVZM%zhw66jq#>LGmDDR^L~%l zWDK%Yi?mIh!;5h36oW#%ycCIc6RzD9bbkRW_DGlD>rX(XztU1=unv0lv|uh;fwY6N zYlEM@@_c3Sj0_EO(Zq!Fy?&nJiqozi)KXiUo2%QAuc~y~=j7spr>2ML+O)r&wY)Ut zl9SIVc{uDn)IT&M)3^V9_$LaW4%p!qJHmGJ3#>4UZ zqwdQTj&H{dsMyuUObGlt_RfwSFTCC1HI1M5K-uE?GjfX-tc2-fXM(s@D}+3jjFcxc zaCMj%#P=vfF)u3afxrB#*6+LhdXHC|oI2cWFrm0rKaj8|Na0umy-6G7Os*Ce?TZMn z0FdmU2D*SCc)fC***q-fj9c$(Ki1xH67}bLz^WA#9aP$aTdy6^THLLj4l1mp%&>?g zq;;BnT3XyCN&|F?=nMQ2=ua^GN7*AHrLNq=&Tqj!Yaj}DD6A?D?6-!J#?(K`e!DRq zKE!y)$C>WOnFs}9RfU)Yv%}~`Zs>mfGnJnmMKqGvI~5h9&_Y?U>nh*;20`&A)4308 zUaKG?vL2uJ(B{pv5zP1>{67k(%ex3jIUw(q-4a^&Qe;|MuO)z5^|k|~PX z?hY@@7~zQSZuhtr1rN6K%L;HDYM&zS>@Ma#O#UFn)e`!X$)1_2XRdV+9Xu;qoYR32a1;ukWQ+tudar&N;fhvkTD+JFqP_O^Zns|G7}$p6hzm=v@MHCOd_n0wWu#?V z5w&hrtDY0v+Bl3fBOq$1${MZmSC_aj+p|A$VIGuwJD;1lFlJ=%!w-Wa)xY4Wzj9k$ zYk8w5qZN6fIicm6s@C!h3F7h|K&TR z?C5mtg6{%Dyo>s{@*Ru?^bO2q`n!IZP6uvSJ@LD$k1O9{ru}H+%X3?Y8F!`DD8iz0 zVll6Xs5wfH{i4RgsvzC$NMj_81-W7vlHB1RYb-IC(-BWIY5C+~WnPqR!PILO*D#Zf zTZFy*Kh|4lFVfs8!d{2HD8ha!vMaZh91f|6875Q4#k>- z_e{$P;h1{F%>mO^k3>j6dE~gn@rVIrD1TLI!}VhrULvB)<7t1?*|92)=> zQKyq}RaFWNu=0!qF=>Oyb##cF$waTrW_Wh}5pO+32hbU>%ve;T1Nh}xskB`1nJuN^ zGvT~k4N?S)S*~4EXWYT2!`((?5@x78G}KDTfdCRDb1+Ep03MO^C=N%}i}F|W*JJ3f z-{b0jgR8q8{e=L_F#!Jhkp+^paIpIfv=>3w)A*0AYwZQa!Tt5q5MCHT1Fz@S`U@an zXR2aFJ6nYi+-J0N0#;xB z8Wf$2s^3{%|8KW!l+4xDZ@p9h&INt$*hI{9zu$0m?yW2G;9zhHJ8Jl>M~VSRs7Xa2 zoWBd!}Iazh6zRm_;q!Hv9H z%{ ziyAYibQ$>WP@Bkgc7e*ZUqtu{_g$;V_jX@I^`BU#Lw(e%{fVYQae5yUh7B`nOgi1! zQ%unI_w{w1Z2$1cfZiBAa-2EEXfbjFYe3e*qIfYX@cq$qY0TyR;h@LA5_!)VKMrbC z4ys6nh(&cJj=^#zmILHPjV5^%#&{h5BNa#4!;G<<@{42H#x_BSY-1)(;PK$<@Mz{L zF?ty1&0$_L+*^^2GaX7P!P2P^wp67ZQzr_lKB@Z{&rz;m(B<~~-C<7{dE|e2?r2Jz ziyD-3sdH&6?sEfj6ia?M6`hHSHe7KgW(FP13c_z|&BC$V&Pf$z^u1P{d8Yq~F z#eyN^$I1MNsWGu0QSFZ_?bwKRMFNdG{5}V-8NDi9j`XNCYk*k6w+~1tY-3a3|174^ z%c?|FG{%YXtUgpp4~fJ6g?W7s=Jg!>x?khh<;gj64g}Ccp%r0Dfo4Scek?yB-zzVb z?ebs2Bxi+>Z8`P#KnsK}wR>fg94muU82IkR0q=l+;OsyPeM^7wY(`w%eeyDSwY*&Z zlPt=sWC!gB@7fMAib&SI-s;WMlv_6sT|N`Ed7d5zf9iwke4Nb+!92;qaVVhr5~eX` zBHBiL2zwGT{u9*v3l>5#i_|`T1ipefh-_=a##O8&ta?r3W^i{Sk$6oo zl_d@FyQ?(tO%&#`v%1;|#Z2|@Klyr--F_F=k9T00QG*d3j;kdShgb29o!K!=XM~vm zM#BAoI+NkHAoQ^GZYH>tP~6tjb-exi@7vp{vL_qxdX65m#00?2BwL0Kvsx_{uuPl- z^O30UJay950meI7T+4#%DX&rGd;m5tu}e=d&S{TB_P>CP5qJ^OtX4rl^pO#ku7BW% z0=m6^G1d@;UeM@94$n*(X4XsV1rD|^w=R}~a4tWd1nRFy2jV;2g;83HQF;gN0x?3w zmpfl*YIpVaA*9yxb$#`EihonvA9c^{I^c)i9~R}7E|{W6+{D!Im{=QC zluAGQIxxUEMW>`hoQ ze9mNyC`)!u9w8Q7&R?g7?U1LroaRDklPUv75oqdGMZGZ;dE$4?zgN;vh>Ouf2^@WQ z5p%-u+>UT}!gpK2PUPfWA8iQ_u9&SKyRx!eA0xo_BiD3nS_wm!8c_o~qm~tBW?nOH z{B;r{f1do6M<0VQ>-gAc1dYgkpPw`IUO+@`bjaJAXzK0$-gTm@$6y+kmI|j*u+P(X zzVDnzT8m0%0dgb>ez1=P9X#}FsA(Vy2};66U+?+g6W5!%+`vmZPoC&-BjrVw&$;0? z!ZQfFIy&@ba5WCrdtF~0{p$N(_gV1z#mB-I8x*UlZbWFkD&N2xtwi0;#K;Qv{rQn)Sp~|J%u@2ksw)e^;_bH3T&@pw z<_Es6mca0$fwz6eY*^2qFb{~<7EysRv@%2#%?Bq8#p_}$q5NTHvGT@(5W7_53nURu zGV89g?Ah3Jjl?V~qfedS& z-^}d9?Mtl9P%YRni~(ZkVlN^5hkw4KhDxH294qf@xB6Z`3R__zCi%u=>`760prvafAR9E5Wq_)f|;L}WtN`Rrm%o9StrKmydD9iL4!OC#7RIq00Kt-ufZy=$UBM` z{uy@6w^T#vSuK)HwSy~yb@USy7+xsgWtXj2iZC6zBXw-Nml@;ZO+#%ZZTpW4(NQRs z^Tq3h5A5744J|Dl0#xl^Zvl6GwWj6_vbt`*6^8sBCeXr2L(@?J)}u{HHTW-m)0TbR zP*aq*`+`0pz0O`xA`R8En*mc4PRz_4H#*Cv?{uB$9e_@1_O!Qqq&p!hsvzxD>2d@% znutU6f?ghKGNKNU|H3(>O7sDjiUAc{90GUa1HJ$v zG~teBoCudU{+VH(5^HDmz5lnYMP}qq8!tjtB*p3US{{<9^=Qx#lau)jO<}3P% ztbDF84z4xJhno$SfsWn)!bPLUPdQL`u92(SgfPoJZ z5`=aatvk`LB5LKL7OPGI$k$ec<_|Gg_=bl4|Ni>ai9_%1-Lkdq*yo=e_~4%hzU$_t zp&6@IWt=&Qzy~e!_nklQI(gyCPY?Y2(9v(c`39W_AZH#Lv|DtG2|+>B#&RQRzN1}( zF#ar+(+1x&2nWg|GI0!@*U{6{q2mLnVNbM$r`%m#UUDZRn~c{&MZDa3(on6dTt$hZZT#O@kwN%=ZuAV zd4%nj8Mlkj%fL5?c5_6U$&3tSy3FXNLZyb8Zf^+pNIb2)oT) zD!a{m#FmHIZN^!tsF)t9J1Bi&8H5`O=-+D1nuHMciCJSHZpKWY*ORiw;N!88{3cy&Ua**7wt9TP(60bi^@%~f>Jty?w@J(;yqqh$n2~NCi z&YT4gA_!{L!w=7lMb_|lhxhOQWWRK)vVNZj#aj$8GipSnbN&Y+okrZu#yXHhEyb9r zuKxQL=ejvqsvd;Bun3>gqD2Z*3at7ZMCcSisalM0ehsjOp^`Ah>@&)h)!^AKEQ6}} zU?Jk$o>$?0JeQ|E0=fA}c24d{^lFGA(uSv|r(FkpWY%0z$Yo0pVWJw<4!=- zIlG9@qr;y^<8yELbFU&h_tQ$Nw4GpQqkNb;sP+`I|2nh+6p)XanA}-?yJQ@4ckeYx)H~ddQf}%rVv>$wSjp(~@JD-zOUfTjCJhewjQe z>W87ChW~I-!`BWq55~YBY)-(fP6$&dQ7OnlMpPzU7b_r#H5zYY5zA+a#;*v4x!h)A z+|0zdnS^mem5PQzVibWhP0tCq&ZE#OK1J5M7<1cD|4^e)v-@PbFd$R;HH9^D0ovO6@j3qT&_fxR3q^G;|Q@@5c7Ov!xu*m z7tP2pd*7S}!Eh6qkI?!xQp&+#ni+S7GmpVam!fw!A)ofhhkLO4eI(6CpYFgkJ`i5B zzJOBoakyXqgH@{qlUKbHuVN^?6<)V?OD`pWC=-EA=X$$|9JIHq_X6TYU>iYQ0n0Gd z5oNh5M{=RY&rk#=iC5$c(s_MYr7rm>C-8#wk}6>f&|kksf8Buo%0YjTXEtVjYU1^! z;508=xDerFn^|S_WA`n)f8LziOZM)~V;!tR8YCx=$JDrQ)v8sGESsB;49O5A`2Y|$ zE*QjL$jTz^j=#TL^-?(%oK$7yEsB)PQYIeN>mgY=oht`i4G7xKGQ}ZQkhQ6j5cL-$ zl5ms_jN;NA|0hxp!y48p)~6Tk7G9fV8a!l3>fl6_QWgY|4={c}p)MK%dafk=zx)_9 zDEt~iYdr-~sgEclaKlI}<81WUJ?Js2mqVESQ1n>r zgy92~)BpA1h0`bBl(lD19>&*kX~=&UDhMD!QVoTXp!0M!|EPYhe1k}80IezyaiV=T zGW>?XxE_a<<3{w^9WW@$5Px-xB2N%kYezK3ke`Tzl<_}^1gw2rsj>pz^?x(hkza$# zD4bb(CB^R>hy{JnP;;yyKGBqD2zh(D`dEySzu*=@VtRQVuh%H^H39RLC~m{^6=h~| z6g$P`N6@N>k4}%?#P5`#m?5KyE(kpj7AT6ZS&cue&He*sMNtLQaVN5ICx(URI*CpP z`wMVaYUS}5p!ZKQ#p$7+@ED~xNy*83{`pC3``3qCn&1EEVAdFYz~k3($?4Jz#S!ud zdKDS}7?~*lfd79syjEBD{Hr@&ee=DB_iUj@$Z4o|S*^p&<{QcY{#LN^m=!B>a?-Ob z!H)mD=aS~)2avejiAlQ$Q}__Nx&s|YaR`)i{1qnlA$4m^fx$4lY5VUhr+mc zeE(g0N8dRxTtbiPIfpMpYcxTg+e+o2dj03vCa%fFNJRHHNSjBiA7pUmfJ^cB-&^P|;5g zN*kP9N{SPIQ3NWS{TDfh3HOh3GU(p_#H=D>*nV=JNdNr8c|?9*L*(37UJGBj2*Z)iL!b+i;}MNsfm2~P^>ze<9XOT7 zM7E3SwfJ9Lk;u>4`-^9)ikykA$lcfoz`kadLAq# z2xV3?EhBulwvfQ>+5T$S<$uc; z@X2g`CuoBR*&gN!TJH=i~){ri}^3%`WZ4bHHl z-kzfK@bfJP!jTmGv zpgE25vko2;(!u0)SZc)>x7&}>D|DQo>@@L!LSZDt3VuZA`>38K+{PqlU&Nh!0e7+p zbB%K5G8yJtO?7omFgPb<1Nng-X3Jt=wK-5qbxIqG*OU!l3mNdejo-6p%M8#>6N}my zB+gMwhZVCJsMNE2_7o`lpu9*Zj@tv=KoBJ^t3?T~k8Z-x61*Ok5a-}D;FdtZCm$TU zJYO|ogeBJCv2FP@BA`BOIxO-o&!RQjqSDeLy?zds@p;@G+%k>`yx)OMp!m~p13$nw z<8a%5!_8yu+HKE%kWliM0`@f+l~TE(>`U#RN|OHdthE4JEWnnF(5#rswW6e{En1G? z>k3xl&|5Qv9yni(5bdjx=gJUs^N8Y|%naSm?_qNap#DOWKzj!I33lR|Eo+qcF)-^= zGGMJ{-n@kfyKzzz?j^pKFea7sqsN40~JjB5&~uYu-}tKf=7RQmFZFI&0Yfynk07?ktio<!PBaeYdY@u`bz0fT`X z{|_RcY6UDWhApP!SWCI3yv?Qv9dh4H#lTj8DTgt7LRsNN|9iEsAMZHnbtGzoZg(p{ zh&JCq+{nx+;}a929T8Z6gI$4EonUKWd&~#+!mdDx+D)|wnht*B?(rs1EM6AQ=os?* z>Ep-eBah>joXoW3#Hf?adp2WJ>`-TeR=98>{vyJWiqWjalikP|6Er9 zHCYUCu^4E9z$MCRHb6&44rTz3kUr#iAgAj1@o&$<{o!Xm@kxC@qPU_A1}(Qf3haW> z0zAr3L%A>wO-oC282M8(Nsl<)mWJ zf75Ur3vE_p*e}O^fbg))PCTJ&?Ri)Y3NUhi5~Hi=nARUhm)Q9hN?C?TV_yj zB?YwjDLm8>OsOEeRbd8bTE&0aC(H^d#jg+``{Mnpjz{z#tTmClu%AUM<{&w5eo4VGHtPF!t;;Hf;^*DPuikNxJPh( zD{*~P4~IN2({R^NxIsS5)z;pn#O+N1zOqCu-+{l&q2*`8qFRjC)1j~MfO4+J`xxw_ z65ChFpMwDYW{Ag9QHsvpR=exfFVZ~278fETTLs+$+#q>MHx({bHGguBro6tT-4XR&eQm9K+R{8}Iy+1w4}a&u9Gn+gChQwB zW!92gq2%v|XxR(&W)Do0G92*`BwH)gpa$)qX4wXR`lKy%kF+K#(AM0_%mzR+NMdIK zD6+uo4^+W9f}(Wdyko8(5;E!%hm9C+H4QIZfGic^k|tI#X!NE*C~yVEMAS#6PaF;F zIsmR&&lyBxI-+#ZybQ6yOQQ%P_ovRj?W%J?jK6C6vi0KwE|2$uH|Pmzd%8|~LIS3T z`Y%~`)#R&LkGG%VMSD(TKRly0Ou2feAHtn}8h4s}Y=jMx-@)K^pHG{yg|&4p=aRr;AwU;kdPDqGBS#F<%0M}}AkWEyK0Ybd7`S-B7vSR(^udmv zi-Ai({lHZNgqPQ>MTV$D%ZCsG%uBH$UPsAK5O?HxUo*~U9-N@_^`34!cI*VGM``K? z!CH3-ne)fIGHT#OYh`~Bpx=-;;qyKEPjq#vB)*jr^8u9<5?R@~FD6ci{nc3Mt*=#}xAuJ)l z5+X#57%^f*3Q1TnLWHORDI%scD%EJIMN2KV*`0u>s8nf-iW)6NYAL3OUP>uVEmxzB zHXo%Jk!p+~Mu;JVB`jgH`~A+$M$y~$_TKw_`(`(@yE8j8@1OIY_nhZE$5E3rW86pe z12m!bHGhOwG#d2S+75kCU%e~!YZ(h?fiK>~sN83}Yh2PUBXfJxd#6WEnuV$N>S=j- zSACQ2d42xSmR;@9o`$V60e$5#{0lMm+-!T~#Xq(fFXni9drm2?WT+0jGI81yT<{0j zY%Vupm%X8w(hmMK)Mvvzy-Dp;9~#%?N_O`3o}g2GMj{187VbLp`RUGHhsTlP(K5%5 zO>^nJ#*5}Gcr`U&Ld{E-@-ftWHZ@-uZMD7n>Z{MpGZQ{shFgQkcrbV4xwH)O%%}H9(g!U74GEXERA?$S+uxtLAMB$}aR0lru_M^OH@vx7x$a7a z-~syStFlB8UQ|td%=kJ3T19O2EY3!W{=7eoPPs&B3~KrX7586f%DrXgNp>>yUg1YJ zA?99(r^j*!{sF?_WuNn#JeeBlBgxFf%*>1od`+=vvb(qIek4{;P|?snWsiWD{k!{nq-?N%A z!#O<@6sEmCU$ z8t&SI3D>gT{wRCWtwoshpHKB@{b`dHEWpV%?dk=klRTgGpz&@{p3oOh8r!nPP%A5D zqH_G$TF595B(AEcoRyE|`+_SfD*XV8rZZbjR~od+inGO_3Q2^O*jH6{;oGZgjCXy$ z>t});M}MZGpH&`8D65*DEdl#i+#*rZwMvJ1coEQnN2&{zJpm{9kOi~+Gshb4teO5< z^DB{~y?)_jw!E{uNLb@P(@<>wGU=Vz#40(PEf zd%kn>y<(bi&YnH{5=Yw~AD7H4X7N7$TAO3i>~Z7HbGE(q^XH%c`D<z#o-wQ1ys_YK}?u^eTsLu$D!H#P8dOu zYf7ZwV8BAfv(c_b`@t6&c4R1nc-?du3zA@aAmJmi(`Y-M|*Rc6x%|jh{TaHn*;|}6caOY7=By>MD3S~#)rgL`^2rY&B8yLIY<#nXm%w1!rJU9{gY?E=UnjUg3_ zZ@Y)so0V0IE9Mpz78VxGU0lHuU6P-u`O40;ip7I*l@BhRbdVL(e`aR-Z)fL1r8;4G zY1Qm095CmuE0GPGl#}s8jzC0JWzNA)hU2{1`4fj4?xA@FrStr71ifD{lXbrZB-p2H zaOEG`R#jCwDYT;q%lp*o6jxe`((|DN_J7!;cm})Zi&JB_*ms2TmR406P7LpK#rnrS z?~217tEVfL(826&f5IM6`=>U0PHE|aI|Uu}EaboS*f?78P(2UmY3UU9%bBuNzI&d} zTKTTtBnYmt-8sLMp169tu$P<)_hTW7sv5*oJ>71%M+tWk_tn}Jwk3CWopHL8N2Ev3 zMs#;_N;2Q3q_}NoPDj$xJ#Kqg?dql@VtRlS#p;NL)=x~E#ZK`x>HgHxs(&_Ex;HxP)w$MiWMGjTG~%2 zE_`-ey(vMv=$CEu%kR-ItLT?==$Gd~TKH65Lv-@=EKR$hIO(-tJ@M1qZo928#g+5s zV~^FH8m73exNY3HB4Ph_cv&xe_%^vxZ)g6w+T_Z(o>fdSyk&I_e{Y>-Wgf;U_Z{Tx zQr&21Z+~qjD*p{E0A#t7j67W#aE9Dxgoo%gf9$$wU38YZTfNZrEmQaYlGHhD(y=Mk!#2@+f`(f8bH^*&eLvG5BYMC>a zEV*%VM*CkSOY+_hd}U~>_FyooW#1Iv&vElbuJHTY<5bo64SDuGE!we{-FN=AJ>$YT zm^Nl+8tbuOz%eiU5kFR9Kek09XQ5X;)%NDDl8c7~hw66d)Y4Hg$LAhs{;;jRtsRmG z0P&DB+JcVMi%WLB`SI!C5Xr`Qtd*}@nh)gWWQ{;kNG26rYfp3?;e@RZtI-oRwl>h( z>+JnKN_!}_4mfInr^A+j{uBcB5DN}E)7jek@salQ;hCd-qtjiUHGJsk3-#(Qr=41h z1qQj&`DWzs^mah5t*xDB3<}ZPgOTwAM#i@p8Q*1OXcH!63ZWP*`S$;7 zzt8@6Mj1<x%#F@KRnkv`8eU7#TqiPyM$$_{-5{x|JkroCPPG-4d!14TUjid6qWz1=MVcwJ^!DNuhf4qzA)sP1LPTNxYQ){ zVTMz{U!OY+hW(>q@Z|xO`VR&aPK&7V<x(JTzlYtfLNFO|ueN$9!roUeXevl`l za19+Mx(*q&28%@eV+-Z@bwT8TB6HOM{_wl8|O}rr2sr;&lFt~zb-IZWh znl^9b@zl#rAz>vfv*qPs@N?AFz4Y`ep%pWkt$)v4yj_ZZM_%5ALxTxZR;&nho%fBU zOY0=UBC)A*iDTk?wE09@|Y?Jw+&pTwe){A@kdLhj`+A9$6|H0<)ROgibDu@sH6u+_4IUqb|R9RF(%9B z8#Bc1PK2m9=1gU+QwU2T6G5bz`JC1uF_^i9(@1 zBSBLm;m}EDelLCq8eCc@$l1sO@}N2MUq@?51~eb7kxOfgLcZBkhW0h?eAX}Xj#+L^ z+;AWgY3u|()4FS|AE)9}C0|^EsCz>8G$bX}!_2D>%JQa<95ssO`81CN)w1TOwcVOh zSGU^U(GkfmUN#FI%9>|?iJ@hWYu~=`U;o_rXZzfl01V$JBCbKqGin1(unh-P%kiLo zvNLq7CuqlrkkdaBozHvv@9p5PQIa}UrK%+QfA9Xo!tSd&fw^vsi zwVAptacFv40(a(0b~t)^B4Irh`1oL5n2C(ldbGFm*s0Z8cUNScEpj#j%@OD^0!#y_ zXDPaJ>Z6vAP5@C^U2E3V7-~u~mk;Cj2Dl5gxsr?P7UIEPjAf|F4lp;>JOfz2J;6dX z`F?FrW#tT%jl)WX60sewTgaW&^K~p6pL+KFO0}Ol0?!qz#%M0?ZMKbvRYzXHrsX-b z)el$ehfw?ui5xQ?Hm^fsggib)8Nh1TWk#Y;sNMr=x4ET+3zg04W@K2Ku{s_o6k&$fwP3&g>2ZU%KwQC(eIYzpma)k=yvz@qw-!QC!bH?)k{wj4g689oOQ zlP{q9x&ul|5FEtXI4@H`fs~q>5xH~`cOaIQ+cAt+VK(=%mMZ54ra{TQDz+B%&z;0Z zb-+g$#{Zg(id9U&&HrFutl7%~2o9w*sI29$hHZ^C2CWcOYWS-$w`*>vL$u+h%2P=? zil01}5m(0$Y6cBas#f4q&0!6-SXJd=jsF6hMZgqe#N zD7{OO>?3TY=tmt6a{7=ugYZ!}vv}3@REP1B0?w;DsCf9RVO#4~T(H~>d?4F3FPVK= z7^n+qv2~40W0ryF0PzL&zAq#2z%0 zlIGbq;4?3bz7?oewg#asUOh`yxSuqM;sZ0VlbrNQp{561kpk9oOd}ECpOs9;GBs6* z(UI3mW1TD9*^3c|KVw}rod;OP>UEY5FRZgexz_)Dx_0m2 z> z%x64Ij?0jur_hIMq<-beip-^lN&G{9=5owFJa8SkT!*mm2#ZbPj&`o3tE+v7bseL| z?QfaV+TP(c+$%G=60bLN<-m1B4tVoJ`6-@8mo@JIUD%SNfYU~oOR4m6CTlnDE{)bwiU>%(%g@Y`nPkUG$JLC(e4#4gSmj;I)JT+fX!GJC>u{+D1mkpYm+ z{}Mbf7M6ZG+th44B8b zIL1ZWu%{x}N6~ZC4g@*s2_9}i=-0r_3^xcXj2dx#T3U;6pECsO+V2WZQBH0ZK zG=hTysAp;rzu|Cpb8>d`VRw1lNz6%u1(hwtvZ6N%>LZ2P(I^AV8QR)fB=?bk>Mds) zY*02aMK;4&h%#raUTuRTTZN60$)Gc^IxZP}{}pQypT?A}Gq|6vvFzwyz(-Rt)zt$N zoN^dN@GvH{NVTm6HAhIWTPSNyxr}^9CZ`f|Xhq^HVd9Qa?z#tLGUpuO`$GDUrdK*ZxE(~ zG>2n=iohlCWUtVF|MzFzIRoio*7{e@x{DZ7v(Eq3S(S4L5WafWOzzc3y$cuHAjXrd z2%K0L%!jRG=dO~%*h01A8Atcp?xyahbH2;TT$Ltk^&Dlh;)O9!_m+9flsVieK22Vi zng7MLC-0XTkGi^)lxT?LqTv9D^+yxE5PPJEX2sKZ)a<{aS7n^j3(l?i<|2Ato?8D? z)Yp!tfr?lCD~i#mt59vJ_N`h@8TFoL)_GpM?yIO_^3ZmL&`D{6OqVN@n)eLUyD-*f zGiC;AK(qk}4k$9MS4Q8#nOwzdB|qn-i|q;6gta@MTx%$MjX89v9Hxf|(}Ji6Azod) zRxw3n25e<@b!87pT!JXD%hjzor_1;y5ek*D6;wjVZ{nT6VRN6-I5@H3!kgoXqP1 z^Z$W?_XdJ5HK3&4&o$5{O&uLg^51yW>WvcR>ZVpilGx*Ny^xW7y`g%XMiIeV-zG=) zNhFAhwz^u)$sXXiNaecEMTAKkT5KJd3$#psrmZc~RvG^!woGeU-(<_v^O~-Vp*T}K z=rr=*Pg@C?B{>{PW>a!^hh44#gqG+8U+4NHvScFH=i@A{<#&H~*$w5>Gg8DZ^qBIH z;E8KX13o-|{PL^MG!MQAO#l>-i7BVm%u2U3a5cO^*tAUdFn z$W|&d9#?W7b-9(gyp_7Vl)Ai>x-3+l88*(FaoODKt}U4|X=J45mgV2Nws`JBGWgv* zgJ4jx$vx;;JdwF*;^HFew=QwXlFQwPckI}4*gbiPF=Feszol~bR>*RB+4;vX!u?)C z(VyD_X@g1B=L&3TdDv%7fqf#`63R=&C9zWCujV)^RlzY=H%w&@IEi^;{5zeE|}_{Q#!{#wcwKc zOA695$7YWmo(7kjGs$?x8vCp04=0NmtIzW%eU{kZE^YZ^AP=O!S_6B zUr~AYecwk0uO)Zjxw}mL>MljfYUP*4#XGkD^{gbJ9W`#;xC_Q*CAEVb+KYpH_fLQN z+YiyqPuub44|2Ot{+X_{8NbUjNV*)j9PXcwY+Ht!U%|pubf|f3RhUWLq8N7sRC5uc zgP1TRp?N_0R}LusCkI?iIw)^p;bb>U;`XB~k>T;uClbS0%E+A}-Ey1qjAuFi_<8d& zCw!}-5-0QkIm4^*HhY%d&`68#F`1=hi2nljqh-35pwL==WG~-KsgL)UKQVEHv1cCw z7Aoa$SXV`5YGF(I(IFx-ELPU;cppAV!-jg#ipbX;w3!R$1#k>~;ojcf)7?F%NqQ8G zncqsFYj5u<0vJ#97_X!cMH;A1(IlCuKHqc<^|*l@DNH{eJa{+fLxFjqM0YYpx`R*r50|5dhTQ^uXlp|XmF-gPVwB5=9y;Lx+YKV3fR+Hv$G4* z0`|_d?Ci9BL#?mB3J#B*z@GNt^HrEY(ufbObGEG8)VZ#ubCY4y_w3OF_Ljr-^=&Ny z`{9=Q`j$51IvP|M&{$AV3TR-_D0117_kRA%`+``m@v|XO!XdFPbQ3(MM0-IQIEaV) zSv7g#f)J~QLSdM&tpCQ(te!rCJ3Nm&l(}E-P*}zjbCxg9$^oO8COSx$A}Lck%<*wLX5*r4(bLhe zkp!|MKPNjoGjn48WhEtsx(ZhDpYe-(F;@^uL6sRlPMR>~{4`BZ%^Z=Go;5zx z2-r>^Jx1cKSXcKNA$MR-0UYR(wd4S=_iPN}# zm7l(5$?)fZ{LZ0zW!Zl-1N(;9V!30|%zO=7^|Qx?Y4j7q#h2+DK5qM%D5GVu%c7qc zX5@l?FPTs7z0x!lJx{p1^^3n&FJC<1Kwn&t#*%Rufyd$qX;RvhBRreTcL$Xd7{4e$ z9XB(=VfrCtfnW_-hv%FuKJb zb~_t({M=duA|?m`GQ5QI4oVs7^=A0E=@G7ETt>;HQi((~ewf7Y=IG4i3dD{i_A;>} ziJqn0Ig0_=jkxLKw(e547}bs!duO{!LOYEs=?aI5I_u_nm~E&-^~^|{t0j_YTnUWH zhqAMn{}ucv9MIX@)}!?jW%Wh!MScw2F%n51(4FmEgPm&-Em156@>+;iTmzmFOM%Jl z&Z~L7=k7beDv1L|_AQis?&`8$3S)JXw-qVql>Byd(g?D-}inu6`6I zyOl;VbBqq8w^L{1z~KYNT;yN@;;kI}f!Gd9*pfL+f`M{l9s>d_Oo;+MMbx`JE(6Ov z$cg|$K8R^rGlWkCL#~sTNCb7tfLTYR_rqNK4zB$^uKh)>y@+d1n>A}@;gsnlbi6o! z%B)$vy@?l0nN4QapcMVuDHkU7T5kdgtM0iQ9MSE|@A*+7Urm}c>*jj|^tc62u9Qb? z_uP8rB;#`L$T8@)BQl2$qMr{=a~wgHZq?H+#W-^H1=g1%N%r%lFDLQkob!!ua<3&= zMy@rh>w8qzN(^|*csCC#iL9J&7S!9`JI|n~(|I(L#;mbGn8{cQbxt1#wD#I0=-;bfrXRbBVOx=j(o>@OX;;D2(Y@w_cY&Xu2jpVr)rFa1{_et$vP&Gh>Yqx@B#Z=i(iMg-L&9$x^1 zy%z=JB}J6cKk?0WzT3vHImDF!&~2Rc_2T z=dd@ZmZw-MN_mQHi-hED8v12ZY1l?*Af&~3V*VLF<-N0a_D_%HC~3%&Bl;FcmSZc$ zt3Rs!NqIlk6;u01oGm}|7h~vw10O@noR*e&=A#1#-gxQh4I4H*^{agb93w7O*i_Ei zuwW*cwn>;qj3>;R5f8ZAXZfzg7AaBjG_IzGp+u@Sw~~9*W`Z*g(6e{oQNQ1IRMU z)}5<}`b`7ZGFfXFk80a?xdM)c2Bpb`l@t6P`B&7*+4R153>$3Qz(T{3P$*Ipx2?!} z`ysCKMy^s~a)je*1~OX8L$>ADPRuQ)%WP5}bS}RZQ9UVtq90@aW}5JM<$33VD_P)` zExl_F()bCEcpfD9N=zEEEyYk47=zowvVJ)q<%|(H$ivVJcwR}Zz$z+>*`S>qVP2}uKToPr-<^uDZQsSbE zS&2`kUZn6_#^5|pAF}kU4(1iBn1uSSA((6U)MzY{M$-p{nE~gse^3F0JyoBr{jTn;B8VFl>{|0*= zHtH@Aqry~d=#tF!ua zIqiQd?Jt=Vr_%oC$;c?HyjO^f&EmTIjui`d%$+-f@hauPgu7<5E>6B^_I39G-Paa; zEg$Z6m@Sl3r-MVi&aAAiu4pFlFg_)+A2fD-lc&4p8#G-hjbTkmIhe0oLKZ~Ma zxumjb=85K~))XnPlB)W8j+F`c8cyT#=n7QDL(}ce&7>5JfUbR8(MMxW80+iotoepn z(E`baYEx-vgj>yZoPjN?U8 z0Mv8v&oK&W;62)C)xXcD;yY55vDE))>R+-lxtziZB-4*Fu26YWzxS#sR}m!fV8DLx zperK-<8HN(kV&}$B*G17AwME+^+)_)%=;@0BQebfN0+LE zgYdkR?QyElEaRXg(E=V#S5BV_1BiBe5_AKmCzQHA@YwU=dq>mQ(4bx|445aLqT_ik9;_ zpI-$Jaw4dNaJ4IWdD#Kidvufcl-QU&_y%Pp?l9-zu6XC@GT-gsbLj|s&3CQwF4Ahg z+e=#Tjc~eTV5}!|^ZPAFPb*PpTBzF=Rq!F$BBZ%uj1qszX^#aIcTjN#l>Qo3?c-w` zn`E2`FbJ`c1a!gG_c4N9{HD6vs>>^=%W2eQ9(6gMx)k3>k(g!(H?pXV1ziXL2>EKt z5*-6uF4oR!GP)|^)tp$>I|Fvl+jVtye>E(sc9DshRG(O=#v=P*E$qCfk76K6!Av^dCXrE& z8>=;GbP*bGfbUGKVG(DmP)1u+9Sk=#9%5h-3ap6_hVl_Yi zLb~5Z?Uquzh4B$8d3v^@rxq%;gO}dHy6U#&OXn^6?mhQ>chS6pt7o8@3ImhjoHs2; zWLlP?wdvTxB9Weml4uM`&Tc;5AKAL~?Sr|KsPR1I>|eGTH=1%?79#mn_2@^-vCxt!xsa`@*h-rKb_-*7lg(I!CHLUcox!x$eftWEb6f=lvr2cp zg^~GF-Fbe2v6O2s!MQ74Q^vt7=Z<96M#VQH=3j+3#Tw0$n+`+we;LisGMckYIF)CR zQ+MP=^zNEIDUp04Hk*PCDF%mveIA7-HJX@#@)&qM11F}&u4PSBupzPD=ROY z&N^X+dD;!iLy61h7x3xz@lP#o%!f2SH3aWu)j`6flnBE~u7-JkDyqH!4l{ zjm1?`M(_F>(_uNi&I0O*>X;N8Mqj%EfQuM2iVz4w8*hCt?(m@)>*f3Th7x)}bzvq> z!#UP?c(v+EXZtg@-!m%li%?Of^!vvZIMBt~|49XZ{yo8c8bUKLM%>!K7efij4&9Tg zr)QCQ#g*<3C#AYwDe10^aY;x}QWXc)eoQRm$d}$@y(4uE@61McK$Woxoi;Pd>T|X^ zNi^=u7rT+HLnK4kC|blri$Fkq*Iiz~`NMoUZug`~=O;USYt_W>nRV;2}?ci#hXWUY)DnGFZ5{pOfifoDgS&WGKmN>Oor zW#y8p8B7MhrT-o_Y#&UT^g$r$#ceDpUf$^tIr7&!#teNxK-$r!xVA6?Sv48z3K>V~ zFm#JCdVjRZsK$95^n{bZQDtWPQLG-0h5KFAq+L_PwSrc-ite3*V!Q$+s1niY=f<)PE#Kn_sGfY`-MdPuH+!nt zW6{{n|Hi`!b4jI;iP2S%;ehaT_@n{H>H{b|xuzVhNmi^QxF*p-lnR+II<>_M7SBX) z-V7?elW^cpLl18chhdK>2WTEP=1{@i(H5A2ym(RoI%Cvr!n<<7&^>vyd;mlbP)#5T zDN2WVZB1qc?lE7RR6rMr;m$r`PES_IE?^LiVvXQZf|Yt$vXKZm1o9~;0&WCKH9S01z#dhxS;9$aoPB4Iypgi=yM5IWUZ z%ov8v)7j~{KmNv=Q?KT{CDf82059acVr5AkOdLNC^TphNdgDN+Cq2!Z;`y}sKW0G# zFu^2F%EL%^=S-H4kI-?YtZ^iZay@cx5wq?-ZNYA(P@U?***7l9tDbIavrS!5LXcjg znk;T%Q+dFVM|Y?t0&v|L$(>_i4tWLj7<3LF)w-^H!-jIhU0pqG&J9cD@xvLYj^=XC zdGD?Brg=I#JVt;d#9w*bpROssQ6n=mh7b43*i`jFnb|@RWCW5lyBK@p58V3N{Q+m^ zu}`oZx3$$cZT2&rDZ;0Rvmwr?KazUN@>wez=}lt)NC3YWf7ojM>+%X?KeSD*&1+gM zsJ3&yoTcm{)zOC7KH?n6(XH+)Bc)GfKp6eX%1r!p{J)^~{iehf@8$vH@njUyC^_OK zO}y5dl2N0OvpF}H_=AT4p_-4?SmJ6d>~s#-ctQLchy2%TEWwgjAKj^V@fDU4ec+A0 z%{6SQ)>bGh&b{0cb-l7u%ZW8>IclY{iT{eQDT28!lqbi?bpKpPG zo7Iw;slj$>K8?p~)RvY&{29OAGR5k96X<&)%Vo7#Y|~<$k+s?;T`v-~O5dM^x#ddJ z#=puG6O!F|nP$LQ5?dCSVc#8F)i+nES*`qpyfT5AbV$EBiGqVrTf#L(_-xkOTKwT~ zu?ZO1W&1h^lB>*%Kfvlp*lxwDv0K?gFWeJ&Kv@XJEHIO$$&R>=yIE~JQ=1 zZ9%^*24g`k=sxw?*JZ_0?RgEK~{x}knAO%)&F_;=p_;xHu>oO z-xRTEoSYgSJnYo|x@UoWY~H;4P|Ta8JQL8Gnttsk3AR|1Dp?2Yadpn|GYD(VVtDfM zE+50l%t-HY^)Lyyzr#wY80q)1@{0R=<>&qNx!T&==8G0dg2)e)PP@mJ>7QFU6J&v< z#5|!qV6QCBA7WDqmCXUIyd2`|r%k8bK4q-LeBm6flxoKK{9 z_V%Nvw1{W;@QjS1C=+_nZ6h2kN|p`c_>C=D$;pH9sQc30j_9e551|?9={c(+msBSo+6s{iK>kaM0duh5e(l_i2dG{TQ$*N54Y5etr4?Vxs zf41=t!gw-Z&bigSb6@{em75>=>8sTD5YI7a1&(=`*UsAo*^`@b)? zPAMB~3q9fA&w!{xta=spO_+DuB8FP=jS?iLWET-$hxc#~Y+_Y-Q~AuXVn`TMRQAnc zF84W*f4g4u`oBL@d0U*KQj{kBzLKohc3Dh48`STZ&5;=LP!FEahqzx_1NKljrQ4Ah z&*(M7YLwU=wmsb`#WO&^m;q?|UFGGOk(z3^d$@PFTRBB#pAr@6KKrxpMfC9%@wORy zd(pUY(`YdN2t9J-ch5in-0%1A-?KqF`fn1oew?rUngr65Jth{#%o7}HM>R^L#fBwm z(cWYHY&RH+NDbcAfTFIGB<8Vo7e=93v)iI)PxnI8h7U%AI6xW>TW)7d%ZHzyifW0& zeZDcN$;mnq&2bio2I{C1kb|COFNpMEyAT$Fe;qv zXm9?_Gcrn^da>zv>fmM0&7~8&AKbu<-JX zV0wZ_@BWaei%45zdHH$z$LM1plPM=YdfJuWx_?-a`>vehKn_msAV6_Ok3J~B3@VdA zeDrKojKP)V#lv-1&)bcEKIKZE>7S8qjij=&JN-1ZWsH2>=1=K{gXIp>95z*dWZSkj z*2x}McS_%>VA9!)UAr3F&QRaIZH>ERRQ=~mjH*3HBKnA#G*Z!5MpfiJuyf|9O4{(d zwziW|*Rb?quIR}&V+SMbgp9CHLs88=G=t^2u;c~pKwOwsf=Q9n$;nQI%;qQI(MvY& zA80;OOT;#0L0U9oOx73(_!SaNwtm!k^yq07eZj`CBKL%*vb)RXFv%VqTFvu`VhtX6 z#IeBQ-?@y|lnm|?c_|*?BGGCIQ@S#i6>Xb&}fUYSk2S&fsB$NTwA}sf(b7O##8fb z1)*$CWHNE>x8=2@l+RH1bH?0QiB|0^!7NDPH@w3sJ%^*@Oqr{$T~vrIq{^tlP?|~x z2)}*5eSfU4FRw3OR4RK^>+VeP25nwF1TC^DcXo4+8@R`7xyNbTqm_rJOWn7n91Xq} zHSgqL{Y33%)wQubMh0#V2qPi<30l<3S zfyO6i#HNAGX^b|4pgkDirh3%0?XzI8{2r;vrjx$xVC-^R@R_%}Fp7oduv}aeSFwJ; zEOuoy6n#3nIQn<>#k&bBQgVpZd_O+#!B6W*f#Y7!{a%ssq3ScV!ju&=P?`%^FKp6& zc-N{DriW*kJ}vCk$7s~sM=dO!ott}pihh}xY`wnB5jhLtbm<_S9?-ACg+*90YHdGS zxRBmoA25>km6hZ=y5E2E&Hc^iUwvUvJ=yJN>V3$xhOGB|Kc}~0%i8tNy_&x-^orl~ z4X=pZ4c~>X2W_AJ?Y)qZR9*eU9~LZ~J;oM3@}Iwaa2}SgZ^mX~4;yEe^HEgi#w}*0 zESB#{d0@+1?cJ_%J0F~M6_R`LB9zH$MlHqmy>HH(WbB^o)}wl^P^ri&C@O>@Q+(sG`4ojsD`Nzl>!} zWIXs_aWOW)Lv5cqQ5tY-9;)BAc=44(+FlI`WM0aT951&GDY;Q0ZmKh2>r@gGg4n%D zjvCZYpHecJX-#vTe#a=K{bvJYqd#dg%!!JTv}{mz_7Gxm+98o?k0{!Z>|!84EwM|q zT}p{xdBaN7puDNgR(2J|E{V1P^bf#^aFhV$6P=Odq@XP+Inp3Ld}dwBHQMVDd}~|d zv({E+BE(EZGL_oa<@UmjCzy>@wikMHEBtuQErP7=T1Dgz-ad(KGGu9(@1k8AFi(@ihX|RfFjFfTNjh$dyZ^ z7D?N<-oAcJUwskH77GlvX^{|4*8?AgB906?>j;POf~AdB&G{pKt@90y0FhDx|gDLtu4@stiBAJ%cnwxVIJCC#-=}gR>cjw(J?!I$g?y+^n z;32?d*w!7({kC6uhXomYVahw&x0P)HcS9u7fHY16;l`~gr1;f~k$Np~8|QgC{OHPJ z8OV*@r?q?X#BSAMDC_;EPP1N`K;P7?j?*pH-zQYi_)uDpe0E0jct>aXGLp4$=Mn6SI*gb>9k!jmeq6LJGO$>0 zNN)v*2Co5bs912Q$tA6r^um#&2#8}5#W5^(MO)j)$LYZy??`uV zuiJRmlpE4xOQ|oJOC@&OtgjB@OPs-v0J>!#S!2eUbV#t2o~s?>#`~%6IK5H-_irwmvD)vh881wSpT( z`C2k1H)rS0B35BOvz~-pkYcaMM6Ur&E|Ah?gV=qPqdO(sf+4)Y?{6?hFv|C|hL!ZM zVT9*r7G^2ogSFLAM0h+M#HU<|yv{>lX+q)|_ISea8WYT%gBlYw$^f=4psWwnu)N)41^3rj z$cKM~t_u+TRzv*!z>b#O$l*7$`AxyJ4dCFkE!RQ~yig78EROa{C$ULxk0RMJs~hy~ z8Z6XnwX&W0g-WgJsgiXnMp;`+ODI&tl-fZ>*2|*%$I4!Fxv2(&C019GVJwSL^IZ^l z+QA<`reyut;wiqBt69m_%;#!~=@T=#CM8tN7#SD)k$dllqp-@9q#t~3O%eIu)9t;H z<8QzEgm6+>Q%V&}f#>S~3V~x`tRkQ_H*cOn=aI6?_J*!pE~ZLrQYp#K9_|Wap;R;` z9QEW!#w>1RqxyXuv$^UJWv^`&j|Iwa)g%m$*FZqM5hY>+7LL=P_2=-uCSJZnqS9RD zER3R0qp<<=Ao7!ilBHfeZCg~(uw7CnS=p8EvNbgP^|PS;?8glSqn$x@%nZZb+4=fI zTYlZp>z%el@^0;ACIRiQ-gcWTWS{4E_k;i5VXvCzJ^Dg*5yJ5f^`W=$u#UtR;0~xA zp9Ph71L`No44F1`EvP0BHpcYzb)RYeTPr@&gh4}nU&Cadlrc0K!%N80#pX!&^zjR= zXji96XPh2X#s}0ZCEo;~94Os9|Y?T%i+(n+}~l6$-_MdiCh(-jK@~ ziMR$Ox%q{UgXyPxmFO@@r#LtbcJY7`ksCw0oCdD)1aOe5ZtC@{jvq#^C;d5va@{+HBTGr9ATyG#MCaQy2+( zu`5)Vim5OdzRm^u+W?t67O9+ z&FfvU;-f60G5Ld+C61uezPin#-MscUCB}6 z=6->rzVoG{0C!FIdUYf@wvVwspKn}dCd4!y_RP#|-eqH}V?~I`ZVcS#V^B4%@5b}p z_>2r2-`O%Q$~ccNbI7y=Gg2%)eH2T_QC~VRJ0rtk?rQC6lw7F-{xEIH@@j3dL}V^Q zaLcQ?VH2Jd`S_fjtq<5sm7h=-(B48lTLy||mO0^0MI7DClyWD2!{xj#<6R|N%W#YT zP_3!H6VuB|wkw(Fzr2_D$iz@s3LsYa5>qg-kH!(<<2BR7Vkj}E`KdQH1h1P*JTH8n ziLb@lYdB%2;sdeOn4XZ0087jbUIQ9znkG!ZcC~4Kd&O*#M*O=pJir5Sn(tD6sa00q z6K5A4dQWBL9n5@pba!h^U(hfKsOwCTI7Ib_H*enju(cUjzkYq-YWySxxJE5o-)!@p z$q&U175#62)cC{8=L6Y7d57-Yoj^hDI16r)_&X%V< z_!$JEJmp~>w`RnbkNEOF#!t=m*kQgt`-hjSB}>tDjO7cEV>21c;~2~1E0)ggJ@mnp zX_LaqC<@7Wg>9{UrOR4d!f&~*?7wErD) z6NLN1g^r%`veNv+ug&&(_Sa_`<9F?VoM(A*t{!5TPvGpRv$L6x;<{kqz1TQ^o$ zZ`@eBe&gm^<5zyfU=5QJxstWHw=6?y+gG)8r=*1oW3#nKwrshQew#)AmE2`n*hB7g zZCVp-iKOXm$dL8QGwLG0@vE9-H+WzYf%b+VG2@DYDN)6(MG)nwo&JT(p@+dC8BzSQ?FR3AmAb=kAZ%vI=hTz-k%H6863>P^~PK*#=Ij zpoo9#SeY>rIF~a%<5)AsdgUQUQaez-sG(njetJM}$ z?J@6BDKAvZ)paOYE^|7?U1-g4a*hAxNN#1lRX0k6+cb|m{N>|r;yCfS6?3&SIHRD1 zG7dBz5mmMQodfUHGu$`Vzjq*s+8TP5i4r+Zu}xHZ8w&ZXq-5t#BeASxw2Y!rvr4aJ>M)gZWz(R07nIGv zvZUn7Yf4M5D=)upJ}7WB%?+mN{$s7IY-T{;hpT*Fz@Asu+?VadND$>uAtNQe&S|b1IAo1hXi7n%y1Ya#s0{v8c?*g41UzB`*ms`Uo0toy1PRG zdxFOdynVrHRT<}!QSb`tcwhyoPS}4n6XZCxmhxSd5E)YwXd_y+koUDVB4#)FnL;cy z;xcVhW7rt6r=(<0=Ba&9wPhB=Nm1PP`*rKq)wj7JmUbKJot0;aQ{5-lK2%*JS^ zS)O9Mpubb!yg8ITw^(i+vsZa`XtPnB(bA%LCV>CAaKMGYcAn>0eSQ5g5PdCX>$IS* z{3dP{7O>SOrhO@!P-%pdRf>c}zD#9Hd6{*jtQYkd3XGyBrlk$_L{1%tk0qiK6sof9 z!2lOXm-KfIr60l7uRAd$JN2`8_|L{yMG|2)fPu`SXJ*ke=a}~KO9?D|JD!o^ZRUte zV-@OB_e{b=UnT6(rF^7p)4xv~=l6?IMLtqp#)!|A`9!@00eqQh6Oz-ao6fO;oE?>_4l#pD+oHn0r-WVd3n#^KV+RL@3G^%$i1?0I|jzxJpgZ3O=~=9u`eiHiFpzQf@8KKis9)NWU2Bn`ibZ>*PO%oVYv!-Cbp|Jd~( zzuiL$;N363RQJ-$yV?5Lx@u9IuA@lo&(+vV$zH&7Cfn9$U+3ssQJHS#zraw5Au{r0 znV)lh+Q_lzotHD=!iz4^biesrBW+gS#o@Qa z7nDoT)vlp^{Q%huK{mm03BoIv)u<0Xxe+GJT`V{feVRbV6EB};^X>WUBkcZ@*ncX= zUd2TU`bluqQm%`Y8Lw7fjO8SX+kpomJ)HY&-$nb2!xpvPV`ynIt&=s&G>VmAF|X<{v=$M_rxtFh=rwFOlY@0fD>1_ryE@t#96$bxC zv{BszA&7kb_-m6*j+_(BHvyse9@qhd`-PEoW6+0SrKOEr6da(e=e$?xRW{hT&PEwIHW( z89^n=?P6aIhr-aKN&m>=ezT}oxf1D}awSD@UaeKr@5DB#zS<^MrgxO4FI~-5(W%jV zX0H}JP>if-RdjuH^S^a9c{#bGCgkN$o|@0qXf$-q7Z+r;^Z*yk`CQTYT#?}R;4Ct6 zdkMpQ=UKSDMBPvvfkDw|U&Ysvx?p;SGI%3KYC}VH_2Ig@SAVzdcQ{~oHg4Ve;sAIL zXV`mWcsH&^wwSy!=CY{7%nBmZ-&0tx<$xr$7E6`JPfbLqJ$2}a%v2&zbPaET3^gz- z*setfW2qw#P@y&U&fDaN8xX13xxoXio z6!{=gRG_WG2%g5KrpF##|KnnC{&<=VZBP9xbMVTR60rYfv;lc2Vz(4I28xqDj4Ngo zGAOUSyn?B-qP*OgXIdJ55%(qkHa_=TP7+fWFdh#iosBp={gKFtuGWuWw7_iRTCM1- z8Ekqm!OcXE)sfe@Us8Op`SJUZ{vk2&LfiW|af*^?VyC)frJtDbHN*n_9voNp$R$L> z_J=z=i{&0--*EnT{iBaHH8q|!N)hI1(Z5TID_olSCD>h<`%- zrN&#i>-();89xb zfx0UR;q_x8Fv;(kE6H8Dbt}?ROkZ!KYi$#1=H*Bm4E)bA@%%QfYyJUw+Kh3m&DfY0 z=_h>NJt#$S4oXfvFMGr=vRL;+RKO}rGqf`x_{j^Rs5M{-2tMuU2`hcLW?1rm+9{%! zm>^kki&V^@js%A(?W0Zs^L9|Fx7RmUlvY)(uC`5@r0fsq`zP(+Kgm!xkcfLBJOg!` zW+H;C(Lt7pN5Xh?4jVF(m(jgsoWothlUKl&5#XufUUG!PjsZmFRL(nt^IpbzM{-`_ zvnx~@hLueo=hRX!o-u8@zog^CL#Hw?xvFgLP2Xb7?lXpmLc4wmGs?rbH6B~Lb@y== zC16=HeBLe;s+`!Wl(mlqs*ML9UR%9p?XH)fd$@*Nd*1=1T}oVrWRy)YhNqXX`YKOc?elq7?aHv+L{Y z>4Lrv{yH9A-K0%2?H~eGeVY8>LKI;>0-i|NiUF1|iiq*FCAGw>ES`XCs0rbXm_SXa z_xwnpUX+Ae$Q?Q#UqIQ)V!Zj!DeKaf&7D0JuMr7KZ$kv#H21vJ$@9K#jB9-7a7Rp4 z8s2#GZ*85dBSP(ikSb@okL+uR^oP2|nHp(5_-7!!65nt%6ulG^*R*2&%pNa zu$G|NAGMuUh$uti@epA($m0@aG?2zYI=WGUhlG=^WTe<&_Asm*R~596c>S-VeP+@= z=hHsgUANs;Y_6KCUElxq9oMp6m~Y}Oma$HF4J)=~;WnJh{Imoq=OjfAxogz>mJ(%? zIyBmQCP@6}r9D zwryAdQ-H({WfNa@9U(2tc-~Cg+($oO&htJFTmXB3OaqlMIT`RRSQPcshu=RE3b?W- zOi1oLi{mZmpbMRsgMGBpG{XNyX$O1mR?lO_Cu_dJXdv&>8c%@sSZm5!QGvTvd)(=o zs6>c=u|gdGjxyQEP46>;VhC2B%MNuPKi+w??eFh4e|q#}U%0E|Q0s}4M^7B#X4!K zy6%xuD!zi|n8iA11rV1T5jZnwKY#)1+6QNt@25h{H4+dzm!F6!WC${dAhR#Mg&|FP z{tNMirUbIf`E$nd`{Y-@HJ-~PSjEk{h#?`A7)0NaVwKgA^|pqr+GlMv+O~a~1)?DZp3e&$v9a*``rr&bQEm!6yAMIGMa8_g=cqn zvKk&{24*)jMg)qXgnBy(B_zIK16vv(UMFjV-NHFT2qQeVqr-TX>=haGL41=e#b+)&G-Mq$YaTyCq?4K zt>{tV2K?$ zlYp584}m8+)$4J%RHuvNcM-SlG@#AFQ(#7pCmd6{m1_W51nWo^ad0?(`0ej6gcQ1lOw$dr);I z1X3hI`L$2Z4N;yMR~F|X;g_o$V9OBo>Uuiu-H^nA-YN%AvS9;5`{&iWO?!PSo@n4YHc&xk6h702@K!Z3g;~LwJDBF= zy%}shlSr#CqOD~dR1>2)y*JcPG`kE1Cv;EY?yj)rVkm^WK0F#B!DS{bZ z7jbP=!oQN-{}*bG)rz+L;`C8jnZC?X<1fj-d|Z}q?C8v#FJ@E&(Tyr4{0q=x46|0Ic zC%kBzdhwKNB(+3$*KyB~(Y|m$lrb9Jwu`v>LBX`qUhj0&;LqdgUx%jZ1axL4j!m1M ze0tN<<^pX6+LYL1u13u*H6`5tKIDE-B+`BIX!i$=jjSL@9R>dJU&Y}2%~^MyVD4Ni zt17Vn+_mzD-!NAJGCluag7aU#i1=8i?oLV~6_Cg6OmM?|)*tC5^YQWi-roL{jP!)Q z-pHBo$*%T~`udJ{hKwI$3|G3KfY622A|9+S9RelVYc$o0mShOX=(dT>P4=^dR7Ab0kS{!#&0(%i$mQM97 z>QDoWqo+vgLE-y$_K?))mXGvZz7<*>DMHtA7|z;ZYOe7-u8Y{}@hRGwGtsCEP7V+l zHirvZgoNZ2a-fr7VUQyNn2a>_v3|RR+1mkZ01lQst}I+M!xakm#dMd)Wm}UdD}g9h zk~7$50tv!d3}ulPKE-)(j97B~7FuZ)tyDoP$x2i_SO1GvvZYtvm3?kgjs90nl|Fe? z^ql5e`hROKxYGUim6^3vZtJ&oTdNt)h-g+;=32R}6_wk% zMdh}xxn(WevaV}pWMpJyq^L-Uhyx5~{?GTB!R+?E{C}6nUyXVSL6R#jDfxDVG`i>foR4mLG4A7OrJ9&h8JW1)5H-q@CTK2hPMeS8184p(t0 z{-B>RLX|ifN_aFmwj>K}e!o9>ExP0kHd%2kNSn^0#TAHOypV-j%-^ZVXLlSu9&R~=->$8_qmzp0fIg2NZfiT**4*?}>+$aP_Kpso zY>|S=N_$%y82SKS3HIKwL0m%jc+*lT<`e3C(B?|>I)nXT9}bgw3^6Rw8GIBDeW{1H z>JBoJ#3y&0?iV^9H(zi5-r8w}+2|@}K>@QsvLC&yYS*mN8)nbGVdm_~Q>ITu1N(ja z9W&1md+MTDv-7b+z^B_W?`J&`Cio2)^#ZlO3 z94^hl%xvCEw{~?qQ*E#twY9XgLC+5T)iF@JaY=LqLF0~qP4W>4G$u+Ut+F5dFhZT! zON5`E*7ar2MRze_H6BV&3eH}tyfFkyVmLg1K0M<|X*Vty)fh5@Hcx27hJZT78H|^( zRdZc)a4ky4d~J1e4bL{YJA46{lY^H)Um{!vQ(zIOV+ghhmjFk$F`0xQ7vk+2EPv7r&v3f6TdvSt|DwycK0?SSjdZnW0Rj zt}k8!jl<$4)@StNGy3rv1NaPy@=Ek1T0y|(3w7S+C&wiAaDC;rO23jFn2fS2j^p*J z&pLe{A?t3sRMr{sX(G(dB~dn{Vf5B8dTSV;oy=$R$*6mIL>_W{5=r)JnYpTO&KdbQBkzU{nVH+SH8r&~9V4HEZ1X%%3$bkC zXZ_%#gF&U^Tn?UPc+=DC>ax?_?$dmNvEa3P6-PQ@NMOg*G!uFip<4L_x~dZBBibx) zk0>0MVMj>2CX#C%&&6{W#V!;X%hZVZfY+Cn=A#PK;4{+PX{h9>86z{t4Yl}EV5xC> z0htOx3h6=C?W5TL`kg2t@ADBV6fD+gO694+Twh| zC>hI@N>tytYA$5uO0n-*n})Vc$y|OhYiK2~o|C#cHq;L%w42m?iQOP*3@Og#(W)AK zsFxe)+so-&;a=2dr>9>59{CaMxW|-7wYhHhL>cSBbBpnW3?6^MB{$8UJM+rfz7#l_ zxef98ig3xZeq*h|aEX{{Ny;cfaSx`P;v0NwR@ON=IX}5*d|pUP84z--5eGYFxXB$l zZ33Z(X!QuO%W$3YdojtQ)zt--gQ5_eLckxG2B1Z3z3bRnBt~%?l4*9NG(Pb7BP&)s z^5D|S$|Bxc49Y}`DO?`8!f-V-AX__|{z-=iQ;v5uj}B^u^3HJ%+_cC7 z-QAy=M6SXT8>zfD@>F}JP&-WHz2PNnHMq`#uCRECBA5g4gL z<_vppga={cHEX6_#06c-Op{E-F^qOPqn$K%UfK1R6ipbGo?bL-%EI~ir1Gs+o^;+j zw!?0@QMr=&D}VDn`YyqTvoH7^#ocL~FAZDf|iznm?7(<<5V zWt~JL_j5rw{s)CvG?%+%U2|6>l zUv$$}Ot$AeboC~>u!aDrP(&R;6Yu8tDBWAbPD3{%9!YOb^WqrPG@C=SCsILP*navA zAL#|f0{e|5K$q)>4|PPyKXUXV&mQPlDg|ET))VT62+tFT50gOLamC|C)~f2t=;{=9 z%DynT1Lj^x8B!I zy~a4bEj(n*gralP`o%lrJZ|^-S53e2y!64n`*!SXv!f97cI*04I$$@E%K4Ey)r#OG zdhBO(s|48Ywyplt>l^Y}9?&Z$u3iro?2*kIUtIU%%asuB-yfCGv8??Xm>-VACmt}EQ1L){n?Qt-rP+(L(LQvOc&ZDkW{VqQmLUEX7v zH|;U4sFP>*L+jo^=vRt*JQrKwYY_etgQ$+FqAweNxCQ$xlcAr5vNs8Cc%8Mori_MMbb_aXH1=8S~~{J=^bCU&x3| zKj}H8N@^Tclkz2*f~zCECR+^G9m*wryFcS9a%o-E8On3;N};qs$JFL@m>nU`&}~w= zK=gqMp&gFuEI*_79;El?A~!DPoW^iYr_Puo5Xjr_oHt{}Yzi-2J|*{@ne*pgdrt1T zGTAz^@?ghccW@_r(!FWtO(SQ*+8>Owu{a)FS#}c^$G8Dz=dN|( z@Cz@Zt5&x%py7A@A?gQ8CItVE@UoAJbnTS>QBKO+=73A3`XYJ{5bz( zufDTo%e%js%FL38(A{hn3#?R=vdA53#fkzPiBcm6J^8FSkJl}nqRqSN!`@_^(n_-~ zgmoWvcs=Jp2Us)_@M}(67cUu6s2g`$m+>ll0A&yulc;@Rvn+^hj7T5r-(Pt}9Yifr z`=X6C6eD`IY!zW4kD77o7>`F{>*`t7Wry*MqOCZ4cxsv_DK0)S$(1zF>rV6x*3@1l z{nTOU!&2Nyo|H~D6G_9-k|>SPFOHH>urz}3P+@KfFID3B*Bd|;QcRF|0uWTo2Zp-| z{)tZ*Tcno}BABMToB=8_h!zNM6ZS{&8Qx*-6(aYfqSREzJfAU_>{Lq)pul%>$xpAi zC^z?_D}Gv100v=70p7lcEQugeq0+J7hO>OW({DEX&`LQ8I_k&kGaOx%U{_#pT(|E1 zuyPiP!I-RFTh}4?h_WSDS68ig;<@M6taGn$4eR+N}y|b~nAji0og(x(Q(!nzG*3h}N zY}73TtF2f7)nvr;|0kZ4q4+lG>LCWKhT&WXWeql9xU=)f(N3(v_9JaA?V-+|&OLkB zV!OLEd$^;uWe*5Cce!p$%c(yCVV6P{qRq{^g{84R(-rii*OF`*N7dEN?j;}!908|D zE~=ZwJ7a7&eVW*<^!GIS`+WM_vmhhu+_B>(6klGpU}n~3H_c#oevwmsDe=C%1v93c znRV7QXwOT3kxzoz3gr>|f|)3~5Cr)x)qL*dh8+bm-QB-Dv15Bx_3wyj?sKLxnF9mk zS(IL>=`r|}^TgCg(hABG0QH8UxA7&)F{Fv7J)PXzlNP%sk5!CJkc{MM{$rJm>FsWW?t@X zR(J+w;LFczdHkN)*r@C~6ueamK+!&70M=VWw}LnY1_AXf zI;c&@T#UES`hkH_WCBAS4tL6uV=)Le_*np00sysE+GVV?pR&>}X5_`vAIZqOFD(;% z`2zNc^Gfb6Wa>s61*UEspFNKv6pNjA%q*lYbEjTu1O^@=LD1)OAAEWJ`Y%-5IjpV= zGCLB=scI^WXTc~7hgD_FzIH9liH}`|G`-8(D5A9_N>Mt53RNK5682u;SSFmP&#vOb z50EQPiHUX47Sn(Q)(sA0XsjsoSi7T@2~pCnT7o{k9Q1&$=I5l|e9vA+Vg z_yKBUsU0^;a=aR3fRG2m1S-8Bh!drt3;o!NgdqWg4?=Mht>ZMB{uaJ#VRn>!3Bgh7 zg@wh%&e+OHD4jO#lH3c&o|lt`QV=C|{FY{*uUO&t$IO#kBR_Lhu6}v-`q%$l{rs!d zhF>@wRoy&ULpZ_VD7)_o?LahysE#0df~6@Kzp+FwokXxeHd6c}+X2Eo}b|+i*UTP|of+2x$a667?!V%o^_B)&ZvT_=Ga~bkOn7}17 zp%CK~SefgQl@A)c_`*)56eQwG&;y5> zv8;)QQ0xzn$eqk4H+Gu1ncB!|ite}2L-HsrnNBoE)Rt3S9BoFQ6$@?~mRyv<`FrlXyFOHNbHRQ6(?u*gm{<8=)t zfl5J-k((e-3;VWReEAVr^3VnszkXunU(c9LimiMZGf>FMrP`>{x$}f#^!C!JvcXP+ z`O<%4gAF)lkE1Wz&NFQ7Tbk1?h=5R-Cj|O+0TB4S4(fcI6%Go_4{?6VUvtcjl3o?5f!sXS18)PHXbNYq|P#ajb@NP^HYXWWet@McGpSXRPK`{!>F?2Yjp~9d>`Vw7c1RCE*(NnV%}D|C{8bA09mfz1iY)PexAbGm`XqQaZn3ZZ}`TI zqepKsaqqIVoBbV!4<0=1=$|>@qpe%_BoDtpNU0|nnvc&1GuRJa3S&TfLuP;SC}x~H zs%|?mD~hh3Gs74@c5HKVrf0BBgA~uuOe%?Gj7o1iIv_LCceJgEeXV9co*Q&9OV1B? zm3xQg=GMMdAF8e0v|-9PvU3K7yFRWpZUnr)(cDP?M{$)GTVRW1aX!&{Nn_4ri=Boh zEG5nb2$)M$Y#>R_(uP{Eh9$@l+UMaZvUuI`{k_RU1|%nW`h&{ppO`w#2Vq#R!ZP;` z@<98Nga!yV=@7IQwcHlkJ<45fOHg{^g2Q(-ke_to)Fez5-G^i(UCC>T%)(mxZ=N(z@pD9l?n5OW~x*O z92YEtS`x=}k~_&A=T1s;rhw7&^>ayXk=uz*XCChf9k;vC0Cl_yigg(7{bd)Athzgb|%M%wYxP8IR zSgdr>uqkEa));zw_3q(O-u7dX##*x6H9_mjnC z2z2LxN_qjt$j?<Q-VrSKv_xQ zqv@i^Ao?&E)U_)RcwG1#mPsbZgLH_LY$>IyC`LdjqkvLau52tkzpw$0#`Mfs%qmbc&wolJ0;x68+n*8&8n@jA@{BfOiX8_k+=TKyPxT zJGoN2O)7L_GA?I$+OAusEp}?kK67k%^8=E z^nF2D8Fx>qD1+m3gjM2YqVFUn#Ld1uFE4Lq85Ipz;Jewtv9&}9S6cT)pL|f6ZJg14 zXxFY?hq|fik>-ruPvCyS|Ey+C34F`Vz;2zy0mP4!#eXLhkNyVi zd3UE(2c{hprmMT7?ZCb-8k<`~$BuP&>Cl27XrrcztsE3*xLmV+Q(Z-nnEy3s=nT?( zbIp7SeykocXHH4Za7Jl(PRX4Ao?bNQ$0l{3u9TdlLQuEH4ftw|}RablCQPrZukP$HsUogUDwQZWIQQZWmD zY_9#-@&5%i>^UX!*jTgsNNanysp<}!+1&JLeFIeiTiXsdCnZo{LhJe=?aZbzr}UHO zRF74$ClFKFY=;yT7p@ee5tVI_%nNSfa>FjOZr1((RF8X3QDd27;)}e8StDo{K}Td- zvt})lZMoy_S@<%p2OaPrOg;1F&B&uBOX}%)Gv-Z1NLHyou#*mn?xd+F3%--@pR~K~ zV0ZnHx@VHqJPDA)OpD;-E_TooApT<#DwkEQdt>{y?Qg8B!f}FCt*%`=mH8vv&~0em zBG9gu;}jct5(?u5=y6vYsV57l*c`Eh)%Pmmlv!gwK^;%=r2n2g`mgrxZz||K$KLHf zGu+Wm1uf7@cIDu{&vx%QaPVMT`_~6U-RRSVNe*?xAlTg<2Cw~D=MT$~lQ(z<8qS#? z80d;`YVbVQSA!>xQH^6%$x>rHqfuwFhz(LJVF*Vb!BkN^Mo?+y*V5@Ft22*xh^COu zJA?y&;I8?XWu~SM9W`p;;T^aA$D-RO4e$N1=3mCZ@#8O>IRmf$jG5q7#|-Skr0q%> zYdG?@Y)zUlv?iaW&dOE)S|bkSF%%9s7%5O|@+Vq(E>{=>ahR-m4Nbm!^@=rX{?L$w zCnRzAOQc3g!q=IIh&~whB<^QfN5@!hX>p~@W8kNe=kdfquQxd{Au-vTl49L;!m6k^ zl8k}k$o!grUUi?m%J{kY zg88iZ5A*A2=s4ma!#~YxLor8EK)-x!zGby)UMKBk;-c><2MFN}wc1E^jC!HfCRl$* zKoqyvYIW8t-=q9uw4V9WtMKsua6R*0l!Lx{=E5%zAQ)`>5~*i?3rp+!1<+4^gH-_C zIBRz46`9ByyD$a#JgMnZu}*Ho#db|wNAqSJT~A>0u6b>J^&6k_Dh)f+5U6pP_2Dup z1jclktX^7?rPEw`B27++s-&)yL?CjJ4?|H+2G9mWOBKxt91JOyhvQOwNZMFSL&}Pr zPyOiM%w;hpWX~KAitc^^^HKb2Qh|98^U*QIHE;XAyY9+UlOd>b@GtJJyBwwS zcje+Y4GY<4LfG?icW7vecUHJ1Ov!=;oPxRxFaI6-yL&fnf_`$mG_8EoCb?S_nX7GD z^{g?#nbFwjJUGVDy|we;yN=<`#>NaMrB)oo8YN`sprx}I^XYSmJ6_GPB96&(qazNg zqA0lOG$?2o?j(3vmFD1Y251gkZ(*0FbeiD~(#*nPhsH}KJO5IyZZcOVbq`MA>ITYc zgBh3Q`DQV*a29&380hCSQA+rgfoG^mo8e_+0)aebrTu)?k*Z0-_-A4{Cl8{HXQSe8 zQL+u#BJq@eep<Ma6|7U7 z!-{=rT9KI*sYN<$G)v5I?=i)j7g-qm=2;>!rRqlNV$`XtZS$1EJjEX@q(=plUVVZ` zTnb}I0gQ(e59&H4SEDz$iypRlVSRZZij)yl=5nq+uvTf1V~Ynx!v4j*+zTKX#1LJavS_`FR;$nQx1bZ*c6B>tNoyEcXO}3 zJihhF8FwuzyFlO5fa4+Vo|`70V$StFpKqy}v+b)s4|iwHF^bg^&7*#y{#pH_x}M+p z>X~Y~I#~Ha`K=AfR(6$gRDDcsRyWeVQunH_seY>k)B-gg%k?X)zh|s@__=y61LkGr z&9}Gh+U?9rHte5l`7$f_=U~3Hd#7effNr6^y8hp5>c8j@6|?J z?(7-k9L?{oiV;LR9@_}|Evsx2-|%rbrY}$XMs|)1d5PUzrB)zk_$%y9eN=<@?V`C}t zY#GaGkqlTgn$3eThg*lm-FBbjcQ4`UTmLM@3L>X7lFyp!%`N8pW__%Eg;a;)O<%KR z%a&*JBC{CHr%xKqWNS2kO|gmQdv2dQ_okWOAIiDbQ0`Wrhj2hzsXCmYOeX-g(VD0- zS-(<$s{UQA)4ba0nxeiL8%#gQbti+_1nE?i9PCpy+gg1Lro$Rck69ia%{wPzp1!6o z$YRDhmi^20`RYeW=7NZxEie~MPp_SbAMHOI%_{sAO-Q3Rlt+{1oay||XgXRtiH~-6 zcR^^>dK?gMr0oEyUtMav)6wzyCwo5os=f1=Gnvus=m68nXxd$If%w)h_Q9Wec=zs> z3K>fMc>761*<}soDMP)^rk0T6aE2%rmJVxmbSR_p;n$31kg*isqpVBGQBXs(@*=mX z&4{JBj)z{(n>9S|_Iz=pC`;XUkL)%wk~pRxHj@2Y*H z%J{?Sn_+O=5`K5bHewZ>hYx;L|Nf5cpB!ju?F=`5)<_Vjv-8;32M+GvZBQ;%s$*$E z-6jM}5c>82O#^v@@Dzp#h_8e3K2rhLmP$TzV2IP}8-5mAO!i2h*QpTC8R{F18j_Oc zJ2gGVb143RN=8!RpkmpHKAUguM9aG^!CSNI$SLQIJvY4T?LIM+uwnPH5qWtNPwU+M z*25FQrZ2EL+V8>injg8xw)}NvTYw>4j-IN4l@e&-ocIS;y})Kx^Sf1)aw>ozpz(E# z`Cl`R(X_@($dg|cxzv0%U|aR4rd~GWo$A6xd6DAOhQbLKoS$=kUg4yo$x{FfC2S$~ z{Z9YFTMO7%rQlqRIzPRDampmdxlX;A5v=0tl`Vj#H~XWb^+&|u8UU4jqqT}hu&D&p ztOe7)HOeW-%rz>BlYu>c_2aSm#-*-HCm9^0=O%S+-DZ1{)4!UnAjwuw0-Gv*}6K~zWQuW z!&gT;4{mokJG$)&hF@taA42$w8!97r0IutCP6ruKQ1{nJ&VB}Jv=olQ&Td%w%{M4tF=$7B-EqyX###NP1ze*?ALZHW91*xK{NoU zj4d_5FWOh%`v?l1^gfTWOWx3qRmrsCIq?o9l{xleSkW5zQuc zhP?IL?~%TUW4>G8rDZEFzChcqc;uhMx)v=Y-{eQtj-I6}J<9MYywDEbDTrYKh(RP{ zt`AuEls(#%fIkoX%3?oM=GNbtecznHN;{Q)5yY`DB1v7eIHEmA2d2-W4$^~`7ik6W zejwnF&mA*nq-)#Pp3K~!8;#DtylUl>zhUmtC#gK$xa;EzZVALUOYPZE_mqoE49}E{n1h5(OXuHn*MbGJ ziy7kOfq+|u(p4D>k6%`nt_Cl&jIj)i0|_p{z(Bc?zLt!I3*VBBI1e?1!)O_i04hB2 zDxt5$Ng7$=Pf`^MS}1y)BMx1Je2f~M(ex|-&J(l`Iy*fJkjQ=gY>T>q=>XPqw zsI>}m=+B?fpXbt_!hs#VEtFDSVB`n%}t zHGx4+Wx{18B}L=1vd$Wro#))w^kr)=Hn-Q1h?0OrqWN?CK=ww%?*g`NVdlt=wgGWk zBc={*v+a33dW}qICbDBv;BHTq+Pu^!FsExWG_5 z6B1mmBup9j+#}In9TFT>t+aY1NRQk{j|f&mQ16oYjC1Alb%K+Lk}oZ=ulwA&apUqL zWM>8rAsPnV3~l+w^%Dh&?le|Cx#o!{)+`5(e_z6utuL?r{Y%fRTKU|wbge6JX1c|r znVwJlFh9Kq-J&Ob66s2l9({SkhdXzEWx|CKY2Ed~OE10j8+IpHU?X=b@sQj8tuV|yfQ@w&9`ZQOsf*X%fCSgz%8sJ9%RH!E<_ zjVqaD$k;E3efsRM5VL^X7VkyheZ&FfwuBzux&gWW=4M10rO##t2ovOKF&UF@ft2r4 zpME;ed^h3gr=Q;R*}jYtD$z2Wb1YTIRql*RLS<-fuzzuJ;n=bKoR@t@MtTN#Z~A;g z;6cTk)7#eq|4?UD;zUF@Dp@&}j_bzW%dWFBkc2v_ zXl{EPI9lDt&ht$-S2)A?vK4o{3J*y*u=1Ph7=6-pNKM>}Ev>)Gtfe*MOp;cDzPZS; zX&;(D?8`rJ9Tulh&|0Ozgc&ogx$>v;XD_&}wA7j>|3|MTxYCkwf+`fu%VcKwC}i9S zu4K^Oswe-lZO6{{-{1M}TN~QLO}jqZvuoSdPwFMbfaYAhd>6@fEy|ODVQ=iLKi=6H zKYZM{aU+tuk8R(+{mrUJAARfvJ^RdaT@6X+Sn?l(uC_CR>26aMPyGl^kz8b=Ph{jtFm5bj5rE zLM!UK`ovmA`w-kT(mn*$C9NAEudv}gXsH>34JBFIcs{)|)Z)_?qC>!vr>AM9w@{?V@OHSd0~qp#@vy>Y?ql5B*I^55x3C99C@h&A8B zTV~FfHGh6;DmwM)7fzWnA&ZT7SZapIYkG6}|Cf7H^wvIoyiZGxYOBwpUz1GOr(XNe zR~472@+UNGkuYa55~39fH@Ik5lca(kb`O45vlPbc0ysgWmFmHFceoHSy8``U5(XhN z(pi@b*J=F5jZh3!2ZMfp0g>EWF^$W#3Ijo(8_+yBCSY=PG$xKLRQ7&gT=p&TxW$^G zHHeod5Ho(BdzrGiSV&H%2KNz4Yzv5bwCv7+qx1N&j?QCUJO~FIA*$9Z-Ccc};#jUF z>wDKyW7ZHjK)RUIac}l{cc(`d>6>abW#JE8imRq(^ZNChSF9lPoKK!rCD`jnALdGO z{%>80jLPXJU5Us`p=ijDyk=EJY}c1RNuF?_WuE$oq+g1I?1ezTsNiQf3ZnyKcxKO@ zgT|gwJgE>=^F?QjWv*9SVqXs{pZ}{dU~4o-6fzzsi+yVZ5dG18)*2P7jIpQ$@MQqW zap__a+8Bt=fK7(PsGza}aBif5JI1Rj*KqP^$Tbkqr9ErDOWRA9)iN}vLJOnfCa^Q! z&$j#hYe41;f|z83ghhGt$kaw-o>cOGeuueoXokGR*@Rcl82MI*q}3Kehu{a^KZNibK3NM`_sL3-hoHqV#1>ba3>(?noG7K=3259Lsi! zi`h=WA*oJh>Pe;&=z?#|rdT}*>CMYxy*c*e-ju$?s)+WaSQcz~&d)FJ>%++B-|9i> z(YciWeT&doi8t1f3!?qFaFX<{@}JwgPO*1=4O#Q8t{ilt`@Un(p6Fw`^1Ge%Ul_1` zT~Ak@=)=DLls=?C&GvTlhmFuBL;CE^@7kWy$FaT~L|^vt@eAj_D_vLYB9vh!+1!v1 zCax?}tho7F9rNILfhRz$Lx|4lDFy66#+v@4Swef;_?fp zjL#oWp+tMsb~b?X!Ohsx7B08GsXyQ3P5-8bf%q(`hBv#i@-?KKpF*~Ls1yT`NfOot z&Lg=4S51;9#1DU540)3PnCaM}r-V5_dUTW%=`ESH5_69diYQz1f%P_+?;+aO z_+!V)@>RS))v{5A(B#COb`kuO)fbs9tf2;ef_9~B7b2O~=^Wz{L25GA!ig}Q~5kT9$ zLSBY(Y?5aOU?pOVsIT8uSJwb}M$;F28tQggnIXIC8uom_k-ZId9HB&5OjmL-N^VB! zHrLWwwVPkBs;Z*g6Q4nz z3p-x|F3AM*xMa|oHt3i&<9ERn2M4M1#D3DNOZf+in)6~awwL77uLbmtL~XL@n-uy+ z*&;c*^HUz#vSr&xyS9DZ+L%6Asr#Vzop)>B{FAaQU~idyH8~?ifchT84Y@{nir*Eg zcPP|=2OAr|kSZxbrfw}c0aZ#c`Iec}a;A;J=v5yD%0e z?c;#8{;PHB@ig)ZqbW;B4^z`&B&y_{uvoYjg6p>aNRF?DmpL3VwRlEKL4WR zY$~+{1Z>BEyPB8y#@ff%*S0skl`-Ms0m`F+fS#7poO^E};e_|uJa;OO>p9IyUe!=b zZ<$2Y`~btfgQtEMe{1Qbhnlv%@0iMUZVUtx`wh=*Yxp|@yrVhO=L(jv#O4wCABXeb ziwAae3un0yrcbY_ znWn4<_cTW-j+Ej2T5tU==5eiYnbxGNRn}@v+E`^R$dV>4N6S%*)k3v|qhqxua8^Mo zY{QB`O7t|dNtvxW$%YPrRBDpHksxlE*+##X7Pou-*y5VfHET-O*A$P%u$D5;zEHE9 zOyg#syE(+6=4Ov)hbOZov#u_4M@uH5v*>tvxW4{epU40*qAkuXL>4I^T;`_%WO}BN zujYyM=g(7{16rfL*{G<{(K?U_6_U6`vP^{~^^;EeEQyoKZe-u$EO9EQ25cV1<1^H< z4gy+Q2QhzJlisw$Sh7U0vQA@(O`wfNlr;-60wytfPA)!&v|`1+rfN-96&{nz14;%N zja2tR0*Jo7n*A+L%?RkVx?bC8R94F3q#nE)sC1zFH#ei}M59S3%e%hwvu)X8$-4|g zD=V|)ovPO$@2DUo63^DysGN{_(pRD*N?-N8UthP@I;|N2TSkVGfq+@bu%ga#PN@M~ zO%0#MMT(NfMT)j)EQ$8~o#`rPA7#83AHW4%Wd=?&L1skNvLE{&7(N}JO6zd&Z7nn#;9?NW6W zEl(Xpl#d2SW}bSh`mnl!-&>Wn`Y#a{Fc_|d=I3i(@HPKq2QNSQ;E#O*-GOW9g_$#7 zFwU;7{wSQDmzS3w{s^f4H}|(}`O2Nm*JQiD0;KiLeM4_ePHqJ(<5&FI{*{kCyZ+CA zfA76NuYY#s$@ee($+YR$-(Gh6_0y;QJFC-NxBT{hXQ*dWNYraq@k40@C|P z`;m~TC!BnrH@0~^ZN}N{M+pEWxJY~LI(qW`&STy1OOtIVl`2lUZ@l^awI$JiCnKEC zF0di8(4QB95O1s}n2$^c!9n+|3ux<`bk>%}^ff9lxn$->S5_i3PwWPnd3_bh?DUb$ zU2SZtC#VaS(3-xs^$mQ=k|n|@AyasX9Z@ZlIJ&kx%sNlH!ly*%urr;ADmDPVr>sbG zB$YabvByAUcBmbGU~3|9`DNmQBr=U9V$?`JZ}ci>ac*MMkLMGMxXNK%rKjQ3e~=ow zVOMLzQK^8Kk&z#j$L{AEY?Dcun?I)cqcsl&v>xT5zyQ*Z+8ZdYiZ`&UJ+x*`PEP)w zd@JT(rvK*Sj)t59Sx~f9w)skb-Ed@FdMgeXYRWA0-ItRyk_)AnUs>6$xjCoFRS)o8 zl*Yf)Iq|9hD43%yVP)vxa;**AGW%b%gOsJoqo_v!{N_MoYP@df4GlGG;96XSGIwsw z1v-}d3$3(FK_7gh@LkINMe)Hky!rQQH`X*5FTy4nATydQ8O>(5nXRo*WA-#P??2oX z4#f{i^Q9y!q>(}&+pBcg zp!B-PwXn&$P9yAn3^xN`5gXHkC2nS~=KV$v4aUfgeXl&d`< z0*W~BZ$delt3A2>rHO#K?oPh+#@mWgQ@Zx-+0*6L^!nF#_)3CvSPh%iv22#_DUEFZ z5~)6*4pY;~Qn*%~!S6UV2M&hwVH3H?`W;Fpup5m* zOuKi{y_W#}627t_>MZrQ>KfX^>Mzx+*xH&@pFdCY1^g;N6fSrQ*K!LC2@A>Gj_U8@ z8S;DM{<66+f7+#mN#&~BUCf5~FTP0HD_G8VE1#=U=Gq&%&bD@KQ+&BiZ{A2z>D$=t z-c^6=G)r!mU`wH`UZfx=m2YXx$7A*SxLgqRz za=)#zu;kWhN(Jv)k4_W~y=~|IYGtu@^`O79wW_s#<1POM4O?5A4|YVfgh8nT<29$t zv13nLk7>G`HpOfrQ|#d3&h|qGllmtoQrhWgJ0g)Av|V0@Re%cG1l7iGcO(dYx2J*y zZ!RSV45|zYJm{Vz#SHpWyq?A{zuJGGg0Bc*L&L7`cInL z+QM47Q-yx#z@cMGOYp6z+_;9Bd<`>MaQYG_5-oY6RClE&;PPUotF#ax-xl!L2L3ylz(CQXj|6ngT12C7cH?ZoIaf#HqbE6nm=JSVAuF#&}!}Bm$&3uz;*r_Ym&^A6w|4<>~GxrWz#;h z7x-oPXxkF}+Dj3=mHtFzy{>z#jCG$bek|{jHL~8-IC?2eFWpNoJwPuN&`VRe$Y}A< zS?IM^(u*J>p`n-mPtG+ct^r zo)sAd1S=_Wg|<0_mPYwXU0AK!%k3HG;m4W~?0cLVeXI}2oHXmEE6+{$k<;tU%t=rG zk0@7Zweo;xickMy%evLC?pHKP#XtP&czQ{R+g&n!vN+<%jj96GVR1idSXUE)<5a5mPoD=M#;Km8E8#e4#E=$Ev5Gg@3{N%hcyhQa&K(d@NRJ zf7R*F!_T6GD;+g|Vr-gpL_1u<)`PFoTi?~gUc+fPnlXL7j`T$Dgh_JUU$$UWJuzI{-0j>wyGVdg2RDF_*RA{(;r z44`I1yaW2B3>xKg0ToCYKkJTL3nM#Qy+xOdOAU7$Rj&8`*$7|$sb{D4v&%+_%cI<_ z#(U39?`=QwMeXJf+shrj9beVgH+7b)$3Dez1%o1>!iPN3|4!0v+S;g<$3E(nw4kF1 zr~Sw`!8|0o;dw7l=>2+owbvs6^+9f~CMu2US!df=XV);YKWCjyWSw0Luw2^TBbsGV zU&LC1a7iHAR+9v?Q=?f3?7n5#nHiCVwxtaB^*o;kD81TT$HupnUA6-!hz1GB#a0cB zUyvZhtIY-q3_c#K`}`5RHuRhz9EV1d*;{W6*vfMElur~EJt}%foTp@`{yds?z1n`~ zcyZX}gCwWL|0;hZ%Vf-L_W*fY5V^XtjH%_ra5BDl#HTT*G->+!lceC zHD+4bCL7h4)jRO3_}IuE0Qa;`Y&@$qBL*E&RG2zI2?^&Bn@v!|k8(Ze^$U@?(7VgI^eXaY(`SSz% z@S;nH5OwCP*>7puYa8Dwj|a8-^18o*#(Rmx0QU;d{Mngfv)y~^wy#(bNEn=z(){7( z*N|HEjRp)H32k++iRi6-;`REr$%uj{xE5(vq|yQK1wnCF5l{SqA(r-MWmQ_8lIhG; zw0`NC7b3+M-g?>C%;Y0`>gw9+I*hji1C!mohxa#Yx?Q*19s0mQX{iHTj^4m&X=$gB zu+rTbvL~muA8cuFJ=E6g@Sc)J0RflWkq~TjxxoM?rTvz9_aHl zl6)yQlz^u$+;xnczz%3*-ws&XVIL}5w0pr(3*I;%J?afeNGkGS?0N$?NJYLnQW~a4 zh2;7fQ5&N#_bVaxUa{T_R9EcXOA30gh`oPFLG=B6!V*kdKEZ)$@U8EcZ|}o9PsCcR zP)g!>EY9^C!$5!KIzfJBM-R;%AwHE?13h@hrIg^;9webZYly z+%u{nJ5TYe89s6wNqtJ3yCNS9#G zf#%b;?oi6j`BBr%HaDg94~2O7gi3Hu+ zP8f1A4FdWpXC#dnT&@ouk#xGRTtD^9q!Fp*ZXTUE6i(Tpnbwo3Ba$+GLAA70@}plR zsv~I{4>H3WAoV)O5-@O5Xz(SJ~yufHSGaqz2s`wks79sQB91022W2lnmT-*SxS2dDW4ILsqo zeYsDu#mDO)1Uo}ooE{gKPE0c)UXNFgcZ3j!4(w^`1!`xrz!t?Hc&upUI?vi|1{4TN94d!MWK49dA!l5<4iO4f&?KkE=_uEs_U`Eo`m@v1 zQxk2<5j2Y|v^Fswm5F;#(J^k%)%!7IO;<*RJ~_Y_1*`URZz-B&wL`dmAotF-}I3!(@J z9?g0&n^qti$@}5+SZkd}?YBPpMb6_@KKX9W^;*t&CZC*#F(KBPHzq^dxmz_N5o(Y;=8>^QGL2}bw-atGxo8^34?EpZ%eYU~J;{gxknM!zSsqj7zK zWpiUB8M9TZzJ0ff(ls&ZT?NyBY4pqi~N1Wg9f1$-UdioSppiME&Kl+x3;;!MvHGGy4w1?Z#In2e- zOE))v-DNIe2~t<3C$iWsN7};`=V@9~)90VHn2wYYlrh8GMGvD2(X(>feXx_n-hKlH zo|>ikiY^>I#HoC}`=6Vefc3?BQ{yWfy>Y2tm%;}p4kqKl6SvqNPho;V?uvjY<0+te zkL|}9#7FfU4{LUvnIGUM#nc?S+0!E>ns~aoGpzL=${RRkJqg}wZLvdhr>6Fg)0Q}F z9PrrH#dbN8q(?QIwam;vF*7e^W=>^hmM}ACnnmQ~7n!s0iT#yy;b^PDyLC4@_$-dk zH1o_+v39OG-YgOfD{-Hz%zM}pv+%1uV*;d!He40Uh&g4M73Qx7$US1FV8&>$Vp2sGUviKRfYjpEFErhUM-#0t3~!}t5ITAliuD}+UdJX9V+EkD z`7c$!b=*(Z_?v7v(e|GD3Z`lsN#9&L+K^4RI|kOR2Mo<8&e( zqaLPWI%|gjo3z!oY){+r0(1{6h+XbD)Y#@3JSZVJNll~OVYLC;!nD1UBj=kBS#7sT zi(IemOS@~L@}-(4(~_Oy?XL7O*G(pj$?~8@r{#LbEn|m=x12OB-J3TPKWt6P$i5QO zJfi^50d*><#f z78C$$u~uez+`x2C+x`Q`lp+~h1dOyVaP{s^o~-;;ooh8&qiM?HTGDPD2K~+5EXDF? zzq1ryBfKt)@ua1=Q!OtidD^}Ctvx4};(b!5o@h&KDNbT9+zF6=1J0tA{jM83yz8B+ zs%OiC!F8?aWAI8n1`4MRd9o_`?u85I7G-CsAJ^}CW8dh0ifI#mlK_pNGlBYmr*t>s`_IPeqJwI>{1*FDWnJ#FaFAymOMJHBpj1H$i0 zaKh(nw~yCSeM3_r#n;=rL+&JRoYR%qFa5{FKn1yI5K+iK$nCVnDsEWi_+rH#pj<<6 zf*GdRVOqQvKD4{8ZYNoc$Bu^BaTHj^!`-7Yb1uB_43E~m_pP`5%eQXb*RAy%HY(J; zbH~ol4tI3BPZ=?MLzd`HoCDv^e(Be!Y6)k>bZA;7-=dO^%~yUn&GXKQu=WiqWg z$%!*YjvOl0vOM9fxZh)h0wfbw8M7FA6)>{5o{=SF%b2JPX_o@;Ee@5AY z4wbDI;rR*1+5+`5jtoGJd4l~XBcSEv+!(chYV==?$=SZC0RNc9Bb2!6z4x{q;Csz| zTXTjw2uP$Eu7d|_WrOKV8GmCTf%ccJ_JBGM*XvT8nmeubihld}l>N`f%n|j8e;LmY z!x0FTSWB0y(>4&*fhwKw=7mkOyVK>+?Ko9>jHQZNAu$e#Y^uG0T3|pN=5qD7R1;UI z8lyB)MkzEA zY|0e(;=eZ>JeOqC1>+9xe03tDGA=pPf6%d=)xWa>2%C0CQWKS@1H?f7_>DPzw{5et zzC6{`|ugMss3!#jg_SDw%FY^ zU*V;5CMk^GdQhd%yYKE8lO5hlW$ z#tYt1sQn<_fAE+Vb`Kt$mNt+?9KGCS(@o8^5p&m$Q@kN5slTL~rMMjCvF6Vk8xOU& z_o(1*RTZEPhFF9h{spUl=hMIU(Z3VvU(x4;kFtN(?%KEivF+n_fs?fDtbMMs94k|w za`nNto|;4yB$^F4HZo6tW$X6O<0guGMH@@G*Add?<`tloym-`2W*$YMa94dh5=b8p`_#_gHS^ z7y8C+Ib(h`DK;|Cp$D$P{##=t)UJPeSs)mAp(S0+Wj}?!XLLZTQM_e`JQ5;E+6UiQQ*{*lAyZ7asAy&k|*Bf8gOpL*=O_% zyE|ID&7N+>m6qnhkts_-N}Km{m#asQ5N#`0?T&zY6j7jQOGae5lj6GDyH(xU*`;aS znnFdZHsJ*7>2_*KQUiHtY5-g@tPzKMD?kK3AaYpKmPgmhg^cAm#&Qs2If$_oyqNfx zW<+%LrH+Z{Ij!ou?-rt8n~|3|It@LgI-pSBFgu`TC_*AK->;F`oKhWx>9B6x$FFXT#2IH^H=v_UFA}3 zr@3BI#hUQ~Yx=%s17751%t6(c14B5zSS1vo)SeNoywk*WG;$qxavi_qI&SAW)P{yj z0O2~RetVz!By2=oF;YG_=~4GyQe zk3d7S`JP%4oJyk8U+~v0kF}@FSIjr4Cogm()6wYW#@bARWGkULEv5_Kh_(HZLb|Uo z5IkX!T-#@m*zFi3M>+#%rL0=Ds%pzVMN6JIckWzPZ5wXiUgyA+Z15a!?+JGdKwm~x zZtUz%Iy>7?b93*vw5di6-VHEEmAamkRiaG;m)Jn;feZ*6VCVWw$z4_6Tmhk8Um!8mqxcOOGpQFQ8zV-Fqg)igcX z#b>k9blXz3C%l-CvB6+VMUGy!H`83q_7)%uo-C2@(ZxY2HM;42~nR|%E7O;lx*LtK)49PaKVNEI$X7I-;YjH*JxVLcL93uQof zQd=zcyt!CpxcVyA(<`i(_Z2ELv0iquUhX%`X+!a1-)lY{YeDlWa~w-#701)?%^i%j zZqtd^8?*qq-rHDAyJGDF@=P-#!&z)|%+awn3+eGBmQ}8Kjk(Nx)yfZ-9Pt;;+p)x+ z!~!caCzz+3-Xha$wGrld=7o_`t-7Y!(2g8N%CK9g%`Z{4Z?LUGKfQMJhuU zsc)^G3hd;3UJz}QNGw<$nGTZlV8H+V<$9jAT#v)3`a`SoN7pd)Pnc#NS9zb&HfyBb z_V1@K+KhAX6bz$C`GF7K*|LR|la<&J-uo_}&OXtfN>rNKv47t_M8Xy4QVJ15rd6wq z`!SZ%wQMy6WW6@lzSfd8w{_f&t9`mQJJzn!5WhqKr>oltKmJ3FdefTJxACUQ!fjOl zC3038&$U_Qy7J)Ay^}CyW32r_y&B;TjfGmHZdE^3n~P#Xr4>*|qgtrtj7&7N#IdCl zr6!10Dpi=H3eRd~rCOFVMYUiYRuo^S6!%(XnJ(o6?w`lYDy`7qIz-aT7Ir}J1J7`O z4Uy0->?lvLpe2_$+LoeOt+oV_;E?S2)%u=!Q*{9-*n$k29q|8v4Duxh&ip}H!PukQgG5w#$=o#@DE@qwN0+{F(n1~xGk&0 zjRgJ0^#x{>0#amUm1Ry=PY8=nNtS}WA5}C=v$u!BiM^3XSnufgy6t#4 zYy*(c*?F{w1PQlpHaG8U{`xq4Mv2L8H{rT2WrEp#tSf?%N0}(*ouZ*orw#Fvirgio zFEJ1Jp*|Ghyd#I&C>jv&Aa2=y_;7100$Eo~e==MrJ>f9*69yzYG^OkCf!0>TNJeed z>||rbZj`PvgGn|V?XhDvJ>0Q487oxLoN>_?5k;hK=wgqme3Rq>PB7eSpeqGECK*Yw zS4MiRR}Rn!X>i8TwxZ|`@-J1$w`qeqXIQ@1UA^a#6vu(KFw z@WTFt%xAQa`!+l!;oijqdS!pG$M%Of9JmmURT$rF1xvpr_`kg=u=B}ofmcAP^s;v> z!9~F97n5cH5E9NQNllX@Q7`T(XjrGQV+a!8!;T^K7HvDj;kp7e9|1v?pxf*U#5E+h z4zH>zEj1?Nvyer(f#oQ!(M*4y+7__YubrJKfYQ}C#pW4OWMdI}b&KjIHKZ((MZINs zLP6h3MJX;p2raZcCM#+ks4v1-ICymPrjQOx{v3 z6SWw`Bh?(>ej%zGO~({2!XDehtFj0V)^ci6V|ggf8!tNQ=@OBmMU@_*jP!!d0A6O; z_U;`$dNHHzCf`rjm2KO~)#74;(LETYdp~RA-hk2E!fnRwy;Z$oT2=4b-X_{w{GoZc z4s&TaXqtsQa+@An8LgPGu#c^Bk(ogoVNNl}@`}sME6wTVbnA0^cx53+F9$}t$N;V1 z*ti%Hn-(%wNRQdEqg-ty*iB zYK^t9R#q_9vl(l#H7(XkoSG-Zz0gFKgDZ<7lz+=c@-S~$sxA0wsc;Uy!}(Xl{bC9p z=*-DKFW{vs*(?4Z^4`wmrInFbl7?ZJUH|8~u4|!B-#&f5zwh_=c>Etf9?zX~ zo%ea4^E$6{^FHUi&-!?hlBr2*T^9nXJt`z!M;HpYK7u6py#Wav7 zf8NN;8II3BSQUNvaCGK)Mxtp8$gH5u!j0n$fpa)cZ;m(1k9!y#XK_^VF>*8j`7OK*?7 zfsrZc=KtF$Xg#Z8a|lZ>-z{V(G3r3hRh5B(l{AO+4K1ej&v1fY72RGtq;_qGo!F~S z94Rk9!I^+2Co2bL&M~Xcux8zNlBStu=)K_RgX+b1b1tK7umc<$A?jS!x@Bn?^M@`M z=#SGG(7nJKSC8*3P5t#!XL4JwNe%M1F?v;Pi&foFWUwbhmLKklGJBcfVQUgg^#^VG z7{!Es%p;7*P|u6hYzDS7v*S2x#*FXgt=$b|Sc|SK60C9y7oTX!ifC#!%Gj^U%0--X zWvF5ik?s8>m%6(#0Ah)fbo0#gnci{f1@8RLd{&iydh)a}H+=Q&`bYHY>==*a_3L5U(2W@l zqoex{9m0G4Aw&B{M_=FUILC+`Z+3m=%`|QmbZ@$_X0j^{=3Wld-YC#4$7R%(~@n)c);u3_REj!v$XY6zw%Q; zf1wvBPuA?V--`6NA^kO{wCgX3Rbt}3y(nmVXj4P@wz32PBgBiDLGG}o!PRVY_2ml> zyE!sKzlYgU-Q?WPbMMe_rktC7?xk}_t5>>32pcGtloTx6>~ej&W)~YMmU@fsT3-Dw z@b(s$&}Qx8%h@M`_;S>?Xk^ZvJX)Ulq?^X(Sow(z#m**KPx_u8Es#(@$!a95gM=Ak zZBM?G+)PV6nMYEB=YIL-!OS40A|8I>OZIrJ4sM#6(OY~dXVUX!MuJ}S2TW?*CSJ+p zgHG2stGBvbo0k=oWcEccJ+}UadbY$X+5&`J%PxISTI{a)+tJe*25-?!&T^{EP?g6| zWEdw{V8%~xd&jJWu#k<06RCXXJBZZGtT<16CQAdD$jK5VnZC6F3cu=4etl~VYP|Wv z)Vm1BEg5`8VOD zB>oXjf@i{?!l|UU_YcFFemmbLq?fLbDzo|W3Rb}Y=gL-$!&`Y@Ox5=U99Vk<1E4`}AG!B4)%J1N-Fnf+DBUvGZu+R*AxGWPI< z^Kkf-l77nbP=8(&}7@ifj1Dk(W=wTOwSIPvSA;>;c_kFHR>T9@yNZ+TDrHme!t zNp~hgnl`6C&dUo4Y2LXT(rJnAK(=;XDfM(!FXS7crQ1>UdDrtdO?8L}_lT@HV?!g` zu}@}Lc~QSU1N9a;3EY{$0$<-!3;nk}%X!0jOB&5+UoWB`rk|3T&(y65bOoZ_K$~q* zEBO@cWCf1&$MjhhRy75!Hce5TVE@`bzJB-Z^3##j>2IW)kh%=x_>S$1`tjYnK7!%~ zb~_$Ieui*D$4Mp%FZaY)kA3>#%I%y@SDXDR8$I%fw?aLdo4!dGbl7RwtYlPK6~vn zcxoI=W*aoJnXx`vQB`e)WG0gM1XdsRCFgqiy9)XcjiEdim~mzKpDuqbPzncn@V||x zZRSGvC5L`JbodZMy2HO8J*GD&p|izfM#;>Db@)6Kji8mlI`taRuhNIR&Jv2d^!pJT zz1ZaXMQuzBZ!j|H*onimGx`r7Q)c<pKGog&`Pt4acph|JbF|*ROTZddL#C5m`e@}YJVvKBdNSv!rx(4w z_4}h|8SXXiJRsqg-i=F29`4Hb7I!PRn{QD@>%~sq|F;{@d@Sbjj#saayv=iG@H4wr zi^#S&44HISJJak&MlBJu1MW#3eoK!I;e4_)D?kM_4DZn6mf@*vh(4REOF5#u-CdK0 zbc(#H)^4ioodlDd8IaVnOrLJQ>j1B2+Uvsx+1siwozo3^gvS3v49RsrdjszsUaB`U z>Bc5{{C4Ck)?%HBjf;!Ey)SQYbziQK7tTM?Ez$pf=N-mEcbr(y%YA+8Q$Y!hg3tbP z;8C8M0z2G2B+UBtz^ULy z3Hrl}4Vkg|`30ZvDLZaAZgYKn@1bMU(gqJ6*e5Q!dGN8)ovWW`Z?xxE?<_qQ+&nt2 z&%nWh)6&M>-aG!F~)ao*1SpIKVhp-Jk*c6ta;l-!-v9 z=*-zF*6$g109zQ>(Nh9OV6cmW&d!}Y{L{YuI)Fxv>e$s)r%#uCnadfB`cLt#AI`p{ z;ex$NeBXuZmdo;fu%OJ4`Ar^OW-bgX536w!W!)Lag^Da@lVXZ^D=v$K;N^LqC!W{8(Nl6*J zuJG3oixOP()IPsju!J{6BDQ9c-uY)}Aad&+sV&MnbGp7~aaf7m=CkdHmHUO8!#gu) zyTvj6r;^R_yfx)&;<=id(u})ztfvAGd8K(zHQ&ZRXI2DY>i?-SM&bzPDvW5T^e=va7l(L`G{ui z4!8bR?GBasQAtk*q~EY8L;rtOnLl*bsO`0fR zT*CWIktcf=_oQLG(fhE}A1kK0IZV^8RqN3D;sd9$TISDvZ1E>$lP8z$T=&M@{5RI^ zEbA1{P@sRm36rL#rHxJO+Ntc5#d9-Xwf51K;d9zct4 z?8+#(k~IdmFaZ=!cI@%?(pNHiTFXR1&F44U__ThlSn5jVI0*ikgY}BmT=A(?l>2Qg z>-D4X`Fp;DDD+mnW9%$HUqgXWb))DftU9k zJ$2f&#Fpln@896V)HKhy;JNcx?mlBSzJbqUy0^|;&LL4|n{LrfgEAUPulfC$6F}{ELa!Njn@YtBwLp2a2$u`cNscKZG7Eh_ON0^uWtvvH_ zs+FFu&EzH_{d-4|ZL}V~S-hGNws@c?69b2t1~|qTYNl9_>C|3R8r!JLzV|Y3B9}^e z8M>`{4Q564Hn)h&a3W*N_eYjh#4yLVkV!O-F2=0DT$A~j+dfk160XW}X7XGvzV%>y zTr+d0M?i@0dPA>5&K>&p6#I%sziQfo@%GWUjf(w-!5}))l?iG_T%P zCk3B+eNHrfuOs|O${CBQ^4UC49K=3y<3_yU5PrfKN z@?d&`C}XZ5vqQt$#PE81U3Wdv;`a*W6Bu?noBR$ySQ>I!kJTObE| z@oG~~;?cUF$(*HMxL5Oql*#NJ-$^~CKi;v7jONVQ>%2XFkg2hgt}15h#Tot{5WHew zH%oR%$#~6I_a7xs=8-45ch`+P=}4Y*<^A9WYsHGJtf;8C>V1k+pnCGoZW{0RQuIPi zPa8h#sova+-_sZ@aUK-5akLC=<@ z+wo=FQ~y5KjMCC=+w><=<#NrMIGL(HQ|(D#p-fb>U<^}OjMXUgup=Fm{@^)!x(sy&q01U9mwtq)r`K594S*r zj#M3}u0D{-syUjNrM}$mN^W-}w;Ph%H6uzfj~4@S#n!&8%{@X@TTO+aqj zGqb>M{lPECC1`az>2{~5yCb2ju&}Ju?Ji~L7|YjUXY5#} ztt)ER)*sV5BUHf%jPE;S9z?zHiAy|8NPuK13r*vi@S;x967biSUo6nI=rB zfh_$S&8%*R>i(Wmo@NtRkbb1P8>>gpFvGu%d4^>yL@sm3$q89%ePVeg7B`mvA~ZQs z)sy9FshZ&7D|*j1-oEZ;yRs~HEi&a{#Vm(fA*l^f@zbaYjdVzW-VCr1?WaeTbaC&nqJ}mOHtt z%6k_n62dTlh)mjjwk&p|2*94txl>Z3gV#w?1$oi9?sw2 zAGlxix)3KqR9-}(NOTo(aG&3ukD^w%rh_*BYjX89r%Y4^l*E^#{O4k3sFhD|1}(M;k}-UpKMVX$Y_Pfkk@~}bg?y{1n9p6n__Da zXRQTg1G`cOmO%yZJ~hxK6LlB?>7?~<{Axdnyi;YKHGbA(7W?qJ7n-Fai{DHAZlUP!UY52Si6R8|HD;>VY7P@y?Oce0FkrhFYdRpaFFemu^DzDv@rcNg zy!JnB*Kz%snmBSj<*rIkc|f8_4hr{_2j+OT21a7`!!3<#+Fw53*3|gFzzn3Vva8Vh z1-Mp_r~D@0v-CZVi~RYgWZ^elggd5K`X9p-krP7s`a9egUuW}$$^hcj=Km%-jz8my z@Kj#-oC!=7vHumMso!6cz_YZFYufyGB=R*eei({+{kkeezrZ}vFDQm*RNDFb17bwK zfG{yZ`?X8S-+xN9$g%$;JgfdQ|Nl1p;tRtIj1)N+Vi$4$e}t#_KlA^$;aA#4o&v(F zwATn7F2DV>;66=(Ha&;E_8PapGHcSX2LFY?Z=U}-&Salm|Gto*JWiPK6P$)lvi#Rm zF#p%^toe6g8GP}fj?@czhA#BvXp9h^xeIwN`^fc~-s{?Zy5IdUrUo~@aa!nE z9=LQKETwPg&y&A10~lx8e7toL^Z)ew&)5HtetQc4 zB`zJ`h5R?er>~zAobD~R#ol_Z>-xpyI8oG9m&kF=7c0zA^397U7cDi=xr4vUQ{E`+{r`X6B&x;VT)+%JgZ-@2912G+oRR)xs-QZANShs9FLuJ3n^ z`voS?gM9L)%pOc%D3xbD{V!xqb;?B*?gfmEa$NM8y?wa~@+-x&)wR{LH6Vh%M>+kz zY)FGV+=`$S;{Uy$n!cgai+*Cfr&OE77v?Z_(z4it>37G|&q$@u0ghlth%jV~g>)$P z$*RY(I_<7C^f}{ca}LvAE0Muo%C(7GnaB?0p1`f7qg-UuZ>^+GRR)!bnBWQ6Npn!R z*UYC}RR)!dd?$hMSnUR@9JVyK%fuRo=Zz5LMg0= z3RnTDkOGO?L>`^qHI#{DyBA~8Kk#HxrgL!5v!X=A|AgE+442NwRg`twJr`##{%>N> zrOr<$4Uyz4&oV1Sn;tjiI65Fyq-(5H+6bPX4)R!Kv~~LVm6;M~Eiv*_ygop&{ zXtArtPbJs=cCLBvqwKip*W{p2Z#%?T%NJe(=6=AWk6#>+jXjk6qbcWvNt|JtzzE?E zz#nZ&4)q}gxzh-%IIsn72nC}pWi@ncuJ+bpdk{*kB`=u`Oh&p7(VNR!R=8F`E zaRT>g*|URtQSU0nTxYAduE$cxSLt@hW^WHyx`^}6Onvz@hvNhjcA&NBK_9H~(*{eubju?in*HEUi?XBWMipP&R>^)oL=wL>DcTI|$5+l5`MLNSdX91`M4oY&K0&UeE=iZR zQ@*x(aWj`1u9pY+u%l#>pB0$<=-+Pj_Hm=6`_KOW&aa9R*~%p%RjQY*rk+c}4I(vM zk5CiDTr-XLz0<{9<`w2%_**R%g=VZMG#ZHYhD+=S02{RZ4}8~F{qfr+)?8p;Z`W~E0zD|hHJZIQ2*n{6n7=Sogsh&ZUx zc6*gbwde6{T}s}EP=|Fr-lr$t#TrwGQ!W%LQ@7;N$d0(~`YCYlLiuv$;wa4z;VUi}cJ-0vwiL$H?+c9zJ}ahNIi z*Y+%tsC2oj9*aAD4*K51uqUx0 zKmxk_M}G0Q)Jrno)6<`axc?jX21e0-jG)~tz)Te>fty5{9VLbZY@pqZ!>wGT@$o_m z?fc;%&e^I}fw@5p4q5?uKv}`hU@Kik>2hSH%L2ux5w=^pHI(5Ul=&jc@Lb4)5)E~G zg+c!f7I^)XGxyAEW1ux+6}qSn5#n@zA4~eMR+2bUD~WsP ze+RflLEtWQ;3Krg3<#H@LE-oTJI_a*ULqWl$!imO`G0G-{})KsY5#u#JwBr?T2(Wa ztIgQWDf6tS&Xq$RZJ2iqsO?nO6_~u=r2nVq>wPTMV@TW!=_ePuN_p3XUpABu#2G=lvVzN{3-@Tk&hz$7X+LYmx<;{Xbc@{n z+Pg^a7+sIctB{K{`{V29b*Ej@<6tMsv%^<6&gedc8?p$iwl?+en(-=e=X+(R&q4c3 zTxT2LR*E0phHLf{PAu***mav6Lwkyw_qPr=9lLIKTlk5QRVbU5`^&|WZ_-6r@=m))Mlk=rFEmbL8+s3sdi~;JoR5h6LkpEAFW9tRVkOd9LaCnx(F}UirhgK3$Jf2vd(YvtgmOqnlDg z_uKV&#y2L|fmz6PJx`I0xsC9$@tcl4!L^>}T)B$XznSmKVLX>>>9HOD{p8iy@v{{4 zb8@M6L%1k?FL~_3Z3AgS=ITVkk0I^F+O%`Lmg5zd4K--oqrHJmp55m`VC3TnP7| z+bVZRgyTZeG3)bZDfqaT#WwGiHAZRJ{l_nF_%+Tm?C<|6+v zWS`4;_>XrWIxVDOm#(8hiQY0pdQRu!wt{OrNK+wcosPK*3V?jAin16h9gy8P*pE|jeES~oeNE^U&2X2)>17SW6X3b2AwfJ z;hw>|ZgPDgtif*qW*($M8uMmzHMpn42JYAIFmm-A1!*p3Tv?3nqtS0Tai)Q;CtG0+ z_FVm2L)=-qEHk&eRm1hU+!Kepmg^62*L_4yvM+sSk@0LPa&86M0B@SL-sVz2_*b|Dt9+0X3o-J`?y zx|g7ra;;M*%3F3<@LT6+O?}q7PD4*QdM*>Yo3tcqu$R#W6mxA2_EZ;bHRRgfx_hQj zh*PCdrQ2$Ud-c4EZo_qZq01j}q!SM5I+F#%kcV>Mm45@Kfa!oPyy=ZYZtSPm_}lSt zeuwz|=VA5&!qDkEL%M75rZJUknsi78u2<=>_k-#CeKru?(P z>$bFl`}O>N9&^^k$eirU-?ROK(H(x!uWm2&zcWc*LsS(LPpJ=GNA$mcy+)Wz(M>6B zRg%V`Z8XaHaDehoxVm3eMcAgECnVk-$g&E#x9T`u2|T+~X-7bZuIDp-HvLQ7;pZ7f zT#WBzE9e4403FDqjJ{a8sG7sIa0`ru40sOMty_Hxd*L)Ay1LLBy29;nFU)}#VIzD8 zM};s0pgG`=PZ@+c24=w1@H%W}M0gGKg;J#11nvt!=D_-J1t3Ep`#uLDU(iGFEUW~=3nIKA z52IJYsMQc!0%fNba@4L1=%F_0tBoFN6J~AnP@8nrAsux{M;&xr2OZaW7#71Cpnlfb z59DV^1Birp7zSxD7xG{|6hVa$Y`rJywt!d|3=<#=76Sh2k;V1e1G3aZmU_ri4_WHH z2=Bw!@GGBF7|;~1g6=@ss6Pb=r~WY^*mqkr=meWs8a+&iMopjt^nnrZ0L+8e06&)u z0`3bffE_@a)EHSBhe8xk7aAwQ6F{08BWq*Q)cCLvO-u-bXqXJ&z;Ar+&a_3->w$b| z`U-pm-@@;L*HzFAI>P`U&%z!8{DzTdVfYQ(10L47HiH}CZg>cmz(+t>mm>3J{U8~p z!+gkxLMVZge7r_oX+~XX77OUS89Hy41q)#fYyHV=bnz;AQ>HbN}*DSD?%Uw;vf-H zAsd!L0qlS>p_?bsA{3&a7vQ%Aep^ufTYLdO!wHV%B@bFsmReGlT2hu;QkGg$mRi0G zl|r-%f#JZlR^)A~ zt_PHpt3QD~aEgz;>cEw7BitrLyGGC!dIEB_n+8t+X>9i)kj8dLgov`?GUx>TVKmHy z1@IVlrS^aS+OWg0vIq_@k5unUfG7_JSMK_}=BqhTg2fHz?a z{0Jw7h^q~)pbHFvRY2ayk@sE6`>u(Q3fX{+T?=3bAZNEI=mmGdG*W$Sr&$akWcpA`Q{0Hz2pqn0)&mNS|9@oMxFc$FJ;{`ze9?0JV z`FkRNPvq~3{5_GsXD*P2p5)_Aje)ptBJP`r`zGS<6$a7J50Zg=?KL0r0e`*l*9(8W zDNnuI2+_v`?&-rleYmF&_w;!HC>MQbllp7|>RX>p`I12SO1J?iUkT#@ z-6Wu!gtvh(6Y!frn70t-Ev=y|+z$7`9C%TPfuw67=^D6Bh(TN%#I-?O8^pE2$T|2) zA#UYacwYX=YjH&v=t~bNtBu4!9bkDV__hSfCu2X5F^?`Iut?)R0uH=|07olkvtm~!8`B; z{0!%W7)5;_bv5(=@@o|Je6$2~ImU*!gh-(*q@bsiav{b(4CrQTr4ZxL%{bCM4n2$` z-Q&>BxNOLU9Z)93c&?4-+IX&w=h}F5G`;}1KA!6n1cX8q5XXe)fH)_R7ZdivX^y(B z3$5X9xDOtOoxt^bjtVg`0Jt`B3!tZo=xGvVVA5rPPA2sP%EP2eAyPvi0+1^exl)lU z^<5|e%E7&qgL~1(z3EUY#N<1Gax(cbplnUX?_}bhOuSQwcS>`>&y<(p1E38^8wP1G z7s%^0@;Z&YPCF*V)Ihi#IsoBKLyl>yg}9IO-`5M0fVl754BrWnJ`m8w{rAIRs1o9V z1`rAHFcc=kqd;5_5Z41=3GrZ8_+2pc1N1(FvOfbI&cJ=f?Qk#50c4m#nr4oK2jOXW z9f*JC_dvONCtPU#hfH_@-Uj4*XfK=+!j1mi?SS&+z7wVb`Q=7GZpxnf3-}o* zdl{6y40N4=-wga_;5UQ#W*JZ)h;tTk&LYlPJA}xjtY=Xsv&h%1PC&k9eJsRmboMZQ zAO2E^N9w?ASOld)WTU_AdBFX1!h!qd^aH}0L%o^9wK=cBCcyt3%E+VF!YbG*#AA(t z^gM=)kKF-NfU@w|OYlB?2b6`m$o}}1K;3`*j1W(RKm>GwAutghhQ+WJcEJH5o=k?H zgvg;>=ivU7g6Tlq^J0Z~+JgS@GJF8vz;A*fDO?I2;bs^GZ^0+3qHkbO3bs{NsR5pMP737bx2=%n)K> zEtmAPy4YRoDpR(_(b7g!C-I;}Uee z1o@T@hYz6$4h!)jI)8B>jDuNFEyObPukmt+Gg?J?p+CV=b|6ie8ys`p517uiH8(IM}zDi!aiVj~zhp&Di z#A~GgwVQzaer=NwucO1)(c$Z#3z2U^0w7O5`SZq;utA77UGNkT{>plQ-d3WwmE_|p z(!1(K*eS$Y4dGtcA;ju%K&H3rz{ z^IZu~z;Zyp?~?X+j|irj;WFq1{b4lBgvEfr_kM(GA>O|Xy1-p96BfXmupJHvrcD4p z>+!R`Oo$ICiyv$j;=?&5!~yaaPKW1V6(DaRem=&}$Fv(ClV>0A z2Fk$}@?}dn!~prWB?a7&3*5Vf@VAsgr4XNlKm-uSCy79~Tki+-{b^qq2@k^4LVQ*i zNXuuW;dA8vd?=(sHY|k#*a2likW{fP6r!LPBtbglzzWy^#X@{B2961_9rH^Enn7n6 z0NU*#cotT|C$I-j39*BG*nz(tx50hzEUbfX;gk?NFM)PII6Dbv=OaK}|LR#Gz9x^q zZUut@y?>3cMJ?e5*a9bo_@)tX?>FzlP9b(R26VBDdcSKUd?&=WVGs?J`)@OVa#GwJ zt_8|NF>c?H{_pak5KaiOn{vGyJ?usgyN?L*J!S3t5%4-+1abO~l=0lYEL%#^|YYcoX#Nqpe_$?67$q~%oN!RZm3sFv(<)opUG#o{5 zN738S&xANO6A1r!D3EW*(RBssuSf;LJ#nuPC+ov?%&n7#QRFbbLA(D9dMp zpeazd&JgyQn*n{Exd&#z=QERI_LvKVH`XFb73*O38g{?hd>07{@}?#oWba)7ID?;3$x%gAYHuOm9+;# zwvcs5PaR~egP!Uf6*9yCWC*zd1^{UYA&nuMg{+Hy>s|vr;5Kjr`l?HQ)IBX^J$6{F zHyfT6vi=Am8zc(Zu)pA7JGfiOOKQU;AWfm8;INR56M(#If*egqTNBdLC1Y}FcYYsI}+wgt-4l?&lJAtOk0#6Wlrb_&`0DtH5a6|xQKYqM8K=B(sZ zYlMs>u1I8vB<@Jkc(nzDcXcly-B)J-vRqv*WLpIdpcTYG9~cG`!42~OncA)uvRxC1 z1j28JzS?~bKL{BW4jmvKhCm8XHlipSQHx;}Y=R;<0F^?v4}>s4uJ&<2+S(_>G{}bM zVWW^8kgdbD@R*R-kiKhr!fGKoRYyh-g|k9-Bt0F8rz7!nB%Y4M(~)>O5>F@M=|nu8 zh^G_rbRwQk#M6m*IuTDN;^~wRAHvUYO32P!>&&&zbKq6j3Y7D>Q0NGxKkf@SBV^YekOQy5_dxmRhQDs9@G%?{vU>s$clRAY+3#L0 zB=b!&zAxMll#Td3LiPv&(%l2M9_YWvS|IKoyMg<9HioNU1Uw1ozUS{k-qaMv0QcR* zeK(Q*|5JLU2-(XGxv&BX0Qq~9mfpDcUInE>_Gt;^Lm&M0*#Z?p_KgAZr7!u+9F%1K zN%rdmGXXz0UkT{r=68W~^(RmJzaTh83_1YidcY7sh5-)%c`yJS48ZRIbeDjh5-tbs zOQ0+yBmy!eAXCC;uwTeq1fZ8&2is2Q`8l;YA?_*N55gGMp9i zR@&lQzvQ*sIw5aM6Ed+5B!jlUDdg?-;5v8^sFQb)raJ}zVGO$l(8;jHLf%Q6bmv+j z??NYcJqf=Gc{ldEN5XRWUdSZEP9hyiGhhvn&f!MwUIZ# zZE!D;=Ogts+Mki=d*pE;lWPGoB~zY~?|`X5{K@Dtc{3n$GIeiMU7$=cS0qQ>4V0l# zl*dtTz$dU5(8uV8&<=V7vX4gA(a*wL@HzYp9wEmx2GT#~W*7q*@B+L8U&1d!rWkN3 zbcS1CJj{kAK$%GS8h#UUtOL#AdbkxP!5nxAK7eoGsF34=pe5W0x5E^89A1Hq@I9Om za(o?V4c*~RxDTF!*WqK>1E+;_n_xIR2+zPu_!NGEb3)#83ABg4FbW=m=iqJl z0uBn!ID)3o5eC3m$b?0(4tBz?LQb;a4nX!vj{#|%^getpWNKaDzI$B|4j;lUH~=Sw zoJ{$ioCU}A-!Nxv&BXU7%7!0#uB@o|} zr-aO*jOE-2zzCamz0oh*I zF62VwTUg9#pOni*+k{+9-Ykv>(z6)37ta)ONdssBu|T?)d?e&j+Qy}C!WJQ4B;Q|r z8c55se()}!gJnO!??S$GH<139DAO;Ir+I{z*9r(Pk9hKkCvO?N2VVjC^D<@f<=267 zxg5PPFC&*P0`&XJ9q@~gD>}g~FdoRa6;A@?VZ}KiUrht#c@2Fr_aa|=5zY$vdISuC z6v$vtFl5PZ3ta&B`~^V1=5L0tfq34SF65i|d6ROmlKWRt&Q_7gZ2;=aI{dC9i~`D2K{&)gBBTIv6y!ny;P>4ypd7u6zTWE& zgJ7(X?<33ml%4kl4dl9w zm3bWb(JUZeKk^8<;Vw8J>Yq z?1Hy}Jo%X4Tj~S)-$EQ)s)YQ6v~9f{2aNrjew7U^8ZCGz~2{? z|1XebdrKGw$g=$npiXT^-Y>5K^!DWT4CjR0*#d3{%GA#H z;i!;b1wk~BM&?B1*K36=LO(^+5ic_^(Zx3gkmui^vv0b>AQ%NN3b~7NwTp7Ki*mIK zee602r-l5sBNPZ(Og-cAH(~BhgVk_S$nUR$B$xxcge(aKWQE?HkF&vLB_`KxG$&Jq8)tDrlO?sMevIb=PDUd~ZJ ztBIq!GoVKg<<3Lgp1Hu;dn_;3Zc}Uumye;%D5gl?c8_|eh|uJ z*_e3+41fpW1$aX!)_y7LW_S~-gtFt|X&_8{k5EosxC(9s;&g>UPZ$oL3l)$BgdbQc z6l=Cr(7W)HP{Hi>7d%9$TBBepaGqeTXW(U_Sf{1xm_mghe+V+vy%d&0nNal#g=#Ps za)oM$Yz^NRs!=H11&_me*bcPFQKo ze$I{AS+wz^unY)`bx*2EK9GhcCxmK>+^l(0VWcr^p-`7Pzz*7%cJza;E~SpLdaXjt z7r`P`IQrKG|19tCo(3(pc9nGm^KyQBh_LwObJwS*2Knvvu+{O~>x)3q#BXmP>atwO z=f5HMQsTW~HX>$ftJi)B5>N`gcD-N!&3=1h?1TLFCZd+0w0ZqB6)rK_Zx16@S~aix zrN~3ex66Jn6T)giH1D+XFvs z?Qwp4L+P?l z*om6(-f6=pj2+n{J#F&ve){TpoBxv6)%(ZqFmTkEsS}1z_T6~%sN}Iz@A3WhUmrB; zp0V8~O-QaW{m$A+J(~!JN}O$Z0%#J z7$Mqn*CfuiYv=WS4}RKlwI=k|7sND>7{+kV1Th@H=OwsK451~t&M#$qY*F~=DB5Fo z;+`mCIqy51`TPsR8Nx3u=UAkeh_u%rQ55%HE3Ws;dG+6hclDpbyD+9(i8mZsCbHK1 zVx5ikYGydDX~aI9>!Z+tPS<$cCehM`d!^F)X#0n4AU>wxZ>sn1uHJBc(ogY9uXF1{ zJ?nJ&Lb!+U+x<&E{Q0`hU7utSJ|^K_Y5HSwcl`ZO6ysN-0z|gB60b1UbH9e8eh5lt9Waq87`(F-&k+i7{OmH z=Y9Ova_Ah;@pcurcNO%vWRJ%^ao`y|pN!PBCxJ)K>qwu9ut93UCo33*{jfdkl%6o4L zVfbp@--UW!GdcvF6H~l;o8rwgT~Z$)JRN>l+5{C&)1~8lPNm_lHLp{C-u1i=v~)Fo{z|%=yy5Gbq{~{e zSGJn+Fh$%-{_1jgu>@l;ic3qSOTuV!T(>l7NUJrT>Ww*tYoqwzoh!Pm=n^&@f8m_O zbfLskxT^DQkT>mP@G**Trg%frA>5De;o>%IHLdI*Z)`eueYJ4nAEs_Oe6i>n*8|=9 z+6-NPd@b}}xm|qMdB5jv7yG!lRlG39n~_qN*r}A!3+)%*KL}s<;Hw+Dnt=a5|GwCF zjjtN>;;ZM=Q*-@aT`s<(n^$`yX+6)|F80A2b^Wh8N^J02{`7}_F}+=mmNGbt+2S}b zhjaV_IEXNa;|6PSAXptv&Z#Tw$@-k5+K`utmvCrUV@_3V%6B%Ga=vOa87`a4%jFfa zg={HX$t&5!y|rv3ui}WYtJ!D29mkBdmmTCaoZ;G0c9NYrxb0eb9f!B+)1AA>8)X~^ z9(I%6Wjx2Z^^`YpzI1O6BkRj?^f$}?ypBlV;QN7c5NEvJ$|2Rau|@ywawtdG592t* zyEr*5Ne-7IjA>=j97>p=G{2RXO<7kNnj%DLUY z$s_W24*WhUkICb*LY|N(Q}JnyGNrTwSiNP%TtT)kQVKWnyVgHPpBtVj(SSXQ%|e;>KU~_J*#rnbLx5Zf?B8+sl{pu zoAQ(icdR^tKH`JSIrCO!lQmfV5YK?kFtySw(fqGZHr`}iV z)d%WB^^w}3HmXf(vno^{t1apiwN-tpK2x8oZR!iPU45x`sGaI7^|dNe->6;cTUD&S zQ@hposzm*uepGu@soJadsh`w-^|Lyl4yrQsi#nu!RfpAY>WKPXm8+xbm^!X1)CqM` zol=$RG$(+Z<#gY3s#KGwLU89~+-)LYo zG#VL~7@*VBBL&G$t9T#=XX5V~UYxOf{w%_ZjKN{l){vgT{1YhB4E4$Z#7O#w;V# z$TDUd4;zmd*~T2>QR6XVuJO3>gz==2V?1TdGoCi)8_yUEjAxBp<2mDb;{{`(vB+3# zEHRcEFB;2?myA5)Wn;PVim}3Y)p*T#-N-lIFy1s)8mo-AjMc{5#v0=tW392yC@|hN z-ZS1e)*Bxf9~vJS8;p&{CS$WvXnbsJF+MT28lM`U8J`>5j4zDs#+SwpW2fa^m@YHG3^aqxV6zqn zT-7l{%(`Yhv%cBDY-lzzFEK;S#%2?}tO@&75jZGw(Cg&HK#<%m>Zs z<_vSD`H<;0Gt60LrkQ2VHXk-0F|*A%=A-6g=3Mh}^9l1wGsk?&oM%35&NrVi7nskQ zx#n}`^X3cYLUWP1*j!>RHD5HBnJ<}n=F8@C^A&T2`KtMv`MQ~JzG1#;t~6JfZ<(vj zx6L)?JLXz*ompVMYrbc`Z>~2#Fh4XuGB=nT%}wTJv(Wt5++u!WZZ$tOKQli!x0zp< z+s!Y{9p+B+EAwl!$o$6KWqxZGo8Otc&F{?;^9S=sbB|eS?lt$BKbiZ@pUng2L9@*K z#XMyGY92O!Gmn_Ro8{(F^O$+utT0cQC(To4rFq&sW1cmu%yVY7>9K?*EoB*&X<3$S zIhM-`umY_hE7+=K)wb$bAy!?ho>kv!U^TQFS(jL$R%5G))zk{JF10SRnpxpibL(>J z3af?H(rRU0X+>DAtv1$GR-|>c)z)ffMOp2w4%RhRwAIn-WOcS;tZS|7tm~~<>jtZf zb)yw$b+x)#-K}`5ht<=%$?9eGw)$9ot$xDK+$1J;AqbZdq+(|X8qTN&0YE7QudW?K(ik678(9P3f*F>9{%xb=kfq?Kbm zWzDmmw&q*USPQIYtz7Fl>v`)1YoWEsT5K(`mRc`b%dD5IJnLm^x%G;*!g|$u&3fI+ zx8AVcv{qWHthcPy*4x$^>m6&YwazNA-nHJd-nZ6UA6Oq+A6Xl$jn*b>vsGw)Y;CbV zv9?;DTAx{;TidKJtnJp9)(&f@^_BItRb+i*?XteLimmUg-PZS3iS>i^qqWB>wf0*3 zte>p?*3Z@f>!4L;{bC)mezgu;zgb7D->q`%sCCRbZdF((tdrI$tI|4cow3eZRn|GH z+Va@KmbS7D+q5kXVsmVl9bgCAL3XfR%dTzLu|w>-c0Iek-N0^WH?l9WL+!?P6T7J$ zW?yPwW;e6L?dJC7_7!#uyQSUAzS54cTib2ytL#YoYP+r7&W^I%+a2s{>}b2A-O283 z$Jp1}*V)(GvGxsi7yCv#&hBb=v%A~zb`QI!eUshG?rrz6``Z2No9+Jg06W3H#U5x6 zvIpC@+C%Ky>_q!^d#HVfJ+u zPqI_(d+o{g6g$nHYEQH8v(xSS?FZ}!?dkRmd#3%6?Y1-QS$3wKWzV)BwjZ&x?K$?N z_G9*3`*HgT`$;>;e#)L_KW)#qpRpI%&)T{6bN2K03-&^Lk-gYnVlTB{w3pd0*?IQM z_Hz3bdxia~{hIx{oo~NkziF?uSJ`jbtL?Y#HTFC9T6>*cV83g>XTNW+w?D8yv_G;p z*cKnbWdCX(wtusa*uUH5_EGzoecZ0FPuM5z zQ+B0&+CF2SwX5uNcD3zsgd-j07>?;!j_o*(%L#A-oggRJspZsm>Np`zU8kN?-)Z19 zbQ(FAIH68sr-{?l33D!WE_0eW;ZAesa_0)Ch11e$a z?VS$JHBPkC(dp!Lc4C}so$H+Ioml4vr;Br=6X$ewx;fpQc&CTc)49p%<@9#?IDMUd z&dpALXMmI7+~N#$204SBTb&`!ZBC+dyED|e!x`q>>D=Yq?IbzFoe|DRC)pY0jCRI2 zDb84DoHO2;;N0U(bS62e&b`iLXNr^NOm(I?_c`g#{mui z$#P~p4?B-I+0Gp2QRgvduJgF_g!816<2>cebDnnQJI^=^oM)X}=Q-zj=LKh>v&dQO zEOC}PFFMPdmz+H3WoNnbinGFb)p^Z%-N|>}aNcxQI;)(woYl_T&Kl<(XRWi&DRAC( z-gDk});k|KA37g78=Q^KCTFu#=zQ#KaXxXjI-fe9IiEY*oG+a1&X>*(XQ%U(^R-jt zeBF8I{TcToc+$v&H?A3Q|A2Q9CChj4mJ5CwE`Of!lF)$E2a2N(1g+XTq73=_8F|knW?(XjH?ha7E z#Na+>Jy zL&FWj5OOG?h8E_+d{_vJVJX}w+&J7M+%y~(4i86!d?|c6 zd?kD}d@X!Ed?S1_d@FoAd?$Q2d@p=I{2=@={3!f5{3QG|{4D%D{384^{3`r9{3iT1 z{4V@HoEy#ye+YjJ=Z6czh2c-(&*3lOuiD!H8E+nM5pNl96_1Lyj<<=ojkk+O$J@ta;vM20sh<4590<5%KWP7 znRMB7xpet-g>=PqrF7+Vm2}l~wRB**db&nBC|xrhoUWCwovxFvo359xpKg#2Nr$Ez zrXl52QcW$*rTMgw7SmF?QMz%uNxEq|EFGSXNXu!GR?;+$si&KzBh$^(Ez&L1tRr>3W+Gt<-4Gtx8Dv(mHEbJAJqx#@Z7`RN7eh3V|{ zqV(c)PI^gtX?j_Dd3r^9WqMV5b$U&DZF*gLeR@NBV|r71b9zg9YkFIHdwNHDXL?t9 zcY05HZ+c&PfBHcBVERz{aQaC4X!=WBVfs<}ar#O6Y5H0EdHO~AW%^b6b^1;EZTemM zeL6Rtm;R9cn9ffZqzh+H*}iQUS|(g+f>m%3^!r8loWb0eSK&Agyq*U>pVx4Xmsh5I zemWA4e6HyEqUTGQU%j74UeDvQJqKvx1KN0idTx1<&oA3LaD7F%&6CH8-k<3GiQb>s z`$JvgzUm^!>jTH@!;+2D2ael^iExhJ2is5X1Lx^O=lzM^pXmLGy+4$yaV9nn$j$w? zsY9->FY5h8y}zjU7B&B(=3mtOi<*DY=ePUV7v~vPxX(Q5d^+#9sm{5HE~G!`F8U07 zuQc*OUL>7b<~VhUa9F#)u)6o^SzvPuB6vc zoL+_JH}XBKhkP~iJ>WdgF^dl3myvt|e)a3x*NXUeMdw8M%%je=G_8w#fOF^ms`HWN z?OFV!`Fj>WX&pU_pGcS7MVFR2UXz@*L3}Xfyo1kAIl}&I-6dD&5Ank&IxdNyIPZ}8 z{E!RfAQzq2sC{+uBkw~k*nL172hi>V+ByO4JwTfm(9Q$U_77)<*I z*9EZ=-FY3jjStB4&%}o&zHii1z{yvQ`U-r={nRDWqq=;HUwYB`a9psh&Zm$cdeQk5 z@o2cXl7&t)H{>fAX#(rbxZab$Q}{f{XwQM)$rq#eVrY{9P$Ouvc79 zlRg_7`F@yEPiD7|vOBp^{&Uy5Xy@`sJqqa8eczlfi_T5_N7%VwTI$UvJ=i1tQ7(rm#~r5B+k^au?DW@u^PJ?^_dRO;Bk5geuOZ*0 zPmw+-(jP_opg2Epe9*(5&m+eNls=}ufgRL+`cZl0dI61(0B!$(qO0V2oZ7l@UGLK$ z&EuM%#C2Bc!=bw0rSs|3i@Eb$0FA!^Ic^spb)GZ$gzM?@Z<_30b33Pb8s!4#Df)50 zFmK|+IqhqX=h|fVv+PV=HonVUbRXu(hl9q+d>`sYayUo6FY-qV^%LkUdd=B7fQw#p zMwgPQUjRv`B7PX=D&>;zVIH1;=6ge)C!ZAehluBKUgtWm{mtv#=DEH``wqS|`N<>g z73gBmV_foS=KDi&KWkp=pV#{5b>0i&SH=q%SNovc4^{LW<|r3=+2w`uHjs~?_N52O zPgn=nn>jCV?Vs~Pt!v%|tyglDC4YG;{XqLOWQ||shZgrI`FdTFs`0kAf1Let<&dUwD+Lab&iW#m*T3C{wU5%>r-4a zQm$YgNROuYr1G5cJn5Y$DqxfiTUX3Gr)8s!k*`4Ng z%Ju5V=W{3DG|CzL7vpC@yAEi418Dof@!7cm+I|3yp8#z1h!0zeDi@{al1qdd~eP$#ao@97gE_J)aqG!TlA#D_=6|dR1KBJntmEo#`jT9i@FL zu4kkt3jJ7&D?V3VW?UOz*EtU2QLY;fzuBcCKFl6JOa2S>J;DyIcbF$14wUDi$Zs2D zp9ji4_?3K{eICWjnf^Q6e#t%kb;u9LEuvFV+&A()tXFcYczslyJ}Ryol~)>>M}j;{ zUMJf3it!8lBAp}i9>94%jrp`LH@589gDneKb+{WtH}b?6Dl9=CbtRwLTr##lk) zs33Br6EGAi2`~vKDKhfeg_(;7F>H~DfutlDgdk=S^K>zt?hiDk2r@~;MrDk}n=lTA z>jKpKN`4d_UU8!?%sUU7Ow-h@c@k(pq$8zP071qUWZEM045OesXQ>g z-N*Y9ZUsL@&cWc$*=YCiK8o0t8v48?v6p7ga*l15Wu9~^dafvF%v73~PeSR+%7Zzs1M}*9loS|U2~#LWIn97l z`gCf6OX*YT0hiJz{eVm9(|G_cI+AaJ^E{i99fR*J)mUJNM{_^^*)^+IMKFWKzkp_KCY)yDZ|#&dG1Ok zbe(5c^1bt15j@h_={kol=eFs5%L3)EDM)FqHx+a>IhlikjK-n>&O_%)z6Bj9k4^G2 zIR7c=FV08qG?0(Lzd8@sFPg8&sV#C&3xfnaFTLhLl#&kvV$VdqD;`}5u8V4KHs9#gTj)1J*=Q1LKai-oPcY7WjF_q;8pP(S?NPT zjN?{$a)S%Iluc%36GooQIw<1FTo;(w=e7HAYBVpEGa_TrrHgK!sgluY66Qv_Ac08X zZSGksf^KqVnw*42BY=pQ>mQhzKmuDHzB^-5MuibEG9@zN6mHrD zRhX+PO;r(fUCSU-DOD-Es)(SnqKrU|Myx9G?c(3+6;?T=opOM}j;#}r{MD6d>XNIj zj8m677@I0b&7FT`jGK&qQ|7qI8E&dDH#r4O8RaJDpgA3M&P|ourt@yByrKZW^Ka@< zXwth)9SVc^dg$UKr@x<?UCv)uMy*S4bY<4M z^hZ~QtyABipkU_*sBzT!(3Jt|>VW9V1a);nbe==*%org-AwE*Zt?JyWXQIfDC&jSmW!}2ETgB&C>sHeLsTwOs;R|dGN64K?=c2z{WDj{8w zepN7AC*osv8o*f zxlm=J%Sr9ZJa;;cxhtdHl~L?+y1O!%T^a5!r?@J^Qsa2Jut_nn#)7Djq z=yKk=DiU2zTvsxr%bDxSjCa}-=x5PS9ZQ||1=qz-a>lzln7T5poputjgXpnVF%sX= zE+g4Nx;G^s8u^C{t%`2@6R-0#TrH`6|*Cyw?DKpokCz|A} zDY$J6V&Ol@et9KTK~8i3%IT`$q$zXX6znuln#jLu@;jO;6-||>res)?zHH3UA?IRz zfdsAmAlb)39V3J2GI)lP`Up85I}bqfCy}AFeE>JV0nqdduA9CAZu0>5=k=UtI7vr5 zXZ(ogjK6@J-UqJtxqje&-Sh--^FIJ>AAr6-t&8>)XKUH+*u_sX!Np@()S zdy-B3tV}!ZlWtjdS{Zj-r=C^D9k}fmL7n+0fVM6`qX(d^3((dvDp&@zeFNG$0BzlX zMkhd{S0M@|RSFGI-Hds$`JsFBU~HP$ZFyx5nahB~Y6ZtJ0+aE*7PW z0MA6M&X5K@r#3IPF4m=}m$~I-?Q-{uF<4#O*y>E{k+u#g>+WE}b$8nO0m^!$t*n1+ z-K1EF-62P?W{$~?)6jzBhE$!m8|HeN5K3tSF`Oq~u&qT!TG?*QsR zhUcUXX~BR?-f6*rOQfjzfy+|Tv%tB?)1ZaJ zeLELGsZT~Wc+SQF^mEm7^h|Nxo(GhEQiL_7=Zzi*A5Z5`j}=uf&CkpgaGw9bNEGAQ zdh?X@#eJXG#=~_}0f0saJWqZZTm|ubM;CQjX0)V|n+HbVz(rR^;J`&!M&Q6jS7vB| zi>~xEfs3x>AI#_DkzWUT;&@JUqNj%Ev~EVmz-=BtqYI$u?(#(bz;z!-^!DBXdT6+B zbU;hJ@e!cy7trVnXzK%%ie{t-ocyewf8bgNBP`%Le=ke241(*n4nWa?Wf+w3H9sR) z;F_NqE#R8pdpH=;;=1U-%nfkSff-}q#s`3+1IstSHNU6b8Ci}4K+0fdde1!XXgQj+|~(t*sFNN_KgIo@e^8XxbCWqU)47TRhh)9 z3|&JbbrDd=nThFOwcVT6iLoOGT01unhCbpkiO0@V3)pTMO@xPRc%Bis*g@ewn( z-~;Lr_1?e=i~qb_D*dV6dsM5qu7y6gYNZ!twlc*K#XLJUJjUfN^m#r;RK;36##N~^ zACGg@*=Lis&UEnbyzWz)foqkt4tQU?pjCho*Z6eGS698;-NDig*@x@jeFK}=jbJCc z5o~8Sf;}0+_t)LP?$$rGJKDkg>)bkQX7^)o9CjnvmLcY$EGR%(U``z=Q8TU!Md2!ktH77h9a>ATnR}4R=*nOhFXrgt@QQ}cgriGnjt`c7@ zkR#?9d%`sp&fFOKZOEYua;E3SvGd~CiJ%&K;HYswRgsG%6HVS6r!w|M^QPn6UzG*S zqK9$kNNH}OMbP89EH9V)1+p$Q-5 z(eip@lQa;n)APvGq-fTo=b^91fZM(SX?fLv1YDjpBU3cbX&kN_9=66&BS2O+roI-z z`^J}mMi)S>uTCvqsRKbKC{R}{L~dAS38ybC0y71%=iP>{EUNuYksv;$)Cb?%}>7xxaL;` zo7J`<=|ZL2=0TRn-a~titq1LhwmwATcKYar<$ZBCo;N8&x`od*#jCPNXxHHNtoRJA z1Lpr^`8$n<6Nx?3@~D_;e)$hY-v~5y7F1QPn=*pUzZp;^N#}}jjN6gsF)qfZTHIgJ zI9VBGNihBfM&H3HFaQA@5E61Wm9G$%g=1ywxpy% zQ@o#P?U07DbH=&IFZA)99%}28RzYHt&ox!>o70I}5*6E(O~;zkx@E`7JKe1vGu^#0 z%Z)5la>yt1`0HAM+ms9n+9Yd}JJ*yLX-sYmP3~Wld)ee}Hht10B?+&c2x{Kb;}Wi#QFRSUR>3sBHIay0z%qS0X-N7* zc-}M@G>|kHSq;~zkqRSSv^eo7-QId{OjYfxr~$XF^@eG?`l>!la~022&`*R0ak7xb z&;-N?jy^bgbj*(cl&0}m9Rqr8E?Xjw-1rD6;t4gHnTBh7IAR;!SFEZqOt|`KAOfsW( zM>ZwZ{su}cJjY6Z5~Z4a!2M3%aq{+UJITx^Zau+y8G4D6G;fTf zxd1chP`rRGeN&xzRM^SheJQ8aKS?NF@M5>_s4iVFrOgLfuubDSnbsTl3Y|pg8xkd} z0jR7s5ZLCxoRq=pGAMIYRp@N`RHAuTuL_)Hjj2U+6`q=>A1O2#UuMb+tlTH`6wPf_ z;aEWhi0tN`?^V~IT4xp$Wid~7y{v}ABG{DXZ4#oQpaA}Z1$Fua8|yH$4t>dUs@|1N zGX?re|Eus>)Sy+I$-Qw)pAc77HnN;)eM*Qg|3q&&-voQSrbGa#zxAmla1$Ot zTL+*5YVsLy6EZ;VW38K2ZbR_~AQiBS7s!$n>dD@h)x2N2U_S_}ouX0X{38u7+4BBP#v6 zR;D9=p%aEmTKs}&mALGBk-t)u#wwzBkuoc?>mWSell$*o`bA%D6qk25DxS8NT`&6d zsrV;S{;9Wj?MoRJmj`_fP`qJOZh7(X^ff{8{keOnM%1E)#iGWRqK2fR29ctMyyD&W zDri?#?5YarRSh6j4IovGAys9b>Ys+XJku{j{{iV$WwfgFQB@arW%z>UbZ#=rRq|3@ zK2+AJZXDE2UKPGnHMUfR4OQi$>i!?)7<@{jSk>rV?(a-rKhXHiK<3{>i)Ic2Q^Yw>4~ayt~%$cbFMn)>W#KK&*}}9 zI?pCLHC2L}8sM86&zpZrEIw@F!>0L~=4%?aaa??1ZE}Uaa+7mFvqyk--hifG0nM%e znqB}j`UBc|1Daj~G`R*erwP#XDxm3aK$BNM(>s8gpMGzis&Q|s#=WV&N|`cYiu;;h z4SiG68`m{I=?z@-Q=bCY{B$;fYkt}_I>xFM1M8JP1O)LRYTmAe1zw;AMy)u?MLT2>QCE@ z`ja-J8m~w48GK#7KkEHa?~i)FQx2eRdH$XL3~-)zr`-Y0^X-%aG}7{XJMBAg?yrl# zy7;Sm8BFWxUJlcGI{5;Ancf#4bOj6gAOl}E(|)NT8Mr+UzmezJb$(rR@1lDr-SHgh z-8nCC@_i>gFu(B;{2PZhAFAp$KA^o1Xzu~iAJNxx!0C7BYdPTbPxNU&aEMkn}}ysuC4fpdTI zr}396xKI5FG~nE)KAi^6^~kORm%pVla8?<3L4Ns^=eayjzFb}qzQpnq`dMv0K%*<5 z%?D_71+@79jjn(;AE50Y(Dn&vdI-?y3utr!wEY6gZ_uBLDf(cbsWG{EvYhk6AF+85 zblLmpE3@(71{)pW*KxcidtE*4B>U53ca$VXT8I8mlfTi(w_r<-r{p)%J5&4=$-6gP zeEOUBddkeqhS`~!i&nzwf6m);@855j*()yZ*mc~=n|I*HwC}#xK8{Qd$s6%=c{3MH zK7rqYJ9Z;}LSyDX?-#rO&&j5lnbTJI(4MOg?Z0vMU<5@M&%AukjWaU`;NPn)q+_<7 zwDrVo+qWK=XXY06yZx@syS5&9)aEVt5wq1xOHbS|d#lZ-Zry?ZKVs&vnZsw6&)Tr( z%uSz-;qdz%_-Q{(fi<6oHSZf|jyPzVu%{zdSD$>r2To?r*s!{!Hyu6M^pR_&$;=b* z!z<6g@3fq=d=~z@|Hexkd@=r+ITL@D{Uv++>HBYa!L0xPm(PCR>^XSm(YoV8~pF literal 0 HcmV?d00001 diff --git a/test/nested_text_run_test.cpp b/test/nested_text_run_test.cpp new file mode 100644 index 00000000..f79a6e6a --- /dev/null +++ b/test/nested_text_run_test.cpp @@ -0,0 +1,61 @@ +#include "rive/core/binary_reader.hpp" +#include "rive/file.hpp" +#include "rive/nested_artboard.hpp" +#include "rive/text/text_value_run.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/animation/state_machine_input_instance.hpp" +#include "catch.hpp" +#include "rive_file_reader.hpp" +#include + +TEST_CASE("validate nested text get/set", "[nestedText]") +{ + auto file = ReadRiveFile("../../test/assets/runtime_nested_text_runs.riv"); + + auto artboard = file->artboard("ArtboardA")->instance(); + REQUIRE(artboard != nullptr); + REQUIRE(artboard->stateMachineCount() == 1); + + // Test getting/setting TextValueRun view nested artboard path one level deep + + auto textRunB1 = artboard->getTextRun("ArtboardBRun", "ArtboardB-1"); + REQUIRE(textRunB1->is()); + REQUIRE(textRunB1->text() == "Artboard B Run"); + + auto textRunB2 = artboard->getTextRun("ArtboardBRun", "ArtboardB-2"); + REQUIRE(textRunB2->is()); + REQUIRE(textRunB2->text() == "Artboard B Run"); + + // Test getting/setting TextValueRun view nested artboard path two level deep + + auto textRunB1C1 = artboard->getTextRun("ArtboardCRun", "ArtboardB-1/ArtboardC-1"); + REQUIRE(textRunB1C1->is()); + REQUIRE(textRunB1C1->text() == "Artboard C Run"); + + auto textRunB1C2 = artboard->getTextRun("ArtboardCRun", "ArtboardB-1/ArtboardC-2"); + REQUIRE(textRunB1C2->is()); + REQUIRE(textRunB1C2->text() == "Artboard C Run"); + + auto textRunB2C1 = artboard->getTextRun("ArtboardCRun", "ArtboardB-2/ArtboardC-1"); + REQUIRE(textRunB2C1->is()); + REQUIRE(textRunB2C1->text() == "Artboard C Run"); + + auto textRunB2C2 = artboard->getTextRun("ArtboardCRun", "ArtboardB-2/ArtboardC-2"); + REQUIRE(textRunB2C2->is()); + REQUIRE(textRunB2C2->text() == "Artboard C Run"); + + // Validate that text run values can be set + + textRunB1->text("Artboard B1 Run Updated"); + textRunB2->text("Artboard B2 Run Updated"); + textRunB1C1->text("Artboard B1C1 Run Updated"); + textRunB1C2->text("Artboard B1C2 Run Updated"); + textRunB2C1->text("Artboard B2C1 Run Updated"); + textRunB2C2->text("Artboard B2C2 Run Updated"); + REQUIRE(textRunB1->text() == "Artboard B1 Run Updated"); + REQUIRE(textRunB2->text() == "Artboard B2 Run Updated"); + REQUIRE(textRunB1C1->text() == "Artboard B1C1 Run Updated"); + REQUIRE(textRunB1C2->text() == "Artboard B1C2 Run Updated"); + REQUIRE(textRunB2C1->text() == "Artboard B2C1 Run Updated"); + REQUIRE(textRunB2C2->text() == "Artboard B2C2 Run Updated"); +} \ No newline at end of file From 2615d26b0e0718fd3b57f587cad6bae9b6fea919 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Tue, 13 Aug 2024 22:54:12 +0000 Subject: [PATCH 125/138] Update version to macosx 11 for runtime. Sorry for the churn in the premake file, someone didn't use the right formatter in a previous commit. We had to bump to 11 for this: ``` ../../../../../../pls/renderer/metal/background_shader_compiler.mm:215:42: error: 'MTLLanguageVersion2_3' is only available on macOS 11.0 or newer [-Werror,-Wunguarded-availability-new] compileOptions.languageVersion = MTLLanguageVersion2_3; // On mac, we need version 2.3+ ^~~~~~~~~~~~~~~~~~~~~ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/Library/Frameworks/Metal.framework/Headers/MTLLibrary.h:190:5: note: 'MTLLanguageVersion2_3' has been marked as being introduced in macOS 11.0 here, but the deployment target is macOS 10.6.0 MTLLanguageVersion2_3 API_AVAILABLE(macos(11.0), ios(14.0)) = (2 << 16) + 3, ^ ../../../../../../pls/renderer/metal/background_shader_compiler.mm:215:42: note: enclose 'MTLLanguageVersion2_3' in an @available check to silence this warning compileOptions.languageVersion = MTLLanguageVersion2_3; // On mac, we need version 2.3+ ^~~~~~~~~~~~~~~~~~~~~ ../../../../../../pls/renderer/metal/background_shader_compiler.mm:220:28: error: 'setPreserveInvariance:' is only available on macOS 11.0 or newer [-Werror,-Wunguarded-availability-new] compileOptions.preserveInvariance = YES; ``` Diffs= e75b8fa63 Update version to macosx 11 for runtime. (#7829) Co-authored-by: Luigi Rosso --- .rive_head | 2 +- build/rive_build_config.lua | 27 +++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index 27941d26..1b186268 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -55de8286c5ba680de950a3a0aac26e13bb890d6b +e75b8fa633a4f8eb102e669ac1308b1d1151fed1 diff --git a/build/rive_build_config.lua b/build/rive_build_config.lua index 55ebd5c7..9e2a7bf1 100644 --- a/build/rive_build_config.lua +++ b/build/rive_build_config.lua @@ -1,9 +1,9 @@ if _ACTION == 'ninja' then - require "ninja" + require('ninja') end if _ACTION == 'export-compile-commands' then - require "export-compile-commands" + require('export-compile-commands') end workspace('rive') @@ -409,12 +409,16 @@ filter({}) if os.host() == 'macosx' then iphoneos_sysroot = os.outputof('xcrun --sdk iphoneos --show-sdk-path') if iphoneos_sysroot == nil then - error('Unable to locate iphoneos sdk. Please ensure Xcode Command Line Tools are installed.') + error( + 'Unable to locate iphoneos sdk. Please ensure Xcode Command Line Tools are installed.' + ) end iphonesimulator_sysroot = os.outputof('xcrun --sdk iphonesimulator --show-sdk-path') if iphonesimulator_sysroot == nil then - error('Unable to locate iphonesimulator sdk. Please ensure Xcode Command Line Tools are installed.') + error( + 'Unable to locate iphonesimulator sdk. Please ensure Xcode Command Line Tools are installed.' + ) end filter('system:ios') @@ -445,6 +449,21 @@ if os.host() == 'macosx' then buildoptions({ '-fobjc-arc' }) end + filter({ 'system:macosx' }) + do + buildoptions({ + '-mmacosx-version-min=11.0', + }) + end + + filter({ 'system:macosx', 'options:arch=host', 'action:xcode4' }) + do + -- xcode tries to specify a target... + buildoptions({ + '--target=' .. os.outputof('uname -m') .. '-apple-macos11.0', + }) + end + filter({ 'system:macosx', 'options:arch=arm64 or arch=universal' }) do buildoptions({ '-arch arm64' }) From a7a0a016a2b08a755aba67885819c0e64dda9a57 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Wed, 14 Aug 2024 01:15:17 +0000 Subject: [PATCH 126/138] fix hovered state of group listeners fixes #7838 Diffs= 4fb978a92 fix hovered state of group listeners (#7839) Co-authored-by: hernan --- .rive_head | 2 +- src/animation/state_machine_instance.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index 1b186268..2db670ff 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e75b8fa633a4f8eb102e669ac1308b1d1151fed1 +4fb978a9230fc006b5e575364f062907e7dd2afe diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index dcc6ff67..e549a1a7 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -432,6 +432,7 @@ class ListenerGroup void consume() { m_isConsumed = true; } // void hover() { m_isHovered = true; } + void unhover() { m_isHovered = false; } void reset() { m_isConsumed = false; @@ -547,6 +548,18 @@ class HitShape : public HitComponent { continue; } + // Because each group is tested individually for its hover state, a group + // could be marked "incorrectly" as hovered at this point. + // But once we iterate each element in the drawing order, that group can + // be occluded by an opaque target on top of it. + // So although it is hovered in isolation, it shouldn't be considered as + // hovered in the full context. + // In this case, we unhover the group so it is not marked as previously + // hovered. + if (!canHit && listenerGroup->isHovered()) + { + listenerGroup->unhover(); + } bool isGroupHovered = canHit ? listenerGroup->isHovered() : false; bool hoverChange = listenerGroup->prevHovered() != isGroupHovered; From f450f95611a5485741f959d816833f2ee1f76a24 Mon Sep 17 00:00:00 2001 From: susan101566 Date: Wed, 14 Aug 2024 22:01:30 +0000 Subject: [PATCH 127/138] editor: nine-slicing core data type definitions This PR adds the core data types to support n-slicing. There are three main types: Axis, NSlicer and NSlicerTileMode. 1. Axis: I didn't want to make this super specific, since it could be used for grids later. So rn, it just represents some position in some dimension, and can either be a value in terms of a positional unit (like 10px) or bounds percentage (like 10%). 2. NSlicer: It's as simple as a component gets, we'll just use it to be a parent of all the n-slicer Axes, and have it be a child of Image later. 3. NSlicerTileMode: The main data here is 'style'. We said to use patchX and patchY separately from patchIndex. The last one is persisted in file, while the other two are actually used at runtime. The non-json files are auto generated, with the runtime json files copy pasted from the dev/defs version. I verified that the editor still runs, and the runtime also runs without error. Next up, I'll use these definitions to change editor behavior. Documentation: https://www.notion.so/rive-app/9-Slice-Tech-Proposal-Image-only-50b25ea8e79c4efabb681110e288f064#15f3a49ce3534baeafc31c37fb30cc0b For a rough direction of how to implement nine-slicing, check out this research branch: https://github.com/rive-app/rive/compare/master...susan/nine-slice-research Diffs= ed56d2de6 editor: nine-slicing core data type definitions (#7840) Co-authored-by: Susan Wang --- .rive_head | 2 +- dev/defs/layout/axis.json | 29 ++++++ dev/defs/layout/axis_x.json | 8 ++ dev/defs/layout/axis_y.json | 8 ++ dev/defs/layout/n_slicer.json | 8 ++ dev/defs/layout/n_slicer_tile_mode.json | 48 ++++++++++ include/rive/generated/core_registry.hpp | 45 ++++++++++ include/rive/generated/layout/axis_base.hpp | 89 +++++++++++++++++++ include/rive/generated/layout/axis_x_base.hpp | 37 ++++++++ include/rive/generated/layout/axis_y_base.hpp | 37 ++++++++ .../rive/generated/layout/n_slicer_base.hpp | 36 ++++++++ .../layout/n_slicer_tile_mode_base.hpp | 89 +++++++++++++++++++ include/rive/layout/axis.hpp | 13 +++ include/rive/layout/axis_x.hpp | 13 +++ include/rive/layout/axis_y.hpp | 13 +++ include/rive/layout/n_slicer.hpp | 13 +++ include/rive/layout/n_slicer_tile_mode.hpp | 13 +++ src/generated/layout/axis_x_base.cpp | 11 +++ src/generated/layout/axis_y_base.cpp | 11 +++ src/generated/layout/n_slicer_base.cpp | 11 +++ .../layout/n_slicer_tile_mode_base.cpp | 11 +++ 21 files changed, 544 insertions(+), 1 deletion(-) create mode 100644 dev/defs/layout/axis.json create mode 100644 dev/defs/layout/axis_x.json create mode 100644 dev/defs/layout/axis_y.json create mode 100644 dev/defs/layout/n_slicer.json create mode 100644 dev/defs/layout/n_slicer_tile_mode.json create mode 100644 include/rive/generated/layout/axis_base.hpp create mode 100644 include/rive/generated/layout/axis_x_base.hpp create mode 100644 include/rive/generated/layout/axis_y_base.hpp create mode 100644 include/rive/generated/layout/n_slicer_base.hpp create mode 100644 include/rive/generated/layout/n_slicer_tile_mode_base.hpp create mode 100644 include/rive/layout/axis.hpp create mode 100644 include/rive/layout/axis_x.hpp create mode 100644 include/rive/layout/axis_y.hpp create mode 100644 include/rive/layout/n_slicer.hpp create mode 100644 include/rive/layout/n_slicer_tile_mode.hpp create mode 100644 src/generated/layout/axis_x_base.cpp create mode 100644 src/generated/layout/axis_y_base.cpp create mode 100644 src/generated/layout/n_slicer_base.cpp create mode 100644 src/generated/layout/n_slicer_tile_mode_base.cpp diff --git a/.rive_head b/.rive_head index 2db670ff..ac7db820 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -4fb978a9230fc006b5e575364f062907e7dd2afe +ed56d2de61afb05abd99e8bab6775b63ab89f1a3 diff --git a/dev/defs/layout/axis.json b/dev/defs/layout/axis.json new file mode 100644 index 00000000..0703844b --- /dev/null +++ b/dev/defs/layout/axis.json @@ -0,0 +1,29 @@ +{ + "name": "Axis", + "key": { + "int": 492, + "string": "axis" + }, + "abstract": true, + "extends": "component.json", + "properties": { + "offset": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 675, + "string": "offset" + } + }, + "normalized": { + "type": "bool", + "initialValue": "false", + "key": { + "int": 676, + "string": "normalized" + }, + "description": "true means offset indicates a percentage" + } + } +} \ No newline at end of file diff --git a/dev/defs/layout/axis_x.json b/dev/defs/layout/axis_x.json new file mode 100644 index 00000000..47774c7b --- /dev/null +++ b/dev/defs/layout/axis_x.json @@ -0,0 +1,8 @@ +{ + "name": "AxisX", + "key": { + "int": 495, + "string": "axisx" + }, + "extends": "layout/axis.json" +} \ No newline at end of file diff --git a/dev/defs/layout/axis_y.json b/dev/defs/layout/axis_y.json new file mode 100644 index 00000000..b3bd16e5 --- /dev/null +++ b/dev/defs/layout/axis_y.json @@ -0,0 +1,8 @@ +{ + "name": "AxisY", + "key": { + "int": 494, + "string": "axisy" + }, + "extends": "layout/axis.json" +} \ No newline at end of file diff --git a/dev/defs/layout/n_slicer.json b/dev/defs/layout/n_slicer.json new file mode 100644 index 00000000..d6421423 --- /dev/null +++ b/dev/defs/layout/n_slicer.json @@ -0,0 +1,8 @@ +{ + "name": "NSlicer", + "key": { + "int": 493, + "string": "nslicer" + }, + "extends": "component.json" +} \ No newline at end of file diff --git a/dev/defs/layout/n_slicer_tile_mode.json b/dev/defs/layout/n_slicer_tile_mode.json new file mode 100644 index 00000000..fae93886 --- /dev/null +++ b/dev/defs/layout/n_slicer_tile_mode.json @@ -0,0 +1,48 @@ +{ + "name": "NSlicerTileMode", + "key": { + "int": 491, + "string": "nslicertilemode" + }, + "extends": "component.json", + "properties": { + "patchX": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 670, + "string": "patchx" + }, + "description": "the x index of the patch to style", + "runtime": false + }, + "patchY": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 671, + "string": "patchy" + }, + "description": "the y index of the patch to style", + "runtime": false + }, + "patchIndex": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 672, + "string": "patchindex" + }, + "description": "the index of the patch to style, non-negative" + }, + "style": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 673, + "string": "style" + }, + "description": "represents stretch, repeat, hidden, etc." + } + } +} \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index d38b4517..fd25b4ca 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -128,7 +128,12 @@ #include "rive/drawable.hpp" #include "rive/event.hpp" #include "rive/joystick.hpp" +#include "rive/layout/axis.hpp" +#include "rive/layout/axis_x.hpp" +#include "rive/layout/axis_y.hpp" #include "rive/layout/layout_component_style.hpp" +#include "rive/layout/n_slicer.hpp" +#include "rive/layout/n_slicer_tile_mode.hpp" #include "rive/layout_component.hpp" #include "rive/nested_animation.hpp" #include "rive/nested_artboard.hpp" @@ -277,8 +282,16 @@ class CoreRegistry return new Solo(); case NestedArtboardLayoutBase::typeKey: return new NestedArtboardLayout(); + case NSlicerTileModeBase::typeKey: + return new NSlicerTileMode(); + case AxisYBase::typeKey: + return new AxisY(); case LayoutComponentStyleBase::typeKey: return new LayoutComponentStyle(); + case AxisXBase::typeKey: + return new AxisX(); + case NSlicerBase::typeKey: + return new NSlicer(); case ListenerFireEventBase::typeKey: return new ListenerFireEvent(); case KeyFrameUintBase::typeKey: @@ -554,6 +567,9 @@ class CoreRegistry case FollowPathConstraintBase::offsetPropertyKey: object->as()->offset(value); break; + case AxisBase::normalizedPropertyKey: + object->as()->normalized(value); + break; case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: object->as()->intrinsicallySizedValue(value); break; @@ -701,6 +717,12 @@ class CoreRegistry case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: object->as()->instanceHeightScaleType(value); break; + case NSlicerTileModeBase::patchIndexPropertyKey: + object->as()->patchIndex(value); + break; + case NSlicerTileModeBase::stylePropertyKey: + object->as()->style(value); + break; case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: object->as()->layoutWidthScaleType(value); break; @@ -1246,6 +1268,9 @@ class CoreRegistry case NestedArtboardLayoutBase::instanceHeightPropertyKey: object->as()->instanceHeight(value); break; + case AxisBase::offsetPropertyKey: + object->as()->offset(value); + break; case LayoutComponentStyleBase::gapHorizontalPropertyKey: object->as()->gapHorizontal(value); break; @@ -1732,6 +1757,8 @@ class CoreRegistry return object->as()->orient(); case FollowPathConstraintBase::offsetPropertyKey: return object->as()->offset(); + case AxisBase::normalizedPropertyKey: + return object->as()->normalized(); case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: return object->as()->intrinsicallySizedValue(); case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: @@ -1833,6 +1860,10 @@ class CoreRegistry return object->as()->instanceWidthScaleType(); case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: return object->as()->instanceHeightScaleType(); + case NSlicerTileModeBase::patchIndexPropertyKey: + return object->as()->patchIndex(); + case NSlicerTileModeBase::stylePropertyKey: + return object->as()->style(); case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: return object->as()->layoutWidthScaleType(); case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: @@ -2206,6 +2237,8 @@ class CoreRegistry return object->as()->instanceWidth(); case NestedArtboardLayoutBase::instanceHeightPropertyKey: return object->as()->instanceHeight(); + case AxisBase::offsetPropertyKey: + return object->as()->offset(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->as()->gapHorizontal(); case LayoutComponentStyleBase::gapVerticalPropertyKey: @@ -2521,6 +2554,7 @@ class CoreRegistry case IKConstraintBase::invertDirectionPropertyKey: case FollowPathConstraintBase::orientPropertyKey: case FollowPathConstraintBase::offsetPropertyKey: + case AxisBase::normalizedPropertyKey: case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: case NestedSimpleAnimationBase::isPlayingPropertyKey: @@ -2569,6 +2603,8 @@ class CoreRegistry case NestedArtboardLayoutBase::instanceHeightUnitsValuePropertyKey: case NestedArtboardLayoutBase::instanceWidthScaleTypePropertyKey: case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: + case NSlicerTileModeBase::patchIndexPropertyKey: + case NSlicerTileModeBase::stylePropertyKey: case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: case LayoutComponentStyleBase::layoutAlignmentTypePropertyKey: @@ -2749,6 +2785,7 @@ class CoreRegistry case NodeBase::yArtboardPropertyKey: case NestedArtboardLayoutBase::instanceWidthPropertyKey: case NestedArtboardLayoutBase::instanceHeightPropertyKey: + case AxisBase::offsetPropertyKey: case LayoutComponentStyleBase::gapHorizontalPropertyKey: case LayoutComponentStyleBase::gapVerticalPropertyKey: case LayoutComponentStyleBase::maxWidthPropertyKey: @@ -2947,6 +2984,8 @@ class CoreRegistry return object->is(); case FollowPathConstraintBase::offsetPropertyKey: return object->is(); + case AxisBase::normalizedPropertyKey: + return object->is(); case LayoutComponentStyleBase::intrinsicallySizedValuePropertyKey: return object->is(); case LayoutComponentStyleBase::linkCornerRadiusPropertyKey: @@ -3041,6 +3080,10 @@ class CoreRegistry return object->is(); case NestedArtboardLayoutBase::instanceHeightScaleTypePropertyKey: return object->is(); + case NSlicerTileModeBase::patchIndexPropertyKey: + return object->is(); + case NSlicerTileModeBase::stylePropertyKey: + return object->is(); case LayoutComponentStyleBase::layoutWidthScaleTypePropertyKey: return object->is(); case LayoutComponentStyleBase::layoutHeightScaleTypePropertyKey: @@ -3393,6 +3436,8 @@ class CoreRegistry return object->is(); case NestedArtboardLayoutBase::instanceHeightPropertyKey: return object->is(); + case AxisBase::offsetPropertyKey: + return object->is(); case LayoutComponentStyleBase::gapHorizontalPropertyKey: return object->is(); case LayoutComponentStyleBase::gapVerticalPropertyKey: diff --git a/include/rive/generated/layout/axis_base.hpp b/include/rive/generated/layout/axis_base.hpp new file mode 100644 index 00000000..b7bf729a --- /dev/null +++ b/include/rive/generated/layout/axis_base.hpp @@ -0,0 +1,89 @@ +#ifndef _RIVE_AXIS_BASE_HPP_ +#define _RIVE_AXIS_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +#include "rive/core/field_types/core_double_type.hpp" +namespace rive +{ +class AxisBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 492; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case AxisBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t offsetPropertyKey = 675; + static const uint16_t normalizedPropertyKey = 676; + +private: + float m_Offset = 0.0f; + bool m_Normalized = false; + +public: + inline float offset() const { return m_Offset; } + void offset(float value) + { + if (m_Offset == value) + { + return; + } + m_Offset = value; + offsetChanged(); + } + + inline bool normalized() const { return m_Normalized; } + void normalized(bool value) + { + if (m_Normalized == value) + { + return; + } + m_Normalized = value; + normalizedChanged(); + } + + void copy(const AxisBase& object) + { + m_Offset = object.m_Offset; + m_Normalized = object.m_Normalized; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case offsetPropertyKey: + m_Offset = CoreDoubleType::deserialize(reader); + return true; + case normalizedPropertyKey: + m_Normalized = CoreBoolType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void offsetChanged() {} + virtual void normalizedChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/layout/axis_x_base.hpp b/include/rive/generated/layout/axis_x_base.hpp new file mode 100644 index 00000000..07859620 --- /dev/null +++ b/include/rive/generated/layout/axis_x_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_AXIS_XBASE_HPP_ +#define _RIVE_AXIS_XBASE_HPP_ +#include "rive/layout/axis.hpp" +namespace rive +{ +class AxisXBase : public Axis +{ +protected: + typedef Axis Super; + +public: + static const uint16_t typeKey = 495; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case AxisXBase::typeKey: + case AxisBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/layout/axis_y_base.hpp b/include/rive/generated/layout/axis_y_base.hpp new file mode 100644 index 00000000..e54b22a3 --- /dev/null +++ b/include/rive/generated/layout/axis_y_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_AXIS_YBASE_HPP_ +#define _RIVE_AXIS_YBASE_HPP_ +#include "rive/layout/axis.hpp" +namespace rive +{ +class AxisYBase : public Axis +{ +protected: + typedef Axis Super; + +public: + static const uint16_t typeKey = 494; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case AxisYBase::typeKey: + case AxisBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/layout/n_slicer_base.hpp b/include/rive/generated/layout/n_slicer_base.hpp new file mode 100644 index 00000000..23fa5487 --- /dev/null +++ b/include/rive/generated/layout/n_slicer_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_N_SLICER_BASE_HPP_ +#define _RIVE_N_SLICER_BASE_HPP_ +#include "rive/component.hpp" +namespace rive +{ +class NSlicerBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 493; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case NSlicerBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/layout/n_slicer_tile_mode_base.hpp b/include/rive/generated/layout/n_slicer_tile_mode_base.hpp new file mode 100644 index 00000000..c3673f0f --- /dev/null +++ b/include/rive/generated/layout/n_slicer_tile_mode_base.hpp @@ -0,0 +1,89 @@ +#ifndef _RIVE_N_SLICER_TILE_MODE_BASE_HPP_ +#define _RIVE_N_SLICER_TILE_MODE_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class NSlicerTileModeBase : public Component +{ +protected: + typedef Component Super; + +public: + static const uint16_t typeKey = 491; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case NSlicerTileModeBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t patchIndexPropertyKey = 672; + static const uint16_t stylePropertyKey = 673; + +private: + uint32_t m_PatchIndex = 0; + uint32_t m_Style = 0; + +public: + inline uint32_t patchIndex() const { return m_PatchIndex; } + void patchIndex(uint32_t value) + { + if (m_PatchIndex == value) + { + return; + } + m_PatchIndex = value; + patchIndexChanged(); + } + + inline uint32_t style() const { return m_Style; } + void style(uint32_t value) + { + if (m_Style == value) + { + return; + } + m_Style = value; + styleChanged(); + } + + Core* clone() const override; + void copy(const NSlicerTileModeBase& object) + { + m_PatchIndex = object.m_PatchIndex; + m_Style = object.m_Style; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case patchIndexPropertyKey: + m_PatchIndex = CoreUintType::deserialize(reader); + return true; + case stylePropertyKey: + m_Style = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + +protected: + virtual void patchIndexChanged() {} + virtual void styleChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout/axis.hpp b/include/rive/layout/axis.hpp new file mode 100644 index 00000000..a5eef6e5 --- /dev/null +++ b/include/rive/layout/axis.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_AXIS_HPP_ +#define _RIVE_AXIS_HPP_ +#include "rive/generated/layout/axis_base.hpp" +#include +namespace rive +{ +class Axis : public AxisBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout/axis_x.hpp b/include/rive/layout/axis_x.hpp new file mode 100644 index 00000000..3cd9a37c --- /dev/null +++ b/include/rive/layout/axis_x.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_AXIS_X_HPP_ +#define _RIVE_AXIS_X_HPP_ +#include "rive/generated/layout/axis_x_base.hpp" +#include +namespace rive +{ +class AxisX : public AxisXBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout/axis_y.hpp b/include/rive/layout/axis_y.hpp new file mode 100644 index 00000000..3f38d834 --- /dev/null +++ b/include/rive/layout/axis_y.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_AXIS_Y_HPP_ +#define _RIVE_AXIS_Y_HPP_ +#include "rive/generated/layout/axis_y_base.hpp" +#include +namespace rive +{ +class AxisY : public AxisYBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout/n_slicer.hpp b/include/rive/layout/n_slicer.hpp new file mode 100644 index 00000000..7f13a61b --- /dev/null +++ b/include/rive/layout/n_slicer.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_N_SLICER_HPP_ +#define _RIVE_N_SLICER_HPP_ +#include "rive/generated/layout/n_slicer_base.hpp" +#include +namespace rive +{ +class NSlicer : public NSlicerBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/layout/n_slicer_tile_mode.hpp b/include/rive/layout/n_slicer_tile_mode.hpp new file mode 100644 index 00000000..06e7cabb --- /dev/null +++ b/include/rive/layout/n_slicer_tile_mode.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_N_SLICER_TILE_MODE_HPP_ +#define _RIVE_N_SLICER_TILE_MODE_HPP_ +#include "rive/generated/layout/n_slicer_tile_mode_base.hpp" +#include +namespace rive +{ +class NSlicerTileMode : public NSlicerTileModeBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/src/generated/layout/axis_x_base.cpp b/src/generated/layout/axis_x_base.cpp new file mode 100644 index 00000000..172c2844 --- /dev/null +++ b/src/generated/layout/axis_x_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout/axis_x_base.hpp" +#include "rive/layout/axis_x.hpp" + +using namespace rive; + +Core* AxisXBase::clone() const +{ + auto cloned = new AxisX(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/layout/axis_y_base.cpp b/src/generated/layout/axis_y_base.cpp new file mode 100644 index 00000000..8815cefc --- /dev/null +++ b/src/generated/layout/axis_y_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout/axis_y_base.hpp" +#include "rive/layout/axis_y.hpp" + +using namespace rive; + +Core* AxisYBase::clone() const +{ + auto cloned = new AxisY(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/layout/n_slicer_base.cpp b/src/generated/layout/n_slicer_base.cpp new file mode 100644 index 00000000..49d6f377 --- /dev/null +++ b/src/generated/layout/n_slicer_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout/n_slicer_base.hpp" +#include "rive/layout/n_slicer.hpp" + +using namespace rive; + +Core* NSlicerBase::clone() const +{ + auto cloned = new NSlicer(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/layout/n_slicer_tile_mode_base.cpp b/src/generated/layout/n_slicer_tile_mode_base.cpp new file mode 100644 index 00000000..068c59ce --- /dev/null +++ b/src/generated/layout/n_slicer_tile_mode_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/layout/n_slicer_tile_mode_base.hpp" +#include "rive/layout/n_slicer_tile_mode.hpp" + +using namespace rive; + +Core* NSlicerTileModeBase::clone() const +{ + auto cloned = new NSlicerTileMode(); + cloned->copy(*this); + return cloned; +} From a57a234fda23abd979e8cc8d16440c0c17a55b3e Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Thu, 15 Aug 2024 19:28:49 +0000 Subject: [PATCH 128/138] added some simple windows build scripts to make building on windows from powershell or command prompt easier added build_rive.bat and build_rive.ps1 to build from the command prompt and PowerShell respectively. also added some setup scripts to the scripts folder to auto-set the path to the correct location Diffs= fb7756072 added some simple windows build scripts to make building on windows from powershell or command prompt easier (#7800) Co-authored-by: Jonathon Copeland --- .rive_head | 2 +- build/build_rive.bat | 10 ++++++++++ build/build_rive.ps1 | 15 +++++++++++++++ build/build_rive.sh | 3 --- 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 build/build_rive.bat create mode 100644 build/build_rive.ps1 diff --git a/.rive_head b/.rive_head index ac7db820..b4f79f30 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -ed56d2de61afb05abd99e8bab6775b63ab89f1a3 +fb7756072f7c28fff774e536b6bbbca664a35664 diff --git a/build/build_rive.bat b/build/build_rive.bat new file mode 100644 index 00000000..a0d7a193 --- /dev/null +++ b/build/build_rive.bat @@ -0,0 +1,10 @@ +@echo off +REM we could check where vs is install via the registery like stated here https://superuser.com/questions/539666/how-to-get-the-visual-studio-installation-path-in-a-batch-file but i think that is overkill +if exist "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" CALL "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" +else ( + if exist CALL "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" + else echo "Visual Studio 2022 does not appear to be installed, please install visual studio to C:\Program Files\Microsoft Visual Studio" +) + +cd %CD% +sh build_rive.sh %* diff --git a/build/build_rive.ps1 b/build/build_rive.ps1 new file mode 100644 index 00000000..b223f9c5 --- /dev/null +++ b/build/build_rive.ps1 @@ -0,0 +1,15 @@ +# requires Set-ExecutionPolicy Bypass -Scope CurrentUser +$CWD = Get-Location +if (Test-Path "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Launch-VsDevShell.ps1" -PathType Leaf) { + & "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Launch-VsDevShell.ps1" +} else { + if ("C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1") { + & 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Launch-VsDevShell.ps1' + } + else { + Write-Error "Visual Studio 2022 does not appear to be installed, please install visual studio to C:\Program Files\Microsoft Visual Studio" + exit + } +} +Set-Location $CWD +sh build_rive.sh $args \ No newline at end of file diff --git a/build/build_rive.sh b/build/build_rive.sh index cb1a3054..30ad0879 100755 --- a/build/build_rive.sh +++ b/build/build_rive.sh @@ -80,9 +80,6 @@ case "$(uname -s)" in MINGW*|MSYS*) HOST_MACHINE="windows" NUM_CORES=$NUMBER_OF_PROCESSORS - # Try to find MSBuild.exe - export PATH="$PATH:$PROGRAMFILES/Microsoft Visual Studio/2022/Enterprise/Msbuild/Current/Bin" - export PATH="$PATH:$PROGRAMFILES/Microsoft Visual Studio/2022/Community/Msbuild/Current/Bin" ;; Linux*) HOST_MACHINE="linux" From 7478e6277e14104532646027e8aa38bf720559d5 Mon Sep 17 00:00:00 2001 From: philter Date: Thu, 15 Aug 2024 23:26:47 +0000 Subject: [PATCH 129/138] Init NestedAnimation's nestedArtboard as nullptr This should fix an issue with nested events not bubbling up on Windows and web editor. Diffs= c5fc07de9 Init NestedAnimation's nestedArtboard as nullptr (#7857) Co-authored-by: Philip Chung --- .rive_head | 2 +- include/rive/nested_animation.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index b4f79f30..f62275ea 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -fb7756072f7c28fff774e536b6bbbca664a35664 +c5fc07de9cc2d14a2d223397c8ea96d7393eb78e diff --git a/include/rive/nested_animation.hpp b/include/rive/nested_animation.hpp index 70edc4d0..ac14f360 100644 --- a/include/rive/nested_animation.hpp +++ b/include/rive/nested_animation.hpp @@ -47,7 +47,7 @@ class NestedEventNotifier } private: - NestedArtboard* m_nestedArtboard; + NestedArtboard* m_nestedArtboard = nullptr; std::vector m_nestedEventListeners; }; From 198caeee25707999ea6084fa3e7511bc3be8e9ed Mon Sep 17 00:00:00 2001 From: bodymovin Date: Fri, 16 Aug 2024 17:37:30 +0000 Subject: [PATCH 130/138] Use artboard properties as transition conditions Adding support for transition conditions based on artboard properties. transition_artboard_condition extends from transition_viewmodel_condition. It might be good to rename transition_viewmodel_condition to transition_property_condition at some point since it is extensible enough to support viewmodels, but also with other properties like here. Diffs= 93cc33b45 Use artboard properties as transition conditions (#7796) Co-authored-by: hernan --- .rive_head | 2 +- .../transition_artboard_condition.json | 8 +++ ...ansition_property_artboard_comparator.json | 19 +++++ include/rive/animation/artboard_property.hpp | 14 ++++ .../transition_artboard_condition.hpp | 13 ++++ ...ransition_property_artboard_comparator.hpp | 20 ++++++ .../transition_artboard_condition_base.hpp | 37 ++++++++++ ...tion_property_artboard_comparator_base.hpp | 72 +++++++++++++++++++ include/rive/generated/core_registry.hpp | 18 ++++- ...ransition_property_artboard_comparator.cpp | 54 ++++++++++++++ src/file.cpp | 1 + .../transition_artboard_condition_base.cpp | 11 +++ ...tion_property_artboard_comparator_base.cpp | 11 +++ 13 files changed, 277 insertions(+), 3 deletions(-) create mode 100644 dev/defs/animation/transition_artboard_condition.json create mode 100644 dev/defs/animation/transition_property_artboard_comparator.json create mode 100644 include/rive/animation/artboard_property.hpp create mode 100644 include/rive/animation/transition_artboard_condition.hpp create mode 100644 include/rive/animation/transition_property_artboard_comparator.hpp create mode 100644 include/rive/generated/animation/transition_artboard_condition_base.hpp create mode 100644 include/rive/generated/animation/transition_property_artboard_comparator_base.hpp create mode 100644 src/animation/transition_property_artboard_comparator.cpp create mode 100644 src/generated/animation/transition_artboard_condition_base.cpp create mode 100644 src/generated/animation/transition_property_artboard_comparator_base.cpp diff --git a/.rive_head b/.rive_head index f62275ea..7e901c4a 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -c5fc07de9cc2d14a2d223397c8ea96d7393eb78e +93cc33b45086e528b22d1245a8f7855bac299a21 diff --git a/dev/defs/animation/transition_artboard_condition.json b/dev/defs/animation/transition_artboard_condition.json new file mode 100644 index 00000000..5a39c662 --- /dev/null +++ b/dev/defs/animation/transition_artboard_condition.json @@ -0,0 +1,8 @@ +{ + "name": "TransitionArtboardCondition", + "key": { + "int": 497, + "string": "transitionartboardcondition" + }, + "extends": "animation/transition_viewmodel_condition.json" +} \ No newline at end of file diff --git a/dev/defs/animation/transition_property_artboard_comparator.json b/dev/defs/animation/transition_property_artboard_comparator.json new file mode 100644 index 00000000..a9502eba --- /dev/null +++ b/dev/defs/animation/transition_property_artboard_comparator.json @@ -0,0 +1,19 @@ +{ + "name": "TransitionPropertyArtboardComparator", + "key": { + "int": 496, + "string": "transitionpropertyartboardcomparator" + }, + "extends": "animation/transition_property_comparator.json", + "properties": { + "propertyType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 677, + "string": "propertytype" + }, + "description": "Integer representation of the artboard's property used for condition" + } + } +} \ No newline at end of file diff --git a/include/rive/animation/artboard_property.hpp b/include/rive/animation/artboard_property.hpp new file mode 100644 index 00000000..0a4d606d --- /dev/null +++ b/include/rive/animation/artboard_property.hpp @@ -0,0 +1,14 @@ +#ifndef _RIVE_ARTBOARD_PROPERTY_HPP_ +#define _RIVE_ARTBOARD_PROPERTY_HPP_ + +namespace rive +{ +enum class ArtboardProperty : int +{ + width = 0, + height = 1, + ratio = 2, +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_artboard_condition.hpp b/include/rive/animation/transition_artboard_condition.hpp new file mode 100644 index 00000000..7892537e --- /dev/null +++ b/include/rive/animation/transition_artboard_condition.hpp @@ -0,0 +1,13 @@ +#ifndef _RIVE_TRANSITION_ARTBOARD_CONDITION_HPP_ +#define _RIVE_TRANSITION_ARTBOARD_CONDITION_HPP_ +#include "rive/generated/animation/transition_artboard_condition_base.hpp" +#include +namespace rive +{ +class TransitionArtboardCondition : public TransitionArtboardConditionBase +{ +public: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/transition_property_artboard_comparator.hpp b/include/rive/animation/transition_property_artboard_comparator.hpp new file mode 100644 index 00000000..184b6490 --- /dev/null +++ b/include/rive/animation/transition_property_artboard_comparator.hpp @@ -0,0 +1,20 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_HPP_ +#define _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_HPP_ +#include "rive/generated/animation/transition_property_artboard_comparator_base.hpp" +#include +namespace rive +{ +class Artboard; +class TransitionPropertyArtboardComparator : public TransitionPropertyArtboardComparatorBase +{ +public: + bool compare(TransitionComparator* comparand, + TransitionConditionOp operation, + const StateMachineInstance* stateMachineInstance) override; + +private: + float propertyValue(const StateMachineInstance* stateMachineInstance); +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_artboard_condition_base.hpp b/include/rive/generated/animation/transition_artboard_condition_base.hpp new file mode 100644 index 00000000..5f079c44 --- /dev/null +++ b/include/rive/generated/animation/transition_artboard_condition_base.hpp @@ -0,0 +1,37 @@ +#ifndef _RIVE_TRANSITION_ARTBOARD_CONDITION_BASE_HPP_ +#define _RIVE_TRANSITION_ARTBOARD_CONDITION_BASE_HPP_ +#include "rive/animation/transition_viewmodel_condition.hpp" +namespace rive +{ +class TransitionArtboardConditionBase : public TransitionViewModelCondition +{ +protected: + typedef TransitionViewModelCondition Super; + +public: + static const uint16_t typeKey = 497; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionArtboardConditionBase::typeKey: + case TransitionViewModelConditionBase::typeKey: + case TransitionConditionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/transition_property_artboard_comparator_base.hpp b/include/rive/generated/animation/transition_property_artboard_comparator_base.hpp new file mode 100644 index 00000000..354087a9 --- /dev/null +++ b/include/rive/generated/animation/transition_property_artboard_comparator_base.hpp @@ -0,0 +1,72 @@ +#ifndef _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_BASE_HPP_ +#define _RIVE_TRANSITION_PROPERTY_ARTBOARD_COMPARATOR_BASE_HPP_ +#include "rive/animation/transition_property_comparator.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class TransitionPropertyArtboardComparatorBase : public TransitionPropertyComparator +{ +protected: + typedef TransitionPropertyComparator Super; + +public: + static const uint16_t typeKey = 496; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case TransitionPropertyArtboardComparatorBase::typeKey: + case TransitionPropertyComparatorBase::typeKey: + case TransitionComparatorBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t propertyTypePropertyKey = 677; + +private: + uint32_t m_PropertyType = 0; + +public: + inline uint32_t propertyType() const { return m_PropertyType; } + void propertyType(uint32_t value) + { + if (m_PropertyType == value) + { + return; + } + m_PropertyType = value; + propertyTypeChanged(); + } + + Core* clone() const override; + void copy(const TransitionPropertyArtboardComparatorBase& object) + { + m_PropertyType = object.m_PropertyType; + TransitionPropertyComparator::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case propertyTypePropertyKey: + m_PropertyType = CoreUintType::deserialize(reader); + return true; + } + return TransitionPropertyComparator::deserialize(propertyKey, reader); + } + +protected: + virtual void propertyTypeChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index fd25b4ca..77e42517 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -59,11 +59,13 @@ #include "rive/animation/state_machine_number.hpp" #include "rive/animation/state_machine_trigger.hpp" #include "rive/animation/state_transition.hpp" +#include "rive/animation/transition_artboard_condition.hpp" #include "rive/animation/transition_bool_condition.hpp" #include "rive/animation/transition_comparator.hpp" #include "rive/animation/transition_condition.hpp" #include "rive/animation/transition_input_condition.hpp" #include "rive/animation/transition_number_condition.hpp" +#include "rive/animation/transition_property_artboard_comparator.hpp" #include "rive/animation/transition_property_comparator.hpp" #include "rive/animation/transition_property_viewmodel_comparator.hpp" #include "rive/animation/transition_trigger_condition.hpp" @@ -318,6 +320,8 @@ class CoreRegistry return new KeyedProperty(); case StateMachineListenerBase::typeKey: return new StateMachineListener(); + case TransitionPropertyArtboardComparatorBase::typeKey: + return new TransitionPropertyArtboardComparator(); case TransitionPropertyViewModelComparatorBase::typeKey: return new TransitionPropertyViewModelComparator(); case KeyFrameIdBase::typeKey: @@ -332,6 +336,10 @@ class CoreRegistry return new TransitionNumberCondition(); case TransitionValueBooleanComparatorBase::typeKey: return new TransitionValueBooleanComparator(); + case TransitionViewModelConditionBase::typeKey: + return new TransitionViewModelCondition(); + case TransitionArtboardConditionBase::typeKey: + return new TransitionArtboardCondition(); case AnyStateBase::typeKey: return new AnyState(); case CubicInterpolatorComponentBase::typeKey: @@ -342,8 +350,6 @@ class CoreRegistry return new KeyFrameString(); case ListenerNumberChangeBase::typeKey: return new ListenerNumberChange(); - case TransitionViewModelConditionBase::typeKey: - return new TransitionViewModelCondition(); case CubicEaseInterpolatorBase::typeKey: return new CubicEaseInterpolator(); case StateTransitionBase::typeKey: @@ -900,6 +906,9 @@ class CoreRegistry case StateMachineListenerBase::eventIdPropertyKey: object->as()->eventId(value); break; + case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey: + object->as()->propertyType(value); + break; case KeyFrameIdBase::valuePropertyKey: object->as()->value(value); break; @@ -1982,6 +1991,8 @@ class CoreRegistry return object->as()->listenerTypeValue(); case StateMachineListenerBase::eventIdPropertyKey: return object->as()->eventId(); + case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey: + return object->as()->propertyType(); case KeyFrameIdBase::valuePropertyKey: return object->as()->value(); case ListenerBoolChangeBase::valuePropertyKey: @@ -2664,6 +2675,7 @@ class CoreRegistry case StateMachineListenerBase::targetIdPropertyKey: case StateMachineListenerBase::listenerTypeValuePropertyKey: case StateMachineListenerBase::eventIdPropertyKey: + case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey: case KeyFrameIdBase::valuePropertyKey: case ListenerBoolChangeBase::valuePropertyKey: case ListenerAlignTargetBase::targetIdPropertyKey: @@ -3202,6 +3214,8 @@ class CoreRegistry return object->is(); case StateMachineListenerBase::eventIdPropertyKey: return object->is(); + case TransitionPropertyArtboardComparatorBase::propertyTypePropertyKey: + return object->is(); case KeyFrameIdBase::valuePropertyKey: return object->is(); case ListenerBoolChangeBase::valuePropertyKey: diff --git a/src/animation/transition_property_artboard_comparator.cpp b/src/animation/transition_property_artboard_comparator.cpp new file mode 100644 index 00000000..a769c7e4 --- /dev/null +++ b/src/animation/transition_property_artboard_comparator.cpp @@ -0,0 +1,54 @@ +#include "rive/animation/transition_property_artboard_comparator.hpp" +#include "rive/animation/transition_property_viewmodel_comparator.hpp" +#include "rive/animation/transition_value_number_comparator.hpp" +#include "rive/animation/artboard_property.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/data_bind/bindable_property_number.hpp" + +using namespace rive; + +float TransitionPropertyArtboardComparator::propertyValue( + const StateMachineInstance* stateMachineInstance) +{ + auto artboard = stateMachineInstance->artboard(); + if (artboard != nullptr) + { + + auto property = static_cast(propertyType()); + switch (property) + { + case ArtboardProperty::width: + return artboard->layoutWidth(); + break; + case ArtboardProperty::height: + return artboard->layoutHeight(); + break; + case ArtboardProperty::ratio: + return artboard->layoutWidth() / artboard->layoutHeight(); + break; + + default: + break; + } + } + return 0; +} + +bool TransitionPropertyArtboardComparator::compare(TransitionComparator* comparand, + TransitionConditionOp operation, + const StateMachineInstance* stateMachineInstance) +{ + auto value = propertyValue(stateMachineInstance); + if (comparand->is()) + { + auto rightValue = comparand->as() + ->value(stateMachineInstance); + return compareNumbers(value, rightValue, operation); + } + else if (comparand->is()) + { + auto rightValue = comparand->as()->value(); + return compareNumbers(value, rightValue, operation); + } + return false; +} \ No newline at end of file diff --git a/src/file.cpp b/src/file.cpp index 96da6840..100969ec 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -375,6 +375,7 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) stackType = ViewModelInstanceList::typeKey; break; case TransitionViewModelCondition::typeKey: + case TransitionArtboardCondition::typeKey: stackObject = rivestd::make_unique( object->as()); stackType = TransitionViewModelCondition::typeKey; diff --git a/src/generated/animation/transition_artboard_condition_base.cpp b/src/generated/animation/transition_artboard_condition_base.cpp new file mode 100644 index 00000000..4adb3c8b --- /dev/null +++ b/src/generated/animation/transition_artboard_condition_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_artboard_condition_base.hpp" +#include "rive/animation/transition_artboard_condition.hpp" + +using namespace rive; + +Core* TransitionArtboardConditionBase::clone() const +{ + auto cloned = new TransitionArtboardCondition(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/transition_property_artboard_comparator_base.cpp b/src/generated/animation/transition_property_artboard_comparator_base.cpp new file mode 100644 index 00000000..31a068a2 --- /dev/null +++ b/src/generated/animation/transition_property_artboard_comparator_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/animation/transition_property_artboard_comparator_base.hpp" +#include "rive/animation/transition_property_artboard_comparator.hpp" + +using namespace rive; + +Core* TransitionPropertyArtboardComparatorBase::clone() const +{ + auto cloned = new TransitionPropertyArtboardComparator(); + cloned->copy(*this); + return cloned; +} From 43d7f27b10c533ffba5b010a2eb6f0c9781c4014 Mon Sep 17 00:00:00 2001 From: philter Date: Sat, 17 Aug 2024 02:48:48 +0000 Subject: [PATCH 131/138] Fix for bug in Runtime LayoutComponent proxy This bug caused layout proxies to be drawn out of order causing layout rendering issues in the runtimes. Diffs= 85343a4e1 Fix for bug in Runtime LayoutComponent proxy (#7867) Co-authored-by: Philip Chung --- .rive_head | 2 +- include/rive/drawable.hpp | 3 +++ src/artboard.cpp | 25 ++++++++++++------------- src/drawable.cpp | 13 +++++++++++++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/.rive_head b/.rive_head index 7e901c4a..b68cbc78 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -93cc33b45086e528b22d1245a8f7855bac299a21 +85343a4e1c287922f872d14172167af72b4c3358 diff --git a/include/rive/drawable.hpp b/include/rive/drawable.hpp index b4e79b81..28220df5 100644 --- a/include/rive/drawable.hpp +++ b/include/rive/drawable.hpp @@ -12,6 +12,7 @@ namespace rive class ClippingShape; class Artboard; class DrawRules; +class LayoutComponent; class Drawable : public DrawableBase { @@ -47,6 +48,8 @@ class Drawable : public DrawableBase DrawableFlag::Opaque; } + bool isChildOfLayout(LayoutComponent* layout); + StatusCode onAddedDirty(CoreContext* context) override; }; diff --git a/src/artboard.cpp b/src/artboard.cpp index b0576d96..b153350e 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp @@ -247,20 +247,12 @@ StatusCode Artboard::initialize() for (int i = 0; i < m_Drawables.size(); i++) { auto drawable = m_Drawables[i]; - LayoutComponent* currentLayout; + LayoutComponent* currentLayout = nullptr; bool isInCurrentLayout = true; if (!layouts.empty()) { currentLayout = layouts.back(); - isInCurrentLayout = false; - } - for (ContainerComponent* parent = drawable; parent != nullptr; parent = parent->parent()) - { - if (parent == currentLayout) - { - isInCurrentLayout = true; - break; - } + isInCurrentLayout = drawable->isChildOfLayout(currentLayout); } // We inject a DrawableProxy after all of the children of a LayoutComponent // so that we can draw a stroke above and background below the children @@ -269,9 +261,16 @@ StatusCode Artboard::initialize() { // This is the first item in the list of drawables that isn't a child // of the layout, so we insert a proxy before it - m_Drawables.insert(m_Drawables.begin() + i, currentLayout->proxy()); - layouts.pop_back(); - i += 1; + do + { + m_Drawables.insert(m_Drawables.begin() + i, currentLayout->proxy()); + layouts.pop_back(); + if (!layouts.empty()) + { + currentLayout = layouts.back(); + } + i += 1; + } while (!layouts.empty() && !drawable->isChildOfLayout(currentLayout)); } if (drawable->is()) { diff --git a/src/drawable.cpp b/src/drawable.cpp index 522bd5ff..0dc9ca07 100644 --- a/src/drawable.cpp +++ b/src/drawable.cpp @@ -1,5 +1,6 @@ #include "rive/drawable.hpp" #include "rive/artboard.hpp" +#include "rive/layout_component.hpp" #include "rive/shapes/clipping_shape.hpp" #include "rive/shapes/path_composer.hpp" #include "rive/shapes/shape.hpp" @@ -70,4 +71,16 @@ ClipResult Drawable::applyClip(Renderer* renderer) const } } return ClipResult::clip; +} + +bool Drawable::isChildOfLayout(LayoutComponent* layout) +{ + for (ContainerComponent* parent = this; parent != nullptr; parent = parent->parent()) + { + if (parent->is() && parent->as() == layout) + { + return true; + } + } + return false; } \ No newline at end of file From 215de972f9e7a91a8f518158e14265a6aa18e24b Mon Sep 17 00:00:00 2001 From: susan101566 Date: Mon, 19 Aug 2024 21:03:29 +0000 Subject: [PATCH 132/138] editor: setting up the update callbacks for n-slicing I did some refactoring on image and mesh, where I created a 'deformer' that manages which mesh to show. I also abstracted out the parts in Mesh that deals with rendering specifically, called MeshDrawable. There's also a simple UI gated behind a feature flag that shows the N Slicing panel, where you can create, delete, update axis data (hold alt to show the remove axis button). The behavior is that when you create a mesh, the nslicer is deleted and vice versa. I mostly tested this manually. I added a print in the temp mesh's update, and made sure that when any axis gets deleted or updated, the print would trigger. I could add an auto test?! I need to look into that, but wanted to send this out to get some feedback on the approach. Next up: I'll add the algorithm for actually updating the render buffers in the temp mesh. doc: https://www.notion.so/rive-app/9-Slice-Tech-Proposal-Image-only-50b25ea8e79c4efabb681110e288f064#15f3a49ce3534baeafc31c37fb30cc0b Diffs= f99c93181 editor: setting up the update callbacks for n-slicing (#7869) Co-authored-by: Susan Wang --- .rive_head | 2 +- dev/defs/layout/n_slicer.json | 2 +- include/rive/generated/layout/n_slicer_base.hpp | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.rive_head b/.rive_head index b68cbc78..7dcbdefd 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -85343a4e1c287922f872d14172167af72b4c3358 +f99c93181b2073db07b0c54f766648ce56c89df9 diff --git a/dev/defs/layout/n_slicer.json b/dev/defs/layout/n_slicer.json index d6421423..c244b37c 100644 --- a/dev/defs/layout/n_slicer.json +++ b/dev/defs/layout/n_slicer.json @@ -4,5 +4,5 @@ "int": 493, "string": "nslicer" }, - "extends": "component.json" + "extends": "container_component.json" } \ No newline at end of file diff --git a/include/rive/generated/layout/n_slicer_base.hpp b/include/rive/generated/layout/n_slicer_base.hpp index 23fa5487..9ef88e90 100644 --- a/include/rive/generated/layout/n_slicer_base.hpp +++ b/include/rive/generated/layout/n_slicer_base.hpp @@ -1,12 +1,12 @@ #ifndef _RIVE_N_SLICER_BASE_HPP_ #define _RIVE_N_SLICER_BASE_HPP_ -#include "rive/component.hpp" +#include "rive/container_component.hpp" namespace rive { -class NSlicerBase : public Component +class NSlicerBase : public ContainerComponent { protected: - typedef Component Super; + typedef ContainerComponent Super; public: static const uint16_t typeKey = 493; @@ -18,6 +18,7 @@ class NSlicerBase : public Component switch (typeKey) { case NSlicerBase::typeKey: + case ContainerComponentBase::typeKey: case ComponentBase::typeKey: return true; default: From f0647c10a19ae96304ba0c76f3571023e78dc319 Mon Sep 17 00:00:00 2001 From: bodymovin Date: Mon, 19 Aug 2024 22:14:44 +0000 Subject: [PATCH 133/138] add arithmetic operation and group converters two new converters: - arithmetic operation, that applies a basic arithmetic operation to an input - group converter: this is a special converter that is used to apply a sequence of converters to a data bound property. https://github.com/user-attachments/assets/50a0226c-343f-4252-923b-4f0c51ca6c8b Diffs= ad34dd4da add arithmetic operation and group converters (#7801) Co-authored-by: hernan --- .rive_head | 2 +- .../converters/data_converter_group.json | 8 ++ .../converters/data_converter_group_item.json | 39 ++++++++ .../converters/data_converter_operation.json | 28 ++++++ .../rive/animation/arithmetic_operation.hpp | 16 ++++ .../converters/data_converter_group.hpp | 28 ++++++ .../converters/data_converter_group_item.hpp | 20 +++++ .../converters/data_converter_operation.hpp | 18 ++++ include/rive/generated/core_registry.hpp | 33 +++++++ .../converters/data_converter_group_base.hpp | 36 ++++++++ .../data_converter_group_item_base.hpp | 66 ++++++++++++++ .../data_converter_operation_base.hpp | 90 +++++++++++++++++++ include/rive/importers/backboard_importer.hpp | 3 + .../data_converter_group_importer.hpp | 20 +++++ .../converters/data_converter_group.cpp | 28 ++++++ .../converters/data_converter_group_item.cpp | 26 ++++++ .../converters/data_converter_operation.cpp | 65 ++++++++++++++ src/file.cpp | 7 ++ .../converters/data_converter_group_base.cpp | 11 +++ .../data_converter_group_item_base.cpp | 11 +++ .../data_converter_operation_base.cpp | 11 +++ src/importers/backboard_importer.cpp | 16 +++- .../data_converter_group_importer.cpp | 9 ++ 23 files changed, 589 insertions(+), 2 deletions(-) create mode 100644 dev/defs/data_bind/converters/data_converter_group.json create mode 100644 dev/defs/data_bind/converters/data_converter_group_item.json create mode 100644 dev/defs/data_bind/converters/data_converter_operation.json create mode 100644 include/rive/animation/arithmetic_operation.hpp create mode 100644 include/rive/data_bind/converters/data_converter_group.hpp create mode 100644 include/rive/data_bind/converters/data_converter_group_item.hpp create mode 100644 include/rive/data_bind/converters/data_converter_operation.hpp create mode 100644 include/rive/generated/data_bind/converters/data_converter_group_base.hpp create mode 100644 include/rive/generated/data_bind/converters/data_converter_group_item_base.hpp create mode 100644 include/rive/generated/data_bind/converters/data_converter_operation_base.hpp create mode 100644 include/rive/importers/data_converter_group_importer.hpp create mode 100644 src/data_bind/converters/data_converter_group.cpp create mode 100644 src/data_bind/converters/data_converter_group_item.cpp create mode 100644 src/data_bind/converters/data_converter_operation.cpp create mode 100644 src/generated/data_bind/converters/data_converter_group_base.cpp create mode 100644 src/generated/data_bind/converters/data_converter_group_item_base.cpp create mode 100644 src/generated/data_bind/converters/data_converter_operation_base.cpp create mode 100644 src/importers/data_converter_group_importer.cpp diff --git a/.rive_head b/.rive_head index 7dcbdefd..41d3f185 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -f99c93181b2073db07b0c54f766648ce56c89df9 +ad34dd4dae54aa071ca80c457e375c015b9497a8 diff --git a/dev/defs/data_bind/converters/data_converter_group.json b/dev/defs/data_bind/converters/data_converter_group.json new file mode 100644 index 00000000..acc05f85 --- /dev/null +++ b/dev/defs/data_bind/converters/data_converter_group.json @@ -0,0 +1,8 @@ +{ + "name": "DataConverterGroup", + "key": { + "int": 499, + "string": "dataconvertergroup" + }, + "extends": "data_bind/converters/data_converter.json" +} \ No newline at end of file diff --git a/dev/defs/data_bind/converters/data_converter_group_item.json b/dev/defs/data_bind/converters/data_converter_group_item.json new file mode 100644 index 00000000..60e95ece --- /dev/null +++ b/dev/defs/data_bind/converters/data_converter_group_item.json @@ -0,0 +1,39 @@ +{ + "name": "DataConverterGroupItem", + "key": { + "int": 498, + "string": "dataconvertergroupitem" + }, + "properties": { + "order": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "key": { + "int": 678, + "string": "order" + }, + "runtime": false + }, + "converterId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 679, + "string": "converterid" + }, + "description": "Id of the converter" + }, + "groupId": { + "type": "Id", + "initialValue": "Core.missingId", + "key": { + "int": 680, + "string": "groupid" + }, + "description": "Id of the group this item belongs to", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/data_bind/converters/data_converter_operation.json b/dev/defs/data_bind/converters/data_converter_operation.json new file mode 100644 index 00000000..1a921799 --- /dev/null +++ b/dev/defs/data_bind/converters/data_converter_operation.json @@ -0,0 +1,28 @@ +{ + "name": "DataConverterOperation", + "key": { + "int": 500, + "string": "dataconverteroperation" + }, + "extends": "data_bind/converters/data_converter.json", + "properties": { + "value": { + "type": "double", + "initialValue": "1", + "key": { + "int": 681, + "string": "value" + }, + "description": "Number to multiply the input to" + }, + "operationType": { + "type": "uint", + "initialValue": "0", + "key": { + "int": 682, + "string": "operationtype" + }, + "description": "The operation tu use for the input and value" + } + } +} \ No newline at end of file diff --git a/include/rive/animation/arithmetic_operation.hpp b/include/rive/animation/arithmetic_operation.hpp new file mode 100644 index 00000000..1870b8dd --- /dev/null +++ b/include/rive/animation/arithmetic_operation.hpp @@ -0,0 +1,16 @@ +#ifndef _RIVE_ARITHMETIC_OPERATION_HPP_ +#define _RIVE_ARITHMETIC_OPERATION_HPP_ + +namespace rive +{ +enum class ArithmeticOperation : int +{ + add = 0, + subtract = 1, + multiply = 2, + divide = 3, + modulo = 4, +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/converters/data_converter_group.hpp b/include/rive/data_bind/converters/data_converter_group.hpp new file mode 100644 index 00000000..40560857 --- /dev/null +++ b/include/rive/data_bind/converters/data_converter_group.hpp @@ -0,0 +1,28 @@ +#ifndef _RIVE_DATA_CONVERTER_GROUP_HPP_ +#define _RIVE_DATA_CONVERTER_GROUP_HPP_ +#include "rive/generated/data_bind/converters/data_converter_group_base.hpp" +#include "rive/data_bind/converters/data_converter_group_item.hpp" +#include +namespace rive +{ +class DataConverterGroup : public DataConverterGroupBase +{ +public: + DataValue* convert(DataValue* value) override; + DataValue* reverseConvert(DataValue* value) override; + void addItem(DataConverterGroupItem* item); + DataType outputType() override + { + if (m_items.size() > 0) + { + return m_items.back()->converter()->outputType(); + }; + return Super::outputType(); + } + +private: + std::vector m_items; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/converters/data_converter_group_item.hpp b/include/rive/data_bind/converters/data_converter_group_item.hpp new file mode 100644 index 00000000..0a6202d8 --- /dev/null +++ b/include/rive/data_bind/converters/data_converter_group_item.hpp @@ -0,0 +1,20 @@ +#ifndef _RIVE_DATA_CONVERTER_GROUP_ITEM_HPP_ +#define _RIVE_DATA_CONVERTER_GROUP_ITEM_HPP_ +#include "rive/generated/data_bind/converters/data_converter_group_item_base.hpp" +#include "rive/data_bind/converters/data_converter.hpp" +#include +namespace rive +{ +class DataConverterGroupItem : public DataConverterGroupItemBase +{ +public: + StatusCode import(ImportStack& importStack) override; + DataConverter* converter() const { return m_dataConverter; }; + void converter(DataConverter* value) { m_dataConverter = value; }; + +protected: + DataConverter* m_dataConverter; +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/data_bind/converters/data_converter_operation.hpp b/include/rive/data_bind/converters/data_converter_operation.hpp new file mode 100644 index 00000000..9bbb2b4a --- /dev/null +++ b/include/rive/data_bind/converters/data_converter_operation.hpp @@ -0,0 +1,18 @@ +#ifndef _RIVE_DATA_CONVERTER_OPERATION_HPP_ +#define _RIVE_DATA_CONVERTER_OPERATION_HPP_ +#include "rive/generated/data_bind/converters/data_converter_operation_base.hpp" +#include "rive/animation/arithmetic_operation.hpp" +#include +namespace rive +{ +class DataConverterOperation : public DataConverterOperationBase +{ +public: + DataValue* convert(DataValue* value) override; + DataValue* reverseConvert(DataValue* value) override; + DataType outputType() override { return DataType::number; }; + ArithmeticOperation op() const { return (ArithmeticOperation)operationType(); } +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index 77e42517..bb2d399d 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -121,6 +121,9 @@ #include "rive/data_bind/bindable_property_number.hpp" #include "rive/data_bind/bindable_property_string.hpp" #include "rive/data_bind/converters/data_converter.hpp" +#include "rive/data_bind/converters/data_converter_group.hpp" +#include "rive/data_bind/converters/data_converter_group_item.hpp" +#include "rive/data_bind/converters/data_converter_operation.hpp" #include "rive/data_bind/converters/data_converter_rounder.hpp" #include "rive/data_bind/converters/data_converter_to_string.hpp" #include "rive/data_bind/data_bind.hpp" @@ -472,8 +475,14 @@ class CoreRegistry return new BindablePropertyBoolean(); case DataBindBase::typeKey: return new DataBind(); + case DataConverterGroupItemBase::typeKey: + return new DataConverterGroupItem(); + case DataConverterGroupBase::typeKey: + return new DataConverterGroup(); case DataConverterRounderBase::typeKey: return new DataConverterRounder(); + case DataConverterOperationBase::typeKey: + return new DataConverterOperation(); case DataConverterToStringBase::typeKey: return new DataConverterToString(); case DataBindContextBase::typeKey: @@ -1047,9 +1056,15 @@ class CoreRegistry case DataBindBase::converterIdPropertyKey: object->as()->converterId(value); break; + case DataConverterGroupItemBase::converterIdPropertyKey: + object->as()->converterId(value); + break; case DataConverterRounderBase::decimalsPropertyKey: object->as()->decimals(value); break; + case DataConverterOperationBase::operationTypePropertyKey: + object->as()->operationType(value); + break; case BindablePropertyEnumBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -1589,6 +1604,9 @@ class CoreRegistry case JoystickBase::heightPropertyKey: object->as()->height(value); break; + case DataConverterOperationBase::valuePropertyKey: + object->as()->value(value); + break; case BindablePropertyNumberBase::propertyValuePropertyKey: object->as()->propertyValue(value); break; @@ -2085,8 +2103,12 @@ class CoreRegistry return object->as()->flags(); case DataBindBase::converterIdPropertyKey: return object->as()->converterId(); + case DataConverterGroupItemBase::converterIdPropertyKey: + return object->as()->converterId(); case DataConverterRounderBase::decimalsPropertyKey: return object->as()->decimals(); + case DataConverterOperationBase::operationTypePropertyKey: + return object->as()->operationType(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->as()->propertyValue(); case NestedArtboardLeafBase::fitPropertyKey: @@ -2456,6 +2478,8 @@ class CoreRegistry return object->as()->width(); case JoystickBase::heightPropertyKey: return object->as()->height(); + case DataConverterOperationBase::valuePropertyKey: + return object->as()->value(); case BindablePropertyNumberBase::propertyValuePropertyKey: return object->as()->propertyValue(); case NestedArtboardLeafBase::alignmentXPropertyKey: @@ -2722,7 +2746,9 @@ class CoreRegistry case DataBindBase::propertyKeyPropertyKey: case DataBindBase::flagsPropertyKey: case DataBindBase::converterIdPropertyKey: + case DataConverterGroupItemBase::converterIdPropertyKey: case DataConverterRounderBase::decimalsPropertyKey: + case DataConverterOperationBase::operationTypePropertyKey: case BindablePropertyEnumBase::propertyValuePropertyKey: case NestedArtboardLeafBase::fitPropertyKey: case WeightBase::valuesPropertyKey: @@ -2901,6 +2927,7 @@ class CoreRegistry case JoystickBase::originYPropertyKey: case JoystickBase::widthPropertyKey: case JoystickBase::heightPropertyKey: + case DataConverterOperationBase::valuePropertyKey: case BindablePropertyNumberBase::propertyValuePropertyKey: case NestedArtboardLeafBase::alignmentXPropertyKey: case NestedArtboardLeafBase::alignmentYPropertyKey: @@ -3308,8 +3335,12 @@ class CoreRegistry return object->is(); case DataBindBase::converterIdPropertyKey: return object->is(); + case DataConverterGroupItemBase::converterIdPropertyKey: + return object->is(); case DataConverterRounderBase::decimalsPropertyKey: return object->is(); + case DataConverterOperationBase::operationTypePropertyKey: + return object->is(); case BindablePropertyEnumBase::propertyValuePropertyKey: return object->is(); case NestedArtboardLeafBase::fitPropertyKey: @@ -3658,6 +3689,8 @@ class CoreRegistry return object->is(); case JoystickBase::heightPropertyKey: return object->is(); + case DataConverterOperationBase::valuePropertyKey: + return object->is(); case BindablePropertyNumberBase::propertyValuePropertyKey: return object->is(); case NestedArtboardLeafBase::alignmentXPropertyKey: diff --git a/include/rive/generated/data_bind/converters/data_converter_group_base.hpp b/include/rive/generated/data_bind/converters/data_converter_group_base.hpp new file mode 100644 index 00000000..32377ba4 --- /dev/null +++ b/include/rive/generated/data_bind/converters/data_converter_group_base.hpp @@ -0,0 +1,36 @@ +#ifndef _RIVE_DATA_CONVERTER_GROUP_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_GROUP_BASE_HPP_ +#include "rive/data_bind/converters/data_converter.hpp" +namespace rive +{ +class DataConverterGroupBase : public DataConverter +{ +protected: + typedef DataConverter Super; + +public: + static const uint16_t typeKey = 499; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterGroupBase::typeKey: + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + +protected: +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/converters/data_converter_group_item_base.hpp b/include/rive/generated/data_bind/converters/data_converter_group_item_base.hpp new file mode 100644 index 00000000..2f512813 --- /dev/null +++ b/include/rive/generated/data_bind/converters/data_converter_group_item_base.hpp @@ -0,0 +1,66 @@ +#ifndef _RIVE_DATA_CONVERTER_GROUP_ITEM_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_GROUP_ITEM_BASE_HPP_ +#include "rive/core.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive +{ +class DataConverterGroupItemBase : public Core +{ +protected: + typedef Core Super; + +public: + static const uint16_t typeKey = 498; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterGroupItemBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t converterIdPropertyKey = 679; + +private: + uint32_t m_ConverterId = -1; + +public: + inline uint32_t converterId() const { return m_ConverterId; } + void converterId(uint32_t value) + { + if (m_ConverterId == value) + { + return; + } + m_ConverterId = value; + converterIdChanged(); + } + + Core* clone() const override; + void copy(const DataConverterGroupItemBase& object) { m_ConverterId = object.m_ConverterId; } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case converterIdPropertyKey: + m_ConverterId = CoreUintType::deserialize(reader); + return true; + } + return false; + } + +protected: + virtual void converterIdChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/data_bind/converters/data_converter_operation_base.hpp b/include/rive/generated/data_bind/converters/data_converter_operation_base.hpp new file mode 100644 index 00000000..12913180 --- /dev/null +++ b/include/rive/generated/data_bind/converters/data_converter_operation_base.hpp @@ -0,0 +1,90 @@ +#ifndef _RIVE_DATA_CONVERTER_OPERATION_BASE_HPP_ +#define _RIVE_DATA_CONVERTER_OPERATION_BASE_HPP_ +#include "rive/core/field_types/core_double_type.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +#include "rive/data_bind/converters/data_converter.hpp" +namespace rive +{ +class DataConverterOperationBase : public DataConverter +{ +protected: + typedef DataConverter Super; + +public: + static const uint16_t typeKey = 500; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override + { + switch (typeKey) + { + case DataConverterOperationBase::typeKey: + case DataConverterBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t valuePropertyKey = 681; + static const uint16_t operationTypePropertyKey = 682; + +private: + float m_Value = 1.0f; + uint32_t m_OperationType = 0; + +public: + inline float value() const { return m_Value; } + void value(float value) + { + if (m_Value == value) + { + return; + } + m_Value = value; + valueChanged(); + } + + inline uint32_t operationType() const { return m_OperationType; } + void operationType(uint32_t value) + { + if (m_OperationType == value) + { + return; + } + m_OperationType = value; + operationTypeChanged(); + } + + Core* clone() const override; + void copy(const DataConverterOperationBase& object) + { + m_Value = object.m_Value; + m_OperationType = object.m_OperationType; + DataConverter::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override + { + switch (propertyKey) + { + case valuePropertyKey: + m_Value = CoreDoubleType::deserialize(reader); + return true; + case operationTypePropertyKey: + m_OperationType = CoreUintType::deserialize(reader); + return true; + } + return DataConverter::deserialize(propertyKey, reader); + } + +protected: + virtual void valueChanged() {} + virtual void operationTypeChanged() {} +}; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/importers/backboard_importer.hpp b/include/rive/importers/backboard_importer.hpp index c92454f7..cb2f9718 100644 --- a/include/rive/importers/backboard_importer.hpp +++ b/include/rive/importers/backboard_importer.hpp @@ -14,6 +14,7 @@ class FileAsset; class FileAssetReferencer; class DataConverter; class DataBind; +class DataConverterGroupItem; class BackboardImporter : public ImportStackObject { private: @@ -24,6 +25,7 @@ class BackboardImporter : public ImportStackObject std::vector m_FileAssetReferencers; std::vector m_DataConverters; std::vector m_DataConverterReferencers; + std::vector m_DataConverterGroupItemReferencers; int m_NextArtboardId; public: @@ -35,6 +37,7 @@ class BackboardImporter : public ImportStackObject void addFileAssetReferencer(FileAssetReferencer* referencer); void addDataConverterReferencer(DataBind* referencer); void addDataConverter(DataConverter* converter); + void addDataConverterGroupItemReferencer(DataConverterGroupItem* referencer); StatusCode resolve() override; const Backboard* backboard() const { return m_Backboard; } diff --git a/include/rive/importers/data_converter_group_importer.hpp b/include/rive/importers/data_converter_group_importer.hpp new file mode 100644 index 00000000..61ba8abb --- /dev/null +++ b/include/rive/importers/data_converter_group_importer.hpp @@ -0,0 +1,20 @@ +#ifndef _RIVE_DATA_CONVERTER_GROUP_IMPORTER_HPP_ +#define _RIVE_DATA_CONVERTER_GROUP_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" + +namespace rive +{ +class Core; +class DataConverterGroup; +class DataConverterGroupImporter : public ImportStackObject +{ +private: + DataConverterGroup* m_dataConverterGroup; + +public: + DataConverterGroupImporter(DataConverterGroup* group); + DataConverterGroup* group() { return m_dataConverterGroup; } +}; +} // namespace rive +#endif \ No newline at end of file diff --git a/src/data_bind/converters/data_converter_group.cpp b/src/data_bind/converters/data_converter_group.cpp new file mode 100644 index 00000000..aab150fd --- /dev/null +++ b/src/data_bind/converters/data_converter_group.cpp @@ -0,0 +1,28 @@ +#include "rive/math/math_types.hpp" +#include "rive/data_bind/converters/data_converter_group.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" +#include "rive/data_bind/data_values/data_value_string.hpp" + +using namespace rive; + +void DataConverterGroup::addItem(DataConverterGroupItem* item) { m_items.push_back(item); } + +DataValue* DataConverterGroup::convert(DataValue* input) +{ + DataValue* value = input; + for (auto item : m_items) + { + value = item->converter()->convert(value); + } + return value; +} + +DataValue* DataConverterGroup::reverseConvert(DataValue* input) +{ + DataValue* value = input; + for (auto it = m_items.rbegin(); it != m_items.rend(); ++it) + { + value = (*it)->converter()->reverseConvert(value); + } + return value; +} \ No newline at end of file diff --git a/src/data_bind/converters/data_converter_group_item.cpp b/src/data_bind/converters/data_converter_group_item.cpp new file mode 100644 index 00000000..3a6fa65e --- /dev/null +++ b/src/data_bind/converters/data_converter_group_item.cpp @@ -0,0 +1,26 @@ +#include "rive/backboard.hpp" +#include "rive/math/math_types.hpp" +#include "rive/data_bind/converters/data_converter_group_item.hpp" +#include "rive/data_bind/converters/data_converter_group.hpp" +#include "rive/importers/data_converter_group_importer.hpp" +#include "rive/importers/backboard_importer.hpp" + +using namespace rive; + +StatusCode DataConverterGroupItem::import(ImportStack& importStack) +{ + auto backboardImporter = importStack.latest(Backboard::typeKey); + if (backboardImporter == nullptr) + { + return StatusCode::MissingObject; + } + backboardImporter->addDataConverterGroupItemReferencer(this); + auto dataConveterGroupImporter = + importStack.latest(DataConverterGroupBase::typeKey); + if (dataConveterGroupImporter == nullptr) + { + return StatusCode::MissingObject; + } + dataConveterGroupImporter->group()->addItem(this); + return Super::import(importStack); +} \ No newline at end of file diff --git a/src/data_bind/converters/data_converter_operation.cpp b/src/data_bind/converters/data_converter_operation.cpp new file mode 100644 index 00000000..dfb43d8a --- /dev/null +++ b/src/data_bind/converters/data_converter_operation.cpp @@ -0,0 +1,65 @@ +#include "rive/math/math_types.hpp" +#include "rive/data_bind/converters/data_converter_operation.hpp" +#include "rive/data_bind/data_values/data_value_number.hpp" + +using namespace rive; + +DataValue* DataConverterOperation::convert(DataValue* input) +{ + auto output = new DataValueNumber(); + if (input->is()) + { + float inputValue = input->as()->value(); + float resultValue = value(); + switch (op()) + { + case ArithmeticOperation::add: + resultValue = inputValue + resultValue; + break; + case ArithmeticOperation::subtract: + resultValue = inputValue - resultValue; + break; + case ArithmeticOperation::multiply: + resultValue = inputValue * resultValue; + break; + case ArithmeticOperation::divide: + resultValue = inputValue / resultValue; + break; + case ArithmeticOperation::modulo: + resultValue = fmodf(inputValue, resultValue); + break; + } + output->value(resultValue); + } + return output; +} + +DataValue* DataConverterOperation::reverseConvert(DataValue* input) +{ + auto output = new DataValueNumber(); + if (input->is()) + { + float inputValue = input->as()->value(); + float resultValue = value(); + switch (op()) + { + case ArithmeticOperation::add: + resultValue = inputValue - resultValue; + break; + case ArithmeticOperation::subtract: + resultValue = inputValue + resultValue; + break; + case ArithmeticOperation::multiply: + resultValue = inputValue / resultValue; + break; + case ArithmeticOperation::divide: + resultValue = inputValue * resultValue; + break; + // No reverse operation for modulo + case ArithmeticOperation::modulo: + break; + } + output->value(resultValue); + } + return output; +} \ No newline at end of file diff --git a/src/file.cpp b/src/file.cpp index 100969ec..db3e98f0 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -9,6 +9,7 @@ #include "rive/importers/artboard_importer.hpp" #include "rive/importers/backboard_importer.hpp" #include "rive/importers/bindable_property_importer.hpp" +#include "rive/importers/data_converter_group_importer.hpp" #include "rive/importers/enum_importer.hpp" #include "rive/importers/file_asset_importer.hpp" #include "rive/importers/import_stack.hpp" @@ -39,6 +40,7 @@ #include "rive/data_bind/bindable_property_color.hpp" #include "rive/data_bind/bindable_property_enum.hpp" #include "rive/data_bind/bindable_property_boolean.hpp" +#include "rive/data_bind/converters/data_converter_group.hpp" #include "rive/assets/file_asset.hpp" #include "rive/assets/audio_asset.hpp" #include "rive/assets/file_asset_contents.hpp" @@ -389,6 +391,11 @@ ImportResult File::read(BinaryReader& reader, const RuntimeHeader& header) rivestd::make_unique(object->as()); stackType = BindablePropertyBase::typeKey; break; + case DataConverterGroupBase::typeKey: + stackObject = rivestd::make_unique( + object->as()); + stackType = DataConverterGroupBase::typeKey; + break; } if (importStack.makeLatest(stackType, std::move(stackObject)) != StatusCode::Ok) { diff --git a/src/generated/data_bind/converters/data_converter_group_base.cpp b/src/generated/data_bind/converters/data_converter_group_base.cpp new file mode 100644 index 00000000..23ee7706 --- /dev/null +++ b/src/generated/data_bind/converters/data_converter_group_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/converters/data_converter_group_base.hpp" +#include "rive/data_bind/converters/data_converter_group.hpp" + +using namespace rive; + +Core* DataConverterGroupBase::clone() const +{ + auto cloned = new DataConverterGroup(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/converters/data_converter_group_item_base.cpp b/src/generated/data_bind/converters/data_converter_group_item_base.cpp new file mode 100644 index 00000000..8f1e17b4 --- /dev/null +++ b/src/generated/data_bind/converters/data_converter_group_item_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/converters/data_converter_group_item_base.hpp" +#include "rive/data_bind/converters/data_converter_group_item.hpp" + +using namespace rive; + +Core* DataConverterGroupItemBase::clone() const +{ + auto cloned = new DataConverterGroupItem(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/data_bind/converters/data_converter_operation_base.cpp b/src/generated/data_bind/converters/data_converter_operation_base.cpp new file mode 100644 index 00000000..77ee84b0 --- /dev/null +++ b/src/generated/data_bind/converters/data_converter_operation_base.cpp @@ -0,0 +1,11 @@ +#include "rive/generated/data_bind/converters/data_converter_operation_base.hpp" +#include "rive/data_bind/converters/data_converter_operation.hpp" + +using namespace rive; + +Core* DataConverterOperationBase::clone() const +{ + auto cloned = new DataConverterOperation(); + cloned->copy(*this); + return cloned; +} diff --git a/src/importers/backboard_importer.cpp b/src/importers/backboard_importer.cpp index 845c5362..97a6c559 100644 --- a/src/importers/backboard_importer.cpp +++ b/src/importers/backboard_importer.cpp @@ -8,6 +8,7 @@ #include "rive/viewmodel/viewmodel.hpp" #include "rive/viewmodel/viewmodel_instance.hpp" #include "rive/data_bind/converters/data_converter.hpp" +#include "rive/data_bind/converters/data_converter_group_item.hpp" #include "rive/data_bind/data_bind.hpp" #include @@ -96,7 +97,15 @@ StatusCode BackboardImporter::resolve() } referencer->converter(m_DataConverters[index]); } - + for (auto referencer : m_DataConverterGroupItemReferencers) + { + auto index = (size_t)referencer->converterId(); + if (index >= m_DataConverters.size() || index < 0) + { + continue; + } + referencer->converter(m_DataConverters[index]); + } return StatusCode::Ok; } @@ -108,4 +117,9 @@ void BackboardImporter::addDataConverter(DataConverter* dataConverter) void BackboardImporter::addDataConverterReferencer(DataBind* dataBind) { m_DataConverterReferencers.push_back(dataBind); +} + +void BackboardImporter::addDataConverterGroupItemReferencer(DataConverterGroupItem* dataBind) +{ + m_DataConverterGroupItemReferencers.push_back(dataBind); } \ No newline at end of file diff --git a/src/importers/data_converter_group_importer.cpp b/src/importers/data_converter_group_importer.cpp new file mode 100644 index 00000000..457a0e2d --- /dev/null +++ b/src/importers/data_converter_group_importer.cpp @@ -0,0 +1,9 @@ +#include "rive/artboard.hpp" +#include "rive/importers/data_converter_group_importer.hpp" +#include "rive/data_bind/converters/data_converter.hpp" + +using namespace rive; + +DataConverterGroupImporter::DataConverterGroupImporter(DataConverterGroup* group) : + m_dataConverterGroup(group) +{} \ No newline at end of file From a8b7f00bed64849f52c402d91c7bbbbe3538558a Mon Sep 17 00:00:00 2001 From: rivessamr Date: Wed, 21 Aug 2024 18:29:40 +0000 Subject: [PATCH 134/138] iOS images unpremult SIMD support Support for SIMD instructions for unpremult First checkin, using rive::int16x4 instructions : 1 pixel at a time Further checkin, using rive::int16x4 instructions : 2 pixels at a time Last checkin, avoid computation when opaque pixels (assume there will be enough opaque pixels to warrant this) Thanks to Chris for the SIMD instructions usage in rive More checkins: move the decode and unpremult to the rive decoder - this requires modifications to build files. The benefits are we are now running tests on this path. However, there are some issues with decoding two images for tests: "../../test/assets/bad.jpg" ... Apple Preview app cannot open this image, however, the current test says that it should be not null And "../../test/assets/bad.png", Apple Preview app can load this images, however, the current test says that it should be null Diffs= e992059d6 iOS images unpremult SIMD support (#7875) Co-authored-by: rivessamr --- .rive_head | 2 +- decoders/premake5_v2.lua | 16 +- decoders/src/bitmap_decoder.cpp | 60 ------- decoders/src/bitmap_decoder_cg.mm | 165 ++++++++++++++++++++ decoders/src/bitmap_decoder_thirdparty.cpp | 69 ++++++++ dependencies/premake5_harfbuzz.lua | 4 +- dependencies/premake5_harfbuzz_v2.lua | 4 +- dependencies/premake5_libjpeg_v2.lua | 2 +- dependencies/premake5_yoga.lua | 2 +- dev/test/premake5.lua | 5 +- skia/thumbnail_generator/build/premake5.lua | 14 +- test/image_decoders_test.cpp | 14 ++ 12 files changed, 280 insertions(+), 77 deletions(-) create mode 100644 decoders/src/bitmap_decoder_cg.mm create mode 100644 decoders/src/bitmap_decoder_thirdparty.cpp diff --git a/.rive_head b/.rive_head index 41d3f185..f67274a7 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -ad34dd4dae54aa071ca80c457e375c015b9497a8 +e992059d6354434e91cde562e463f51bff7eac58 diff --git a/decoders/premake5_v2.lua b/decoders/premake5_v2.lua index 44ba4c92..7f7c37b7 100644 --- a/decoders/premake5_v2.lua +++ b/decoders/premake5_v2.lua @@ -13,7 +13,7 @@ do includedirs({ 'include', '../include', libpng, libjpeg }) - files({ 'src/**.cpp' }) + files({ 'src/bitmap_decoder.cpp' }) filter({ 'options:not no-libjpeg-renames' }) do @@ -22,4 +22,18 @@ do }) forceincludes({ 'rive_libjpeg_renames.h' }) end + + filter({ 'system:macosx or system:ios' }) + do + files({ 'src/**.mm' }) + end + + filter({ 'system:not macosx', 'system:not ios' }) + do + files({ + 'src/bitmap_decoder_thirdparty.cpp', + 'src/decode_jpeg.cpp', + 'src/decode_png.cpp', + }) + end end diff --git a/decoders/src/bitmap_decoder.cpp b/decoders/src/bitmap_decoder.cpp index e497a6ea..5bb4ee0a 100644 --- a/decoders/src/bitmap_decoder.cpp +++ b/decoders/src/bitmap_decoder.cpp @@ -38,66 +38,6 @@ size_t Bitmap::byteSize(PixelFormat format) const size_t Bitmap::byteSize() const { return byteSize(m_PixelFormat); } -std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount); -std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount); -std::unique_ptr DecodeWebP(const uint8_t bytes[], size_t byteCount) { return nullptr; } - -using BitmapDecoder = std::unique_ptr (*)(const uint8_t bytes[], size_t byteCount); -struct ImageFormat -{ - const char* name; - std::vector fingerprint; - BitmapDecoder decodeImage; -}; - -std::unique_ptr Bitmap::decode(const uint8_t bytes[], size_t byteCount) -{ - static ImageFormat decoders[] = { - { - "png", - {0x89, 0x50, 0x4E, 0x47}, - DecodePng, - }, - { - "jpeg", - {0xFF, 0xD8, 0xFF}, - DecodeJpeg, - }, - { - "webp", - {0x52, 0x49, 0x46}, - DecodeWebP, - }, - }; - - for (auto recognizer : decoders) - { - auto& fingerprint = recognizer.fingerprint; - - // Immediately discard decoders with fingerprints that are longer than - // the file buffer. - if (recognizer.fingerprint.size() > byteCount) - { - continue; - } - - // If the fingerprint doesn't match, discrd this decoder. These are all bytes so .size() is - // fine here. - if (memcmp(fingerprint.data(), bytes, fingerprint.size()) != 0) - { - continue; - } - - auto bitmap = recognizer.decodeImage(bytes, byteCount); - if (!bitmap) - { - fprintf(stderr, "Bitmap::decode - failed to decode a %s.\n", recognizer.name); - } - return bitmap; - } - return nullptr; -} - void Bitmap::pixelFormat(PixelFormat format) { if (format == m_PixelFormat) diff --git a/decoders/src/bitmap_decoder_cg.mm b/decoders/src/bitmap_decoder_cg.mm new file mode 100644 index 00000000..82b15d6d --- /dev/null +++ b/decoders/src/bitmap_decoder_cg.mm @@ -0,0 +1,165 @@ +/* + * Copyright 2023 Rive + */ + +#include "rive/decoders/bitmap_decoder.hpp" +#include "rive/rive_types.hpp" +#include "rive/math/simd.hpp" +#include "rive/math/math_types.hpp" +#include "rive/core/type_conversions.hpp" +#include "utils/auto_cf.hpp" + +#include + +#if TARGET_OS_IPHONE +#include +#include +#elif TARGET_OS_MAC +#include +#endif + +#include +#include +#include + +// Represents raw, premultiplied, RGBA image data with tightly packed rows (width * 4 bytes). +struct PlatformCGImage +{ + uint32_t width = 0; + uint32_t height = 0; + bool opaque = false; + std::unique_ptr pixels; +}; + +bool cg_image_decode(const uint8_t* encodedBytes, + size_t encodedSizeInBytes, + PlatformCGImage* platformImage) +{ + AutoCF data = CFDataCreate(kCFAllocatorDefault, encodedBytes, encodedSizeInBytes); + if (!data) + { + return false; + } + + AutoCF source = CGImageSourceCreateWithData(data, nullptr); + if (!source) + { + return false; + } + + AutoCF image = CGImageSourceCreateImageAtIndex(source, 0, nullptr); + if (!image) + { + return false; + } + + bool isOpaque = false; + switch (CGImageGetAlphaInfo(image.get())) + { + case kCGImageAlphaNone: + case kCGImageAlphaNoneSkipFirst: + case kCGImageAlphaNoneSkipLast: + isOpaque = true; + break; + default: + break; + } + + const size_t width = CGImageGetWidth(image); + const size_t height = CGImageGetHeight(image); + const size_t rowBytes = width * 4; // 4 bytes per pixel + const size_t size = rowBytes * height; + + const size_t bitsPerComponent = 8; + CGBitmapInfo cgInfo = kCGBitmapByteOrder32Big; // rgba + if (isOpaque) + { + cgInfo |= kCGImageAlphaNoneSkipLast; + } + else + { + cgInfo |= kCGImageAlphaPremultipliedLast; + } + + std::unique_ptr pixels(new uint8_t[size]); + + AutoCF cs = CGColorSpaceCreateDeviceRGB(); + AutoCF cg = + CGBitmapContextCreate(pixels.get(), width, height, bitsPerComponent, rowBytes, cs, cgInfo); + if (!cg) + { + return false; + } + + CGContextSetBlendMode(cg, kCGBlendModeCopy); + CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image); + + platformImage->width = rive::castTo(width); + platformImage->height = rive::castTo(height); + platformImage->opaque = isOpaque; + platformImage->pixels = std::move(pixels); + + return true; +} + +std::unique_ptr Bitmap::decode(const uint8_t bytes[], size_t byteCount) +{ + PlatformCGImage image; + if (!cg_image_decode(bytes, byteCount, &image)) + { + return nullptr; + } + + // CG only supports premultiplied alpha. Unmultiply now. + size_t imageNumPixels = image.height * image.width; + size_t imageSizeInBytes = imageNumPixels * 4; + // Process 2 pixels at once, deal with odd number of pixels + if (imageNumPixels & 1) + { + imageSizeInBytes -= 4; + } + size_t i; + for (i = 0; i < imageSizeInBytes; i += 8) + { + // Load 2 pixels into 64 bits + auto twoPixels = rive::simd::load(&image.pixels[i]); + auto a0 = twoPixels[3]; + auto a1 = twoPixels[7]; + // Avoid computation if both pixels are either fully transparent or opaque pixels + if ((a0 > 0 && a0 < 255) || (a1 > 0 && a1 < 255)) + { + // Avoid potential division by zero + a0 = std::max(a0, 1); + a1 = std::max(a1, 1); + // Cast to 16 bits to avoid overflow + rive::uint16x8 rgbaWidex2 = rive::simd::cast(twoPixels); + // Unpremult: multiply by RGB by "255.0 / alpha" + rgbaWidex2 *= rive::uint16x8{255, 255, 255, 1, 255, 255, 255, 1}; + rgbaWidex2 /= rive::uint16x8{a0, a0, a0, 1, a1, a1, a1, 1}; + // Cast back to 8 bits and store + twoPixels = rive::simd::cast(rgbaWidex2); + rive::simd::store(&image.pixels[i], twoPixels); + } + } + // Process last odd pixel if needed + if (imageNumPixels & 1) + { + // Load 1 pixel into 32 bits + auto rgba = rive::simd::load(&image.pixels[i]); + // Avoid computation for fully transparent or opaque pixels + if (rgba.a > 0 && rgba.a < 255) + { + // Cast to 16 bits to avoid overflow + rive::uint16x4 rgbaWide = rive::simd::cast(rgba); + // Unpremult: multiply by RGB by "255.0 / alpha" + rgbaWide *= rive::uint16x4{255, 255, 255, 1}; + rgbaWide /= rive::uint16x4{rgba.a, rgba.a, rgba.a, 1}; + // Cast back to 8 bits and store + rgba = rive::simd::cast(rgbaWide); + rive::simd::store(&image.pixels[i], rgba); + } + } + + return std::make_unique( + image.width, image.height, PixelFormat::RGBA, std::move(image.pixels)); +} diff --git a/decoders/src/bitmap_decoder_thirdparty.cpp b/decoders/src/bitmap_decoder_thirdparty.cpp new file mode 100644 index 00000000..6dc5a91e --- /dev/null +++ b/decoders/src/bitmap_decoder_thirdparty.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2023 Rive + */ + +#include "rive/decoders/bitmap_decoder.hpp" +#include "rive/rive_types.hpp" +#include +#include +#include + +std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount); +std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount); +std::unique_ptr DecodeWebP(const uint8_t bytes[], size_t byteCount) { return nullptr; } + +using BitmapDecoder = std::unique_ptr (*)(const uint8_t bytes[], size_t byteCount); +struct ImageFormat +{ + const char* name; + std::vector fingerprint; + BitmapDecoder decodeImage; +}; + +std::unique_ptr Bitmap::decode(const uint8_t bytes[], size_t byteCount) +{ + static ImageFormat decoders[] = { + { + "png", + {0x89, 0x50, 0x4E, 0x47}, + DecodePng, + }, + { + "jpeg", + {0xFF, 0xD8, 0xFF}, + DecodeJpeg, + }, + { + "webp", + {0x52, 0x49, 0x46}, + DecodeWebP, + }, + }; + + for (auto recognizer : decoders) + { + auto& fingerprint = recognizer.fingerprint; + + // Immediately discard decoders with fingerprints that are longer than + // the file buffer. + if (recognizer.fingerprint.size() > byteCount) + { + continue; + } + + // If the fingerprint doesn't match, discrd this decoder. These are all bytes so .size() is + // fine here. + if (memcmp(fingerprint.data(), bytes, fingerprint.size()) != 0) + { + continue; + } + + auto bitmap = recognizer.decodeImage(bytes, byteCount); + if (!bitmap) + { + fprintf(stderr, "Bitmap::decode - failed to decode a %s.\n", recognizer.name); + } + return bitmap; + } + return nullptr; +} diff --git a/dependencies/premake5_harfbuzz.lua b/dependencies/premake5_harfbuzz.lua index 9c161731..768cb138 100644 --- a/dependencies/premake5_harfbuzz.lua +++ b/dependencies/premake5_harfbuzz.lua @@ -352,7 +352,7 @@ do filter('system:macosx or system:ios') do - defines({'HAVE_CORETEXT'}) - files({harfbuzz .. '/src/hb-coretext.cc'}) + defines({ 'HAVE_CORETEXT' }) + files({ harfbuzz .. '/src/hb-coretext.cc' }) end end diff --git a/dependencies/premake5_harfbuzz_v2.lua b/dependencies/premake5_harfbuzz_v2.lua index 92655552..c26c1d28 100644 --- a/dependencies/premake5_harfbuzz_v2.lua +++ b/dependencies/premake5_harfbuzz_v2.lua @@ -277,7 +277,7 @@ do filter('system:macosx or system:ios') do - defines({'HAVE_CORETEXT'}) - files({harfbuzz .. '/src/hb-coretext.cc'}) + defines({ 'HAVE_CORETEXT' }) + files({ harfbuzz .. '/src/hb-coretext.cc' }) end end diff --git a/dependencies/premake5_libjpeg_v2.lua b/dependencies/premake5_libjpeg_v2.lua index 6ef35f95..34ba3547 100644 --- a/dependencies/premake5_libjpeg_v2.lua +++ b/dependencies/premake5_libjpeg_v2.lua @@ -15,7 +15,7 @@ newoption({ project('libjpeg') do kind('StaticLib') - optimize("Speed") -- Always optimize image encoding/decoding, even in debug builds. + optimize('Speed') -- Always optimize image encoding/decoding, even in debug builds. includedirs({ libjpeg }) diff --git a/dependencies/premake5_yoga.lua b/dependencies/premake5_yoga.lua index d4149e71..bf83e1ba 100644 --- a/dependencies/premake5_yoga.lua +++ b/dependencies/premake5_yoga.lua @@ -17,7 +17,7 @@ do includedirs({ yoga }) - files({ + files({ yoga .. '/yoga/Utils.cpp', yoga .. '/yoga/YGConfig.cpp', yoga .. '/yoga/YGLayout.cpp', diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index 0cbd9062..dea984ef 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -63,12 +63,13 @@ do forceincludes({ 'rive_yoga_renames.h' }) end - filter({ 'system:macosx'} ) + filter({ 'system:macosx' }) do links({ 'Foundation.framework', + 'ImageIO.framework', 'CoreGraphics.framework', - 'CoreText.framework' + 'CoreText.framework', }) end end diff --git a/skia/thumbnail_generator/build/premake5.lua b/skia/thumbnail_generator/build/premake5.lua index 40171376..a724d647 100644 --- a/skia/thumbnail_generator/build/premake5.lua +++ b/skia/thumbnail_generator/build/premake5.lua @@ -71,13 +71,13 @@ defines({ 'NDEBUG' }) optimize('On') filter({ 'options:with_rive_layout' }) - do - defines({ 'YOGA_EXPORT=' }) - includedirs({ yoga }) - links({ - 'rive_yoga', - }) - end +do + defines({ 'YOGA_EXPORT=' }) + includedirs({ yoga }) + links({ + 'rive_yoga', + }) +end -- Clean Function -- newaction({ diff --git a/test/image_decoders_test.cpp b/test/image_decoders_test.cpp index 21132c27..4d6a8216 100644 --- a/test/image_decoders_test.cpp +++ b/test/image_decoders_test.cpp @@ -28,6 +28,9 @@ TEST_CASE("jpeg file decodes correctly", "[image-decoder]") REQUIRE(bitmap->height() == 200); } +#ifndef __APPLE__ +// Loading this particular jpeg image in CG causes a memory leak CGImageSourceCreateImageAtIndex +// calls IIOReadPlugin::createInfoPtr which leaks TEST_CASE("bad jpeg file doesn't cause an overflow", "[image-decoder]") { auto file = ReadFile("../../test/assets/bad.jpg"); @@ -40,6 +43,7 @@ TEST_CASE("bad jpeg file doesn't cause an overflow", "[image-decoder]") REQUIRE(bitmap->width() == 24566); REQUIRE(bitmap->height() == 58278); } +#endif TEST_CASE("bad png file doesn't cause an overflow", "[image-decoder]") { @@ -48,5 +52,15 @@ TEST_CASE("bad png file doesn't cause an overflow", "[image-decoder]") auto bitmap = Bitmap::decode(file.data(), file.size()); +#ifdef __APPLE__ + // Loading this bad PNG file in CG actually works and we do get an image albiet black + REQUIRE(bitmap != nullptr); + + REQUIRE(bitmap->width() == 58278); + REQUIRE(bitmap->height() == 24566); +#else + // Our decoders return null as we have an invalid header with bogus resolution and we want to + // avoid a potential attack vector REQUIRE(bitmap == nullptr); +#endif } From 6acee5a096a01cea5dee0b1fb9cbcae4a41f3fd4 Mon Sep 17 00:00:00 2001 From: rivessamr Date: Thu, 22 Aug 2024 04:33:03 +0000 Subject: [PATCH 135/138] Add webp decoder. We've been needing this for a while for the game engines but we also need it to support decoding webp images for use in the editor with the Rive Renderer. I haven't instrumented the build properly to use SIMD extensions, but I left some notes for how to do so. This PR unblocks the use of WebP, let's do some perf improvements in a follow up that perhaps the runtime team can own? Diffs= 160d9eefb Add webp decoder. (#7883) Co-authored-by: Luigi Rosso Co-authored-by: rivessamr --- .rive_head | 2 +- decoders/premake5_v2.lua | 10 +- decoders/src/bitmap_decoder_thirdparty.cpp | 2 +- decoders/src/decode_webp.cpp | 68 +++++++++ dependencies/premake5_libjpeg_v2.lua | 4 - dependencies/premake5_libwebp_v2.lua | 166 +++++++++++++++++++++ dev/test/premake5.lua | 1 + test/assets/1.webp | Bin 0 -> 30320 bytes test/image_decoders_test.cpp | 13 ++ viewer/build/premake5_viewer.lua | 2 +- 10 files changed, 259 insertions(+), 9 deletions(-) create mode 100644 decoders/src/decode_webp.cpp create mode 100644 dependencies/premake5_libwebp_v2.lua create mode 100644 test/assets/1.webp diff --git a/.rive_head b/.rive_head index f67274a7..dce3e71a 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -e992059d6354434e91cde562e463f51bff7eac58 +160d9eefb4d3e42b620053987fcc8654e98d40a6 diff --git a/decoders/premake5_v2.lua b/decoders/premake5_v2.lua index 7f7c37b7..6c90d953 100644 --- a/decoders/premake5_v2.lua +++ b/decoders/premake5_v2.lua @@ -1,17 +1,22 @@ dofile('rive_build_config.lua') +if _OPTIONS['no-rive-decoders'] then + return +end + rive = path.getabsolute('../') dofile(rive .. '/dependencies/premake5_libpng_v2.lua') dofile(rive .. '/dependencies/premake5_libjpeg_v2.lua') +dofile(rive .. '/dependencies/premake5_libwebp_v2.lua') project('rive_decoders') do - dependson('libpng', 'zlib', 'libjpeg') + dependson('libpng', 'zlib', 'libjpeg', 'libwebp') kind('StaticLib') flags({ 'FatalWarnings' }) - includedirs({ 'include', '../include', libpng, libjpeg }) + includedirs({ 'include', '../include', libpng, libjpeg, libwebp .. '/src' }) files({ 'src/bitmap_decoder.cpp' }) @@ -32,6 +37,7 @@ do do files({ 'src/bitmap_decoder_thirdparty.cpp', + 'src/decode_webp.cpp', 'src/decode_jpeg.cpp', 'src/decode_png.cpp', }) diff --git a/decoders/src/bitmap_decoder_thirdparty.cpp b/decoders/src/bitmap_decoder_thirdparty.cpp index 6dc5a91e..37c5a667 100644 --- a/decoders/src/bitmap_decoder_thirdparty.cpp +++ b/decoders/src/bitmap_decoder_thirdparty.cpp @@ -10,7 +10,7 @@ std::unique_ptr DecodePng(const uint8_t bytes[], size_t byteCount); std::unique_ptr DecodeJpeg(const uint8_t bytes[], size_t byteCount); -std::unique_ptr DecodeWebP(const uint8_t bytes[], size_t byteCount) { return nullptr; } +std::unique_ptr DecodeWebP(const uint8_t bytes[], size_t byteCount); using BitmapDecoder = std::unique_ptr (*)(const uint8_t bytes[], size_t byteCount); struct ImageFormat diff --git a/decoders/src/decode_webp.cpp b/decoders/src/decode_webp.cpp new file mode 100644 index 00000000..f2617982 --- /dev/null +++ b/decoders/src/decode_webp.cpp @@ -0,0 +1,68 @@ +#include "rive/decoders/bitmap_decoder.hpp" +#include "webp/decode.h" +#include "webp/demux.h" +#include +#include +#include + +std::unique_ptr DecodeWebP(const uint8_t bytes[], size_t byteCount) +{ + WebPDecoderConfig config; + if (!WebPInitDecoderConfig(&config)) + { + fprintf(stderr, "DecodeWebP - Library version mismatch!\n"); + return nullptr; + } + config.options.dithering_strength = 50; + config.options.alpha_dithering_strength = 100; + + if (!WebPGetInfo(bytes, byteCount, nullptr, nullptr)) + { + fprintf(stderr, "DecodeWebP - Input file doesn't appear to be WebP format.\n"); + } + + WebPData data = {bytes, byteCount}; + WebPDemuxer* demuxer = WebPDemux(&data); + if (demuxer == nullptr) + { + fprintf(stderr, "DecodeWebP - Could not create demuxer.\n"); + } + + WebPIterator currentFrame; + if (!WebPDemuxGetFrame(demuxer, 1, ¤tFrame)) + { + fprintf(stderr, "DecodeWebP - WebPDemuxGetFrame couldn't get frame.\n"); + WebPDemuxDelete(demuxer); + return nullptr; + } + config.output.colorspace = MODE_RGBA; + + uint32_t width = WebPDemuxGetI(demuxer, WEBP_FF_CANVAS_WIDTH); + uint32_t height = WebPDemuxGetI(demuxer, WEBP_FF_CANVAS_HEIGHT); + + size_t pixelBufferSize = + static_cast(width) * static_cast(height) * static_cast(4); + std::unique_ptr pixelBuffer = std::make_unique(pixelBufferSize); + + config.output.u.RGBA.rgba = (uint8_t*)pixelBuffer.get(); + config.output.u.RGBA.stride = (int)(width * 4); + config.output.u.RGBA.size = pixelBufferSize; + config.output.is_external_memory = 1; + + if (WebPDecode(currentFrame.fragment.bytes, currentFrame.fragment.size, &config) != + VP8_STATUS_OK) + { + fprintf(stderr, "DecodeWebP - WebPDemuxGetFrame couldn't decode.\n"); + WebPDemuxReleaseIterator(¤tFrame); + WebPDemuxDelete(demuxer); + return nullptr; + } + + WebPDemuxReleaseIterator(¤tFrame); + WebPDemuxDelete(demuxer); + + return std::make_unique(width, + height, + Bitmap::PixelFormat::RGBA, + std::move(pixelBuffer)); +} \ No newline at end of file diff --git a/dependencies/premake5_libjpeg_v2.lua b/dependencies/premake5_libjpeg_v2.lua index 34ba3547..3ed2ecc0 100644 --- a/dependencies/premake5_libjpeg_v2.lua +++ b/dependencies/premake5_libjpeg_v2.lua @@ -1,9 +1,5 @@ dofile('rive_build_config.lua') -if _OPTIONS['no-rive-decoders'] then - return -end - local dependency = require('dependency') libjpeg = dependency.github('rive-app/libjpeg', 'v9f') diff --git a/dependencies/premake5_libwebp_v2.lua b/dependencies/premake5_libwebp_v2.lua new file mode 100644 index 00000000..00eb5f18 --- /dev/null +++ b/dependencies/premake5_libwebp_v2.lua @@ -0,0 +1,166 @@ +dofile('rive_build_config.lua') + +local dependency = require('dependency') +libwebp = dependency.github('webmproject/libwebp', 'v1.4.0') + +project('libwebp') +do + kind('StaticLib') + optimize('Speed') -- Always optimize image encoding/decoding, even in debug builds. + + includedirs({ libwebp }) + + -- Leaving some notes here for future perf improvements. Define these when + -- we can determine we're on a compatible platform/perf gain is worth it. + -- + -- Some extra details about each of these: + -- https://github.com/webmproject/libwebp/blob/main/cmake/config.h.in + defines({ + -- 'WEBP_USE_NEON=1', + -- 'WEBP_HAVE_NEON_RTCD=1', -- runtime detection of NEON extensions + -- 'WEBP_HAVE_SSE41=1', + -- 'WEBP_USE_THREAD=1' + }) + + files({ + -- common dsp + libwebp .. '/src/dsp/alpha_processing.c', + libwebp .. '/src/dsp/cpu.c', + libwebp .. '/src/dsp/dec.c', + libwebp .. '/src/dsp/dec_clip_tables.c', + libwebp .. '/src/dsp/filters.c', + libwebp .. '/src/dsp/lossless.c', + libwebp .. '/src/dsp/rescaler.c', + libwebp .. '/src/dsp/upsampling.c', + libwebp .. '/src/dsp/yuv.c', + + -- encoder dsp + libwebp .. '/src/dsp/cost.c', + libwebp .. '/src/dsp/enc.c', + libwebp .. '/src/dsp/lossless_enc.c', + libwebp .. '/src/dsp/ssim.c', + + -- decoder + libwebp .. '/src/dec/alpha_dec.c', + libwebp .. '/src/dec/buffer_dec.c', + libwebp .. '/src/dec/frame_dec.c', + libwebp .. '/src/dec/idec_dec.c', + libwebp .. '/src/dec/io_dec.c', + libwebp .. '/src/dec/quant_dec.c', + libwebp .. '/src/dec/tree_dec.c', + libwebp .. '/src/dec/vp8_dec.c', + libwebp .. '/src/dec/vp8l_dec.c', + libwebp .. '/src/dec/webp_dec.c', + + -- libwebpdspdecode_sse41_la_SOURCES = + libwebp .. '/src/dsp/alpha_processing_sse41.c', + libwebp .. '/src/dsp/dec_sse41.c', + libwebp .. '/src/dsp/lossless_sse41.c', + libwebp .. '/src/dsp/upsampling_sse41.c', + libwebp .. '/src/dsp/yuv_sse41.c', + + -- libwebpdspdecode_sse2_la_SOURCES = + libwebp .. '/src/dsp/alpha_processing_sse2.c', + libwebp .. '/src/dsp/common_sse2.h', + libwebp .. '/src/dsp/dec_sse2.c', + libwebp .. '/src/dsp/filters_sse2.c', + libwebp .. '/src/dsp/lossless_sse2.c', + libwebp .. '/src/dsp/rescaler_sse2.c', + libwebp .. '/src/dsp/upsampling_sse2.c', + libwebp .. '/src/dsp/yuv_sse2.c', + + -- neon sources + -- TODO: define WEBP_HAVE_NEON when we're on a platform that supports it. + libwebp .. '/src/dsp/alpha_processing_neon.c', + libwebp .. '/src/dsp/dec_neon.c', + libwebp .. '/src/dsp/filters_neon.c', + libwebp .. '/src/dsp/lossless_neon.c', + libwebp .. '/src/dsp/neon.h', + libwebp .. '/src/dsp/rescaler_neon.c', + libwebp .. '/src/dsp/upsampling_neon.c', + libwebp .. '/src/dsp/yuv_neon.c', + + -- libwebpdspdecode_msa_la_SOURCES = + libwebp .. '/src/dsp/dec_msa.c', + libwebp .. '/src/dsp/filters_msa.c', + libwebp .. '/src/dsp/lossless_msa.c', + libwebp .. '/src/dsp/msa_macro.h', + libwebp .. '/src/dsp/rescaler_msa.c', + libwebp .. '/src/dsp/upsampling_msa.c', + + -- libwebpdspdecode_mips32_la_SOURCES = + libwebp .. '/src/dsp/dec_mips32.c', + libwebp .. '/src/dsp/mips_macro.h', + libwebp .. '/src/dsp/rescaler_mips32.c', + libwebp .. '/src/dsp/yuv_mips32.c', + + -- libwebpdspdecode_mips_dsp_r2_la_SOURCES = + libwebp .. '/src/dsp/alpha_processing_mips_dsp_r2.c', + libwebp .. '/src/dsp/dec_mips_dsp_r2.c', + libwebp .. '/src/dsp/filters_mips_dsp_r2.c', + libwebp .. '/src/dsp/lossless_mips_dsp_r2.c', + libwebp .. '/src/dsp/mips_macro.h', + libwebp .. '/src/dsp/rescaler_mips_dsp_r2.c', + libwebp .. '/src/dsp/upsampling_mips_dsp_r2.c', + libwebp .. '/src/dsp/yuv_mips_dsp_r2.c', + + -- libwebpdsp_sse2_la_SOURCES = + libwebp .. '/src/dsp/cost_sse2.c', + libwebp .. '/src/dsp/enc_sse2.c', + libwebp .. '/src/dsp/lossless_enc_sse2.c', + libwebp .. '/src/dsp/ssim_sse2.c', + + -- libwebpdsp_sse41_la_SOURCES = + libwebp .. '/src/dsp/enc_sse41.c', + libwebp .. '/src/dsp/lossless_enc_sse41.c', + + -- libwebpdsp_neon_la_SOURCES = + libwebp .. '/src/dsp/cost_neon.c', + libwebp .. '/src/dsp/enc_neon.c', + libwebp .. '/src/dsp/lossless_enc_neon.c', + + -- libwebpdsp_msa_la_SOURCES = + libwebp .. '/src/dsp/enc_msa.c', + libwebp .. '/src/dsp/lossless_enc_msa.c', + + -- libwebpdsp_mips32_la_SOURCES = + libwebp .. '/src/dsp/cost_mips32.c', + libwebp .. '/src/dsp/enc_mips32.c', + libwebp .. '/src/dsp/lossless_enc_mips32.c', + + -- libwebpdsp_mips_dsp_r2_la_SOURCES = + libwebp .. '/src/dsp/cost_mips_dsp_r2.c', + libwebp .. '/src/dsp/enc_mips_dsp_r2.c', + libwebp .. '/src/dsp/lossless_enc_mips_dsp_r2.c', + + -- COMMON_SOURCES = + libwebp .. '/src/utils/bit_reader_utils.c', + libwebp .. '/src/utils/bit_reader_utils.h', + libwebp .. '/src/utils/color_cache_utils.c', + libwebp .. '/src/utils/filters_utils.c', + libwebp .. '/src/utils/huffman_utils.c', + libwebp .. '/src/utils/palette.c', + libwebp .. '/src/utils/quant_levels_dec_utils.c', + libwebp .. '/src/utils/rescaler_utils.c', + libwebp .. '/src/utils/random_utils.c', + libwebp .. '/src/utils/thread_utils.c', + libwebp .. '/src/utils/utils.c', + + -- ENC_SOURCES = + libwebp .. '/src/utils/bit_writer_utils.c', + libwebp .. '/src/utils/huffman_encode_utils.c', + libwebp .. '/src/utils/quant_levels_utils.c', + + -- libwebpdemux_la_SOURCES = + libwebp .. '/src/demux/anim_decode.c', + libwebp .. '/src/demux/demux.c', + }) + + filter({ 'system:windows', 'toolset:clang' }) + do + -- https://github.com/webmproject/libwebp/blob/233e86b91f4e0af7833d50013e3b978f825f73f5/src/dsp/cpu.h#L57 + -- webp automaticall enables these for windows so we need to compile + -- with the correct settings or we get an error. + buildoptions({ '-mssse3', '-msse4.1' }) + end +end diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua index dea984ef..e6e2cc73 100644 --- a/dev/test/premake5.lua +++ b/dev/test/premake5.lua @@ -36,6 +36,7 @@ do 'libpng', 'zlib', 'libjpeg', + 'libwebp', }) files({ diff --git a/test/assets/1.webp b/test/assets/1.webp new file mode 100644 index 0000000000000000000000000000000000000000..122741b605f3121d393829ffb5b7a0924db13c86 GIT binary patch literal 30320 zcmV(tKTmC{=ev&ww;z9|_ry=T z^PTx_`2Lsq!+NdrPv?>9GyT5%ruBFDOIy!7>zDLCzZ=2*7lI$!`*?qu-#_f1)A|8> zgU`wfy|Mi-K)-`?+roe8JwUwG@2>SfU@y^rvcK|qE&cEQhp<8wpptVpQWhb!X}Zd%R$eqq0vegID&;yS z!@|+2PxyC^DtG1o4Ga1{5Nl0s&+YO@go{R+4Od+M?-^gad_8=WjKDnv2|TrLo?nT| zA_K+5HRwKnp30vvG`)`5Pf%xm-J)~2vMAx8{F5Fl!`m=i-;Se=xGamtY|PJYlWdGK zsFNM6Qxn#Z9pMVuGjY6k!^S0E9j^SZ*I9RmJS-6OqQ?yt%Ft$Q6{6881V7H(okMR1pZP9!V`IDsRtc${F!5oJ7yS_gDklLmBy z!6bMV80~AwGCEDim)kQ=T$l~mqJbb=i&BL2Efa+ zfJmyJQ?QUILxy0_m1^8i^&vbtLi%7uEqUECLm8rH3eM@qzQR1ag@!9;fwxF9Xw>66UhLocR*N^W+gr_9va|DM%=x7FjYzH5_0 za|b1>odX;i_55r2gpAb~SFY^RG>{i4%C^4D6yD$4(q1-j&yIa-x8DT;)v8@&ZU>L59=7XBU=V8=Cx%4d3={>BB5?;~zwy1;hnJZnR%P;8rjEF{-u+vKc#iW0DH5rDd9<8f0R+XoY|{1lKxHNKMKGM;!VH z=WZX1niQA;9_VL@)@d@4JOVg{sW+$(!*KGf_XX_Nt2{CEMHkWg7LXb=-MuyF<$}Bu zsi*5WD(z%)pSG6s*C;2|N$lgwPF2;%nKgmA({J*t*1x!vmrTD8mB2oXluEw0rJB@)P^zGP9 zpMJ&UdR*)!>kW#Jc?ud4InYzImQewdsq>34mB-M9$88(U}%z%^Y- z(^D9|fr_A3@$x2$TSg4qqMOTjW@IrmGG@^f^W5~1*sLq$E}X?vLa^-(?!Jhv-4^H6 zVZ>BSfFK|u*N^LnB?%SFN{r+)9LVOD(#;Lb>;T3JwDCF*M_EpaL8%t%Pt0G7BanQ$wR{5Z>Q6j;vYlkhw zd7z6W!!eh439>CaRG=UiF85}f-dAg(si4k*gzev-(a2yN35sHxmlAa>0>`;qimz(y zasKBA{@bKq%QmEbV@QOh%K5rBtv?NbXxuqc!L;{gnd3Z)8Rdpv1XfdL=PcR!$Ooiz zm?;}n|U@Om;WXj^{woV2bocR>P7_B@tIUhff!wkiAq^$a=LWVhz3mtv4=5mv{EjHYKT= zII@1j_=&Mp-KXRdArrbPiB#Ge4$Gtm;tK#<-C1HU=dm`PKCj%S%oNeURmoKi4O8*U zl{&)^*f}6JL^|eckO8;f+qUZ&G4ZPb3_kdc4TTKb7S0!XTDJdkG|y1m;cn(=LvEMN zp&PQB2rHgB!ED4sk9;B3#6B{ef`m7+Szk z3>1~9j>vWWX^7z2z&+r{#?dlnE`4!QKrQWEPzQoq7E#{F>8h?rM&~25jChdXf4R-Z( zij+k~V?YV-K3a@5L1pJ`ngV=?F2SHV_HHJu77VY*2fEbr>b|mpj7%!w01=fHJp1f6 z?x7CgUwhaKF~wQ4S0m)NaD@F;{Z6Iw?lQk)n*%ufGQgY=37onk;D-lVi08Nz>$N63 zhfch@jc((5p(f(dWja=>1)n*E$J#pF|5|kcaLYP3Jni(;)D>nDRKlHv%8&2S`n7>o zB8v?`uGi(rd#)K#&|hDbfE&lwrlr~P4Jrv0IY9=m`1`>(`LYMbHP)wjxh)>{xE)_V z=&OG0XZ$bxl4z9PxH`K(PC;1D7P(CyIAXh@v-`v;LbG0Vo*Q=q(IbJrXO*IIgp&PV z{u*`or!jGn;5b`dq~#)t1}x(u>8rZZJ~5p3IM}~(T+*HtG`ukaRoPfbEbz+YSqfd*?fT8m0RfQ9!iWh7(!YX!gp< z%%47vEJwy|2r>qbdi=B_CC`et&34IFNd`~<)t|v^T1kc@i?ztj`US!)35oq>4vsyi z6{TuL=m#7xht|GtTBWin?>9UU+M-qnDX{NC6&;$DU3-|22!EULn!{ul-9k&45rh*v zzZ=pYQ$lj`x{+WN?%P=v2P@2>imL=Y&OQ}eVQ~#T&fDiLZqNCBE%Q=Sg9xE?kj@!G zuSXye-?rA9Q_3Ts+-T#fH@0|uS-2A!d!6LSefTZF8OOyQPQVn(?92o7yypE4vE}Cq zd^S9;RaOHUPk1N)zyRPrG0YiG)lu&B-ASlqd(NY{ecv>tVo?6{4u8(^O=oodHkKpo z%cV>@q;|V}A_FGS`8dko4)>Sxrm*XYiF0k9|Ezn?g&jH|*dZ;)irT?W|Dsm7EZq1x zl5h1bFS$Op@aw8=R_F2m;bZzSH^y_47C+_gXWr#-%m3ALY9h1lFjD*27=ll(xI@Z+ zH=*c+gItf?%k`cES@*(Bd$w9^ILLWhQ%%)iV zoNMp-703waEa25w2YfGog@h-FA0l=R_jyRrXYtY_-ECfzD?SE8=P~kGuNI063x)3l zsDyZ_!w1rL9=-yrx#~Isxd6ydeoUl94up1N!c-eGVE`Q)T6%x)+|V|GQWIAhUlU8) zIfI5FK^muZ+fwd0l4--Phm0n1q=kMO5@rXbBkZy`(iCAW1dEd>9Wj2#Bm03H-~YXc7Ij4*6Bv7`aX1?&(yf$_SR079 zXxxqR9mL6Z2P^HoP#a>U?99Jb4ZTbR%PbVBWi0a-5?fxksIj!HHUof7(0HVaEi_j= z?-MZ@^Aep0n7Y#}1!yv6YRx_MUdzP6(#bm?a6QdQ*s=WA8lIZAY8LpnDwZGpv8yrR z;O2KsI_U?bXhZea%$52*j&ju_(ERh1i7k?GQ6r*UV5TYmKZPVkj+LVr?Z;%#xxU3S zDpm(m>OU>E_=dKw`z9n`;+L&oLlRv{6ewN`tk8D>3-02F7V(NxV)*I#E!UuDTEKU! z92O&<4ZQ_Zj`qqow3Rq%kL(#l1OBjJAD?L~C8t<6UR>Gd*bf%rGw894N-{?Tkv{uY z8rvvbs~AW`YetHqwKxCPW}ZANeS}e)89~A@R(kiaaA)^qe`f4YYcbSgM9%s7$3-gU zV*=eU1U5rvaf=waixw2d$sP=Mj-b&^BH52sy)zfAoi!y+cm3$p&1x&GQt-i%o(+Yv zoTr-jt9icMECqe2eD_$H8DzoH(?qByp!GKWyCSlR931f^HZ2*xDr=cQf-xYpQ%15@ zt=9Cpf$6bc_HsZ52AM}d-Rz_ejHm$p*dh&I?fmg4&EV7c%DV~VFr|S33L)#ihaRm; za3kI-cfH^YgPMre;$uP@sj{1GGuM-+`CQ438;osgZ$ARuZI%Lqm;1nUPQ}D>s_0o0 zg3iJZV@`va?cn<|YY`(6EagS!l>ko!V0R*i0}m8qT1v$cNF^^MKI%3Wxo!YAJ|Mnl z^1j$;3Xd2+)lT7?AhZ1ALcDvaDord5YqYElY4JwH+ZCjCUODNI3DBCye;Nx*Y#QUsyU2R0;q}XE4tfaU6f-E93=|_Hq|7@3Pjd1GA z0tG;P50tWH21^Tvem!H*-J58X0mt6tmVCp*k6tWwYjGf>G+3{M7!=R7FO!RT;EGB; z9)@IO<&o5*1e9n|4gJGJEXM6I!y4Ln02#0bb*slwA|kSu1G^*1W3XxVyB>LE1tac) z=Ypz}e8?)f&;j?s;rf>S!?5r%*IKs0L>SboMm~)e086*Wo~VA-1{$={k9X#8ahSu| z%z_)$b+BcC*p5Av+Z^Sv_P>lN*fhT?sgLrcy6|nyw(^}63lRGW-h%Mjm74W>Ih#S1 zy{x=}3N08FbF)38=>{d`071E0-oI*R^HK$R}o4jN&1sk)K4+jid-ZMtR zH#2+!(5dLh<0N|*;)D@|%cIF`g{BD0cD-gp7uqmJ$ddS!}$hlTtX>5y%nm~a8^$UrfA*yqK@uuwN}#8wi3D$=Hl2(`E-@o6hH38U6y ziLJ+-wz%+ua9d!Bea2}Z^Xn+cx_%Pio>{D`$3ck0J0gg_?hW=(|6@v(Vw(T$$IL3B zJWs3L_Kqev3})KtaRahfQ^hq;izpE0ebIwr@MIMhKB!vOG+(T)p$MY>L+0#G!vCh@#eC^;<{rH*|@e^wP{1Zkcl zoVTH69n9ADX%^7fYAU8Y21~%d@;Q4{)6h5oE%w6}&TNR23%u`4Rk-86)?Rxx{x9kY zCAWCTkH!gD?EhnjeSXzwA>;D;`+XF}z@5S8dJ3=&ABCYDhS$~_P>GjAf{EZE$Gsnx z763|jlRjB5GUWxp?1PR?JY#gQ+D;!CqD!<6Te z8g04Hq6Oghx->Qcq?WN=uR}}*j!C9^w)qM|mh|)&%*9=%vkjO5+0`gfPosFc?*urL z|2(Am66NRI<@)Hnz}JcfyJ6d@FwQjZ<`(PeTQlZyx}Z|>T$uRa9KyTXf+`YDIgs#g z@neS*j?q2FxD*r;$|z>)1)3$6VvO)EtiI{_yh>o*=roXYtTJL_zA?zsWFTY9bjXy~ zvrI6Za$vxU)CWTF7)tT-J8DIAx#ntz*bRXUPfD`vC=9xyGU|Gt>U3A$$ZR*t+ra_| z=G>X%3)c(ULlJwbH*x%U^--DLC&NzH)OrRoB zM_-lF3!|5*V)4tv=EI$uA{1q=b~u@v{z^WP6SF3rxb!dbi+XpUZV=W%41t~-7x{wkmynW2MQ~aBlC*2um1~C9go{8Ovnscfev5ZNmmojBV9$?QYMr4{f2O06kLJa z+%0l0gD2YeB%j@rp=nR3vP;M~K;FC#np7j}aiAjuUsBi+pYWB42Yv(uaf_2DSuXGr8=P~B zrXX43Vs#p^0_hcaD@dDDfBLDg=Wk4GJKKqRUhg!e{>dD!@{os$xEGY2h^m*wQ z40yHrz`qNf<)qV^oSrio%T>;R$WOh`H|(exWZ#KZ9WUU+%()MB=Q6HD2=s(~Pd*vR zVLyW9hEnM3&pcE;3(8Vc{6nw9Uha$0Wt>okv&7pi$NtI#$4JG+JE<-o@*rbiIS*_$ zjNJU!rc8n zix@!+*ZJ_3EN(hN)$Q3#J@8mK3x@t8rc8pxNplN>aJ4_ircDzySGb(xIsYtDJNW9W zT~SfGl3#+@7O%63tI1f-^LAejL*u9n+l zC0ToI&x5@|6w34xr{tF$Cq~a^AVOTz_w?$bwsxI_5^mILg{U5LstmO)?XUwkZK#(| zp9>HAd0wkOb6!Wx^LyDd1K;k&`>q{qFUJVIM%PuTTfh6qw(#-$o$((PqFF3V`#&bw zmf)(V3^32?O1e0tk^sMpL5i>1A2J^PaU}r$WW=z&|H*BUAZZ=PtDx<;;}+4l-d4B5 ziJ;7eC!n^OieFtVY4lI43|oz4kgA6zOJF@YQ^61xzhL&B57W&rzQ{uD--!oSDqYegAJW`V^ zaJuLNuqMAJ$0=rENEovut#QX24_D~u05(}1(3l- zAw4Y<8dAE8hDiZL9ul zZMYcyNno+8n#=MLvtCh4UJNAOX!ZToE$g5o?Hivq3TVDygtwl%A^Ca_{AaK*IH>5i zrbOGUx>b+NTR5%*&TeqGXL%&j-8oQBynzdNcid}0(!nBrU#xo_RhcYfW6b;e`gGIb zz4qm+7I##Zu8g76Ca*mu5nH!Z;s--no{zNuT?x96nDn8U!}(Zz*FSztq^`PiL^K0A zyv-xc9J_VYSg-U=x8+GF!|sB47T7i_)LhUV;QoydW?*$EU*|$`GL3e2ks3_&ADfKH zI~JM)-CgtbE0%nNO-4d)ouAsX%|&?cf+kQ^DZ6vfPd=z9X*;X{Lx4OGn#)S67vy%^ zLMUtbrl$a#gnnr59WDfy_~Wq8`f#+9X^eXkfL-|q$J~yQP`tXrw9e;p%uI=bEGO?? zEFTYqWOmwl-y&3*NBVB8U^6hY>80sdV-*>(5DGESl5GM;QWGY_HhIYS@>BH+Bi|Sv z<{Od|l=)ra`DZG(@J%(k=qW-~6ODj@vU5(XLxT8g$G-Vorh&heHS?l{&k+mSJE#1y z(6u%XL@ZdQW;u{ACFl(SPeKrWzk1MAPDewLps#m5h-0VP89l8ZX`EVqEy!!kV2voq z^(n}&myqfIvQVXv%+S?20hu}81Pvvdhtb!Tmwosqk=uRMRak$g-yyiuaBXZ_&amZ( zEoeF(pl!Al|8yFFw^fvpsy!5^0buD#uc8yBNH7ES7!W+Ujg!L=)1if@=Do9gU-?#2 zCd26u>nqb>TIce0(%#V}fn3K&C=(VHU}l-X3ovE$V%+aq{S@p@O$t*n8~I&>Enu>P z4S|%Kj{3VR!3ejO2T7|yZP4dpS9WhF(^2iJi|sOLXJ647ig9e=9z$Ei53#!VyIuYsl3!R%M~5nkP~)Ijl$pGhrcAel-mHp{a>Jw z!p#67{?oiLVno6ivQ97=oTjor$IIRMNSQHmhSLq~c)$iTp4%^l6NB}wG{DFSVHSWO zFx8_tIwi%ZtOOm4`zs&L^p)u{BgOJkV0x2MgrbkMygbnM9|3hpE)7t910<@p+!q(z z@vOqjXXb_z=Xr@du;u5wMn_*^tLNEHaratU1++ng`l$v*ZC5MBszlywAI31hHD!jT z-2FzJuAyFO80SI|fz75MaXR@?GSNsDn^L+`C3>6zr8RDmR*C7cz1Oi;7y5VQI;0OM0Y zBQZP;5(Q5q6VITR-1h7Y+@ud!YG+Hkg7mi{z!8^cy2G+vb_IJ0-tmMyy#VKdB~j6` zqrcZBa)f1@L&Z)}L_JtA2w(=*EF$5{YXh9qIwPL0UgjwUXt|&@sTR8^^Dy#Twe`b* zcJelmQG`=ThmsE2V1oA;yvr`Jw#YmyjienmKV=3ZAfG)GbeKmYmvWlq$O;S|^fr{T z?Ne50<}`@&oG)y~HY_?p4-dib1EB9tnN{{yL-0xdi72xvgpIGDe)X$}+H{t?2G~iY1XR|CB?%=cW(GE$s7SHaI>%ghC zBXCrIVng=KCS;Z(;rTWwwvh?-(${HS(JSlGm<_o=V0}&kRv_X@>$YcT8->OQ{ngn^ z;I71Uz*~+#g}DOM^1Q>RWI=BS5<+CiE$j&#NTUl@VC@_|^W9%Bi~JMlX7S>N_Ce29 zVX|ZMFmthmNaj)8`N5iO$mao|aOY`bpWKVB3JYuH4W}orfE%5*f@5__8|}lttim{- za4I`O>T=65v#Zo z2hktLfS8oiiEAz4H&q^+Xt?>P5~Ky!e{Z*>kONop(&s!jjXqVgcqt4vZqdC9a;;$z z;Haz-*r{O+-8~O7Q7RzItzl5-+3_$nWHYUfe?xozwL1_1BFTXQ2!M)Ci#W7 ziY-j(duF9W$}lf46Ph;8Dt5PkSCE3w@ye<*ZN#0vHz|@(Z!n(z=rzN8o8NOYyEBcJ zPviB_ADNwU<2)(3pj9S2f7T~8*c-M*J^P+rQ1L~Y;h*{b?84(rgfX?873ikDrMg|#(S zOO06VNVlb-agfMkk5hqVvg_i3SN`4GEVV77{wibWrnq}Gq$w^rd(@z5|!P+-nn}7H-%2c@B=W~&F5rovV{#V z|4qI;_8DhJa_%w52FHX&#aX3{$azpjwP(c_C3qc`dwWG0x zvlBoCaDeh23OC_Ed`-A=I}co-M2+aD-M)n={*!#aQV4&*hy|;m&zeJC@(V7g8i5&O zgFaZSc*x*WNE?+|>w7iSs z@r8r<9lMiyZ2~7aZ558xvgQx;i^N1L4g(5N$-RzCk?9AQ(tCX}&$|>6A+6t!;&m%3Snkq{qk6%I*75K z94dlFRk&1ui36O&fyT1)mnUv2DaP0fjH)a$Tf0V75rL;-zP@K9iupZk#by&n%E@}d zc-Dz(ELA|6N-i7)bY%NB637M<;(qDQ_{6kDNP*r`EWyY`5WjsA(`(D58Eu_nk)dIy zV4*j9$v)dMo^7Y%)k@-zAO_)5rRJg!tZTkrRo$p z;3*BA_n!Z#uQf1*nIHNh5vv&@fu1bT3jRbyk0i%?fMKbjZ)HvH!nt$B!*Z6DkIi$< z)#57GcTRg>JOOC7d>9DtGy35(%kQb#6ho;lZ{$rJG39YK%^$C&toH(hXf~1IZB@Lh z4;xCJB(0m;m6Td2_hLjHe2e2`ihY$i9k(~F2;>fSc?-cb!%ME5<*f$wi`4YSqV5AL zH}3!{O9{S#Yi|*D{aEe|WeL4^BcefMJU6IdQ1*Aqt z)V439EIA&ZCdj1P#7%r;E-8uKqFpSiPHXR7^^kXniVKh%=PNz2lPytd>TMEWX&n~H zzP1ugN%PzfFLgPE9Q(k94PUW@wN1;ZuX|Y11``@m9Cq`^V^SJpKWACPa}N54reKHw zB_bKXV3^%{#fRgK8UKf!+DVQ#p<-q-ckrO8v`C-CLegKo3%-@5@eUW56{i_S&hg6e zpR{u6kFkd7UAY7@(H;5a`G{~ci$qE=x19Eso7e^Fn>X#p$XcMaIm^CA88Qk}>7?m0 ze9)Nv(H*#sMHqN^nwlokq_TeBBfUH1{mOB8uK~dsW1(*)pSkt@^a)8@Mt~x@S z?aqhWtLdJyK98|Ef7vHm0Ufi`f$=-hDEx&C#HLWzM7+&lCl zWCA-kdhhut`HUH-Tx*q|HDi10bYTrI!r9blTJ0nP-GxPSj~t@_9j&}^gOa3)gzSAj zKm%->4CCS#&dm!08u+Sc&hU+pwl|~Z>L}I(%2J!HY{k1mI@lmR0Y;9*r0BpRDyT#U zv`S2K_RrVsj6H!>2%JRa0E<=&Ktt-F*pB_etRy7u;@lDE{Z4fSDC6-^y+U;u*lM}N&lzW&8PNRzi#@%`jU+oGpxvAjq{lJE*<|Foz zSBx${OXL~1;Z!l0>ojF>@vqqaSW42c-?n?7t8ztgo$_R@# zx8#`Qjbw^a3p-Hk#3e-_E)|5k;QSuqv@si!Wy_1#iFtyHdsUuxrTPj?4Nr!DmD2g- zu&KhYWDNaYS002aEHpFNwG8#rmej9IH9&FGkcXbvs(CY%eNycLSqYFGqEpwO{qknT zN2R++ysj0qMYmj)2K%w&Xw=|fk_cBcD^@vZO{=Jr@TC$I+PW%AuOgox76lLx z-i0vdc$7;Zws64%nvU041ebs+G)K(+a{r<&oqxv7Sa}#r7)LWECwLrv)OEFVaD9Wl zQVYdD|Mn@uF=N&bmDeL3BUtB|&|LUF!9B*w&rgL~fvcfIY%KvNSB)lApyBZhI)J|( z=%niZ!M|5IG@f*kAp>-LVbMM=zE7jgM?VDKKuk|*P8{Hj13TD<8_jjL<#dmlOK^qU=kZV(H)@s1@r?gnrIl$t3PfS9+sbZ7t_ z6T9mN$B;#o;uA&pzhP}XSf3PW@Rlg4C^4zPn%6?m-zj7kc@CCe(XU%1fMO$1v=i;< zG|bTg3V@*wG9ICabJ1$C9sQuL@$w9uhUucjAz?>+mQbWdvoZ*i!n&|*UXHx&$)f!z zSUoIUhyG;ZGb|Hf`g~)%ZP^IC%Zarvi5se2ZJ8yr+HlWAACBhZ1gFVy;#|(XA%gBd zoqgLX)7awaC1sYV-!i3{WcIQ7f~=0>w`$MiU3akUQ%;Cf5MjiY@SNW%(Al{<^cx0V z+1Z7Lq+&Y7i}+2X7!?q-`~<6`ywsV$*r9z$pGM-I(y#=YaS^}sF({kvd9O1%TNNWs z^qXc@R{u9;EraSlSc@ii5|!6yU~i{__M-J6$s(TD3@Fxk3w(m)ffLW$DuCL4MGS;a zXJ%3zr7tsQ;lWo)JY4G%GVUCBF z>qaR=2Uh2e15A0UJAdYD}EQ_b;C2A8^az-Issgft<5WgV*2PcrzPjFSO2fO zS|8_Bgmj)hlzt`K* z5xpQe^zuLMRu#E^6o51;pw{5elAG-b~K8tB?RotJ0coyk7r zHP$)CTX6WI*jor-YnNJGQJyPg4$U$yNk|!7hu8suIQBCmKToA$(ayvYbk#K20D!(y z0*xpU3B}V1)Xadi*{k8p9;lBa7K`MsPvw-$U8*kK%vuX;iH%-&pCh57%$&t3Q&s4L zUW{blCY>q@4Hb!vJYjt~c#}IsJF4FP(1ebKuU(2Ifyg$H!|-bRRiiqz9GVDN8F624 zSFZs3sgcjYZF+cNvTDZlC_VdCxLdDTk|-A$)$Xzl#-2VD zVcx$+V_E6V*4PpLwN1>x{L9}rx4&Me81E{v)ZKn8!Ij&nKd?CVADf}cpLd6zUDu!` z{mo|{W;cR2`QS+uE*NqFPYv#DtWN?cH++goAOB!L1-iwzUtk%DfjPg$ob?52>BXt{ z(e;+&xgZyAG(K|M?;V{#2$RE4RBF}}k)k>IL-AZryIYU2t#Cz5E54#02vL^bxY9jP z@py50Toj3}F0#NP#)HSHyz%)RET6c0JJfp`v@}lu#Ul_1PzemQ*m9jq{&YW4e*6dy zi#Uix)+^xL2qkla#aJDzF4KfIBWdhrg8@ugPQ`}Nf?cJnS+{_agfDbUB9T`H$_j(3 z>Ps{H_0xVk#ccL%hx-oN=+yR8Eoa}p8{C+yPsuU$F#q8H`=X=OF`vvjU5)szmmS5C zFX9^jap1^s1ZVMh3O@BwwI^-{XB3wUw^ASl6$-o*Q|v6m2GOUzt#%e1_yi!8D}xc>>1YF46H_4%*2+6L5ynbd=hI?0V)-pFU8 z1DFiab*|zYuUg*aOhje#Lei1Hz=XBwpU?(nM2Xoqg3x&EYuSPNx9do9;{nNFTT~dE z{PG*K*->NK>sBzcDXZ-YHsCcM*E(Jqj<1N|*>z5qUQ&P=vN7oc&Q|YKDKfIcA{4I_ z2(%7DkjL$v#iT%)BF8U5B>3F2)#h-E8eNEwO95G)bb!Tq{T#snsbf9*ZZXO$Yp>$- zLo+%FGc?3k@bsOPDSl62iQp?t{nN?w?oqOvH z6p3&i)py?sn^fNz!iN^DK%G~XoVE*%Hs}L$dpyIQu~~>L5`W}v1wMe^Ow1hiFuE8J zUsZ#8gkZNCIx5gnRmDpw*_8on`{2s@N`SP&_;zysKJjlUAda0=q+dXHTMFRW7zpv=Aan`@lNi632F8nn@Mcv4A zDsV{#88^75+os59SkO8u7r2qM5AGn8(j9&f?cEK&gBV&o(q5!vj)_is#C)6aH4NbY z)D^cprH4oI*?wMTA_hJLx8&i{tz%7-4_;MkEAGV`3}_q)ka9q{viZ(p><>LWJO;5t ztHw|zIvGnBTA3E7AaXq^`X0gZk>um2FH_6t|Ea4k-HC^m5tA>4^5bQyBZO+(zj*~z zE&MjdR`Ew#^iH*s}cPL4m0T-R~tZtrX@BJ27Cm+(6IX983+4aEMbOuW^d+uD<#)`ce`n{sEtFSW*ik?qQVTi;$R#LE1tbDjvIL!7p zU;S)r!##`RB7NWmAI{2m>I(VSbO3t}dAw;{o#!E#65>vUa&jfn1zZZ2H}NLxP6f37 zGC~n9UR!IEKYlmoB0EHKpN4r~aMnW9Glizk;)0LXn(PBM_rarN%!tz|HkZyXrR%sw zjMtR-^#y<5$#JdV%jhM|C^QHTTxU1Y;YI*|vzdKNv+p*L#O`9V1yn2VpR1(n09V<* zqN|a{opD!0?j>~iZW0+oLDI(2B`|UDGtO5&O;+zI(dx%tlO%j7?ch^7rJt3J4F{xQ z)_TXmIt~%eu8In!u2$-2X4DY+tKG3jpbw7FJcJz&Ym@u!#x~4svV#aMDF6r8n&kE? zs*J=cc<@p)6ZK6yH=Ax z+Thu>8-XwY=FD#j6kwdN4GHV@u&!_eGgf~bl8n;}AH$XjF zTt_jD%{U}wfx1l5@$XYp5^*r|;&C~#HMEnKg>dTX^;oolT~J|L^z1pU@;haha{+iD za7NJapbCo^UHEMbJ%+LAY_zw$$=Vo*|6Vv8A*2|ng=27tIou5O(tpdhju5se1&pIQ z7oA;zwP=La8f3aZG&3e7?~YULTp{YSCw_(_K4ETH7xQWj>%9w$7cKMiPEK*?+XcHo zi`o-E$Z#0nz8DXyL1QqtTp8LphJ(yrQO8ErDIn*CbyKE_TN6aVokIPlt7HZ^HsF(m z#&g_a^)TVJYAH~iJ?4v2*y!IGIA`IG=B764oZ##B)B)J)@D4b+%QZJ12yz`=m=sNC z4Z$A`BhqnysW?DP7k=i@u9#8he5q2+-f9KRNb>9Gvld@5vGx9O-GEy^wOhVGBHxuH z+Bj&R+a>>-NMC6(P=h87fmzYJ7Ym8zE9FTz3mdldRxA$APEh|7-#K<79i*H$nswQG z?%A$}c@!ye0nT=&q>-o=cO{r@M7%eMBZFY?pg6{}W(Y|gRy$Qzlt>?PH!?(lH@N5&xI!P=QKzcs!`TQq z105@T)(dVQGoGQZ1+&@}ZF{^G_>7Vo(a%ngY5^hp*dP#(ZF#YA7w44GJ-J1TJ=kEaRM`|EorBIaHkRjdQ?je z_77!|G_MF}w-8E2zu?LPFM)%{1S{KT1kHASpE$o{DRH=9g2JaBOhX#5C;OJ|w;V&& zfxZcDLMOm>DLZUm=m8ugc=cJr8;Ci8`BbJN2Cvs0?x%l?R&LUTDg?ApDO zlvGaS&n>fso$ELcs zXLOaLFY&99;5NG8?c}{SmUgfbDGS(wh%V zr$b;K^sp3#May_^=H!wCBW7~MV^ejH%vOr0-OI`f;bpwOIjfY+n<$ z|MSb)!?{&n+9(RpiiBZq4Ks-3d2xui*pfkl45>N6|9n$FC!F~(U|-cR#x_j4`A)CH zSX=sFLKxQ=A4%4xIkWMjxAfZ%^k+s@s?mYbSzidFD`}l}kJ90* zr@ne>RV`_7=n6>tG|-3`^@wf=FpkpJ;Uh)?@vP;Ax1u&D`dU##DztEBmC@nkDes8d z#d!6db<7tHDZ9DEmtk7m_b61SHgd0i_9$a1eCXT+#gf(TePChFsHm%5!M~5g33@(f zN3xz;$v+>K`tw3>fIP+m$5nscLU%tKd{(wMh`M~>bRh6i-s)QZzh}%z=(4LqBWbbo zFSdnNH3Gb@<{0f3$qRgE60@5z-GNmurCygss|njGU&wA%QtEok0BRH$bwlcIW2{_C z#I`ddzD+dT_wY>^1us0zLYD?4COjD%{wq27iVi=T5A5q^wd2tMICoAJzO`EmH@Ex* zN64bLa|3|>&uPeGx1S;s0se7938Ntx#XrsLIpPOqhpUk+nzI+aHkgJg)sy>QCEHZ@w!?e)_QC z#w58OWlDVHnF1`(b9@&;f8%_2^j+29ao3dU2a_1cCz zVS>DNLJ%zuo#0go4_MgUcScZNU;gjZUqD;{{#{fYZ6TlfU~n;Euo|i$bjXPiOu0vo zc!CB|BFCcUtPW~_I=BtaODx1)U3&ztq7`3~M14_aM7SE2Gph+2Z(}8(_#4(@CkXJm z%MuL9LFQOH*7Z| z;;Aq~I458nf^ybUKQAhn@6b&9q0749Q3S1Hyv{a6vHJocP<==h?o$<}Xfp6+yB=(L z?Tv#+qm664g0 z(H(`|4kvJ5zVC^P_t`n?%fK>Mpt9*xS{kG#uEp!5`oljKEE{(bh1d%Hv`B}+IHr*= zxb`dQA}GTsjBX5oV9?5GVINeq18GsN>QClQ!Ri5BHloQN`!%CmQs_QwZC%e*G`{i zO3g?2&{JZHr?M0i{~2Xiq7;U$2}BGk>;d<8UhhQwg(+66FN-`OM2Rtwsnc!MxXF#z zU{0rr&5DlP(`W0nRp06tC7;`XpB3-8eZ^aC9D9p%`XvZ)QiKX)6>b^gR1qm4GScI9 zXNqS?@rDnRRoc8ZcyF2E1h0(`-w1q#%N(WTu&|g?l1wO~;t8*^k?5_`hfcRZSGNv6 zt_FS#5Uo~!Tx17!khIUux;!Wq=To+$pVj}FuqjKKB}?WQ&Ncvh%L#y z)Aynxogw@vS8vhAzW+62XCgm8Z?iH?y0IQQQHh6y&fkKH_x|1mF=%o*F_%NGcZ=$! zKLlaYgENErPcrY}05S_D9D#Mm$IJR~8rIIeC{vlocBRsWK^U5o_|t_rS@oPX7n?iGV( zeCww8ztLjIVkoq}wQYpB>xH(q=^E@_p_FMa#u*HN>5Q%EO(*8;k)*P8W+1V!2h`%2 z3ZVn)FKZ-w9=H0G#C5J0vBGu=Z6?eHXX3q{$oJc z00omZ@Zj`9MuyX-XLr+3lDXiwK87j3^(Sj}Mp6YIwF2{OgA99ix@4Cu%-=1u$BPoeO4ySzPUWqHpv z7^m(<+(WYmrR~KQb2xTivriIzSie-~>+53f`!_%uV?bKMh=(|X&jtQjsW40pVA zrof?oQSM{oYusGY^Xx^hK^>pId0xoJ5&xC;&M9WaS-s#pg}u;1Kkw0%-tP{1+VZiK zhu~$891)*%FRpFV2Wr8^-0xDD#6CLM#-aqfKVG)uAA$G$tmY)mG5jTF=d|;KV~T|#5Ztlmz>F0%jY>Q0YH0N>)gOods0X9 zCGlSgT(M_yY}B9O`l>yQaV~9l_B?-}C!HtVu5W?g?DZwlu;|KGcct2j6zTf6t%&^C zkawaTk@~dZ2U3!D>&A1A9QoFEkaNcxnUau@Krlb`SJ8If`9g%^LSU8hXLiO6SF*Bad?uJRtzpwY3sKqCy7T zCh@6wln^fuL`=WLsaCcUp>?Ub_3I}dWS*Z71HtNiWk4h+E{b#0$(lM$fE%svvE2Nh zoFCPLUEzd=h!HMth7MwmLL$j%Ff(S%Q0emRMl(%CP=UE+6o)-7{oDu}>l z1Y~h8db>Zx<2R=N_fXSONz^*zoe3wu>YfT$LP!uY#FO6H*>qp-U}W^X4L>S+WJ6ge zRyU+gK=Pkj8KxF*&!-t6;cW&*ZuOTpI9}J~v52+DI7JDMgB?NPj_}2@*B8!7NR03mbGSMlh8t8}BGMO4+WL4(xS1a9M%+%;s3RQ);i zq@~JhIYn&2H6j`G;jK*N$h@RmH040#>e_9ew)-xxKre3z+%XXSJ_k_vh?T&M+o=Ts zai&CYZx_PHr^fvbu^f&y2(1~()w8*}B0N*0_gIchQvBN<*~Ls@+W1R-*%LBio+a3l zabzSx^HBmvFF|xhwdPM*InRBQ3-kj2$b~Ctwg-o2>J9zcv7zF1AaZkcYKA{2 z#HPgDG)f2mB;W}cZD4f-EjzFT3>WDi$MY_~RFNpsux$1OIkGL4m%hOoDW(yx&x53H zz1wBw%{gWBq2o4a$j@G$e*kZ4MV%B;PlT>(Z&ipJnH;n)C1k20{p@k<@tIyZt-e!z6O|cY^@7tTH3D%(CDLr#fo*LVW6A+!AK!wAR6{2k2P+vmGWX0r0nb4Rg!sY^onba8h>@=@)UjDC0D`K;DvQ~9TdiL_R z#q><}kL!|5=&!XeRYjnJ%5>8`7=*}=&vsnCZW#B_DDS;c#tvLr7BAaO(LZWWtOZdB zyn`HNhJ)B-`dGuCM`Hh=FWB)aE*~{FU#yqlt11hG^A*8=J&t?@Ddi@yUWJ$T6SU?9o#FJf?C3u()QS_&3(ofArWc+4F z#JT=K2Vif+X@I{SNWo2A3>!+v?g_4>L=@EM^YRZtA5>0}rS(&0tA)##>6+_{X9aNW z;(u~nu!gZ|ON2(}8~o*cNc+iV!2U)hw&o}4zt-OWJ)Vly_gAkKo*P0uRgj4>Ig!>Di;56`}$Y1y`{iZ>IVH2>GHJU4qQ*#JCI*$4j{) zeC{EthErzxqy+nH^oL4JtcS$NGgSQZCp`X84>*9T@u@H*C=>-B&wcw0GOv#>#CN}rh@6Ys;({982orYS`{KytVOnyIudVq9qd79gG`jzad zkmtoouvnFcm7ogubNSRswtH857U}EP;7t}RV08KSNh|fj#oVO)>Vr7n5X3%*`WzB+ z9cC)z5n2@q!kEWAc%P$T-|Q4HGZ&#t{2yOXz3&{-McVHB+Q7L&d9-?74N+ar!itM~^=awD;hmm5hT{Hu0oy=H^Uo7N| zmnVO>o-#f}u}p}!4Lk0vGToeM&V-(6tewwy7y!DSy+Q_B4z55&+uJKyod&tx3Wc_a zv#6NJp~F_NYrlx-X&{xYc@S6g?EZ~@R8y5`gN^xg*ZBiK&Q6E}_MA>qsY790rYvvU z!NFig*2krnh;*v*M){Nu4FO)S4#wd%%++PD~|+R^2;yqB}tZBx9$(r z^NzPh7&^Ce{i|8Kkx-p_%-hCUB`**&2^_^GamA6$-Xa#L+t@7O3*{Gg3%&{ecEz?h zlgeaIv=$^)&Dkt~awwCnoRd5%>j}?Y0HD-9f~4Oj`O0g*!Fv}T(B#!ETV61xMM#PV zsmt7^A=>3TVFRAWw!L(=g+a{}-9DyZrz$(@jYfC-B~7A)2+T>V?$MMbT|;t5Oz{ zE&>9;u#zH;LT_at7T0*rfgs3?O#ViKYTb7KJ0c%NzK$$kguzIz8P`S^zs|8QckzfX6)&O_NH!2pF}ahh263`9 z7BY2y&GFkE!xML(w1Fy;$Jv7P4hcYC{+bwCe_iFljWU2*3eXlb{O~1mjHi&hr1-7K zb?z-P;ZttNgIy)m=l;x+WecNm6dCe5HU#FGnIEwRY~SfJ8;g|@%-wC{%V9u6Zn%Q% zq~c|yXI?;Bd#+0DwI*W42#>}|WW(f01JDz9lrIVF%IxD| zi0F=ZPfoDA&?~4+8QYS}!+effJ}4b&M1^;Mgly3JHh*op+Y7_n$40(GV$9p>^l}xe zXhS>e2`;T&u$S%C$u5NeTV{NpU3GI(pmvLO+MJ!o2?OT5eN5p2q3~m<8ixyrLC4g+ zyUqfI1(pC)QlE*RLJezqAAJMzvn~Nf#YKy`2U*b?_SK_dY#unCNxx$=06J32PsVAh z4#Q5QWh|*^(iI5KyA3ZTF>R9E)k{VljqeX|@kZE|J?D~u2kmfKL;#K|Uhqn)%5kvU zjf#^S)8WQ|8UCB`U;z(gLX8<)UAvDF%QfW=+-ai?|zs6pg5h3YRo;%a8Wg_xO za=#2*ORaaI^2wOk9$FkSqSLU6E0n(;;&zEG3)G|!q0CfaF8&r}IMr4sz&Q@I3-J`# zQ)w!NJWl1z+K)%B;rg*?nEt?_mhYzrl_w4ucwaC7bs!~GYV$;(hshuR55Nzhx3@Fakt zn`6fjk6ROk02d9wVg9sL8>bd{Th<1?^ugJ(a*-Jdw7-<=rI#9Ex8;d;x5{Y81Cg3H zXADKPPnF?px{L#nit%LBGd@kq=7Q`@wH=`#^UmgA~51K z%t*v71t2(PEBppRekXzf176OLDI8vCNeFCQO|!;=A0&+O#6No+Vt-@gIs@Sk7YS6RJV3U-UyyM8r< zC%r%YfV!79=U+y_$>3%MSg|rLHl(D^rEbgqm-U8Jp0Ua%8>m<;yq)bQ zh5uJbdm#;e6+DOYF5NZ;9;sYFCyDSr_i(ll-GU>t;sAe)(UXRO@gk0_`|!p>JM#Ge z2iClKbE2A<)1S$JL-UfTqI-`re1Cg^0?bL}@!mDjPH_$Q*`SYVfj$%sS>Rwb6Qfsj z8_#ML=!Gm!q#r2SBA^RK_~61f27W>}u5O*xfX%#BbO0|X z;t^u@=Y4RBw&d8jXU^Z!Q6ic1QhPphrqkKZGw;^;(@S6DFwJ(sd6v2f2ecGBF+n#l z-z)(02#-%hgZKUsIh~tu;YB5 z-2g(P1DJKVN+Kk)NV30HAmnD3MSaqJ&Vu3!Y*09zCEuX#H`r=o2Z|a<5+pkn<^uw- z3LMh2N6GRN-Y55dT-)jBiSJT2VQiqskr(jh2E9|tJ#^c#)sKl^u*~1WANs%PRM22D zRSSdE7ybfpT;Uw0Wy27?53=wSm{XX%mWQ709fpMORcCC(JfBGyf#GIW8;xDl$ zwBrXnAY~&*EIui3kxtGkw=0(3W0(A#m`ujhZ2bs|%i-Hn_}bsAGzh)PmdEvsKJ65N zESq;~fqINSkwrHT;vtf$bx`mCWQdG^mpUaBy^QKMpbm5kO>N*#&3t*nJB9X`Fuv$n!3@Y)2h3Q@NVHve4kaJ=b^&%;8 zjh5A@NP)OgXH7!Iay(-IX|#M*le7hB7=Ly#?aYp4QBOcpF_~SjE?THlFBqvvKUuaX zd72~*oz)dH#P;`iQlSDdqUlROlS!eYn7yO%3^>2e(DNskf6!_i+56NMs%h@;woSRx zn*q&aXDc#v+UluP?%_~$1D7|>uAZ4%@-fh+{wNR0T$2P`g9~e!<*_P;Gyx?GnN|~i zowYdH#);sr>H@q^$AF>wE3KZx^=CQ~f4S}Mb4;*J02Q8c9LC;Y64NrS`H)y6QKOZO zf#g2G$$(w@Dp|jI17wF&X(@|Z{b&EtKoOTz5@q8CYaI{VN!o5)R65fq86d7oiN4n7 zjXdR0x>iJFPYH`A(LPx3#l=rdE%w53CIV9hD9f7e#RRg%DN89vX(CG?t>E{T!EX_C zWO%fonlflnrC%T)$eN7BK%EuF6O#&Wh@ihfu1qMwoiG{GvWRc`ip_UxT^F_^*JBcP zm5tP_5of3;dP#P5ERFKsjxI2ZSOuK6W(zkvS{pZAG;iQ-!RL%5AzCrUvy3?dZw=T7 zAy2uMB@aCLKMQPbq8I7&Fl)brx1;T}vYVxwsN*lzt>BS+Z|o4i$?EhT(9WJ9(1X1> zc3Ta9i03nLK74tXQIUfabTz4B|1c8yC)xuy7;!BG{-@I@+2drS2-JB1#a*ItU8WVv zO2<8hJI(dE4|tgR&_W@GCSD@#8w5~%fH@9QUHl{+JUR0h2DHkAw|RGF8NZnX2g|)k zb43=S9D&<*Vx~9vMn|O|Sd`^*p;9DQ`HYaP%q21zhR6k?^?YZJ!@?C|1N0wATK1*? ze$=oeXaBrhdF^t*7dozPf@h_~9P5jjLG>gb$H=OnhqVT#;Hjp@Kt zJAq&87}@81jp4cJcs&ax zZ*KG`=tX6$;F1^YhWtxY1%4oE_&Ib`93vaHrZ@nyNXI;!cg$7 zgRE8xX(GX{6o>KiYu9x3#r_1Xy{t!a7q@NTY^}!a2BZkhsYh*Dx10{NOgp^LuNMW^ zmT`{a{$(Eu&GAdxL0k5JBz)mKO=$haSlE1t_t3NcoK$kS=$b?eq5cZQN|t$1K!Vy( zO*9!3-m-1%-38{?UO1Ny1GArelvt}F3VvjxU`0aR%x32^jJU*wax3M>c^y%Yg329N zxIiAS@o)p)i5b>q@*K}6l-OK%h(K?)DaJMg^h_TBTP5q6h(d+Nyh%30RrNvSyoc}^ zyjQ<3r;I_)JN0iZx$f6(wf0PcROM^Yj>&}3u*fNv=1uq|XwbRU$71fRc?rtG?L%@L z_^!wxuZ09;4wBEonC?i7t@tYaM*WR^oqA8rgOcryVrft_~IQ6x^M$ z=vmaxXmrBCl-is|+hRaHx6jz{*&jbDP3o?ddzuj>0t(R6{iPmXx?820e5b{SBi=jP z=4LNy)UL9wopVnkX!_G|e>(b!5Rn_kLMqi-LQBNNyX5F}%XL52kxc-&V07ZK`nD+_ zw9wdj14;|YcTC~9t9jD3GM;9w%^(>md)%v1I}5=x$Ri%xnB9%QH0iz~SL$ zD@h*CGP2RPs61eS^p+ko#!BEOS?(pkEpb5g;_2XMcEH1HMe$AkF=4g?m_j&=_Cs`elEzkWXo zt@$F!1{9{Q8#xZb2ReaP3v|g&wrMsOQlKw2)?(z49 z><0|${StF(CbX0*Zzc(8-Ia!4CB<-{wOHpsbKycEOI+NyWmT{opIVhHHr^$KUz}*q zs;5sA>&RFoY~vSQlj!Pq>{BWCR-{fO@u(1lJ*%z=C@mb_Ufa(6ITZ0$)=ZK9CWET@ zoiD= zDAYxEH_(q=?vAr?RH^d0McBw|FB9qAhW6WdWyQ$jjjAXVNalcB%T6OtQU&>R3`a=8 z8xMF!^CyeYcx@WXI9S|T8_WPb;otSDdV3^M9BGw?696-Asb9BRBsTpN#$<)XQ892G`&Em4x(BswDbNgM z8B-X8{c0o)una#^&WlYq(U12slhZ*~P7-+MY9W5jk2l+m)9uc7bXySJ&Q4+F5||SA z^H7k;y09Yz*y1$b#(cpZyt3sKdA}}!LNID}x$7VLFKb3Ij}}=?h^{|sKo0O=WK{Zo z5dIS(nvAbW+Dppda| z^lIfhL(A?ZJ5zyq(l=uuLwvF?>$C({!@-3>I-{3DBnkwIgRF3++R4(7DsJ&GrtuEQ zqA^?cncdofW1^2i$u|3#VNmbg3Ry2Igzz#GZ{flRcif1LrJpC8bldH6hP*+JIEtv! zmH@HpmRrMhX9GA9Tc6vj^m$Q0^ae&gdpeq)n~490dzj3 z-SL=&_!VI1!hj?q*T>JB+;6X@5-0WxeiUQeQ3S)+tmAruhFu==2nNau^DL((%LtEwOnW6LXWIzjdfh* zj#EI3^9nG}1dJS3!#WSm)|A9nyf4ZzrIXN>x(m$&DWpn5n}M!9R<^Sv9iNUn80>@c zrq9&e$Z=_8r2w84HKZCt+d(1Ub_8xdsr0}q+aUIVI8~kHh{Hy*A5(Hg=dY<{o_*It zKx7Zlzkim;oUZqqcOkOR(SM{4t3?aR4=a>4#UVs%?FH`O!X!kRfOo~cJEpXbZ!C4m zJ9TSBDft* zZiJ;ryei(vO$-Y%d-i>cGxxz>7S&caO6}7tZy=`%#pSA}l6P8jy#`Z9;8RZ8C6Lh! zqd6KIiK^DoC+BsYA%BQ91}@+`|Ke&|VfguFlCpCV#T#X}L9vmXcRt%zgZY!elLlyK zSrQ2~aqD>PcL8e%%3OU6A4>f-h5S_zqsuN)L}L7(=6n|{i*fhMi6ON@O*>b;eKnTN=@%Dy-JS@rs3VUbx6j2CwTn4jjfZV@3Y3#@ zZpk&VdlOR)IS^H%!K%;D3>7ObuA&JLEPqDQ-X9cDYisS~+)TYiMQmio;lR>31-E`h zj~}l-^Lbb81=>tO=yO&a7%Ae9m|^hRbo#~9NmQE9k!gl8ufm+Go{@acBQ47bFI1Nl zKqU^2Y1AvMeCKtZkKhdqoMbySCxTakv6IkkLXSa8omD zuGy6M=@xsA&G`axww-hulPip^*)1`el6@T;#c9V)t(!$S{WGu(?Hd=3%x{|TUym&7 znO4-qXaucj<~U)V*s_y?k}%Ogu)8KKaooo+Cpw|P@9K3TdeF_n3i72|7t1Gc z4x|F&J2=MFeGr?ysCY}fpEfY*B$%o)3}$WU%>~^B4<*R>dMG$3^L0L*el5(}7q_PD z2TDQb7tdn6nU5^G=}%br>hcK^R~c90`l|A`=3xOTjRw+X!&4!JjHF8c&L6KHSNR$jt=qYXs?ciCZ(E9V&7VIq6*FVsR&ZQhWL-uop|x53@&0^67aPNn zMwmS(LpTSFe+<@6V*Y-+9a3Zhdt3^6*~IXNim9?G`p%ow(=Tv}^sDy&cp9y0W9-{f zq5~eOS^;=2cxXIy++?dmRH~`tY4ntjW1SPdJci)uO(+%t%X&4Ku3`@-hctQPf!Z7u z$S+=MtG?@rozX6{Cs4mwz?nYGh>2|dVL4zO@CN9Hc&ZK3K;UfMe7?j#id}|NnW@Xr zK7MzYMCllvG!DT5eF)ACiz@C+vVJ+0`zMtbXfJlLs|sLs)FF){Mo?>v2&YY?2U;Zj zvj-D>vincFWS+*!*hyYVn2$mlGWd$1Wu&{ytJoc39Awo<}E9Es1M)ciku;J)@ zZl0n*!oxYm)03fb2Zu%Qnt7Xin56!X*-}Kd*3}QX_o_T}aJw2=r)PjYTkZf%!=MBr zl34Snd6)Z{J9d9Nxv$lKyjpJkE?q==T*@DO@5e0%ebx8-0F|HBKm1?*tS8qIGiI|U za7)f5v81`NjH<3iCZ|)nY}U3_!{?fQc|(6Gi3o~|Y6TS)5$bFJ4nc05^bK6-&%>kC z%)jGGsNd12mV$PRHb=2ZHIfTps#8rI=OcJ06Z3Dr^!O!rAZj6S1Iuz-usz}V|M5_N z_5KWdjFt9X+1s5>iEL4xiTr`NASEWj703da-M#u!*n}AXQsKg{JsF*mo*5ORwIN33 z{hMVU_N`g402gTwQ{x)J49c{0S3qb&iBfQJAn@r06bPJB2LH*qOso_TQjO0VK+cJe1s$o4xIV zfd^+-*iP?)_=Da41N(FcM}YE?r3hEK8kq(PkeS;WmHHZ$?>=J7<@G7#3+0~Ga1N`d zdYJZyg@Pzfi*onONbhj7NBs{-5m2g2KI;?e_I+WO$8AyJHS+(hg^x2D8|rY0vDAU$ zb3qum1XX!c%;-s!^AuGMy>$qoLLF(RoZLFPKr&79g_y+zIGV z1-kim**;L~726t#oEYwQrB41(#lsM?dUh)j%UA^eY$5d)i_qdiYCrFgi0eN}iO6m1 zRYR#@1~X$V=~FH=2w`M(H6jQ|)9i!}a5$WUz?}zLQK>TqY*eMVm*Dh;I%w#zCD%a( zM=h4Tb>y`(DX;$AG`z}U`aVI4q28dZL)u%3$ojG_KL2w4r=vxZRg>(Yh}T7`}NvE!1-xY_iLVtsb^!ppaT`^Ll|8V@p8rc4A4(-@jnmR^nn4gRR?QgN%73( z(22hooQLiq__ETn8HjxEi!eW43tQDAPK&kBmBIQsA_m7q#^M?lE`9rtq|2QV;8gqs zm+Hnn$u6K|jNC^P;AU=cl07F3ue-8g4PKQ;iurt=U)p1#{7V-q`IA_E*{XHWPw)p8 zMK&wqfAh$NSM#SLHPo2EU}-r4Am*16Kj-T zN$C!ItE)*0P5O|fEaOY4kXl0$;YwulZ59s41Dh1q0Vy*aVZ_x!b9*ncav0qOg)ozY zsu?O@9AtzpViN+(b7 zmrARxNIrhh_i$yJ5kESHCL|}EJs;7J4k!R+IqvL~LWcYWsLEj@GFcLhw5TrbDyTGG zmNPvrS`99z>=TW(Tu$0`Ww~`{4GNX_dM8qGK}i7>D%<^~wEE3lPDQrA9z#wHlUGX+hAu4j@yh{4Y@1d_U~y0kH(B?nuE^5 z{!B=Ul+#)7E*4RFjs%h|W|58Lku7zt^W#gRr2a7C=~YjaVxjlu^Od`lAFa?0CK$@H zwv{^*aD;b>8!)6g+y(c;5=b@dm`=hH+M3NJvJQN=i?`c~9g2!-88|MxLqD92Py^}h zp1pD#-}CCJ*v_YvnNe)m&C@hKp=dXo)R{?}tn0nmYu+fEXU}1}xo)J4+F$l)U3ry(m6S5@W3@lhI*TAw}|lcdJut7C?T$@`J35b0z0O)_Vz zH;X1Zgz7}keG*5Atr{B{nD1}5V@VIvt*1&bdfcDep9l1`U*3|4j2Vk}-3i}@zpnMO zR2{|5BAr)9GN*yq5ymz5W^$l82Zhcb+I`F5X>miEd=Jx(hdP3)OAd468bs=)m5y?= z#>Tn)0J+yWM5zbIjNJVdN!#cTEfH^0ftHJ5*#mu~_AWx0tmjHEt`D@iw*I_~n!;9U z>xuOv=RW6>O)-{cA;1;PlsIS6_nD5P6BEK>>a6WLCwehG#CzGe<^_70kZ?u@dzI`G z)-HYU#G;SIj91&)_E-y_&wgoVeEkw?2f59C@k)fmDGFAFfI;k-EjdyvH8~?1gf|7I z?0RScuA2yEq49=p6L1#9xS0MBT7v1zDke-#RGAJVf7x=GEgw~`BPOof+^!7-G&`C_ z=;4$syvsWGp^HD^6_LrgLUUht+WBJbyYxa9Spn=#f0k?UE4FG~JC@aA)>_cuf=f`R zhsB=tJ2y)*L?|P{SC==uQ^dQpP1A!Pc3?_(xH<+O?Yd<~88R2D0IBgwjI0PO7fhuG?v{ z2pdy)zAH;U^V;hk$w%D-{&|h`T_IYHG{kL`3u{y;? z*w@-@8jdv4khSP$skp}SJ(6EJwI&UHPR(n^gVgo?msng98i;)L(@S}Oz(sH*)Eclo zy!uAn-&|R$5V%grsRP6sIYOLgB-l&eXsG`Y_b4Tg!Do4kx7rj?DMW-)y^PzmdV~l( zRjd@Fp^op;GCyYZg=Y=~SA#ovAwYsr_cbiyx5%gbs`EKM%ld0lUi^m%RHbm&6xEo2 zL=gL8{33T?AAszSR?@|I<|6)8F^wbY=dW~dMzeE641qR_FH6)$kL&ZVTc1G)-xiIm z`e4+X-`DTinwedt-*AWk`8yK?@0qQ19=p`oV>mE-ERYc$PSBSUPmnMhV>|qb@Sz*` zM=-*vfcBiu_;L|yBX=!Z2hxckGGP`f1w2os#G0eH_m28k4Ap=q%&^DZ@*jlS27ZM; z3vJlX9s&Q#mtiOF3TChfU**1m4>@26>mZ#X4e$XmYtdSQs`C?QfrepP9&)ryTn)BL zWS5v#syUn(t#MW@suWi?gN%t(2pZ3ckeAY69{^U8)-y8u4((@;XqgMEG$^y#isT^n zkUBRqMT&haUHr_E427ta;`*8|RlwttJ{Dda|cE+n|)x1e| zh}4I?gRxaTFzy`E+A=r=~`x~nzngSwcIz!28#J2OL$=7p3AvIhV zMrb+{QN1A~_Hm-elGCM&H;JgH`V*1WB3G4SqWcpw0bVqmER9IS^-;7?BK&WiTvfra zcZZjyi7@lyF<3EhkL^1%X##D!=?8R>wZpJtx7r#e9NQjkT2@g+m0q|C0J%1y4GAMr)C1rGmLINdP+phiuNcq(~z$+gMihPjOn^(L-|SPr-C^o>Oom9<_uZ6T8V~g-bQK%fE#k9yZV$BFOL zIMfJUO}G~Dv5Y8kb6(@tD6?SE(#%~TF_j_h5c+sfRJX_OS#PmpH~$i#+&}OuWE^|3 ztU@7(R)%k5FaQ{&w-MfS#U{^R)Po)0Bo|kQDM=EVD8rp8ZKKER+ndQSHbu)$rdV1| zJdIiIg3#wP!c}h>Fa#KwhBkELj;3*rzkj`dy)_HZyOJ TU=pkm8Veub3_|1vJMaJi)t)C5 literal 0 HcmV?d00001 diff --git a/test/image_decoders_test.cpp b/test/image_decoders_test.cpp index 4d6a8216..024115b8 100644 --- a/test/image_decoders_test.cpp +++ b/test/image_decoders_test.cpp @@ -64,3 +64,16 @@ TEST_CASE("bad png file doesn't cause an overflow", "[image-decoder]") REQUIRE(bitmap == nullptr); #endif } + +TEST_CASE("webp file decodes correctly", "[image-decoder]") +{ + auto file = ReadFile("../../test/assets/1.webp"); + REQUIRE(file.size() == 30320); + + auto bitmap = Bitmap::decode(file.data(), file.size()); + + REQUIRE(bitmap != nullptr); + + REQUIRE(bitmap->width() == 550); + REQUIRE(bitmap->height() == 368); +} \ No newline at end of file diff --git a/viewer/build/premake5_viewer.lua b/viewer/build/premake5_viewer.lua index 9418d8c3..725da540 100644 --- a/viewer/build/premake5_viewer.lua +++ b/viewer/build/premake5_viewer.lua @@ -79,7 +79,7 @@ do do includedirs({ rive_tess .. '/include', rive .. '/decoders/include' }) defines({ 'RIVE_RENDERER_TESS' }) - links({ 'rive_tess_renderer', 'rive_decoders', 'libpng', 'zlib', 'libjpeg' }) + links({ 'rive_tess_renderer', 'rive_decoders', 'libpng', 'zlib', 'libjpeg', 'libwebp' }) libdirs({ rive_tess .. '/build/%{cfg.system}/bin/%{cfg.buildcfg}' }) end From f5c9054202ec1710e0b3faa93226fcab5463c6fe Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Thu, 22 Aug 2024 06:31:59 +0000 Subject: [PATCH 136/138] Improve Vulkan loading and organization Load the Vulkan library at runtime and build our own dispatch table. This alleviates the need for DYLD_FALLBACK_LIBRARY_PATH on Mac/MoltenVK, will allow us to continue targeting Android 21 (which doesn't have Vulkan libraries to link against), and removes our requirement for the $VULKAN_SDK environment variable during build. Split out the lower level functionality within PLSRenderContextVulkanImpl to a new "VulkanContext" class, which also hosts the Vulkan dispatch table. Instead of using Vulkan APIs directly to initialize our context, use the vk-bootstrap library. (We only incorporate this library for tests and path_fiddle; it's not part of the core renderer.) Split out the headless functionality from fiddle_context_vulkan into a separate class. We don't build GLFW on Android and will need a Vulkan context. Diffs= 46a3045ae Improve Vulkan loading and organization (#7873) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- build/build_rive.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rive_head b/.rive_head index dce3e71a..481c9cbd 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -160d9eefb4d3e42b620053987fcc8654e98d40a6 +46a3045ae0a8bc9ab0cbbc61f37a49d13e60a3ed diff --git a/build/build_rive.sh b/build/build_rive.sh index 30ad0879..e091ec0a 100755 --- a/build/build_rive.sh +++ b/build/build_rive.sh @@ -270,7 +270,7 @@ case "$RIVE_BUILD_SYSTEM" in if [[ $# = 0 ]]; then echo 'No targets specified for xcode: Attempting to grok them from "xcodebuild -list".' XCODE_SCHEMES=$(for f in $(xcodebuild -list -workspace $RIVE_OUT/rive.xcworkspace | grep '^ '); do printf " $f"; done) - echo " -> groked:$XCODE_SCHEMES" + echo " -> grokked:$XCODE_SCHEMES" else XCODE_SCHEMES="$@" fi From 8812887efeda4319985af860ba9d3ff69349e4e2 Mon Sep 17 00:00:00 2001 From: umberto-sonnino Date: Thu, 22 Aug 2024 07:51:55 +0000 Subject: [PATCH 137/138] Fix Android goldens It also removes premake5 alpha and bump a few deps Diffs= 5c14a4a30 Fix Android goldens (#7902) Co-authored-by: Umberto Sonnino --- .github/workflows/tests.yml | 4 ++-- .rive_head | 2 +- Dockerfile | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e51343e3..286469cc 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,8 +15,8 @@ jobs: - uses: actions/checkout@v2 - name: Install run: | - wget https://github.com/premake/premake-core/releases/download/v5.0.0-alpha16/premake-5.0.0-alpha16-linux.tar.gz - tar -xvf premake-5.0.0-alpha16-linux.tar.gz + wget -q https://github.com/premake/premake-core/releases/download/v5.0.0-alpha16/premake-5.0.0-alpha16-linux.tar.gz + tar -xf premake-5.0.0-alpha16-linux.tar.gz sudo chmod a+x premake5 sudo mv premake5 /usr/local/bin diff --git a/.rive_head b/.rive_head index 481c9cbd..a69c8997 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -46a3045ae0a8bc9ab0cbbc61f37a49d13e60a3ed +5c14a4a306b45042e505a7a7ba176e301f1d8305 diff --git a/Dockerfile b/Dockerfile index 31ab9376..e3e6d188 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,8 @@ FROM dart:stable RUN apt update && apt-get -y install unzip zip clang cmake ninja-build pkg-config libgtk-3-dev xvfb cargo wget g++ WORKDIR / -RUN wget https://github.com/premake/premake-core/releases/download/v5.0.0-alpha15/premake-5.0.0-alpha15-linux.tar.gz -RUN tar -xvf premake-5.0.0-alpha15-linux.tar.gz +RUN wget -q https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-linux.tar.gz +RUN tar -xf premake-5.0.0-beta2-linux.tar.gz RUN mv premake5 /usr/bin/ ENV LDFLAGS="-pthreads" From 1740f4a209e233119a47007de732bbd8a81afb1b Mon Sep 17 00:00:00 2001 From: bodymovin Date: Thu, 22 Aug 2024 15:53:39 +0000 Subject: [PATCH 138/138] mark dirty when constraint changes mark the constraint dirty when its values change Diffs= b2d27b6bd mark dirty when constraint changes (#7909) Co-authored-by: hernan --- .rive_head | 2 +- include/rive/constraints/distance_constraint.hpp | 2 ++ src/constraints/distance_constraint.cpp | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.rive_head b/.rive_head index a69c8997..1e827643 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -5c14a4a306b45042e505a7a7ba176e301f1d8305 +b2d27b6bde96e68a9cac4f3b7efd12782e9351cd diff --git a/include/rive/constraints/distance_constraint.hpp b/include/rive/constraints/distance_constraint.hpp index 83a9f9ff..5af1a705 100644 --- a/include/rive/constraints/distance_constraint.hpp +++ b/include/rive/constraints/distance_constraint.hpp @@ -8,6 +8,8 @@ class DistanceConstraint : public DistanceConstraintBase { public: void constrain(TransformComponent* component) override; + void distanceChanged() override; + void modeValueChanged() override; }; } // namespace rive diff --git a/src/constraints/distance_constraint.cpp b/src/constraints/distance_constraint.cpp index 7565ed7e..3ea5e664 100644 --- a/src/constraints/distance_constraint.cpp +++ b/src/constraints/distance_constraint.cpp @@ -55,3 +55,7 @@ void DistanceConstraint::constrain(TransformComponent* component) world[4] = position.x; world[5] = position.y; } + +void DistanceConstraint::distanceChanged() { markConstraintDirty(); } + +void DistanceConstraint::modeValueChanged() { markConstraintDirty(); } \ No newline at end of file