Line data Source code
1 : /* File: layout_visible_set.c; Copyright and License: see below */
2 :
3 : #include "layout/layout_visible_set.h"
4 : #include "filter/pencil_rules.h"
5 : #include "u8/u8_trace.h"
6 : #include "u8/u8_log.h"
7 : #include <assert.h>
8 :
9 5 : void layout_visible_set_init( layout_visible_set_t *this_, const data_visible_set_t *input_data )
10 : {
11 5 : U8_TRACE_BEGIN();
12 5 : assert ( NULL != input_data );
13 5 : U8_TRACE_INFO_INT( "sizeof(layout_visible_set_t):", sizeof(layout_visible_set_t) );
14 :
15 5 : data_rules_init ( &((*this_).filter_rules) );
16 :
17 : /* init input data */
18 5 : (*this_).input_data = input_data;
19 :
20 : /* initialite the layout data objects */
21 5 : layout_visible_set_private_init_diagram( this_ );
22 5 : layout_visible_set_private_init_classifiers( this_ );
23 5 : layout_visible_set_private_init_features( this_ );
24 5 : layout_visible_set_private_init_relationships( this_ );
25 :
26 5 : if ( data_visible_set_is_valid( input_data ) )
27 : {
28 4 : assert ( layout_visible_set_is_consistent( this_ ) );
29 : }
30 5 : U8_TRACE_END();
31 5 : }
32 :
33 5 : void layout_visible_set_private_init_diagram( layout_visible_set_t *this_ )
34 : {
35 5 : U8_TRACE_BEGIN();
36 5 : assert ( NULL != (*this_).input_data );
37 :
38 5 : layout_diagram_init ( &((*this_).diagram_layout),
39 : data_visible_set_get_diagram_const( (*this_).input_data )
40 : );
41 5 : (*this_).diagram_valid = layout_diagram_is_valid( &((*this_).diagram_layout) );
42 :
43 5 : U8_TRACE_INFO_INT ( "diagram data objects:", 1 );
44 5 : U8_TRACE_INFO_INT ( "diagram ignored objects:", 0 ); /* we do not ignore diagram objects */
45 5 : U8_TRACE_INFO_INT ( "layout_diagram objects:", 1 );
46 :
47 5 : U8_TRACE_END();
48 5 : }
49 :
50 5 : void layout_visible_set_private_init_classifiers( layout_visible_set_t *this_ )
51 : {
52 5 : U8_TRACE_BEGIN();
53 5 : assert ( NULL != (*this_).input_data );
54 :
55 5 : const uint_fast32_t data_classifier_count = data_visible_set_get_visible_classifier_count( (*this_).input_data );
56 5 : (*this_).visible_classifier_count = 0;
57 5 : assert ( data_classifier_count <= LAYOUT_VISIBLE_SET_MAX_CLASSIFIERS );
58 :
59 153 : for ( uint_fast32_t c_idx = 0; c_idx < data_classifier_count; c_idx ++ )
60 : {
61 : const data_visible_classifier_t *const classifier_data
62 148 : = data_visible_set_get_visible_classifier_const( (*this_).input_data, c_idx );
63 :
64 148 : if ( ( NULL != classifier_data ) && data_visible_classifier_is_valid( classifier_data ) )
65 : {
66 148 : layout_visible_classifier_init( &((*this_).visible_classifier_layout[(*this_).visible_classifier_count]),
67 : classifier_data
68 : );
69 148 : (*this_).visible_classifier_count ++;
70 : }
71 : else
72 : {
73 0 : U8_LOG_ERROR("error in input_data: illegal classifier.");
74 0 : assert(false);
75 : }
76 : } /* end for all classifier_data */
77 :
78 5 : U8_TRACE_INFO_INT ( "classifier data objects:", data_classifier_count );
79 5 : U8_TRACE_INFO_INT ( "classifier ignored objects:", data_classifier_count - (*this_).visible_classifier_count );
80 5 : U8_TRACE_INFO_INT ( "layout_v._classifier objects:", (*this_).visible_classifier_count );
81 :
82 5 : U8_TRACE_END();
83 5 : }
84 :
85 5 : void layout_visible_set_private_init_features( layout_visible_set_t *this_ )
86 : {
87 5 : U8_TRACE_BEGIN();
88 5 : assert ( NULL != (*this_).input_data );
89 :
90 5 : const uint_fast32_t data_feature_count = data_visible_set_get_feature_count( (*this_).input_data );
91 : uint_fast32_t debug_dropped_features;
92 5 : debug_dropped_features = 0;
93 : uint_fast32_t warn_dropped_features;
94 5 : warn_dropped_features = 0;
95 5 : (*this_).feature_count = 0;
96 :
97 306 : for ( uint_fast32_t f_idx = 0; f_idx < data_feature_count; f_idx ++ )
98 : {
99 : const data_feature_t *const feature_data
100 301 : = data_visible_set_get_feature_const( (*this_).input_data, f_idx );
101 301 : uint_fast32_t layout_feature_count = 0;
102 :
103 301 : if ( ( NULL != feature_data ) && data_feature_is_valid( feature_data ) )
104 301 : {
105 301 : const data_row_t feature_id = data_feature_get_row_id( feature_data );
106 301 : const bool show = data_rules_diagram_shows_feature ( &((*this_).filter_rules),
107 : (*this_).input_data,
108 : feature_id
109 : );
110 :
111 301 : if ( show )
112 : {
113 33528 : for ( uint_fast32_t c_idx2 = 0; c_idx2 < (*this_).visible_classifier_count; c_idx2 ++ )
114 : {
115 33238 : layout_visible_classifier_t *const parent_classifier
116 : = &((*this_).visible_classifier_layout[c_idx2]);
117 :
118 33238 : const bool one_parent_found = data_rules_vis_classifier_has_feature ( &((*this_).filter_rules),
119 : layout_visible_classifier_get_data_const( parent_classifier ),
120 : feature_data );
121 33238 : if ( one_parent_found )
122 : {
123 580 : if ( (*this_).feature_count < LAYOUT_VISIBLE_SET_MAX_FEATURES )
124 : {
125 356 : layout_feature_init( &((*this_).feature_layout[(*this_).feature_count]),
126 : feature_data,
127 : parent_classifier
128 : );
129 356 : (*this_).feature_count ++;
130 356 : layout_feature_count ++;
131 : }
132 : else
133 : {
134 224 : warn_dropped_features ++;
135 : }
136 : } /* one_parent_found */
137 : } /* end search-for parent_classifier */
138 : }
139 : }
140 : else
141 : {
142 0 : U8_LOG_ERROR("error in input_data: illegal feature.");
143 0 : assert(false);
144 : }
145 :
146 301 : if ( layout_feature_count == 0 )
147 : {
148 : /* no warning here, dropping features - e.g. lifelines for other diagrams - is ok */
149 123 : debug_dropped_features ++;
150 : }
151 : } /* end for all feature_data */
152 :
153 5 : U8_TRACE_INFO_INT ( "feature data objects:", data_feature_count );
154 5 : U8_TRACE_INFO_INT ( "feature ignored objects:", debug_dropped_features );
155 5 : U8_TRACE_INFO_INT ( "layout_feature objects:", (*this_).feature_count );
156 5 : if ( 0 != warn_dropped_features )
157 : {
158 1 : U8_LOG_WARNING_INT( "LAYOUT_VISIBLE_SET_MAX_FEATURES exceeded, layout_features not visible:", warn_dropped_features );
159 : }
160 :
161 5 : U8_TRACE_END();
162 5 : }
163 :
164 5 : void layout_visible_set_private_init_relationships( layout_visible_set_t *this_ )
165 : {
166 5 : U8_TRACE_BEGIN();
167 5 : assert ( NULL != (*this_).input_data );
168 :
169 5 : const uint32_t data_relationship_count = data_visible_set_get_relationship_count( (*this_).input_data );
170 : uint32_t debug_dropped_relationships;
171 5 : debug_dropped_relationships = 0;
172 : uint32_t warn_dropped_relationships;
173 5 : warn_dropped_relationships = 0;
174 5 : (*this_).relationship_count = 0;
175 :
176 424 : for ( uint32_t r_idx = 0; r_idx < data_relationship_count; r_idx ++ )
177 : {
178 : const data_relationship_t *relationship_data;
179 419 : relationship_data = data_visible_set_get_relationship_const( (*this_).input_data, r_idx );
180 :
181 419 : uint32_t layout_relationship_count = 0;
182 419 : if ( ( NULL != relationship_data ) && data_relationship_is_valid( relationship_data ) )
183 419 : {
184 419 : const bool show = data_rules_diagram_shows_relationship ( &((*this_).filter_rules),
185 : (*this_).input_data,
186 : data_relationship_get_row_id( relationship_data )
187 : );
188 :
189 419 : if ( show )
190 : {
191 407 : layout_relationship_count = layout_visible_set_private_init_relationship( this_,
192 : relationship_data,
193 : &warn_dropped_relationships
194 : );
195 : }
196 : }
197 : else
198 : {
199 0 : U8_LOG_ERROR("error in input_data: illegal relationship.");
200 0 : assert(false);
201 : }
202 :
203 419 : if ( layout_relationship_count == 0 )
204 : {
205 : /* no warning here, dropping relationships - e.g. only one end-object visible in current diagram - is ok */
206 205 : debug_dropped_relationships ++;
207 : }
208 : } /* end for all relationship_data */
209 :
210 5 : U8_TRACE_INFO_INT ( "relationship data objects:", data_relationship_count );
211 5 : U8_TRACE_INFO_INT ( "relationship ignored objects:", debug_dropped_relationships );
212 5 : U8_TRACE_INFO_INT ( "layout_relationship objects:", (*this_).relationship_count );
213 5 : if ( 0 != warn_dropped_relationships )
214 : {
215 1 : U8_LOG_WARNING_INT( "LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS exceeded, layout_relationships not visible:", warn_dropped_relationships );
216 : }
217 :
218 5 : U8_TRACE_END();
219 5 : }
220 :
221 407 : uint32_t layout_visible_set_private_init_relationship( layout_visible_set_t *this_,
222 : const data_relationship_t *relationship_data,
223 : uint32_t *io_dropped_relationships )
224 : {
225 407 : U8_TRACE_BEGIN();
226 407 : assert ( NULL != (*this_).input_data );
227 407 : assert ( NULL != relationship_data );
228 407 : assert ( NULL != io_dropped_relationships );
229 407 : uint32_t layout_relationship_count = 0;
230 :
231 407 : const data_row_t from_classifier_id = data_relationship_get_from_classifier_row_id( relationship_data );
232 407 : const data_row_t to_classifier_id = data_relationship_get_to_classifier_row_id( relationship_data );
233 407 : const data_row_t from_feature_id = data_relationship_get_from_feature_row_id( relationship_data );
234 407 : const data_row_t to_feature_id = data_relationship_get_to_feature_row_id( relationship_data );
235 :
236 407 : if ( DATA_ROW_VOID == from_feature_id ) /* search source(from) in classifiers */
237 : {
238 49852 : for ( uint32_t c_idx3 = 0; c_idx3 < (*this_).visible_classifier_count; c_idx3 ++ )
239 : {
240 49447 : layout_visible_classifier_t *const probe3_classifier
241 : = &((*this_).visible_classifier_layout[c_idx3]);
242 :
243 49447 : const bool one_from_classifier_found = ( from_classifier_id == layout_visible_classifier_get_classifier_id( probe3_classifier ) );
244 49447 : if ( one_from_classifier_found )
245 : {
246 810 : if ( DATA_ROW_VOID == to_feature_id ) /* search destination(to) in classifiers */
247 : {
248 99704 : for ( uint32_t c_idx4 = 0; c_idx4 < (*this_).visible_classifier_count; c_idx4 ++ )
249 : {
250 : layout_visible_classifier_t *probe4_classifier;
251 98894 : probe4_classifier = &((*this_).visible_classifier_layout[c_idx4]);
252 :
253 98894 : const bool one_to_classifier_found = ( to_classifier_id == layout_visible_classifier_get_classifier_id( probe4_classifier ) );
254 98894 : if ( one_to_classifier_found )
255 : {
256 1620 : if ( (*this_).relationship_count < LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS )
257 : {
258 852 : layout_relationship_init( &((*this_).relationship_layout[(*this_).relationship_count]),
259 : relationship_data,
260 : probe3_classifier,
261 : probe4_classifier,
262 : NULL,
263 : NULL
264 : );
265 852 : (*this_).relationship_count ++;
266 852 : layout_relationship_count ++;
267 : }
268 : else
269 : {
270 768 : (*io_dropped_relationships) ++;
271 : }
272 : } /* one_to_classifier_found */
273 : } /* end search-for to_classifier */
274 : }
275 : else /* search destination(to) in features */
276 : {
277 0 : for ( uint32_t f_idx4 = 0; f_idx4 < (*this_).feature_count; f_idx4 ++ )
278 : {
279 0 : layout_feature_t *const probe4_feature = &((*this_).feature_layout[f_idx4]);
280 :
281 0 : const bool one_to_feature_found = ( to_feature_id == layout_feature_get_feature_id( probe4_feature ) );
282 0 : if ( one_to_feature_found )
283 : {
284 0 : const bool to_feature_ok
285 0 : = ( to_classifier_id == data_feature_get_classifier_row_id(layout_feature_get_data_const( probe4_feature )) );
286 0 : if ( to_feature_ok )
287 : {
288 0 : if ( (*this_).relationship_count < LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS )
289 : {
290 0 : layout_relationship_init( &((*this_).relationship_layout[(*this_).relationship_count]),
291 : relationship_data,
292 : probe3_classifier,
293 : layout_feature_get_classifier_ptr( probe4_feature ),
294 : NULL,
295 : probe4_feature
296 : );
297 0 : (*this_).relationship_count ++;
298 0 : layout_relationship_count ++;
299 : }
300 : else
301 : {
302 0 : (*io_dropped_relationships) ++;
303 : }
304 : }
305 : else
306 : {
307 0 : U8_LOG_ERROR("error in input_data: relationship links to feature and inconsistent classifier.");
308 : }
309 : } /* one_to_feature_found */
310 : } /* end search-for to_feature */
311 : }
312 : } /* one_from_classifier_found */
313 : } /* end search-for from_classifier */
314 : }
315 : else /* search source(from) in features */
316 : {
317 70 : for ( uint32_t f_idx3 = 0; f_idx3 < (*this_).feature_count; f_idx3 ++ )
318 : {
319 : layout_feature_t *probe3_feature;
320 68 : probe3_feature = &((*this_).feature_layout[f_idx3]);
321 :
322 68 : const bool one_from_feature_found = ( from_feature_id == layout_feature_get_feature_id( probe3_feature ) );
323 68 : if ( one_from_feature_found )
324 : {
325 4 : const bool from_feature_ok = ( from_classifier_id == data_feature_get_classifier_row_id(layout_feature_get_data_const( probe3_feature )) );
326 4 : if ( from_feature_ok )
327 : {
328 2 : if ( DATA_ROW_VOID == to_feature_id ) /* search destination(to) in classifiers */
329 : {
330 0 : for ( uint32_t c_idx5 = 0; c_idx5 < (*this_).visible_classifier_count; c_idx5 ++ )
331 : {
332 0 : layout_visible_classifier_t *const probe5_classifier
333 : = &((*this_).visible_classifier_layout[c_idx5]);
334 :
335 0 : const bool one_to_classifier_found
336 0 : = ( to_classifier_id == layout_visible_classifier_get_classifier_id( probe5_classifier ) );
337 0 : if ( one_to_classifier_found )
338 : {
339 0 : if ( (*this_).relationship_count < LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS )
340 : {
341 0 : layout_relationship_init( &((*this_).relationship_layout[(*this_).relationship_count]),
342 : relationship_data,
343 : layout_feature_get_classifier_ptr( probe3_feature ),
344 : probe5_classifier,
345 : probe3_feature,
346 : NULL
347 : );
348 0 : (*this_).relationship_count ++;
349 0 : layout_relationship_count ++;
350 : }
351 : else
352 : {
353 0 : (*io_dropped_relationships) ++;
354 : }
355 : } /* one_to_classifier_found */
356 : } /* end search-for to_classifier */
357 : }
358 : else /* search destination(to) in features */
359 : {
360 122 : for ( uint32_t f_idx5 = 0; f_idx5 < (*this_).feature_count; f_idx5 ++ )
361 : {
362 120 : layout_feature_t *const probe5_feature
363 : = &((*this_).feature_layout[f_idx5]);
364 :
365 120 : const bool one_to_feature_found = ( to_feature_id == layout_feature_get_feature_id( probe5_feature ) );
366 120 : if ( one_to_feature_found )
367 : {
368 4 : const bool to_feature_ok = ( to_classifier_id == data_feature_get_classifier_row_id(layout_feature_get_data_const( probe5_feature )) );
369 4 : if ( to_feature_ok )
370 : {
371 4 : if ( (*this_).relationship_count < LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS )
372 : {
373 4 : layout_relationship_init( &((*this_).relationship_layout[(*this_).relationship_count]),
374 : relationship_data,
375 : layout_feature_get_classifier_ptr( probe3_feature ),
376 : layout_feature_get_classifier_ptr( probe5_feature ),
377 : probe3_feature,
378 : probe5_feature
379 : );
380 4 : (*this_).relationship_count ++;
381 4 : layout_relationship_count ++;
382 : }
383 : else
384 : {
385 0 : (*io_dropped_relationships) ++;
386 : }
387 : }
388 : else
389 : {
390 0 : U8_LOG_ERROR("error in input_data: relationship links to feature and inconsistent classifier.");
391 : }
392 : } /* one_to_feature_found */
393 : } /* end search-for to_feature */
394 : }
395 : }
396 : else
397 : {
398 2 : U8_LOG_ERROR("error in input_data: relationship links from feature and inconsistent classifier.");
399 : }
400 : } /* one_from_feature_found */
401 : } /* end search-for from_feature */
402 : } /* endif: search source(from) */
403 :
404 407 : U8_TRACE_END();
405 407 : return layout_relationship_count;
406 : }
407 :
408 5 : void layout_visible_set_destroy( layout_visible_set_t *this_ )
409 : {
410 5 : U8_TRACE_BEGIN();
411 5 : assert( (*this_).visible_classifier_count <= LAYOUT_VISIBLE_SET_MAX_CLASSIFIERS );
412 5 : assert( (*this_).feature_count <= LAYOUT_VISIBLE_SET_MAX_FEATURES );
413 5 : assert( (*this_).relationship_count <= LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS );
414 :
415 5 : data_rules_destroy ( &((*this_).filter_rules) );
416 :
417 5 : if ( (*this_).diagram_valid )
418 : {
419 4 : layout_diagram_destroy ( &((*this_).diagram_layout) );
420 : }
421 :
422 153 : for ( uint_fast32_t c_idx = 0; c_idx < (*this_).visible_classifier_count; c_idx ++ )
423 : {
424 148 : layout_visible_classifier_destroy( &((*this_).visible_classifier_layout[c_idx]) );
425 : }
426 :
427 361 : for ( uint_fast32_t f_idx = 0; f_idx < (*this_).feature_count; f_idx ++ )
428 : {
429 356 : layout_feature_destroy( &((*this_).feature_layout[f_idx]) );
430 : }
431 :
432 861 : for ( uint_fast32_t r_idx = 0; r_idx < (*this_).relationship_count; r_idx ++ )
433 : {
434 856 : layout_relationship_destroy( &((*this_).relationship_layout[r_idx]) );
435 : }
436 :
437 5 : U8_TRACE_END();
438 5 : }
439 :
440 : /* ================================ misc ================================ */
441 :
442 9 : bool layout_visible_set_is_consistent ( const layout_visible_set_t *this_ )
443 : {
444 9 : bool result = true;
445 :
446 : /* check input data */
447 9 : if ( NULL == (*this_).input_data )
448 : {
449 0 : result = false;
450 : }
451 : else
452 : {
453 9 : if ( ! data_visible_set_is_valid( (*this_).input_data ) )
454 : {
455 1 : result = false;
456 : }
457 : }
458 :
459 : /* check diagram */
460 9 : if ( ! (*this_).diagram_valid )
461 : {
462 1 : result = false;
463 : }
464 : else
465 : {
466 8 : if ( ! layout_diagram_is_valid( &((*this_).diagram_layout) ) )
467 : {
468 0 : result = false;
469 : }
470 : }
471 :
472 : /* check classifiers */
473 9 : if ( (*this_).visible_classifier_count > LAYOUT_VISIBLE_SET_MAX_CLASSIFIERS )
474 : {
475 : /* if the object is already initialized, this is a severe error */
476 0 : result = false;
477 : }
478 : else
479 : {
480 305 : for ( uint_fast32_t c_idx = 0; c_idx < (*this_).visible_classifier_count; c_idx ++ )
481 : {
482 296 : const layout_visible_classifier_t *current = &((*this_).visible_classifier_layout[c_idx]);
483 296 : if ( ! layout_visible_classifier_is_valid( current ) )
484 : {
485 0 : result = false;
486 : }
487 : }
488 : }
489 :
490 : /* check features */
491 9 : if ( (*this_).feature_count > LAYOUT_VISIBLE_SET_MAX_FEATURES )
492 : {
493 : /* if the object is already initialized, this is a severe error */
494 0 : result = false;
495 : }
496 : else
497 : {
498 721 : for ( uint_fast32_t f_idx = 0; f_idx < (*this_).feature_count; f_idx ++ )
499 : {
500 712 : const layout_feature_t *current = &((*this_).feature_layout[f_idx]);
501 712 : if ( ! layout_feature_is_valid( current ) )
502 : {
503 0 : result = false;
504 : }
505 : }
506 : }
507 :
508 : /* check relationships */
509 9 : if ( (*this_).relationship_count > LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS )
510 : {
511 : /* if the object is already initialized, this is a severe error */
512 0 : result = false;
513 : }
514 : else
515 : {
516 1721 : for ( uint_fast32_t r_idx = 0; r_idx < (*this_).relationship_count; r_idx ++ )
517 : {
518 1712 : const layout_relationship_t *current = &((*this_).relationship_layout[r_idx]);
519 1712 : if ( ! layout_relationship_is_valid( current ) )
520 : {
521 0 : result = false;
522 : }
523 : }
524 : }
525 :
526 9 : return result;
527 : }
528 :
529 0 : void layout_visible_set_get_statistics ( const layout_visible_set_t *this_, data_stat_t *io_layout_stat )
530 : {
531 0 : U8_TRACE_BEGIN();
532 0 : assert( (*this_).visible_classifier_count <= LAYOUT_VISIBLE_SET_MAX_CLASSIFIERS );
533 0 : assert( (*this_).feature_count <= LAYOUT_VISIBLE_SET_MAX_FEATURES );
534 0 : assert( (*this_).relationship_count <= LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS );
535 0 : assert( io_layout_stat != NULL );
536 : pencil_rules_t pencil_rules;
537 0 : pencil_rules_init( &pencil_rules );
538 :
539 : /* check if diagram is valid */
540 0 : if ( (*this_).diagram_valid )
541 : {
542 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_EXPORTED );
543 :
544 0 : const geometry_rectangle_t *const diag_bounds = layout_diagram_get_bounds_const( &((*this_).diagram_layout) );
545 0 : const geometry_rectangle_t *const diag_space = layout_diagram_get_draw_area_const( &((*this_).diagram_layout) );
546 : /* ignore the label_box, it is irrelevant for determining overlaps with classifiers, features and relationships */
547 :
548 : /* check classifiers against diagram */
549 0 : for ( uint_fast32_t c_idx = 0; c_idx < (*this_).visible_classifier_count; c_idx ++ )
550 : {
551 0 : const layout_visible_classifier_t *const classifier = &((*this_).visible_classifier_layout[c_idx]);
552 :
553 0 : const geometry_rectangle_t *const c_symbox = layout_visible_classifier_get_symbol_box_const( classifier );
554 0 : const geometry_rectangle_t *const c_label = layout_visible_classifier_get_label_box_const( classifier );
555 : /* ignore the space, it is irrelevant for determining overlaps with the diagram border */
556 : /* ignore the icon_box, it is irrelevant for determining overlaps with the diagram border */
557 :
558 0 : if ( geometry_rectangle_is_containing( diag_space, c_symbox )
559 0 : && geometry_rectangle_is_containing( diag_space, c_label ) )
560 : {
561 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_EXPORTED );
562 : }
563 0 : else if ( geometry_rectangle_is_containing( diag_bounds, c_symbox )
564 0 : && geometry_rectangle_is_containing( diag_bounds, c_label ) )
565 : {
566 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_EXPORTED );
567 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_WARNING );
568 : }
569 : else
570 : {
571 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_ERROR );
572 : }
573 : }
574 :
575 : /* check features against diagram */
576 0 : for ( uint_fast32_t f_idx = 0; f_idx < (*this_).feature_count; f_idx ++ )
577 : {
578 0 : const layout_feature_t *const feature = &((*this_).feature_layout[f_idx]);
579 0 : const data_feature_t *const feature_data = layout_feature_get_data_const( feature );
580 0 : const data_feature_type_t feature_type = data_feature_get_main_type( feature_data );
581 0 : const data_row_t feature_id = layout_feature_get_feature_id( feature );
582 : const bool feature_visible
583 0 : = data_rules_diagram_shows_feature( &((*this_).filter_rules),
584 0 : (*this_).input_data,
585 : feature_id
586 : );
587 0 : const data_stat_table_t feat_or_lifeline
588 0 : = ( feature_type == DATA_FEATURE_TYPE_LIFELINE ) ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE;
589 :
590 0 : const geometry_rectangle_t *const f_symbox = layout_feature_get_symbol_box_const( feature );
591 0 : const geometry_rectangle_t *const f_label = layout_feature_get_label_box_const( feature );
592 :
593 0 : if ( ! feature_visible )
594 : {
595 : /* nothing to do, feature is not visible in this diagram */
596 : }
597 0 : else if ( ( geometry_rectangle_is_empty( f_symbox )
598 0 : || geometry_rectangle_is_containing( diag_space, f_symbox ) )
599 0 : && geometry_rectangle_is_containing( diag_space, f_label ) )
600 : {
601 0 : data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_EXPORTED );
602 : }
603 0 : else if ( geometry_rectangle_is_containing( diag_bounds, f_symbox )
604 0 : && geometry_rectangle_is_containing( diag_bounds, f_label ) )
605 : {
606 0 : data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_EXPORTED );
607 0 : data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_WARNING );
608 : }
609 : else
610 : {
611 0 : data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_ERROR );
612 : }
613 : }
614 :
615 : /* check relationships against diagram */
616 0 : for ( uint_fast32_t r_idx = 0; r_idx < (*this_).relationship_count; r_idx ++ )
617 : {
618 0 : const layout_relationship_t *const relationship = &((*this_).relationship_layout[r_idx]);
619 0 : const data_row_t relationship_id = layout_relationship_get_relationship_id( relationship );
620 : const bool relationship_visible
621 0 : = data_rules_diagram_shows_relationship( &((*this_).filter_rules),
622 0 : (*this_).input_data,
623 : relationship_id
624 : );
625 0 : const geometry_rectangle_t *const rel_label = layout_relationship_get_label_box_const( relationship );
626 0 : const geometry_connector_t *const rel_shape = layout_relationship_get_shape_const( relationship );
627 0 : const geometry_rectangle_t rel_bounds = geometry_connector_get_bounding_rectangle( rel_shape );
628 :
629 0 : if ( ! relationship_visible )
630 : {
631 : /* nothing to do, relationship is not visible in this diagram */
632 : }
633 0 : else if ( geometry_rectangle_is_containing( diag_space, &rel_bounds )
634 0 : && geometry_rectangle_is_containing( diag_space, rel_label ) )
635 : {
636 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_EXPORTED );
637 : }
638 0 : else if ( geometry_rectangle_is_containing( diag_bounds, &rel_bounds )
639 0 : && geometry_rectangle_is_containing( diag_bounds, rel_label ) )
640 : {
641 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_EXPORTED );
642 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_WARNING );
643 : }
644 : else
645 : {
646 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_ERROR );
647 : }
648 : }
649 : }
650 : else
651 : {
652 0 : data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_ERROR );
653 : }
654 :
655 0 : pencil_rules_destroy( &pencil_rules );
656 0 : U8_TRACE_END();
657 0 : }
658 :
659 :
660 : /*
661 : Copyright 2017-2025 Andreas Warnke
662 :
663 : Licensed under the Apache License, Version 2.0 (the "License");
664 : you may not use this file except in compliance with the License.
665 : You may obtain a copy of the License at
666 :
667 : http://www.apache.org/licenses/LICENSE-2.0
668 :
669 : Unless required by applicable law or agreed to in writing, software
670 : distributed under the License is distributed on an "AS IS" BASIS,
671 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
672 : See the License for the specific language governing permissions and
673 : limitations under the License.
674 : */
|