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

Generated by: LCOV version 1.16