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

            Line data    Source code
       1              : /* File: pencil_diagram_painter.c; Copyright and License: see below */
       2              : 
       3              : #include "pencil_diagram_painter.h"
       4              : #include "u8/u8_trace.h"
       5              : #include <pango/pangocairo.h>
       6              : #include <stdio.h>
       7              : #include <stdlib.h>
       8              : #include <assert.h>
       9              : 
      10            0 : void pencil_diagram_painter_init( pencil_diagram_painter_t *this_ )
      11              : {
      12            0 :     U8_TRACE_BEGIN();
      13              : 
      14            0 :     pencil_marker_init( &((*this_).marker) );
      15            0 :     draw_diagram_label_init( &((*this_).draw_diagram_label) );
      16            0 :     draw_diagram_ornaments_init( &((*this_).draw_diagram_ornaments) );
      17              : 
      18            0 :     U8_TRACE_END();
      19            0 : }
      20              : 
      21            0 : void pencil_diagram_painter_destroy( pencil_diagram_painter_t *this_ )
      22              : {
      23            0 :     U8_TRACE_BEGIN();
      24              : 
      25            0 :     draw_diagram_ornaments_destroy( &((*this_).draw_diagram_ornaments) );
      26            0 :     draw_diagram_label_init( &((*this_).draw_diagram_label) );
      27            0 :     pencil_marker_destroy( &((*this_).marker) );
      28              : 
      29            0 :     U8_TRACE_END();
      30            0 : }
      31              : 
      32            0 : void pencil_diagram_painter_draw ( pencil_diagram_painter_t *this_,
      33              :                                    const layout_diagram_t *layouted_diagram,
      34              :                                    bool mark_focused,
      35              :                                    bool mark_highlighted,
      36              :                                    bool mark_selected,
      37              :                                    const data_profile_part_t *profile,
      38              :                                    const pencil_size_t *pencil_size,
      39              :                                    PangoLayout *font_layout,
      40              :                                    cairo_t *cr )
      41              : {
      42            0 :     U8_TRACE_BEGIN();
      43            0 :     assert( NULL != layouted_diagram );
      44            0 :     assert( NULL != profile );
      45            0 :     assert( NULL != pencil_size );
      46            0 :     assert( NULL != font_layout );
      47            0 :     assert( NULL != cr );
      48              : 
      49            0 :     const data_diagram_t *const the_diagram = layout_diagram_get_data_const( layouted_diagram );
      50            0 :     const geometry_rectangle_t *const diagram_bounds = layout_diagram_get_bounds_const( layouted_diagram );
      51            0 :     const geometry_rectangle_t *const label_box = layout_diagram_get_label_box_const( layouted_diagram );
      52              : 
      53            0 :     const double left = geometry_rectangle_get_left ( diagram_bounds );
      54            0 :     const double top = geometry_rectangle_get_top ( diagram_bounds );
      55            0 :     const double right = geometry_rectangle_get_right ( diagram_bounds );
      56            0 :     const double bottom = geometry_rectangle_get_bottom ( diagram_bounds );
      57            0 :     const double width = geometry_rectangle_get_width ( diagram_bounds );
      58            0 :     const double height = geometry_rectangle_get_height ( diagram_bounds );
      59              : 
      60            0 :     U8_TRACE_INFO_INT( "w", (int)(width) );
      61            0 :     U8_TRACE_INFO_INT( "h", (int)(height) );
      62              : 
      63            0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
      64              : 
      65              :     /* draw diagram border and name */
      66              :     {
      67            0 :         U8_TRACE_INFO_INT("drawing diagram id",data_diagram_get_row_id(the_diagram));
      68              : 
      69            0 :         const double std_line_width = pencil_size_get_standard_line_width( pencil_size );
      70            0 :         cairo_set_line_width( cr, std_line_width );
      71            0 :         if ( data_diagram_is_valid(the_diagram) )
      72              :         {
      73              :             /* draw border line */
      74              :             const GdkRGBA fg_color
      75              :                 = mark_highlighted
      76            0 :                 ? pencil_size_get_highlight_color( pencil_size )
      77            0 :                 : pencil_size_get_standard_color( pencil_size );
      78            0 :             cairo_set_source_rgba( cr, fg_color.red, fg_color.green, fg_color.blue, fg_color.alpha );
      79            0 :             cairo_rectangle ( cr, left+gap, top+gap, width-2.0*gap, height-2.0*gap );
      80            0 :             cairo_stroke (cr);
      81              : 
      82              :             /* draw title corner */
      83            0 :             draw_diagram_label_draw_type_and_name( &((*this_).draw_diagram_label),
      84              :                                                    the_diagram,
      85              :                                                    profile,
      86              :                                                    &fg_color,
      87              :                                                    label_box,
      88              :                                                    pencil_size,
      89              :                                                    font_layout,
      90              :                                                    cr
      91              :                                                  );
      92              : 
      93            0 :             const double title_corner_height = geometry_rectangle_get_height( label_box ) + 2.0 * gap;
      94            0 :             const double title_corner_edge45 = 0.4 * title_corner_height;
      95            0 :             double title_corner_width
      96            0 :                 = geometry_rectangle_get_width( label_box ) + 3.0 * gap + title_corner_edge45;
      97            0 :             if ( title_corner_width > width*0.9 )
      98              :             {
      99            0 :                 title_corner_width = width*0.9;
     100              :             }
     101            0 :             cairo_move_to ( cr, left+gap, top+gap+title_corner_height );
     102            0 :             cairo_line_to ( cr, left+gap+title_corner_width - title_corner_edge45, top+gap+title_corner_height );
     103            0 :             cairo_line_to ( cr, left+gap+title_corner_width, top+gap+title_corner_height-title_corner_edge45 );
     104            0 :             cairo_line_to ( cr, left+gap+title_corner_width, top+gap );
     105            0 :             cairo_stroke (cr);
     106              :         }
     107              :         else
     108              :         {
     109              :             /* draw cross line */
     110            0 :             const GdkRGBA standard_color = pencil_size_get_standard_color( pencil_size );
     111            0 :             cairo_set_source_rgba( cr, standard_color.red, standard_color.green, standard_color.blue, standard_color.alpha );
     112            0 :             cairo_move_to ( cr, left, top );
     113            0 :             cairo_line_to ( cr, right, bottom );
     114            0 :             cairo_move_to ( cr, left, bottom );
     115            0 :             cairo_line_to ( cr, right, top );
     116            0 :             cairo_stroke (cr);
     117              :         }
     118              :     }
     119              : 
     120              :     /* draw id */
     121              :     {
     122              :         /* prepare text */
     123            0 :         const data_id_t the_id = data_diagram_get_data_id(the_diagram);
     124              : 
     125              :         char id_buf[DATA_ID_MAX_UTF8STRING_SIZE+5];
     126            0 :         utf8stringbuf_t id_str = UTF8STRINGBUF( id_buf );
     127            0 :         utf8stringbuf_copy_str( &id_str, "{id=" );
     128            0 :         data_id_to_utf8stringbuf( &the_id, id_str );
     129            0 :         utf8stringbuf_append_str( &id_str, "}" );
     130              : 
     131              :         int text4_width;
     132              :         int text4_height;
     133            0 :         pango_layout_set_font_description (font_layout, pencil_size_get_footnote_font_description(pencil_size) );
     134            0 :         pango_layout_set_text (font_layout, utf8stringbuf_get_string( &id_str ), -1);
     135            0 :         pango_layout_get_pixel_size (font_layout, &text4_width, &text4_height);
     136            0 :         text4_height += PENCIL_SIZE_FONT_ALIGN_MARGIN;  /* allow to align font with pixel border */
     137            0 :         text4_width += PENCIL_SIZE_FONT_ALIGN_MARGIN;
     138              : 
     139              :         /* draw text */
     140            0 :         const GdkRGBA grey_color = pencil_size_get_gray_out_color( pencil_size );
     141            0 :         cairo_set_source_rgba( cr, grey_color.red, grey_color.green, grey_color.blue, grey_color.alpha );
     142            0 :         cairo_move_to( cr,
     143            0 :                        ceil( left + width - text4_width - gap - gap ),
     144              :                        ceil( top + gap )
     145              :                      );  /* align font with pixel border */
     146            0 :         pango_cairo_show_layout( cr, font_layout );
     147              :     }
     148              : 
     149              :     /* draw ornaments */
     150            0 :     if ( data_diagram_is_valid( the_diagram ) )
     151              :     {
     152              :         /* draw color */
     153              :         const GdkRGBA fg_color
     154              :             = mark_highlighted
     155            0 :             ? pencil_size_get_highlight_color( pencil_size )
     156            0 :             : pencil_size_get_standard_color( pencil_size );
     157            0 :         cairo_set_source_rgba( cr, fg_color.red, fg_color.green, fg_color.blue, fg_color.alpha );
     158              : 
     159              :         /* get locations */
     160            0 :         const geometry_rectangle_t *const diagram_draw_area = layout_diagram_get_draw_area_const( layouted_diagram );
     161            0 :         const double draw_left = geometry_rectangle_get_left ( diagram_draw_area );
     162            0 :         const double draw_bottom = geometry_rectangle_get_bottom ( diagram_draw_area );
     163            0 :         const double draw_width = geometry_rectangle_get_width ( diagram_draw_area );
     164              : 
     165            0 :         if ( data_diagram_get_diagram_type( the_diagram ) == DATA_DIAGRAM_TYPE_UML_TIMING_DIAGRAM )
     166              :         {
     167            0 :             const double obj_dist = pencil_size_get_preferred_object_distance( pencil_size );
     168            0 :             const double used_draw_width = draw_width - 2.0 * obj_dist;
     169              :             /* const double phi = 1.6180339; */
     170            0 :             const double minor_ratio = (1.0 - 0.6180339);
     171            0 :             const double classifier_width = used_draw_width * minor_ratio / 2.0;
     172            0 :             const geometry_rectangle_t scale_bounds
     173            0 :                 = { .left = draw_left + obj_dist + classifier_width + obj_dist,
     174            0 :                     .top = draw_bottom - obj_dist,
     175            0 :                     .width = used_draw_width - classifier_width - obj_dist,
     176              :                     .height = obj_dist
     177              :                   };
     178            0 :             draw_diagram_ornaments_draw_scale( &((*this_).draw_diagram_ornaments),
     179              :                                                &scale_bounds,
     180              :                                                pencil_size,
     181              :                                                cr
     182              :                                              );
     183              :         }
     184              :     }
     185              : 
     186              :     /* mark focused and highlighted */
     187              :     {
     188            0 :         if ( mark_focused )
     189              :         {
     190            0 :             pencil_marker_mark_focused_rectangle( &((*this_).marker), *diagram_bounds, cr );
     191              :         }
     192              : 
     193            0 :         if ( mark_selected )
     194              :         {
     195              :             geometry_rectangle_t selected_rect;
     196            0 :             geometry_rectangle_init( &selected_rect, left+gap, top+gap, width-2.0*gap, height-2.0*gap );
     197            0 :             pencil_marker_mark_selected_rectangle( &((*this_).marker), selected_rect, cr );
     198            0 :             geometry_rectangle_destroy( &selected_rect );
     199              :         }
     200              :     }
     201              : 
     202            0 :     U8_TRACE_END();
     203            0 : }
     204              : 
     205            0 : void pencil_diagram_painter_do_layout ( pencil_diagram_painter_t *this_,
     206              :                                         const data_diagram_t *the_diagram,
     207              :                                         const geometry_rectangle_t *diagram_bounds,
     208              :                                         const data_profile_part_t *profile,
     209              :                                         const pencil_size_t *pencil_size,
     210              :                                         PangoLayout *font_layout,
     211              :                                         layout_diagram_t *io_layout_diagram )
     212              : {
     213            0 :     U8_TRACE_BEGIN();
     214            0 :     assert( NULL != the_diagram );
     215            0 :     assert( NULL != diagram_bounds );
     216            0 :     assert( NULL != profile );
     217            0 :     assert( NULL != pencil_size );
     218            0 :     assert( NULL != font_layout );
     219            0 :     assert( NULL != io_layout_diagram );
     220              : 
     221              :     /* determine diagram bounds */
     222            0 :     const double left = geometry_rectangle_get_left ( diagram_bounds );
     223            0 :     const double top = geometry_rectangle_get_top ( diagram_bounds );
     224            0 :     const double width = geometry_rectangle_get_width ( diagram_bounds );
     225            0 :     const double height = geometry_rectangle_get_height ( diagram_bounds );
     226            0 :     const double gap = pencil_size_get_standard_object_border( pencil_size );
     227              : 
     228              :     /* calculate label_box */
     229            0 :     const double text_left = left + 3.0 * gap;
     230            0 :     const double text_top = top + 2.0 * gap;
     231            0 :     const geometry_dimensions_t label_dim_proposal
     232            0 :         = { .width = width, .height = pencil_size_get_standard_font_size( pencil_size ) };
     233              :     geometry_dimensions_t label_dim;
     234            0 :     draw_diagram_label_get_type_and_name_dimensions( &((*this_).draw_diagram_label),
     235              :                                                      the_diagram,
     236              :                                                      profile,
     237              :                                                      &label_dim_proposal,
     238              :                                                      pencil_size,
     239              :                                                      font_layout,
     240              :                                                      &label_dim
     241              :                                                    );
     242            0 :     const double text_width = geometry_dimensions_get_width( &label_dim );
     243            0 :     const double text_height = geometry_dimensions_get_height( &label_dim );
     244              :     geometry_rectangle_t label_box;
     245            0 :     geometry_rectangle_init( &label_box, text_left, text_top, text_width, text_height );
     246              : 
     247              :     /* calculate space */
     248            0 :     const double space_left = left + 2.0 * gap;
     249            0 :     const double space_top = top + 4.0 * gap + text_height;
     250            0 :     const double space_width = width - 4.0 * gap;
     251            0 :     const double space_height = height - 6.0 * gap - text_height;
     252              :     geometry_rectangle_t space;
     253            0 :     if ( ( space_width <= 0.0 ) || ( space_height <= 0.0 ) )
     254              :     {
     255            0 :         geometry_rectangle_init_empty( &space );
     256              :     }
     257              :     else
     258              :     {
     259            0 :         geometry_rectangle_init( &space, space_left, space_top, space_width, space_height );
     260              :     }
     261              : 
     262              :     /* set new metrics */
     263            0 :     layout_diagram_set_bounds( io_layout_diagram, diagram_bounds );
     264            0 :     layout_diagram_set_draw_area( io_layout_diagram, &space );
     265            0 :     layout_diagram_set_label_box( io_layout_diagram, &label_box );
     266              : 
     267            0 :     geometry_rectangle_destroy( &space );
     268            0 :     geometry_rectangle_destroy( &label_box );
     269            0 :     U8_TRACE_END();
     270            0 : }
     271              : 
     272              : 
     273              : /*
     274              : Copyright 2017-2026 Andreas Warnke
     275              : 
     276              : Licensed under the Apache License, Version 2.0 (the "License");
     277              : you may not use this file except in compliance with the License.
     278              : You may obtain a copy of the License at
     279              : 
     280              :     http://www.apache.org/licenses/LICENSE-2.0
     281              : 
     282              : Unless required by applicable law or agreed to in writing, software
     283              : distributed under the License is distributed on an "AS IS" BASIS,
     284              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     285              : See the License for the specific language governing permissions and
     286              : limitations under the License.
     287              : */
        

Generated by: LCOV version 2.0-1