Line data Source code
1 : /* File: geometry_compartments.inl; Copyright and License: see below */
2 :
3 : #include "u8/u8_trace.h"
4 : #include "u8/u8_log.h"
5 : #include "u8/u8_f64.h"
6 : #include <assert.h>
7 : #include <math.h>
8 :
9 10 : static inline void geometry_compartments_init( geometry_compartments_t *this_,
10 : double standard_object_border,
11 : double preferred_object_distance )
12 : {
13 10 : geometry_dimensions_init( &((*this_).feature_compartments), 0.0, 0.0 );
14 10 : (*this_).has_properties = false;
15 10 : (*this_).has_operations = false;
16 10 : (*this_).has_tagged_values = false;
17 10 : (*this_).port_height_on_left = 0.0;
18 10 : (*this_).port_height_on_right = 0.0;
19 10 : (*this_).port_width_on_top = 0.0;
20 10 : (*this_).port_width_on_bottom = 0.0;
21 10 : (*this_).iface_height_on_left = 0.0;
22 10 : (*this_).iface_height_on_right = 0.0;
23 10 : (*this_).iface_width_on_top = 0.0;
24 10 : (*this_).iface_width_on_bottom = 0.0;
25 10 : (*this_).standard_object_border = standard_object_border;
26 10 : (*this_).preferred_object_distance = preferred_object_distance;
27 10 : }
28 :
29 3 : static inline void geometry_compartments_reinit( geometry_compartments_t *this_,
30 : double standard_object_border,
31 : double preferred_object_distance )
32 : {
33 3 : geometry_dimensions_destroy( &((*this_).feature_compartments) );
34 3 : geometry_compartments_init( this_, standard_object_border, preferred_object_distance );
35 3 : }
36 :
37 1 : static inline void geometry_compartments_copy ( geometry_compartments_t *this_, const geometry_compartments_t *original )
38 : {
39 1 : *this_ = *original;
40 1 : geometry_dimensions_copy( &((*this_).feature_compartments), &((*original).feature_compartments) );
41 1 : }
42 :
43 1 : static inline void geometry_compartments_move ( geometry_compartments_t *this_, geometry_compartments_t *that )
44 : {
45 1 : *this_ = *that;
46 1 : geometry_dimensions_copy( &((*this_).feature_compartments), &((*that).feature_compartments) );
47 1 : geometry_compartments_destroy( that );
48 1 : }
49 :
50 1 : static inline void geometry_compartments_replace ( geometry_compartments_t *this_, const geometry_compartments_t *original )
51 : {
52 1 : geometry_dimensions_destroy( &((*this_).feature_compartments) );
53 1 : *this_ = *original;
54 1 : geometry_dimensions_copy( &((*this_).feature_compartments), &((*original).feature_compartments) );
55 1 : }
56 :
57 1 : static inline void geometry_compartments_replacemove ( geometry_compartments_t *this_, geometry_compartments_t *that )
58 : {
59 1 : geometry_dimensions_destroy( &((*this_).feature_compartments) );
60 1 : *this_ = *that;
61 1 : geometry_dimensions_copy( &((*this_).feature_compartments), &((*that).feature_compartments) );
62 1 : geometry_compartments_destroy( that );
63 1 : }
64 :
65 4 : static inline geometry_compartments_t geometry_compartments_new_empty()
66 : {
67 : geometry_compartments_t result;
68 4 : geometry_compartments_init( &result, 0.0, 0.0 );
69 4 : return result;
70 : }
71 :
72 1 : static inline geometry_compartments_t geometry_compartments_new( const geometry_dimensions_t *compartments,
73 : const geometry_dimensions_t *outer )
74 : {
75 : geometry_compartments_t result;
76 1 : geometry_compartments_init( &result, 0.0, 0.0 );
77 1 : geometry_dimensions_replace( &(result.feature_compartments), compartments );
78 1 : result.port_height_on_left = geometry_dimensions_get_height( outer );
79 1 : result.port_width_on_top = geometry_dimensions_get_width( outer );
80 1 : return result;
81 : }
82 :
83 5 : static inline void geometry_compartments_destroy( geometry_compartments_t *this_ )
84 : {
85 5 : geometry_dimensions_destroy( &((*this_).feature_compartments) );
86 5 : }
87 :
88 15 : static inline void geometry_compartments_add_feature( geometry_compartments_t *this_,
89 : geometry_compartment_type_t compartment,
90 : const geometry_dimensions_t * feature_dim )
91 : {
92 15 : const double gap = (*this_).preferred_object_distance;
93 15 : switch ( compartment )
94 : {
95 1 : case GEOMETRY_COMPARTMENT_TYPE_PROPERTIES:
96 : {
97 : /* update dimensions of feature_compartments */
98 1 : double f_width = geometry_dimensions_get_width( &((*this_).feature_compartments) );
99 1 : double f_height = geometry_dimensions_get_height( &((*this_).feature_compartments) );
100 1 : if ( ! ( (*this_).has_properties || (*this_).has_operations || (*this_).has_tagged_values ) )
101 : {
102 1 : f_height += 2.0 * (*this_).standard_object_border; /* gaps above and below the bottom compartment line */
103 : }
104 1 : if ( ! (*this_).has_properties )
105 : {
106 1 : (*this_).has_properties = true;
107 1 : f_height += 4.0 * (*this_).standard_object_border; /* gaps above and below the new top compartment line */
108 : /* 2.0 * gap is reserved for compartment label */
109 : }
110 :
111 1 : const double new_feat_width
112 1 : = geometry_dimensions_get_width( feature_dim ) + 2.0 * (*this_).standard_object_border;
113 1 : f_width = u8_f64_max2( f_width, new_feat_width );
114 1 : f_height += geometry_dimensions_get_height( feature_dim );
115 1 : geometry_dimensions_reinit( &((*this_).feature_compartments), f_width, f_height );
116 : }
117 1 : break;
118 :
119 1 : case GEOMETRY_COMPARTMENT_TYPE_OPERATIONS:
120 : {
121 : /* update dimensions of feature_compartments */
122 1 : double f_width = geometry_dimensions_get_width( &((*this_).feature_compartments) );
123 1 : double f_height = geometry_dimensions_get_height( &((*this_).feature_compartments) );
124 1 : if ( ! ( (*this_).has_properties || (*this_).has_operations || (*this_).has_tagged_values ) )
125 : {
126 1 : f_height += 2.0 * (*this_).standard_object_border; /* gaps above and below the bottom compartment line */
127 : }
128 1 : if ( ! (*this_).has_operations )
129 : {
130 1 : (*this_).has_operations = true;
131 1 : f_height += 4.0 * (*this_).standard_object_border; /* gaps above and below the new top compartment line */
132 : /* 2.0 * gap is reserved for compartment label */
133 : }
134 :
135 1 : const double new_feat_width
136 1 : = geometry_dimensions_get_width( feature_dim ) + 2.0 * (*this_).standard_object_border;
137 1 : f_width = u8_f64_max2( f_width, new_feat_width );
138 1 : f_height += geometry_dimensions_get_height( feature_dim );
139 1 : geometry_dimensions_reinit( &((*this_).feature_compartments), f_width, f_height );
140 : }
141 1 : break;
142 :
143 1 : case GEOMETRY_COMPARTMENT_TYPE_TAGGED_VALUES:
144 : {
145 : /* update dimensions of feature_compartments */
146 1 : double f_width = geometry_dimensions_get_width( &((*this_).feature_compartments) );
147 1 : double f_height = geometry_dimensions_get_height( &((*this_).feature_compartments) );
148 1 : if ( ! ( (*this_).has_properties || (*this_).has_operations || (*this_).has_tagged_values ) )
149 : {
150 1 : f_height += 2.0 * (*this_).standard_object_border; /* gaps above and below the bottom compartment line */
151 : }
152 1 : if ( ! (*this_).has_tagged_values )
153 : {
154 1 : (*this_).has_tagged_values = true;
155 1 : f_height += 4.0 * (*this_).standard_object_border; /* gaps above and below the new top compartment line */
156 : /* 2.0 * gap is reserved for compartment label */
157 : }
158 :
159 1 : const double new_feat_width
160 1 : = geometry_dimensions_get_width( feature_dim ) + 2.0 * (*this_).standard_object_border;
161 1 : f_width = u8_f64_max2( f_width, new_feat_width );
162 1 : f_height += geometry_dimensions_get_height( feature_dim );
163 1 : geometry_dimensions_reinit( &((*this_).feature_compartments), f_width, f_height );
164 : }
165 1 : break;
166 :
167 1 : case GEOMETRY_COMPARTMENT_TYPE_PORT_ON_LEFT:
168 : {
169 1 : (*this_).port_height_on_left += geometry_dimensions_get_height( feature_dim ) + gap;
170 : }
171 1 : break;
172 :
173 1 : case GEOMETRY_COMPARTMENT_TYPE_PORT_ON_RIGHT:
174 : {
175 1 : (*this_).port_height_on_right += geometry_dimensions_get_height( feature_dim ) + gap;
176 : }
177 1 : break;
178 :
179 1 : case GEOMETRY_COMPARTMENT_TYPE_PORT_ON_TOP:
180 : {
181 1 : (*this_).port_width_on_top += geometry_dimensions_get_width( feature_dim ) + gap;
182 : }
183 1 : break;
184 :
185 1 : case GEOMETRY_COMPARTMENT_TYPE_PORT_ON_BOTTOM:
186 : {
187 1 : (*this_).port_width_on_bottom += geometry_dimensions_get_width( feature_dim ) + gap;
188 : }
189 1 : break;
190 :
191 4 : case GEOMETRY_COMPARTMENT_TYPE_IF_ON_LEFT:
192 : {
193 4 : (*this_).iface_height_on_left += geometry_dimensions_get_height( feature_dim ) + gap;
194 : }
195 4 : break;
196 :
197 1 : case GEOMETRY_COMPARTMENT_TYPE_IF_ON_RIGHT:
198 : {
199 1 : (*this_).iface_height_on_right += geometry_dimensions_get_height( feature_dim ) + gap;
200 : }
201 1 : break;
202 :
203 1 : case GEOMETRY_COMPARTMENT_TYPE_IF_ON_TOP:
204 : {
205 1 : (*this_).iface_width_on_top += geometry_dimensions_get_width( feature_dim ) + gap;
206 : }
207 1 : break;
208 :
209 1 : case GEOMETRY_COMPARTMENT_TYPE_IF_ON_BOTTOM:
210 : {
211 1 : (*this_).iface_width_on_bottom += geometry_dimensions_get_width( feature_dim ) + gap;
212 : }
213 1 : break;
214 :
215 1 : default: /* or */
216 : case GEOMETRY_COMPARTMENT_TYPE_VOID:
217 : {
218 1 : assert( compartment == GEOMETRY_COMPARTMENT_TYPE_VOID );
219 : /* ignore */
220 : }
221 1 : break;
222 : }
223 15 : }
224 :
225 196 : static inline const geometry_dimensions_t * geometry_compartments_get_feature_compartments ( const geometry_compartments_t *this_ )
226 : {
227 196 : return &((*this_).feature_compartments);
228 : }
229 :
230 1 : static inline double geometry_compartments_get_port_height_on_left( const geometry_compartments_t *this_ )
231 : {
232 1 : return (*this_).port_height_on_left;
233 : }
234 :
235 1 : static inline double geometry_compartments_get_port_height_on_right( const geometry_compartments_t *this_ )
236 : {
237 1 : return (*this_).port_height_on_right;
238 : }
239 :
240 1 : static inline double geometry_compartments_get_port_width_on_top( const geometry_compartments_t *this_ )
241 : {
242 1 : return (*this_).port_width_on_top;
243 : }
244 :
245 1 : static inline double geometry_compartments_get_port_width_on_bottom( const geometry_compartments_t *this_ )
246 : {
247 1 : return (*this_).port_width_on_bottom;
248 : }
249 :
250 4 : static inline double geometry_compartments_get_if_height_on_left( const geometry_compartments_t *this_ )
251 : {
252 4 : return (*this_).iface_height_on_left;
253 : }
254 :
255 1 : static inline double geometry_compartments_get_if_height_on_right( const geometry_compartments_t *this_ )
256 : {
257 1 : return (*this_).iface_height_on_right;
258 : }
259 :
260 1 : static inline double geometry_compartments_get_if_width_on_top( const geometry_compartments_t *this_ )
261 : {
262 1 : return (*this_).iface_width_on_top;
263 : }
264 :
265 1 : static inline double geometry_compartments_get_if_width_on_bottom( const geometry_compartments_t *this_ )
266 : {
267 1 : return (*this_).iface_width_on_bottom;
268 : }
269 :
270 194 : static inline double geometry_compartments_get_outer_height ( const geometry_compartments_t *this_ )
271 : {
272 194 : const double iface_height = u8_f64_max2( (*this_).iface_height_on_left, (*this_).iface_height_on_right );
273 194 : const double port_height = u8_f64_max2( (*this_).port_height_on_left, (*this_).port_height_on_right );
274 194 : const double result = u8_f64_max2( iface_height, port_height );
275 194 : return result;
276 : }
277 :
278 194 : static inline double geometry_compartments_get_outer_width ( const geometry_compartments_t *this_ )
279 : {
280 194 : const double iface_width = u8_f64_max2( (*this_).iface_width_on_top, (*this_).iface_width_on_bottom );
281 194 : const double port_width = u8_f64_max2( (*this_).port_width_on_top, (*this_).port_width_on_bottom );
282 194 : const double result = u8_f64_max2( iface_width, port_width );
283 194 : return result;
284 : }
285 :
286 1 : static inline void geometry_compartments_trace( const geometry_compartments_t *this_ )
287 : {
288 1 : U8_TRACE_INFO( "geometry_compartments_t" );
289 1 : geometry_dimensions_trace( &((*this_).feature_compartments) );
290 1 : U8_TRACE_INFO_INT( "- port_height_on_left:", (*this_).port_height_on_left );
291 1 : U8_TRACE_INFO_INT( "- port_height_on_right:", (*this_).port_height_on_right );
292 1 : U8_TRACE_INFO_INT( "- port_width_on_top:", (*this_).port_width_on_top );
293 1 : U8_TRACE_INFO_INT( "- port_width_on_bottom:", (*this_).port_width_on_bottom );
294 1 : U8_TRACE_INFO_INT( "- iface_height_on_left:", (*this_).iface_height_on_left );
295 1 : U8_TRACE_INFO_INT( "- iface_height_on_right:", (*this_).iface_height_on_right );
296 1 : U8_TRACE_INFO_INT( "- iface_width_on_top:", (*this_).iface_width_on_top );
297 1 : U8_TRACE_INFO_INT( "- iface_width_on_bottom:", (*this_).iface_width_on_bottom );
298 1 : }
299 :
300 :
301 : /*
302 : * Copyright 2026-2026 Andreas Warnke
303 : *
304 : * Licensed under the Apache License, Version 2.0 (the "License");
305 : * you may not use this file except in compliance with the License.
306 : * You may obtain a copy of the License at
307 : *
308 : * http://www.apache.org/licenses/LICENSE-2.0
309 : *
310 : * Unless required by applicable law or agreed to in writing, software
311 : * distributed under the License is distributed on an "AS IS" BASIS,
312 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
313 : * See the License for the specific language governing permissions and
314 : * limitations under the License.
315 : */
|