LCOV - code coverage report
Current view: top level - pencil/source - pencil_classifier_1d_layouter.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.65.6_covts Lines: 0 300 0.0 %
Date: 2025-09-25 21:07:53 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /* File: pencil_classifier_1d_layouter.c; Copyright and License: see below */
       2             : 
       3             : #include "pencil_classifier_1d_layouter.h"
       4             : #include "layout/layout_visible_classifier_iter.h"
       5             : #include "u8/u8_trace.h"
       6             : #include <pango/pangocairo.h>
       7             : #include <stdio.h>
       8             : #include <stdlib.h>
       9             : #include <math.h>
      10             : 
      11           0 : void pencil_classifier_1d_layouter_init( pencil_classifier_1d_layouter_t *this_,
      12             :                                          layout_visible_set_t *layout_data,
      13             :                                          const data_profile_part_t *profile,
      14             :                                          const pencil_size_t *pencil_size )
      15             : {
      16           0 :     U8_TRACE_BEGIN();
      17           0 :     assert( NULL != layout_data );
      18           0 :     assert( NULL != profile );
      19           0 :     assert( NULL != pencil_size );
      20             : 
      21           0 :     (*this_).layout_data = layout_data;
      22           0 :     (*this_).profile = profile;
      23           0 :     (*this_).pencil_size = pencil_size;
      24           0 :     pencil_classifier_composer_init( &((*this_).classifier_composer) );
      25           0 :     data_rules_init( &((*this_).rules) );
      26             : 
      27             :     /* get draw area */
      28             :     {
      29             :         const layout_diagram_t *const diagram_layout
      30           0 :             = layout_visible_set_get_diagram_ptr( (*this_).layout_data );
      31           0 :         (*this_).diagram_draw_area = layout_diagram_get_draw_area_const( diagram_layout );
      32             :     }
      33             : 
      34           0 :     U8_TRACE_END();
      35           0 : }
      36             : 
      37           0 : void pencil_classifier_1d_layouter_destroy( pencil_classifier_1d_layouter_t *this_ )
      38             : {
      39           0 :     U8_TRACE_BEGIN();
      40             : 
      41           0 :     data_rules_destroy( &((*this_).rules) );
      42           0 :     pencil_classifier_composer_destroy( &((*this_).classifier_composer) );
      43             : 
      44           0 :     U8_TRACE_END();
      45           0 : }
      46             : 
      47           0 : void pencil_classifier_1d_layouter_layout_for_list( pencil_classifier_1d_layouter_t *this_, PangoLayout *font_layout )
      48             : {
      49           0 :     U8_TRACE_BEGIN();
      50             : 
      51             :     /* get preferred object distance */
      52           0 :     const double obj_dist = pencil_size_get_preferred_object_distance( (*this_).pencil_size );
      53             :     /* const double gap = pencil_size_get_standard_object_border( (*this_).pencil_size ); */
      54             : 
      55             :     /* get the draw coordinates */
      56             :     geometry_rectangle_t draw_area;
      57           0 :     geometry_rectangle_copy( &draw_area, (*this_).diagram_draw_area );
      58           0 :     geometry_rectangle_enlarge( &draw_area, 0.0, (- obj_dist) );
      59           0 :     double diag_w = geometry_rectangle_get_width( &draw_area );
      60           0 :     double diag_h = geometry_rectangle_get_height( &draw_area );
      61             : 
      62           0 :     const double phi = 1.6180339; /* minor=0.618, major=1.0, sum=1.618 => (sum/major)==(major/minor) */
      63           0 :     const double golden_ratio_width = diag_w/phi;
      64           0 :     const double golden_ratio_height = diag_h/phi;
      65             : 
      66             :     /* sort the classifiers according to their list_order */
      67             :     universal_array_index_sorter_t sorted_classifiers;
      68           0 :     universal_array_index_sorter_init( &sorted_classifiers );
      69             : 
      70             :     /* calculate preferred classifier bounds/envelopes */
      71           0 :     const uint_fast32_t c_count = layout_visible_set_get_visible_classifier_count( (*this_).layout_data );
      72           0 :     for ( uint_fast32_t plain_idx = 0; plain_idx < c_count; plain_idx ++ )
      73             :     {
      74             :         layout_visible_classifier_t *const visible_classifier1
      75           0 :             = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, plain_idx );
      76             :         const data_visible_classifier_t *const visible_classifier_data
      77           0 :             = layout_visible_classifier_get_data_const ( visible_classifier1 );
      78           0 :         const data_classifier_t *const classifier1 = data_visible_classifier_get_classifier_const( visible_classifier_data );
      79             : 
      80             :         /* sort the classifiers according to their list_order */
      81             :         {
      82           0 :             const double weight = (const double) data_classifier_get_list_order( classifier1 );
      83           0 :             const int insert_err = universal_array_index_sorter_insert( &sorted_classifiers, plain_idx, weight );
      84           0 :             if ( 0 != insert_err )
      85             :             {
      86           0 :                 U8_LOG_ERROR ( "universal_array_index_sorter_t list is full." );
      87             :             }
      88             :         }
      89             : 
      90             :         /* set the preferred bounds, space and label_box of the classifier layout */
      91             :         {
      92             :             geometry_rectangle_t envelope_box;
      93           0 :             geometry_rectangle_init( &envelope_box, 0.0, 0.0, golden_ratio_width, (golden_ratio_height/c_count) );
      94             : 
      95           0 :             const bool has_contained_children = false;  /* this diagram type does not embrace children */
      96           0 :             pencil_classifier_composer_set_envelope_box( &((*this_).classifier_composer),
      97             :                                                          &envelope_box,
      98             :                                                          has_contained_children,
      99             :                                                          (*this_).profile,
     100             :                                                          (*this_).pencil_size,
     101             :                                                          font_layout,
     102             :                                                          visible_classifier1
     103             :                                                        );
     104             : 
     105           0 :             geometry_rectangle_destroy( &envelope_box );
     106             :         }
     107             :     }
     108             : 
     109             :     /* layout list */
     110           0 :     pencil_classifier_1d_layouter_private_layout_vertical( this_,
     111             :                                                            &sorted_classifiers,
     112             :                                                            &draw_area,
     113             :                                                            GEOMETRY_H_ALIGN_CENTER
     114             :                                                          );
     115             : 
     116             :     /* cleanup sorted array indices and area-rectangles */
     117           0 :     universal_array_index_sorter_destroy( &sorted_classifiers );
     118           0 :     geometry_rectangle_destroy( &draw_area );
     119             : 
     120           0 :     U8_TRACE_END();
     121           0 : }
     122             : 
     123           0 : void pencil_classifier_1d_layouter_layout_for_sequence( pencil_classifier_1d_layouter_t *this_, PangoLayout *font_layout )
     124             : {
     125           0 :     U8_TRACE_BEGIN();
     126             : 
     127             :     /* get preferred object distance */
     128           0 :     const double obj_dist = pencil_size_get_preferred_object_distance( (*this_).pencil_size );
     129             :     /* const double gap = pencil_size_get_standard_object_border( (*this_).pencil_size ); */
     130             : 
     131             :     /* get the diagram coordinates */
     132             :     geometry_rectangle_t draw_area;
     133           0 :     geometry_rectangle_copy( &draw_area, (*this_).diagram_draw_area );
     134           0 :     geometry_rectangle_shift( &draw_area, obj_dist, 0.0 );
     135           0 :     geometry_rectangle_enlarge( &draw_area, (-2.0 * obj_dist), (- obj_dist) );
     136           0 :     double diag_w = geometry_rectangle_get_width( &draw_area );
     137           0 :     double diag_h = geometry_rectangle_get_height( &draw_area );
     138             : 
     139           0 :     const double phi = 1.6180339; /* minor=0.618, major=1.0, sum=1.618 => (sum/major)==(major/minor) */
     140           0 :     const double minor_ratio = (1.0 - 0.6180339);
     141           0 :     const double golden_ratio_width = diag_w/phi;
     142           0 :     const double minor_minor_height = diag_h * minor_ratio * minor_ratio;
     143           0 :     const double half_minor_width = diag_w * minor_ratio * 0.5;
     144             : 
     145             :     geometry_rectangle_t left_area;
     146           0 :     geometry_rectangle_copy( &left_area, &draw_area );
     147           0 :     geometry_rectangle_enlarge( &left_area, (- half_minor_width), 0.0 );
     148             : 
     149             :     geometry_rectangle_t right_column;
     150           0 :     geometry_rectangle_copy( &right_column, &draw_area );
     151           0 :     geometry_rectangle_shift( &right_column, (diag_w-half_minor_width), minor_minor_height );
     152           0 :     geometry_rectangle_enlarge( &right_column, (half_minor_width-diag_w), (- minor_minor_height) );
     153             : 
     154             :     /* sort the classifiers according to their list_order */
     155             :     universal_array_index_sorter_t sorted_notes_reqs;
     156           0 :     universal_array_index_sorter_init( &sorted_notes_reqs );
     157             :     universal_array_index_sorter_t sorted_diag_refs;
     158           0 :     universal_array_index_sorter_init( &sorted_diag_refs );
     159             :     universal_array_index_sorter_t sorted_acting_classifiers;
     160           0 :     universal_array_index_sorter_init( &sorted_acting_classifiers );
     161             : 
     162             :     /* calculate preferred classifier bounds */
     163           0 :     const uint_fast32_t c_count = layout_visible_set_get_visible_classifier_count( (*this_).layout_data );
     164           0 :     for ( uint_fast32_t plain_idx = 0; plain_idx < c_count; plain_idx ++ )
     165             :     {
     166             :         layout_visible_classifier_t *const visible_classifier1
     167           0 :             = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, plain_idx );
     168             :         const data_visible_classifier_t *const visible_classifier_data
     169           0 :             = layout_visible_classifier_get_data_const ( visible_classifier1 );
     170           0 :         const data_classifier_t *const classifier1 = data_visible_classifier_get_classifier_const( visible_classifier_data );
     171           0 :         const data_classifier_type_t c1_type = data_classifier_get_main_type ( classifier1 );
     172             : 
     173             :         /* check classifier type and sort into corresponding list */
     174             :         {
     175           0 :             int insert_err = 0;
     176           0 :             const double weight = (const double) data_classifier_get_list_order( classifier1 );
     177             :             const bool c1_type_is_scenario
     178           0 :                 = data_rules_classifier_has_scenario_semantics( &((*this_).rules),
     179             :                                                                 DATA_DIAGRAM_TYPE_UML_SEQUENCE_DIAGRAM,
     180             :                                                                 c1_type
     181             :                                                               );
     182           0 :             if ( c1_type == DATA_CLASSIFIER_TYPE_INTERACTION_USE )
     183             :             {
     184           0 :                 insert_err = universal_array_index_sorter_insert( &sorted_diag_refs, plain_idx, weight );
     185             :             }
     186           0 :             else if ( ! c1_type_is_scenario )
     187             :             {
     188           0 :                 insert_err = universal_array_index_sorter_insert( &sorted_notes_reqs, plain_idx, weight );
     189             :             }
     190             :             else
     191             :             {
     192           0 :                 insert_err = universal_array_index_sorter_insert( &sorted_acting_classifiers, plain_idx, weight );
     193             :             }
     194           0 :             if ( 0 != insert_err )
     195             :             {
     196           0 :                 U8_LOG_ERROR ( "universal_array_index_sorter_t list is full." );
     197             :             }
     198             :         }
     199             : 
     200             :         /* set the preferred bounds, space and label_box of the classifier layout */
     201             :         {
     202             :             geometry_rectangle_t envelope_box;
     203           0 :             if ( c1_type == DATA_CLASSIFIER_TYPE_INTERACTION_USE )
     204             :             {
     205           0 :                 geometry_rectangle_init( &envelope_box, 0.0, 0.0, (diag_w-half_minor_width), (minor_minor_height/2.0) );
     206             :             }
     207             :             else
     208             :             {
     209           0 :                 geometry_rectangle_init( &envelope_box, 0.0, 0.0, (golden_ratio_width/c_count), minor_minor_height );
     210             :             }
     211             : 
     212           0 :             const bool has_contained_children = false;  /* this diagram type does not embrace children */
     213           0 :             pencil_classifier_composer_set_envelope_box( &((*this_).classifier_composer),
     214             :                                                          &envelope_box,
     215             :                                                          has_contained_children,
     216             :                                                          (*this_).profile,
     217             :                                                          (*this_).pencil_size,
     218             :                                                          font_layout,
     219             :                                                          visible_classifier1
     220             :                                                        );
     221             : 
     222           0 :             geometry_rectangle_destroy( &envelope_box );
     223             :         }
     224             :     }
     225           0 :     assert( c_count
     226             :             == universal_array_index_sorter_get_count( &sorted_notes_reqs )
     227             :             + universal_array_index_sorter_get_count( &sorted_diag_refs )
     228             :             + universal_array_index_sorter_get_count( &sorted_acting_classifiers )
     229             :           );
     230             : 
     231             :     /* layout acting classifiers */
     232           0 :     pencil_classifier_1d_layouter_private_layout_horizontal( this_,
     233             :                                                              &sorted_acting_classifiers,
     234             :                                                              &left_area,
     235             :                                                              GEOMETRY_V_ALIGN_TOP
     236             :                                                            );
     237             :     /* layout digram references */
     238           0 :     pencil_classifier_1d_layouter_private_linear_vertical( this_,
     239             :                                                            &sorted_diag_refs,
     240             :                                                            &left_area,
     241             :                                                            GEOMETRY_H_ALIGN_LEFT
     242             :                                                          );
     243             :     /* layout notes/comments and requirements */
     244           0 :     pencil_classifier_1d_layouter_private_linear_vertical( this_,
     245             :                                                            &sorted_notes_reqs,
     246             :                                                            &right_column,
     247             :                                                            GEOMETRY_H_ALIGN_RIGHT
     248             :                                                          );
     249             : 
     250             :     /* cleanup sorted array indices and area-rectangles */
     251           0 :     universal_array_index_sorter_destroy( &sorted_acting_classifiers );
     252           0 :     universal_array_index_sorter_destroy( &sorted_diag_refs );
     253           0 :     universal_array_index_sorter_destroy( &sorted_notes_reqs );
     254           0 :     geometry_rectangle_destroy( &right_column );
     255           0 :     geometry_rectangle_destroy( &left_area );
     256           0 :     geometry_rectangle_destroy( &draw_area );
     257             : 
     258           0 :     U8_TRACE_END();
     259           0 : }
     260             : 
     261           0 : void pencil_classifier_1d_layouter_layout_for_timing( pencil_classifier_1d_layouter_t *this_, PangoLayout *font_layout )
     262             : {
     263           0 :     U8_TRACE_BEGIN();
     264             : 
     265             :     /* get preferred object distance */
     266           0 :     const double obj_dist = pencil_size_get_preferred_object_distance( (*this_).pencil_size );
     267             :     /* const double gap = pencil_size_get_standard_object_border( (*this_).pencil_size ); */
     268             : 
     269             :     /* get the diagram coordinates */
     270             :     geometry_rectangle_t draw_area;
     271           0 :     geometry_rectangle_copy( &draw_area, (*this_).diagram_draw_area );
     272           0 :     geometry_rectangle_shift( &draw_area, obj_dist, 0.0 );
     273           0 :     geometry_rectangle_enlarge( &draw_area, (-2.0 * obj_dist), (- obj_dist) );
     274           0 :     const double diag_w = geometry_rectangle_get_width( &draw_area );
     275           0 :     const double diag_h = geometry_rectangle_get_height( &draw_area );
     276             : 
     277           0 :     const double phi = 1.6180339; /* minor=0.618, major=1.0, sum=1.618 => (sum/major)==(major/minor) */
     278           0 :     const double minor_ratio = (1.0 - 0.6180339);
     279           0 :     const double golden_ratio_width = diag_w/phi;
     280           0 :     const double golden_ratio_height = diag_h/phi;
     281           0 :     const double minor_minor_width = diag_w * minor_ratio * minor_ratio;
     282           0 :     const double minor_minor_height = diag_h * minor_ratio * minor_ratio;
     283             : 
     284             :     geometry_rectangle_t top_row;
     285           0 :     geometry_rectangle_copy( &top_row, &draw_area );
     286           0 :     geometry_rectangle_shift( &top_row, minor_minor_width, 0.0 );
     287           0 :     geometry_rectangle_enlarge( &top_row, (- minor_minor_width), (minor_minor_width-diag_h) );
     288             : 
     289             :     geometry_rectangle_t center_area;
     290           0 :     geometry_rectangle_copy( &center_area, &draw_area );
     291           0 :     geometry_rectangle_shift( &center_area, 0.0, minor_minor_height );
     292           0 :     geometry_rectangle_enlarge( &center_area, 0.0, (- minor_minor_height) );
     293             : 
     294             :     /* sort the classifiers according to their list_order */
     295             :     universal_array_index_sorter_t sorted_notes_reqs;
     296           0 :     universal_array_index_sorter_init( &sorted_notes_reqs );
     297             :     universal_array_index_sorter_t sorted_acting_classifiers;
     298           0 :     universal_array_index_sorter_init( &sorted_acting_classifiers );
     299             : 
     300             :     /* calculate preferred classifier bounds */
     301           0 :     const uint_fast32_t c_count = layout_visible_set_get_visible_classifier_count( (*this_).layout_data );
     302           0 :     for ( uint_fast32_t plain_idx = 0; plain_idx < c_count; plain_idx ++ )
     303             :     {
     304             :         layout_visible_classifier_t *const visible_classifier1
     305           0 :             = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, plain_idx );
     306             :         const data_visible_classifier_t *const visible_classifier_data
     307           0 :             = layout_visible_classifier_get_data_const ( visible_classifier1 );
     308           0 :         const data_classifier_t *const classifier1 = data_visible_classifier_get_classifier_const( visible_classifier_data );
     309           0 :         const data_classifier_type_t c1_type = data_classifier_get_main_type ( classifier1 );
     310             : 
     311             :         /* check classifier type and sort into corresponding list */
     312             :         {
     313           0 :             int insert_err = 0;
     314           0 :             const double weight = (const double) data_classifier_get_list_order( classifier1 );
     315             :             const bool c1_type_is_scenario
     316           0 :                 = data_rules_classifier_has_scenario_semantics( &((*this_).rules),
     317             :                                                                 DATA_DIAGRAM_TYPE_UML_TIMING_DIAGRAM,
     318             :                                                                 c1_type
     319             :                                                               );
     320           0 :             if ( ! c1_type_is_scenario )
     321             :             {
     322           0 :                 insert_err = universal_array_index_sorter_insert( &sorted_notes_reqs, plain_idx, weight );
     323             :             }
     324             :             else
     325             :             {
     326           0 :                 insert_err = universal_array_index_sorter_insert( &sorted_acting_classifiers, plain_idx, weight );
     327             :             }
     328           0 :             if ( 0 != insert_err )
     329             :             {
     330           0 :                 U8_LOG_ERROR ( "universal_array_index_sorter_t list is full." );
     331             :             }
     332             :         }
     333             : 
     334             :         /* set the preferred bounds, space and label_box of the classifier layout */
     335             :         {
     336             :             geometry_rectangle_t envelope_box;
     337           0 :             geometry_rectangle_init( &envelope_box, 0.0, 0.0, ((diag_w-golden_ratio_width)/2.0), (golden_ratio_height/c_count) );
     338             : 
     339           0 :             const bool has_contained_children = false;  /* this diagram type does not embrace children */
     340           0 :             pencil_classifier_composer_set_envelope_box( &((*this_).classifier_composer),
     341             :                                                          &envelope_box,
     342             :                                                          has_contained_children,
     343             :                                                          (*this_).profile,
     344             :                                                          (*this_).pencil_size,
     345             :                                                          font_layout,
     346             :                                                          visible_classifier1
     347             :                                                        );
     348             : 
     349           0 :             geometry_rectangle_destroy( &envelope_box );
     350             :         }
     351             :     }
     352           0 :     assert( c_count
     353             :             == universal_array_index_sorter_get_count( &sorted_notes_reqs )
     354             :             + universal_array_index_sorter_get_count( &sorted_acting_classifiers )
     355             :           );
     356             : 
     357             :     /* layout acting classifiers */
     358           0 :     pencil_classifier_1d_layouter_private_layout_vertical( this_,
     359             :                                                            &sorted_acting_classifiers,
     360             :                                                            &center_area,
     361             :                                                            GEOMETRY_H_ALIGN_LEFT
     362             :                                                          );
     363             :     /* layout notes/comments and requirements */
     364           0 :     pencil_classifier_1d_layouter_private_linear_horizontal( this_,
     365             :                                                              &sorted_notes_reqs,
     366             :                                                              &top_row,
     367             :                                                              GEOMETRY_V_ALIGN_TOP
     368             :                                                            );
     369             : 
     370             :     /* cleanup sorted array indices and area-rectangles */
     371           0 :     universal_array_index_sorter_destroy( &sorted_acting_classifiers );
     372           0 :     universal_array_index_sorter_destroy( &sorted_notes_reqs );
     373           0 :     geometry_rectangle_destroy( &center_area );
     374           0 :     geometry_rectangle_destroy( &top_row );
     375           0 :     geometry_rectangle_destroy( &draw_area );
     376             : 
     377           0 :     U8_TRACE_END();
     378           0 : }
     379             : 
     380           0 : void pencil_classifier_1d_layouter_private_layout_horizontal( const pencil_classifier_1d_layouter_t *this_,
     381             :                                                               const universal_array_index_sorter_t *classifier_list,
     382             :                                                               const geometry_rectangle_t *dest_rect,
     383             :                                                               geometry_v_align_t v_alignment )
     384             : {
     385           0 :     U8_TRACE_BEGIN();
     386             : 
     387             :     /* get the destination rectangle coordinates */
     388           0 :     const double diag_x = geometry_rectangle_get_left( dest_rect );
     389           0 :     const double diag_w = geometry_rectangle_get_width( dest_rect );
     390             : 
     391             :     /* calculate sum of wished envelope widths */
     392           0 :     double total_wish_width = 0.0;
     393             :     layout_visible_classifier_iter_t classifer_iterator;
     394           0 :     layout_visible_classifier_iter_init( &classifer_iterator, (*this_).layout_data, classifier_list );
     395           0 :     while( layout_visible_classifier_iter_has_next( &classifer_iterator ) )
     396             :     {
     397             :         const layout_visible_classifier_t *const visible_classifier1
     398           0 :             = layout_visible_classifier_iter_next_ptr( &classifer_iterator );
     399             : 
     400             :         /* update sum of wished envelope widths */
     401             :         const geometry_rectangle_t envelope
     402           0 :             = layout_visible_classifier_get_envelope_box( visible_classifier1 );
     403           0 :         total_wish_width += geometry_rectangle_get_width( &envelope );
     404             :     }
     405           0 :     layout_visible_classifier_iter_destroy( &classifer_iterator );
     406           0 :     const uint_fast32_t count_classifiers = universal_array_index_sorter_get_count ( classifier_list );
     407           0 :     const double dx_spaces = (count_classifiers==0) ? diag_w : ((diag_w - total_wish_width)/count_classifiers);
     408             : 
     409             :     /* update the classifier coordinates */
     410           0 :     double current_x = diag_x;
     411           0 :     layout_visible_classifier_iter_init( &classifer_iterator, (*this_).layout_data, classifier_list );
     412           0 :     while( layout_visible_classifier_iter_has_next( &classifer_iterator ) )
     413             :     {
     414             :         layout_visible_classifier_t *const visible_classifier2
     415           0 :             = layout_visible_classifier_iter_next_ptr( &classifer_iterator );
     416             : 
     417             :         const geometry_rectangle_t envelope
     418           0 :             = layout_visible_classifier_get_envelope_box( visible_classifier2 );
     419           0 :         const double envelope_top = geometry_rectangle_get_top( &envelope );
     420           0 :         const double envelope_height = geometry_rectangle_get_height( &envelope );
     421           0 :         const double envelope_left = geometry_rectangle_get_left( &envelope );
     422           0 :         const double envelope_width = geometry_rectangle_get_width( &envelope );
     423             : 
     424           0 :         const double dest_top = geometry_v_align_get_top( &v_alignment,
     425             :                                                           envelope_height,
     426             :                                                           geometry_rectangle_get_top( dest_rect ),
     427             :                                                           geometry_rectangle_get_height( dest_rect )
     428             :                                                         );
     429           0 :         const double delta_y = dest_top - envelope_top;
     430             : 
     431           0 :         if ( dx_spaces > 0.0 )
     432             :         {
     433             :             /* equal spaces if there are spaces */
     434           0 :             const double delta_x = current_x + (dx_spaces/2.0) - envelope_left;
     435           0 :             const geometry_offset_t offset = geometry_offset_new( delta_x, delta_y );
     436             : 
     437           0 :             layout_visible_classifier_shift( visible_classifier2, &offset );
     438             : 
     439           0 :             current_x += dx_spaces + envelope_width;
     440             :         }
     441             :         else
     442             :         {
     443             :             /* const double wish2avail_ratio = (diag_h == 0.0) ? 1.0 : (total_wish_width/diag_h); */
     444           0 :             const double avail2wish_ratio = (total_wish_width == 0.0) ? 1.0 : (diag_w/total_wish_width);
     445           0 :             const double available_width = envelope_width * avail2wish_ratio;
     446           0 :             const uint32_t position = layout_visible_classifier_iter_count_processed( &classifer_iterator ) - 1;
     447           0 :             const double x_align_ratio = (count_classifiers==1) ? 0.5 : position / ( count_classifiers - 1.0 );
     448           0 :             const double x_align_envelope = envelope_width * x_align_ratio;
     449           0 :             const double x_align_available = available_width * x_align_ratio;
     450             : 
     451           0 :             const double delta_x = (current_x+x_align_available) - (envelope_left+x_align_envelope);
     452           0 :             const geometry_offset_t offset = geometry_offset_new( delta_x, delta_y );
     453             : 
     454           0 :             layout_visible_classifier_shift( visible_classifier2, &offset );
     455             : 
     456           0 :             current_x += available_width;
     457             :         }
     458             :     }
     459           0 :     layout_visible_classifier_iter_destroy( &classifer_iterator );
     460             : 
     461           0 :     U8_TRACE_END();
     462           0 : }
     463             : 
     464           0 : void pencil_classifier_1d_layouter_private_layout_vertical( const pencil_classifier_1d_layouter_t *this_,
     465             :                                                             const universal_array_index_sorter_t *classifier_list,
     466             :                                                             const geometry_rectangle_t *dest_rect,
     467             :                                                             geometry_h_align_t h_alignment )
     468             : {
     469           0 :     U8_TRACE_BEGIN();
     470             : 
     471             :     /* get the destination rectangle coordinates */
     472           0 :     const double diag_y = geometry_rectangle_get_top( dest_rect );
     473           0 :     const double diag_h = geometry_rectangle_get_height( dest_rect );
     474             : 
     475             :     /* calculate sum of wished envelope heights */
     476           0 :     double total_wish_height = 0.0;
     477             :     layout_visible_classifier_iter_t classifer_iterator;
     478           0 :     layout_visible_classifier_iter_init( &classifer_iterator, (*this_).layout_data, classifier_list );
     479           0 :     while( layout_visible_classifier_iter_has_next( &classifer_iterator ) )
     480             :     {
     481             :         const layout_visible_classifier_t *const visible_classifier1
     482           0 :             = layout_visible_classifier_iter_next_ptr( &classifer_iterator );
     483             : 
     484             :         /* update sum of wished envelope heights */
     485             :         const geometry_rectangle_t envelope
     486           0 :             = layout_visible_classifier_get_envelope_box( visible_classifier1 );
     487           0 :         total_wish_height += geometry_rectangle_get_height( &envelope );
     488             :     }
     489           0 :     layout_visible_classifier_iter_destroy( &classifer_iterator );
     490           0 :     const uint_fast32_t count_classifiers = universal_array_index_sorter_get_count ( classifier_list );
     491           0 :     const double dy_spaces = (count_classifiers==0) ? diag_h : ((diag_h - total_wish_height)/count_classifiers);
     492             : 
     493             :     /* update the classifier coordinates */
     494           0 :     double current_y = diag_y;
     495           0 :     layout_visible_classifier_iter_init( &classifer_iterator, (*this_).layout_data, classifier_list );
     496           0 :     while( layout_visible_classifier_iter_has_next( &classifer_iterator ) )
     497             :     {
     498             :         layout_visible_classifier_t *const visible_classifier2
     499           0 :             = layout_visible_classifier_iter_next_ptr( &classifer_iterator );
     500             : 
     501             :         const geometry_rectangle_t envelope
     502           0 :             = layout_visible_classifier_get_envelope_box( visible_classifier2 );
     503           0 :         const double envelope_top = geometry_rectangle_get_top( &envelope );
     504           0 :         const double envelope_height = geometry_rectangle_get_height( &envelope );
     505           0 :         const double envelope_left = geometry_rectangle_get_left( &envelope );
     506           0 :         const double envelope_width = geometry_rectangle_get_width( &envelope );
     507             : 
     508           0 :         const double dest_left = geometry_h_align_get_left( &h_alignment,
     509             :                                                             envelope_width,
     510             :                                                             geometry_rectangle_get_left( dest_rect ),
     511             :                                                             geometry_rectangle_get_width( dest_rect )
     512             :                                                           );
     513           0 :         const double delta_x = dest_left - envelope_left;
     514             : 
     515           0 :         if ( dy_spaces > 0.0 )
     516             :         {
     517             :             /* equal spaces if there are spaces */
     518           0 :             const double delta_y = current_y + (dy_spaces/2.0) - envelope_top;
     519           0 :             const geometry_offset_t offset = geometry_offset_new( delta_x, delta_y );
     520             : 
     521           0 :             layout_visible_classifier_shift( visible_classifier2, &offset );
     522             : 
     523           0 :             current_y += dy_spaces + envelope_height;
     524             :         }
     525             :         else
     526             :         {
     527             :             /* keep available-to-wish ratio if classifiers overlap */
     528             :             /* const double wish2avail_ratio = (diag_h == 0.0) ? 1.0 : (total_wish_height/diag_h); */
     529           0 :             const double avail2wish_ratio = (total_wish_height == 0.0) ? 1.0 : (diag_h/total_wish_height);
     530           0 :             const double available_height = envelope_height * avail2wish_ratio;
     531           0 :             const uint32_t position = layout_visible_classifier_iter_count_processed( &classifer_iterator ) - 1;
     532           0 :             const double y_align_ratio = (count_classifiers==1) ? 0.5 : position / ( count_classifiers - 1.0 );
     533           0 :             const double y_align_envelope = envelope_height * y_align_ratio;
     534           0 :             const double y_align_available = available_height * y_align_ratio;
     535             : 
     536           0 :             const double delta_y = (current_y+y_align_available) - (envelope_top+y_align_envelope);
     537           0 :             const geometry_offset_t offset = geometry_offset_new( delta_x, delta_y );
     538             : 
     539           0 :             layout_visible_classifier_shift( visible_classifier2, &offset );
     540             : 
     541           0 :             current_y += available_height;
     542             :         }
     543             :     }
     544           0 :     layout_visible_classifier_iter_destroy( &classifer_iterator );
     545             : 
     546           0 :     U8_TRACE_END();
     547           0 : }
     548             : 
     549           0 : void pencil_classifier_1d_layouter_private_linear_horizontal( const pencil_classifier_1d_layouter_t *this_,
     550             :                                                               const universal_array_index_sorter_t *classifier_list,
     551             :                                                               const geometry_rectangle_t *dest_rect,
     552             :                                                               geometry_v_align_t v_alignment )
     553             : {
     554           0 :     U8_TRACE_BEGIN();
     555             : 
     556             :     /* get the destination rectangle coordinates */
     557           0 :     const double diag_x = geometry_rectangle_get_left( (*this_).diagram_draw_area );
     558           0 :     const double diag_w = geometry_rectangle_get_width( (*this_).diagram_draw_area );
     559           0 :     const double dest_left = geometry_rectangle_get_left( dest_rect );
     560           0 :     const double dest_right = geometry_rectangle_get_right( dest_rect );
     561             : 
     562             :     /* update the classifier coordinates */
     563             :     layout_visible_classifier_iter_t classifer_iterator;
     564           0 :     layout_visible_classifier_iter_init( &classifer_iterator, (*this_).layout_data, classifier_list );
     565           0 :     while( layout_visible_classifier_iter_has_next( &classifer_iterator ) )
     566             :     {
     567             :         layout_visible_classifier_t *const visible_classifier2
     568           0 :             = layout_visible_classifier_iter_next_ptr( &classifer_iterator );
     569             : 
     570             :         /* get envelope */
     571             :         const geometry_rectangle_t envelope
     572           0 :             = layout_visible_classifier_get_envelope_box( visible_classifier2 );
     573           0 :         const double envelope_top = geometry_rectangle_get_top( &envelope );
     574           0 :         const double envelope_height = geometry_rectangle_get_height( &envelope );
     575           0 :         const double envelope_left = geometry_rectangle_get_left( &envelope );
     576           0 :         const double envelope_width = geometry_rectangle_get_width( &envelope );
     577             : 
     578             :         /* calc x */
     579             :         const data_visible_classifier_t *const visible_classifier_data
     580           0 :             = layout_visible_classifier_get_data_const ( visible_classifier2 );
     581           0 :         const data_classifier_t *const classifier2 = data_visible_classifier_get_classifier_const( visible_classifier_data );
     582           0 :         const int32_t list_order = data_classifier_get_list_order( classifier2 );
     583           0 :         const double x_value_rel = (list_order/((double)UINT32_MAX))+0.5;
     584           0 :         double new_left = diag_x + (diag_w-envelope_width)*x_value_rel;
     585           0 :         if ( (new_left+envelope_width) > dest_right )
     586             :         {
     587           0 :             new_left = dest_right - envelope_width;
     588             :         }
     589           0 :         if ( new_left < dest_left )
     590             :         {
     591           0 :             new_left = dest_left;
     592             :         }
     593           0 :         const double delta_x = new_left - envelope_left;
     594             : 
     595             :         /* calc y */
     596           0 :         const double dest_top = geometry_v_align_get_top( &v_alignment,
     597             :                                                           envelope_height,
     598             :                                                           geometry_rectangle_get_top( dest_rect ),
     599             :                                                           geometry_rectangle_get_height( dest_rect )
     600             :                                                         );
     601           0 :         const double delta_y = dest_top - envelope_top;
     602           0 :         const geometry_offset_t offset = geometry_offset_new( delta_x, delta_y );
     603             : 
     604           0 :         layout_visible_classifier_shift( visible_classifier2, &offset );
     605             :     }
     606           0 :     layout_visible_classifier_iter_destroy( &classifer_iterator );
     607             : 
     608           0 :     U8_TRACE_END();
     609           0 : }
     610             : 
     611           0 : void pencil_classifier_1d_layouter_private_linear_vertical( const pencil_classifier_1d_layouter_t *this_,
     612             :                                                             const universal_array_index_sorter_t *classifier_list,
     613             :                                                             const geometry_rectangle_t *dest_rect,
     614             :                                                             geometry_h_align_t h_alignment )
     615             : {
     616           0 :     U8_TRACE_BEGIN();
     617             : 
     618             :     /* get the destination rectangle coordinates */
     619           0 :     const double diag_y = geometry_rectangle_get_top( (*this_).diagram_draw_area );
     620           0 :     const double diag_h = geometry_rectangle_get_height( (*this_).diagram_draw_area );
     621           0 :     const double dest_top = geometry_rectangle_get_top( dest_rect );
     622           0 :     const double dest_bottom = geometry_rectangle_get_bottom( dest_rect );
     623             : 
     624             :     /* update the classifier coordinates */
     625             :     layout_visible_classifier_iter_t classifer_iterator;
     626           0 :     layout_visible_classifier_iter_init( &classifer_iterator, (*this_).layout_data, classifier_list );
     627           0 :     while( layout_visible_classifier_iter_has_next( &classifer_iterator ) )
     628             :     {
     629             :         layout_visible_classifier_t *const visible_classifier2
     630           0 :             = layout_visible_classifier_iter_next_ptr( &classifer_iterator );
     631             : 
     632             :         /* get envelope */
     633             :         const geometry_rectangle_t envelope
     634           0 :             = layout_visible_classifier_get_envelope_box( visible_classifier2 );
     635           0 :         const double envelope_top = geometry_rectangle_get_top( &envelope );
     636           0 :         const double envelope_height = geometry_rectangle_get_height( &envelope );
     637           0 :         const double envelope_left = geometry_rectangle_get_left( &envelope );
     638           0 :         const double envelope_width = geometry_rectangle_get_width( &envelope );
     639             : 
     640             :         /* calc x */
     641           0 :         const double dest_left = geometry_h_align_get_left( &h_alignment,
     642             :                                                             envelope_width,
     643             :                                                             geometry_rectangle_get_left( dest_rect ),
     644             :                                                             geometry_rectangle_get_width( dest_rect )
     645             :                                                           );
     646           0 :         const double delta_x = dest_left - envelope_left;
     647             : 
     648             :         /* calc y */
     649             :         const data_visible_classifier_t *const visible_classifier_data
     650           0 :             = layout_visible_classifier_get_data_const ( visible_classifier2 );
     651           0 :         const data_classifier_t *const classifier2 = data_visible_classifier_get_classifier_const( visible_classifier_data );
     652           0 :         const int32_t list_order = data_classifier_get_list_order( classifier2 );
     653           0 :         const double y_value_rel = (list_order/((double)UINT32_MAX))+0.5;
     654           0 :         double new_top = diag_y + (diag_h-envelope_height)*y_value_rel;
     655           0 :         if ( (new_top+envelope_height) > dest_bottom )
     656             :         {
     657           0 :             new_top = dest_bottom - envelope_height;
     658             :         }
     659           0 :         if ( new_top < dest_top )
     660             :         {
     661           0 :             new_top = dest_top;
     662             :         }
     663           0 :         const double delta_y = new_top - envelope_top;
     664           0 :         const geometry_offset_t offset = geometry_offset_new( delta_x, delta_y );
     665             : 
     666           0 :         layout_visible_classifier_shift( visible_classifier2, &offset );
     667             : 
     668             :     }
     669           0 :     layout_visible_classifier_iter_destroy( &classifer_iterator );
     670             : 
     671           0 :     U8_TRACE_END();
     672           0 : }
     673             : 
     674             : 
     675             : /*
     676             : Copyright 2017-2025 Andreas Warnke
     677             : 
     678             : Licensed under the Apache License, Version 2.0 (the "License");
     679             : you may not use this file except in compliance with the License.
     680             : You may obtain a copy of the License at
     681             : 
     682             :     http://www.apache.org/licenses/LICENSE-2.0
     683             : 
     684             : Unless required by applicable law or agreed to in writing, software
     685             : distributed under the License is distributed on an "AS IS" BASIS,
     686             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     687             : See the License for the specific language governing permissions and
     688             : limitations under the License.
     689             : */

Generated by: LCOV version 1.16