LCOV - code coverage report
Current view: top level - pencil/include - pencil_floating_label_layouter.inl (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 0.0 % 67 0
Test Date: 2025-05-01 10:10:14 Functions: 0.0 % 1 0

            Line data    Source code
       1              : /* File: pencil_floating_label_layouter.inl; Copyright and License: see below */
       2              : 
       3              : #include <assert.h>
       4              : 
       5            0 : static inline void pencil_floating_label_layouter_private_propose_solution( const pencil_floating_label_layouter_t *this_,
       6              :                                                                             const geometry_anchor_t *anchor,
       7              :                                                                             const geometry_dimensions_t *preferred_dim,
       8              :                                                                             draw_feature_label_t *draw_estimator_feat,
       9              :                                                                             const data_feature_t *feature,
      10              :                                                                             draw_relationship_label_t *draw_estimator_rel,
      11              :                                                                             const data_relationship_t *relation,
      12              :                                                                             geometry_rectangle_t *out_solution )
      13              : {
      14            0 :     U8_TRACE_BEGIN();
      15            0 :     assert( (*this_).pencil_size != NULL );
      16            0 :     assert( (*this_).layout_data != NULL );
      17            0 :     assert( (*this_).profile != NULL );
      18            0 :     assert( (*this_).font_layout != NULL );
      19            0 :     assert( anchor != NULL );
      20            0 :     assert( preferred_dim != NULL );
      21            0 :     if ( draw_estimator_feat == NULL )
      22              :     {
      23            0 :         assert( feature == NULL );
      24            0 :         assert( draw_estimator_rel != NULL );
      25            0 :         assert( relation != NULL );
      26              :     }
      27              :     else
      28              :     {
      29            0 :         assert( feature != NULL );
      30            0 :         assert( draw_estimator_rel == NULL );
      31            0 :         assert( relation == NULL );
      32              :     }
      33            0 :     assert( out_solution != NULL );
      34              : 
      35              :     /* get draw area */
      36            0 :     const layout_diagram_t *const diagram_layout = layout_visible_set_get_diagram_ptr( (*this_).layout_data );
      37            0 :     const geometry_rectangle_t *const diagram_draw_rect = layout_diagram_get_draw_area_const( diagram_layout );
      38              : 
      39              :     /* Start shrinking the available solution space to anchor-alignment and diagram space. */
      40              :     /* To not accidentially shrink to wrong width/height by taking into account far-away elements, */
      41              :     /* start with a smaller rectagle of 3..5 * preferred_dim: This allows for moving by +/- 0.5 and re-sizing by factor 2..4 */
      42              :     geometry_dimensions_t search_area;  /* limit the search area to avoid that far-away elements limit width or height */
      43            0 :     geometry_dimensions_init( &search_area, 3.0 * geometry_dimensions_get_width( preferred_dim ), 5.0 * geometry_dimensions_get_height( preferred_dim ) );
      44            0 :     geometry_rectangle_t available = geometry_anchor_align_dim( anchor, &search_area );
      45            0 :     geometry_rectangle_init_by_intersect( &available, &available, diagram_draw_rect );
      46              : 
      47              :     /* iterate over all classifiers */
      48            0 :     const uint32_t count_classifiers = layout_visible_set_get_visible_classifier_count( (*this_).layout_data );
      49            0 :     for ( uint32_t classifier_index = 0; classifier_index < count_classifiers; classifier_index ++ )
      50              :     {
      51              :         const layout_visible_classifier_t *const probe_classifier
      52            0 :             = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, classifier_index );
      53            0 :         const geometry_rectangle_t *const probe_space = layout_visible_classifier_get_space_const( probe_classifier );
      54            0 :         if ( geometry_rectangle_contains_point( probe_space, geometry_anchor_get_point_const( anchor ) ) )
      55              :         {
      56              :             /* reference point is inside the space of probe_classifier */
      57              :             /* shrink the available solution space to the classifier space */
      58            0 :             geometry_rectangle_init_by_intersect( &available, &available, probe_space );
      59              :         }
      60              :         else
      61              :         {
      62            0 :             geometry_rectangle_init_by_difference_at_pivot( &available,
      63              :                                                             &available,
      64              :                                                             layout_visible_classifier_get_symbol_box_const( probe_classifier ),
      65              :                                                             geometry_anchor_get_point_const( anchor )
      66              :                                                           );
      67            0 :             geometry_rectangle_init_by_difference_at_pivot( &available,
      68              :                                                             &available,
      69              :                                                             layout_visible_classifier_get_label_box_const( probe_classifier ),
      70              :                                                             geometry_anchor_get_point_const( anchor )
      71              :                                                           );
      72              :             /*
      73              :             icon_box is covered by symbol_box
      74              :             geometry_rectangle_init_by_difference_at_pivot( &available,
      75              :                                                             &available,
      76              :                                                             layout_visible_classifier_get_icon_box_const( probe_classifier ),
      77              :                                                             geometry_anchor_get_point_const( anchor )
      78              :                                                           );
      79              :             */
      80              :         }
      81              :     }
      82              : 
      83              :     /* iterate over all features */
      84            0 :     const uint32_t count_features = layout_visible_set_get_feature_count( (*this_).layout_data );
      85            0 :     for ( uint32_t feature_index = 0; feature_index < count_features; feature_index ++ )
      86              :     {
      87              :         const layout_feature_t *const probe_feature
      88            0 :             = layout_visible_set_get_feature_ptr( (*this_).layout_data, feature_index );
      89            0 :         const data_feature_t *const probe_feature_data = layout_feature_get_data_const( probe_feature );
      90            0 :         if ( DATA_FEATURE_TYPE_LIFELINE != data_feature_get_main_type( probe_feature_data ) )
      91              :         {
      92            0 :             geometry_rectangle_init_by_difference_at_pivot( &available,
      93              :                                                             &available,
      94              :                                                             layout_feature_get_symbol_box_const( probe_feature ),
      95              :                                                             geometry_anchor_get_point_const( anchor )
      96              :                                                           );
      97              :             /* note: the label_box may not yet have been initialized in all cases */
      98              :         }
      99              :         else
     100              :         {
     101              :             /* ignore lifelines - otherwise the labels are shrinked to fit between lielines which looks ugly */
     102              :         }
     103              :     }
     104              : 
     105              :     /* iterate over all relationships */
     106            0 :     const uint32_t count_relationships = layout_visible_set_get_relationship_count( (*this_).layout_data );
     107            0 :     for ( uint32_t relationship_index = 0; relationship_index < count_relationships; relationship_index ++ )
     108              :     {
     109              :         const layout_relationship_t *const probe_relationship
     110            0 :             = layout_visible_set_get_relationship_ptr( (*this_).layout_data, relationship_index );
     111            0 :         const geometry_connector_t *const conn = layout_relationship_get_shape_const( probe_relationship );
     112            0 :         const geometry_rectangle_t source = geometry_connector_get_segment_bounds( conn, GEOMETRY_CONNECTOR_SEGMENT_SOURCE );
     113            0 :         const geometry_rectangle_t middle = geometry_connector_get_segment_bounds( conn, GEOMETRY_CONNECTOR_SEGMENT_MAIN );
     114            0 :         const geometry_rectangle_t dest = geometry_connector_get_segment_bounds( conn, GEOMETRY_CONNECTOR_SEGMENT_DESTINATION );
     115            0 :         geometry_rectangle_init_by_difference_at_pivot( &available,
     116              :                                                         &available,
     117              :                                                         &source,
     118              :                                                         geometry_anchor_get_point_const( anchor )
     119              :                                                       );
     120            0 :         geometry_rectangle_init_by_difference_at_pivot( &available,
     121              :                                                         &available,
     122              :                                                         &middle,
     123              :                                                         geometry_anchor_get_point_const( anchor )
     124              :                                                       );
     125            0 :         geometry_rectangle_init_by_difference_at_pivot( &available,
     126              :                                                         &available,
     127              :                                                         &dest,
     128              :                                                         geometry_anchor_get_point_const( anchor )
     129              :                                                       );
     130              :         /* note: the label_box may not yet have been initialized in all cases */
     131              :     }
     132              : 
     133              :     /* if the available solution space has a positive width, layout the label */
     134            0 :     const double available_width = geometry_rectangle_get_width( &available );
     135            0 :     const geometry_dimensions_t available_dim = geometry_rectangle_get_dimensions( &available );
     136            0 :     bool preferred_fits = geometry_dimensions_can_contain( &available_dim, preferred_dim )
     137            0 :         || ( geometry_dimensions_get_width( preferred_dim ) < 0.000000001 );
     138            0 :     if ( preferred_fits )
     139              :     {
     140              :         /* no need to re-calculate, just shift */
     141            0 :         *out_solution = geometry_anchor_align_biased_dim( anchor, preferred_dim, &available );
     142              :     }
     143            0 :     else if ( available_width > pencil_size_get_standard_font_size( (*this_).pencil_size ) )
     144              :     {
     145              :         /* try to fit the label into the available space */
     146              :         geometry_dimensions_t label_dim;
     147            0 :         if ( draw_estimator_feat != NULL )
     148              :         {
     149            0 :             draw_feature_label_get_key_and_value_dimensions( draw_estimator_feat,
     150              :                                                              feature,
     151            0 :                                                              (*this_).profile,
     152              :                                                              &available_dim,
     153            0 :                                                              (*this_).pencil_size,
     154            0 :                                                              (*this_).font_layout,
     155              :                                                              &label_dim
     156              :                                                            );
     157              :         }
     158              :         else
     159              :         {
     160            0 :             draw_relationship_label_get_type_and_name_dimensions( draw_estimator_rel,
     161              :                                                                   relation,
     162            0 :                                                                   (*this_).profile,
     163              :                                                                   &available_dim,
     164            0 :                                                                   (*this_).pencil_size,
     165            0 :                                                                   (*this_).font_layout,
     166              :                                                                   &label_dim
     167              :                                                                 );
     168              :         }
     169              : 
     170            0 :         *out_solution = geometry_anchor_align_biased_dim( anchor, &label_dim, &available );
     171              : 
     172            0 :         U8_TRACE_INFO_INT_INT("pencil_floating_label: label does not fit to available space", (int) geometry_dimensions_get_width( preferred_dim ), (int) available_width );
     173            0 :         U8_TRACE_INFO_INT("pencil_floating_label: suitable label width found:", (int) geometry_dimensions_get_width( &label_dim ) );
     174              :     }
     175              :     else
     176              :     {
     177              :         /* there is no space, accept any overlap */
     178            0 :         *out_solution = geometry_anchor_align_dim( anchor, preferred_dim );
     179              :     }
     180              : 
     181            0 :     U8_TRACE_END();
     182            0 : }
     183              : 
     184              : 
     185              : /*
     186              : Copyright 2025-2025 Andreas Warnke
     187              : 
     188              : Licensed under the Apache License, Version 2.0 (the "License");
     189              : you may not use this file except in compliance with the License.
     190              : You may obtain a copy of the License at
     191              : 
     192              :     http://www.apache.org/licenses/LICENSE-2.0
     193              : 
     194              : Unless required by applicable law or agreed to in writing, software
     195              : distributed under the License is distributed on an "AS IS" BASIS,
     196              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     197              : See the License for the specific language governing permissions and
     198              : limitations under the License.
     199              : */
        

Generated by: LCOV version 2.0-1