Line data Source code
1 : /* File: pencil_classifier_2d_layouter.inl; Copyright and License: see below */ 2 : 3 : #include "u8/u8_log.h" 4 : #include <assert.h> 5 : 6 : /* ================================ INITIAL LAYOUT ================================ */ 7 : 8 : /* ================================ MOVE TO AVOID OVERLAPS ================================ */ 9 : 10 : /* ================================ EMBRACE CHILDREN STEP BY STEP ================================ */ 11 : 12 : /* ================================ EMBRACE CHILDREN COMMON ================================ */ 13 : 14 : /* ================================ EMBRACE AND MOVE CHILDREN TOGETHER ================================ */ 15 : 16 0 : static inline geometry_rectangle_t pencil_classifier_2d_layouter_private_calc_descendant_envelope( pencil_classifier_2d_layouter_t *this_, 17 : const layout_visible_classifier_t *ancestor_classifier ) 18 : { 19 0 : assert( ancestor_classifier != NULL ); 20 : geometry_rectangle_t descendant_envelope; 21 0 : bool descendant_envelope_initialized = false; 22 : 23 0 : const uint32_t count_classifiers = layout_visible_set_get_visible_classifier_count( (*this_).layout_data ); 24 0 : for ( uint32_t classifier_search_idx = 0; classifier_search_idx < count_classifiers; classifier_search_idx ++ ) 25 : { 26 : const layout_visible_classifier_t *const probe_classifier 27 0 : = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, classifier_search_idx ); 28 0 : if ( layout_visible_set_is_ancestor( (*this_).layout_data, ancestor_classifier, probe_classifier ) ) 29 : { 30 0 : const geometry_rectangle_t probe_envelope = layout_visible_classifier_get_envelope_box( probe_classifier ); 31 0 : if ( ! descendant_envelope_initialized ) 32 : { 33 0 : geometry_rectangle_copy( &descendant_envelope, &probe_envelope ); 34 0 : descendant_envelope_initialized = true; 35 : } 36 : else 37 : { 38 0 : geometry_rectangle_init_by_bounds ( &descendant_envelope, &descendant_envelope, &probe_envelope ); 39 : } 40 : } 41 : } 42 0 : if ( ! descendant_envelope_initialized ) 43 : { 44 0 : descendant_envelope = layout_visible_classifier_get_envelope_box( ancestor_classifier ); 45 : } 46 : 47 0 : return descendant_envelope; 48 : } 49 : 50 0 : static inline geometry_rectangle_t pencil_classifier_2d_layouter_private_calc_outer_space( pencil_classifier_2d_layouter_t *this_, 51 : const geometry_rectangle_t *start_rect, 52 : const layout_visible_classifier_t *the_classifier ) 53 : { 54 0 : assert( start_rect != NULL ); 55 0 : assert( the_classifier != NULL ); 56 : 57 : /* fetch data on parent classifier */ 58 0 : const geometry_rectangle_t parent_envelope = layout_visible_classifier_get_envelope_box( the_classifier ); 59 0 : const geometry_rectangle_t *const parent_space = layout_visible_classifier_get_space_const( the_classifier ); 60 0 : const double parent_space_width_diff 61 0 : = geometry_rectangle_get_width(&parent_envelope) - geometry_rectangle_get_width(parent_space); 62 0 : const double parent_space_height_diff 63 0 : = geometry_rectangle_get_height(&parent_envelope) - geometry_rectangle_get_height(parent_space); 64 : 65 : /* determine outer space around start_rect rectangle */ 66 : geometry_rectangle_t outer_space; 67 : { 68 0 : geometry_rectangle_copy( &outer_space, start_rect ); 69 0 : const double children_envelope_w = geometry_rectangle_get_width(start_rect); 70 0 : const double children_envelope_h = geometry_rectangle_get_height(start_rect); 71 0 : geometry_rectangle_shift ( &outer_space, 72 0 : -0.5*children_envelope_w-parent_space_width_diff, 73 0 : -0.5*children_envelope_h-parent_space_height_diff 74 : ); 75 0 : geometry_rectangle_enlarge ( &outer_space, 76 0 : children_envelope_w+2.0*parent_space_width_diff, 77 0 : children_envelope_h+2.0*parent_space_height_diff 78 : ); 79 : 80 0 : geometry_rectangle_init_by_intersect( &outer_space, &outer_space, (*this_).diagram_draw_area ); 81 : 82 0 : const uint32_t count_classifiers = layout_visible_set_get_visible_classifier_count ( (*this_).layout_data ); 83 0 : for ( uint32_t probe_index = 0; probe_index < count_classifiers; probe_index ++ ) 84 : { 85 : /* get classifier to check overlaps */ 86 : const layout_visible_classifier_t *const the_probe 87 0 : = layout_visible_set_get_visible_classifier_const( (*this_).layout_data, probe_index ); 88 : 89 0 : const bool ignore 90 0 : = layout_visible_set_is_ancestor ( (*this_).layout_data, the_classifier, the_probe ) 91 0 : || layout_visible_set_is_ancestor ( (*this_).layout_data, the_probe, the_classifier ) /* ancestor may already encapsulate probe */ 92 0 : || ( layout_visible_classifier_is_equal_diagramelement_id( the_classifier, the_probe )); 93 0 : if ( ! ignore ) 94 : { 95 0 : const geometry_rectangle_t probe_envelope = layout_visible_classifier_get_envelope_box( the_probe ); 96 0 : geometry_rectangle_init_by_difference( &outer_space, &outer_space, &probe_envelope ); 97 : } 98 : } 99 : } 100 : 101 0 : return outer_space; 102 : } 103 : 104 0 : static inline void pencil_classifier_2d_layouter_private_move_descendants( pencil_classifier_2d_layouter_t *this_, 105 : const layout_visible_classifier_t *ancestor_classifier, 106 : double delta_x, 107 : double delta_y ) 108 : { 109 0 : assert( ancestor_classifier != NULL ); 110 : 111 : /* check all classifiers */ 112 0 : const uint32_t count_classifiers = layout_visible_set_get_visible_classifier_count ( (*this_).layout_data ); 113 0 : for ( uint32_t index = 0; index < count_classifiers; index ++ ) 114 : { 115 0 : layout_visible_classifier_t *const probe_classifier = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, index ); 116 0 : const bool is_descendant = layout_visible_set_is_ancestor ( (*this_).layout_data, ancestor_classifier, probe_classifier ); 117 0 : if ( is_descendant ) 118 : { 119 0 : layout_visible_classifier_shift ( probe_classifier, delta_x, delta_y ); 120 : } 121 : } 122 0 : } 123 : 124 : 125 : /* 126 : Copyright 2018-2024 Andreas Warnke 127 : 128 : Licensed under the Apache License, Version 2.0 (the "License"); 129 : you may not use this file except in compliance with the License. 130 : You may obtain a copy of the License at 131 : 132 : http://www.apache.org/licenses/LICENSE-2.0 133 : 134 : Unless required by applicable law or agreed to in writing, software 135 : distributed under the License is distributed on an "AS IS" BASIS, 136 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137 : See the License for the specific language governing permissions and 138 : limitations under the License. 139 : */