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 : U8_TRACE_BEGIN(); 20 0 : assert( ancestor_classifier != NULL ); 21 : geometry_rectangle_t descendant_envelope; 22 0 : geometry_rectangle_init( &descendant_envelope, 0.0, 0.0, 0.0, 0.0 ); 23 0 : bool descendant_envelope_initialized = false; 24 : 25 0 : const uint32_t count_classifiers = layout_visible_set_get_visible_classifier_count( (*this_).layout_data ); 26 0 : for ( uint32_t classifier_search_idx = 0; classifier_search_idx < count_classifiers; classifier_search_idx ++ ) 27 : { 28 : const layout_visible_classifier_t *const probe_classifier 29 0 : = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, classifier_search_idx ); 30 : 31 0 : const bool is_ancestor = layout_visible_set_is_ancestor( (*this_).layout_data, ancestor_classifier, probe_classifier ); 32 0 : const bool is_self 33 0 : = ( layout_visible_classifier_get_classifier_id( ancestor_classifier ) 34 0 : == layout_visible_classifier_get_classifier_id( probe_classifier ) ); 35 : 36 0 : if ( is_ancestor && ( ! is_self ) ) 37 : { 38 0 : const geometry_rectangle_t probe_envelope = layout_visible_classifier_get_envelope_box( probe_classifier ); 39 0 : if ( ! descendant_envelope_initialized ) 40 : { 41 0 : geometry_rectangle_copy( &descendant_envelope, &probe_envelope ); 42 0 : descendant_envelope_initialized = true; 43 : } 44 : else 45 : { 46 0 : geometry_rectangle_init_by_bounds ( &descendant_envelope, &descendant_envelope, &probe_envelope ); 47 : } 48 : } 49 : } 50 : 51 0 : U8_TRACE_END(); 52 0 : return descendant_envelope; 53 : } 54 : 55 0 : static inline geometry_rectangle_t pencil_classifier_2d_layouter_private_calc_outer_space( pencil_classifier_2d_layouter_t *this_, 56 : const geometry_rectangle_t *start_rect, 57 : const layout_visible_classifier_t *the_classifier ) 58 : { 59 0 : U8_TRACE_BEGIN(); 60 0 : assert( start_rect != NULL ); 61 0 : assert( the_classifier != NULL ); 62 : 63 : /* fetch data on parent classifier */ 64 0 : const geometry_rectangle_t parent_envelope = layout_visible_classifier_get_envelope_box( the_classifier ); 65 0 : const geometry_rectangle_t *const parent_space = layout_visible_classifier_get_space_const( the_classifier ); 66 0 : const double parent_space_width_diff 67 0 : = geometry_rectangle_get_width(&parent_envelope) - geometry_rectangle_get_width(parent_space); 68 0 : const double parent_space_height_diff 69 0 : = geometry_rectangle_get_height(&parent_envelope) - geometry_rectangle_get_height(parent_space); 70 : 71 : /* determine outer space around start_rect rectangle */ 72 : geometry_rectangle_t outer_space; 73 : { 74 0 : geometry_rectangle_copy( &outer_space, start_rect ); 75 0 : const double children_envelope_w = geometry_rectangle_get_width(start_rect); 76 0 : const double children_envelope_h = geometry_rectangle_get_height(start_rect); 77 0 : geometry_rectangle_shift ( &outer_space, 78 0 : -0.5*children_envelope_w-parent_space_width_diff, 79 0 : -0.5*children_envelope_h-parent_space_height_diff 80 : ); 81 0 : geometry_rectangle_enlarge ( &outer_space, 82 0 : children_envelope_w+2.0*parent_space_width_diff, 83 0 : children_envelope_h+2.0*parent_space_height_diff 84 : ); 85 : 86 0 : geometry_rectangle_init_by_intersect( &outer_space, &outer_space, (*this_).diagram_draw_area ); 87 : 88 0 : const uint32_t count_classifiers = layout_visible_set_get_visible_classifier_count ( (*this_).layout_data ); 89 0 : for ( uint32_t probe_index = 0; probe_index < count_classifiers; probe_index ++ ) 90 : { 91 : /* get classifier to check overlaps */ 92 : const layout_visible_classifier_t *const the_probe 93 0 : = layout_visible_set_get_visible_classifier_const( (*this_).layout_data, probe_index ); 94 : 95 0 : const bool ignore 96 0 : = layout_visible_set_is_ancestor ( (*this_).layout_data, the_classifier, the_probe ) 97 0 : || layout_visible_set_is_ancestor ( (*this_).layout_data, the_probe, the_classifier ) /* ancestor may already encapsulate probe */ 98 0 : || ( layout_visible_classifier_is_equal_diagramelement_id( the_classifier, the_probe )); 99 0 : if ( ! ignore ) 100 : { 101 0 : const geometry_rectangle_t probe_envelope = layout_visible_classifier_get_envelope_box( the_probe ); 102 0 : geometry_rectangle_init_by_difference_max( &outer_space, &outer_space, &probe_envelope ); 103 : } 104 : } 105 : } 106 : 107 0 : U8_TRACE_END(); 108 0 : return outer_space; 109 : } 110 : 111 0 : static inline void pencil_classifier_2d_layouter_private_move_descendants( pencil_classifier_2d_layouter_t *this_, 112 : const layout_visible_classifier_t *ancestor_classifier, 113 : const geometry_offset_t *offset ) 114 : { 115 0 : U8_TRACE_BEGIN(); 116 0 : assert( ancestor_classifier != NULL ); 117 : 118 : /* check all classifiers */ 119 0 : const uint32_t count_classifiers = layout_visible_set_get_visible_classifier_count ( (*this_).layout_data ); 120 0 : for ( uint32_t index = 0; index < count_classifiers; index ++ ) 121 : { 122 0 : layout_visible_classifier_t *const probe_classifier = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, index ); 123 0 : const bool is_descendant = layout_visible_set_is_ancestor ( (*this_).layout_data, ancestor_classifier, probe_classifier ); 124 0 : const bool is_self 125 0 : = ( layout_visible_classifier_get_classifier_id( ancestor_classifier ) 126 0 : == layout_visible_classifier_get_classifier_id( probe_classifier ) ); 127 0 : if ( is_descendant && ( ! is_self ) ) 128 : { 129 : /* trace */ 130 0 : U8_TRACE_INFO_INT_INT( "classifier moved:", 131 : geometry_offset_get_dx( offset ), 132 : geometry_offset_get_dy( offset ) 133 : ); 134 : 135 0 : layout_visible_classifier_shift( probe_classifier, offset ); 136 : } 137 : } 138 0 : U8_TRACE_END(); 139 0 : } 140 : 141 : 142 : /* 143 : Copyright 2018-2025 Andreas Warnke 144 : 145 : Licensed under the Apache License, Version 2.0 (the "License"); 146 : you may not use this file except in compliance with the License. 147 : You may obtain a copy of the License at 148 : 149 : http://www.apache.org/licenses/LICENSE-2.0 150 : 151 : Unless required by applicable law or agreed to in writing, software 152 : distributed under the License is distributed on an "AS IS" BASIS, 153 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154 : See the License for the specific language governing permissions and 155 : limitations under the License. 156 : */