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 : */
|