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-2025 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 : */
|