LCOV - code coverage report
Current view: top level - pencil/source - pencil_classifier_composer.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 99.5 % 216 215
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /* File: pencil_classifier_composer.c; Copyright and License: see below */
       2              : 
       3              : #include "pencil_classifier_composer.h"
       4              : #include "u8/u8_trace.h"
       5              : #include "u8/u8_f64.h"
       6              : #include "utf8stringbuf/utf8stringbuf.h"
       7              : #include "utf8stringbuf/utf8string.h"
       8              : #include <pango/pangocairo.h>
       9              : #include <stdio.h>
      10              : #include <stdlib.h>
      11              : #include <assert.h>
      12              : 
      13            3 : void pencil_classifier_composer_init( pencil_classifier_composer_t *this_ )
      14              : {
      15            3 :     U8_TRACE_BEGIN();
      16              : 
      17            3 :     draw_classifier_icon_init( &((*this_).draw_classifier_icon) );
      18            3 :     draw_classifier_label_init( &((*this_).draw_classifier_label) );
      19            3 :     draw_classifier_contour_init( &((*this_).draw_classifier_contour) );
      20            3 :     draw_stereotype_icon_init( &((*this_).draw_stereotype_icon) );
      21              : 
      22            3 :     U8_TRACE_END();
      23            3 : }
      24              : 
      25            3 : void pencil_classifier_composer_destroy( pencil_classifier_composer_t *this_ )
      26              : {
      27            3 :     U8_TRACE_BEGIN();
      28              : 
      29            3 :     draw_classifier_icon_destroy( &((*this_).draw_classifier_icon) );
      30            3 :     draw_classifier_label_destroy( &((*this_).draw_classifier_label) );
      31            3 :     draw_classifier_contour_destroy( &((*this_).draw_classifier_contour) );
      32            3 :     draw_stereotype_icon_destroy( &((*this_).draw_stereotype_icon) );
      33              : 
      34            3 :     U8_TRACE_END();
      35            3 : }
      36              : 
      37          128 : int pencil_classifier_composer_expand_space( pencil_classifier_composer_t *this_,
      38              :                                              const geometry_rectangle_t *space,
      39              :                                              bool shows_contained_children,
      40              :                                              const data_profile_part_t *profile,
      41              :                                              const pencil_size_t *pencil_size,
      42              :                                              PangoLayout *font_layout,
      43              :                                              layout_visible_classifier_t *io_classifier_layout )
      44              : {
      45          128 :     U8_TRACE_BEGIN();
      46          128 :     assert( NULL != space );
      47          128 :     assert( NULL != pencil_size );
      48          128 :     assert( NULL != font_layout );
      49          128 :     assert( NULL != io_classifier_layout );
      50              : 
      51              :     /* get data that shall be layouted/composed */
      52              :     const data_visible_classifier_t *const visible_classifier
      53          128 :         = layout_visible_classifier_get_data_const( io_classifier_layout );
      54              :     const data_classifier_t *const classifier
      55          128 :         = data_visible_classifier_get_classifier_const( visible_classifier );
      56              :     const data_classifier_type_t classifier_type
      57          128 :         = data_classifier_get_main_type( classifier );
      58          128 :     const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
      59              :     const bool has_stereotype_icon
      60          128 :         = draw_stereotype_icon_exists( &((*this_).draw_stereotype_icon), classifier_stereotype, profile );
      61              : 
      62          128 :     U8_TRACE_INFO_INT("expanding bounds of classifier id:", data_classifier_get_row_id( classifier ) );
      63          128 :     U8_TRACE_INFO_INT_INT("expanding bounds of classifier type, children:", classifier_type, shows_contained_children?1:0 );
      64              : 
      65              :     /* determine border sizes of the main line (label and optionally icon) */
      66              :     geometry_rectangle_t label_rect;
      67          128 :     geometry_rectangle_init_empty( &label_rect );
      68              :     geometry_rectangle_t icon_rect;
      69          128 :     geometry_rectangle_init_empty( &icon_rect );
      70              :     geometry_rectangle_t label_compartment;
      71          128 :     geometry_rectangle_init_empty( &label_compartment );
      72          128 :     const geometry_rectangle_t *space_and_label_fake = space;  /* fake space_and_label to be identical to requested space */
      73              :     const int area_too_small
      74          128 :         = pencil_classifier_composer_private_get_label_box( this_,
      75              :                                                             visible_classifier,
      76              :                                                             shows_contained_children,
      77              :                                                             has_stereotype_icon,
      78              :                                                             space_and_label_fake,
      79              :                                                             pencil_size,
      80              :                                                             font_layout,
      81              :                                                             &label_rect,
      82              :                                                             &icon_rect,
      83              :                                                             &label_compartment
      84              :                                                           );
      85          128 :     if ( area_too_small != 0 )
      86              :     {
      87           64 :         U8_TRACE_INFO("new width is defined by label-and-icon, not by requested inner space" );
      88              :     }
      89              :     /* shift the label and icon because space_and_label was a fake; the top side is at space top instead of label top */
      90          128 :     const double delta_top = geometry_rectangle_get_bottom( &label_compartment ) - geometry_rectangle_get_top( space );
      91          128 :     geometry_rectangle_set_top( &label_rect, geometry_rectangle_get_top( &label_rect ) - delta_top );
      92          128 :     geometry_rectangle_set_top( &icon_rect, geometry_rectangle_get_top( &icon_rect ) - delta_top );
      93          128 :     geometry_rectangle_set_top( &label_compartment, geometry_rectangle_get_top( &label_compartment ) - delta_top );
      94              : 
      95              :     /* sizes of geometric objects are determined, */
      96              :     /* now position the geometric objects */
      97              :     {
      98              :         const bool has_contour
      99          128 :             = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     100              : 
     101          128 :         if ( has_contour )
     102              :         {
     103           92 :             U8_TRACE_INFO("calculating symbol box as envelope around label and space..." );
     104              : 
     105              :             /* calculate symbol bounds */
     106              :             geometry_rectangle_t inner_area;
     107           92 :             if ( area_too_small )
     108              :             {
     109           92 :                 geometry_rectangle_init( &inner_area,
     110              :                                          geometry_rectangle_get_left( &label_compartment ),
     111              :                                          geometry_rectangle_get_top( &label_compartment ),
     112              :                                          geometry_rectangle_get_width( &label_compartment ),
     113           46 :                                          geometry_rectangle_get_height( &label_compartment )
     114           46 :                                          + geometry_rectangle_get_height( space )
     115              :                                        );
     116              :             }
     117              :             else
     118              :             {
     119           46 :                 geometry_rectangle_copy( &inner_area, space );
     120           46 :                 geometry_rectangle_shift( &inner_area, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     121           46 :                 geometry_rectangle_enlarge( &inner_area, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     122              :             }
     123              :             const geometry_rectangle_t envelope
     124           92 :                 = draw_classifier_contour_calc_outer_bounds( &((*this_).draw_classifier_contour),
     125              :                                                              classifier_type,
     126              :                                                              &inner_area,
     127              :                                                              pencil_size
     128              :                                                            );
     129           92 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &envelope );
     130           92 :             geometry_rectangle_destroy( &inner_area );
     131              :         }
     132              :         else
     133              :         {
     134           36 :             U8_TRACE_INFO("calculating symbol box for fixed-sized icon..." );
     135              : 
     136           36 :             const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );
     137           36 :             const double symbol_width = symbol_height;
     138              : 
     139              :             /* calculate symbol bounds */
     140           36 :             const geometry_h_align_t H_CENTER = GEOMETRY_H_ALIGN_CENTER;
     141              :             const double symbol_left
     142           36 :                 = geometry_h_align_get_left( &H_CENTER,
     143              :                                              symbol_width,
     144              :                                              geometry_rectangle_get_left( space ),
     145              :                                              geometry_rectangle_get_width( space )
     146              :                                            );
     147           36 :             const double symbol_top = geometry_rectangle_get_top( &label_compartment ) - symbol_height;
     148              :             geometry_rectangle_t classifier_symbol_box;
     149           36 :             geometry_rectangle_init( &classifier_symbol_box, symbol_left, symbol_top, symbol_width, symbol_height );
     150           36 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &classifier_symbol_box );
     151           36 :             geometry_rectangle_destroy( &classifier_symbol_box );
     152              :         }
     153              : 
     154              :         /* calculate label_box */
     155          128 :         layout_visible_classifier_set_label_box( io_classifier_layout, &label_rect );
     156          128 :         layout_visible_classifier_set_label_anchor( io_classifier_layout,
     157              :                                                     GEOMETRY_H_ALIGN_CENTER,
     158              :                                                     GEOMETRY_V_ALIGN_TOP
     159              :                                                   );
     160              :         /* calculate icon_box */
     161          128 :         layout_visible_classifier_set_icon_box( io_classifier_layout, &icon_rect );
     162              : 
     163              :         /* calculate space */
     164              :         /* get the symbol and label boxes and inner space rectangles to modify */
     165              :         geometry_rectangle_t classifier_space;
     166          128 :         geometry_rectangle_init( &classifier_space,
     167              :                                  geometry_rectangle_get_left( &label_compartment ),
     168              :                                  geometry_rectangle_get_top( space ),
     169              :                                  geometry_rectangle_get_width( &label_compartment ),
     170              :                                  geometry_rectangle_get_height( space )
     171              :                                );
     172          128 :         layout_visible_classifier_set_space( io_classifier_layout, &classifier_space );
     173          128 :         geometry_rectangle_destroy( &classifier_space );
     174              :     }
     175              : 
     176          128 :     U8_TRACE_INFO("==== symbol_box ====" );
     177          128 :     geometry_rectangle_trace( layout_visible_classifier_get_symbol_box_const( io_classifier_layout ) );
     178          128 :     U8_TRACE_INFO("==== label_box  ====" );
     179          128 :     geometry_rectangle_trace( &label_rect );
     180          128 :     U8_TRACE_INFO("==== icon_box  ====" );
     181          128 :     geometry_rectangle_trace( &icon_rect );
     182          128 :     U8_TRACE_INFO("==== space     =====" );
     183          128 :     geometry_rectangle_trace( layout_visible_classifier_get_space_const( io_classifier_layout ) );
     184              : 
     185          128 :     geometry_rectangle_destroy( &label_rect );
     186          128 :     geometry_rectangle_destroy( &icon_rect );
     187          128 :     geometry_rectangle_destroy( &label_compartment );
     188              : 
     189          128 :     U8_TRACE_END_ERR(area_too_small);
     190          128 :     return area_too_small;
     191              : }
     192              : 
     193          128 : int pencil_classifier_composer_set_envelope_box( pencil_classifier_composer_t *this_,
     194              :                                                  const geometry_rectangle_t *envelope,
     195              :                                                  bool shows_contained_children,
     196              :                                                  const data_profile_part_t *profile,
     197              :                                                  const pencil_size_t *pencil_size,
     198              :                                                  PangoLayout *font_layout,
     199              :                                                  layout_visible_classifier_t *io_classifier_layout )
     200              : {
     201          128 :     U8_TRACE_BEGIN();
     202          128 :     assert( NULL != envelope );
     203          128 :     assert( NULL != pencil_size );
     204          128 :     assert( NULL != font_layout );
     205          128 :     assert( NULL != io_classifier_layout );
     206              : 
     207              :     /* get data that shall be layouted/composed */
     208              :     const data_visible_classifier_t *const visible_classifier
     209          128 :         = layout_visible_classifier_get_data_const( io_classifier_layout );
     210              :     const data_classifier_t *const classifier
     211          128 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     212              :     const data_classifier_type_t classifier_type
     213          128 :         = data_classifier_get_main_type( classifier );
     214          128 :     const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
     215              :     const bool has_stereotype_icon
     216          128 :         = draw_stereotype_icon_exists( &((*this_).draw_stereotype_icon), classifier_stereotype, profile );
     217              : 
     218          128 :     U8_TRACE_INFO_INT("calculating bounds of classifier id, type:", data_classifier_get_row_id( classifier ) );
     219          128 :     U8_TRACE_INFO_INT_INT("calculating bounds of classifier type, children:", classifier_type, shows_contained_children?1:0 );
     220              : 
     221              :     /* determine border sizes of the classifier-shape */
     222              :     const geometry_rectangle_t space_and_label
     223          128 :         = draw_classifier_contour_calc_inner_area( &((*this_).draw_classifier_contour),
     224              :                                                    classifier_type,
     225              :                                                    envelope,
     226              :                                                    pencil_size
     227              :                                                  );
     228              : 
     229              :     /* determine border sizes of the main line (label and optionally icon) */
     230              :     geometry_rectangle_t label_rect;
     231          128 :     geometry_rectangle_init_empty( &label_rect );
     232              :     geometry_rectangle_t icon_rect;
     233          128 :     geometry_rectangle_init_empty( &icon_rect );
     234              :     geometry_rectangle_t label_compartment;
     235          128 :     geometry_rectangle_init_empty( &label_compartment );
     236              :     const int area_too_small
     237          128 :         = pencil_classifier_composer_private_get_label_box( this_,
     238              :                                                             visible_classifier,
     239              :                                                             shows_contained_children,
     240              :                                                             has_stereotype_icon,
     241              :                                                             &space_and_label,
     242              :                                                             pencil_size,
     243              :                                                             font_layout,
     244              :                                                             &label_rect,
     245              :                                                             &icon_rect,
     246              :                                                             &label_compartment
     247              :                                                           );
     248              : 
     249              :     /* if label fits into space_and_label */
     250          128 :     if ( 0 == area_too_small )
     251              :     {
     252              :         const bool has_contour
     253           64 :             = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     254              : 
     255              :         /* get the symbol and label boxes and inner space rectangles to modify */
     256              :         geometry_rectangle_t classifier_space;
     257           64 :         geometry_rectangle_copy( &classifier_space, &space_and_label );
     258              : 
     259           64 :         if ( has_contour )
     260              :         {
     261           46 :             U8_TRACE_INFO("calculating symbol box as envelope around label and space..." );
     262              : 
     263              :             /* calculate symbol bounds */
     264           46 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, envelope );
     265              : 
     266              :             /* calculate space */
     267           46 :             geometry_rectangle_shift( &classifier_space, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     268           46 :             geometry_rectangle_enlarge( &classifier_space, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     269              :         }
     270              :         else
     271              :         {
     272           18 :             U8_TRACE_INFO("calculating symbol box for fixed-sized icon..." );
     273              : 
     274           18 :             const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );
     275           18 :             const double symbol_width = symbol_height;
     276              : 
     277              :             /* calculate symbol bounds */
     278           18 :             const geometry_h_align_t H_CENTER = GEOMETRY_H_ALIGN_CENTER;
     279              :             const double symbol_left
     280           18 :                 = geometry_h_align_get_left( &H_CENTER,
     281              :                                              symbol_width,
     282              :                                              geometry_rectangle_get_left( &space_and_label ),
     283              :                                              geometry_rectangle_get_width( &space_and_label )
     284              :                                            );
     285           18 :             const double symbol_top = geometry_rectangle_get_top( &label_compartment ) - symbol_height;
     286              :             geometry_rectangle_t classifier_symbol_box;
     287           18 :             geometry_rectangle_init( &classifier_symbol_box, symbol_left, symbol_top, symbol_width, symbol_height );
     288           18 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &classifier_symbol_box );
     289           18 :             geometry_rectangle_destroy( &classifier_symbol_box );
     290              : 
     291              :             /* calculate space */
     292           18 :             const double label_and_symbol_height = geometry_rectangle_get_height( &label_compartment ) + symbol_height;
     293           18 :             geometry_rectangle_shift( &classifier_space, 0.0, label_and_symbol_height );
     294           18 :             geometry_rectangle_enlarge( &classifier_space, 0.0, -label_and_symbol_height );
     295              :         }
     296           64 :         layout_visible_classifier_set_space( io_classifier_layout, &classifier_space );
     297              : 
     298              : 
     299              :         /* calculate label_box */
     300           64 :         layout_visible_classifier_set_label_box( io_classifier_layout, &label_rect );
     301           64 :         layout_visible_classifier_set_label_anchor( io_classifier_layout,
     302              :                                                     GEOMETRY_H_ALIGN_CENTER,
     303              :                                                     GEOMETRY_V_ALIGN_TOP
     304              :                                                   );
     305              :         /* calculate icon_box */
     306           64 :         layout_visible_classifier_set_icon_box( io_classifier_layout, &icon_rect );
     307              : 
     308           64 :         U8_TRACE_INFO("==== symbol_box ====" );
     309           64 :         geometry_rectangle_trace( layout_visible_classifier_get_symbol_box_const( io_classifier_layout ) );
     310           64 :         U8_TRACE_INFO("==== label_box  ====" );
     311           64 :         geometry_rectangle_trace( &label_rect );
     312           64 :         U8_TRACE_INFO("==== icon_box  ====" );
     313           64 :         geometry_rectangle_trace( &icon_rect );
     314           64 :         U8_TRACE_INFO("==== space     =====" );
     315           64 :         geometry_rectangle_trace( &classifier_space );
     316              : 
     317           64 :         geometry_rectangle_destroy( &classifier_space );
     318              :     }
     319              :     else
     320              :     {
     321              :         geometry_rectangle_t space_guess;  /* guess the inner space based on current text height */
     322           64 :         geometry_rectangle_copy( &space_guess, &space_and_label );
     323           64 :         geometry_rectangle_shift( &space_guess, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     324           64 :         geometry_rectangle_enlarge( &space_guess, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     325           64 :         U8_TRACE_INFO("==== space_guess====" );
     326           64 :         geometry_rectangle_trace( &space_guess );
     327           64 :         pencil_classifier_composer_expand_space( this_,
     328              :                                                  &space_guess,
     329              :                                                  shows_contained_children,
     330              :                                                  profile,
     331              :                                                  pencil_size,
     332              :                                                  font_layout,
     333              :                                                  io_classifier_layout
     334              :                                                );
     335           64 :         geometry_rectangle_destroy( &space_guess );
     336              : 
     337              :         /* shift/center to requested position after resizing beyond requested size */
     338              :         const geometry_rectangle_t current_envelope
     339           64 :             = layout_visible_classifier_get_envelope_box( io_classifier_layout );
     340           64 :         const double shift_to_right = geometry_rectangle_get_center_x( envelope ) - geometry_rectangle_get_center_x( &current_envelope );
     341           64 :         const double shift_to_bottom = geometry_rectangle_get_center_y( envelope ) - geometry_rectangle_get_center_y( &current_envelope );
     342           64 :         const geometry_offset_t offset = geometry_offset_new( shift_to_right, shift_to_bottom );
     343           64 :         layout_visible_classifier_shift( io_classifier_layout, &offset );
     344              :     }
     345              : 
     346          128 :     geometry_rectangle_destroy( &label_rect );
     347          128 :     geometry_rectangle_destroy( &icon_rect );
     348          128 :     geometry_rectangle_destroy( &label_compartment );
     349              : 
     350          128 :     U8_TRACE_END_ERR( area_too_small );
     351          128 :     return area_too_small;
     352              : }
     353              : 
     354          256 : int pencil_classifier_composer_private_get_label_box( pencil_classifier_composer_t *this_,
     355              :                                                       const data_visible_classifier_t *visible_classifier,
     356              :                                                       bool shows_contained_children,
     357              :                                                       bool has_stereotype_icon,
     358              :                                                       const geometry_rectangle_t *space_and_label,
     359              :                                                       const pencil_size_t *pencil_size,
     360              :                                                       PangoLayout *font_layout,
     361              :                                                       geometry_rectangle_t *out_label_box,
     362              :                                                       geometry_rectangle_t *out_icon_box,
     363              :                                                       geometry_rectangle_t *out_label_compartment )
     364              : {
     365          256 :     U8_TRACE_BEGIN();
     366          256 :     assert( NULL != visible_classifier );
     367          256 :     assert( NULL != space_and_label );
     368          256 :     assert( NULL != pencil_size );
     369          256 :     assert( NULL != font_layout );
     370          256 :     assert( NULL != out_label_box );
     371          256 :     assert( NULL != out_icon_box );
     372          256 :     assert( NULL != out_label_compartment );
     373              : 
     374          256 :     int result = 0;
     375              : 
     376              :     /* get classifier type */
     377              :     const data_classifier_t *const classifier
     378          256 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     379              :     const data_classifier_type_t classifier_type
     380          256 :         = data_classifier_get_main_type( classifier );
     381              : 
     382              :     /* get standard gap size */
     383          256 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     384              : 
     385              :     /* determine icon space */
     386              :     const geometry_dimensions_t icon_dim
     387              :         = has_stereotype_icon
     388            0 :         ? draw_stereotype_icon_get_dimensions( &((*this_).draw_stereotype_icon),
     389              :                                                pencil_size
     390              :                                              )
     391          256 :         : draw_classifier_icon_get_icon_dimensions( &((*this_).draw_classifier_icon),
     392              :                                                     classifier_type,
     393              :                                                     pencil_size
     394              :                                                   );
     395              : 
     396              :     /* determine stereotype and name dimensions */
     397              :     geometry_dimensions_t label_dim;
     398              :     const bool has_contour
     399          256 :         = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     400          256 :     const double icon_gap
     401          256 :         = ( ! has_contour ) ? 0.0 : ( geometry_dimensions_get_width( &icon_dim ) < 0.000001 ) ? 0.0 : gap;
     402          256 :     const double proposed_label_width
     403              :         = has_contour
     404          184 :         ? geometry_rectangle_get_width( space_and_label ) - geometry_dimensions_get_width( &icon_dim ) - icon_gap
     405          440 :         : geometry_rectangle_get_width( space_and_label );
     406          512 :     const geometry_dimensions_t proposed_label_dim
     407          256 :         = { .width = proposed_label_width, .height = geometry_rectangle_get_height( space_and_label ) };
     408          256 :     draw_classifier_label_get_stereotype_and_name_dimensions( &((*this_).draw_classifier_label),
     409              :                                                               visible_classifier,
     410              :                                                               ( ! has_stereotype_icon ),
     411              :                                                               &proposed_label_dim,
     412              :                                                               pencil_size,
     413              :                                                               font_layout,
     414              :                                                               &label_dim
     415          256 :                                                             );
     416          256 :     const double text_width = geometry_dimensions_get_width( &label_dim );
     417          256 :     const double text_height = geometry_dimensions_get_height( &label_dim );
     418          256 :     if ( text_width > (proposed_label_width + 0.0001) )
     419              :     {
     420          128 :         U8_TRACE_INFO_INT_INT( "label does not fit to provided width",
     421              :                                (int) text_width,
     422              :                                (int) proposed_label_width
     423              :                              );
     424          128 :         result = 1;
     425              :     }
     426          256 :     const double proposed_label_height = geometry_rectangle_get_height( space_and_label );
     427          256 :     if ( text_height > (proposed_label_height + 0.0001) )
     428              :     {
     429          128 :         U8_TRACE_INFO_INT_INT( "label does not fit to provided height",
     430              :                                (int) text_height,
     431              :                                (int) proposed_label_height
     432              :                              );
     433          128 :         result = 1;
     434              :     }
     435              : 
     436          256 :     if ( has_contour )
     437              :     {
     438          184 :         double top_border = geometry_rectangle_get_top( space_and_label );
     439              : 
     440              :         /* calculate label_compartment */
     441          184 :         const double min_required_width = text_width + icon_gap + geometry_dimensions_get_width( &icon_dim );
     442          184 :         const double comp_width = u8_f64_max2( min_required_width, geometry_rectangle_get_width( space_and_label ) );
     443          184 :         const geometry_h_align_t compartment_h_align = GEOMETRY_H_ALIGN_CENTER;
     444          184 :         const double comp_left = geometry_h_align_get_left( &compartment_h_align,
     445              :                                                             comp_width,
     446              :                                                             geometry_rectangle_get_left( space_and_label ),
     447              :                                                             geometry_rectangle_get_width( space_and_label )
     448              :                                                           );
     449          184 :         geometry_rectangle_reinit( out_label_compartment, comp_left, top_border, comp_width, text_height );
     450              : 
     451              :         /* calculate label_box and icon_box */
     452          184 :         const bool is_package_with_contents = (classifier_type == DATA_CLASSIFIER_TYPE_PACKAGE) && shows_contained_children;
     453          184 :         if ( is_package_with_contents )
     454              :         {
     455              :             /* re-calculate the outer bounds (envelope) to see the diff to top of packages, ignore space_and_label */
     456              :             const geometry_rectangle_t envelope
     457            4 :                 = draw_classifier_contour_calc_outer_bounds( &((*this_).draw_classifier_contour),
     458              :                                                              classifier_type,
     459              :                                                              out_label_compartment,
     460              :                                                              pencil_size
     461              :                                                            );
     462            4 :             double comp_top = geometry_rectangle_get_top( &envelope ) + 2.0 * gap;
     463              : 
     464              :             /* calculate label_box */
     465            4 :             geometry_rectangle_reinit( out_label_box,
     466              :                                        comp_left,
     467              :                                        comp_top,
     468              :                                        text_width,
     469              :                                        text_height
     470              :                                      );
     471              :             /* calculate icon_box */
     472            4 :             geometry_rectangle_reinit( out_icon_box,
     473            4 :                                        comp_left + text_width + icon_gap,
     474              :                                        comp_top,
     475              :                                        geometry_dimensions_get_width( &icon_dim ),
     476              :                                        geometry_dimensions_get_height( &icon_dim )
     477              :                                      );
     478              :         }
     479              :         else
     480              :         {
     481          180 :             const geometry_h_align_t text_h_align = GEOMETRY_H_ALIGN_CENTER;
     482          360 :             const double text_left = geometry_h_align_get_left( &text_h_align,
     483              :                                                                 text_width,
     484              :                                                                 geometry_rectangle_get_left( space_and_label ),
     485          180 :                                                                 geometry_rectangle_get_width( space_and_label ) - icon_gap - geometry_dimensions_get_width( &icon_dim )
     486              :                                                               );
     487              :             /* calculate label_box */
     488          180 :             geometry_rectangle_reinit( out_label_box,
     489              :                                        text_left,
     490              :                                        top_border,
     491              :                                        text_width,
     492              :                                        text_height
     493              :                                      );
     494              :             /* calculate icon_box */
     495          180 :             geometry_rectangle_reinit( out_icon_box,
     496          180 :                                        comp_left + comp_width - geometry_dimensions_get_width( &icon_dim ),
     497              :                                        top_border,
     498              :                                        geometry_dimensions_get_width( &icon_dim ),
     499              :                                        geometry_dimensions_get_height( &icon_dim )
     500              :                                      );
     501              :         }
     502              :     }
     503              :     else
     504              :     {
     505              :         /* calculate text position */
     506           72 :         const geometry_h_align_t h_align_center = GEOMETRY_H_ALIGN_CENTER;
     507           72 :         const double text_left = geometry_h_align_get_left( &h_align_center,
     508              :                                                             text_width,
     509              :                                                             geometry_rectangle_get_left( space_and_label ),
     510              :                                                             geometry_rectangle_get_width( space_and_label )
     511              :                                                           );
     512           72 :         const double text_top = geometry_rectangle_get_top( space_and_label );
     513              : 
     514              :         /* calculate label_compartment */
     515           72 :         const double comp_width = u8_f64_max2( text_width, geometry_rectangle_get_width( space_and_label ) );
     516           72 :         const geometry_h_align_t compartment_h_align = GEOMETRY_H_ALIGN_CENTER;
     517           72 :         const double comp_left = geometry_h_align_get_left( &compartment_h_align,
     518              :                                                             comp_width,
     519              :                                                             geometry_rectangle_get_left( space_and_label ),
     520              :                                                             geometry_rectangle_get_width( space_and_label )
     521              :                                                           );
     522           72 :         geometry_rectangle_reinit( out_label_compartment, comp_left, text_top, comp_width, text_height );
     523              : 
     524              :         /* calculate label_box */
     525           72 :         geometry_rectangle_reinit( out_label_box, text_left, text_top, text_width, text_height );
     526              :         /* calculate icon_box */
     527           72 :         const double icon_left = geometry_h_align_get_left( &h_align_center,
     528              :                                                             geometry_dimensions_get_width( &icon_dim ),
     529              :                                                             geometry_rectangle_get_left( space_and_label ),
     530              :                                                             geometry_rectangle_get_width( space_and_label )
     531              :                                                           );
     532           72 :         geometry_rectangle_reinit( out_icon_box,
     533              :                                    icon_left,
     534           72 :                                    text_top - gap - geometry_dimensions_get_height( &icon_dim ),
     535              :                                    geometry_dimensions_get_width( &icon_dim ),
     536              :                                    geometry_dimensions_get_height( &icon_dim )
     537              :                                  );
     538              :     }
     539              : 
     540          256 :     U8_TRACE_END_ERR( result );
     541          256 :     return result;
     542              : }
     543              : 
     544              : 
     545              : /*
     546              : Copyright 2016-2025 Andreas Warnke
     547              :     http://www.apache.org/licenses/LICENSE-2.0
     548              : 
     549              : Licensed under the Apache License, Version 2.0 (the "License");
     550              : you may not use this file except in compliance with the License.
     551              : You may obtain a copy of the License at
     552              : 
     553              : 
     554              : Unless required by applicable law or agreed to in writing, software
     555              : distributed under the License is distributed on an "AS IS" BASIS,
     556              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     557              : See the License for the specific language governing permissions and
     558              : limitations under the License.
     559              : */
        

Generated by: LCOV version 2.0-1