LCOV - code coverage report
Current view: top level - pencil/source - pencil_feature_painter.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.69.0_covts Lines: 0.0 % 287 0
Test Date: 2026-03-08 20:58:47 Functions: 0.0 % 8 0

            Line data    Source code
       1              : /* File: pencil_feature_painter.c; Copyright and License: see below */
       2              : 
       3              : #include "pencil_feature_painter.h"
       4              : #include "layout/layout_visible_set.h"
       5              : #include "u8/u8_trace.h"
       6              : #include <pango/pangocairo.h>
       7              : #include <stdio.h>
       8              : #include <stdlib.h>
       9              : #include <assert.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              : const static double SINE_OF_45_DEGREE = 0.707106781187;
      14              : 
      15            0 : void pencil_feature_painter_init( pencil_feature_painter_t *this_ )
      16              : {
      17            0 :     U8_TRACE_BEGIN();
      18              : 
      19            0 :     pencil_marker_init( &((*this_).marker) );
      20            0 :     draw_feature_label_init( &((*this_).draw_feature_label) );
      21            0 :     draw_feature_symbol_init( &((*this_).draw_feature_symbol) );
      22              : 
      23            0 :     U8_TRACE_END();
      24            0 : }
      25              : 
      26            0 : void pencil_feature_painter_destroy( pencil_feature_painter_t *this_ )
      27              : {
      28            0 :     U8_TRACE_BEGIN();
      29              : 
      30            0 :     draw_feature_symbol_destroy( &((*this_).draw_feature_symbol) );
      31            0 :     draw_feature_label_destroy( &((*this_).draw_feature_label) );
      32            0 :     pencil_marker_destroy( &((*this_).marker) );
      33              : 
      34            0 :     U8_TRACE_END();
      35            0 : }
      36              : 
      37            0 : void pencil_feature_painter_draw( pencil_feature_painter_t *this_,
      38              :                                   const layout_feature_t *layouted_feature,
      39              :                                   bool mark_focused,
      40              :                                   bool mark_highlighted,
      41              :                                   bool mark_selected,
      42              :                                   bool gray_out,
      43              :                                   layout_relationship_iter_t *relationships,
      44              :                                   const data_profile_part_t *profile,
      45              :                                   const pencil_size_t *pencil_size,
      46              :                                   PangoLayout *layout,
      47              :                                   cairo_t *cr )
      48              : {
      49            0 :     U8_TRACE_BEGIN();
      50            0 :     assert( NULL != profile );
      51            0 :     assert( NULL != pencil_size );
      52            0 :     assert( NULL != layouted_feature );
      53            0 :     assert( NULL != layout );
      54            0 :     assert( NULL != cr );
      55              : 
      56            0 :     const data_feature_t *the_feature = layout_feature_get_data_const( layouted_feature );
      57            0 :     const geometry_rectangle_t *const feature_symbol_box = layout_feature_get_symbol_box_const( layouted_feature );
      58              : 
      59            0 :     if ( data_feature_is_valid( the_feature ) )
      60              :     {
      61            0 :         U8_TRACE_INFO_INT("drawing feature id", data_feature_get_row_id( the_feature ) );
      62              : 
      63              :         /* select color */
      64              :         GdkRGBA foreground_color;
      65              :         {
      66            0 :             if ( mark_highlighted )
      67              :             {
      68            0 :                 foreground_color = pencil_size_get_highlight_color( pencil_size );
      69              :             }
      70            0 :             else if ( gray_out )
      71              :             {
      72            0 :                 foreground_color = pencil_size_get_gray_out_color( pencil_size );
      73              :             }
      74              :             else
      75              :             {
      76            0 :                 foreground_color = pencil_size_get_standard_color( pencil_size );
      77              :             }
      78            0 :             cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
      79              :         }
      80              : 
      81            0 :         switch ( data_feature_get_main_type (the_feature) )
      82              :         {
      83            0 :             case DATA_FEATURE_TYPE_PORT:  /* or */
      84              :             case DATA_FEATURE_TYPE_IN_PORT_PIN:  /* or */
      85              :             case DATA_FEATURE_TYPE_OUT_PORT_PIN:
      86              :             {
      87            0 :                 pencil_feature_painter_private_draw_port_pin_icon( this_, layouted_feature, pencil_size, foreground_color, cr );
      88              :             }
      89            0 :             break;
      90              : 
      91            0 :             case DATA_FEATURE_TYPE_ENTRY:  /* or */
      92              :             case DATA_FEATURE_TYPE_EXIT:
      93              :             {
      94            0 :                 pencil_feature_painter_private_draw_entry_exit_icon( this_, layouted_feature, pencil_size, foreground_color, cr );
      95              :             }
      96            0 :             break;
      97              : 
      98            0 :             case DATA_FEATURE_TYPE_PROVIDED_INTERFACE:  /* or */
      99              :             case DATA_FEATURE_TYPE_REQUIRED_INTERFACE:
     100              :             {
     101            0 :                 pencil_feature_painter_private_draw_interface_icon( this_, layouted_feature, pencil_size, cr );
     102              :             }
     103            0 :             break;
     104              : 
     105            0 :             case DATA_FEATURE_TYPE_LIFELINE:
     106              :             {
     107            0 :                 pencil_feature_painter_private_draw_lifeline_icon( this_,
     108              :                                                                    layouted_feature,
     109              :                                                                    mark_highlighted,
     110              :                                                                    relationships,
     111              :                                                                    pencil_size,
     112              :                                                                    cr
     113              :                                                                  );
     114              :             }
     115            0 :             break;
     116              : 
     117            0 :             case DATA_FEATURE_TYPE_PROPERTY: /* or */
     118              :             case DATA_FEATURE_TYPE_OPERATION: /* or */
     119              :             case DATA_FEATURE_TYPE_TAGGED_VALUE:
     120              :             {
     121              :                 /* no icon */
     122              :             }
     123            0 :             break;
     124              : 
     125            0 :             default:
     126              :             {
     127            0 :                 U8_LOG_ANOMALY("unknown feature type in pencil_feature_painter_draw");
     128              :                 /* this may happen if a new database file has been read by an old program version */
     129              :                 /* no icon */
     130              :             }
     131            0 :             break;
     132              :         }
     133              : 
     134              :         /* draw the label */
     135            0 :         draw_feature_label_draw_key_and_value( &((*this_).draw_feature_label),
     136              :                                                layout_feature_get_data_const( layouted_feature ),
     137              :                                                profile,
     138              :                                                &foreground_color,
     139              :                                                layout_feature_get_label_box_const( layouted_feature ),
     140              :                                                pencil_size,
     141              :                                                layout,
     142              :                                                cr
     143              :                                              );
     144              : 
     145            0 :         if ( mark_selected )
     146              :         {
     147            0 :             pencil_marker_mark_selected_rectangle( &((*this_).marker), *feature_symbol_box, cr );
     148              :         }
     149              : 
     150            0 :         if ( mark_focused )
     151              :         {
     152            0 :             pencil_marker_mark_focused_rectangle( &((*this_).marker), *feature_symbol_box, cr );
     153              :         }
     154              :     }
     155              :     else
     156              :     {
     157            0 :         U8_LOG_ERROR("invalid visible feature in array!");
     158              :     }
     159              : 
     160            0 :     U8_TRACE_END();
     161            0 : }
     162              : 
     163            0 : void pencil_feature_painter_private_draw_lifeline_icon ( pencil_feature_painter_t *this_,
     164              :                                                          const layout_feature_t *layouted_feature,
     165              :                                                          bool marked,
     166              :                                                          layout_relationship_iter_t *relationships,
     167              :                                                          const pencil_size_t *pencil_size,
     168              :                                                          cairo_t *cr )
     169              : {
     170            0 :     U8_TRACE_BEGIN();
     171            0 :     assert( NULL != pencil_size );
     172            0 :     assert( NULL != layouted_feature );
     173            0 :     assert( NULL != cr );
     174              : 
     175              :     /* reset the draw_feature_symbol helper class */
     176            0 :     draw_feature_symbol_reinit( &((*this_).draw_feature_symbol) );
     177              : 
     178            0 :     const geometry_rectangle_t *const feature_symbol_box = layout_feature_get_symbol_box_const( layouted_feature );
     179            0 :     const data_feature_t *const feature_data = layout_feature_get_data_const( layouted_feature );
     180            0 :     const data_id_t feature_id = data_feature_get_data_id( feature_data );
     181              : 
     182            0 :     if ( GEOMETRY_DIRECTION_RIGHT == layout_feature_get_icon_direction( layouted_feature ) )
     183              :     {
     184              :         /* lifeline in timing diagrams */
     185            0 :         bool past_active = false;  /* flag that tells if the line left of the current drawing position is active (bold) or inactive (dashed) */
     186            0 :         while ( layout_relationship_iter_has_next( relationships ) )
     187              :         {
     188            0 :             const layout_relationship_t *const message_layout = layout_relationship_iter_next( relationships );
     189            0 :             const data_relationship_t *const message_data = layout_relationship_get_data_const( message_layout );
     190            0 :             const data_relationship_type_t message_type = data_relationship_get_main_type( message_data );
     191            0 :             const data_id_t from_feat = data_relationship_get_from_feature_data_id( message_data );
     192            0 :             const data_id_t to_feat = data_relationship_get_to_feature_data_id( message_data );
     193            0 :             const bool depart_from_here = data_id_equals( &feature_id, &from_feat );
     194            0 :             const bool arrive_here = data_id_equals( &feature_id, &to_feat );
     195              : 
     196            0 :             if ((( message_type == DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL )
     197            0 :                 || ( message_type == DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL ))
     198            0 :                 && ( depart_from_here || arrive_here ))
     199              :             {
     200              :                 /* determine x location */
     201            0 :                 const geometry_connector_t *const conn = layout_relationship_get_shape_const( message_layout );
     202            0 :                 if ( arrive_here )
     203              :                 {
     204            0 :                     const double x1 = geometry_connector_get_destination_end_x( conn );
     205            0 :                     draw_feature_symbol_draw_timeline( &((*this_).draw_feature_symbol),
     206              :                                                        feature_symbol_box,
     207              :                                                        x1,   /* to_x */
     208              :                                                        true,  /* active */
     209              :                                                        pencil_size,
     210              :                                                        cr
     211              :                                                      );
     212            0 :                     past_active = false;  /* note that we are traversing backwards in time */
     213              :                 }
     214            0 :                 if ( depart_from_here )
     215              :                 {
     216            0 :                     const double x2 = geometry_connector_get_source_end_x( conn );
     217            0 :                     draw_feature_symbol_draw_timeline( &((*this_).draw_feature_symbol),
     218              :                                                        feature_symbol_box,
     219              :                                                        x2,   /* to_x */
     220              :                                                        false,  /* active */
     221              :                                                        pencil_size,
     222              :                                                        cr
     223              :                                                      );
     224            0 :                     past_active = true;  /* note that we are traversing backwards in time */
     225              :                 }
     226              : 
     227              : 
     228              :             }
     229              :         }
     230            0 :         draw_feature_symbol_draw_timeline( &((*this_).draw_feature_symbol),
     231              :                                            feature_symbol_box,
     232              :                                            -INFINITY,   /* to_x */
     233              :                                            past_active,  /* active */
     234              :                                            pencil_size,
     235              :                                            cr
     236              :                                          );
     237              :     }
     238            0 :     else if ( GEOMETRY_DIRECTION_DOWN == layout_feature_get_icon_direction( layouted_feature ) )
     239              :     {
     240              :         /* lifeline in sequence diagrams */
     241            0 :         uint32_t past_depth = 0;  /* estimated depth of activity bars above the current drawing position */
     242            0 :         while ( layout_relationship_iter_has_next( relationships ) )
     243              :         {
     244            0 :             const layout_relationship_t *const message_layout = layout_relationship_iter_next( relationships );
     245            0 :             const data_relationship_t *const message_data = layout_relationship_get_data_const( message_layout );
     246            0 :             const data_relationship_type_t message_type = data_relationship_get_main_type( message_data );
     247            0 :             const data_id_t from_feat = data_relationship_get_from_feature_data_id( message_data );
     248            0 :             const data_id_t to_feat = data_relationship_get_to_feature_data_id( message_data );
     249            0 :             const bool depart_from_here = data_id_equals( &feature_id, &from_feat );
     250            0 :             const bool arrive_here = data_id_equals( &feature_id, &to_feat );
     251              : 
     252            0 :             if ((( message_type == DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL )
     253            0 :                 || ( message_type == DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL ))
     254            0 :                 && ( depart_from_here || arrive_here ))
     255              :             {
     256              :                 /* determine y location */
     257            0 :                 const geometry_connector_t *const conn = layout_relationship_get_shape_const( message_layout );
     258            0 :                 if ( arrive_here && ( message_type == DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL ))
     259              :                 {
     260              :                     /* past_depth = ( past_depth == 0 ) ? 1 : past_depth; */  /* adjust the estimation when there is an arriving edge */
     261            0 :                     const double y1 = geometry_connector_get_destination_end_y( conn );
     262            0 :                     draw_feature_symbol_draw_execution_spec( &((*this_).draw_feature_symbol),
     263              :                                                              feature_symbol_box,
     264              :                                                              y1,   /* to_y */
     265              :                                                              past_depth,  /* depth */
     266              :                                                              pencil_size,
     267              :                                                              cr
     268              :                                                            );
     269            0 :                     past_depth = ( past_depth > 0 ) ? ( past_depth - 1 ) : 0;  /* decrease the depth of activity bars */
     270              :                 }
     271            0 :                 if ( depart_from_here && ( message_type == DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL ) )
     272              :                 {
     273            0 :                     const double y2 = geometry_connector_get_source_end_y( conn );
     274            0 :                     draw_feature_symbol_draw_execution_spec( &((*this_).draw_feature_symbol),
     275              :                                                              feature_symbol_box,
     276              :                                                              y2,   /* to_y */
     277              :                                                              past_depth,  /* depth */
     278              :                                                              pencil_size,
     279              :                                                              cr
     280              :                                                            );
     281            0 :                     past_depth = past_depth + 1;  /* increase the depth of activity bars */
     282              :                 }
     283              :             }
     284              :         }
     285            0 :         draw_feature_symbol_draw_execution_spec( &((*this_).draw_feature_symbol),
     286              :                                                  feature_symbol_box,
     287              :                                                  -INFINITY,   /* to_y */
     288              :                                                  past_depth,  /* depth */
     289              :                                                  pencil_size,
     290              :                                                  cr
     291              :                                                );
     292              :     }
     293              :     else
     294              :     {
     295              :         /* lifeline in communication and interaction overview diagrams, */
     296              :         /* or comments in other interaction diagrams */
     297              :         /* are only drawn if highlighted (marked): */
     298            0 :         draw_feature_symbol_draw_life_rectangle( &((*this_).draw_feature_symbol),
     299              :                                                  feature_symbol_box,
     300              :                                                  marked,
     301              :                                                  pencil_size,
     302              :                                                  cr
     303              :                                                );
     304              :     }
     305              : 
     306            0 :     U8_TRACE_END();
     307            0 : }
     308              : 
     309            0 : void pencil_feature_painter_private_draw_port_pin_icon ( pencil_feature_painter_t *this_,
     310              :                                                          const layout_feature_t *layouted_feature,
     311              :                                                          const pencil_size_t *pencil_size,
     312              :                                                          GdkRGBA foreground_color,
     313              :                                                          cairo_t *cr )
     314              : {
     315            0 :     U8_TRACE_BEGIN();
     316            0 :     assert( NULL != pencil_size );
     317            0 :     assert( NULL != layouted_feature );
     318            0 :     assert( NULL != cr );
     319              : 
     320            0 :     const geometry_rectangle_t *const symbol_box_bounds = layout_feature_get_symbol_box_const( layouted_feature );
     321              : 
     322            0 :     const double left = geometry_rectangle_get_left ( symbol_box_bounds );
     323            0 :     const double top = geometry_rectangle_get_top ( symbol_box_bounds );
     324            0 :     const double width = geometry_rectangle_get_width ( symbol_box_bounds );
     325            0 :     const double height = geometry_rectangle_get_height ( symbol_box_bounds );
     326              : 
     327            0 :     cairo_rectangle ( cr, left, top, width, height );
     328              : 
     329              :     /* Note: It is possible to read out the current color and set it again */
     330              :     /* but the interface for that looks like this might result in 1 additional memory allocation */
     331              :     /* which shall be avoided */
     332              :     /* cairo_pattern_t *const defined_color = cairo_get_source( cr ); */
     333              :     /* cairo_pattern_reference( defined_color );                      */
     334              :     /* ...                                                            */
     335              :     /* cairo_set_source( cr, defined_color );                         */
     336              :     /* cairo_pattern_destroy( defined_color );                        */
     337              : 
     338            0 :     cairo_set_source_rgba( cr, 1.0, 1.0, 1.0, 1.0 );  /* white background */
     339            0 :     cairo_fill_preserve (cr);
     340            0 :     cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
     341            0 :     cairo_stroke (cr);
     342              : 
     343              :     /* draw the arrow */
     344            0 :     const double center_x = geometry_rectangle_get_center_x ( symbol_box_bounds );
     345            0 :     const double center_y = geometry_rectangle_get_center_y ( symbol_box_bounds );
     346            0 :     const double h_arrow_left = left + 0.25*width;
     347            0 :     const double h_arrow_right = left + 0.75*width;
     348            0 :     const double h_arrow_top = top + 0.25*height;
     349            0 :     const double h_arrow_bottom = top + 0.75*height;
     350            0 :     const double v_arrow_left = left + 0.25*width;
     351            0 :     const double v_arrow_right = left + 0.75*width;
     352            0 :     const double v_arrow_top = top + 0.25*height;
     353            0 :     const double v_arrow_bottom = top + 0.75*height;
     354            0 :     switch ( layout_feature_get_icon_direction( layouted_feature ) )
     355              :     {
     356            0 :         case GEOMETRY_DIRECTION_LEFT:
     357              :         {
     358            0 :             cairo_move_to ( cr, h_arrow_left, center_y );
     359            0 :             cairo_line_to ( cr, h_arrow_right, center_y );
     360            0 :             cairo_move_to ( cr, h_arrow_right, h_arrow_top );
     361            0 :             cairo_line_to ( cr, h_arrow_left, center_y );
     362            0 :             cairo_line_to ( cr, h_arrow_right, h_arrow_bottom );
     363              : 
     364            0 :             cairo_stroke (cr);
     365              :         }
     366            0 :         break;
     367              : 
     368            0 :         case GEOMETRY_DIRECTION_UP:
     369              :         {
     370            0 :             cairo_move_to ( cr, center_x, v_arrow_top );
     371            0 :             cairo_line_to ( cr, center_x, v_arrow_bottom );
     372            0 :             cairo_move_to ( cr, v_arrow_left, v_arrow_bottom );
     373            0 :             cairo_line_to ( cr, center_x, v_arrow_top );
     374            0 :             cairo_line_to ( cr, v_arrow_right, v_arrow_bottom );
     375              : 
     376            0 :             cairo_stroke (cr);
     377              :         }
     378            0 :         break;
     379              : 
     380            0 :         case GEOMETRY_DIRECTION_RIGHT:
     381              :         {
     382            0 :             cairo_move_to ( cr, h_arrow_right, center_y );
     383            0 :             cairo_line_to ( cr, h_arrow_left, center_y );
     384            0 :             cairo_move_to ( cr, h_arrow_left, h_arrow_top );
     385            0 :             cairo_line_to ( cr, h_arrow_right, center_y );
     386            0 :             cairo_line_to ( cr, h_arrow_left, h_arrow_bottom );
     387              : 
     388            0 :             cairo_stroke (cr);
     389              :         }
     390            0 :         break;
     391              : 
     392            0 :         case GEOMETRY_DIRECTION_DOWN:
     393              :         {
     394            0 :             cairo_move_to ( cr, center_x, v_arrow_bottom );
     395            0 :             cairo_line_to ( cr, center_x, v_arrow_top );
     396            0 :             cairo_move_to ( cr, v_arrow_left, v_arrow_top );
     397            0 :             cairo_line_to ( cr, center_x, v_arrow_bottom );
     398            0 :             cairo_line_to ( cr, v_arrow_right, v_arrow_top );
     399              : 
     400            0 :             cairo_stroke (cr);
     401              :         }
     402            0 :         break;
     403              : 
     404            0 :         case GEOMETRY_DIRECTION_CENTER:
     405              :         {
     406              :             /* no arrow */
     407              :         }
     408            0 :         break;
     409              : 
     410            0 :         default:
     411              :         {
     412            0 :             U8_LOG_ERROR( "unexpected value in geometry_direction_t." );
     413              :         }
     414            0 :         break;
     415              :     }
     416              : 
     417            0 :     U8_TRACE_END();
     418            0 : }
     419              : 
     420            0 : void pencil_feature_painter_private_draw_entry_exit_icon ( pencil_feature_painter_t *this_,
     421              :                                                            const layout_feature_t *layouted_feature,
     422              :                                                            const pencil_size_t *pencil_size,
     423              :                                                            GdkRGBA foreground_color,
     424              :                                                            cairo_t *cr )
     425              : {
     426            0 :     U8_TRACE_BEGIN();
     427            0 :     assert( NULL != pencil_size );
     428            0 :     assert( NULL != layouted_feature );
     429            0 :     assert( NULL != cr );
     430              : 
     431            0 :     const data_feature_t *the_feature = layout_feature_get_data_const( layouted_feature );
     432            0 :     const geometry_rectangle_t *const symbol_box_bounds = layout_feature_get_symbol_box_const( layouted_feature );
     433              : 
     434            0 :     const double left = geometry_rectangle_get_left ( symbol_box_bounds );
     435            0 :     const double top = geometry_rectangle_get_top ( symbol_box_bounds );
     436            0 :     const double center_x = geometry_rectangle_get_center_x( symbol_box_bounds );
     437            0 :     const double center_y = geometry_rectangle_get_center_y( symbol_box_bounds );
     438            0 :     const double circle_x_radius = center_x - left;
     439            0 :     const double circle_y_radius = center_y - top;
     440            0 :     const double bottom = geometry_rectangle_get_bottom( symbol_box_bounds );
     441            0 :     const double right = geometry_rectangle_get_right( symbol_box_bounds );
     442            0 :     const double ctrl_x_offset = circle_x_radius * (1.0-BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE);
     443            0 :     const double ctrl_y_offset = circle_y_radius * (1.0-BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE);
     444              : 
     445            0 :     cairo_move_to ( cr, center_x, bottom );
     446            0 :     cairo_curve_to ( cr, left + ctrl_x_offset, bottom, left, bottom - ctrl_y_offset, left /* end point x */, center_y /* end point y */ );
     447            0 :     cairo_curve_to ( cr, left, top + ctrl_y_offset, left + ctrl_x_offset, top, center_x /* end point x */, top /* end point y */ );
     448            0 :     cairo_curve_to ( cr, right - ctrl_x_offset, top, right, top + ctrl_y_offset, right /* end point x */, center_y /* end point y */ );
     449            0 :     cairo_curve_to ( cr, right, bottom - ctrl_y_offset, right - ctrl_x_offset, bottom, center_x /* end point x */, bottom /* end point y */ );
     450              : 
     451            0 :     cairo_set_source_rgba( cr, 1.0, 1.0, 1.0, 1.0 );  /* white background */
     452            0 :     cairo_fill_preserve (cr);
     453            0 :     cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
     454            0 :     cairo_stroke (cr);
     455              : 
     456              :     /* draw X of exit icon */
     457            0 :     if ( data_feature_get_main_type( the_feature ) == DATA_FEATURE_TYPE_EXIT )
     458              :     {
     459            0 :         const double half_width = geometry_rectangle_get_width ( symbol_box_bounds )/2.0;
     460            0 :         const double half_height = geometry_rectangle_get_height ( symbol_box_bounds )/2.0;
     461            0 :         const double cross_end_dx = half_width * SINE_OF_45_DEGREE;
     462            0 :         const double cross_end_dy = half_height * SINE_OF_45_DEGREE;
     463              : 
     464            0 :         cairo_move_to ( cr, center_x + cross_end_dx, center_y - cross_end_dy );
     465            0 :         cairo_line_to ( cr, center_x - cross_end_dx, center_y + cross_end_dy );
     466            0 :         cairo_move_to ( cr, center_x - cross_end_dx, center_y - cross_end_dy );
     467            0 :         cairo_line_to ( cr, center_x + cross_end_dx, center_y + cross_end_dy );
     468              : 
     469            0 :         cairo_stroke (cr);
     470              :     }
     471              : 
     472            0 :     U8_TRACE_END();
     473            0 : }
     474              : 
     475            0 : void pencil_feature_painter_private_draw_interface_icon ( pencil_feature_painter_t *this_,
     476              :                                                           const layout_feature_t *layouted_feature,
     477              :                                                           const pencil_size_t *pencil_size,
     478              :                                                           cairo_t *cr )
     479              : {
     480            0 :     U8_TRACE_BEGIN();
     481            0 :     assert( NULL != pencil_size );
     482            0 :     assert( NULL != layouted_feature );
     483            0 :     assert( NULL != cr );
     484              : 
     485            0 :     const geometry_rectangle_t *const symbol_box_bounds = layout_feature_get_symbol_box_const( layouted_feature );
     486              : 
     487            0 :     const double left = geometry_rectangle_get_left ( symbol_box_bounds );
     488            0 :     const double top = geometry_rectangle_get_top ( symbol_box_bounds );
     489            0 :     const double width = geometry_rectangle_get_width ( symbol_box_bounds );
     490            0 :     const double height = geometry_rectangle_get_height ( symbol_box_bounds );
     491              : 
     492            0 :     double bottom = top + height;
     493            0 :     double right = left + width;
     494            0 :     double half_width = 0.5 * width;
     495            0 :     double half_height = 0.5 * height;
     496            0 :     double center_x = left + half_width;
     497            0 :     double center_y = top + half_height;
     498            0 :     double ctrl_xoffset = half_width * (1.0-BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE);
     499            0 :     double ctrl_yoffset = half_height * (1.0-BEZIER_CTRL_POINT_FOR_90_DEGREE_CIRCLE);
     500              : 
     501            0 :     switch ( layout_feature_get_icon_direction( layouted_feature ) )
     502              :     {
     503            0 :         case GEOMETRY_DIRECTION_LEFT:
     504              :         {
     505            0 :             cairo_move_to ( cr, center_x, top );
     506            0 :             cairo_curve_to ( cr, right - ctrl_xoffset, top, right, top + ctrl_yoffset, right /* end point x */, center_y /* end point y */ );
     507            0 :             cairo_curve_to ( cr, right, bottom - ctrl_yoffset, right - ctrl_xoffset, bottom, center_x /* end point x */, bottom /* end point y */ );
     508            0 :             cairo_stroke (cr);
     509              :         }
     510            0 :         break;
     511              : 
     512            0 :         case GEOMETRY_DIRECTION_UP:
     513              :         {
     514            0 :             cairo_move_to ( cr, right, center_y );
     515            0 :             cairo_curve_to ( cr, right, bottom - ctrl_yoffset, right - ctrl_xoffset, bottom, center_x /* end point x */, bottom /* end point y */ );
     516            0 :             cairo_curve_to ( cr, left + ctrl_xoffset, bottom, left, bottom - ctrl_yoffset, left /* end point x */, center_y /* end point y */ );
     517            0 :             cairo_stroke (cr);
     518              :         }
     519            0 :         break;
     520              : 
     521            0 :         case GEOMETRY_DIRECTION_RIGHT:
     522              :         {
     523            0 :             cairo_move_to ( cr, center_x, bottom );
     524            0 :             cairo_curve_to ( cr, left + ctrl_xoffset, bottom, left, bottom - ctrl_yoffset, left /* end point x */, center_y /* end point y */ );
     525            0 :             cairo_curve_to ( cr, left, top + ctrl_yoffset, left + ctrl_xoffset, top, center_x /* end point x */, top /* end point y */ );
     526            0 :             cairo_stroke (cr);
     527              :         }
     528            0 :         break;
     529              : 
     530            0 :         case GEOMETRY_DIRECTION_DOWN:
     531              :         {
     532            0 :             cairo_move_to ( cr, left, center_y );
     533            0 :             cairo_curve_to ( cr, left, top + ctrl_yoffset, left + ctrl_xoffset, top, center_x /* end point x */, top /* end point y */ );
     534            0 :             cairo_curve_to ( cr, right - ctrl_xoffset, top, right, top + ctrl_yoffset, right /* end point x */, center_y /* end point y */ );
     535            0 :             cairo_stroke (cr);
     536              :         }
     537            0 :         break;
     538              : 
     539            0 :         case GEOMETRY_DIRECTION_CENTER:
     540              :         {
     541            0 :             cairo_move_to ( cr, center_x, bottom );
     542            0 :             cairo_curve_to ( cr, left + ctrl_xoffset, bottom, left, bottom - ctrl_yoffset, left /* end point x */, center_y /* end point y */ );
     543            0 :             cairo_curve_to ( cr, left, top + ctrl_yoffset, left + ctrl_xoffset, top, center_x /* end point x */, top /* end point y */ );
     544            0 :             cairo_curve_to ( cr, right - ctrl_xoffset, top, right, top + ctrl_yoffset, right /* end point x */, center_y /* end point y */ );
     545            0 :             cairo_curve_to ( cr, right, bottom - ctrl_yoffset, right - ctrl_xoffset, bottom, center_x /* end point x */, bottom /* end point y */ );
     546            0 :             cairo_stroke (cr);
     547              :         }
     548            0 :         break;
     549              : 
     550            0 :         default:
     551              :         {
     552            0 :             U8_LOG_ERROR( "unexpected value in geometry_direction_t." );
     553              :         }
     554            0 :         break;
     555              :     }
     556              : 
     557            0 :     U8_TRACE_END();
     558            0 : }
     559              : 
     560            0 : void pencil_feature_painter_get_minimum_bounds ( pencil_feature_painter_t *this_,
     561              :                                                  const data_feature_t *the_feature,
     562              :                                                  const data_profile_part_t *profile,
     563              :                                                  const pencil_size_t *pencil_size,
     564              :                                                  PangoLayout *font_layout,
     565              :                                                  geometry_dimensions_t *out_feature_bounds )
     566              : {
     567            0 :     U8_TRACE_BEGIN();
     568            0 :     assert( NULL != the_feature );
     569            0 :     assert( NULL != profile );
     570            0 :     assert( NULL != pencil_size );
     571            0 :     assert( NULL != font_layout );
     572            0 :     assert( NULL != out_feature_bounds );
     573              : 
     574            0 :     const geometry_dimensions_t label_dim_proposal = {
     575            0 :         .width = 25.0 * pencil_size_get_standard_font_size( pencil_size ),
     576            0 :         .height = pencil_size_get_standard_font_size( pencil_size )
     577              :     };
     578            0 :     draw_feature_label_get_key_and_value_dimensions( &((*this_).draw_feature_label),
     579              :                                                      the_feature,
     580              :                                                      profile,
     581              :                                                      &label_dim_proposal,
     582              :                                                      pencil_size,
     583              :                                                      font_layout,
     584              :                                                      out_feature_bounds
     585              :                                                    );
     586              : 
     587            0 :     U8_TRACE_END();
     588            0 : }
     589              : 
     590              : 
     591              : /*
     592              : Copyright 2017-2026 Andreas Warnke
     593              : 
     594              : Licensed under the Apache License, Version 2.0 (the "License");
     595              : you may not use this file except in compliance with the License.
     596              : You may obtain a copy of the License at
     597              : 
     598              :     http://www.apache.org/licenses/LICENSE-2.0
     599              : 
     600              : Unless required by applicable law or agreed to in writing, software
     601              : distributed under the License is distributed on an "AS IS" BASIS,
     602              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     603              : See the License for the specific language governing permissions and
     604              : limitations under the License.
     605              : */
        

Generated by: LCOV version 2.0-1