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.71.2_covts Lines: 0.0 % 181 0
Test Date: 2026-08-22 19:47:36 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 border_gap = pencil_size_get_standard_object_border( (*this_).pencil_size );
     197            0 :         const double label_dist = line_w + border_gap;  /* distance from label-test to line */
     198            0 :         const double object_dist = pencil_size_get_preferred_object_distance( (*this_).pencil_size );
     199              : 
     200              :         /* get connector data */
     201            0 :         const geometry_connector_t *const shape = layout_relationship_get_shape_const ( current_relation );
     202            0 :         const double source_end_x = geometry_connector_get_source_end_x ( shape );
     203            0 :         const double source_end_y = geometry_connector_get_source_end_y ( shape );
     204            0 :         const double main_line_source_x = geometry_connector_get_main_line_source_x ( shape );
     205            0 :         const double main_line_source_y = geometry_connector_get_main_line_source_y ( shape );
     206            0 :         const double main_line_destination_x = geometry_connector_get_main_line_destination_x ( shape );
     207            0 :         const double main_line_destination_y = geometry_connector_get_main_line_destination_y ( shape );
     208            0 :         const double destination_end_x = geometry_connector_get_destination_end_x ( shape );
     209            0 :         const double destination_end_y = geometry_connector_get_destination_end_y ( shape );
     210              :         geometry_point_t src_end;
     211              :         geometry_point_t main_src;
     212              :         geometry_point_t main_dst;
     213              :         geometry_point_t dst_end;
     214            0 :         geometry_point_init ( &src_end, source_end_x, source_end_y );
     215            0 :         geometry_point_init ( &main_src, main_line_source_x, main_line_source_y );
     216            0 :         geometry_point_init ( &main_dst, main_line_destination_x, main_line_destination_y );
     217            0 :         geometry_point_init ( &dst_end, destination_end_x, destination_end_y );
     218            0 :         const geometry_3dir_t connector_dirs = geometry_connector_get_directions( shape );
     219            0 :         const geometry_direction_t src_dir = geometry_3dir_get_first ( &connector_dirs );
     220            0 :         const geometry_direction_t main_dir = geometry_3dir_get_second ( &connector_dirs );
     221            0 :         const geometry_direction_t dst_dir = geometry_3dir_get_third ( &connector_dirs );
     222              : 
     223              :         /* propose solutions */
     224            0 :         assert( solutions_max >= 10 );
     225            0 :         uint32_t solution_idx = 0;
     226              : 
     227              :         /* there are 0 or 4 solutions at the src line segment */
     228            0 :         if ( geometry_point_calc_chess_distance( &src_end, &main_src ) > object_dist )
     229              :         {
     230              :             /* this is a noteworthy line segment */
     231              :             geometry_anchor_t anchor_1;
     232              :             geometry_anchor_t anchor_2;
     233              :             geometry_anchor_t anchor_3;
     234              :             geometry_anchor_t anchor_4;
     235              : 
     236            0 :             if ( ( src_dir == GEOMETRY_DIRECTION_UP ) || ( src_dir == GEOMETRY_DIRECTION_DOWN ) )
     237              :             {
     238              :                 /* right */
     239            0 :                 geometry_anchor_init( &anchor_1,
     240              :                                       main_line_source_x + label_dist,
     241            0 :                                       (source_end_y + main_line_source_y) / 2.0,
     242              :                                       GEOMETRY_H_ALIGN_LEFT,  /* the reference point is the left side of the label */
     243              :                                       GEOMETRY_V_ALIGN_CENTER
     244              :                                     );
     245              : 
     246              :                 /* left */
     247            0 :                 geometry_anchor_init( &anchor_2,
     248              :                                       main_line_source_x - label_dist,
     249            0 :                                       (source_end_y + main_line_source_y) / 2.0,
     250              :                                       GEOMETRY_H_ALIGN_RIGHT,  /* the reference point is the right side of the label */
     251              :                                       GEOMETRY_V_ALIGN_CENTER
     252              :                                     );
     253              :                 /* at bend to main line */
     254            0 :                 geometry_anchor_init( &anchor_3,
     255              :                                       main_line_source_x,
     256            0 :                                       main_line_source_y + (( src_dir == GEOMETRY_DIRECTION_UP ) ? (-label_dist) : label_dist ),
     257              :                                       GEOMETRY_H_ALIGN_CENTER,
     258              :                                       ( src_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_BOTTOM : GEOMETRY_V_ALIGN_TOP
     259              :                                     );
     260            0 :                 geometry_anchor_init( &anchor_4,
     261            0 :                                       main_line_source_x + (( main_dir == GEOMETRY_DIRECTION_LEFT ) ? label_dist : (-label_dist) ),
     262              :                                       main_line_source_y,
     263              :                                       ( main_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_LEFT : GEOMETRY_H_ALIGN_RIGHT,
     264              :                                       GEOMETRY_V_ALIGN_CENTER
     265              :                                     );
     266              :             }
     267              :             else
     268              :             {
     269              :                 /* down */
     270            0 :                 geometry_anchor_init( &anchor_1,
     271            0 :                                       (source_end_x + main_line_source_x) / 2.0,
     272              :                                       main_line_source_y + label_dist,
     273              :                                       GEOMETRY_H_ALIGN_CENTER,
     274              :                                       GEOMETRY_V_ALIGN_TOP  /* the reference point is the top of the label */
     275              :                                     );
     276              : 
     277              :                 /* up */
     278            0 :                 geometry_anchor_init( &anchor_2,
     279            0 :                                       (source_end_x + main_line_source_x) / 2.0,
     280              :                                       main_line_source_y - label_dist,
     281              :                                       GEOMETRY_H_ALIGN_CENTER,
     282              :                                       GEOMETRY_V_ALIGN_BOTTOM  /* the reference point is the bottom of the label */
     283              :                                     );
     284              :                 /* at bend to main line */
     285            0 :                 geometry_anchor_init( &anchor_3,
     286            0 :                                       main_line_source_x + (( src_dir == GEOMETRY_DIRECTION_LEFT ) ? (-label_dist) : label_dist ),
     287              :                                       main_line_source_y,
     288              :                                       ( src_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_RIGHT : GEOMETRY_H_ALIGN_LEFT,
     289              :                                       GEOMETRY_V_ALIGN_CENTER
     290              :                                     );
     291            0 :                 geometry_anchor_init( &anchor_4,
     292              :                                       main_line_source_x,
     293            0 :                                       main_line_source_y + (( main_dir == GEOMETRY_DIRECTION_UP ) ? label_dist : (-label_dist) ),
     294              :                                       GEOMETRY_H_ALIGN_CENTER,
     295              :                                       ( main_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_TOP : GEOMETRY_V_ALIGN_BOTTOM
     296              :                                     );
     297              :             }
     298              : 
     299            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     300              :                                                                  &anchor_1,
     301              :                                                                  &preferred_label_dim,
     302              :                                                                  &((*this_).draw_relationship_label),
     303              :                                                                  the_relationship,
     304            0 :                                                                  &(out_solutions[solution_idx])
     305              :                                                                );
     306            0 :             solution_idx ++;
     307              : 
     308            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     309              :                                                                  &anchor_2,
     310              :                                                                  &preferred_label_dim,
     311              :                                                                  &((*this_).draw_relationship_label),
     312              :                                                                  the_relationship,
     313            0 :                                                                  &(out_solutions[solution_idx])
     314              :                                                                );
     315            0 :             solution_idx ++;
     316              : 
     317            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     318              :                                                                  &anchor_3,
     319              :                                                                  &preferred_label_dim,
     320              :                                                                  &((*this_).draw_relationship_label),
     321              :                                                                  the_relationship,
     322            0 :                                                                  &(out_solutions[solution_idx])
     323              :                                                                );
     324            0 :             solution_idx ++;
     325              : 
     326            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     327              :                                                                  &anchor_4,
     328              :                                                                  &preferred_label_dim,
     329              :                                                                  &((*this_).draw_relationship_label),
     330              :                                                                  the_relationship,
     331            0 :                                                                  &(out_solutions[solution_idx])
     332              :                                                                );
     333            0 :             solution_idx ++;
     334              :         }
     335              : 
     336              :         /* there are 2 solutions at the main line segment */
     337              :         {
     338              :             geometry_anchor_t anchor_5;
     339              :             geometry_anchor_t anchor_6;
     340              : 
     341            0 :             if ( ( main_dir == GEOMETRY_DIRECTION_UP ) || ( main_dir == GEOMETRY_DIRECTION_DOWN ) )
     342              :             {
     343            0 :                 geometry_anchor_init( &anchor_5,
     344              :                                       main_line_source_x + label_dist,
     345            0 :                                       (main_line_source_y + main_line_destination_y) / 2.0,
     346              :                                       GEOMETRY_H_ALIGN_LEFT,  /* the reference point is the left side of the label */
     347              :                                       GEOMETRY_V_ALIGN_CENTER
     348              :                                     );
     349            0 :                 geometry_anchor_init( &anchor_6,
     350              :                                       main_line_source_x - label_dist,
     351            0 :                                       (main_line_source_y + main_line_destination_y) / 2.0,
     352              :                                       GEOMETRY_H_ALIGN_RIGHT,  /* the reference point is the right side of the label */
     353              :                                       GEOMETRY_V_ALIGN_CENTER
     354              :                                     );
     355              :             }
     356              :             else
     357              :             {
     358            0 :                 geometry_anchor_init( &anchor_5,
     359            0 :                                       (main_line_source_x + main_line_destination_x) / 2.0,
     360              :                                       main_line_source_y + label_dist,
     361              :                                       GEOMETRY_H_ALIGN_CENTER,
     362              :                                       GEOMETRY_V_ALIGN_TOP  /* the reference point is the top of the label */
     363              :                                     );
     364            0 :                 geometry_anchor_init( &anchor_6,
     365            0 :                                       (main_line_source_x + main_line_destination_x) / 2.0,
     366              :                                       main_line_source_y - label_dist,
     367              :                                       GEOMETRY_H_ALIGN_CENTER,
     368              :                                       GEOMETRY_V_ALIGN_BOTTOM  /* the reference point is the bottom of the label */
     369              :                                     );
     370              :             }
     371              : 
     372            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     373              :                                                                  &anchor_5,
     374              :                                                                  &preferred_label_dim,
     375              :                                                                  &((*this_).draw_relationship_label),
     376              :                                                                  the_relationship,
     377            0 :                                                                  &(out_solutions[solution_idx])
     378              :                                                                );
     379            0 :             solution_idx ++;
     380              : 
     381            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     382              :                                                                  &anchor_6,
     383              :                                                                  &preferred_label_dim,
     384              :                                                                  &((*this_).draw_relationship_label),
     385              :                                                                  the_relationship,
     386            0 :                                                                  &(out_solutions[solution_idx])
     387              :                                                                );
     388            0 :             solution_idx ++;
     389              :         }
     390              : 
     391              :         /* there are 0 or 4 solutions at the dst line segment */
     392            0 :         if ( geometry_point_calc_chess_distance( &main_dst, &dst_end ) > object_dist )
     393              :         {
     394              :             geometry_anchor_t anchor_7;
     395              :             geometry_anchor_t anchor_8;
     396              :             geometry_anchor_t anchor_9;
     397              :             geometry_anchor_t anchor_10;
     398              : 
     399              :             /* this is a noteworthy line segment */
     400            0 :             if ( ( dst_dir == GEOMETRY_DIRECTION_UP ) || ( dst_dir == GEOMETRY_DIRECTION_DOWN ) )
     401              :             {
     402              :                 /* at bend to main line */
     403            0 :                 geometry_anchor_init( &anchor_7,
     404            0 :                                       main_line_destination_x + (( main_dir == GEOMETRY_DIRECTION_LEFT ) ? (-label_dist) : label_dist ),
     405              :                                       main_line_destination_y,
     406              :                                       ( main_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_RIGHT : GEOMETRY_H_ALIGN_LEFT,
     407              :                                       GEOMETRY_V_ALIGN_CENTER
     408              :                                     );
     409            0 :                 geometry_anchor_init( &anchor_8,
     410              :                                       main_line_destination_x,
     411            0 :                                       main_line_destination_y + (( dst_dir == GEOMETRY_DIRECTION_UP ) ? label_dist : (-label_dist) ),
     412              :                                       GEOMETRY_H_ALIGN_CENTER,
     413              :                                       ( dst_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_TOP : GEOMETRY_V_ALIGN_BOTTOM
     414              :                                     );
     415              :                 /* right */
     416            0 :                 geometry_anchor_init( &anchor_9,
     417              :                                       main_line_destination_x + label_dist,
     418            0 :                                       (destination_end_y + main_line_destination_y) / 2.0,
     419              :                                       GEOMETRY_H_ALIGN_LEFT,  /* the reference point is the left side of the label */
     420              :                                       GEOMETRY_V_ALIGN_CENTER
     421              :                                     );
     422              :                 /* left */
     423            0 :                 geometry_anchor_init( &anchor_10,
     424              :                                       main_line_destination_x - label_dist,
     425            0 :                                       (destination_end_y + main_line_destination_y) / 2.0,
     426              :                                       GEOMETRY_H_ALIGN_RIGHT,  /* the reference point is the right side of the label */
     427              :                                       GEOMETRY_V_ALIGN_CENTER
     428              :                                     );
     429              :             }
     430              :             else
     431              :             {
     432              :                 /* at bend to main line */
     433            0 :                 geometry_anchor_init( &anchor_7,
     434              :                                       main_line_destination_x,
     435            0 :                                       main_line_destination_y + (( main_dir == GEOMETRY_DIRECTION_UP ) ? (-label_dist) : label_dist ),
     436              :                                       GEOMETRY_H_ALIGN_CENTER,
     437              :                                       ( main_dir == GEOMETRY_DIRECTION_UP ) ? GEOMETRY_V_ALIGN_BOTTOM : GEOMETRY_V_ALIGN_TOP
     438              :                                     );
     439            0 :                 geometry_anchor_init( &anchor_8,
     440            0 :                                       main_line_destination_x + (( dst_dir == GEOMETRY_DIRECTION_LEFT ) ? label_dist : (-label_dist) ),
     441              :                                       main_line_destination_y,
     442              :                                       ( dst_dir == GEOMETRY_DIRECTION_LEFT ) ? GEOMETRY_H_ALIGN_LEFT : GEOMETRY_H_ALIGN_RIGHT,
     443              :                                       GEOMETRY_V_ALIGN_CENTER
     444              :                                     );
     445              :                 /* down */
     446            0 :                 geometry_anchor_init( &anchor_9,
     447            0 :                                       (destination_end_x + main_line_destination_x) / 2.0,
     448              :                                       main_line_destination_y + label_dist,
     449              :                                       GEOMETRY_H_ALIGN_CENTER,
     450              :                                       GEOMETRY_V_ALIGN_TOP  /* the reference point is the top of the label */
     451              :                                     );
     452              : 
     453              :                 /* up */
     454            0 :                 geometry_anchor_init( &anchor_10,
     455            0 :                                       (destination_end_x + main_line_destination_x) / 2.0,
     456              :                                       main_line_destination_y - label_dist,
     457              :                                       GEOMETRY_H_ALIGN_CENTER,
     458              :                                       GEOMETRY_V_ALIGN_BOTTOM  /* the reference point is the bottom of the label */
     459              :                                     );
     460              : 
     461              :             }
     462              : 
     463            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     464              :                                                                  &anchor_7,
     465              :                                                                  &preferred_label_dim,
     466              :                                                                  &((*this_).draw_relationship_label),
     467              :                                                                  the_relationship,
     468            0 :                                                                  &(out_solutions[solution_idx])
     469              :                                                                );
     470            0 :             solution_idx ++;
     471              : 
     472            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     473              :                                                                  &anchor_8,
     474              :                                                                  &preferred_label_dim,
     475              :                                                                  &((*this_).draw_relationship_label),
     476              :                                                                  the_relationship,
     477            0 :                                                                  &(out_solutions[solution_idx])
     478              :                                                                );
     479            0 :             solution_idx ++;
     480              : 
     481            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     482              :                                                                  &anchor_9,
     483              :                                                                  &preferred_label_dim,
     484              :                                                                  &((*this_).draw_relationship_label),
     485              :                                                                  the_relationship,
     486            0 :                                                                  &(out_solutions[solution_idx])
     487              :                                                                );
     488            0 :             solution_idx ++;
     489              : 
     490            0 :             pencil_floating_label_layouter_propose_solution_rel( &((*this_).label_floater),
     491              :                                                                  &anchor_10,
     492              :                                                                  &preferred_label_dim,
     493              :                                                                  &((*this_).draw_relationship_label),
     494              :                                                                  the_relationship,
     495            0 :                                                                  &(out_solutions[solution_idx])
     496              :                                                                );
     497            0 :             solution_idx ++;
     498              :         }
     499              : 
     500            0 :         assert( solution_idx > 0 );
     501            0 :         assert( solution_idx <= solutions_max );
     502            0 :         assert(( solution_idx == 2 )||( solution_idx == 6 )||( solution_idx == 10 ));
     503            0 :         *out_solutions_count = solution_idx;
     504              :     }
     505              : 
     506            0 :     U8_TRACE_END();
     507            0 : }
     508              : 
     509              : 
     510              : /*
     511              : Copyright 2019-2026 Andreas Warnke
     512              : 
     513              : Licensed under the Apache License, Version 2.0 (the "License");
     514              : you may not use this file except in compliance with the License.
     515              : You may obtain a copy of the License at
     516              : 
     517              :     http://www.apache.org/licenses/LICENSE-2.0
     518              : 
     519              : Unless required by applicable law or agreed to in writing, software
     520              : distributed under the License is distributed on an "AS IS" BASIS,
     521              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     522              : See the License for the specific language governing permissions and
     523              : limitations under the License.
     524              : */
        

Generated by: LCOV version 2.0-1