LCOV - code coverage report
Current view: top level - pencil/source - pencil_classifier_composer.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 203 410 49.5 %
Date: 2024-10-26 21:44:38 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 ( 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 layout_visible_set_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           0 :         if ( data_small_set_contains_row_id( mark_selected, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id(diagramelement) ) )
     461             :         {
     462           0 :             pencil_marker_mark_selected_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
     463             :         }
     464             : 
     465           0 :         if ( data_id_equals_id( &mark_focused, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id(diagramelement) )
     466           0 :             ||  data_id_equals_id( &mark_focused, DATA_TABLE_CLASSIFIER, data_classifier_get_row_id(classifier) ) )
     467             :         {
     468           0 :             pencil_marker_mark_focused_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
     469             :         }
     470             :     }
     471             : 
     472           0 :     U8_TRACE_END();
     473           0 : }
     474             : 
     475         128 : int pencil_classifier_composer_expand_space ( pencil_classifier_composer_t *this_,
     476             :                                               const geometry_rectangle_t *space,
     477             :                                               bool shows_contained_children,
     478             :                                               const data_profile_part_t *profile,
     479             :                                               const pencil_size_t *pencil_size,
     480             :                                               PangoLayout *font_layout,
     481             :                                               layout_visible_classifier_t *io_classifier_layout )
     482             : {
     483         128 :     U8_TRACE_BEGIN();
     484         128 :     assert( NULL != space );
     485         128 :     assert( NULL != pencil_size );
     486         128 :     assert( NULL != font_layout );
     487         128 :     assert( NULL != io_classifier_layout );
     488             : 
     489             :     /* get data that shall be layouted/composed */
     490             :     const data_visible_classifier_t *const visible_classifier
     491         128 :         = layout_visible_classifier_get_data_const( io_classifier_layout );
     492             :     const data_classifier_t *const classifier
     493         128 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     494             :     const data_classifier_type_t classifier_type
     495         128 :         = data_classifier_get_main_type( classifier );
     496         128 :     const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
     497             :     const bool has_stereotype_image
     498         128 :         = draw_stereotype_image_exists( &((*this_).draw_stereotype_image), classifier_stereotype, profile );
     499             : 
     500         128 :     U8_TRACE_INFO_INT("expanding bounds of classifier id:", data_classifier_get_row_id( classifier ) );
     501         128 :     U8_TRACE_INFO_INT_INT("expanding bounds of classifier type, children:", classifier_type, shows_contained_children?1:0 );
     502             : 
     503             :     /* determine icon space */
     504             :     const geometry_dimensions_t icon_dim
     505             :         = has_stereotype_image
     506           0 :         ? draw_stereotype_image_get_dimensions( &((*this_).draw_stereotype_image),
     507             :                                                 pencil_size
     508             :                                               )
     509         128 :         : draw_classifier_icon_get_icon_dimensions( &((*this_).draw_classifier_icon),
     510             :                                                     classifier_type,
     511             :                                                     pencil_size
     512             :                                                   );
     513             : 
     514             :     /* determine border sizes of the main line (label and optionally icon) */
     515             :     geometry_rectangle_t label_rect;
     516         128 :     geometry_rectangle_init_empty( &label_rect );
     517             :     geometry_rectangle_t label_compartment;
     518         128 :     geometry_rectangle_init_empty( &label_compartment );
     519         128 :     const geometry_rectangle_t *space_and_label_fake = space;  /* fake space_and_label to be identical to requested space */
     520             :     const int area_too_small
     521         128 :         = pencil_classifier_composer_private_get_label_box( this_,
     522             :                                                             visible_classifier,
     523             :                                                             shows_contained_children,
     524             :                                                             ( ! has_stereotype_image ),
     525             :                                                             space_and_label_fake,
     526             :                                                             &icon_dim,
     527             :                                                             pencil_size,
     528             :                                                             font_layout,
     529             :                                                             &label_rect,
     530             :                                                             &label_compartment
     531         128 :                                                           );
     532         128 :     if ( area_too_small != 0 )
     533             :     {
     534          64 :         U8_TRACE_INFO("new width is defined by label-and-icon, not by requested inner space" );
     535             :     }
     536         128 :     const double label_top = geometry_rectangle_get_top( space ) - geometry_rectangle_get_height( &label_compartment );
     537         128 :     geometry_rectangle_set_top( &label_rect, label_top );
     538         128 :     geometry_rectangle_set_top( &label_compartment, label_top );
     539             : 
     540             :     /* sizes of geometric objects are determined, */
     541             :     /* now position the geometric objects */
     542             :     {
     543             :         const bool has_contour
     544         128 :             = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     545             : 
     546         128 :         if ( has_contour )
     547             :         {
     548          92 :             U8_TRACE_INFO("calculating symbol box as envelope around label and space..." );
     549             : 
     550             :             /* calculate symbol bounds */
     551             :             geometry_rectangle_t inner_area;
     552          92 :             if ( area_too_small )
     553             :             {
     554          92 :                 geometry_rectangle_init( &inner_area,
     555             :                                          geometry_rectangle_get_left( &label_compartment ),
     556             :                                          geometry_rectangle_get_top( &label_compartment ),
     557             :                                          geometry_rectangle_get_width( &label_compartment ),
     558          46 :                                          geometry_rectangle_get_height( &label_compartment )
     559          46 :                                          + geometry_rectangle_get_height( space )
     560             :                                        );
     561             :             }
     562             :             else
     563             :             {
     564          46 :                 geometry_rectangle_copy( &inner_area, space );
     565          46 :                 geometry_rectangle_shift( &inner_area, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     566          46 :                 geometry_rectangle_enlarge( &inner_area, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     567             :             }
     568             :             const geometry_rectangle_t envelope
     569          92 :                 = draw_classifier_contour_calc_outer_bounds( &((*this_).draw_classifier_contour),
     570             :                                                              classifier_type,
     571             :                                                              &inner_area,
     572             :                                                              pencil_size
     573             :                                                            );
     574          92 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &envelope );
     575          92 :             geometry_rectangle_destroy( &inner_area );
     576             :         }
     577             :         else
     578             :         {
     579          36 :             U8_TRACE_INFO("calculating symbol box for fixed-sized icon..." );
     580             : 
     581          36 :             const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );
     582          36 :             const double symbol_width = symbol_height;
     583             : 
     584             :             /* calculate symbol bounds */
     585          36 :             const geometry_h_align_t H_CENTER = GEOMETRY_H_ALIGN_CENTER;
     586             :             const double symbol_left
     587          36 :                 = geometry_h_align_get_left( &H_CENTER,
     588             :                                              symbol_width,
     589             :                                              geometry_rectangle_get_left( space ),
     590             :                                              geometry_rectangle_get_width( space )
     591             :                                            );
     592          36 :             const double symbol_top = geometry_rectangle_get_top( &label_compartment ) - symbol_height;
     593             :             geometry_rectangle_t classifier_symbol_box;
     594          36 :             geometry_rectangle_init( &classifier_symbol_box, symbol_left, symbol_top, symbol_width, symbol_height );
     595          36 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &classifier_symbol_box );
     596          36 :             geometry_rectangle_destroy( &classifier_symbol_box );
     597             :         }
     598             : 
     599             :         /* calculate label_box */
     600         128 :         layout_visible_classifier_set_label_box( io_classifier_layout, &label_rect );
     601         128 :         layout_visible_classifier_set_label_anchor( io_classifier_layout,
     602             :                                                     GEOMETRY_H_ALIGN_CENTER,
     603             :                                                     GEOMETRY_V_ALIGN_TOP
     604             :                                                   );
     605             : 
     606             :         /* calculate space */
     607             :         /* get the symbol and label boxes and inner space rectangles to modify */
     608             :         geometry_rectangle_t classifier_space;
     609         128 :         geometry_rectangle_init( &classifier_space,
     610             :                                  geometry_rectangle_get_left( &label_compartment ),
     611             :                                  geometry_rectangle_get_top( space ),
     612             :                                  geometry_rectangle_get_width( &label_compartment ),
     613             :                                  geometry_rectangle_get_height( space )
     614             :                                );
     615         128 :         layout_visible_classifier_set_space( io_classifier_layout, &classifier_space );
     616         128 :         geometry_rectangle_destroy( &classifier_space );
     617             :     }
     618             : 
     619         128 :     U8_TRACE_INFO("==== symbol_box ====" );
     620         128 :     geometry_rectangle_trace( layout_visible_classifier_get_symbol_box_const( io_classifier_layout ) );
     621         128 :     U8_TRACE_INFO("==== label_box  ====" );
     622         128 :     geometry_rectangle_trace( &label_rect );
     623         128 :     U8_TRACE_INFO("==== space     =====" );
     624         128 :     geometry_rectangle_trace( layout_visible_classifier_get_space_const( io_classifier_layout ) );
     625             : 
     626         128 :     geometry_rectangle_destroy( &label_rect );
     627         128 :     geometry_rectangle_destroy( &label_compartment );
     628             : 
     629         128 :     U8_TRACE_END_ERR(area_too_small);
     630         128 :     return area_too_small;
     631             : }
     632             : 
     633         128 : int pencil_classifier_composer_set_envelope_box( pencil_classifier_composer_t *this_,
     634             :                                                  const geometry_rectangle_t *envelope,
     635             :                                                  bool shows_contained_children,
     636             :                                                  const data_profile_part_t *profile,
     637             :                                                  const pencil_size_t *pencil_size,
     638             :                                                  PangoLayout *font_layout,
     639             :                                                  layout_visible_classifier_t *io_classifier_layout )
     640             : {
     641         128 :     U8_TRACE_BEGIN();
     642         128 :     assert( NULL != envelope );
     643         128 :     assert( NULL != pencil_size );
     644         128 :     assert( NULL != font_layout );
     645         128 :     assert( NULL != io_classifier_layout );
     646             : 
     647             :     /* get data that shall be layouted/composed */
     648             :     const data_visible_classifier_t *const visible_classifier
     649         128 :         = layout_visible_classifier_get_data_const( io_classifier_layout );
     650             :     const data_classifier_t *const classifier
     651         128 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     652             :     const data_classifier_type_t classifier_type
     653         128 :         = data_classifier_get_main_type( classifier );
     654         128 :     const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
     655             :     const bool has_stereotype_image
     656         128 :         = draw_stereotype_image_exists( &((*this_).draw_stereotype_image), classifier_stereotype, profile );
     657             : 
     658         128 :     U8_TRACE_INFO_INT("calculating bounds of classifier id, type:", data_classifier_get_row_id( classifier ) );
     659         128 :     U8_TRACE_INFO_INT_INT("calculating bounds of classifier type, children:", classifier_type, shows_contained_children?1:0 );
     660             : 
     661             :     /* determine icon space */
     662             :     const geometry_dimensions_t icon_dim
     663             :         = has_stereotype_image
     664           0 :         ? draw_stereotype_image_get_dimensions( &((*this_).draw_stereotype_image),
     665             :                                                 pencil_size
     666             :                                               )
     667         128 :         : draw_classifier_icon_get_icon_dimensions( &((*this_).draw_classifier_icon),
     668             :                                                     classifier_type,
     669             :                                                     pencil_size
     670             :                                                   );
     671             : 
     672             :     /* determine border sizes of the classifier-shape */
     673             :     const geometry_rectangle_t space_and_label
     674         128 :         = draw_classifier_contour_calc_inner_area( &((*this_).draw_classifier_contour),
     675             :                                                    classifier_type,
     676             :                                                    envelope,
     677             :                                                    pencil_size
     678             :                                                  );
     679             : 
     680             :     /* determine border sizes of the main line (label and optionally icon) */
     681             :     geometry_rectangle_t label_rect;
     682         128 :     geometry_rectangle_init_empty( &label_rect );
     683             :     geometry_rectangle_t label_compartment;
     684         128 :     geometry_rectangle_init_empty( &label_compartment );
     685             :     const int area_too_small
     686         128 :         = pencil_classifier_composer_private_get_label_box( this_,
     687             :                                                             visible_classifier,
     688             :                                                             shows_contained_children,
     689             :                                                             ( ! has_stereotype_image ),
     690             :                                                             &space_and_label,
     691             :                                                             &icon_dim,
     692             :                                                             pencil_size,
     693             :                                                             font_layout,
     694             :                                                             &label_rect,
     695             :                                                             &label_compartment
     696         128 :                                                           );
     697             : 
     698             :     /* if label fits into space_and_label */
     699         128 :     if ( 0 == area_too_small )
     700             :     {
     701             :         const bool has_contour
     702          64 :             = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     703             : 
     704             :         /* get the symbol and label boxes and inner space rectangles to modify */
     705             :         geometry_rectangle_t classifier_space;
     706          64 :         geometry_rectangle_copy( &classifier_space, &space_and_label );
     707             : 
     708          64 :         if ( has_contour )
     709             :         {
     710          46 :             U8_TRACE_INFO("calculating symbol box as envelope around label and space..." );
     711             : 
     712             :             /* calculate symbol bounds */
     713          46 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, envelope );
     714             : 
     715             :             /* calculate space */
     716          46 :             geometry_rectangle_shift( &classifier_space, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     717          46 :             geometry_rectangle_enlarge( &classifier_space, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     718             :         }
     719             :         else
     720             :         {
     721          18 :             U8_TRACE_INFO("calculating symbol box for fixed-sized icon..." );
     722             : 
     723          18 :             const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );
     724          18 :             const double symbol_width = symbol_height;
     725             : 
     726             :             /* calculate symbol bounds */
     727          18 :             const geometry_h_align_t H_CENTER = GEOMETRY_H_ALIGN_CENTER;
     728             :             const double symbol_left
     729          18 :                 = geometry_h_align_get_left( &H_CENTER,
     730             :                                              symbol_width,
     731             :                                              geometry_rectangle_get_left( &space_and_label ),
     732             :                                              geometry_rectangle_get_width( &space_and_label )
     733             :                                            );
     734          18 :             const double symbol_top = geometry_rectangle_get_top( &label_compartment ) - symbol_height;
     735             :             geometry_rectangle_t classifier_symbol_box;
     736          18 :             geometry_rectangle_init( &classifier_symbol_box, symbol_left, symbol_top, symbol_width, symbol_height );
     737          18 :             layout_visible_classifier_set_symbol_box( io_classifier_layout, &classifier_symbol_box );
     738          18 :             geometry_rectangle_destroy( &classifier_symbol_box );
     739             : 
     740             :             /* calculate space */
     741          18 :             const double label_and_symbol_height = geometry_rectangle_get_height( &label_compartment ) + symbol_height;
     742          18 :             geometry_rectangle_shift( &classifier_space, 0.0, label_and_symbol_height );
     743          18 :             geometry_rectangle_enlarge( &classifier_space, 0.0, -label_and_symbol_height );
     744             :         }
     745          64 :         layout_visible_classifier_set_space( io_classifier_layout, &classifier_space );
     746             : 
     747             : 
     748             :         /* calculate label_box */
     749          64 :         layout_visible_classifier_set_label_box( io_classifier_layout, &label_rect );
     750          64 :         layout_visible_classifier_set_label_anchor( io_classifier_layout,
     751             :                                                     GEOMETRY_H_ALIGN_CENTER,
     752             :                                                     GEOMETRY_V_ALIGN_TOP
     753             :                                                   );
     754             : 
     755          64 :         U8_TRACE_INFO("==== symbol_box ====" );
     756          64 :         geometry_rectangle_trace( layout_visible_classifier_get_symbol_box_const( io_classifier_layout ) );
     757          64 :         U8_TRACE_INFO("==== label_box  ====" );
     758          64 :         geometry_rectangle_trace( &label_rect );
     759          64 :         U8_TRACE_INFO("==== space     =====" );
     760          64 :         geometry_rectangle_trace( &classifier_space );
     761             : 
     762          64 :         geometry_rectangle_destroy( &classifier_space );
     763             :     }
     764             :     else
     765             :     {
     766             :         geometry_rectangle_t space_guess;  /* guess the inner space based on current text height */
     767          64 :         geometry_rectangle_copy( &space_guess, &space_and_label );
     768          64 :         geometry_rectangle_shift( &space_guess, 0.0, geometry_rectangle_get_height( &label_compartment ) );
     769          64 :         geometry_rectangle_enlarge( &space_guess, 0.0, -geometry_rectangle_get_height( &label_compartment ) );
     770          64 :         U8_TRACE_INFO("==== space_guess====" );
     771          64 :         geometry_rectangle_trace( &space_guess );
     772          64 :         pencil_classifier_composer_expand_space( this_,
     773             :                                                  &space_guess,
     774             :                                                  shows_contained_children,
     775             :                                                  profile,
     776             :                                                  pencil_size,
     777             :                                                  font_layout,
     778             :                                                  io_classifier_layout
     779             :                                                );
     780          64 :         geometry_rectangle_destroy( &space_guess );
     781             : 
     782             :         /* shift/center to requested position after resizing beyond requested size */
     783             :         const geometry_rectangle_t current_envelope
     784          64 :             = layout_visible_classifier_get_envelope_box( io_classifier_layout );
     785          64 :         const double shift_to_right = geometry_rectangle_get_center_x( envelope ) - geometry_rectangle_get_center_x( &current_envelope );
     786          64 :         const double shift_to_bottom = geometry_rectangle_get_center_y( envelope ) - geometry_rectangle_get_center_y( &current_envelope );
     787          64 :         layout_visible_classifier_shift( io_classifier_layout, shift_to_right, shift_to_bottom );
     788             :     }
     789             : 
     790         128 :     geometry_rectangle_destroy( &label_rect );
     791         128 :     geometry_rectangle_destroy( &label_compartment );
     792             : 
     793         128 :     U8_TRACE_END_ERR( area_too_small );
     794         128 :     return area_too_small;
     795             : }
     796             : 
     797         256 : int pencil_classifier_composer_private_get_label_box ( pencil_classifier_composer_t *this_,
     798             :                                                        const data_visible_classifier_t *visible_classifier,
     799             :                                                        bool shows_contained_children,
     800             :                                                        bool with_stereotype,
     801             :                                                        const geometry_rectangle_t *space_and_label,
     802             :                                                        const geometry_dimensions_t *icon_dim,
     803             :                                                        const pencil_size_t *pencil_size,
     804             :                                                        PangoLayout *font_layout,
     805             :                                                        geometry_rectangle_t *out_label_box,
     806             :                                                        geometry_rectangle_t *out_label_compartment )
     807             : {
     808         256 :     U8_TRACE_BEGIN();
     809         256 :     assert( NULL != visible_classifier );
     810         256 :     assert( NULL != space_and_label );
     811         256 :     assert( NULL != icon_dim );
     812         256 :     assert( NULL != pencil_size );
     813         256 :     assert( NULL != font_layout );
     814         256 :     assert( NULL != out_label_box );
     815         256 :     assert( NULL != out_label_compartment );
     816             : 
     817         256 :     int result = 0;
     818             : 
     819             :     /* get classifier type */
     820             :     const data_classifier_t *const classifier
     821         256 :         = data_visible_classifier_get_classifier_const( visible_classifier );
     822             :     const data_classifier_type_t classifier_type
     823         256 :         = data_classifier_get_main_type( classifier );
     824             : 
     825             :     /* get standard gap size */
     826         256 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     827             : 
     828             :     /* determine stereotype and name dimensions */
     829             :     geometry_dimensions_t label_dim;
     830             :     const bool has_contour
     831         256 :         = draw_classifier_contour_has_contour( &((*this_).draw_classifier_contour), classifier_type );
     832         256 :     const double icon_gap
     833         256 :         = ( ! has_contour ) ? 0.0 : ( geometry_dimensions_get_width( icon_dim ) < 0.000001 ) ? 0.0 : gap;
     834         256 :     const double proposed_label_width
     835             :         = has_contour
     836         184 :         ? geometry_rectangle_get_width( space_and_label ) - geometry_dimensions_get_width( icon_dim ) - icon_gap
     837         440 :         : geometry_rectangle_get_width( space_and_label );
     838         512 :     const geometry_dimensions_t proposed_label_dim
     839         256 :         = { .width = proposed_label_width, .height = geometry_rectangle_get_height( space_and_label ) };
     840         256 :     draw_classifier_label_get_stereotype_and_name_dimensions( &((*this_).draw_classifier_label),
     841             :                                                               visible_classifier,
     842             :                                                               with_stereotype,
     843             :                                                               &proposed_label_dim,
     844             :                                                               pencil_size,
     845             :                                                               font_layout,
     846             :                                                               &label_dim
     847             :                                                             );
     848         256 :     const double text_width = geometry_dimensions_get_width( &label_dim );
     849         256 :     const double text_height = geometry_dimensions_get_height( &label_dim );
     850         256 :     if ( text_width > (proposed_label_width + 0.0001) )
     851             :     {
     852         128 :         U8_TRACE_INFO_INT_INT( "label does not fit to provided width",
     853             :                                 (int) text_width,
     854             :                                 (int) proposed_label_width
     855             :                                 );
     856         128 :         result = 1;
     857             :     }
     858         256 :     const double proposed_label_height = geometry_rectangle_get_height( space_and_label );
     859         256 :     if ( text_height > (proposed_label_height + 0.0001) )
     860             :     {
     861         128 :         U8_TRACE_INFO_INT_INT( "label does not fit to provided height",
     862             :                                 (int) text_height,
     863             :                                 (int) proposed_label_height
     864             :                                 );
     865         128 :         result = 1;
     866             :     }
     867             : 
     868         256 :     if ( has_contour )
     869             :     {
     870         184 :         double top_border = geometry_rectangle_get_top( space_and_label );
     871             : 
     872             :         /* calculate label_compartment */
     873             :         {
     874         184 :             const double min_required_width = text_width + icon_gap + geometry_dimensions_get_width( icon_dim );
     875         184 :             const double comp_width = u8_f64_max2( min_required_width, geometry_rectangle_get_width( space_and_label ) );
     876         184 :             const geometry_h_align_t compartment_h_align = GEOMETRY_H_ALIGN_CENTER;
     877         184 :             const double comp_left = geometry_h_align_get_left( &compartment_h_align,
     878             :                                                                 comp_width,
     879             :                                                                 geometry_rectangle_get_left( space_and_label ),
     880             :                                                                 geometry_rectangle_get_width( space_and_label )
     881             :                                                               );
     882         184 :             geometry_rectangle_reinit( out_label_compartment, comp_left, top_border, comp_width, text_height );
     883             :         }
     884             : 
     885             :         /* calculate label_box */
     886         184 :         const bool is_package_with_contents = (classifier_type == DATA_CLASSIFIER_TYPE_PACKAGE) && shows_contained_children;
     887         184 :         if ( is_package_with_contents )
     888             :         {
     889             :             const geometry_rectangle_t envelope
     890           4 :                 = draw_classifier_contour_calc_outer_bounds( &((*this_).draw_classifier_contour),
     891             :                                                              classifier_type,
     892             :                                                              out_label_compartment,
     893             :                                                              pencil_size
     894             :                                                            );
     895           8 :             geometry_rectangle_reinit( out_label_box,
     896           4 :                                        geometry_rectangle_get_left( &envelope ) + 2.0 * gap,
     897           4 :                                        geometry_rectangle_get_top( &envelope ) + 2.0 * gap,
     898             :                                        text_width,
     899             :                                        text_height
     900             :                                      );
     901             :         }
     902             :         else
     903             :         {
     904         180 :             const geometry_h_align_t text_h_align = GEOMETRY_H_ALIGN_CENTER;
     905         360 :             const double text_left = geometry_h_align_get_left( &text_h_align,
     906             :                                                                 text_width,
     907             :                                                                 geometry_rectangle_get_left( space_and_label ),
     908         180 :                                                                 geometry_rectangle_get_width( space_and_label ) - icon_gap - geometry_dimensions_get_width( icon_dim )
     909             :                                                               );
     910         180 :             geometry_rectangle_reinit( out_label_box,
     911             :                                        text_left,
     912             :                                        top_border,
     913             :                                        text_width,
     914             :                                        text_height
     915             :                                      );
     916             :         }
     917             :     }
     918             :     else
     919             :     {
     920             :         /*const double symbol_height = pencil_size_get_classifier_symbol_height( pencil_size );*/
     921             : 
     922             :         /* calculate text position */
     923          72 :         const geometry_h_align_t text_h_align = GEOMETRY_H_ALIGN_CENTER;
     924          72 :         const double text_left = geometry_h_align_get_left( &text_h_align,
     925             :                                                             text_width,
     926             :                                                             geometry_rectangle_get_left( space_and_label ),
     927             :                                                             geometry_rectangle_get_width( space_and_label )
     928             :                                                           );
     929          72 :         const double text_top = geometry_rectangle_get_top( space_and_label ) /*+ symbol_height*/;
     930             : 
     931             :         /* calculate label_compartment */
     932          72 :         const double comp_width = u8_f64_max2( text_width, geometry_rectangle_get_width( space_and_label ) );
     933          72 :         const geometry_h_align_t compartment_h_align = GEOMETRY_H_ALIGN_CENTER;
     934          72 :         const double comp_left = geometry_h_align_get_left( &compartment_h_align,
     935             :                                                             comp_width,
     936             :                                                             geometry_rectangle_get_left( space_and_label ),
     937             :                                                             geometry_rectangle_get_width( space_and_label )
     938             :                                                           );
     939          72 :         geometry_rectangle_reinit( out_label_compartment, comp_left, text_top, comp_width, text_height );
     940             : 
     941             :         /* calculate label_box */
     942          72 :         geometry_rectangle_reinit( out_label_box, text_left, text_top, text_width, text_height );
     943             :     }
     944             : 
     945         256 :     U8_TRACE_END_ERR( result );
     946         256 :     return result;
     947             : }
     948             : 
     949           0 : void pencil_classifier_composer_private_draw_feature_compartments ( const pencil_classifier_composer_t *this_,
     950             :                                                                     const layout_visible_classifier_t *layouted_classifier,
     951             :                                                                     const layout_visible_set_t *layout_data,
     952             :                                                                     const pencil_size_t *pencil_size,
     953             :                                                                     cairo_t *cr )
     954             : {
     955           0 :     U8_TRACE_BEGIN();
     956           0 :     assert( NULL != layouted_classifier );
     957           0 :     assert( NULL != layout_data );
     958           0 :     assert( NULL != pencil_size );
     959           0 :     assert( NULL != cr );
     960             : 
     961             :     /* define names for input data */
     962             :     const geometry_rectangle_t *const classifier_symbol_box
     963           0 :         = layout_visible_classifier_get_symbol_box_const( layouted_classifier );
     964             :     const geometry_rectangle_t *const classifier_space
     965           0 :         = layout_visible_classifier_get_space_const( layouted_classifier );
     966           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     967           0 :     const data_row_id_t diagele_id = layout_visible_classifier_get_diagramelement_id ( layouted_classifier );
     968             : 
     969             :     /* determine number of properties and operations */
     970           0 :     double compartment1_y = geometry_rectangle_get_top( classifier_space ) + gap;
     971           0 :     double compartment2_y = geometry_rectangle_get_top( classifier_space ) + 3.0 * gap;
     972           0 :     double compartment3_y = geometry_rectangle_get_top( classifier_space ) + 5.0 * gap;
     973           0 :     uint_fast32_t count_compartment_entries = 0;
     974             : 
     975           0 :     const uint32_t num_features = layout_visible_set_get_feature_count ( layout_data );
     976           0 :     for ( uint32_t f_probe_idx = 0; f_probe_idx < num_features; f_probe_idx ++ )
     977             :     {
     978           0 :         const layout_feature_t *const f_probe_layout = layout_visible_set_get_feature_const ( layout_data, f_probe_idx );
     979           0 :         assert ( NULL != f_probe_layout );
     980           0 :         const layout_visible_classifier_t *const probe_vis_classfy = layout_feature_get_classifier_const ( f_probe_layout );
     981           0 :         assert ( NULL != probe_vis_classfy );
     982             : 
     983             :         /* check if this f_probe_layout has the same diagram element id as the_feature */
     984           0 :         if ( diagele_id == layout_visible_classifier_get_diagramelement_id( probe_vis_classfy ) )
     985             :         {
     986             :             /* this is a feature of the current layouted_classifier */
     987           0 :             const data_feature_t *const f_probe_data = layout_feature_get_data_const( f_probe_layout );
     988           0 :             assert ( NULL != f_probe_data );
     989           0 :             const data_feature_type_t f_probe_type = data_feature_get_main_type( f_probe_data );
     990             :             const double f_probe_bottom
     991           0 :                 = geometry_rectangle_get_bottom( layout_feature_get_symbol_box_const( f_probe_layout ) );
     992           0 :             if ( data_feature_type_inside_compartment( f_probe_type ) )
     993             :             {
     994           0 :                 count_compartment_entries ++;
     995             :             }
     996           0 :             if ( DATA_FEATURE_TYPE_PROPERTY == f_probe_type )
     997             :             {
     998           0 :                 compartment2_y = u8_f64_max2( compartment2_y, f_probe_bottom + gap );
     999           0 :                 compartment3_y = u8_f64_max2( compartment3_y, f_probe_bottom + 3.0 * gap );
    1000             :             }
    1001           0 :             else if ( DATA_FEATURE_TYPE_OPERATION == f_probe_type )
    1002             :             {
    1003           0 :                 compartment3_y = u8_f64_max2( compartment3_y, f_probe_bottom + gap );
    1004             :             }
    1005             :         }
    1006             :     }
    1007             : 
    1008             :     /* draw compartments if there are features */
    1009           0 :     if ( count_compartment_entries != 0 )
    1010             :     {
    1011             :         const data_visible_classifier_t *const visible_classifier
    1012           0 :             = layout_visible_classifier_get_data_const( layouted_classifier );
    1013             :         const data_classifier_t *const classifier
    1014           0 :             = data_visible_classifier_get_classifier_const( visible_classifier );
    1015           0 :         const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
    1016             : 
    1017           0 :         draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
    1018             :                                                         classifier_type,
    1019             :                                                         classifier_symbol_box,
    1020             :                                                         compartment1_y,
    1021             :                                                         pencil_size,
    1022             :                                                         cr
    1023             :                                                       );
    1024           0 :         draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
    1025             :                                                         classifier_type,
    1026             :                                                         classifier_symbol_box,
    1027             :                                                         compartment2_y,
    1028             :                                                         pencil_size,
    1029             :                                                         cr
    1030             :                                                       );
    1031           0 :         draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
    1032             :                                                         classifier_type,
    1033             :                                                         classifier_symbol_box,
    1034             :                                                         compartment3_y,
    1035             :                                                         pencil_size,
    1036             :                                                         cr
    1037             :                                                       );
    1038             :     }
    1039             : 
    1040           0 :     U8_TRACE_END();
    1041           0 : }
    1042             : 
    1043             : 
    1044             : /*
    1045             : Copyright 2016-2024 Andreas Warnke
    1046             :     http://www.apache.org/licenses/LICENSE-2.0
    1047             : 
    1048             : Licensed under the Apache License, Version 2.0 (the "License");
    1049             : you may not use this file except in compliance with the License.
    1050             : You may obtain a copy of the License at
    1051             : 
    1052             : 
    1053             : Unless required by applicable law or agreed to in writing, software
    1054             : distributed under the License is distributed on an "AS IS" BASIS,
    1055             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1056             : See the License for the specific language governing permissions and
    1057             : limitations under the License.
    1058             : */

Generated by: LCOV version 1.16