LCOV - code coverage report
Current view: top level - pencil/source - pencil_classifier_composer.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.57.0_covts Lines: 203 417 48.7 %
Date: 2024-04-07 11:14:42 Functions: 5 7 71.4 %

          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 :     pencil_marker_init( &((*this_).marker) );
      18           3 :     data_rules_init ( &((*this_).data_rules) );
      19           3 :     draw_classifier_icon_init( &((*this_).draw_classifier_icon) );
      20           3 :     draw_classifier_label_init( &((*this_).draw_classifier_label) );
      21           3 :     draw_classifier_contour_init( &((*this_).draw_classifier_contour) );
      22           3 :     draw_stereotype_image_init( &((*this_).draw_stereotype_image) );
      23             : 
      24           3 :     U8_TRACE_END();
      25           3 : }
      26             : 
      27           3 : void pencil_classifier_composer_destroy( pencil_classifier_composer_t *this_ )
      28             : {
      29           3 :     U8_TRACE_BEGIN();
      30             : 
      31           3 :     draw_classifier_icon_destroy( &((*this_).draw_classifier_icon) );
      32           3 :     draw_classifier_label_destroy( &((*this_).draw_classifier_label) );
      33           3 :     draw_classifier_contour_destroy( &((*this_).draw_classifier_contour) );
      34           3 :     draw_stereotype_image_destroy( &((*this_).draw_stereotype_image) );
      35           3 :     data_rules_destroy ( &((*this_).data_rules) );
      36           3 :     pencil_marker_destroy( &((*this_).marker) );
      37             : 
      38           3 :     U8_TRACE_END();
      39           3 : }
      40             : 
      41           0 : void pencil_classifier_composer_draw ( const pencil_classifier_composer_t *this_,
      42             :                                        const layout_visible_classifier_t *layouted_classifier,
      43             :                                        data_id_t mark_focused,
      44             :                                        data_id_t mark_highlighted,
      45             :                                        const data_small_set_t *mark_selected,
      46             :                                        const pencil_layout_data_t *layout_data,
      47             :                                        const data_profile_part_t *profile,
      48             :                                        const pencil_size_t *pencil_size,
      49             :                                        PangoLayout *font_layout,
      50             :                                        cairo_t *cr )
      51             : {
      52           0 :     U8_TRACE_BEGIN();
      53           0 :     assert( NULL != layouted_classifier );
      54           0 :     assert( NULL != mark_selected );
      55           0 :     assert( NULL != layout_data );
      56           0 :     assert( NULL != profile );
      57           0 :     assert( NULL != pencil_size );
      58           0 :     assert( NULL != font_layout );
      59           0 :     assert( NULL != cr );
      60             : 
      61             :     const data_visible_classifier_t *const visible_classifier
      62           0 :         = layout_visible_classifier_get_data_const( layouted_classifier );
      63             :     const geometry_rectangle_t *const classifier_symbol_box
      64           0 :         = layout_visible_classifier_get_symbol_box_const( layouted_classifier );
      65             :     const geometry_rectangle_t *const classifier_label_box
      66           0 :         = layout_visible_classifier_get_label_box_const( layouted_classifier );
      67             :     const data_classifier_t *const classifier
      68           0 :         = data_visible_classifier_get_classifier_const( visible_classifier );
      69             :     const data_diagramelement_t *const diagramelement
      70           0 :         = data_visible_classifier_get_diagramelement_const( visible_classifier );
      71           0 :     const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
      72           0 :     const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
      73             :     const bool has_stereotype_image
      74           0 :         = draw_stereotype_image_exists( &((*this_).draw_stereotype_image), classifier_stereotype, profile );
      75             :     const data_diagramelement_flag_t display_flags
      76           0 :         = data_diagramelement_get_display_flags( diagramelement );
      77             : 
      78           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
      79           0 :     const double std_line_width = pencil_size_get_standard_line_width( pencil_size );
      80             :     /* set the right drawing color */
      81             :     GdkRGBA foreground_color;
      82             :     {
      83           0 :         if ( data_id_equals_id( &mark_highlighted, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id( diagramelement ) ) )
      84             :         {
      85           0 :             foreground_color = pencil_size_get_highlight_color( pencil_size );
      86             :         }
      87           0 :         else if ( 0 != ( display_flags & DATA_DIAGRAMELEMENT_FLAG_GRAY_OUT ))
      88             :         {
      89           0 :             foreground_color = pencil_size_get_gray_out_color( pencil_size );
      90             :         }
      91             :         else
      92             :         {
      93           0 :             foreground_color = pencil_size_get_standard_color( pencil_size );
      94             :         }
      95             :     }
      96             : 
      97           0 :     U8_TRACE_INFO_INT("drawing classifier id", data_classifier_get_row_id( classifier ) );
      98             : 
      99             :     /* draw the stereotype image */
     100           0 :     bool icon_override = false;  /* in case of a stereotype image, the icon shall not be drawn. */
     101           0 :     if ( has_stereotype_image )
     102             :     {
     103             :         /* check if the image is a small icon within a contour or if it is the full symbol */
     104           0 :         const bool has_contour = geometry_rectangle_is_containing( classifier_symbol_box, classifier_label_box );
     105             : 
     106             :         /* determine border sizes of the classifier-shape */
     107           0 :         const geometry_rectangle_t space_and_label
     108             :             = has_contour
     109           0 :             ? draw_classifier_contour_calc_inner_area( &((*this_).draw_classifier_contour),
     110             :                                                        classifier_type,
     111             :                                                        classifier_symbol_box,
     112             :                                                        pencil_size
     113             :                                                      )
     114           0 :             : (*classifier_symbol_box);
     115             : 
     116             :         /* draw icon */
     117           0 :         cairo_set_line_width( cr, std_line_width );
     118           0 :         const geometry_rectangle_t stereotype_box
     119             :             = has_contour
     120           0 :             ? draw_stereotype_image_get_bounds( &((*this_).draw_stereotype_image),
     121             :                                                 geometry_rectangle_get_right( &space_and_label ),  /* x */
     122             :                                                 geometry_rectangle_get_top( &space_and_label ),  /* y */
     123             :                                                 GEOMETRY_H_ALIGN_RIGHT,
     124             :                                                 GEOMETRY_V_ALIGN_TOP,
     125             :                                                 pencil_size
     126             :                                               )
     127           0 :             : (*classifier_symbol_box);
     128             :         u8_error_info_t err_info;
     129             :         const u8_error_t stereotype_err
     130           0 :             = draw_stereotype_image_draw( &((*this_).draw_stereotype_image),
     131             :                                           data_classifier_get_stereotype_const( classifier ),
     132             :                                           profile,
     133             :                                           &foreground_color,
     134             :                                           &err_info,
     135             :                                           &stereotype_box,
     136             :                                           cr
     137             :                                         );
     138           0 :         if ( u8_error_info_is_error( &err_info ) )
     139             :         {
     140           0 :             U8_LOG_WARNING_INT( "stereotype image: unxpected token in svg path in line",
     141             :                                 u8_error_info_get_line( &err_info )
     142             :                               );
     143             :         }
     144           0 :         icon_override = ( stereotype_err == U8_ERROR_NONE );
     145             :     }
     146             : 
     147             :     /* draw the classifier */
     148             :     {
     149             :         /* set line width */
     150           0 :         cairo_set_line_width( cr, std_line_width );
     151             :         /* set color */
     152           0 :         cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
     153             : 
     154             :         /* highlight */
     155           0 :         if ( 0 != ( display_flags & DATA_DIAGRAMELEMENT_FLAG_EMPHASIS ))
     156             :         {
     157           0 :             const GdkRGBA emph_color = pencil_size_get_emphasized_bgcolor( pencil_size );
     158           0 :             cairo_set_source_rgba( cr, emph_color.red, emph_color.green, emph_color.blue, emph_color.alpha );
     159           0 :             cairo_rectangle ( cr,
     160             :                               geometry_rectangle_get_left( classifier_label_box ),
     161             :                               geometry_rectangle_get_top( classifier_label_box ),
     162             :                               geometry_rectangle_get_width( classifier_label_box ),
     163             :                               geometry_rectangle_get_height( classifier_label_box )
     164             :                             );
     165           0 :             cairo_fill (cr);
     166           0 :             cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
     167             :         }
     168             : 
     169             :         /* draw label */
     170           0 :         draw_classifier_label_draw_stereotype_and_name( &((*this_).draw_classifier_label),
     171             :                                                         visible_classifier,
     172             :                                                         ( ! has_stereotype_image ),
     173             :                                                         &foreground_color,
     174             :                                                         classifier_label_box,
     175             :                                                         pencil_size,
     176             :                                                         font_layout,
     177             :                                                         cr
     178           0 :                                                       );
     179             : 
     180             :         /* draw rectangle */
     181             :         geometry_rectangle_t classifier_icon_box;
     182             :         {
     183           0 :             geometry_rectangle_copy( &classifier_icon_box, classifier_symbol_box );
     184           0 :             geometry_rectangle_enlarge( &classifier_icon_box, -2.0*gap, -2.0*gap );
     185           0 :             geometry_rectangle_shift( &classifier_icon_box, gap, gap );
     186             :         }
     187           0 :         const double icon_left = geometry_rectangle_get_left ( &classifier_icon_box );
     188           0 :         const double icon_top = geometry_rectangle_get_top ( &classifier_icon_box );
     189           0 :         const double icon_width = geometry_rectangle_get_width ( &classifier_icon_box );
     190           0 :         const double icon_height = geometry_rectangle_get_height ( &classifier_icon_box );
     191           0 :         switch ( classifier_type )
     192             :         {
     193           0 :             case DATA_CLASSIFIER_TYPE_REQUIREMENT:  /* SysML */
     194             :             case DATA_CLASSIFIER_TYPE_PART:
     195             :             {
     196           0 :                 draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     197             :             }
     198           0 :             break;
     199             : 
     200           0 :             case DATA_CLASSIFIER_TYPE_BLOCK:  /* SysML */
     201             :             case DATA_CLASSIFIER_TYPE_CLASS:
     202             :             case DATA_CLASSIFIER_TYPE_OBJECT:
     203             :             case DATA_CLASSIFIER_TYPE_INTERFACE:
     204             :             case DATA_CLASSIFIER_TYPE_STEREOTYPE:
     205             :             {
     206           0 :                 draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     207           0 :                 pencil_classifier_composer_private_draw_feature_compartments( this_,
     208             :                                                                               layouted_classifier,
     209             :                                                                               layout_data,
     210             :                                                                               pencil_size,
     211             :                                                                               cr
     212             :                                                                             );
     213             :             }
     214           0 :             break;
     215             : 
     216           0 :             case DATA_CLASSIFIER_TYPE_COMPONENT:
     217             :             {
     218           0 :                 draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     219             : 
     220             :                 /* draw icon */
     221           0 :                 const double component_icon_height = pencil_size_get_title_font_size( pencil_size );
     222             :                 const geometry_rectangle_t icon_bounds
     223           0 :                     = draw_classifier_icon_get_component_bounds( &((*this_).draw_classifier_icon),
     224           0 :                                                                  icon_left + icon_width - gap,  /* x */
     225             :                                                                  icon_top + gap,  /* y */
     226             :                                                                  GEOMETRY_H_ALIGN_RIGHT,
     227             :                                                                  GEOMETRY_V_ALIGN_TOP,
     228             :                                                                  component_icon_height
     229             :                                                                );
     230           0 :                 if ( ! icon_override )
     231             :                 {
     232           0 :                     draw_classifier_icon_draw_component ( &((*this_).draw_classifier_icon), icon_bounds, cr );
     233             :                 }
     234             :             }
     235           0 :             break;
     236             : 
     237           0 :             case DATA_CLASSIFIER_TYPE_ARTIFACT:
     238             :             {
     239           0 :                 draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     240             : 
     241             :                 /* draw icon */
     242           0 :                 const double artifact_icon_height = pencil_size_get_title_font_size( pencil_size );
     243             :                 const geometry_rectangle_t icon_bounds
     244           0 :                     = draw_classifier_icon_get_artifact_bounds( &((*this_).draw_classifier_icon),
     245           0 :                                                                 icon_left + icon_width - gap,  /* x */
     246             :                                                                 icon_top + gap,  /* y */
     247             :                                                                 GEOMETRY_H_ALIGN_RIGHT,
     248             :                                                                 GEOMETRY_V_ALIGN_TOP,
     249             :                                                                 artifact_icon_height
     250             :                                                               );
     251           0 :                 if ( ! icon_override )
     252             :                 {
     253           0 :                     draw_classifier_icon_draw_artifact ( &((*this_).draw_classifier_icon), icon_bounds, cr );
     254             :                 }
     255             :             }
     256           0 :             break;
     257             : 
     258           0 :             case DATA_CLASSIFIER_TYPE_ACTIVITY:
     259             :             case DATA_CLASSIFIER_TYPE_STATE:
     260             :             case DATA_CLASSIFIER_TYPE_CONSTRAINT_BLOCK:
     261             :             {
     262           0 :                 draw_classifier_contour_draw_rounded_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, false, pencil_size, cr );
     263           0 :                 pencil_classifier_composer_private_draw_feature_compartments ( this_,
     264             :                                                                                layouted_classifier,
     265             :                                                                                layout_data,
     266             :                                                                                pencil_size,
     267             :                                                                                cr
     268             :                                                                              );
     269             :             }
     270           0 :             break;
     271             : 
     272           0 :             case DATA_CLASSIFIER_TYPE_DYN_INTERRUPTABLE_REGION:
     273             :             {
     274           0 :                 draw_classifier_contour_draw_rounded_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, true, pencil_size, cr );
     275             :             }
     276           0 :             break;
     277             : 
     278           0 :             case DATA_CLASSIFIER_TYPE_USE_CASE:
     279             :             {
     280           0 :                 draw_classifier_contour_draw_ellipse ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     281           0 :                 pencil_classifier_composer_private_draw_feature_compartments ( this_,
     282             :                                                                                layouted_classifier,
     283             :                                                                                layout_data,
     284             :                                                                                pencil_size,
     285             :                                                                                cr
     286             :                                                                              );
     287             :             }
     288           0 :             break;
     289             : 
     290           0 :             case DATA_CLASSIFIER_TYPE_NODE:
     291             :             {
     292           0 :                 draw_classifier_contour_draw_3d_box ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     293             :             }
     294           0 :             break;
     295             : 
     296           0 :             case DATA_CLASSIFIER_TYPE_ACTOR:
     297             :             {
     298           0 :                 if ( ! icon_override )
     299             :                 {
     300           0 :                     const double actor_height = icon_height;
     301           0 :                     const double half_width = 0.5 * icon_width;
     302             :                     const geometry_rectangle_t icon_bounds
     303           0 :                         = draw_classifier_icon_get_actor_bounds( &((*this_).draw_classifier_icon),
     304             :                                                                  icon_left + half_width,
     305             :                                                                  icon_top,
     306             :                                                                  GEOMETRY_H_ALIGN_CENTER,
     307             :                                                                  GEOMETRY_V_ALIGN_TOP,
     308             :                                                                  actor_height
     309             :                                                                );
     310           0 :                     draw_classifier_icon_draw_actor ( &((*this_).draw_classifier_icon), icon_bounds, cr );
     311             :                 }
     312             :             }
     313           0 :             break;
     314             : 
     315           0 :             case DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE:
     316             :             case DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE:
     317             :             case DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY:
     318             :             case DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY:
     319             :             {
     320           0 :                 if ( ! icon_override )
     321             :                 {
     322           0 :                     const double circle_diameter = icon_height;
     323           0 :                     const double half_width = 0.5 * icon_width;
     324             :                     const geometry_rectangle_t icon_bounds
     325           0 :                         = draw_classifier_icon_get_circle_bounds( &((*this_).draw_classifier_icon),
     326             :                                                                   icon_left + half_width,
     327             :                                                                   icon_top,
     328             :                                                                   GEOMETRY_H_ALIGN_CENTER,
     329             :                                                                   GEOMETRY_V_ALIGN_TOP,
     330             :                                                                   circle_diameter
     331             :                                                                 );
     332           0 :                     const bool stroke = ( classifier_type != DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE );
     333           0 :                     const bool fill = ( ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE )
     334           0 :                                     || ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE ) );
     335           0 :                     const bool shallow_history = ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY );
     336           0 :                     const bool deep_history = ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY );
     337           0 :                     draw_classifier_icon_draw_circle( &((*this_).draw_classifier_icon),
     338             :                                                       icon_bounds,
     339             :                                                       pencil_size,
     340             :                                                       stroke,
     341             :                                                       fill,
     342             :                                                       shallow_history,
     343             :                                                       deep_history,
     344             :                                                       cr
     345             :                                                     );
     346             :                 }
     347             :             }
     348           0 :             break;
     349             : 
     350           0 :             case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_EVENT :
     351             :             {
     352           0 :                 draw_classifier_contour_draw_accept_event ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     353             :             }
     354           0 :             break;
     355             : 
     356           0 :             case DATA_CLASSIFIER_TYPE_DYN_SEND_SIGNAL:
     357             :             {
     358           0 :                 draw_classifier_contour_draw_send_signal ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     359             :             }
     360           0 :             break;
     361             : 
     362           0 :             case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_TIME_EVENT:
     363             :             {
     364           0 :                 if ( ! icon_override )
     365             :                 {
     366           0 :                     const double time_icon_height = icon_height;
     367           0 :                     const double half_width = 0.5 * icon_width;
     368             :                     const geometry_rectangle_t icon_bounds
     369           0 :                         = draw_classifier_icon_get_time_bounds( &((*this_).draw_classifier_icon),
     370             :                                                                 icon_left + half_width,
     371             :                                                                 icon_top,
     372             :                                                                 GEOMETRY_H_ALIGN_CENTER,
     373             :                                                                 GEOMETRY_V_ALIGN_TOP,
     374             :                                                                 time_icon_height
     375             :                                                               );
     376           0 :                     draw_classifier_icon_draw_time ( &((*this_).draw_classifier_icon), icon_bounds, cr );
     377             :                 }
     378             :             }
     379           0 :             break;
     380             : 
     381           0 :             case DATA_CLASSIFIER_TYPE_DYN_FORK_NODE:
     382             :             case DATA_CLASSIFIER_TYPE_DYN_JOIN_NODE:
     383             :             {
     384           0 :                 if ( ! icon_override )
     385             :                 {
     386           0 :                     const double box_icon_height = icon_height;
     387           0 :                     const double half_width = 0.5 * icon_width;
     388             :                     const geometry_rectangle_t icon_bounds
     389           0 :                         = draw_classifier_icon_get_sync_bounds( &((*this_).draw_classifier_icon),
     390             :                                                                 icon_left + half_width,
     391             :                                                                 icon_top,
     392             :                                                                 GEOMETRY_H_ALIGN_CENTER,
     393             :                                                                 GEOMETRY_V_ALIGN_TOP,
     394             :                                                                 box_icon_height,
     395             :                                                                 pencil_size
     396             :                                                               );
     397           0 :                     draw_classifier_icon_draw_sync ( &((*this_).draw_classifier_icon), icon_bounds, cr );
     398             :                 }
     399             :             }
     400           0 :             break;
     401             : 
     402           0 :             case DATA_CLASSIFIER_TYPE_DYN_DECISION_NODE:
     403             :             {
     404           0 :                 draw_classifier_contour_draw_rhombus ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     405             :             }
     406           0 :             break;
     407             : 
     408           0 :             case DATA_CLASSIFIER_TYPE_SUBSYSTEM:
     409             :             {
     410           0 :                 draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     411             :             }
     412           0 :             break;
     413             : 
     414           0 :             case DATA_CLASSIFIER_TYPE_DIAGRAM_REFERENCE:
     415             :             {
     416           0 :                 draw_classifier_contour_draw_diagram_ref ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     417             :             }
     418           0 :             break;
     419             : 
     420           0 :             case DATA_CLASSIFIER_TYPE_PACKAGE:
     421             :             {
     422           0 :                 draw_classifier_contour_draw_package( &((*this_).draw_classifier_contour),
     423             :                                                       classifier_symbol_box,
     424             :                                                       classifier_label_box,
     425             :                                                       pencil_size,
     426             :                                                       cr
     427             :                                                     );
     428             :             }
     429           0 :             break;
     430             : 
     431           0 :             case DATA_CLASSIFIER_TYPE_COMMENT:
     432             :             {
     433           0 :                 draw_classifier_contour_draw_comment ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     434             :             }
     435           0 :             break;
     436             : 
     437           0 :             case DATA_CLASSIFIER_TYPE_IMAGE:
     438             :             {
     439           0 :                 if ( ! icon_override )
     440             :                 {
     441           0 :                     draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
     442             :                 }
     443             :             }
     444           0 :             break;
     445             : 
     446           0 :             default:
     447             :             {
     448             :                 /* this case can happen if a model file of a new cfu version is opened with an older version of cfu */
     449           0 :                 U8_LOG_ANOMALY("unknown data_classifier_type_t in pencil_classifier_composer_draw()");
     450             :                 /* type is unknown, so one cannot decide if to draw rounded corners. */
     451           0 :                 draw_classifier_contour_draw_cornerless( &((*this_).draw_classifier_contour),
     452             :                                                          classifier_symbol_box,
     453             :                                                          pencil_size,
     454             :                                                          cr
     455             :                                                        );
     456             :             }
     457           0 :             break;
     458             :         }
     459             : 
     460             : #ifdef PENCIL_LAYOUT_DATA_DRAW_FOR_DEBUG
     461             :         /* draw the rectangles */
     462             :         {
     463             :             const geometry_rectangle_t *const classifier_space
     464           0 :                 = layout_visible_classifier_get_space_const( layouted_classifier );
     465             :             const geometry_rectangle_t *const classifier_label_box
     466           0 :                 = layout_visible_classifier_get_label_box_const( layouted_classifier );
     467             : 
     468           0 :             cairo_set_source_rgba( cr, 1.0, 0.5, 0.6, 0.5 );
     469           0 :             cairo_rectangle ( cr,
     470             :                               geometry_rectangle_get_left ( classifier_symbol_box ),
     471             :                               geometry_rectangle_get_top ( classifier_symbol_box ),
     472             :                               geometry_rectangle_get_width ( classifier_symbol_box ),
     473             :                               geometry_rectangle_get_height ( classifier_symbol_box )
     474             :                             );
     475           0 :             cairo_rectangle ( cr,
     476             :                               geometry_rectangle_get_left ( classifier_space ),
     477             :                               geometry_rectangle_get_top ( classifier_space ),
     478             :                               geometry_rectangle_get_width ( classifier_space ),
     479             :                               geometry_rectangle_get_height ( classifier_space )
     480             :                             );
     481           0 :             cairo_rectangle ( cr,
     482             :                               geometry_rectangle_get_left ( classifier_label_box ),
     483             :                               geometry_rectangle_get_top ( classifier_label_box ),
     484             :                               geometry_rectangle_get_width ( classifier_label_box ),
     485             :                               geometry_rectangle_get_height ( classifier_label_box )
     486             :                             );
     487           0 :             cairo_stroke (cr);
     488             :         }
     489             : #endif
     490             : 
     491           0 :         if ( data_small_set_contains_row_id( mark_selected, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id(diagramelement) ) )
     492             :         {
     493           0 :             pencil_marker_mark_selected_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
     494             :         }
     495             : 
     496           0 :         if ( data_id_equals_id( &mark_focused, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id(diagramelement) )
     497           0 :             ||  data_id_equals_id( &mark_focused, DATA_TABLE_CLASSIFIER, data_classifier_get_row_id(classifier) ) )
     498             :         {
     499           0 :             pencil_marker_mark_focused_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
     500             :         }
     501             :     }
     502             : 
     503           0 :     U8_TRACE_END();
     504           0 : }
     505             : 
     506         128 : int pencil_classifier_composer_expand_space ( const pencil_classifier_composer_t *this_,
     507             :                                               const geometry_rectangle_t *space,
     508             :                                               bool shows_contained_children,
     509             :                                               const data_profile_part_t *profile,
     510             :                                               const pencil_size_t *pencil_size,
     511             :                                               PangoLayout *font_layout,
     512             :                                               layout_visible_classifier_t *io_classifier_layout )
     513             : {
     514         128 :     U8_TRACE_BEGIN();
     515         128 :     assert( NULL != space );
     516         128 :     assert( NULL != pencil_size );
     517         128 :     assert( NULL != font_layout );
     518         128 :     assert( NULL != io_classifier_layout );
     519             : 
     520             :     /* get data that shall be layouted/composed */
     521             :     const data_visible_classifier_t *const visible_classifier
     522         128 :         = layout_visible_classifier_get_data_const( io_classifier_layout );
     523             :     const data_classifier_t *const classifier
     524         128 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     525             :     const data_classifier_type_t classifier_type
     526         128 :         = data_classifier_get_main_type( classifier );
     527         128 :     const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
     528             :     const bool has_stereotype_image
     529         128 :         = draw_stereotype_image_exists( &((*this_).draw_stereotype_image), classifier_stereotype, profile );
     530             : 
     531         128 :     U8_TRACE_INFO_INT("expanding bounds of classifier id:", data_classifier_get_row_id( classifier ) );
     532         128 :     U8_TRACE_INFO_INT_INT("expanding bounds of classifier type, children:", classifier_type, shows_contained_children?1:0 );
     533             : 
     534             :     /* determine icon space */
     535             :     const geometry_dimensions_t icon_dim
     536             :         = has_stereotype_image
     537           0 :         ? draw_stereotype_image_get_dimensions( &((*this_).draw_stereotype_image),
     538             :                                                 pencil_size
     539             :                                               )
     540         128 :         : draw_classifier_icon_get_icon_dimensions( &((*this_).draw_classifier_icon),
     541             :                                                     classifier_type,
     542             :                                                     pencil_size
     543             :                                                   );
     544             : 
     545             :     /* determine border sizes of the main line (label and optionally icon) */
     546             :     geometry_rectangle_t label_rect;
     547         128 :     geometry_rectangle_init_empty( &label_rect );
     548             :     geometry_rectangle_t label_compartment;
     549         128 :     geometry_rectangle_init_empty( &label_compartment );
     550         128 :     const geometry_rectangle_t *space_and_label_fake = space;  /* fake space_and_label to be identical to requested space */
     551             :     const int area_too_small
     552         128 :         = pencil_classifier_composer_private_get_label_box( this_,
     553             :                                                             visible_classifier,
     554             :                                                             shows_contained_children,
     555             :                                                             ( ! has_stereotype_image ),
     556             :                                                             space_and_label_fake,
     557             :                                                             &icon_dim,
     558             :                                                             pencil_size,
     559             :                                                             font_layout,
     560             :                                                             &label_rect,
     561             :                                                             &label_compartment
     562         128 :                                                           );
     563         128 :     if ( area_too_small != 0 )
     564             :     {
     565          64 :         U8_TRACE_INFO("new width is defined by label-and-icon, not by requested inner space" );
     566             :     }
     567         128 :     const double label_top = geometry_rectangle_get_top( space ) - geometry_rectangle_get_height( &label_compartment );
     568         128 :     geometry_rectangle_set_top( &label_rect, label_top );
     569         128 :     geometry_rectangle_set_top( &label_compartment, label_top );
     570             : 
     571             :     /* sizes of geometric objects are determined, */
     572             :     /* now position the geometric objects */
     573             :     {
     574             :         const bool has_contour
     575         128 :             = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     576             : 
     577         128 :         if ( has_contour )
     578             :         {
     579          92 :             U8_TRACE_INFO("calculating symbol box as envelope around label and space..." );
     580             : 
     581             :             /* calculate symbol bounds */
     582             :             geometry_rectangle_t inner_area;
     583          92 :             if ( area_too_small )
     584             :             {
     585          92 :                 geometry_rectangle_init( &inner_area,
     586             :                                          geometry_rectangle_get_left( &label_compartment ),
     587             :                                          geometry_rectangle_get_top( &label_compartment ),
     588             :                                          geometry_rectangle_get_width( &label_compartment ),
     589          46 :                                          geometry_rectangle_get_height( &label_compartment )
     590          46 :                                          + geometry_rectangle_get_height( space )
     591             :                                        );
     592             :             }
     593             :             else
     594             :             {
     595          46 :                 geometry_rectangle_copy( &inner_area, space );
     596          46 :                 geometry_rectangle_shift( &inner_area, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     597          46 :                 geometry_rectangle_enlarge( &inner_area, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     598             :             }
     599             :             const geometry_rectangle_t envelope
     600          92 :                 = draw_classifier_contour_calc_outer_bounds( &((*this_).draw_classifier_contour),
     601             :                                                              classifier_type,
     602             :                                                              &inner_area,
     603             :                                                              pencil_size
     604             :                                                            );
     605          92 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &envelope );
     606          92 :             geometry_rectangle_destroy( &inner_area );
     607             :         }
     608             :         else
     609             :         {
     610          36 :             U8_TRACE_INFO("calculating symbol box for fixed-sized icon..." );
     611             : 
     612          36 :             const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );
     613          36 :             const double symbol_width = symbol_height;
     614             : 
     615             :             /* calculate symbol bounds */
     616          36 :             const geometry_h_align_t H_CENTER = GEOMETRY_H_ALIGN_CENTER;
     617             :             const double symbol_left
     618          36 :                 = geometry_h_align_get_left( &H_CENTER,
     619             :                                              symbol_width,
     620             :                                              geometry_rectangle_get_left( space ),
     621             :                                              geometry_rectangle_get_width( space )
     622             :                                            );
     623          36 :             const double symbol_top = geometry_rectangle_get_top( &label_compartment ) - symbol_height;
     624             :             geometry_rectangle_t classifier_symbol_box;
     625          36 :             geometry_rectangle_init( &classifier_symbol_box, symbol_left, symbol_top, symbol_width, symbol_height );
     626          36 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &classifier_symbol_box );
     627          36 :             geometry_rectangle_destroy( &classifier_symbol_box );
     628             :         }
     629             : 
     630             :         /* calculate label_box */
     631         128 :         layout_visible_classifier_set_label_box( io_classifier_layout, &label_rect );
     632         128 :         layout_visible_classifier_set_label_anchor( io_classifier_layout,
     633             :                                                     GEOMETRY_H_ALIGN_CENTER,
     634             :                                                     GEOMETRY_V_ALIGN_TOP
     635             :                                                   );
     636             : 
     637             :         /* calculate space */
     638             :         /* get the symbol and label boxes and inner space rectangles to modify */
     639             :         geometry_rectangle_t classifier_space;
     640         128 :         geometry_rectangle_init( &classifier_space,
     641             :                                  geometry_rectangle_get_left( &label_compartment ),
     642             :                                  geometry_rectangle_get_top( space ),
     643             :                                  geometry_rectangle_get_width( &label_compartment ),
     644             :                                  geometry_rectangle_get_height( space )
     645             :                                );
     646         128 :         layout_visible_classifier_set_space( io_classifier_layout, &classifier_space );
     647         128 :         geometry_rectangle_destroy( &classifier_space );
     648             :     }
     649             : 
     650         128 :     U8_TRACE_INFO("==== symbol_box ====" );
     651         128 :     geometry_rectangle_trace( layout_visible_classifier_get_symbol_box_const( io_classifier_layout ) );
     652         128 :     U8_TRACE_INFO("==== label_box  ====" );
     653         128 :     geometry_rectangle_trace( &label_rect );
     654         128 :     U8_TRACE_INFO("==== space     =====" );
     655         128 :     geometry_rectangle_trace( layout_visible_classifier_get_space_const( io_classifier_layout ) );
     656             : 
     657         128 :     geometry_rectangle_destroy( &label_rect );
     658         128 :     geometry_rectangle_destroy( &label_compartment );
     659             : 
     660         128 :     U8_TRACE_END_ERR(area_too_small);
     661         128 :     return area_too_small;
     662             : }
     663             : 
     664         128 : int pencil_classifier_composer_set_envelope_box( const pencil_classifier_composer_t *this_,
     665             :                                                  const geometry_rectangle_t *envelope,
     666             :                                                  bool shows_contained_children,
     667             :                                                  const data_profile_part_t *profile,
     668             :                                                  const pencil_size_t *pencil_size,
     669             :                                                  PangoLayout *font_layout,
     670             :                                                  layout_visible_classifier_t *io_classifier_layout )
     671             : {
     672         128 :     U8_TRACE_BEGIN();
     673         128 :     assert( NULL != envelope );
     674         128 :     assert( NULL != pencil_size );
     675         128 :     assert( NULL != font_layout );
     676         128 :     assert( NULL != io_classifier_layout );
     677             : 
     678             :     /* get data that shall be layouted/composed */
     679             :     const data_visible_classifier_t *const visible_classifier
     680         128 :         = layout_visible_classifier_get_data_const( io_classifier_layout );
     681             :     const data_classifier_t *const classifier
     682         128 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     683             :     const data_classifier_type_t classifier_type
     684         128 :         = data_classifier_get_main_type( classifier );
     685         128 :     const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
     686             :     const bool has_stereotype_image
     687         128 :         = draw_stereotype_image_exists( &((*this_).draw_stereotype_image), classifier_stereotype, profile );
     688             : 
     689         128 :     U8_TRACE_INFO_INT("calculating bounds of classifier id, type:", data_classifier_get_row_id( classifier ) );
     690         128 :     U8_TRACE_INFO_INT_INT("calculating bounds of classifier type, children:", classifier_type, shows_contained_children?1:0 );
     691             : 
     692             :     /* determine icon space */
     693             :     const geometry_dimensions_t icon_dim
     694             :         = has_stereotype_image
     695           0 :         ? draw_stereotype_image_get_dimensions( &((*this_).draw_stereotype_image),
     696             :                                                 pencil_size
     697             :                                               )
     698         128 :         : draw_classifier_icon_get_icon_dimensions( &((*this_).draw_classifier_icon),
     699             :                                                     classifier_type,
     700             :                                                     pencil_size
     701             :                                                   );
     702             : 
     703             :     /* determine border sizes of the classifier-shape */
     704             :     const geometry_rectangle_t space_and_label
     705         128 :         = draw_classifier_contour_calc_inner_area( &((*this_).draw_classifier_contour),
     706             :                                                    classifier_type,
     707             :                                                    envelope,
     708             :                                                    pencil_size
     709             :                                                  );
     710             : 
     711             :     /* determine border sizes of the main line (label and optionally icon) */
     712             :     geometry_rectangle_t label_rect;
     713         128 :     geometry_rectangle_init_empty( &label_rect );
     714             :     geometry_rectangle_t label_compartment;
     715         128 :     geometry_rectangle_init_empty( &label_compartment );
     716             :     const int area_too_small
     717         128 :         = pencil_classifier_composer_private_get_label_box( this_,
     718             :                                                             visible_classifier,
     719             :                                                             shows_contained_children,
     720             :                                                             ( ! has_stereotype_image ),
     721             :                                                             &space_and_label,
     722             :                                                             &icon_dim,
     723             :                                                             pencil_size,
     724             :                                                             font_layout,
     725             :                                                             &label_rect,
     726             :                                                             &label_compartment
     727         128 :                                                           );
     728             : 
     729             :     /* if label fits into space_and_label */
     730         128 :     if ( 0 == area_too_small )
     731             :     {
     732             :         const bool has_contour
     733          64 :             = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     734             : 
     735             :         /* get the symbol and label boxes and inner space rectangles to modify */
     736             :         geometry_rectangle_t classifier_space;
     737          64 :         geometry_rectangle_copy( &classifier_space, &space_and_label );
     738             : 
     739          64 :         if ( has_contour )
     740             :         {
     741          46 :             U8_TRACE_INFO("calculating symbol box as envelope around label and space..." );
     742             : 
     743             :             /* calculate symbol bounds */
     744          46 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, envelope );
     745             : 
     746             :             /* calculate space */
     747          46 :             geometry_rectangle_shift( &classifier_space, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     748          46 :             geometry_rectangle_enlarge( &classifier_space, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     749             :         }
     750             :         else
     751             :         {
     752          18 :             U8_TRACE_INFO("calculating symbol box for fixed-sized icon..." );
     753             : 
     754          18 :             const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );
     755          18 :             const double symbol_width = symbol_height;
     756             : 
     757             :             /* calculate symbol bounds */
     758          18 :             const geometry_h_align_t H_CENTER = GEOMETRY_H_ALIGN_CENTER;
     759             :             const double symbol_left
     760          18 :                 = geometry_h_align_get_left( &H_CENTER,
     761             :                                              symbol_width,
     762             :                                              geometry_rectangle_get_left( &space_and_label ),
     763             :                                              geometry_rectangle_get_width( &space_and_label )
     764             :                                            );
     765          18 :             const double symbol_top = geometry_rectangle_get_top( &label_compartment ) - symbol_height;
     766             :             geometry_rectangle_t classifier_symbol_box;
     767          18 :             geometry_rectangle_init( &classifier_symbol_box, symbol_left, symbol_top, symbol_width, symbol_height );
     768          18 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &classifier_symbol_box );
     769          18 :             geometry_rectangle_destroy( &classifier_symbol_box );
     770             : 
     771             :             /* calculate space */
     772          18 :             const double label_and_symbol_height = geometry_rectangle_get_height( &label_compartment ) + symbol_height;
     773          18 :             geometry_rectangle_shift( &classifier_space, 0.0, label_and_symbol_height );
     774          18 :             geometry_rectangle_enlarge( &classifier_space, 0.0, -label_and_symbol_height );
     775             :         }
     776          64 :         layout_visible_classifier_set_space( io_classifier_layout, &classifier_space );
     777             : 
     778             : 
     779             :         /* calculate label_box */
     780          64 :         layout_visible_classifier_set_label_box( io_classifier_layout, &label_rect );
     781          64 :         layout_visible_classifier_set_label_anchor( io_classifier_layout,
     782             :                                                     GEOMETRY_H_ALIGN_CENTER,
     783             :                                                     GEOMETRY_V_ALIGN_TOP
     784             :                                                   );
     785             : 
     786          64 :         U8_TRACE_INFO("==== symbol_box ====" );
     787          64 :         geometry_rectangle_trace( layout_visible_classifier_get_symbol_box_const( io_classifier_layout ) );
     788          64 :         U8_TRACE_INFO("==== label_box  ====" );
     789          64 :         geometry_rectangle_trace( &label_rect );
     790          64 :         U8_TRACE_INFO("==== space     =====" );
     791          64 :         geometry_rectangle_trace( &classifier_space );
     792             : 
     793          64 :         geometry_rectangle_destroy( &classifier_space );
     794             :     }
     795             :     else
     796             :     {
     797             :         geometry_rectangle_t space_guess;  /* guess the inner space based on current text height */
     798          64 :         geometry_rectangle_copy( &space_guess, &space_and_label );
     799          64 :         geometry_rectangle_shift( &space_guess, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     800          64 :         geometry_rectangle_enlarge( &space_guess, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     801          64 :         U8_TRACE_INFO("==== space_guess====" );
     802          64 :         geometry_rectangle_trace( &space_guess );
     803          64 :         pencil_classifier_composer_expand_space( this_,
     804             :                                                  &space_guess,
     805             :                                                  shows_contained_children,
     806             :                                                  profile,
     807             :                                                  pencil_size,
     808             :                                                  font_layout,
     809             :                                                  io_classifier_layout
     810             :                                                );
     811          64 :         geometry_rectangle_destroy( &space_guess );
     812             : 
     813             :         /* shift/center to requested position after resizing beyond requested size */
     814             :         const geometry_rectangle_t current_envelope
     815          64 :             = layout_visible_classifier_get_envelope_box( io_classifier_layout );
     816          64 :         const double shift_to_right = geometry_rectangle_get_center_x( envelope ) - geometry_rectangle_get_center_x( &current_envelope );
     817          64 :         const double shift_to_bottom = geometry_rectangle_get_center_y( envelope ) - geometry_rectangle_get_center_y( &current_envelope );
     818          64 :         layout_visible_classifier_shift( io_classifier_layout, shift_to_right, shift_to_bottom );
     819             :     }
     820             : 
     821         128 :     geometry_rectangle_destroy( &label_rect );
     822         128 :     geometry_rectangle_destroy( &label_compartment );
     823             : 
     824         128 :     U8_TRACE_END_ERR( area_too_small );
     825         128 :     return area_too_small;
     826             : }
     827             : 
     828         256 : int pencil_classifier_composer_private_get_label_box ( const pencil_classifier_composer_t *this_,
     829             :                                                        const data_visible_classifier_t *visible_classifier,
     830             :                                                        bool shows_contained_children,
     831             :                                                        bool with_stereotype,
     832             :                                                        const geometry_rectangle_t *space_and_label,
     833             :                                                        const geometry_dimensions_t *icon_dim,
     834             :                                                        const pencil_size_t *pencil_size,
     835             :                                                        PangoLayout *font_layout,
     836             :                                                        geometry_rectangle_t *out_label_box,
     837             :                                                        geometry_rectangle_t *out_label_compartment )
     838             : {
     839         256 :     U8_TRACE_BEGIN();
     840         256 :     assert( NULL != visible_classifier );
     841         256 :     assert( NULL != space_and_label );
     842         256 :     assert( NULL != icon_dim );
     843         256 :     assert( NULL != pencil_size );
     844         256 :     assert( NULL != font_layout );
     845         256 :     assert( NULL != out_label_box );
     846         256 :     assert( NULL != out_label_compartment );
     847             : 
     848         256 :     int result = 0;
     849             : 
     850             :     /* get classifier type */
     851             :     const data_classifier_t *const classifier
     852         256 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     853             :     const data_classifier_type_t classifier_type
     854         256 :         = data_classifier_get_main_type( classifier );
     855             : 
     856             :     /* get standard gap size */
     857         256 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     858             : 
     859             :     /* determine stereotype and name dimensions */
     860             :     geometry_dimensions_t label_dim;
     861             :     const bool has_contour
     862         256 :         = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     863         256 :     const double icon_gap
     864         256 :         = ( ! has_contour ) ? 0.0 : ( geometry_dimensions_get_width( icon_dim ) < 0.000001 ) ? 0.0 : gap;
     865         256 :     const double proposed_label_width
     866             :         = has_contour
     867         184 :         ? geometry_rectangle_get_width( space_and_label ) - geometry_dimensions_get_width( icon_dim ) - icon_gap
     868         440 :         : geometry_rectangle_get_width( space_and_label );
     869         512 :     const geometry_dimensions_t proposed_label_dim
     870         256 :         = { .width = proposed_label_width, .height = geometry_rectangle_get_height( space_and_label ) };
     871         256 :     draw_classifier_label_get_stereotype_and_name_dimensions( &((*this_).draw_classifier_label),
     872             :                                                               visible_classifier,
     873             :                                                               with_stereotype,
     874             :                                                               &proposed_label_dim,
     875             :                                                               pencil_size,
     876             :                                                               font_layout,
     877             :                                                               &label_dim
     878             :                                                             );
     879         256 :     const double text_width = geometry_dimensions_get_width( &label_dim );
     880         256 :     const double text_height = geometry_dimensions_get_height( &label_dim );
     881         256 :     if ( text_width > (proposed_label_width + 0.0001) )
     882             :     {
     883         128 :         U8_TRACE_INFO_INT_INT( "label does not fit to provided width",
     884             :                                 (int) text_width,
     885             :                                 (int) proposed_label_width
     886             :                                 );
     887         128 :         result = 1;
     888             :     }
     889         256 :     const double proposed_label_height = geometry_rectangle_get_height( space_and_label );
     890         256 :     if ( text_height > (proposed_label_height + 0.0001) )
     891             :     {
     892         128 :         U8_TRACE_INFO_INT_INT( "label does not fit to provided height",
     893             :                                 (int) text_height,
     894             :                                 (int) proposed_label_height
     895             :                                 );
     896         128 :         result = 1;
     897             :     }
     898             : 
     899         256 :     if ( has_contour )
     900             :     {
     901         184 :         double top_border = geometry_rectangle_get_top( space_and_label );
     902             : 
     903             :         /* calculate label_compartment */
     904             :         {
     905         184 :             const double min_required_width = text_width + icon_gap + geometry_dimensions_get_width( icon_dim );
     906         184 :             const double comp_width = u8_f64_max2( min_required_width, geometry_rectangle_get_width( space_and_label ) );
     907         184 :             const geometry_h_align_t compartment_h_align = GEOMETRY_H_ALIGN_CENTER;
     908         184 :             const double comp_left = geometry_h_align_get_left( &compartment_h_align,
     909             :                                                                 comp_width,
     910             :                                                                 geometry_rectangle_get_left( space_and_label ),
     911             :                                                                 geometry_rectangle_get_width( space_and_label )
     912             :                                                               );
     913         184 :             geometry_rectangle_reinit( out_label_compartment, comp_left, top_border, comp_width, text_height );
     914             :         }
     915             : 
     916             :         /* calculate label_box */
     917         184 :         const bool is_package_with_contents = (classifier_type == DATA_CLASSIFIER_TYPE_PACKAGE) && shows_contained_children;
     918         184 :         if ( is_package_with_contents )
     919             :         {
     920             :             const geometry_rectangle_t envelope
     921           4 :                 = draw_classifier_contour_calc_outer_bounds( &((*this_).draw_classifier_contour),
     922             :                                                              classifier_type,
     923             :                                                              out_label_compartment,
     924             :                                                              pencil_size
     925             :                                                            );
     926           8 :             geometry_rectangle_reinit( out_label_box,
     927           4 :                                        geometry_rectangle_get_left( &envelope ) + 2.0 * gap,
     928           4 :                                        geometry_rectangle_get_top( &envelope ) + 2.0 * gap,
     929             :                                        text_width,
     930             :                                        text_height
     931             :                                      );
     932             :         }
     933             :         else
     934             :         {
     935         180 :             const geometry_h_align_t text_h_align = GEOMETRY_H_ALIGN_CENTER;
     936         360 :             const double text_left = geometry_h_align_get_left( &text_h_align,
     937             :                                                                 text_width,
     938             :                                                                 geometry_rectangle_get_left( space_and_label ),
     939         180 :                                                                 geometry_rectangle_get_width( space_and_label ) - icon_gap - geometry_dimensions_get_width( icon_dim )
     940             :                                                               );
     941         180 :             geometry_rectangle_reinit( out_label_box,
     942             :                                        text_left,
     943             :                                        top_border,
     944             :                                        text_width,
     945             :                                        text_height
     946             :                                      );
     947             :         }
     948             :     }
     949             :     else
     950             :     {
     951             :         /*const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );*/
     952             : 
     953             :         /* calculate text position */
     954          72 :         const geometry_h_align_t text_h_align = GEOMETRY_H_ALIGN_CENTER;
     955          72 :         const double text_left = geometry_h_align_get_left( &text_h_align,
     956             :                                                             text_width,
     957             :                                                             geometry_rectangle_get_left( space_and_label ),
     958             :                                                             geometry_rectangle_get_width( space_and_label )
     959             :                                                           );
     960          72 :         const double text_top = geometry_rectangle_get_top( space_and_label ) /*+ symbol_height*/;
     961             : 
     962             :         /* calculate label_compartment */
     963          72 :         const double comp_width = u8_f64_max2( text_width, geometry_rectangle_get_width( space_and_label ) );
     964          72 :         const geometry_h_align_t compartment_h_align = GEOMETRY_H_ALIGN_CENTER;
     965          72 :         const double comp_left = geometry_h_align_get_left( &compartment_h_align,
     966             :                                                             comp_width,
     967             :                                                             geometry_rectangle_get_left( space_and_label ),
     968             :                                                             geometry_rectangle_get_width( space_and_label )
     969             :                                                           );
     970          72 :         geometry_rectangle_reinit( out_label_compartment, comp_left, text_top, comp_width, text_height );
     971             : 
     972             :         /* calculate label_box */
     973          72 :         geometry_rectangle_reinit( out_label_box, text_left, text_top, text_width, text_height );
     974             :     }
     975             : 
     976         256 :     U8_TRACE_END_ERR( result );
     977         256 :     return result;
     978             : }
     979             : 
     980           0 : void pencil_classifier_composer_private_draw_feature_compartments ( const pencil_classifier_composer_t *this_,
     981             :                                                                     const layout_visible_classifier_t *layouted_classifier,
     982             :                                                                     const pencil_layout_data_t *layout_data,
     983             :                                                                     const pencil_size_t *pencil_size,
     984             :                                                                     cairo_t *cr )
     985             : {
     986           0 :     U8_TRACE_BEGIN();
     987           0 :     assert( NULL != layouted_classifier );
     988           0 :     assert( NULL != layout_data );
     989           0 :     assert( NULL != pencil_size );
     990           0 :     assert( NULL != cr );
     991             : 
     992             :     /* define names for input data */
     993             :     const geometry_rectangle_t *const classifier_symbol_box
     994           0 :         = layout_visible_classifier_get_symbol_box_const( layouted_classifier );
     995             :     const geometry_rectangle_t *const classifier_space
     996           0 :         = layout_visible_classifier_get_space_const( layouted_classifier );
     997           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     998           0 :     const data_row_id_t diagele_id = layout_visible_classifier_get_diagramelement_id ( layouted_classifier );
     999             : 
    1000             :     /* determine number of properties and operations */
    1001           0 :     double compartment1_y = geometry_rectangle_get_top( classifier_space ) + gap;
    1002           0 :     double compartment2_y = geometry_rectangle_get_top( classifier_space ) + 3.0 * gap;
    1003           0 :     double compartment3_y = geometry_rectangle_get_top( classifier_space ) + 5.0 * gap;
    1004           0 :     uint_fast32_t count_compartment_entries = 0;
    1005             : 
    1006           0 :     const uint32_t num_features = pencil_layout_data_get_feature_count ( layout_data );
    1007           0 :     for ( uint32_t f_probe_idx = 0; f_probe_idx < num_features; f_probe_idx ++ )
    1008             :     {
    1009           0 :         const layout_feature_t *const f_probe_layout = pencil_layout_data_get_feature_const ( layout_data, f_probe_idx );
    1010           0 :         assert ( NULL != f_probe_layout );
    1011           0 :         const layout_visible_classifier_t *const probe_vis_classfy = layout_feature_get_classifier_const ( f_probe_layout );
    1012           0 :         assert ( NULL != probe_vis_classfy );
    1013             : 
    1014             :         /* check if this f_probe_layout has the same diagram element id as the_feature */
    1015           0 :         if ( diagele_id == layout_visible_classifier_get_diagramelement_id( probe_vis_classfy ) )
    1016             :         {
    1017             :             /* this is a feature of the current layouted_classifier */
    1018           0 :             const data_feature_t *const f_probe_data = layout_feature_get_data_const( f_probe_layout );
    1019           0 :             assert ( NULL != f_probe_data );
    1020           0 :             const data_feature_type_t f_probe_type = data_feature_get_main_type( f_probe_data );
    1021             :             const double f_probe_bottom
    1022           0 :                 = geometry_rectangle_get_bottom( layout_feature_get_symbol_box_const( f_probe_layout ) );
    1023           0 :             if ( data_feature_type_inside_compartment( f_probe_type ) )
    1024             :             {
    1025           0 :                 count_compartment_entries ++;
    1026             :             }
    1027           0 :             if ( DATA_FEATURE_TYPE_PROPERTY == f_probe_type )
    1028             :             {
    1029           0 :                 compartment2_y = u8_f64_max2( compartment2_y, f_probe_bottom + gap );
    1030           0 :                 compartment3_y = u8_f64_max2( compartment3_y, f_probe_bottom + 3.0 * gap );
    1031             :             }
    1032           0 :             else if ( DATA_FEATURE_TYPE_OPERATION == f_probe_type )
    1033             :             {
    1034           0 :                 compartment3_y = u8_f64_max2( compartment3_y, f_probe_bottom + gap );
    1035             :             }
    1036             :         }
    1037             :     }
    1038             : 
    1039             :     /* draw compartments if there are features */
    1040           0 :     if ( count_compartment_entries != 0 )
    1041             :     {
    1042             :         const data_visible_classifier_t *const visible_classifier
    1043           0 :             = layout_visible_classifier_get_data_const( layouted_classifier );
    1044             :         const data_classifier_t *const classifier
    1045           0 :             = data_visible_classifier_get_classifier_const( visible_classifier );
    1046           0 :         const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
    1047             : 
    1048           0 :         draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
    1049             :                                                         classifier_type,
    1050             :                                                         classifier_symbol_box,
    1051             :                                                         compartment1_y,
    1052             :                                                         pencil_size,
    1053             :                                                         cr
    1054             :                                                       );
    1055           0 :         draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
    1056             :                                                         classifier_type,
    1057             :                                                         classifier_symbol_box,
    1058             :                                                         compartment2_y,
    1059             :                                                         pencil_size,
    1060             :                                                         cr
    1061             :                                                       );
    1062           0 :         draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
    1063             :                                                         classifier_type,
    1064             :                                                         classifier_symbol_box,
    1065             :                                                         compartment3_y,
    1066             :                                                         pencil_size,
    1067             :                                                         cr
    1068             :                                                       );
    1069             :     }
    1070             : 
    1071           0 :     U8_TRACE_END();
    1072           0 : }
    1073             : 
    1074             : 
    1075             : /*
    1076             : Copyright 2016-2024 Andreas Warnke
    1077             :     http://www.apache.org/licenses/LICENSE-2.0
    1078             : 
    1079             : Licensed under the Apache License, Version 2.0 (the "License");
    1080             : you may not use this file except in compliance with the License.
    1081             : You may obtain a copy of the License at
    1082             : 
    1083             : 
    1084             : Unless required by applicable law or agreed to in writing, software
    1085             : distributed under the License is distributed on an "AS IS" BASIS,
    1086             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1087             : See the License for the specific language governing permissions and
    1088             : limitations under the License.
    1089             : */

Generated by: LCOV version 1.16