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

            Line data    Source code
       1              : /* File: pencil_diagram_maker.c; Copyright and License: see below */
       2              : 
       3              : #include "pencil_diagram_maker.h"
       4              : #include "u8/u8_trace.h"
       5              : #include <pango/pangocairo.h>
       6              : #include <stdio.h>
       7              : #include <stdlib.h>
       8              : #include <math.h>
       9              : 
      10            0 : void pencil_diagram_maker_draw ( pencil_diagram_maker_t *this_,
      11              :                                  data_id_t mark_focused,
      12              :                                  data_id_t mark_highlighted,
      13              :                                  const data_small_set_t *mark_selected,
      14              :                                  cairo_t *cr )
      15              : {
      16            0 :     U8_TRACE_BEGIN();
      17            0 :     assert( NULL != mark_selected );
      18            0 :     assert( NULL != cr );
      19              : 
      20              :     PangoLayout *layout;
      21            0 :     layout = pango_cairo_create_layout (cr);
      22              : 
      23              :     /* get layout data object */
      24            0 :     const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const ( &((*this_).layouter) );
      25              : 
      26              :     /* get diagram bounds */
      27            0 :     const layout_diagram_t *const diagram_layout = layout_visible_set_get_diagram_const( layout_data );
      28            0 :     const geometry_rectangle_t *const diagram_bounds = layout_diagram_get_bounds_const ( diagram_layout );
      29            0 :     double width = geometry_rectangle_get_width ( diagram_bounds );
      30            0 :     double height = geometry_rectangle_get_height ( diagram_bounds );
      31              : 
      32            0 :     const pencil_size_t *const pencil_size = pencil_layouter_get_pencil_size_const( &((*this_).layouter) );
      33              : 
      34              :     /* draw diagram */
      35            0 :     const data_diagram_t *diag = data_visible_set_get_diagram_const( (*this_).input_data );
      36            0 :     pencil_diagram_painter_draw ( &((*this_).diagram_painter),
      37              :                                   diagram_layout,
      38              :                                   data_id_equals_id( &mark_focused, DATA_TABLE_DIAGRAM, data_diagram_get_row_id(diag) ),
      39              :                                   data_id_equals_id( &mark_highlighted, DATA_TABLE_DIAGRAM, data_diagram_get_row_id(diag) ),
      40              :                                   data_small_set_contains_row_id( mark_selected, DATA_TABLE_DIAGRAM, data_diagram_get_row_id(diag) ),
      41              :                                   (*this_).profile,
      42              :                                   pencil_size,
      43              :                                   layout,
      44              :                                   cr
      45              :                                 );
      46              : 
      47            0 :     if (( width > 20.0 ) && ( height > 20.0 ))
      48              :     {
      49              :         /* draw all contained classifiers */
      50            0 :         pencil_diagram_maker_private_draw_classifiers ( this_,
      51              :                                                         mark_focused,
      52              :                                                         mark_highlighted,
      53              :                                                         mark_selected,
      54              :                                                         layout,
      55              :                                                         cr
      56              :                                                       );
      57              : 
      58              :         /* draw all contained features */
      59            0 :         pencil_diagram_maker_private_draw_features ( this_,
      60              :                                                      mark_focused,
      61              :                                                      mark_highlighted,
      62              :                                                      mark_selected,
      63              :                                                      layout,
      64              :                                                      cr
      65              :                                                    );
      66              : 
      67              :         /* draw all contained relationships */
      68            0 :         pencil_diagram_maker_private_draw_relationships ( this_,
      69              :                                                           mark_focused,
      70              :                                                           mark_highlighted,
      71              :                                                           mark_selected,
      72              :                                                           layout,
      73              :                                                           cr
      74              :                                                         );
      75              :     }
      76              : 
      77            0 :     g_object_unref (layout);
      78              : 
      79            0 :     U8_TRACE_END();
      80            0 : }
      81              : 
      82            0 : void pencil_diagram_maker_private_draw_classifiers ( pencil_diagram_maker_t *this_,
      83              :                                                      data_id_t mark_focused,
      84              :                                                      data_id_t mark_highlighted,
      85              :                                                      const data_small_set_t *mark_selected,
      86              :                                                      PangoLayout *layout,
      87              :                                                      cairo_t *cr )
      88              : {
      89            0 :     U8_TRACE_BEGIN();
      90            0 :     assert( NULL != mark_selected );
      91            0 :     assert( NULL != cr );
      92              : 
      93            0 :     const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const ( &((*this_).layouter) );
      94              : 
      95              :     /* iterate over all classifiers */
      96            0 :     const uint32_t count = layout_visible_set_get_visible_classifier_count ( layout_data );
      97            0 :     for ( uint32_t index = 0; index < count; index ++ )
      98              :     {
      99            0 :         const layout_visible_classifier_t *const classifier_layout = layout_visible_set_get_visible_classifier_const( layout_data, index );
     100              : 
     101            0 :         const pencil_size_t *const pencil_size = pencil_layouter_get_pencil_size_const( &((*this_).layouter) );
     102              : 
     103            0 :         pencil_classifier_painter_draw( &((*this_).classifier_painter),
     104              :                                         classifier_layout,
     105              :                                         mark_focused,
     106              :                                         mark_highlighted,
     107              :                                         mark_selected,
     108              :                                         layout_data,
     109              :                                         (*this_).profile,
     110              :                                         pencil_size,
     111              :                                         layout,
     112              :                                         cr
     113              :                                       );
     114              :     }
     115              : 
     116            0 :     U8_TRACE_END();
     117            0 : }
     118              : 
     119            0 : void pencil_diagram_maker_private_draw_features ( pencil_diagram_maker_t *this_,
     120              :                                                   data_id_t mark_focused,
     121              :                                                   data_id_t mark_highlighted,
     122              :                                                   const data_small_set_t *mark_selected,
     123              :                                                   PangoLayout *layout,
     124              :                                                   cairo_t *cr )
     125              : {
     126            0 :     U8_TRACE_BEGIN();
     127            0 :     assert( NULL != mark_selected );
     128            0 :     assert( NULL != cr );
     129              : 
     130            0 :     const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const( &((*this_).layouter) );
     131            0 :     layout_visible_set_t *const layout_data_mod = pencil_layouter_get_layout_data_ptr( &((*this_).layouter) );
     132              : 
     133              :     /* create an iterator over a backwards-sorted list of layout_relationship_t */
     134              :     /* Assuming that there is a chance that layout_data is already ordered, traverse it reverse to speed up sorting */
     135            0 :     universal_array_index_sorter_init( &((*this_).temp_order) );
     136            0 :     const uint32_t rel_count = layout_visible_set_get_relationship_count ( layout_data );
     137            0 :     for ( uint32_t rel_index_top = rel_count; rel_index_top > 0; rel_index_top -- )
     138              :     {
     139            0 :         const uint32_t rel_index = rel_index_top - 1;
     140            0 :         const layout_relationship_t *const relationship_layout = layout_visible_set_get_relationship_const( layout_data, rel_index );
     141            0 :         const data_relationship_t *const the_relationship = layout_relationship_get_data_const( relationship_layout );
     142            0 :         const int32_t order = data_relationship_get_list_order( the_relationship );
     143            0 :         const int64_t backwards = ( -order );
     144            0 :         const u8_error_t full = universal_array_index_sorter_insert( &((*this_).temp_order), rel_index, backwards );
     145            0 :         if ( full != U8_ERROR_NONE )
     146              :         {
     147            0 :             U8_LOG_ERROR("There are more relationships than can be sorted");
     148              :         }
     149              :     }
     150              :     layout_relationship_iter_t relationships;
     151            0 :     layout_relationship_iter_init( &relationships, layout_data_mod, &((*this_).temp_order) );
     152              : 
     153              :     /* iterate over all features */
     154            0 :     const uint32_t count = layout_visible_set_get_feature_count ( layout_data );
     155            0 :     for ( uint32_t f_idx = 0; f_idx < count; f_idx ++ )
     156              :     {
     157              :         /* get feature */
     158            0 :         const layout_feature_t *const the_feature = layout_visible_set_get_feature_const( layout_data, f_idx );
     159              : 
     160              :         /* determine display flags of diagramelement */
     161            0 :         const layout_visible_classifier_t *const classifier_layout = layout_feature_get_classifier_const( the_feature );
     162            0 :         const data_diagramelement_t *const diagramelement = layout_visible_classifier_get_diagramelement_const( classifier_layout );
     163            0 :         const data_diagramelement_flag_t display_flags = data_diagramelement_get_display_flags( diagramelement );
     164              : 
     165              :         /* draw features */
     166            0 :         pencil_feature_painter_draw ( &((*this_).feature_painter),
     167              :                                       the_feature,
     168              :                                       data_id_equals_id( &mark_focused, DATA_TABLE_FEATURE, layout_feature_get_feature_id(the_feature) ),
     169              :                                       data_id_equals_id( &mark_highlighted, DATA_TABLE_FEATURE, layout_feature_get_feature_id( the_feature ) ),
     170              :                                       data_small_set_contains_row_id( mark_selected, DATA_TABLE_FEATURE, layout_feature_get_feature_id(the_feature) ),
     171            0 :                                       (0 != ( display_flags & DATA_DIAGRAMELEMENT_FLAG_GRAY_OUT )),
     172              :                                       &relationships,
     173              :                                       (*this_).profile,
     174              :                                       pencil_layouter_get_pencil_size_const( &((*this_).layouter) ),
     175              :                                       layout,
     176              :                                       cr
     177              :                                     );
     178              : 
     179              :         /* reset for next loop */
     180            0 :         layout_relationship_iter_reset( &relationships );
     181              :     }
     182              : 
     183            0 :     layout_relationship_iter_destroy( &relationships );
     184            0 :     universal_array_index_sorter_destroy( &((*this_).temp_order) );
     185              : 
     186            0 :     U8_TRACE_END();
     187            0 : }
     188              : 
     189            0 : void pencil_diagram_maker_private_draw_relationships ( pencil_diagram_maker_t *this_,
     190              :                                                        data_id_t mark_focused,
     191              :                                                        data_id_t mark_highlighted,
     192              :                                                        const data_small_set_t *mark_selected,
     193              :                                                        PangoLayout *layout,
     194              :                                                        cairo_t *cr )
     195              : {
     196            0 :     U8_TRACE_BEGIN();
     197            0 :     assert( NULL != mark_selected );
     198            0 :     assert( NULL != cr );
     199              : 
     200            0 :     const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const ( &((*this_).layouter) );
     201              : 
     202            0 :     const uint32_t rel_count = layout_visible_set_get_relationship_count ( layout_data );
     203            0 :     for ( uint32_t index = 0; index < rel_count; index ++ )
     204              :     {
     205              :         pencil_visibility_t show_relation;
     206            0 :         const layout_relationship_t *const relationship_layout = layout_visible_set_get_relationship_const ( layout_data, index );
     207            0 :         const data_relationship_t *const the_relationship = layout_relationship_get_data_const ( relationship_layout );
     208            0 :         show_relation = layout_relationship_get_visibility ( relationship_layout );
     209            0 :         if ( PENCIL_VISIBILITY_IMPLICIT == show_relation )
     210              :         {
     211            0 :             if ( data_id_equals_id( &mark_focused, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) )
     212            0 :                 || data_id_equals_id( &mark_highlighted, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) )
     213            0 :                 || data_small_set_contains_row_id( mark_selected, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) ) )
     214              :             {
     215              :                 /* the implicit relationship is focused or marked or highlighted */
     216            0 :                 show_relation = PENCIL_VISIBILITY_SHOW;
     217              :             }
     218              :             else
     219              :             {
     220            0 :                 if ( DATA_TABLE_DIAGRAMELEMENT == data_id_get_table( &mark_highlighted ) )
     221              :                 {
     222            0 :                     const data_row_t diagramelement_id = data_id_get_row_id( &mark_highlighted );
     223              :                     const data_visible_classifier_t *visible_clsfy
     224            0 :                         = data_visible_set_get_visible_classifier_by_id_const( (*this_).input_data, diagramelement_id );
     225            0 :                     if ( visible_clsfy != NULL )
     226              :                     {
     227            0 :                         if ( data_visible_classifier_is_valid( visible_clsfy ) )
     228              :                         {
     229            0 :                             const data_classifier_t *classifier = data_visible_classifier_get_classifier_const( visible_clsfy );
     230            0 :                             if (( data_classifier_get_row_id( classifier ) == data_relationship_get_from_classifier_row_id( the_relationship ) )
     231            0 :                                 ||( data_classifier_get_row_id( classifier ) == data_relationship_get_to_classifier_row_id( the_relationship ) ))
     232              :                             {
     233              :                                 /* the implicit relationship has highlighted from or to classifier */
     234            0 :                                 show_relation = PENCIL_VISIBILITY_SHOW;
     235              :                             }
     236              :                         }
     237              :                     }
     238              : 
     239              :                 }
     240              :             }
     241              :         }
     242            0 :         if (( PENCIL_VISIBILITY_SHOW == show_relation )||( PENCIL_VISIBILITY_GRAY_OUT == show_relation ))
     243              :         {
     244            0 :             const pencil_size_t *const pencil_size = pencil_layouter_get_pencil_size_const( &((*this_).layouter) );
     245            0 :             pencil_relationship_painter_draw ( &((*this_).relationship_painter),
     246              :                                                relationship_layout,
     247              :                                                data_id_equals_id( &mark_focused, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) ),
     248              :                                                data_id_equals_id( &mark_highlighted, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id( the_relationship ) ),
     249              :                                                data_small_set_contains_row_id( mark_selected, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) ),
     250              :                                                (*this_).profile,
     251              :                                                pencil_size,
     252              :                                                layout,
     253              :                                                cr
     254              :                                              );
     255              :         }
     256              :     }
     257              : 
     258            0 :     U8_TRACE_END();
     259            0 : }
     260              : 
     261            0 : pencil_error_t pencil_diagram_maker_get_order_at_pos ( const pencil_diagram_maker_t *this_,
     262              :                                                        data_id_t obj_id,
     263              :                                                        double x,
     264              :                                                        double y,
     265              :                                                        double snap_to_grid_distance,
     266              :                                                        layout_order_t* out_layout_order )
     267              : {
     268            0 :     U8_TRACE_BEGIN();
     269            0 :     assert( NULL != out_layout_order );
     270              : 
     271            0 :     pencil_error_t result = PENCIL_ERROR_NONE;
     272              : 
     273            0 :     const data_table_t table = data_id_get_table ( &obj_id );
     274            0 :     switch ( table )
     275              :     {
     276            0 :         case DATA_TABLE_CLASSIFIER:
     277              :         {
     278            0 :             const data_row_t classifier_id = data_id_get_row_id ( &obj_id );
     279              :             const data_classifier_t *const the_classifier
     280            0 :                 = data_visible_set_get_classifier_by_id_const ( (*this_).input_data, classifier_id );
     281            0 :             const data_classifier_type_t c_type
     282              :                 = (NULL == the_classifier)
     283              :                 ? DATA_CLASSIFIER_TYPE_CLASS  /* for new or unknown objects, assume class */
     284            0 :                 : data_classifier_get_main_type( the_classifier );
     285            0 :             result = pencil_layouter_get_classifier_order_at_pos ( &((*this_).layouter),
     286              :                                                                    c_type,
     287              :                                                                    x,
     288              :                                                                    y,
     289              :                                                                    snap_to_grid_distance,
     290              :                                                                    out_layout_order
     291              :                                                                  );
     292              :         }
     293            0 :         break;
     294              : 
     295            0 :         case DATA_TABLE_FEATURE:
     296              :         {
     297            0 :             const data_row_t feature_id = data_id_get_row_id ( &obj_id );
     298              :             const data_feature_t *const the_feature
     299            0 :                 = data_visible_set_get_feature_by_id_const ( (*this_).input_data, feature_id );
     300            0 :             if( NULL != the_feature )
     301              :             {
     302            0 :                 result = pencil_layouter_get_feature_order_at_pos ( &((*this_).layouter),
     303              :                                                                     the_feature,
     304              :                                                                     x,
     305              :                                                                     y,
     306              :                                                                     out_layout_order
     307              :                                                                   );
     308              :             }
     309              :             else
     310              :             {
     311            0 :                 U8_LOG_ANOMALY( "feature to move does not exist in input_data." );
     312            0 :                 layout_order_init_empty( out_layout_order );
     313            0 :                 result = PENCIL_ERROR_UNKNOWN_OBJECT;
     314              :             }
     315              :         }
     316            0 :         break;
     317              : 
     318            0 :         case DATA_TABLE_RELATIONSHIP:
     319              :         {
     320            0 :             result = pencil_layouter_get_relationship_order_at_pos ( &((*this_).layouter),
     321              :                                                                      x,
     322              :                                                                      y,
     323              :                                                                      out_layout_order
     324              :                                                                    );
     325              :         }
     326            0 :         break;
     327              : 
     328            0 :         case DATA_TABLE_DIAGRAMELEMENT:
     329              :         {
     330            0 :             U8_LOG_WARNING( "not implemented to move diagramelements. use the classifier instead." );
     331            0 :             layout_order_init_empty( out_layout_order );
     332            0 :             result = PENCIL_ERROR_UNKNOWN_OBJECT;
     333              :         }
     334            0 :         break;
     335              : 
     336            0 :         case DATA_TABLE_DIAGRAM:
     337              :         {
     338              :             /* pencil cannot move diagrams */
     339            0 :             U8_LOG_WARNING( "object to be re-positioned has unexpected type: diagram" );
     340            0 :             layout_order_init_empty( out_layout_order );
     341            0 :             result = PENCIL_ERROR_UNKNOWN_OBJECT;
     342              :         }
     343            0 :         break;
     344              : 
     345            0 :         default:
     346              :         {
     347            0 :             U8_LOG_WARNING( "object to be re-positioned has illegal type" );
     348            0 :             layout_order_init_empty( out_layout_order );
     349            0 :             result = PENCIL_ERROR_UNKNOWN_OBJECT;
     350              :         }
     351            0 :         break;
     352              :     }
     353              : 
     354            0 :     U8_TRACE_END_ERR(result);
     355            0 :     return result;
     356              : }
     357              : 
     358            0 : pencil_error_t pencil_diagram_maker_get_feature_order_at_pos ( const pencil_diagram_maker_t *this_,
     359              :                                                                const data_feature_t *feature_ptr,
     360              :                                                                double x,
     361              :                                                                double y,
     362              :                                                                layout_order_t* out_layout_order )
     363              : {
     364            0 :     U8_TRACE_BEGIN();
     365            0 :     assert( NULL != feature_ptr );
     366            0 :     assert( NULL != out_layout_order );
     367              : 
     368              :     const pencil_error_t result
     369            0 :         = pencil_layouter_get_feature_order_at_pos ( &((*this_).layouter),
     370              :                                                      feature_ptr,
     371              :                                                      x,
     372              :                                                      y,
     373              :                                                      out_layout_order
     374              :                                                    );
     375              : 
     376            0 :     U8_TRACE_END_ERR(result);
     377            0 :     return result;
     378              : }
     379              : 
     380              : 
     381              : /*
     382              : Copyright 2016-2026 Andreas Warnke
     383              : 
     384              : Licensed under the Apache License, Version 2.0 (the "License");
     385              : you may not use this file except in compliance with the License.
     386              : You may obtain a copy of the License at
     387              : 
     388              :     http://www.apache.org/licenses/LICENSE-2.0
     389              : 
     390              : Unless required by applicable law or agreed to in writing, software
     391              : distributed under the License is distributed on an "AS IS" BASIS,
     392              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     393              : See the License for the specific language governing permissions and
     394              : limitations under the License.
     395              : */
        

Generated by: LCOV version 2.0-1