LCOV - code coverage report
Current view: top level - pencil/source/draw - draw_classifier_contour.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 124 392 31.6 %
Date: 2024-10-26 21:44:38 Functions: 2 12 16.7 %

          Line data    Source code
       1             : /* File: draw_classifier_contour.c; Copyright and License: see below */
       2             : 
       3             : #include "draw/draw_classifier_contour.h"
       4             : #include "draw/draw_classifier_icon.h"
       5             : #include "u8/u8_trace.h"
       6             : #include <stdio.h>
       7             : #include <stdlib.h>
       8             : #include <assert.h>
       9             : #include <math.h>
      10             : 
      11             : /*! where to place the control points of a bezier curve to get a good approximation for a 90 degree curve */
      12             : const static double BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE = 0.552284749831;
      13             : 
      14             : const static double SINUS_OF_45_DEGREE = 0.707106781;
      15             : 
      16         161 : geometry_rectangle_t draw_classifier_contour_calc_inner_area ( const draw_classifier_contour_t *this_,
      17             :                                                                data_classifier_type_t classifier_type,
      18             :                                                                const geometry_rectangle_t *outer_bounds,
      19             :                                                                const pencil_size_t *pencil_size )
      20             : {
      21         161 :     U8_TRACE_BEGIN();
      22         161 :     assert ( NULL != outer_bounds );
      23         161 :     assert ( NULL != pencil_size );
      24             : 
      25             :     geometry_rectangle_t result;
      26         161 :     geometry_rectangle_init_empty( &result );
      27             : 
      28         161 :     double gap = pencil_size_get_standard_object_border( pencil_size );
      29         161 :     double double_gap = 2.0 * gap;  /* a line has the gap distance on both sides to the next object */
      30             : 
      31         161 :     switch ( classifier_type )
      32             :     {
      33           6 :         case DATA_CLASSIFIER_TYPE_USE_CASE:
      34             :         {
      35             :             /* within a use case, space is limited (double_gap is the border on each side): */
      36           6 :             double inner_x_radius = 0.5 * geometry_rectangle_get_width( outer_bounds ) - double_gap;
      37           6 :             double inner_y_radius = 0.5 * geometry_rectangle_get_height( outer_bounds ) - double_gap;
      38           6 :             double h_offset = (1.0 - SINUS_OF_45_DEGREE) * inner_x_radius;
      39           6 :             double v_offset = (1.0 - SINUS_OF_45_DEGREE) * inner_y_radius;
      40             : 
      41           6 :             geometry_rectangle_replace( &result, outer_bounds );
      42           6 :             geometry_rectangle_expand_4dir( &result, -double_gap - h_offset, -double_gap - v_offset );
      43             :         }
      44           6 :         break;
      45             : 
      46           5 :         case DATA_CLASSIFIER_TYPE_NODE:
      47             :         {
      48             :             /* the 3d border of a node shrinks the space */
      49           5 :             double offset_3d = double_gap;
      50             : 
      51           5 :             geometry_rectangle_replace( &result, outer_bounds );
      52           5 :             geometry_rectangle_enlarge( &result, -2.0 * double_gap - offset_3d, -2.0 * double_gap - offset_3d );
      53           5 :             geometry_rectangle_shift( &result, double_gap, double_gap + offset_3d );
      54             :         }
      55           5 :         break;
      56             : 
      57          45 :         case DATA_CLASSIFIER_TYPE_ACTOR:
      58             :         case DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE:
      59             :         case DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE:
      60             :         case DATA_CLASSIFIER_TYPE_DYN_FORK_NODE:
      61             :         case DATA_CLASSIFIER_TYPE_DYN_JOIN_NODE:
      62             :         case DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY:
      63             :         case DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY:
      64             :         case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_TIME_EVENT:
      65             :         case DATA_CLASSIFIER_TYPE_IMAGE:
      66             :         {
      67             :             /* the symbol icon height is part of the shape border  */
      68          45 :             double symbol_icon_height = pencil_size_get_classifier_symbol_height( pencil_size );
      69             : 
      70          45 :             geometry_rectangle_replace( &result, outer_bounds );
      71          45 :             geometry_rectangle_enlarge( &result, -2.0 * double_gap, -2.0 * double_gap - symbol_icon_height );
      72          45 :             geometry_rectangle_shift( &result, double_gap, double_gap + symbol_icon_height );
      73             :         }
      74          45 :         break;
      75             : 
      76          20 :         case DATA_CLASSIFIER_TYPE_DIAGRAM_REFERENCE:  /* and */
      77             :         case DATA_CLASSIFIER_TYPE_INTERACTION:  /* and */
      78             :         case DATA_CLASSIFIER_TYPE_PACKAGE:  /* and */
      79             :         case DATA_CLASSIFIER_TYPE_COMMENT:
      80             :         {
      81          20 :             double top_ornament_height = pencil_size_get_standard_font_size( pencil_size );
      82             : 
      83          20 :             geometry_rectangle_replace( &result, outer_bounds );
      84          20 :             geometry_rectangle_enlarge( &result, -2.0 * double_gap, -2.0 * double_gap - top_ornament_height );
      85          20 :             geometry_rectangle_shift( &result, double_gap, double_gap + top_ornament_height );
      86             :         }
      87          20 :         break;
      88             : 
      89          70 :         case DATA_CLASSIFIER_TYPE_BLOCK:
      90             :         case DATA_CLASSIFIER_TYPE_REQUIREMENT:
      91             :         case DATA_CLASSIFIER_TYPE_SUBSYSTEM:
      92             :         case DATA_CLASSIFIER_TYPE_ACTIVITY:
      93             :         case DATA_CLASSIFIER_TYPE_STATE:
      94             :         case DATA_CLASSIFIER_TYPE_COMPONENT:
      95             :         case DATA_CLASSIFIER_TYPE_PART:
      96             :         case DATA_CLASSIFIER_TYPE_INTERFACE:
      97             :         case DATA_CLASSIFIER_TYPE_CLASS:
      98             :         case DATA_CLASSIFIER_TYPE_OBJECT:
      99             :         case DATA_CLASSIFIER_TYPE_ARTIFACT:
     100             :         case DATA_CLASSIFIER_TYPE_CONSTRAINT_BLOCK:
     101             :         case DATA_CLASSIFIER_TYPE_DYN_INTERRUPTABLE_REGION:
     102             :         case DATA_CLASSIFIER_TYPE_STEREOTYPE:
     103             :         {
     104             :             /* standard size */
     105          70 :             geometry_rectangle_replace( &result, outer_bounds );
     106          70 :             geometry_rectangle_expand_4dir( &result, -double_gap, -double_gap );
     107             :         }
     108          70 :         break;
     109             : 
     110           5 :         case DATA_CLASSIFIER_TYPE_DYN_DECISION_NODE:
     111             :         {
     112             :             /* within a decision rhombus, space is limited by factor 2 per dimension: */
     113           5 :             double half_outer_width = 0.5 * geometry_rectangle_get_width( outer_bounds ) - double_gap;
     114           5 :             double half_outer_height = 0.5 * geometry_rectangle_get_height( outer_bounds ) - double_gap;
     115           5 :             double h_offset = 0.5 * half_outer_width;
     116           5 :             double v_offset = 0.5 * half_outer_height;
     117             : 
     118           5 :             geometry_rectangle_replace( &result, outer_bounds );
     119           5 :             geometry_rectangle_expand_4dir( &result, -double_gap - h_offset, -double_gap - v_offset );
     120             :         }
     121           5 :         break;
     122             : 
     123           5 :         case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_EVENT :
     124             :         {
     125             :             /* within an accept event, space is limited (double_gap is the border on each side): */
     126           5 :             double half_outer_height = 0.5 * geometry_rectangle_get_height( outer_bounds ) - double_gap;
     127           5 :             double horizontal_offset = half_outer_height;
     128             : 
     129           5 :             geometry_rectangle_replace( &result, outer_bounds );
     130           5 :             geometry_rectangle_enlarge( &result, -2.0 * double_gap - horizontal_offset, -2.0 * double_gap );
     131           5 :             geometry_rectangle_shift( &result, double_gap + horizontal_offset, double_gap );
     132             :         }
     133           5 :         break;
     134             : 
     135           5 :         case DATA_CLASSIFIER_TYPE_DYN_SEND_SIGNAL:
     136             :         {
     137             :             /* within a send signal, space is limited (double_gap is the border on each side): */
     138           5 :             double half_outer_height = 0.5 * geometry_rectangle_get_height( outer_bounds ) - double_gap;
     139           5 :             double horizontal_offset = half_outer_height;
     140             : 
     141           5 :             geometry_rectangle_replace( &result, outer_bounds );
     142           5 :             geometry_rectangle_enlarge( &result, -2.0 * double_gap - horizontal_offset, -2.0 * double_gap );
     143           5 :             geometry_rectangle_shift( &result, double_gap, double_gap );
     144             :         }
     145           5 :         break;
     146             : 
     147           0 :         default:
     148             :         {
     149             :             /* this case can happen if a model file of a new cfu version is opened with an older version of cfu */
     150           0 :             U8_LOG_ANOMALY("unknown data_classifier_type_t in draw_classifier_contour_calc_inner_area()");
     151             :             /* assume standard size */
     152           0 :             geometry_rectangle_replace( &result, outer_bounds );
     153           0 :             geometry_rectangle_expand_4dir( &result, -double_gap, -double_gap );
     154             :         }
     155           0 :         break;
     156             :     }
     157             : 
     158         161 :     U8_TRACE_END();
     159         161 :     return result;
     160             : }
     161             : 
     162         128 : geometry_rectangle_t draw_classifier_contour_calc_outer_bounds ( const draw_classifier_contour_t *this_,
     163             :                                                                  data_classifier_type_t classifier_type,
     164             :                                                                  const geometry_rectangle_t *inner_area,
     165             :                                                                  const pencil_size_t *pencil_size )
     166             : {
     167         128 :     U8_TRACE_BEGIN();
     168         128 :     assert ( NULL != inner_area );
     169         128 :     assert ( NULL != pencil_size );
     170             : 
     171             :     geometry_rectangle_t result;
     172         128 :     geometry_rectangle_init_empty( &result );
     173             : 
     174         128 :     double gap = pencil_size_get_standard_object_border( pencil_size );
     175         128 :     double double_gap = 2.0 * gap;  /* a line has the gap distance on both sides to the next object */
     176             : 
     177         128 :     switch ( classifier_type )
     178             :     {
     179           5 :         case DATA_CLASSIFIER_TYPE_USE_CASE:
     180             :         {
     181             :             /* within a use case, space is limited (double_gap is the border on each side): */
     182           5 :             double half_inner_width = 0.5 * geometry_rectangle_get_width( inner_area );
     183           5 :             double half_inner_height = 0.5 * geometry_rectangle_get_height( inner_area );
     184           5 :             double h_offset = half_inner_width * ( 1.0 / SINUS_OF_45_DEGREE - 1.0  );
     185           5 :             double v_offset = half_inner_height * ( 1.0 / SINUS_OF_45_DEGREE - 1.0  );
     186             : 
     187           5 :             geometry_rectangle_replace( &result, inner_area );
     188           5 :             geometry_rectangle_expand_4dir( &result, +double_gap + h_offset, +double_gap + v_offset );
     189             :         }
     190           5 :         break;
     191             : 
     192           5 :         case DATA_CLASSIFIER_TYPE_NODE:
     193             :         {
     194             :             /* the 3d border of a node shrinks the space */
     195           5 :             double offset_3d = double_gap;
     196             : 
     197           5 :             geometry_rectangle_replace( &result, inner_area );
     198           5 :             geometry_rectangle_enlarge( &result, +2.0 * double_gap + offset_3d, +2.0 * double_gap + offset_3d );
     199           5 :             geometry_rectangle_shift( &result, -double_gap, -double_gap - offset_3d );
     200             :         }
     201           5 :         break;
     202             : 
     203           9 :         case DATA_CLASSIFIER_TYPE_ACTOR:
     204             :         case DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE:
     205             :         case DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE:
     206             :         case DATA_CLASSIFIER_TYPE_DYN_FORK_NODE:
     207             :         case DATA_CLASSIFIER_TYPE_DYN_JOIN_NODE:
     208             :         case DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY:
     209             :         case DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY:
     210             :         case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_TIME_EVENT:
     211             :         case DATA_CLASSIFIER_TYPE_IMAGE:
     212             :         {
     213             :             /* the symbol icon height is part of the shape border  */
     214           9 :             double symbol_icon_height = pencil_size_get_classifier_symbol_height( pencil_size );
     215             : 
     216           9 :             geometry_rectangle_replace( &result, inner_area );
     217           9 :             geometry_rectangle_enlarge( &result, +2.0 * double_gap, +2.0 * double_gap + symbol_icon_height );
     218           9 :             geometry_rectangle_shift( &result, -double_gap, -double_gap - symbol_icon_height );
     219             :         }
     220           9 :         break;
     221             : 
     222          24 :         case DATA_CLASSIFIER_TYPE_DIAGRAM_REFERENCE:  /* and */
     223             :         case DATA_CLASSIFIER_TYPE_INTERACTION:  /* and */
     224             :         case DATA_CLASSIFIER_TYPE_PACKAGE:  /* and */
     225             :         case DATA_CLASSIFIER_TYPE_COMMENT:
     226             :         {
     227          24 :             double top_ornament_height = pencil_size_get_standard_font_size( pencil_size );
     228             : 
     229          24 :             geometry_rectangle_replace( &result, inner_area );
     230          24 :             geometry_rectangle_enlarge( &result, +2.0 * double_gap, +2.0 * double_gap + top_ornament_height );
     231          24 :             geometry_rectangle_shift( &result, -double_gap, -double_gap - top_ornament_height );
     232             :         }
     233          24 :         break;
     234             : 
     235          70 :         case DATA_CLASSIFIER_TYPE_BLOCK:
     236             :         case DATA_CLASSIFIER_TYPE_REQUIREMENT:
     237             :         case DATA_CLASSIFIER_TYPE_SUBSYSTEM:
     238             :         case DATA_CLASSIFIER_TYPE_ACTIVITY:
     239             :         case DATA_CLASSIFIER_TYPE_STATE:
     240             :         case DATA_CLASSIFIER_TYPE_COMPONENT:
     241             :         case DATA_CLASSIFIER_TYPE_PART:
     242             :         case DATA_CLASSIFIER_TYPE_INTERFACE:
     243             :         case DATA_CLASSIFIER_TYPE_CLASS:
     244             :         case DATA_CLASSIFIER_TYPE_OBJECT:
     245             :         case DATA_CLASSIFIER_TYPE_ARTIFACT:
     246             :         case DATA_CLASSIFIER_TYPE_CONSTRAINT_BLOCK:
     247             :         case DATA_CLASSIFIER_TYPE_DYN_INTERRUPTABLE_REGION:
     248             :         case DATA_CLASSIFIER_TYPE_STEREOTYPE:
     249             :         {
     250             :             /* standard size */
     251          70 :             geometry_rectangle_replace( &result, inner_area );
     252          70 :             geometry_rectangle_expand_4dir( &result, +double_gap, +double_gap );
     253             :         }
     254          70 :         break;
     255             : 
     256           5 :         case DATA_CLASSIFIER_TYPE_DYN_DECISION_NODE:
     257             :         {
     258             :             /* within a decision rhombus, space is limited by factor 2 per dimension: */
     259           5 :             double half_inner_width = 0.5 * geometry_rectangle_get_width( inner_area );
     260           5 :             double half_inner_height = 0.5 * geometry_rectangle_get_height( inner_area );
     261           5 :             double h_offset = half_inner_width;
     262           5 :             double v_offset = half_inner_height;
     263             : 
     264           5 :             geometry_rectangle_replace( &result, inner_area );
     265           5 :             geometry_rectangle_expand_4dir( &result, +double_gap + h_offset, +double_gap + v_offset );
     266             :         }
     267           5 :         break;
     268             : 
     269           5 :         case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_EVENT :
     270             :         {
     271             :             /* within an accept event, space is limited (double_gap is the border on each side): */
     272           5 :             double half_inner_height = 0.5 * geometry_rectangle_get_height( inner_area );
     273           5 :             double horizontal_offset = half_inner_height;
     274             : 
     275           5 :             geometry_rectangle_replace( &result, inner_area );
     276           5 :             geometry_rectangle_enlarge( &result, +2.0 * double_gap + horizontal_offset, +2.0 * double_gap );
     277           5 :             geometry_rectangle_shift( &result, -double_gap - horizontal_offset, -double_gap );
     278             :         }
     279           5 :         break;
     280             : 
     281           5 :         case DATA_CLASSIFIER_TYPE_DYN_SEND_SIGNAL:
     282             :         {
     283             :             /* within a send signal, space is limited (double_gap is the border on each side): */
     284           5 :             double half_inner_height = 0.5 * geometry_rectangle_get_height( inner_area );
     285           5 :             double horizontal_offset = half_inner_height;
     286             : 
     287           5 :             geometry_rectangle_replace( &result, inner_area );
     288           5 :             geometry_rectangle_enlarge( &result, +2.0 * double_gap + horizontal_offset, +2.0 * double_gap );
     289           5 :             geometry_rectangle_shift( &result, -double_gap, -double_gap );
     290             :         }
     291           5 :         break;
     292             : 
     293           0 :         default:
     294             :         {
     295             :             /* this case can happen if a model file of a new cfu version is opened with an older version of cfu */
     296           0 :             U8_LOG_ANOMALY("unknown data_classifier_type_t in draw_classifier_contour_calc_outer_bounds()");
     297             :             /* assume standard size */
     298           0 :             geometry_rectangle_replace( &result, inner_area );
     299           0 :             geometry_rectangle_expand_4dir( &result, +double_gap, +double_gap );
     300             :         }
     301           0 :         break;
     302             :     }
     303             : 
     304         128 :     U8_TRACE_END();
     305         128 :     return result;
     306             : }
     307             : 
     308           0 : void draw_classifier_contour_draw_rounded_rect ( const draw_classifier_contour_t *this_,
     309             :                                                  const geometry_rectangle_t *outer_bounds,
     310             :                                                  bool dashed_line,
     311             :                                                  const pencil_size_t *pencil_size,
     312             :                                                  cairo_t *cr )
     313             : {
     314           0 :     U8_TRACE_BEGIN();
     315           0 :     assert ( NULL != outer_bounds );
     316           0 :     assert ( NULL != pencil_size );
     317           0 :     assert ( NULL != cr );
     318           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     319           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     320           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     321           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     322           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     323           0 :     const double border_bottom = border_top + border_height;
     324           0 :     const double border_right = border_left + border_width;
     325           0 :     const double corner_radius = 6.0 * gap;
     326           0 :     const double ctrl_offset = corner_radius * (1.0-BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE);
     327             : 
     328             :     /* set dashes */
     329           0 :     if ( dashed_line )
     330             :     {
     331             :         double dashes[2];
     332           0 :         dashes[0] = 2.0 * pencil_size_get_line_dash_length( pencil_size );
     333           0 :         dashes[1] = 1.0 * pencil_size_get_line_dash_length( pencil_size );
     334           0 :         cairo_set_dash ( cr, dashes, 2, 0.0 );
     335             :     }
     336             : 
     337           0 :     cairo_move_to ( cr, border_right - corner_radius, border_bottom );
     338           0 :     cairo_line_to ( cr, border_left + corner_radius, border_bottom );
     339           0 :     cairo_curve_to ( cr, border_left + ctrl_offset, border_bottom, border_left, border_bottom - ctrl_offset, border_left /* end point x */, border_bottom - corner_radius /* end point y */ );
     340           0 :     cairo_line_to ( cr, border_left, border_top + corner_radius );
     341           0 :     cairo_curve_to ( cr, border_left, border_top + ctrl_offset, border_left + ctrl_offset, border_top, border_left + corner_radius /* end point x */, border_top /* end point y */ );
     342           0 :     cairo_line_to ( cr, border_right - corner_radius, border_top );
     343           0 :     cairo_curve_to ( cr, border_right - ctrl_offset, border_top, border_right, border_top + ctrl_offset, border_right /* end point x */, border_top + corner_radius /* end point y */ );
     344           0 :     cairo_line_to ( cr, border_right, border_bottom - corner_radius );
     345           0 :     cairo_curve_to ( cr, border_right, border_bottom - ctrl_offset, border_right - ctrl_offset, border_bottom, border_right - corner_radius /* end point x */, border_bottom /* end point y */ );
     346           0 :     cairo_stroke (cr);
     347             : 
     348             :     /* reset dashes */
     349           0 :     if ( dashed_line )
     350             :     {
     351           0 :         cairo_set_dash ( cr, NULL, 0, 0.0 );
     352             :     }
     353             : 
     354           0 :     U8_TRACE_END();
     355           0 : }
     356             : 
     357           0 : void draw_classifier_contour_draw_ellipse ( const draw_classifier_contour_t *this_,
     358             :                                             const geometry_rectangle_t *outer_bounds,
     359             :                                             const pencil_size_t *pencil_size,
     360             :                                             cairo_t *cr )
     361             : {
     362           0 :     U8_TRACE_BEGIN();
     363           0 :     assert ( NULL != outer_bounds );
     364           0 :     assert ( NULL != pencil_size );
     365           0 :     assert ( NULL != cr );
     366           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     367           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     368           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     369           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     370           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     371           0 :     const double border_bottom = border_top + border_height;
     372           0 :     const double border_right = border_left + border_width;
     373           0 :     const double half_width = 0.5 * border_width;
     374           0 :     const double half_height = 0.5 * border_height;
     375           0 :     const double center_x = border_left + half_width;
     376           0 :     const double center_y = border_top + half_height;
     377           0 :     const double ctrl_xoffset = half_width * (1.0-BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE);
     378           0 :     const double ctrl_yoffset = half_height * (1.0-BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE);
     379             : 
     380           0 :     cairo_move_to ( cr, center_x, border_bottom );
     381           0 :     cairo_curve_to ( cr, border_left + ctrl_xoffset, border_bottom, border_left, border_bottom - ctrl_yoffset, border_left /* end point x */, center_y /* end point y */ );
     382           0 :     cairo_curve_to ( cr, border_left, border_top + ctrl_yoffset, border_left + ctrl_xoffset, border_top, center_x /* end point x */, border_top /* end point y */ );
     383           0 :     cairo_curve_to ( cr, border_right - ctrl_xoffset, border_top, border_right, border_top + ctrl_yoffset, border_right /* end point x */, center_y /* end point y */ );
     384           0 :     cairo_curve_to ( cr, border_right, border_bottom - ctrl_yoffset, border_right - ctrl_xoffset, border_bottom, center_x /* end point x */, border_bottom /* end point y */ );
     385           0 :     cairo_stroke (cr);
     386             : 
     387           0 :     U8_TRACE_END();
     388           0 : }
     389             : 
     390           0 : void draw_classifier_contour_draw_rhombus ( const draw_classifier_contour_t *this_,
     391             :                                             const geometry_rectangle_t *outer_bounds,
     392             :                                             const pencil_size_t *pencil_size,
     393             :                                             cairo_t *cr )
     394             : {
     395           0 :     U8_TRACE_BEGIN();
     396           0 :     assert ( NULL != outer_bounds );
     397           0 :     assert ( NULL != pencil_size );
     398           0 :     assert ( NULL != cr );
     399           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     400           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     401           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     402           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     403           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     404           0 :     const double border_bottom = border_top + border_height;
     405           0 :     const double border_right = border_left + border_width;
     406           0 :     const double center_x = geometry_rectangle_get_center_x ( outer_bounds );
     407           0 :     const double center_y = geometry_rectangle_get_center_y ( outer_bounds );
     408             : 
     409           0 :     cairo_move_to ( cr, center_x, border_bottom );
     410           0 :     cairo_line_to ( cr, border_left, center_y );
     411           0 :     cairo_line_to ( cr, center_x, border_top );
     412           0 :     cairo_line_to ( cr, border_right, center_y );
     413           0 :     cairo_line_to ( cr, center_x, border_bottom );
     414           0 :     cairo_stroke (cr);
     415             : 
     416           0 :     U8_TRACE_END();
     417           0 : }
     418             : 
     419           0 : void draw_classifier_contour_draw_3d_box ( const draw_classifier_contour_t *this_,
     420             :                                            const geometry_rectangle_t *outer_bounds,
     421             :                                            const pencil_size_t *pencil_size,
     422             :                                            cairo_t *cr )
     423             : {
     424           0 :     U8_TRACE_BEGIN();
     425           0 :     assert ( NULL != outer_bounds );
     426           0 :     assert ( NULL != pencil_size );
     427           0 :     assert ( NULL != cr );
     428           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     429           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     430           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     431           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     432           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     433           0 :     const double border_bottom = border_top + border_height;
     434           0 :     const double border_right = border_left + border_width;
     435           0 :     const double offset_3d = 2.0*gap;
     436             : 
     437           0 :     cairo_rectangle ( cr, border_left, border_top+offset_3d, border_width-offset_3d, border_height-offset_3d );
     438           0 :     cairo_stroke (cr);
     439             : 
     440           0 :     cairo_move_to ( cr, border_left, border_top+offset_3d );
     441           0 :     cairo_line_to ( cr, border_left+offset_3d, border_top );
     442           0 :     cairo_line_to ( cr, border_right, border_top );
     443           0 :     cairo_line_to ( cr, border_right, border_bottom-offset_3d );
     444           0 :     cairo_line_to ( cr, border_right-offset_3d, border_bottom );
     445           0 :     cairo_stroke (cr);
     446           0 :     cairo_move_to ( cr, border_right, border_top );
     447           0 :     cairo_line_to ( cr, border_right-offset_3d, border_top+offset_3d );
     448           0 :     cairo_stroke (cr);
     449             : 
     450           0 :     U8_TRACE_END();
     451           0 : }
     452             : 
     453           0 : void draw_classifier_contour_draw_accept_event ( const draw_classifier_contour_t *this_,
     454             :                                                  const geometry_rectangle_t *outer_bounds,
     455             :                                                  const pencil_size_t *pencil_size,
     456             :                                                  cairo_t *cr )
     457             : {
     458           0 :     U8_TRACE_BEGIN();
     459           0 :     assert ( NULL != outer_bounds );
     460           0 :     assert ( NULL != pencil_size );
     461           0 :     assert ( NULL != cr );
     462           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     463           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     464           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     465           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     466           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     467           0 :     const double border_bottom = border_top + border_height;
     468           0 :     const double border_right = border_left + border_width;
     469           0 :     const double center_y = geometry_rectangle_get_center_y ( outer_bounds );
     470           0 :     const double x_indent = border_height / 2.0;
     471             : 
     472           0 :     cairo_move_to ( cr, border_right, border_bottom );
     473           0 :     cairo_line_to ( cr, border_right, border_top );
     474           0 :     cairo_line_to ( cr, border_left, border_top );
     475           0 :     cairo_line_to ( cr, border_left + x_indent, center_y );
     476           0 :     cairo_line_to ( cr, border_left, border_bottom );
     477           0 :     cairo_line_to ( cr, border_right, border_bottom );
     478           0 :     cairo_stroke (cr);
     479             : 
     480           0 :     U8_TRACE_END();
     481           0 : }
     482             : 
     483           0 : void draw_classifier_contour_draw_send_signal ( const draw_classifier_contour_t *this_,
     484             :                                                 const geometry_rectangle_t *outer_bounds,
     485             :                                                 const pencil_size_t *pencil_size,
     486             :                                                 cairo_t *cr )
     487             : {
     488           0 :     U8_TRACE_BEGIN();
     489           0 :     assert ( NULL != outer_bounds );
     490           0 :     assert ( NULL != pencil_size );
     491           0 :     assert ( NULL != cr );
     492           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     493           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     494           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     495           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     496           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     497           0 :     const double border_bottom = border_top + border_height;
     498           0 :     const double border_right = border_left + border_width;
     499           0 :     const double center_y = geometry_rectangle_get_center_y ( outer_bounds );
     500           0 :     const double x_indent = border_height / 2.0;
     501             : 
     502           0 :     cairo_move_to ( cr, border_right - x_indent, border_bottom );
     503           0 :     cairo_line_to ( cr, border_right, center_y );
     504           0 :     cairo_line_to ( cr, border_right - x_indent, border_top );
     505           0 :     cairo_line_to ( cr, border_left, border_top );
     506           0 :     cairo_line_to ( cr, border_left, border_bottom );
     507           0 :     cairo_line_to ( cr, border_right - x_indent, border_bottom );
     508           0 :     cairo_stroke (cr);
     509             : 
     510           0 :     U8_TRACE_END();
     511           0 : }
     512             : 
     513           0 : void draw_classifier_contour_draw_package ( const draw_classifier_contour_t *this_,
     514             :                                             const geometry_rectangle_t *outer_bounds,
     515             :                                             const geometry_rectangle_t *label_box,
     516             :                                             const pencil_size_t *pencil_size,
     517             :                                             cairo_t *cr )
     518             : {
     519           0 :     U8_TRACE_BEGIN();
     520           0 :     assert ( NULL != outer_bounds );
     521           0 :     assert ( NULL != pencil_size );
     522           0 :     assert ( NULL != cr );
     523           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     524           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     525           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     526           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     527           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     528             : 
     529             :     double tab_width;
     530             :     double tab_height;
     531           0 :     const bool label_in_tab = ( geometry_rectangle_get_top( label_box ) < (border_top + gap + gap) );
     532           0 :     if ( label_in_tab )
     533             :     {
     534           0 :         tab_width = geometry_rectangle_get_width ( label_box ) + gap + gap;
     535           0 :         tab_height = geometry_rectangle_get_height ( label_box ) + gap;
     536             :     }
     537             :     else
     538             :     {
     539           0 :         tab_width = border_width/3.0;
     540           0 :         tab_height = pencil_size_get_standard_font_size( pencil_size );
     541             :     }
     542           0 :     cairo_rectangle ( cr, border_left, border_top, tab_width, tab_height );
     543           0 :     cairo_rectangle ( cr, border_left, border_top+tab_height, border_width, border_height-tab_height );
     544           0 :     cairo_stroke (cr);
     545             : 
     546           0 :     U8_TRACE_END();
     547           0 : }
     548             : 
     549           0 : void draw_classifier_contour_draw_diagram_ref ( const draw_classifier_contour_t *this_,
     550             :                                                 const geometry_rectangle_t *outer_bounds,
     551             :                                                 const pencil_size_t *pencil_size,
     552             :                                                 cairo_t *cr )
     553             : {
     554           0 :     U8_TRACE_BEGIN();
     555           0 :     assert ( NULL != outer_bounds );
     556           0 :     assert ( NULL != pencil_size );
     557           0 :     assert ( NULL != cr );
     558           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     559           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     560           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     561           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     562           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     563           0 :     const double title_corner_height = pencil_size_get_standard_font_size( pencil_size );
     564           0 :     const double title_corner_edge45 = 0.4 * title_corner_height;
     565           0 :     const double title_corner_width = border_width/5.0;
     566             : 
     567           0 :     cairo_rectangle ( cr, border_left, border_top, border_width, border_height );
     568           0 :     cairo_move_to ( cr, border_left, border_top+title_corner_height );
     569           0 :     cairo_line_to ( cr, border_left+title_corner_width - title_corner_edge45, border_top+title_corner_height );
     570           0 :     cairo_line_to ( cr, border_left+title_corner_width, border_top+title_corner_height-title_corner_edge45 );
     571           0 :     cairo_line_to ( cr, border_left+title_corner_width, border_top );
     572           0 :     cairo_stroke (cr);
     573             : 
     574           0 :     U8_TRACE_END();
     575           0 : }
     576             : 
     577           0 : void draw_classifier_contour_draw_comment ( const draw_classifier_contour_t *this_,
     578             :                                             const geometry_rectangle_t *outer_bounds,
     579             :                                             const pencil_size_t *pencil_size,
     580             :                                             cairo_t *cr )
     581             : {
     582           0 :     U8_TRACE_BEGIN();
     583           0 :     assert ( NULL != outer_bounds );
     584           0 :     assert ( NULL != pencil_size );
     585           0 :     assert ( NULL != cr );
     586           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     587           0 :     const double border_left = geometry_rectangle_get_left ( outer_bounds ) + gap;
     588           0 :     const double border_top = geometry_rectangle_get_top ( outer_bounds ) + gap;
     589           0 :     const double border_width = geometry_rectangle_get_width ( outer_bounds ) - gap - gap;
     590           0 :     const double border_height = geometry_rectangle_get_height ( outer_bounds ) - gap - gap;
     591           0 :     const double corner_edge = pencil_size_get_standard_font_size( pencil_size );
     592           0 :     const double border_bottom = border_top + border_height;
     593           0 :     const double border_right = border_left + border_width;
     594             : 
     595           0 :     cairo_move_to ( cr, border_right, border_top + corner_edge );
     596           0 :     cairo_line_to ( cr, border_right - corner_edge, border_top + corner_edge );
     597           0 :     cairo_line_to ( cr, border_right - corner_edge, border_top );
     598           0 :     cairo_line_to ( cr, border_left, border_top );
     599           0 :     cairo_line_to ( cr, border_left, border_bottom );
     600           0 :     cairo_line_to ( cr, border_right, border_bottom );
     601           0 :     cairo_line_to ( cr, border_right, border_top + corner_edge );
     602           0 :     cairo_line_to ( cr, border_right - corner_edge, border_top );
     603           0 :     cairo_stroke (cr);
     604             : 
     605           0 :     U8_TRACE_END();
     606           0 : }
     607             : 
     608           0 : void draw_classifier_contour_draw_compartment_line ( const draw_classifier_contour_t *this_,
     609             :                                                      data_classifier_type_t classifier_type,
     610             :                                                      const geometry_rectangle_t *outer_bounds,
     611             :                                                      double y_coordinate,
     612             :                                                      const pencil_size_t *pencil_size,
     613             :                                                      cairo_t *cr )
     614             : {
     615           0 :     U8_TRACE_BEGIN();
     616           0 :     assert ( NULL != outer_bounds );
     617           0 :     assert ( NULL != pencil_size );
     618           0 :     assert ( NULL != cr );
     619             : 
     620           0 :     const double bounds_left = geometry_rectangle_get_left( outer_bounds );
     621           0 :     const double bounds_width = geometry_rectangle_get_width( outer_bounds );
     622           0 :     const double bounds_height = geometry_rectangle_get_height( outer_bounds );
     623           0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     624             : 
     625           0 :     double left = bounds_left + gap;
     626           0 :     double right = bounds_left + bounds_width - gap;
     627           0 :     switch ( classifier_type )
     628             :     {
     629           0 :         case DATA_CLASSIFIER_TYPE_USE_CASE:
     630             :         {
     631           0 :             const double center_x = geometry_rectangle_get_center_x( outer_bounds );
     632           0 :             const double center_y = geometry_rectangle_get_center_y( outer_bounds );
     633           0 :             const double radius_x = ( bounds_width / 2.0 ) - gap; /* there is 1.0*gap around the ellipsis */
     634           0 :             const double radius_y = ( bounds_height / 2.0 ) - gap; /* there is 1.0*gap around the ellipsis */
     635           0 :             const double norm_dy = ( y_coordinate - center_y ) / radius_y;
     636           0 :             const double sqr_norm_dx = 1.0 - ( norm_dy * norm_dy );
     637           0 :             if ( sqr_norm_dx >= 0.0 )
     638             :             {
     639           0 :                 const double dx = sqrt( sqr_norm_dx ) * radius_x;
     640           0 :                 left = center_x - dx;
     641           0 :                 right = center_x + dx;
     642             :             }
     643             :             else
     644             :             {
     645           0 :                 left = bounds_left + gap;
     646           0 :                 right = bounds_left + bounds_width - gap;
     647             :             }
     648             :         }
     649           0 :         break;
     650             : 
     651           0 :         case DATA_CLASSIFIER_TYPE_NODE:
     652             :         {
     653             :             /* the 3d border of a node shrinks the space */
     654           0 :             const double offset_3d = 2.0 * gap;
     655           0 :             left = bounds_left + gap;
     656           0 :             right = bounds_left + bounds_width - offset_3d - gap;
     657             :         }
     658           0 :         break;
     659             : 
     660           0 :         default:
     661             :         {
     662             :             /* for all other cases; this switch is not exhaustive */
     663           0 :             left = bounds_left + gap;
     664           0 :             right = bounds_left + bounds_width - gap;
     665             :         }
     666           0 :         break;
     667             :     }
     668             : 
     669           0 :     cairo_move_to ( cr, left, y_coordinate );
     670           0 :     cairo_line_to ( cr, right, y_coordinate );
     671           0 :     cairo_stroke (cr);
     672             : 
     673           0 :     U8_TRACE_END();
     674           0 : }
     675             : 
     676             : 
     677             : /*
     678             : Copyright 2016-2024 Andreas Warnke
     679             :     http://www.apache.org/licenses/LICENSE-2.0
     680             : 
     681             : Licensed under the Apache License, Version 2.0 (the "License");
     682             : you may not use this file except in compliance with the License.
     683             : You may obtain a copy of the License at
     684             : 
     685             : 
     686             : Unless required by applicable law or agreed to in writing, software
     687             : distributed under the License is distributed on an "AS IS" BASIS,
     688             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     689             : See the License for the specific language governing permissions and
     690             : limitations under the License.
     691             : */

Generated by: LCOV version 1.16