LCOV - code coverage report
Current view: top level - pencil/include/geometry - geometry_anchor.inl (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 100.0 % 87 87
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 13 13

            Line data    Source code
       1              : /* File: geometry_anchor.inl; Copyright and License: see below */
       2              : 
       3              : #include "u8/u8_trace.h"
       4              : #include "u8/u8_log.h"
       5              : #include <assert.h>
       6              : #include <math.h>
       7              : 
       8            3 : static inline void geometry_anchor_init( geometry_anchor_t *this_,
       9              :                                          double x,
      10              :                                          double y,
      11              :                                          geometry_h_align_t x_align,
      12              :                                          geometry_v_align_t y_align )
      13              : {
      14            3 :     geometry_point_init( &((*this_).reference_point), x, y );
      15            3 :     (*this_).x_align = x_align;
      16            3 :     (*this_).y_align = y_align;
      17            3 : }
      18              : 
      19            1 : static inline void geometry_anchor_copy( geometry_anchor_t *this_, const geometry_anchor_t *original )
      20              : {
      21            1 :     assert( NULL != original );
      22            1 :     (*this_) = (*original);
      23            1 : }
      24              : 
      25            1 : static inline void geometry_anchor_replace( geometry_anchor_t *this_, const geometry_anchor_t *original )
      26              : {
      27            1 :     assert( NULL != original );
      28            1 :     (*this_) = (*original);
      29            1 : }
      30              : 
      31            3 : static inline void geometry_anchor_destroy( geometry_anchor_t *this_ )
      32              : {
      33            3 :     geometry_point_destroy( &((*this_).reference_point) );
      34            3 : }
      35              : 
      36            1 : static inline double geometry_anchor_get_x( const geometry_anchor_t *this_ )
      37              : {
      38            1 :     return geometry_point_get_x( &((*this_).reference_point) );
      39              : }
      40              : 
      41            1 : static inline double geometry_anchor_get_y( const geometry_anchor_t *this_ )
      42              : {
      43            1 :     return geometry_point_get_y( &((*this_).reference_point) );
      44              : }
      45              : 
      46            1 : static inline geometry_h_align_t geometry_anchor_get_x_align( const geometry_anchor_t *this_ )
      47              : {
      48            1 :     return (*this_).x_align;
      49              : }
      50              : 
      51            1 : static inline geometry_v_align_t geometry_anchor_get_y_align( const geometry_anchor_t *this_ )
      52              : {
      53            1 :     return (*this_).y_align;
      54              : }
      55              : 
      56            1 : static inline const geometry_point_t * geometry_anchor_get_point_const( const geometry_anchor_t *this_ )
      57              : {
      58            1 :     return &((*this_).reference_point);
      59              : }
      60              : 
      61            1 : static inline geometry_rectangle_t geometry_anchor_align_rect( const geometry_anchor_t *this_,
      62              :                                                                const geometry_rectangle_t *unaligned )
      63              : {
      64            1 :     assert( unaligned != NULL );
      65              : 
      66              :     geometry_rectangle_t result;
      67            1 :     double left = geometry_h_align_get_left( &((*this_).x_align),
      68              :                                              geometry_rectangle_get_width( unaligned ),
      69              :                                              geometry_point_get_x( &((*this_).reference_point) ),
      70              :                                              0.0 /* reference_width is zero, the reference is a point */
      71              :                                            );
      72            1 :     double top = geometry_v_align_get_top( &((*this_).y_align),
      73              :                                            geometry_rectangle_get_height( unaligned ),
      74              :                                            geometry_point_get_y( &((*this_).reference_point) ),
      75              :                                            0.0 /* reference_height is zero, the reference is a point */
      76              :                                          );
      77            1 :     geometry_rectangle_init( &result,
      78              :                              left,
      79              :                              top,
      80              :                              geometry_rectangle_get_width( unaligned ),
      81              :                              geometry_rectangle_get_height( unaligned )
      82              :                            );
      83            1 :     return result;
      84              : }
      85              : 
      86            1 : static inline geometry_rectangle_t geometry_anchor_align_dim ( const geometry_anchor_t *this_,
      87              :                                                                const geometry_dimensions_t *unaligned )
      88              : {
      89            1 :     assert( unaligned != NULL );
      90              : 
      91              :     geometry_rectangle_t result;
      92            1 :     double left = geometry_h_align_get_left( &((*this_).x_align),
      93              :                                              geometry_dimensions_get_width( unaligned ),
      94              :                                              geometry_point_get_x( &((*this_).reference_point) ),
      95              :                                              0.0 /* reference_width is zero, the reference is a point */
      96              :                                            );
      97            1 :     double top = geometry_v_align_get_top( &((*this_).y_align),
      98              :                                            geometry_dimensions_get_height( unaligned ),
      99              :                                            geometry_point_get_y( &((*this_).reference_point) ),
     100              :                                            0.0 /* reference_height is zero, the reference is a point */
     101              :                                          );
     102            1 :     geometry_rectangle_init( &result,
     103              :                              left,
     104              :                              top,
     105              :                              geometry_dimensions_get_width( unaligned ),
     106              :                              geometry_dimensions_get_height( unaligned )
     107              :                            );
     108            1 :     return result;
     109              : }
     110              : 
     111            8 : static inline geometry_rectangle_t geometry_anchor_align_biased_dim( const geometry_anchor_t *this_,
     112              :                                                                      const geometry_dimensions_t *unaligned,
     113              :                                                                      const geometry_rectangle_t *preferred_location )
     114              : {
     115            8 :     assert( unaligned != NULL );
     116              : 
     117              :     geometry_rectangle_t result;
     118              : 
     119            8 :     const double width = geometry_dimensions_get_width( unaligned );
     120            8 :     const double height = geometry_dimensions_get_height( unaligned );
     121              : 
     122            8 :     double left = geometry_h_align_get_left( &((*this_).x_align),
     123              :                                              width,
     124              :                                              geometry_point_get_x( &((*this_).reference_point) ),
     125              :                                              0.0 /* reference_width is zero, the reference is a point */
     126              :                                            );
     127            8 :     double top = geometry_v_align_get_top( &((*this_).y_align),
     128              :                                            height,
     129              :                                            geometry_point_get_y( &((*this_).reference_point) ),
     130              :                                            0.0 /* reference_height is zero, the reference is a point */
     131              :                                          );
     132              : 
     133              :     /* in case of center, allow small moves */
     134            8 :     if ( (*this_).x_align == GEOMETRY_H_ALIGN_CENTER )
     135              :     {
     136              :         /* if left/top position exceeds preferred_location, then move */
     137            7 :         const double min_x = geometry_rectangle_get_left( preferred_location );
     138            7 :         const double max_x = geometry_rectangle_get_right( preferred_location );
     139            7 :         const double max_width = geometry_rectangle_get_width( preferred_location );
     140            7 :         if ( left < min_x )
     141              :         {
     142            3 :             if ( width <= max_width )
     143              :             {
     144              :                 /* left/top position is too far left, but can fit if moved */
     145            2 :                 left = min_x;
     146              :             }
     147              :             else
     148              :             {
     149              :                 /* unaligned does not fit to preferred_location, simply center the result */
     150            1 :                 left = geometry_rectangle_get_center_x( preferred_location ) - 0.5 * width;
     151              :             }
     152              :         }
     153            4 :         else if ( left + width > max_x )
     154              :         {
     155            3 :             if ( width <= max_width )
     156              :             {
     157              :                 /* left/top position is too far left, but can fit if moved */
     158            2 :                 left = max_x - width;
     159              :             }
     160              :             else
     161              :             {
     162              :                 /* unaligned does not fit to preferred_location, simply center the result */
     163            1 :                 left = geometry_rectangle_get_center_x( preferred_location ) - 0.5 * width;
     164              :             }
     165              :         }
     166              :         /* if result moved too far, pull it back to anchor */
     167            7 :         const double reference_x = geometry_point_get_x( &((*this_).reference_point) );
     168            7 :         if ( left + width < reference_x )
     169              :         {
     170            1 :             left = reference_x - width;
     171              :         }
     172            7 :         if ( left > reference_x )
     173              :         {
     174            1 :             left = reference_x;
     175              :         }
     176              :     }
     177            8 :     if ( (*this_).y_align == GEOMETRY_V_ALIGN_CENTER )
     178              :     {
     179              :         /* if left/top position exceeds preferred_location, then move */
     180            7 :         const double min_y = geometry_rectangle_get_top( preferred_location );
     181            7 :         const double max_y = geometry_rectangle_get_bottom( preferred_location );
     182            7 :         const double max_height = geometry_rectangle_get_height( preferred_location );
     183            7 :         if ( top < min_y )
     184              :         {
     185            3 :             if ( height <= max_height )
     186              :             {
     187              :                 /* left/top position is too far left, but can fit if moved */
     188            2 :                 top = min_y;
     189              :             }
     190              :             else
     191              :             {
     192              :                 /* unaligned does not fit to preferred_location, simply center the result */
     193            1 :                 top = geometry_rectangle_get_center_y( preferred_location ) - 0.5 * height;
     194              :             }
     195              :         }
     196            4 :         else if ( top + height > max_y )
     197              :         {
     198            3 :             if ( height <= max_height )
     199              :             {
     200              :                 /* left/top position is too far left, but can fit if moved */
     201            2 :                 top = max_y - height;
     202              :             }
     203              :             else
     204              :             {
     205              :                 /* unaligned does not fit to preferred_location, simply center the result */
     206            1 :                 top = geometry_rectangle_get_center_y( preferred_location ) - 0.5 * height;
     207              :             }
     208              :         }
     209              :         /* if result moved too far, pull it back to anchor */
     210            7 :         const double reference_y = geometry_point_get_y( &((*this_).reference_point) );
     211            7 :         if ( top + height < reference_y )
     212              :         {
     213            1 :             top = reference_y - height;
     214              :         }
     215            7 :         if ( top > reference_y )
     216              :         {
     217            1 :             top = reference_y;
     218              :         }
     219              :     }
     220              : 
     221            8 :     geometry_rectangle_init( &result, left, top, width, height );
     222            8 :     return result;
     223              : }
     224              : 
     225            1 : static inline void geometry_anchor_trace( const geometry_anchor_t *this_ )
     226              : {
     227            1 :     U8_TRACE_INFO( "geometry_anchor_t" );
     228            1 :     U8_TRACE_INFO_INT( "- x:", geometry_point_get_x( &((*this_).reference_point) ) );
     229            1 :     U8_TRACE_INFO_INT( "- y:", geometry_point_get_y( &((*this_).reference_point) ) );
     230            1 :     U8_TRACE_INFO_INT( "- x_align:", (*this_).x_align );
     231            1 :     U8_TRACE_INFO_INT( "- y_align:", (*this_).y_align );
     232            1 : }
     233              : 
     234              : 
     235              : /*
     236              : Copyright 2021-2025 Andreas Warnke
     237              : 
     238              : Licensed under the Apache License, Version 2.0 (the "License");
     239              : you may not use this file except in compliance with the License.
     240              : You may obtain a copy of the License at
     241              : 
     242              :     http://www.apache.org/licenses/LICENSE-2.0
     243              : 
     244              : Unless required by applicable law or agreed to in writing, software
     245              : distributed under the License is distributed on an "AS IS" BASIS,
     246              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     247              : See the License for the specific language governing permissions and
     248              : limitations under the License.
     249              : */
        

Generated by: LCOV version 2.0-1