Line data Source code
1 : /* File: shape_int_rectangle.inl; Copyright and License: see below */ 2 : 3 : #include "u8/u8_trace.h" 4 : #include <assert.h> 5 : 6 : #define SHAPE_INT_RECTANGLE_MAX(a,b) ((a) > (b) ? (a) : (b)) 7 : #define SHAPE_INT_RECTANGLE_MIN(a,b) ((a) < (b) ? (a) : (b)) 8 : 9 23 : static inline void shape_int_rectangle_init ( shape_int_rectangle_t *this_, int32_t left, int32_t top, uint32_t width, uint32_t height ) 10 : { 11 23 : (*this_).left = left; 12 23 : (*this_).top = top; 13 23 : (*this_).width = width; 14 23 : (*this_).height = height; 15 23 : } 16 : 17 44 : static inline void shape_int_rectangle_init_empty ( shape_int_rectangle_t *this_ ) 18 : { 19 44 : (*this_).left = 0; 20 44 : (*this_).top = 0; 21 44 : (*this_).width = 0; 22 44 : (*this_).height = 0; 23 44 : } 24 : 25 : static inline void shape_int_rectangle_copy ( shape_int_rectangle_t *this_, const shape_int_rectangle_t *that ) 26 : { 27 : assert( that != NULL ); 28 : *this_ = *that; 29 : } 30 : 31 47 : static inline void shape_int_rectangle_replace ( shape_int_rectangle_t *this_, const shape_int_rectangle_t *that ) 32 : { 33 47 : assert( that != NULL ); 34 47 : *this_ = *that; 35 47 : } 36 : 37 14 : static inline void shape_int_rectangle_reinit ( shape_int_rectangle_t *this_, int32_t left, int32_t top, uint32_t width, uint32_t height ) 38 : { 39 14 : (*this_).left = left; 40 14 : (*this_).top = top; 41 14 : (*this_).width = width; 42 14 : (*this_).height = height; 43 14 : } 44 : 45 0 : static inline void shape_int_rectangle_init_by_bounds ( shape_int_rectangle_t *this_, 46 : const shape_int_rectangle_t *rect_a, 47 : const shape_int_rectangle_t *rect_b ) 48 : { 49 0 : assert( NULL != rect_a ); 50 0 : assert( NULL != rect_b ); 51 : 52 0 : const int32_t rect_a_right = (*rect_a).left + (*rect_a).width; 53 0 : const int32_t rect_a_bottom = (*rect_a).top + (*rect_a).height; 54 0 : const int32_t rect_b_right = (*rect_b).left + (*rect_b).width; 55 0 : const int32_t rect_b_bottom = (*rect_b).top + (*rect_b).height; 56 : 57 0 : (*this_).left = SHAPE_INT_RECTANGLE_MIN( (*rect_a).left, (*rect_b).left ); 58 0 : (*this_).top = SHAPE_INT_RECTANGLE_MIN( (*rect_a).top, (*rect_b).top ); 59 0 : (*this_).width = SHAPE_INT_RECTANGLE_MAX( rect_a_right, rect_b_right ) - (*this_).left; 60 0 : (*this_).height = SHAPE_INT_RECTANGLE_MAX( rect_a_bottom, rect_b_bottom ) - (*this_).top; 61 0 : } 62 : 63 67 : static inline void shape_int_rectangle_destroy ( shape_int_rectangle_t *this_ ) 64 : { 65 67 : } 66 : 67 34 : static inline int32_t shape_int_rectangle_get_left ( const shape_int_rectangle_t *this_ ) 68 : { 69 34 : return (*this_).left; 70 : } 71 : 72 143 : static inline int32_t shape_int_rectangle_get_top ( const shape_int_rectangle_t *this_ ) 73 : { 74 143 : return (*this_).top; 75 : } 76 : 77 15 : static inline int32_t shape_int_rectangle_get_right ( const shape_int_rectangle_t *this_ ) 78 : { 79 15 : return (*this_).left + (*this_).width; 80 : } 81 : 82 150 : static inline int32_t shape_int_rectangle_get_bottom ( const shape_int_rectangle_t *this_ ) 83 : { 84 150 : return (*this_).top + (*this_).height; 85 : } 86 : 87 28 : static inline uint32_t shape_int_rectangle_get_width ( const shape_int_rectangle_t *this_ ) 88 : { 89 28 : return (*this_).width; 90 : } 91 : 92 0 : static inline uint32_t shape_int_rectangle_get_height ( const shape_int_rectangle_t *this_ ) 93 : { 94 0 : return (*this_).height; 95 : } 96 : 97 280 : static inline bool shape_int_rectangle_contains ( const shape_int_rectangle_t *this_, int32_t x, int32_t y ) 98 : { 99 : bool result; 100 280 : const int32_t right = (*this_).left + (*this_).width; 101 280 : const int32_t bottom = (*this_).top + (*this_).height; 102 : /* 103 : result = ( x >= (*this_).left )&&( y >= (*this_).top )&&( x < right )&&( y < bottom ); 104 : causes (depending on compiler, architecture and optimization level): 105 : warning: assuming signed overflow does not occur when assuming that (X + c) >= X is always true [-Wstrict-overflow] 106 : fix: 107 : */ 108 280 : result = ( x-(*this_).left >= 0 )&&( y-(*this_).top >= 0 )&&( x-right < 0 )&&( y-bottom < 0 ); 109 280 : return result; 110 : } 111 : 112 0 : static inline void shape_int_rectangle_shrink_by_border ( shape_int_rectangle_t *this_, int32_t border ) 113 : { 114 : int32_t double_border; 115 0 : double_border = 2 * border; 116 0 : if ( double_border > (*this_).width ) 117 : { 118 0 : (*this_).left += ((*this_).width/2); /* take the h-center of the old rectangle */ 119 0 : (*this_).width = 0; 120 : } 121 : else 122 : { 123 0 : (*this_).left += border; 124 0 : (*this_).width -= double_border; 125 : } 126 0 : if ( double_border > (*this_).height ) 127 : { 128 0 : (*this_).top += ((*this_).height/2); /* take the v-middle of the old rectangle */ 129 0 : (*this_).height = 0; 130 : } 131 : else 132 : { 133 0 : (*this_).top += border; 134 0 : (*this_).height -= double_border; 135 : } 136 0 : } 137 : 138 0 : static inline void shape_int_rectangle_shrink_to_ratio ( shape_int_rectangle_t *this_, 139 : uint32_t ratio_width, 140 : uint32_t ratio_height, 141 : shape_h_align_t h_align, 142 : shape_v_align_t v_align ) 143 : { 144 0 : if ( (*this_).width * ratio_height == (*this_).height * ratio_width ) 145 : { 146 : /* nothing to do - and the case for the div by 0 problem of ratio_width==0 and ratio_height==0 */ 147 : } 148 0 : else if ( (*this_).width * ratio_height > (*this_).height * ratio_width ) 149 : { 150 : /* the rectangle needs to shrink at left and/or right */ 151 : uint32_t new_width; 152 0 : new_width = ( (*this_).height * ratio_width ) / ratio_height; 153 0 : switch ( h_align ) 154 : { 155 0 : case SHAPE_H_ALIGN_LEFT: 156 : { 157 : } 158 0 : break; 159 : 160 0 : case SHAPE_H_ALIGN_RIGHT: 161 : { 162 0 : (*this_).left += ((*this_).width - new_width); 163 : } 164 0 : break; 165 : 166 0 : case SHAPE_H_ALIGN_CENTER: /* and */ 167 : default: 168 : { 169 0 : (*this_).left += ( ((*this_).width - new_width)/2 ); 170 : } 171 : } 172 0 : (*this_).width = new_width; 173 : } 174 : else 175 : { 176 : /* the rectangle needs to shrink at top and/or bottom */ 177 : uint32_t new_height; 178 0 : new_height = ( (*this_).width * ratio_height ) / ratio_width; 179 0 : switch ( v_align ) 180 : { 181 0 : case SHAPE_V_ALIGN_TOP: 182 : { 183 : } 184 0 : break; 185 : 186 0 : case SHAPE_V_ALIGN_BOTTOM: 187 : { 188 0 : (*this_).top += ((*this_).height - new_height); 189 : } 190 0 : break; 191 : 192 0 : case SHAPE_V_ALIGN_CENTER: /* and */ 193 : default: 194 : { 195 0 : (*this_).top += ( ((*this_).height - new_height)/2 ); 196 : } 197 : } 198 0 : (*this_).height = new_height; 199 : } 200 0 : } 201 : 202 0 : static inline void shape_int_rectangle_trace ( const shape_int_rectangle_t *this_ ) 203 : { 204 0 : U8_TRACE_INFO( "shape_int_rectangle_t" ); 205 0 : U8_TRACE_INFO_INT( "- left:", (*this_).left ); 206 0 : U8_TRACE_INFO_INT( "- top:", (*this_).top ); 207 0 : U8_TRACE_INFO_INT( "- width:", (*this_).width ); 208 0 : U8_TRACE_INFO_INT( "- height:", (*this_).height ); 209 0 : } 210 : 211 : 212 : /* 213 : Copyright 2016-2024 Andreas Warnke 214 : 215 : Licensed under the Apache License, Version 2.0 (the "License"); 216 : you may not use this file except in compliance with the License. 217 : You may obtain a copy of the License at 218 : 219 : http://www.apache.org/licenses/LICENSE-2.0 220 : 221 : Unless required by applicable law or agreed to in writing, software 222 : distributed under the License is distributed on an "AS IS" BASIS, 223 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 224 : See the License for the specific language governing permissions and 225 : limitations under the License. 226 : */