LCOV - code coverage report
Current view: top level - pencil/source - pencil_rel_label_layouter.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 0.0 % 179 0
Test Date: 2025-05-01 10:10:14 Functions: 0.0 % 6 0

            Line data    Source code
       1              : /* File: pencil_rel_label_layouter.c; Copyright and License: see below */
       2              : 
       3              : #include "pencil_rel_label_layouter.h"
       4              : #include "layout/layout_relationship_iter.h"
       5              : #include "geometry/geometry_point.h"
       6              : #include "geometry/geometry_direction.h"
       7              : #include "u8/u8_trace.h"
       8              : #include "utf8stringbuf/utf8string.h"
       9              : 
      10            0 : void pencil_rel_label_layouter_init( pencil_rel_label_layouter_t *this_,
      11              :                                      layout_visible_set_t *layout_data,
      12              :                                      const data_profile_part_t *profile,
      13              :                                      const pencil_size_t *pencil_size )
      14              : {
      15            0 :     U8_TRACE_BEGIN();
      16            0 :     assert( NULL != layout_data );
      17            0 :     assert( NULL != profile );
      18            0 :     assert( NULL != pencil_size );
      19              : 
      20            0 :     (*this_).layout_data = layout_data;
      21            0 :     (*this_).profile = profile;
      22            0 :     (*this_).pencil_size = pencil_size;
      23            0 :     draw_relationship_label_init( &((*this_).draw_relationship_label) );
      24            0 :     pencil_floating_label_layouter_init_void( &((*this_).label_floater) );
      25              : 
      26            0 :     U8_TRACE_END();
      27            0 : }
      28              : 
      29            0 : void pencil_rel_label_layouter_reinit( pencil_rel_label_layouter_t *this_,
      30              :                                        layout_visible_set_t *layout_data,
      31              :                                        const data_profile_part_t *profile,
      32              :                                        const pencil_size_t *pencil_size )
      33              : {
      34            0 :     U8_TRACE_BEGIN();
      35            0 :     assert( NULL != layout_data );
      36            0 :     assert( NULL != profile );
      37            0 :     assert( NULL != pencil_size );
      38              : 
      39            0 :     (*this_).layout_data = layout_data;
      40            0 :     (*this_).profile = profile;
      41            0 :     (*this_).pencil_size = pencil_size;
      42            0 :     pencil_floating_label_layouter_init_void( &((*this_).label_floater) );
      43              : 
      44            0 :     U8_TRACE_END();
      45            0 : }
      46              : 
      47            0 : void pencil_rel_label_layouter_destroy( pencil_rel_label_layouter_t *this_ )
      48              : {
      49            0 :     U8_TRACE_BEGIN();
      50              : 
      51            0 :     pencil_floating_label_layouter_destroy ( &((*this_).label_floater) );
      52            0 :     draw_relationship_label_destroy( &((*this_).draw_relationship_label) );
      53              : 
      54            0 :     U8_TRACE_END();
      55            0 : }
      56              : 
      57            0 : void pencil_rel_label_layouter_do_layout( pencil_rel_label_layouter_t *this_, PangoLayout *font_layout )
      58              : {
      59            0 :     U8_TRACE_BEGIN();
      60              :     assert ( (unsigned int) UNIVERSAL_ARRAY_INDEX_SORTER_MAX_ARRAY_SIZE >= (unsigned int) LAYOUT_VISIBLE_SET_MAX_RELATIONSHIPS );
      61            0 :     assert( NULL != font_layout );
      62              : 
      63            0 :     pencil_floating_label_layouter_reinit( &((*this_).label_floater),
      64              :                                            (*this_).layout_data,
      65              :                                            (*this_).profile,
      66              :                                            (*this_).pencil_size,
      67              :                                            font_layout
      68              :                                          );
      69              : 
      70              :     universal_array_index_sorter_t sorted;
      71            0 :     universal_array_index_sorter_init( &sorted );
      72              : 
      73              :     /* sort the relationships by their label-box layouting needs, drop invisible relations */
      74            0 :     pencil_rel_label_layouter_private_propose_processing_order ( this_, &sorted );
      75              : 
      76              :     /* layout the relationship label-boxes */
      77              :     layout_relationship_iter_t relationship_iterator;
      78            0 :     layout_relationship_iter_init( &relationship_iterator, (*this_).layout_data, &sorted );
      79            0 :     while ( layout_relationship_iter_has_next( &relationship_iterator ) )
      80              :     {
      81              :         /* determine pointer to relationship */
      82            0 :         layout_relationship_t *const current_relation = layout_relationship_iter_next_ptr( &relationship_iterator );
      83            0 :         geometry_point_t relation_middle = layout_relationship_get_middle ( current_relation );
      84              : 
      85              :         /* declaration of list of options */
      86            0 :         uint32_t solutions_count = 0;
      87              :         static const uint32_t SOLUTIONS_MAX = 10;
      88              :         geometry_rectangle_t solution[10];
      89              : 
      90              :         /* propose options */
      91            0 :         pencil_rel_label_layouter_private_propose_solutions( this_,
      92              :                                                              current_relation,
      93              :                                                              font_layout,
      94              :                                                              SOLUTIONS_MAX,
      95              :                                                              solution,
      96              :                                                              &solutions_count
      97              :                                                            );
      98              : 
      99              :         /* select best option */
     100              :         uint32_t index_of_best;
     101            0 :         if ( 1 == solutions_count )
     102              :         {
     103            0 :             index_of_best = 0;
     104              :         }
     105              :         else
     106              :         {
     107            0 :             pencil_floating_label_layouter_select_solution( &((*this_).label_floater),
     108              :                                                             relation_middle,
     109              :                                                             solutions_count,
     110              :                                                             solution,
     111              :                                                             &index_of_best
     112              :                                                           );
     113              :         }
     114              : 
     115              :         /* store best option to (*this_).layout_data */
     116            0 :         layout_relationship_set_label_box( current_relation, &(solution[index_of_best]) );
     117              :     }
     118              : 
     119            0 :     layout_relationship_iter_destroy( &relationship_iterator );
     120            0 :     universal_array_index_sorter_destroy( &sorted );
     121              : 
     122            0 :     pencil_floating_label_layouter_reinit_void( &((*this_).label_floater) );
     123              : 
     124            0 :     U8_TRACE_END();
     125            0 : }
     126              : 
     127            0 : void pencil_rel_label_layouter_private_propose_processing_order( pencil_rel_label_layouter_t *this_,
     128              :                                                                  universal_array_index_sorter_t *out_sorted )
     129              : {
     130            0 :     U8_TRACE_BEGIN();
     131            0 :     assert( NULL != out_sorted );
     132              : 
     133              :     /* sort the relationships by their label-box: the less simple, the earlier it shall be processed */
     134              :     const uint32_t count_relations
     135            0 :         = layout_visible_set_get_relationship_count ( (*this_).layout_data );
     136            0 :     for ( uint32_t index = 0; index < count_relations; index ++ )
     137              :     {
     138              :         const layout_relationship_t *const current_relation
     139            0 :             = layout_visible_set_get_relationship_ptr ( (*this_).layout_data, index );
     140              :         const data_relationship_t *const relation_data
     141            0 :             = layout_relationship_get_data_const ( current_relation );
     142            0 :         assert( NULL != relation_data );
     143              : 
     144            0 :         int64_t simpleness = 0;
     145              : 
     146              :         /* determine simpleness by length of label */
     147            0 :         simpleness -= utf8string_get_length( data_relationship_get_name_const( relation_data ) );
     148              : 
     149              :         /* insert relation to sorted array, the simpler the more to the back */
     150            0 :         if ( PENCIL_VISIBILITY_HIDE != layout_relationship_get_visibility ( current_relation ) )
     151              :         {
     152              :             int insert_error;
     153            0 :             insert_error = universal_array_index_sorter_insert( out_sorted, index, simpleness );
     154            0 :             if ( 0 != insert_error )
     155              :             {
     156            0 :                 U8_LOG_WARNING( "not all relationship label-boxes are layouted" );
     157              :             }
     158              :         }
     159              :     }
     160              : 
     161            0 :     U8_TRACE_END();
     162            0 : }
     163              : 
     164            0 : void pencil_rel_label_layouter_private_propose_solutions( pencil_rel_label_layouter_t *this_,
     165              :                                                           layout_relationship_t *current_relation,
     166              :                                                           PangoLayout *font_layout,
     167              :                                                           uint32_t solutions_max,
     168              :                                                           geometry_rectangle_t out_solutions[],
     169              :                                                           uint32_t *out_solutions_count )
     170              : {
     171            0 :     U8_TRACE_BEGIN();
     172            0 :     assert( NULL != current_relation );
     173            0 :     assert( NULL != font_layout );
     174            0 :     assert( NULL != out_solutions );
     175            0 :     assert( NULL != out_solutions_count );
     176              : 
     177            0 :     const data_relationship_t *the_relationship = layout_relationship_get_data_const( current_relation );
     178              :     {
     179              :         /* determine label dimensions */
     180            0 :         const geometry_dimensions_t label_dim_proposal = {
     181            0 :             .width = 30.0 * pencil_size_get_standard_font_size( (*this_).pencil_size ),
     182            0 :             .height = pencil_size_get_standard_font_size( (*this_).pencil_size )
     183              :         };
     184              :         geometry_dimensions_t preferred_label_dim;
     185            0 :         draw_relationship_label_get_type_and_name_dimensions( &((*this_).draw_relationship_label),
     186              :                                                               the_relationship,
     187              :                                                               (*this_).profile,
     188              :                                                               &label_dim_proposal,
     189              :                                                               (*this_).pencil_size,
     190              :                                                               font_layout,
     191              :                                                               &preferred_label_dim
     192              :                                                             );
     193              : 
     194              :         /* get layout data */
     195            0 :         const double line_w = 0.5 * pencil_size_get_standard_line_width( (*this_).pencil_size );
     196            0 :         const double object_dist = pencil_size_get_preferred_object_distance( (*this_).pencil_size );
     197              : 
     198              :         /* get connector data */
     199            0 :         const geometry_connector_t *const shape = layout_relationship_get_shape_const ( current_relation );
     200            0 :         const double source_end_x = geometry_connector_get_source_end_x ( shape );
     201            0 :         const double source_end_y = geometry_connector_get_source_end_y ( shape );
     202            0 :         const double main_line_source_x = geometry_connector_get_main_line_source_x ( shape );
     203            0 :         const double main_line_source_y = geometry_connector_get_main_line_source_y ( shape );
     204            0 :         const double main_line_destination_x = geometry_connector_get_main_line_destination_x ( shape );
     205            0 :         const double main_line_destination_y = geometry_connector_get_main_line_destination_y ( shape );
     206            0 :         const double destination_end_x = geometry_connector_get_destination_end_x ( shape );
     207            0 :         const double destination_end_y = geometry_connector_get_destination_end_y ( shape );
     208              :         geometry_point_t src_end;
     209              :         geometry_point_t main_src;
     210              :         geometry_point_t main_dst;
     211              :         geometry_point_t dst_end;
     212            0 :         geometry_point_init ( &src_end, source_end_x, source_end_y );
     213            0 :         geometry_point_init ( &main_src, main_line_source_x, main_line_source_y );
     214            0 :         geometry_point_init ( &main_dst, main_line_destination_x, main_line_destination_y );
     215            0 :         geometry_point_init ( &dst_end, destination_end_x, destination_end_y );
     216            0 :         const geometry_3dir_t connector_dirs = geometry_connector_get_directions( shape );
     217            0 :         const geometry_direction_t src_dir = geometry_3dir_get_first ( &connector_dirs );
     218            0 :         const geometry_direction_t main_dir = geometry_3dir_get_second ( &connector_dirs );
     219            0 :         const geometry_direction_t dst_dir = geometry_3dir_get_third ( &connector_dirs );
     220              : 
     221              :         /* propose solutions */
     222            0 :         assert( solutions_max >= 10 );
     223            0 :         uint32_t solution_idx = 0;
     224              : 
     225              :         /* there are 0 or 3 solutions at the src line segment */
     226            0 :         if ( geometry_point_calc_chess_distance( &src_end, &main_src ) > object_dist )
     227              :         {
     228              :             /* this is a noteworthy line segment */
     229              :             geometry_anchor_t anchor_1;
     230              :             geometry_anchor_t anchor_2;
     231              :             geometry_anchor_t anchor_3;
     232              :             geometry_anchor_t anchor_4;
     233              : 
     234            0 :             if ( ( src_dir == GEOMETRY_DIRECTION_UP ) || ( src_dir == GEOMETRY_DIRECTION_DOWN ) )
     235              :             {
     236              :                 /* right */
     237            0 :                 geometry_anchor_init( &anchor_1,
     238              :                                       main_line_source_x + line_w,
     239            0 :                                       (source_end_y + main_line_source_y) / 2.0,
     240              :                                       GEOMETRY_H_ALIGN_LEFT,  /* the reference point is the left side of the label */
     241              :                                       GEOMETRY_V_ALIGN_CENTER
     242              :                                     );
     243              : 
     244              :                 /* left */
     245            0 :                 geometry_anchor_init( &anchor_2,
     246              :                                       main_line_source_x - line_w,
     247            0 :                                       (source_end_y + main_line_source_y) / 2.0,
     248              :                                       GEOMETRY_H_ALIGN_RIGHT,  /* the reference point is the right side of the label */
     249              :                                       GEOMETRY_V_ALIGN_CENTER
     250              :                                     );
     251              :                 /* at bend to main line */
     252            0 :                 geometry_anchor_init( &anchor_3,
     253              :                                       main_line_source_x,
     254            0 :                                       main_line_source_y + (( src_dir == GEOMETRY_DIRECTION_UP ) ? (-line_w) : line_w ),
     255              :                                       GEOMETRY_H_ALIGN_CENTER,
     256              :                                       ( src_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_BOTTOM : GEOMETRY_V_ALIGN_TOP
     257              :                                     );
     258            0 :                 geometry_anchor_init( &anchor_4,
     259            0 :                                       main_line_source_x + (( main_dir == GEOMETRY_DIRECTION_LEFT ) ? line_w : (-line_w) ),
     260              :                                       main_line_source_y,
     261              :                                       ( main_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_LEFT : GEOMETRY_H_ALIGN_RIGHT,
     262              :                                       GEOMETRY_V_ALIGN_CENTER
     263              :                                     );
     264              :             }
     265              :             else
     266              :             {
     267              :                 /* down */
     268            0 :                 geometry_anchor_init( &anchor_1,
     269            0 :                                       (source_end_x + main_line_source_x) / 2.0,
     270              :                                       main_line_source_y + line_w,
     271              :                                       GEOMETRY_H_ALIGN_CENTER,
     272              :                                       GEOMETRY_V_ALIGN_TOP  /* the reference point is the top of the label */
     273              :                                     );
     274              : 
     275              :                 /* up */
     276            0 :                 geometry_anchor_init( &anchor_2,
     277            0 :                                       (source_end_x + main_line_source_x) / 2.0,
     278              :                                       main_line_source_y - line_w,
     279              :                                       GEOMETRY_H_ALIGN_CENTER,
     280              :                                       GEOMETRY_V_ALIGN_BOTTOM  /* the reference point is the bottom of the label */
     281              :                                     );
     282              :                 /* at bend to main line */
     283            0 :                 geometry_anchor_init( &anchor_3,
     284            0 :                                       main_line_source_x + (( src_dir == GEOMETRY_DIRECTION_LEFT ) ? (-line_w) : line_w ),
     285              :                                       main_line_source_y,
     286              :                                       ( src_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_RIGHT : GEOMETRY_H_ALIGN_LEFT,
     287              :                                       GEOMETRY_V_ALIGN_CENTER
     288              :                                     );
     289            0 :                 geometry_anchor_init( &anchor_4,
     290              :                                       main_line_source_x,
     291            0 :                                       main_line_source_y + (( main_dir == GEOMETRY_DIRECTION_UP ) ? line_w : (-line_w) ),
     292              :                                       GEOMETRY_H_ALIGN_CENTER,
     293              :                                       ( main_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_TOP : GEOMETRY_V_ALIGN_BOTTOM
     294              :                                     );
     295              :             }
     296              : 
     297            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     298              :                                                                  &anchor_1,
     299              :                                                                  &preferred_label_dim,
     300              :                                                                  &((*this_).draw_relationship_label),
     301              :                                                                  the_relationship,
     302            0 :                                                                  &(out_solutions[solution_idx])
     303              :                                                                );
     304            0 :             solution_idx ++;
     305              : 
     306            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     307              :                                                                  &anchor_2,
     308              :                                                                  &preferred_label_dim,
     309              :                                                                  &((*this_).draw_relationship_label),
     310              :                                                                  the_relationship,
     311            0 :                                                                  &(out_solutions[solution_idx])
     312              :                                                                );
     313            0 :             solution_idx ++;
     314              : 
     315            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     316              :                                                                  &anchor_3,
     317              :                                                                  &preferred_label_dim,
     318              :                                                                  &((*this_).draw_relationship_label),
     319              :                                                                  the_relationship,
     320            0 :                                                                  &(out_solutions[solution_idx])
     321              :                                                                );
     322            0 :             solution_idx ++;
     323              : 
     324            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     325              :                                                                  &anchor_4,
     326              :                                                                  &preferred_label_dim,
     327              :                                                                  &((*this_).draw_relationship_label),
     328              :                                                                  the_relationship,
     329            0 :                                                                  &(out_solutions[solution_idx])
     330              :                                                                );
     331            0 :             solution_idx ++;
     332              :         }
     333              : 
     334              :         /* there are 2 solutions at the main line segment */
     335              :         {
     336              :             geometry_anchor_t anchor_5;
     337              :             geometry_anchor_t anchor_6;
     338              : 
     339            0 :             if ( ( main_dir == GEOMETRY_DIRECTION_UP ) || ( main_dir == GEOMETRY_DIRECTION_DOWN ) )
     340              :             {
     341            0 :                 geometry_anchor_init( &anchor_5,
     342              :                                       main_line_source_x + line_w,
     343            0 :                                       (main_line_source_y + main_line_destination_y) / 2.0,
     344              :                                       GEOMETRY_H_ALIGN_LEFT,  /* the reference point is the left side of the label */
     345              :                                       GEOMETRY_V_ALIGN_CENTER
     346              :                                     );
     347            0 :                 geometry_anchor_init( &anchor_6,
     348              :                                       main_line_source_x - line_w,
     349            0 :                                       (main_line_source_y + main_line_destination_y) / 2.0,
     350              :                                       GEOMETRY_H_ALIGN_RIGHT,  /* the reference point is the right side of the label */
     351              :                                       GEOMETRY_V_ALIGN_CENTER
     352              :                                     );
     353              :             }
     354              :             else
     355              :             {
     356            0 :                 geometry_anchor_init( &anchor_5,
     357            0 :                                       (main_line_source_x + main_line_destination_x) / 2.0,
     358              :                                       main_line_source_y + line_w,
     359              :                                       GEOMETRY_H_ALIGN_CENTER,
     360              :                                       GEOMETRY_V_ALIGN_TOP  /* the reference point is the top of the label */
     361              :                                     );
     362            0 :                 geometry_anchor_init( &anchor_6,
     363            0 :                                       (main_line_source_x + main_line_destination_x) / 2.0,
     364              :                                       main_line_source_y - line_w,
     365              :                                       GEOMETRY_H_ALIGN_CENTER,
     366              :                                       GEOMETRY_V_ALIGN_BOTTOM  /* the reference point is the bottom of the label */
     367              :                                     );
     368              :             }
     369              : 
     370            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     371              :                                                                  &anchor_5,
     372              :                                                                  &preferred_label_dim,
     373              :                                                                  &((*this_).draw_relationship_label),
     374              :                                                                  the_relationship,
     375            0 :                                                                  &(out_solutions[solution_idx])
     376              :                                                                );
     377            0 :             solution_idx ++;
     378              : 
     379            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     380              :                                                                  &anchor_6,
     381              :                                                                  &preferred_label_dim,
     382              :                                                                  &((*this_).draw_relationship_label),
     383              :                                                                  the_relationship,
     384            0 :                                                                  &(out_solutions[solution_idx])
     385              :                                                                );
     386            0 :             solution_idx ++;
     387              :         }
     388              : 
     389              :         /* there are 0 or 3 solutions at the dst line segment */
     390            0 :         if ( geometry_point_calc_chess_distance( &main_dst, &dst_end ) > object_dist )
     391              :         {
     392              :             geometry_anchor_t anchor_7;
     393              :             geometry_anchor_t anchor_8;
     394              :             geometry_anchor_t anchor_9;
     395              :             geometry_anchor_t anchor_10;
     396              : 
     397              :             /* this is a noteworthy line segment */
     398            0 :             if ( ( dst_dir == GEOMETRY_DIRECTION_UP ) || ( dst_dir == GEOMETRY_DIRECTION_DOWN ) )
     399              :             {
     400              :                 /* at bend to main line */
     401            0 :                 geometry_anchor_init( &anchor_7,
     402            0 :                                       main_line_destination_x + (( main_dir == GEOMETRY_DIRECTION_LEFT ) ? (-line_w) : line_w ),
     403              :                                       main_line_destination_y,
     404              :                                       ( main_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_RIGHT : GEOMETRY_H_ALIGN_LEFT,
     405              :                                       GEOMETRY_V_ALIGN_CENTER
     406              :                                     );
     407            0 :                 geometry_anchor_init( &anchor_8,
     408              :                                       main_line_destination_x,
     409            0 :                                       main_line_destination_y + (( dst_dir == GEOMETRY_DIRECTION_UP ) ? line_w : (-line_w) ),
     410              :                                       GEOMETRY_H_ALIGN_CENTER,
     411              :                                       ( dst_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_TOP : GEOMETRY_V_ALIGN_BOTTOM
     412              :                                     );
     413              :                 /* right */
     414            0 :                 geometry_anchor_init( &anchor_9,
     415              :                                       main_line_destination_x + line_w,
     416            0 :                                       (destination_end_y + main_line_destination_y) / 2.0,
     417              :                                       GEOMETRY_H_ALIGN_LEFT,  /* the reference point is the left side of the label */
     418              :                                       GEOMETRY_V_ALIGN_CENTER
     419              :                                     );
     420              :                 /* left */
     421            0 :                 geometry_anchor_init( &anchor_10,
     422              :                                       main_line_destination_x - line_w,
     423            0 :                                       (destination_end_y + main_line_destination_y) / 2.0,
     424              :                                       GEOMETRY_H_ALIGN_RIGHT,  /* the reference point is the right side of the label */
     425              :                                       GEOMETRY_V_ALIGN_CENTER
     426              :                                     );
     427              :             }
     428              :             else
     429              :             {
     430              :                 /* at bend to main line */
     431            0 :                 geometry_anchor_init( &anchor_7,
     432              :                                       main_line_destination_x,
     433            0 :                                       main_line_destination_y + (( main_dir == GEOMETRY_DIRECTION_UP ) ? (-line_w) : line_w ),
     434              :                                       GEOMETRY_H_ALIGN_CENTER,
     435              :                                       ( main_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_BOTTOM : GEOMETRY_V_ALIGN_TOP
     436              :                                     );
     437            0 :                 geometry_anchor_init( &anchor_8,
     438            0 :                                       main_line_destination_x + (( dst_dir == GEOMETRY_DIRECTION_LEFT ) ? line_w : (-line_w) ),
     439              :                                       main_line_destination_y,
     440              :                                       ( dst_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_LEFT : GEOMETRY_H_ALIGN_RIGHT,
     441              :                                       GEOMETRY_V_ALIGN_CENTER
     442              :                                     );
     443              :                 /* down */
     444            0 :                 geometry_anchor_init( &anchor_9,
     445            0 :                                       (destination_end_x + main_line_destination_x) / 2.0,
     446              :                                       main_line_destination_y + line_w,
     447              :                                       GEOMETRY_H_ALIGN_CENTER,
     448              :                                       GEOMETRY_V_ALIGN_TOP  /* the reference point is the top of the label */
     449              :                                     );
     450              : 
     451              :                 /* up */
     452            0 :                 geometry_anchor_init( &anchor_10,
     453            0 :                                       (destination_end_x + main_line_destination_x) / 2.0,
     454              :                                       main_line_destination_y - line_w,
     455              :                                       GEOMETRY_H_ALIGN_CENTER,
     456              :                                       GEOMETRY_V_ALIGN_BOTTOM  /* the reference point is the bottom of the label */
     457              :                                     );
     458              : 
     459              :             }
     460              : 
     461            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     462              :                                                                  &anchor_7,
     463              :                                                                  &preferred_label_dim,
     464              :                                                                  &((*this_).draw_relationship_label),
     465              :                                                                  the_relationship,
     466            0 :                                                                  &(out_solutions[solution_idx])
     467              :                                                                );
     468            0 :             solution_idx ++;
     469              : 
     470            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     471              :                                                                  &anchor_8,
     472              :                                                                  &preferred_label_dim,
     473              :                                                                  &((*this_).draw_relationship_label),
     474              :                                                                  the_relationship,
     475            0 :                                                                  &(out_solutions[solution_idx])
     476              :                                                                );
     477            0 :             solution_idx ++;
     478              : 
     479            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     480              :                                                                  &anchor_9,
     481              :                                                                  &preferred_label_dim,
     482              :                                                                  &((*this_).draw_relationship_label),
     483              :                                                                  the_relationship,
     484            0 :                                                                  &(out_solutions[solution_idx])
     485              :                                                                );
     486            0 :             solution_idx ++;
     487              : 
     488            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     489              :                                                                  &anchor_10,
     490              :                                                                  &preferred_label_dim,
     491              :                                                                  &((*this_).draw_relationship_label),
     492              :                                                                  the_relationship,
     493            0 :                                                                  &(out_solutions[solution_idx])
     494              :                                                                );
     495            0 :             solution_idx ++;
     496              :         }
     497              : 
     498            0 :         assert( solution_idx > 0 );
     499            0 :         assert( solution_idx <= solutions_max );
     500            0 :         assert(( solution_idx == 2 )||( solution_idx == 6 )||( solution_idx == 10 ));
     501            0 :         *out_solutions_count = solution_idx;
     502              :     }
     503              : 
     504            0 :     U8_TRACE_END();
     505            0 : }
     506              : 
     507              : 
     508              : /*
     509              : Copyright 2019-2025 Andreas Warnke
     510              : 
     511              : Licensed under the Apache License, Version 2.0 (the "License");
     512              : you may not use this file except in compliance with the License.
     513              : You may obtain a copy of the License at
     514              : 
     515              :     http://www.apache.org/licenses/LICENSE-2.0
     516              : 
     517              : Unless required by applicable law or agreed to in writing, software
     518              : distributed under the License is distributed on an "AS IS" BASIS,
     519              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     520              : See the License for the specific language governing permissions and
     521              : limitations under the License.
     522              : */
        

Generated by: LCOV version 2.0-1