LCOV - code coverage report
Current view: top level - pencil/source - pencil_layout_data.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.57.0_covts Lines: 179 432 41.4 %
Date: 2024-04-07 11:14:42 Functions: 8 11 72.7 %

          Line data    Source code
       1             : /* File: pencil_layout_data.c; Copyright and License: see below */
       2             : 
       3             : #include "pencil_layout_data.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 pencil_layout_data_init( pencil_layout_data_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(pencil_layout_data_t):", sizeof(pencil_layout_data_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 :     pencil_layout_data_private_init_diagram( this_ );
      22           5 :     pencil_layout_data_private_init_classifiers( this_ );
      23           5 :     pencil_layout_data_private_init_features( this_ );
      24           5 :     pencil_layout_data_private_init_relationships( this_ );
      25             : 
      26           5 :     if ( data_visible_set_is_valid( input_data ) )
      27             :     {
      28           4 :         assert ( pencil_layout_data_is_valid( this_ ) );
      29             :     }
      30           5 :     U8_TRACE_END();
      31           5 : }
      32             : 
      33           5 : void pencil_layout_data_private_init_diagram( pencil_layout_data_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 pencil_layout_data_private_init_classifiers( pencil_layout_data_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 <= PENCIL_LAYOUT_DATA_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 pencil_layout_data_private_init_features( pencil_layout_data_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_id_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 < PENCIL_LAYOUT_DATA_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( "PENCIL_LAYOUT_DATA_MAX_FEATURES exceeded, layout_features not visible:", warn_dropped_features );
     159             :     }
     160             : 
     161           5 :     U8_TRACE_END();
     162           5 : }
     163             : 
     164           5 : void pencil_layout_data_private_init_relationships( pencil_layout_data_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        1064 :     for ( uint32_t r_idx = 0; r_idx < data_relationship_count; r_idx ++ )
     177             :     {
     178             :         const data_relationship_t *relationship_data;
     179        1059 :         relationship_data = data_visible_set_get_relationship_const( (*this_).input_data, r_idx );
     180             : 
     181        1059 :         uint32_t layout_relationship_count = 0;
     182        1059 :         if ( ( NULL != relationship_data ) && data_relationship_is_valid( relationship_data ) )
     183        1059 :         {
     184        1059 :             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        1059 :             if ( show )
     190             :             {
     191        1047 :                 layout_relationship_count = pencil_layout_data_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        1059 :         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         525 :             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( "PENCIL_LAYOUT_DATA_MAX_RELATIONSHIPS exceeded, layout_relationships not visible:", warn_dropped_relationships );
     216             :     }
     217             : 
     218           5 :     U8_TRACE_END();
     219           5 : }
     220             : 
     221        1047 : uint32_t pencil_layout_data_private_init_relationship( pencil_layout_data_t *this_,
     222             :                                                        const data_relationship_t *relationship_data,
     223             :                                                        uint32_t *io_dropped_relationships )
     224             : {
     225        1047 :     U8_TRACE_BEGIN();
     226        1047 :     assert ( NULL != (*this_).input_data );
     227        1047 :     assert ( NULL != relationship_data );
     228        1047 :     assert ( NULL != io_dropped_relationships );
     229        1047 :     uint32_t layout_relationship_count = 0;
     230             : 
     231        1047 :     const data_row_id_t from_classifier_id = data_relationship_get_from_classifier_row_id( relationship_data );
     232        1047 :     const data_row_id_t to_classifier_id = data_relationship_get_to_classifier_row_id( relationship_data );
     233        1047 :     const data_row_id_t from_feature_id = data_relationship_get_from_feature_row_id( relationship_data );
     234        1047 :     const data_row_id_t to_feature_id = data_relationship_get_to_feature_row_id( relationship_data );
     235             : 
     236        1047 :     if ( DATA_ROW_ID_VOID == from_feature_id )  /* search source(from) in classifiers */
     237             :     {
     238      132412 :         for ( uint32_t c_idx3 = 0; c_idx3 < (*this_).visible_classifier_count; c_idx3 ++ )
     239             :         {
     240      131367 :             layout_visible_classifier_t *const probe3_classifier
     241             :                 = &((*this_).visible_classifier_layout[c_idx3]);
     242             : 
     243      131367 :             const bool one_from_classifier_found = ( from_classifier_id == layout_visible_classifier_get_classifier_id( probe3_classifier ) );
     244      131367 :             if ( one_from_classifier_found )
     245             :             {
     246        2090 :                 if ( DATA_ROW_ID_VOID == to_feature_id )  /* search destination(to) in classifiers */
     247             :                 {
     248      264824 :                     for ( uint32_t c_idx4 = 0; c_idx4 < (*this_).visible_classifier_count; c_idx4 ++ )
     249             :                     {
     250             :                         layout_visible_classifier_t *probe4_classifier;
     251      262734 :                         probe4_classifier = &((*this_).visible_classifier_layout[c_idx4]);
     252             : 
     253      262734 :                         const bool one_to_classifier_found =  ( to_classifier_id == layout_visible_classifier_get_classifier_id( probe4_classifier ) );
     254      262734 :                         if ( one_to_classifier_found )
     255             :                         {
     256        4180 :                             if ( (*this_).relationship_count < PENCIL_LAYOUT_DATA_MAX_RELATIONSHIPS )
     257             :                             {
     258        2132 :                                 layout_relationship_init( &((*this_).relationship_layout[(*this_).relationship_count]),
     259             :                                                           relationship_data,
     260             :                                                           probe3_classifier,
     261             :                                                           probe4_classifier,
     262             :                                                           NULL,
     263             :                                                           NULL
     264             :                                                         );
     265        2132 :                                 (*this_).relationship_count ++;
     266        2132 :                                 layout_relationship_count ++;
     267             :                             }
     268             :                             else
     269             :                             {
     270        2048 :                                 (*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 < PENCIL_LAYOUT_DATA_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_ID_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 < PENCIL_LAYOUT_DATA_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 < PENCIL_LAYOUT_DATA_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        1047 :     U8_TRACE_END();
     405        1047 :     return layout_relationship_count;
     406             : }
     407             : 
     408           5 : void pencil_layout_data_destroy( pencil_layout_data_t *this_ )
     409             : {
     410           5 :     U8_TRACE_BEGIN();
     411           5 :     assert( (*this_).visible_classifier_count <= PENCIL_LAYOUT_DATA_MAX_CLASSIFIERS );
     412           5 :     assert( (*this_).feature_count <= PENCIL_LAYOUT_DATA_MAX_FEATURES );
     413           5 :     assert( (*this_).relationship_count <= PENCIL_LAYOUT_DATA_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        2141 :     for ( uint_fast32_t r_idx = 0; r_idx < (*this_).relationship_count; r_idx ++ )
     433             :     {
     434        2136 :         layout_relationship_destroy( &((*this_).relationship_layout[r_idx]) );
     435             :     }
     436             : 
     437           5 :     U8_TRACE_END();
     438           5 : }
     439             : 
     440             : /* ================================ misc ================================ */
     441             : 
     442           9 : bool pencil_layout_data_is_valid ( const pencil_layout_data_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 > PENCIL_LAYOUT_DATA_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 > PENCIL_LAYOUT_DATA_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 > PENCIL_LAYOUT_DATA_MAX_RELATIONSHIPS )
     510             :     {
     511             :         /* if the object is already initialized, this is a severe error */
     512           0 :         result = false;
     513             :     }
     514             :     else
     515             :     {
     516        4281 :         for ( uint_fast32_t r_idx = 0; r_idx < (*this_).relationship_count;  r_idx ++ )
     517             :         {
     518        4272 :             const layout_relationship_t *current = &((*this_).relationship_layout[r_idx]);
     519        4272 :             if ( ! layout_relationship_is_valid( current ) )
     520             :             {
     521           0 :                 result = false;
     522             :             }
     523             :         }
     524             :     }
     525             : 
     526           9 :     return result;
     527             : }
     528             : 
     529             : #ifndef NDEBUG
     530             : #define PENCIL_LAYOUT_DATA_STATS_WITH_WARNINGS
     531             : #else
     532             : /* REMOVE ME */
     533             : #define PENCIL_LAYOUT_DATA_STATS_WITH_WARNINGS
     534             : #endif
     535             : 
     536           0 : void pencil_layout_data_private_analyze_nothing_callback ( void *data,
     537             :                                                            const geometry_rectangle_t *rect_a,
     538             :                                                            const geometry_rectangle_t *rect_b )
     539             : {
     540           0 : }
     541             : 
     542           0 : void pencil_layout_data_get_statistics ( const pencil_layout_data_t *this_, data_stat_t *io_layout_stat )
     543             : {
     544           0 :     U8_TRACE_BEGIN();
     545           0 :     pencil_layout_data_analyze( this_, io_layout_stat, pencil_layout_data_private_analyze_nothing_callback, NULL );
     546           0 :     U8_TRACE_END();
     547           0 : }
     548             : 
     549           0 : void pencil_layout_data_analyze ( const pencil_layout_data_t *this_,
     550             :                                   data_stat_t *io_layout_stat,
     551             :                                   void (*overlap_callback)(void *data, const geometry_rectangle_t *a, const geometry_rectangle_t *b),
     552             :                                   void *data )
     553             : {
     554           0 :     U8_TRACE_BEGIN();
     555           0 :     assert( (*this_).visible_classifier_count <= PENCIL_LAYOUT_DATA_MAX_CLASSIFIERS );
     556           0 :     assert( (*this_).feature_count <= PENCIL_LAYOUT_DATA_MAX_FEATURES );
     557           0 :     assert( (*this_).relationship_count <= PENCIL_LAYOUT_DATA_MAX_RELATIONSHIPS );
     558           0 :     assert( io_layout_stat != NULL );
     559             :     pencil_rules_t pencil_rules;
     560           0 :     pencil_rules_init( &pencil_rules );
     561             : 
     562             :     /* check if diagram is valid */
     563             : 
     564           0 :     if ( (*this_).diagram_valid )
     565             :     {
     566           0 :         data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_EXPORTED );
     567             : 
     568           0 :         const data_diagram_t *const diag_data = layout_diagram_get_data_const ( &((*this_).diagram_layout) );
     569           0 :         const data_diagram_type_t diag_type = data_diagram_get_diagram_type ( diag_data );
     570           0 :         const geometry_rectangle_t *const diag_bounds = layout_diagram_get_bounds_const( &((*this_).diagram_layout) );
     571           0 :         const geometry_rectangle_t *const diag_space = layout_diagram_get_draw_area_const( &((*this_).diagram_layout) );
     572             : 
     573             :         /* check classifiers against diagram */
     574             : 
     575           0 :         for ( uint_fast32_t c_idx = 0; c_idx < (*this_).visible_classifier_count; c_idx ++ )
     576             :         {
     577           0 :             const layout_visible_classifier_t *const classifier = &((*this_).visible_classifier_layout[c_idx]);
     578             :             const geometry_rectangle_t *const c_symbox
     579           0 :                 = layout_visible_classifier_get_symbol_box_const( classifier );
     580             :             const geometry_rectangle_t *const c_label
     581           0 :                = layout_visible_classifier_get_label_box_const( classifier );
     582             : #ifdef PENCIL_LAYOUT_DATA_STATS_WITH_WARNINGS
     583             :             const geometry_rectangle_t *const c_space
     584           0 :                = layout_visible_classifier_get_space_const( classifier );
     585             : #endif
     586             : 
     587           0 :             if ( geometry_rectangle_is_containing( diag_space, c_symbox )
     588           0 :                 && geometry_rectangle_is_containing( diag_space, c_label ) )
     589             :             {
     590           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_EXPORTED );
     591             : 
     592             : #ifdef PENCIL_LAYOUT_DATA_STATS_WITH_WARNINGS
     593             :                 /* check current classifier against already processed classifiers */
     594             : 
     595           0 :                 for ( uint_fast32_t probe_idx = 0; probe_idx < c_idx; probe_idx ++ )
     596             :                 {
     597           0 :                     const layout_visible_classifier_t *const probe = &((*this_).visible_classifier_layout[probe_idx]);
     598             :                     const geometry_rectangle_t *const probe_symbox
     599           0 :                         = layout_visible_classifier_get_symbol_box_const( probe );
     600             :                     const geometry_rectangle_t *const probe_label
     601           0 :                         = layout_visible_classifier_get_label_box_const( probe );
     602             :                     const geometry_rectangle_t *const probe_space
     603           0 :                         = layout_visible_classifier_get_space_const( probe );
     604             : 
     605             :                     const bool symbox_overlaps
     606           0 :                         = geometry_rectangle_is_intersecting( c_symbox, probe_symbox );
     607           0 :                     const bool mixed_overlaps
     608           0 :                         = ( geometry_rectangle_is_intersecting( c_symbox, probe_label )
     609           0 :                         || geometry_rectangle_is_intersecting( c_label, probe_symbox ) );
     610             :                     const bool label_overlaps
     611           0 :                         = geometry_rectangle_is_intersecting( c_label, probe_label );
     612             : 
     613           0 :                     if ( symbox_overlaps || mixed_overlaps || label_overlaps )
     614             :                     {
     615             :                         const bool probe_is_ancestor
     616           0 :                             = pencil_layout_data_is_ancestor( this_,
     617             :                                                               probe,      /* ancestor */
     618             :                                                               classifier  /* descendant */
     619             :                                                             );
     620             :                         const bool probe_is_descendant
     621           0 :                             = pencil_layout_data_is_ancestor( this_,
     622             :                                                               classifier,  /* ancestor */
     623             :                                                               probe        /* descendant */
     624             :                                                             );
     625           0 :                         const bool probe_contains_c
     626           0 :                             = ( geometry_rectangle_is_containing( probe_space, c_symbox )
     627           0 :                             && geometry_rectangle_is_containing( probe_space, c_label ) );
     628           0 :                         const bool c_contains_probe
     629           0 :                             = ( geometry_rectangle_is_containing( c_space, probe_symbox )
     630           0 :                             && geometry_rectangle_is_containing( c_space, probe_label ) );
     631           0 :                         if ( probe_is_ancestor && probe_contains_c )
     632             :                         {
     633             :                             /* ok */
     634             :                         }
     635           0 :                         else if ( probe_is_descendant && c_contains_probe )
     636             :                         {
     637             :                             /* ok */
     638             :                         }
     639             :                         else
     640             :                         {
     641           0 :                             data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_WARNING );
     642           0 :                             (*overlap_callback)( data, probe_space, c_symbox );
     643           0 :                             (*overlap_callback)( data, probe_space, c_label );
     644           0 :                             (*overlap_callback)( data, c_space, probe_symbox );
     645           0 :                             (*overlap_callback)( data, c_space, probe_label );
     646             :                         }
     647             :                     }
     648             :                 }
     649             : #endif
     650             : 
     651             :             }
     652           0 :             else if ( geometry_rectangle_is_containing( diag_bounds, c_symbox )
     653           0 :                 && geometry_rectangle_is_containing( diag_bounds, c_label ) )
     654             :             {
     655           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_EXPORTED );
     656           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_WARNING );
     657           0 :                 (*overlap_callback)( data, diag_bounds, c_symbox );
     658           0 :                 (*overlap_callback)( data, diag_bounds, c_label );
     659             :             }
     660             :             else
     661             :             {
     662           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_ERROR );
     663           0 :                 (*overlap_callback)( data, diag_space, diag_space );
     664             :             }
     665             : 
     666             :         }
     667             : 
     668             :         /* check features against diagram */
     669             : 
     670           0 :         for ( uint_fast32_t f_idx = 0; f_idx < (*this_).feature_count; f_idx ++ )
     671             :         {
     672           0 :             const layout_feature_t *const feature = &((*this_).feature_layout[f_idx]);
     673           0 :             const data_feature_t *const feature_data = layout_feature_get_data_const( feature );
     674           0 :             const data_feature_type_t feature_type = data_feature_get_main_type( feature_data );
     675           0 :             const data_row_id_t feature_id = layout_feature_get_feature_id( feature );
     676             :             const bool feature_visible
     677           0 :                 = data_rules_diagram_shows_feature( &((*this_).filter_rules),
     678           0 :                                                     (*this_).input_data,
     679             :                                                     feature_id
     680             :                                                   );
     681           0 :             const data_stat_table_t feat_or_lifeline
     682           0 :                 = ( feature_type == DATA_FEATURE_TYPE_LIFELINE ) ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE;
     683             : 
     684             :             const geometry_rectangle_t *const f_symbox
     685           0 :                 = layout_feature_get_symbol_box_const( feature );
     686             :             const geometry_rectangle_t *const f_label
     687           0 :                 = layout_feature_get_label_box_const( feature );
     688             : 
     689           0 :             if ( ! feature_visible )
     690             :             {
     691             :                 /* nothing to do, feature is not visible in this diagram */
     692             :             }
     693           0 :             else if ( ( geometry_rectangle_is_empty( f_symbox )
     694           0 :                 || geometry_rectangle_is_containing( diag_space, f_symbox ))
     695           0 :                 && geometry_rectangle_is_containing( diag_space, f_label ) )
     696             :             {
     697           0 :                 data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_EXPORTED );
     698             : 
     699             : #ifdef PENCIL_LAYOUT_DATA_STATS_WITH_WARNINGS
     700             :                 /* check features against classifiers */
     701             : 
     702           0 :                 for ( uint_fast32_t probe_idx = 0; probe_idx < (*this_).visible_classifier_count; probe_idx ++ )
     703             :                 {
     704           0 :                     const layout_visible_classifier_t *const probe = &((*this_).visible_classifier_layout[probe_idx]);
     705           0 :                     const data_classifier_t *const probe_data = layout_visible_classifier_get_classifier_const( probe );
     706           0 :                     const data_classifier_type_t probe_type = data_classifier_get_main_type( probe_data );
     707             :                     /* determine if this probe classifier shall be drawn in the same rectangle as the lifeline */
     708             :                     const bool feature_is_proxy_for_probe
     709           0 :                         = pencil_rules_feature_is_implicit_proxy( &pencil_rules, feature_type, probe_type, diag_type );
     710             :                     const geometry_rectangle_t *const probe_symbox
     711           0 :                         = layout_visible_classifier_get_symbol_box_const( probe );
     712             :                     const geometry_rectangle_t *const probe_label
     713           0 :                         = layout_visible_classifier_get_label_box_const( probe );
     714             :                     const geometry_rectangle_t *const c_space
     715           0 :                         = layout_visible_classifier_get_space_const( probe );
     716             : 
     717           0 :                     const bool symbox_overlaps
     718           0 :                         = geometry_rectangle_is_intersecting( f_symbox, probe_symbox )
     719           0 :                         && ( ! geometry_rectangle_is_containing( c_space, f_symbox ) );
     720             :                     const bool f_sym_overlaps_c_label
     721           0 :                         = geometry_rectangle_is_intersecting( f_symbox, probe_label );
     722           0 :                     const bool f_label_overlaps_c_sym
     723           0 :                         = geometry_rectangle_is_intersecting( f_label, probe_symbox )
     724           0 :                         && ( ! geometry_rectangle_is_containing( c_space, f_label ) );
     725             :                     const bool label_overlaps
     726           0 :                         = geometry_rectangle_is_intersecting( f_label, probe_label );
     727             : 
     728           0 :                     if ( ! feature_is_proxy_for_probe )
     729             :                     {
     730           0 :                         if ( f_sym_overlaps_c_label || f_label_overlaps_c_sym || label_overlaps )
     731             :                         {
     732           0 :                             data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_WARNING );
     733           0 :                             (*overlap_callback)( data, f_symbox, probe_label );
     734           0 :                             (*overlap_callback)( data, f_label, probe_symbox );
     735           0 :                             (*overlap_callback)( data, f_label, probe_label );
     736             :                         }
     737           0 :                         else if ( symbox_overlaps )
     738             :                         {
     739             :                             const layout_visible_classifier_t *const f_parent
     740           0 :                                 = layout_feature_get_classifier_const ( feature );
     741             :                             const bool probe_is_parent
     742           0 :                                 = layout_visible_classifier_is_equal_diagramelement_id( f_parent, probe );
     743           0 :                             if ( probe_is_parent )
     744             :                             {
     745             :                                 /* ok: a feature may overlap its own parent classifier */
     746             :                             }
     747             :                             else
     748             :                             {
     749           0 :                                 data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_WARNING );
     750           0 :                                 (*overlap_callback)( data, f_symbox, probe_symbox );
     751             :                             }
     752             :                         }
     753             :                     }
     754             :                 }
     755             : 
     756             :                 /* check current feature against already processed features */
     757             : 
     758           0 :                 for ( uint_fast32_t probe_idx = 0; probe_idx < f_idx; probe_idx ++ )
     759             :                 {
     760           0 :                     const layout_feature_t *const probe = &((*this_).feature_layout[probe_idx]);
     761           0 :                     const data_row_id_t probe_id = layout_feature_get_feature_id( probe );
     762             :                     const bool probe_visible
     763           0 :                         = data_rules_diagram_shows_feature( &((*this_).filter_rules),
     764           0 :                                                             (*this_).input_data,
     765             :                                                             probe_id
     766             :                                                           );
     767             :                     const geometry_rectangle_t *const probe_symbox
     768           0 :                          = layout_feature_get_symbol_box_const( probe );
     769             :                     const geometry_rectangle_t *const probe_label
     770           0 :                         = layout_feature_get_label_box_const( probe );
     771             : 
     772           0 :                     if ( probe_visible )
     773             :                     {
     774             :                         const bool symbox_overlaps
     775           0 :                             = geometry_rectangle_is_intersecting( f_symbox, probe_symbox );
     776           0 :                         const bool mixed_overlaps
     777           0 :                             = ( geometry_rectangle_is_intersecting( f_symbox, probe_label )
     778           0 :                             || geometry_rectangle_is_intersecting( f_label, probe_symbox ) );
     779             :                         const bool label_overlaps
     780           0 :                             = geometry_rectangle_is_intersecting( f_label, probe_label );
     781             : 
     782           0 :                         if ( mixed_overlaps || label_overlaps )
     783             :                         {
     784           0 :                             data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_WARNING );
     785           0 :                             (*overlap_callback)( data, f_symbox, probe_label );
     786           0 :                             (*overlap_callback)( data, f_label, probe_symbox );
     787           0 :                             (*overlap_callback)( data, f_label, probe_label );
     788             :                         }
     789           0 :                         else if ( symbox_overlaps )
     790             :                         {
     791             :                             const layout_visible_classifier_t *const f_parent
     792           0 :                                 = layout_feature_get_classifier_const ( feature );
     793             :                             const layout_visible_classifier_t *const probe_parent
     794           0 :                                 = layout_feature_get_classifier_const ( probe );
     795             : 
     796             :                             const bool same_parent
     797           0 :                                 = layout_visible_classifier_is_equal_diagramelement_id( f_parent, probe_parent );
     798           0 :                             if ( same_parent )
     799             :                             {
     800             :                                 /* ok, not a layouting issue */
     801             :                             }
     802             :                             else
     803             :                             {
     804           0 :                                 data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_WARNING );
     805           0 :                                 (*overlap_callback)( data, f_symbox, probe_symbox );
     806             :                             }
     807             :                         }
     808             :                     }
     809             :                 }
     810             : #endif
     811             : 
     812             :             }
     813           0 :             else if ( geometry_rectangle_is_containing( diag_bounds, f_symbox )
     814           0 :                 && geometry_rectangle_is_containing( diag_bounds, f_label ) )
     815             :             {
     816           0 :                 data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_EXPORTED );
     817           0 :                 data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_WARNING );
     818           0 :                 (*overlap_callback)( data, diag_bounds, f_symbox );
     819           0 :                 (*overlap_callback)( data, diag_bounds, f_label );
     820             :             }
     821             :             else
     822             :             {
     823           0 :                 data_stat_inc_count( io_layout_stat, feat_or_lifeline, DATA_STAT_SERIES_ERROR );
     824           0 :                 (*overlap_callback)( data, diag_space, diag_space );
     825             :             }
     826             :         }
     827             : 
     828             :         /* check relationships against diagram */
     829             : 
     830           0 :         for ( uint_fast32_t r_idx = 0; r_idx < (*this_).relationship_count; r_idx ++ )
     831             :         {
     832           0 :             const layout_relationship_t *const relationship = &((*this_).relationship_layout[r_idx]);
     833           0 :             const data_row_id_t relationship_id = layout_relationship_get_relationship_id( relationship );
     834             :             const bool relationship_visible
     835           0 :                 = data_rules_diagram_shows_relationship( &((*this_).filter_rules),
     836           0 :                                                          (*this_).input_data,
     837             :                                                          relationship_id
     838             :                                                        );
     839             :             const geometry_rectangle_t *const r_label
     840           0 :                 = layout_relationship_get_label_box_const( relationship );
     841             :             const geometry_connector_t *const r_shape
     842           0 :                 = layout_relationship_get_shape_const( relationship );
     843           0 :             const geometry_rectangle_t r_bounds = geometry_connector_get_bounding_rectangle( r_shape );
     844             : 
     845           0 :             if ( ! relationship_visible )
     846             :             {
     847             :                 /* nothing to do, relationship is not visible in this diagram */
     848             :             }
     849           0 :             else if ( geometry_rectangle_is_containing( diag_space, &r_bounds )
     850           0 :                  && geometry_rectangle_is_containing( diag_space, r_label ) )
     851             :             {
     852           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_EXPORTED );
     853             : 
     854             : #ifdef PENCIL_LAYOUT_DATA_STATS_WITH_WARNINGS
     855             :                 /* check relationships against classifiers */
     856             : 
     857           0 :                 for ( uint_fast32_t probe_idx = 0; probe_idx < (*this_).visible_classifier_count; probe_idx ++ )
     858             :                 {
     859           0 :                     const layout_visible_classifier_t *const probe = &((*this_).visible_classifier_layout[probe_idx]);
     860             :                     const geometry_rectangle_t *const probe_symbox
     861           0 :                         = layout_visible_classifier_get_symbol_box_const( probe );
     862             :                     const geometry_rectangle_t *const probe_label
     863           0 :                         = layout_visible_classifier_get_label_box_const( probe );
     864             :                     const geometry_rectangle_t *const probe_space
     865           0 :                         = layout_visible_classifier_get_space_const( probe );
     866             : 
     867             :                     const bool label_overlaps_label
     868           0 :                         = geometry_rectangle_is_intersecting( r_label, probe_label );
     869           0 :                     const bool label_overlaps_symbox
     870           0 :                         = ( geometry_rectangle_is_intersecting( r_label, probe_symbox )
     871           0 :                         && ! geometry_rectangle_is_containing( probe_space, r_label ) );
     872             :                     const bool shape_overlaps_label
     873           0 :                         = geometry_connector_is_intersecting_rectangle( r_shape, probe_label );
     874             : 
     875           0 :                     if ( label_overlaps_label || label_overlaps_symbox || shape_overlaps_label )
     876             :                     {
     877           0 :                         data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_WARNING );
     878           0 :                         (*overlap_callback)( data, r_label, probe_label );
     879           0 :                         (*overlap_callback)( data, r_label, probe_symbox );
     880           0 :                         (*overlap_callback)( data, &r_bounds, probe_label );
     881             :                     }
     882             :                 }
     883             : 
     884             :                 /* check relationships against features */
     885             : 
     886           0 :                 for ( uint_fast32_t probe_idx = 0; probe_idx < (*this_).feature_count; probe_idx ++ )
     887             :                 {
     888           0 :                     const layout_feature_t *const probe = &((*this_).feature_layout[probe_idx]);
     889           0 :                     const data_feature_t *const probe_data = layout_feature_get_data_const( probe );
     890           0 :                     const data_feature_type_t probe_type = data_feature_get_main_type( probe_data );
     891           0 :                     const data_row_id_t probe_id = layout_feature_get_feature_id( probe );
     892             :                     const bool probe_visible
     893           0 :                         = data_rules_diagram_shows_feature( &((*this_).filter_rules),
     894           0 :                                                             (*this_).input_data,
     895             :                                                             probe_id
     896             :                                                           );
     897             :                     const geometry_rectangle_t *const probe_symbox
     898           0 :                          = layout_feature_get_symbol_box_const( probe );
     899             :                     const geometry_rectangle_t *const probe_label
     900           0 :                         = layout_feature_get_label_box_const( probe );
     901             : 
     902           0 :                     if ( probe_visible && ( DATA_FEATURE_TYPE_LIFELINE != probe_type ) )
     903             :                     {
     904             :                         const bool label_overlaps_label
     905           0 :                             = geometry_rectangle_is_intersecting( r_label, probe_label );
     906             :                         const bool label_overlaps_symbox
     907           0 :                             = geometry_rectangle_is_intersecting( r_label, probe_symbox );
     908             :                         const bool shape_overlaps_label
     909           0 :                             = geometry_connector_is_intersecting_rectangle( r_shape, probe_label );
     910             : 
     911           0 :                         if (  label_overlaps_label || label_overlaps_symbox || shape_overlaps_label )
     912             :                         {
     913           0 :                             data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_WARNING );
     914           0 :                             (*overlap_callback)( data, r_label, probe_label );
     915           0 :                             (*overlap_callback)( data, r_label, probe_symbox );
     916           0 :                             (*overlap_callback)( data, &r_bounds, probe_label );
     917             :                         }
     918             :                     }
     919             :                 }
     920             : 
     921             :                 /* check current relationship against already processed relationships */
     922             : 
     923           0 :                 for ( uint_fast32_t probe_idx = 0; probe_idx < r_idx; probe_idx ++ )
     924             :                 {
     925           0 :                     const layout_relationship_t *const probe = &((*this_).relationship_layout[probe_idx]);
     926           0 :                     const data_row_id_t probe_id = layout_relationship_get_relationship_id( probe );
     927             :                     const bool probe_visible
     928           0 :                         = data_rules_diagram_shows_relationship( &((*this_).filter_rules),
     929           0 :                                                                  (*this_).input_data,
     930             :                                                                  probe_id
     931             :                                                                );
     932             :                     const geometry_rectangle_t *const probe_label
     933           0 :                         = layout_relationship_get_label_box_const( probe );
     934             :                     const geometry_connector_t *const probe_shape
     935           0 :                         = layout_relationship_get_shape_const( probe );
     936             : 
     937           0 :                     if ( probe_visible )
     938             :                     {
     939             :                         const bool label_overlaps
     940           0 :                             = geometry_rectangle_is_intersecting( r_label, probe_label );
     941           0 :                         const bool mixed_overlaps
     942           0 :                             = ( geometry_connector_is_intersecting_rectangle( r_shape, probe_label )
     943           0 :                             || geometry_connector_is_intersecting_rectangle( probe_shape, r_label ) );
     944             : 
     945           0 :                         if ( label_overlaps || mixed_overlaps )
     946             :                         {
     947           0 :                             data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_WARNING );
     948           0 :                             (*overlap_callback)( data, r_label, probe_label );
     949           0 :                             (*overlap_callback)( data, &r_bounds, probe_label );
     950             :                             const geometry_rectangle_t probe_bounds
     951           0 :                                 = geometry_connector_get_bounding_rectangle( probe_shape );
     952           0 :                             (*overlap_callback)( data, &probe_bounds, r_label );
     953             :                         }
     954             :                     }
     955             :                 }
     956             : #endif
     957             : 
     958             :             }
     959           0 :             else if ( geometry_rectangle_is_containing( diag_bounds, &r_bounds )
     960           0 :                 && geometry_rectangle_is_containing( diag_bounds, r_label ) )
     961             :             {
     962           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_EXPORTED );
     963           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_WARNING );
     964           0 :                 (*overlap_callback)( data, diag_bounds, &r_bounds );
     965           0 :                 (*overlap_callback)( data, diag_bounds, r_label );
     966             :             }
     967             :             else
     968             :             {
     969           0 :                 data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_ERROR );
     970           0 :                 (*overlap_callback)( data, diag_space, diag_space );
     971             :             }
     972             :         }
     973             :     }
     974             :     else
     975             :     {
     976           0 :         data_stat_inc_count( io_layout_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_ERROR );
     977             :     }
     978             : 
     979           0 :     pencil_rules_destroy( &pencil_rules );
     980           0 :     U8_TRACE_END();
     981           0 : }
     982             : 
     983             : 
     984             : /*
     985             : Copyright 2017-2024 Andreas Warnke
     986             : 
     987             : Licensed under the Apache License, Version 2.0 (the "License");
     988             : you may not use this file except in compliance with the License.
     989             : You may obtain a copy of the License at
     990             : 
     991             :     http://www.apache.org/licenses/LICENSE-2.0
     992             : 
     993             : Unless required by applicable law or agreed to in writing, software
     994             : distributed under the License is distributed on an "AS IS" BASIS,
     995             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     996             : See the License for the specific language governing permissions and
     997             : limitations under the License.
     998             : */

Generated by: LCOV version 1.16