LCOV - code coverage report
Current view: top level - pencil/source - pencil_feat_label_layouter.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 0 110 0.0 %
Date: 2024-10-26 21:44:38 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /* File: pencil_feat_label_layouter.c; Copyright and License: see below */
       2             : 
       3             : #include "pencil_feat_label_layouter.h"
       4             : #include "u8/u8_trace.h"
       5             : #include "utf8stringbuf/utf8string.h"
       6             : 
       7           0 : void pencil_feat_label_layouter_init( pencil_feat_label_layouter_t *this_,
       8             :                                       layout_visible_set_t *layout_data,
       9             :                                       const data_profile_part_t *profile,
      10             :                                       const pencil_size_t *pencil_size )
      11             : {
      12           0 :     U8_TRACE_BEGIN();
      13           0 :     assert( NULL != layout_data );
      14           0 :     assert( NULL != profile );
      15           0 :     assert( NULL != pencil_size );
      16             : 
      17           0 :     (*this_).layout_data = layout_data;
      18           0 :     (*this_).profile = profile;
      19           0 :     (*this_).pencil_size = pencil_size;
      20           0 :     draw_feature_label_init( &((*this_).draw_feature_label) );
      21           0 :     pencil_label_layout_helper_init ( &((*this_).label_layout_helper) );
      22             : 
      23           0 :     U8_TRACE_END();
      24           0 : }
      25             : 
      26           0 : void pencil_feat_label_layouter_reinit( pencil_feat_label_layouter_t *this_,
      27             :                                         layout_visible_set_t *layout_data,
      28             :                                         const data_profile_part_t *profile,
      29             :                                         const pencil_size_t *pencil_size )
      30             : {
      31           0 :     U8_TRACE_BEGIN();
      32           0 :     assert( NULL != layout_data );
      33           0 :     assert( NULL != profile );
      34           0 :     assert( NULL != pencil_size );
      35             : 
      36           0 :     (*this_).layout_data = layout_data;
      37           0 :     (*this_).profile = profile;
      38           0 :     (*this_).pencil_size = pencil_size;
      39             : 
      40           0 :     U8_TRACE_END();
      41           0 : }
      42             : 
      43           0 : void pencil_feat_label_layouter_destroy( pencil_feat_label_layouter_t *this_ )
      44             : {
      45           0 :     U8_TRACE_BEGIN();
      46             : 
      47           0 :     pencil_label_layout_helper_destroy ( &((*this_).label_layout_helper) );
      48           0 :     draw_feature_label_destroy( &((*this_).draw_feature_label) );
      49             : 
      50           0 :     U8_TRACE_END();
      51           0 : }
      52             : 
      53           0 : void pencil_feat_label_layouter_do_layout ( pencil_feat_label_layouter_t *this_, PangoLayout *font_layout )
      54             : {
      55           0 :     U8_TRACE_BEGIN();
      56             :     assert ( (unsigned int) UNIVERSAL_ARRAY_INDEX_SORTER_MAX_ARRAY_SIZE >= (unsigned int) LAYOUT_VISIBLE_SET_MAX_FEATURES );
      57           0 :     assert( NULL != font_layout );
      58             : 
      59             :     universal_array_index_sorter_t sorted;
      60           0 :     universal_array_index_sorter_init( &sorted );
      61             : 
      62             :     /* sort the features by their label-box layouting needs, drop invisible relations */
      63           0 :     pencil_feat_label_layouter_private_propose_processing_order ( this_, &sorted );
      64             : 
      65             :     /* layout the features label-boxes */
      66             :     const uint32_t count_sorted
      67           0 :         = universal_array_index_sorter_get_count( &sorted );
      68           0 :     for ( uint32_t sort_index = 0; sort_index < count_sorted; sort_index ++ )
      69             :     {
      70             :         /* determine pointer to feature */
      71             :         const uint32_t index
      72           0 :             = universal_array_index_sorter_get_array_index( &sorted, sort_index );
      73             :         layout_feature_t *current_feature;
      74           0 :         current_feature = layout_visible_set_get_feature_ptr( (*this_).layout_data, index );
      75           0 :         geometry_point_t feature_middle = layout_feature_get_symbol_middle ( current_feature );
      76             : 
      77             :         /* declaration of list of options */
      78           0 :         uint32_t solutions_count = 0;
      79             :         static const uint32_t SOLUTIONS_MAX = 8;
      80             :         geometry_rectangle_t solution[8];
      81             : 
      82             :         /* propose options */
      83           0 :         pencil_feat_label_layouter_private_propose_solutions ( this_,
      84             :                                                                current_feature,
      85             :                                                                font_layout,
      86             :                                                                SOLUTIONS_MAX,
      87             :                                                                solution,
      88             :                                                                &solutions_count
      89             :                                                              );
      90             : 
      91             :         /* select best option */
      92             :         uint32_t index_of_best;
      93           0 :         if ( 1 == solutions_count )
      94             :         {
      95           0 :             index_of_best = 0;
      96             :         }
      97             :         else
      98             :         {
      99           0 :             pencil_label_layout_helper_select_solution ( &((*this_).label_layout_helper),
     100             :                                                          (*this_).layout_data,
     101             :                                                          feature_middle,
     102             :                                                          solutions_count,
     103             :                                                          solution,
     104             :                                                          &index_of_best
     105             :                                                        );
     106             :         }
     107             : 
     108             :         /* store best option to (*this_).layout_data */
     109           0 :         layout_feature_set_label_box( current_feature, &(solution[index_of_best]) );
     110             :     }
     111             : 
     112           0 :     universal_array_index_sorter_destroy( &sorted );
     113             : 
     114           0 :     U8_TRACE_END();
     115           0 : }
     116             : 
     117           0 : void pencil_feat_label_layouter_private_propose_processing_order ( pencil_feat_label_layouter_t *this_, universal_array_index_sorter_t *out_sorted )
     118             : {
     119           0 :     U8_TRACE_BEGIN();
     120           0 :     assert( NULL != out_sorted );
     121             : 
     122             :     /* sort the features by their label-box: the less simple, the earlier it shall be processed */
     123             :     const uint32_t count_features
     124           0 :         = layout_visible_set_get_feature_count ( (*this_).layout_data );
     125           0 :     for ( uint32_t index = 0; index < count_features; index ++ )
     126             :     {
     127             :         const layout_feature_t *const current_feature
     128           0 :             = layout_visible_set_get_feature_ptr ( (*this_).layout_data, index );
     129           0 :         const data_feature_t *const feature_data = layout_feature_get_data_const ( current_feature );
     130           0 :         assert( NULL != feature_data );
     131           0 :         const data_feature_type_t current_type = data_feature_get_main_type( feature_data );
     132             : 
     133           0 :         int64_t simpleness = 0;
     134             : 
     135             :         /* determine simpleness by length of label */
     136           0 :         simpleness -= utf8string_get_length( data_feature_get_key_const( feature_data ) );
     137           0 :         simpleness -= utf8string_get_length( data_feature_get_value_const( feature_data ) );
     138             : 
     139             :         /* do the properties and operations first, they have a fixed positiion given by the classifier */
     140           0 :         if ( ! data_feature_type_outside_compartment( current_type ) )
     141             :         {
     142           0 :             simpleness = -100000;
     143             :         }
     144             : 
     145             :         /* insert relation to sorted array - except for lifelines which have no label */
     146           0 :         if ( DATA_FEATURE_TYPE_LIFELINE != current_type )
     147             :         {
     148             :             const int insert_error
     149           0 :                 = universal_array_index_sorter_insert( out_sorted, index, simpleness );
     150           0 :             if ( 0 != insert_error )
     151             :             {
     152           0 :                 U8_LOG_WARNING( "not all relationship label-boxes are layouted" );
     153             :             }
     154             :         }
     155             :     }
     156             : 
     157           0 :     U8_TRACE_END();
     158           0 : }
     159             : 
     160           0 : void pencil_feat_label_layouter_private_propose_solutions ( pencil_feat_label_layouter_t *this_,
     161             :                                                             layout_feature_t *current_feature,
     162             :                                                             PangoLayout *font_layout,
     163             :                                                             uint32_t solutions_max,
     164             :                                                             geometry_rectangle_t out_solutions[],
     165             :                                                             uint32_t *out_solutions_count )
     166             : {
     167           0 :     U8_TRACE_BEGIN();
     168           0 :     assert( NULL != current_feature );
     169           0 :     assert( NULL != font_layout );
     170           0 :     assert( NULL != out_solutions );
     171           0 :     assert( NULL != out_solutions_count );
     172             : 
     173           0 :     const data_feature_t *feature_data = layout_feature_get_data_const ( current_feature );
     174           0 :     assert( NULL != feature_data );
     175           0 :     const data_feature_type_t current_type = data_feature_get_main_type( feature_data );
     176             : 
     177           0 :     if ( data_feature_type_inside_compartment( current_type ) )
     178             :     {
     179             :         /* the label-box is already calculated by pencil_feature_layouter_do_layout() */
     180             :         /* which is called before pencil_feat_label_layouter_do_layout() */
     181           0 :         assert( solutions_max >= 1 );
     182           0 :         geometry_rectangle_copy( &(out_solutions[0]), layout_feature_get_label_box_const ( current_feature ) );
     183           0 :         *out_solutions_count = 1;
     184             :     }
     185             :     else
     186             :     {
     187             :         /* key and value dimensions */
     188           0 :         const geometry_dimensions_t label_dim_proposal = {
     189           0 :             .width = 25.0 * pencil_size_get_standard_font_size( (*this_).pencil_size ),
     190           0 :             .height = pencil_size_get_standard_font_size( (*this_).pencil_size )
     191             :         };
     192             :         geometry_dimensions_t label_dim;
     193           0 :         draw_feature_label_get_key_and_value_dimensions( &((*this_).draw_feature_label),
     194             :                                                          feature_data,
     195             :                                                          (*this_).profile,
     196             :                                                          &label_dim_proposal,
     197             :                                                          (*this_).pencil_size,
     198             :                                                          font_layout,
     199             :                                                          &label_dim
     200             :                                                        );
     201           0 :         const double text_width = geometry_dimensions_get_width( &label_dim );
     202           0 :         const double text_height = geometry_dimensions_get_height( &label_dim );
     203           0 :         const double half_width = text_width/2.0;
     204           0 :         const double half_height = text_height/2.0;
     205             : 
     206           0 :         const double gap = pencil_size_get_standard_object_border( (*this_).pencil_size );
     207           0 :         const geometry_rectangle_t *const  bounds = layout_feature_get_symbol_box_const ( current_feature );
     208           0 :         const double left = geometry_rectangle_get_left( bounds );
     209           0 :         const double top = geometry_rectangle_get_top( bounds );
     210           0 :         const double center_x = geometry_rectangle_get_center_x( bounds );
     211           0 :         const double center_y = geometry_rectangle_get_center_y( bounds );
     212           0 :         const double bottom = geometry_rectangle_get_bottom( bounds );
     213           0 :         const double right = geometry_rectangle_get_right( bounds );
     214             : 
     215           0 :         assert( solutions_max >= 8 );
     216             :         /* top */
     217           0 :         geometry_rectangle_init( &(out_solutions[0]),
     218             :                                  center_x - half_width,
     219           0 :                                  top - text_height - gap,
     220             :                                  text_width,
     221             :                                  text_height
     222             :                                );
     223             :         /* bottom */
     224           0 :         geometry_rectangle_init( &(out_solutions[1]),
     225             :                                  center_x - half_width,
     226             :                                  bottom + gap,
     227             :                                  text_width,
     228             :                                  text_height
     229             :                                );
     230             :         /* left */
     231           0 :         geometry_rectangle_init( &(out_solutions[2]),
     232           0 :                                  left - text_width - gap,
     233             :                                  center_y - half_height,
     234             :                                  text_width,
     235             :                                  text_height
     236             :                                );
     237             :         /* right */
     238           0 :         geometry_rectangle_init( &(out_solutions[3]),
     239             :                                  right + gap,
     240             :                                  center_y - half_height,
     241             :                                  text_width,
     242             :                                  text_height
     243             :                                );
     244             :         /* top-left */
     245           0 :         geometry_rectangle_init( &(out_solutions[4]),
     246             :                                  left - text_width,
     247             :                                  top - text_height,
     248             :                                  text_width,
     249             :                                  text_height
     250             :                                );
     251             :         /* top-right */
     252           0 :         geometry_rectangle_init( &(out_solutions[5]),
     253             :                                  right,
     254             :                                  top - text_height,
     255             :                                  text_width,
     256             :                                  text_height
     257             :                                );
     258             :         /* bottom-left */
     259           0 :         geometry_rectangle_init( &(out_solutions[6]),
     260             :                                  left - text_width,
     261             :                                  bottom,
     262             :                                  text_width,
     263             :                                  text_height
     264             :                                );
     265             :         /* bottom-right */
     266           0 :         geometry_rectangle_init( &(out_solutions[7]),
     267             :                                  right,
     268             :                                  bottom,
     269             :                                  text_width,
     270             :                                  text_height
     271             :                                );
     272           0 :         *out_solutions_count = 8;
     273             :     }
     274             : 
     275           0 :     U8_TRACE_END();
     276           0 : }
     277             : 
     278             : 
     279             : /*
     280             :  * Copyright 2019-2024 Andreas Warnke
     281             :  *
     282             :  * Licensed under the Apache License, Version 2.0 (the "License");
     283             :  * you may not use this file except in compliance with the License.
     284             :  * You may obtain a copy of the License at
     285             :  *
     286             :  *    http://www.apache.org/licenses/LICENSE-2.0
     287             :  *
     288             :  * Unless required by applicable law or agreed to in writing, software
     289             :  * distributed under the License is distributed on an "AS IS" BASIS,
     290             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     291             :  * See the License for the specific language governing permissions and
     292             :  * limitations under the License.
     293             :  */

Generated by: LCOV version 1.16