Branch data Line data Source code
1 : : /*
2 : : * This file is part of libplacebo.
3 : : *
4 : : * libplacebo is free software; you can redistribute it and/or
5 : : * modify it under the terms of the GNU Lesser General Public
6 : : * License as published by the Free Software Foundation; either
7 : : * version 2.1 of the License, or (at your option) any later version.
8 : : *
9 : : * libplacebo is distributed in the hope that it will be useful,
10 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : : * GNU Lesser General Public License for more details.
13 : : *
14 : : * You should have received a copy of the GNU Lesser General Public
15 : : * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
16 : : */
17 : :
18 : : #include <math.h>
19 : :
20 : : #include "common.h"
21 : : #include "version.h"
22 : :
23 : : #include <libplacebo/common.h>
24 : :
25 : 0 : int pl_fix_ver(void)
26 : : {
27 : 0 : return BUILD_FIX_VER;
28 : : }
29 : :
30 : 11 : const char *pl_version(void)
31 : : {
32 : 11 : return BUILD_VERSION;
33 : : }
34 : :
35 : 1898 : void pl_rect2d_normalize(pl_rect2d *rc)
36 : : {
37 : 1898 : *rc = (pl_rect2d) {
38 : 1898 : .x0 = PL_MIN(rc->x0, rc->x1),
39 : 1898 : .x1 = PL_MAX(rc->x0, rc->x1),
40 : 1898 : .y0 = PL_MIN(rc->y0, rc->y1),
41 : 1898 : .y1 = PL_MAX(rc->y0, rc->y1),
42 : : };
43 : 1898 : }
44 : :
45 : 409 : void pl_rect3d_normalize(pl_rect3d *rc)
46 : : {
47 : 409 : *rc = (pl_rect3d) {
48 : 409 : .x0 = PL_MIN(rc->x0, rc->x1),
49 : 409 : .x1 = PL_MAX(rc->x0, rc->x1),
50 : 409 : .y0 = PL_MIN(rc->y0, rc->y1),
51 : 409 : .y1 = PL_MAX(rc->y0, rc->y1),
52 : 409 : .z0 = PL_MIN(rc->z0, rc->z1),
53 : 409 : .z1 = PL_MAX(rc->z0, rc->z1),
54 : : };
55 : 409 : }
56 : :
57 : 3930 : void pl_rect2df_normalize(pl_rect2df *rc)
58 : : {
59 : 3930 : *rc = (pl_rect2df) {
60 [ + + ]: 3930 : .x0 = PL_MIN(rc->x0, rc->x1),
61 [ + + ]: 3930 : .x1 = PL_MAX(rc->x0, rc->x1),
62 [ + + ]: 3930 : .y0 = PL_MIN(rc->y0, rc->y1),
63 [ + + ]: 3930 : .y1 = PL_MAX(rc->y0, rc->y1),
64 : : };
65 : 3930 : }
66 : :
67 : 1 : void pl_rect3df_normalize(pl_rect3df *rc)
68 : : {
69 : 1 : *rc = (pl_rect3df) {
70 [ + - ]: 1 : .x0 = PL_MIN(rc->x0, rc->x1),
71 [ - + ]: 1 : .x1 = PL_MAX(rc->x0, rc->x1),
72 [ + - ]: 1 : .y0 = PL_MIN(rc->y0, rc->y1),
73 [ - + ]: 1 : .y1 = PL_MAX(rc->y0, rc->y1),
74 [ + - ]: 1 : .z0 = PL_MIN(rc->z0, rc->z1),
75 [ - + ]: 1 : .z1 = PL_MAX(rc->z0, rc->z1),
76 : : };
77 : 1 : }
78 : :
79 : 1 : pl_rect2d pl_rect2df_round(const pl_rect2df *rc)
80 : : {
81 : 1 : return (pl_rect2d) {
82 : 1 : .x0 = roundf(rc->x0),
83 : 1 : .x1 = roundf(rc->x1),
84 : 1 : .y0 = roundf(rc->y0),
85 : 1 : .y1 = roundf(rc->y1),
86 : : };
87 : : }
88 : :
89 : 1 : pl_rect3d pl_rect3df_round(const pl_rect3df *rc)
90 : : {
91 : 1 : return (pl_rect3d) {
92 : 1 : .x0 = roundf(rc->x0),
93 : 1 : .x1 = roundf(rc->x1),
94 : 1 : .y0 = roundf(rc->y0),
95 : 1 : .y1 = roundf(rc->y1),
96 : 1 : .z0 = roundf(rc->z0),
97 : 1 : .z1 = roundf(rc->z1),
98 : : };
99 : : }
100 : :
101 : : const pl_matrix3x3 pl_matrix3x3_identity = {{
102 : : { 1, 0, 0 },
103 : : { 0, 1, 0 },
104 : : { 0, 0, 1 },
105 : : }};
106 : :
107 : 271 : void pl_matrix3x3_apply(const pl_matrix3x3 *mat, float vec[3])
108 : : {
109 : 271 : float x = vec[0], y = vec[1], z = vec[2];
110 : :
111 [ + + ]: 1084 : for (int i = 0; i < 3; i++)
112 : 813 : vec[i] = mat->m[i][0] * x + mat->m[i][1] * y + mat->m[i][2] * z;
113 : 271 : }
114 : :
115 : 0 : void pl_matrix3x3_apply_rc(const pl_matrix3x3 *mat, pl_rect3df *rc)
116 : : {
117 : 0 : float x0 = rc->x0, x1 = rc->x1,
118 : 0 : y0 = rc->y0, y1 = rc->y1,
119 : 0 : z0 = rc->z0, z1 = rc->z1;
120 : :
121 : 0 : rc->x0 = mat->m[0][0] * x0 + mat->m[0][1] * y0 + mat->m[0][2] * z0;
122 : 0 : rc->y0 = mat->m[1][0] * x0 + mat->m[1][1] * y0 + mat->m[1][2] * z0;
123 : 0 : rc->z0 = mat->m[2][0] * x0 + mat->m[2][1] * y0 + mat->m[2][2] * z0;
124 : :
125 : 0 : rc->x1 = mat->m[0][0] * x1 + mat->m[0][1] * y1 + mat->m[0][2] * z1;
126 : 0 : rc->y1 = mat->m[1][0] * x1 + mat->m[1][1] * y1 + mat->m[1][2] * z1;
127 : 0 : rc->z1 = mat->m[2][0] * x1 + mat->m[2][1] * y1 + mat->m[2][2] * z1;
128 : 0 : }
129 : :
130 : 989 : void pl_matrix3x3_scale(pl_matrix3x3 *mat, float scale)
131 : : {
132 [ + + ]: 3956 : for (int i = 0; i < 3; i++) {
133 [ + + ]: 11868 : for (int j = 0; j < 3; j++)
134 : 8901 : mat->m[i][j] *= scale;
135 : : }
136 : 989 : }
137 : :
138 : 5908 : void pl_matrix3x3_invert(pl_matrix3x3 *mat)
139 : : {
140 : 5908 : double m00 = mat->m[0][0], m01 = mat->m[0][1], m02 = mat->m[0][2],
141 : 5908 : m10 = mat->m[1][0], m11 = mat->m[1][1], m12 = mat->m[1][2],
142 : 5908 : m20 = mat->m[2][0], m21 = mat->m[2][1], m22 = mat->m[2][2];
143 : :
144 : : // calculate the adjoint
145 : 5908 : double a00 = (m11 * m22 - m21 * m12);
146 : 5908 : double a01 = -(m01 * m22 - m21 * m02);
147 : 5908 : double a02 = (m01 * m12 - m11 * m02);
148 : 5908 : double a10 = -(m10 * m22 - m20 * m12);
149 : 5908 : double a11 = (m00 * m22 - m20 * m02);
150 : 5908 : double a12 = -(m00 * m12 - m10 * m02);
151 : 5908 : double a20 = (m10 * m21 - m20 * m11);
152 : 5908 : double a21 = -(m00 * m21 - m20 * m01);
153 : 5908 : double a22 = (m00 * m11 - m10 * m01);
154 : :
155 : : // calculate the determinant (as inverse == 1/det * adjoint,
156 : : // adjoint * m == identity * det, so this calculates the det)
157 : 5908 : double det = m00 * a00 + m10 * a01 + m20 * a02;
158 : 5908 : det = 1.0 / det;
159 : :
160 : 5908 : mat->m[0][0] = det * a00;
161 : 5908 : mat->m[0][1] = det * a01;
162 : 5908 : mat->m[0][2] = det * a02;
163 : 5908 : mat->m[1][0] = det * a10;
164 : 5908 : mat->m[1][1] = det * a11;
165 : 5908 : mat->m[1][2] = det * a12;
166 : 5908 : mat->m[2][0] = det * a20;
167 : 5908 : mat->m[2][1] = det * a21;
168 : 5908 : mat->m[2][2] = det * a22;
169 : 5908 : }
170 : :
171 : 3328 : void pl_matrix3x3_mul(pl_matrix3x3 *a, const pl_matrix3x3 *b)
172 : : {
173 : 3328 : float a00 = a->m[0][0], a01 = a->m[0][1], a02 = a->m[0][2],
174 : 3328 : a10 = a->m[1][0], a11 = a->m[1][1], a12 = a->m[1][2],
175 : 3328 : a20 = a->m[2][0], a21 = a->m[2][1], a22 = a->m[2][2];
176 : :
177 [ + + ]: 13312 : for (int i = 0; i < 3; i++) {
178 : 9984 : a->m[0][i] = a00 * b->m[0][i] + a01 * b->m[1][i] + a02 * b->m[2][i];
179 : 9984 : a->m[1][i] = a10 * b->m[0][i] + a11 * b->m[1][i] + a12 * b->m[2][i];
180 : 9984 : a->m[2][i] = a20 * b->m[0][i] + a21 * b->m[1][i] + a22 * b->m[2][i];
181 : : }
182 : 3328 : }
183 : :
184 : 4 : void pl_matrix3x3_rmul(const pl_matrix3x3 *a, pl_matrix3x3 *b)
185 : : {
186 : 4 : pl_matrix3x3 m = *a;
187 : 4 : pl_matrix3x3_mul(&m, b);
188 : 4 : *b = m;
189 : 4 : }
190 : :
191 : : const pl_transform3x3 pl_transform3x3_identity = {
192 : : .mat = {{
193 : : { 1, 0, 0 },
194 : : { 0, 1, 0 },
195 : : { 0, 0, 1 },
196 : : }},
197 : : };
198 : :
199 : 135 : void pl_transform3x3_apply(const pl_transform3x3 *t, float vec[3])
200 : : {
201 : 135 : pl_matrix3x3_apply(&t->mat, vec);
202 : :
203 [ + + ]: 540 : for (int i = 0; i < 3; i++)
204 : 405 : vec[i] += t->c[i];
205 : 135 : }
206 : :
207 : 0 : void pl_transform3x3_apply_rc(const pl_transform3x3 *t, pl_rect3df *rc)
208 : : {
209 : 0 : pl_matrix3x3_apply_rc(&t->mat, rc);
210 : :
211 : 0 : rc->x0 += t->c[0];
212 : 0 : rc->x1 += t->c[0];
213 : 0 : rc->y0 += t->c[1];
214 : 0 : rc->y1 += t->c[1];
215 : 0 : rc->z0 += t->c[2];
216 : 0 : rc->z1 += t->c[2];
217 : 0 : }
218 : :
219 : 2 : void pl_transform3x3_scale(pl_transform3x3 *t, float scale)
220 : : {
221 : 2 : pl_matrix3x3_scale(&t->mat, scale);
222 : :
223 [ + + ]: 8 : for (int i = 0; i < 3; i++)
224 : 6 : t->c[i] *= scale;
225 : 2 : }
226 : :
227 : : // based on DarkPlaces engine (relicensed from GPL to LGPL)
228 : 145 : void pl_transform3x3_invert(pl_transform3x3 *t)
229 : : {
230 : 145 : pl_matrix3x3_invert(&t->mat);
231 : :
232 : 145 : float m00 = t->mat.m[0][0], m01 = t->mat.m[0][1], m02 = t->mat.m[0][2],
233 : 145 : m10 = t->mat.m[1][0], m11 = t->mat.m[1][1], m12 = t->mat.m[1][2],
234 : 145 : m20 = t->mat.m[2][0], m21 = t->mat.m[2][1], m22 = t->mat.m[2][2];
235 : :
236 : : // fix the constant coefficient
237 : : // rgb = M * yuv + C
238 : : // M^-1 * rgb = yuv + M^-1 * C
239 : : // yuv = M^-1 * rgb - M^-1 * C
240 : : // ^^^^^^^^^^
241 : 145 : float c0 = t->c[0], c1 = t->c[1], c2 = t->c[2];
242 : 145 : t->c[0] = -(m00 * c0 + m01 * c1 + m02 * c2);
243 : 145 : t->c[1] = -(m10 * c0 + m11 * c1 + m12 * c2);
244 : 145 : t->c[2] = -(m20 * c0 + m21 * c1 + m22 * c2);
245 : 145 : }
246 : :
247 : : const pl_matrix2x2 pl_matrix2x2_identity = {{
248 : : { 1, 0 },
249 : : { 0, 1 },
250 : : }};
251 : :
252 : 0 : pl_matrix2x2 pl_matrix2x2_rotation(float a)
253 : : {
254 : 0 : return (pl_matrix2x2) {{
255 : 0 : { cosf(a), -sinf(a) },
256 : : { sinf(a), cosf(a) },
257 : : }};
258 : : }
259 : :
260 : 280 : void pl_matrix2x2_apply(const pl_matrix2x2 *mat, float vec[2])
261 : : {
262 : 280 : float x = vec[0], y = vec[1];
263 : :
264 [ + + ]: 840 : for (int i = 0; i < 2; i++)
265 : 560 : vec[i] = mat->m[i][0] * x + mat->m[i][1] * y;
266 : 280 : }
267 : :
268 : 0 : void pl_matrix2x2_apply_rc(const pl_matrix2x2 *mat, pl_rect2df *rc)
269 : : {
270 : 0 : float x0 = rc->x0, x1 = rc->x1,
271 : 0 : y0 = rc->y0, y1 = rc->y1;
272 : :
273 : 0 : rc->x0 = mat->m[0][0] * x0 + mat->m[0][1] * y0;
274 : 0 : rc->y0 = mat->m[1][0] * x0 + mat->m[1][1] * y0;
275 : :
276 : 0 : rc->x1 = mat->m[0][0] * x1 + mat->m[0][1] * y1;
277 : 0 : rc->y1 = mat->m[1][0] * x1 + mat->m[1][1] * y1;
278 : 0 : }
279 : :
280 : 72 : void pl_matrix2x2_mul(pl_matrix2x2 *a, const pl_matrix2x2 *b)
281 : : {
282 : 72 : float a00 = a->m[0][0], a01 = a->m[0][1],
283 : 72 : a10 = a->m[1][0], a11 = a->m[1][1];
284 : :
285 [ + + ]: 216 : for (int i = 0; i < 2; i++) {
286 : 144 : a->m[0][i] = a00 * b->m[0][i] + a01 * b->m[1][i];
287 : 144 : a->m[1][i] = a10 * b->m[0][i] + a11 * b->m[1][i];
288 : : }
289 : 72 : }
290 : :
291 : 48 : void pl_matrix2x2_rmul(const pl_matrix2x2 *a, pl_matrix2x2 *b)
292 : : {
293 : 48 : pl_matrix2x2 m = *a;
294 : 48 : pl_matrix2x2_mul(&m, b);
295 : 48 : *b = m;
296 : 48 : }
297 : :
298 : 4 : void pl_matrix2x2_scale(pl_matrix2x2 *mat, float scale)
299 : : {
300 [ + + ]: 12 : for (int i = 0; i < 2; i++) {
301 [ + + ]: 24 : for (int j = 0; j < 2; j++)
302 : 16 : mat->m[i][j] *= scale;
303 : : }
304 : 4 : }
305 : :
306 : 24 : void pl_matrix2x2_invert(pl_matrix2x2 *mat)
307 : : {
308 : 24 : float m00 = mat->m[0][0], m01 = mat->m[0][1],
309 : 24 : m10 = mat->m[1][0], m11 = mat->m[1][1];
310 : 24 : float invdet = 1.0f / (m11 * m00 - m10 * m01);
311 : :
312 : 24 : mat->m[0][0] = m11 * invdet;
313 : 24 : mat->m[0][1] = -m01 * invdet;
314 : 24 : mat->m[1][0] = -m10 * invdet;
315 : 24 : mat->m[1][1] = m00 * invdet;
316 : 24 : }
317 : :
318 : : const pl_transform2x2 pl_transform2x2_identity = {
319 : : .mat = {{
320 : : { 1, 0 },
321 : : { 0, 1 },
322 : : }},
323 : : };
324 : :
325 : 280 : void pl_transform2x2_apply(const pl_transform2x2 *t, float vec[2])
326 : : {
327 : 280 : pl_matrix2x2_apply(&t->mat, vec);
328 : :
329 [ + + ]: 840 : for (int i = 0; i < 2; i++)
330 : 560 : vec[i] += t->c[i];
331 : 280 : }
332 : :
333 : 0 : void pl_transform2x2_apply_rc(const pl_transform2x2 *t, pl_rect2df *rc)
334 : : {
335 : 0 : pl_matrix2x2_apply_rc(&t->mat, rc);
336 : :
337 : 0 : rc->x0 += t->c[0];
338 : 0 : rc->x1 += t->c[0];
339 : 0 : rc->y0 += t->c[1];
340 : 0 : rc->y1 += t->c[1];
341 : 0 : }
342 : :
343 : 24 : void pl_transform2x2_mul(pl_transform2x2 *a, const pl_transform2x2 *b)
344 : : {
345 : 24 : float c[2] = { b->c[0], b->c[1] };
346 : 24 : pl_transform2x2_apply(a, c);
347 : 24 : memcpy(a->c, c, sizeof(c));
348 : 24 : pl_matrix2x2_mul(&a->mat, &b->mat);
349 : 24 : }
350 : :
351 : 48 : void pl_transform2x2_rmul(const pl_transform2x2 *a, pl_transform2x2 *b)
352 : : {
353 : 48 : pl_transform2x2_apply(a, b->c);
354 : 48 : pl_matrix2x2_rmul(&a->mat, &b->mat);
355 : 48 : }
356 : :
357 : 4 : void pl_transform2x2_scale(pl_transform2x2 *t, float scale)
358 : : {
359 : 4 : pl_matrix2x2_scale(&t->mat, scale);
360 : :
361 [ + + ]: 12 : for (int i = 0; i < 2; i++)
362 : 8 : t->c[i] *= scale;
363 : 4 : }
364 : :
365 : 24 : void pl_transform2x2_invert(pl_transform2x2 *t)
366 : : {
367 : 24 : pl_matrix2x2_invert(&t->mat);
368 : :
369 : 24 : float m00 = t->mat.m[0][0], m01 = t->mat.m[0][1],
370 : 24 : m10 = t->mat.m[1][0], m11 = t->mat.m[1][1];
371 : 24 : float c0 = t->c[0], c1 = t->c[1];
372 : 24 : t->c[0] = -(m00 * c0 + m01 * c1);
373 : 24 : t->c[1] = -(m10 * c0 + m11 * c1);
374 : 24 : }
375 : :
376 : 28 : pl_rect2df pl_transform2x2_bounds(const pl_transform2x2 *t, const pl_rect2df *rc)
377 : : {
378 : 28 : float p[4][2] = {
379 : 28 : { rc->x0, rc->y0 },
380 : 28 : { rc->x0, rc->y1 },
381 : 28 : { rc->x1, rc->y0 },
382 : : { rc->x1, rc->y1 },
383 : : };
384 [ + + ]: 140 : for (int i = 0; i < PL_ARRAY_SIZE(p); i++)
385 : 112 : pl_transform2x2_apply(t, p[i]);
386 : :
387 : 28 : return (pl_rect2df) {
388 : 28 : .x0 = fminf(fminf(p[0][0], p[1][0]), fminf(p[2][0], p[3][0])),
389 : 28 : .x1 = fmaxf(fmaxf(p[0][0], p[1][0]), fmaxf(p[2][0], p[3][0])),
390 : 28 : .y0 = fminf(fminf(p[0][1], p[1][1]), fminf(p[2][1], p[3][1])),
391 : 28 : .y1 = fmaxf(fmaxf(p[0][1], p[1][1]), fmaxf(p[2][1], p[3][1])),
392 : : };
393 : : }
394 : :
395 : 74 : float pl_rect2df_aspect(const pl_rect2df *rc)
396 : : {
397 : 74 : float w = fabsf(pl_rect_w(*rc)), h = fabsf(pl_rect_h(*rc));
398 [ + - ]: 74 : return h ? (w / h) : 0.0;
399 : : }
400 : :
401 : 22 : void pl_rect2df_aspect_set(pl_rect2df *rc, float aspect, float panscan)
402 : : {
403 [ - + ]: 22 : pl_assert(aspect >= 0);
404 : 22 : float orig_aspect = pl_rect2df_aspect(rc);
405 [ + - ]: 22 : if (!aspect || !orig_aspect)
406 : : return;
407 : :
408 : : float scale_x, scale_y;
409 [ + + ]: 22 : if (aspect > orig_aspect) {
410 : : // New aspect is wider than the original, so we need to either grow in
411 : : // scale_x (panscan=1) or shrink in scale_y (panscan=0)
412 : 10 : scale_x = powf(aspect / orig_aspect, panscan);
413 : 10 : scale_y = powf(aspect / orig_aspect, panscan - 1.0);
414 [ + - ]: 12 : } else if (aspect < orig_aspect) {
415 : : // New aspect is taller, so either grow in scale_y (panscan=1) or
416 : : // shrink in scale_x (panscan=0)
417 : 12 : scale_x = powf(orig_aspect / aspect, panscan - 1.0);
418 : 12 : scale_y = powf(orig_aspect / aspect, panscan);
419 : : } else {
420 : : return; // No change in aspect
421 : : }
422 : :
423 : 22 : pl_rect2df_stretch(rc, scale_x, scale_y);
424 : : }
425 : :
426 : 2 : void pl_rect2df_aspect_fit(pl_rect2df *rc, const pl_rect2df *src, float panscan)
427 : : {
428 : 2 : float orig_w = fabs(pl_rect_w(*rc)),
429 : 2 : orig_h = fabs(pl_rect_h(*rc));
430 [ + - ]: 2 : if (!orig_w || !orig_h)
431 : : return;
432 : :
433 : : // If either one of these is larger than 1, then we need to shrink to fit,
434 : : // otherwise we can just directly stretch the rect.
435 : 2 : float scale_x = fabs(pl_rect_w(*src)) / orig_w,
436 : 2 : scale_y = fabs(pl_rect_h(*src)) / orig_h;
437 : :
438 [ + + - + ]: 2 : if (scale_x > 1.0 || scale_y > 1.0) {
439 : 1 : pl_rect2df_aspect_copy(rc, src, panscan);
440 : : } else {
441 : 1 : pl_rect2df_stretch(rc, scale_x, scale_y);
442 : : }
443 : : }
444 : :
445 : 51 : void pl_rect2df_stretch(pl_rect2df *rc, float stretch_x, float stretch_y)
446 : : {
447 : 51 : float midx = (rc->x0 + rc->x1) / 2.0,
448 : 51 : midy = (rc->y0 + rc->y1) / 2.0;
449 : :
450 : 51 : rc->x0 = rc->x0 * stretch_x + midx * (1.0 - stretch_x);
451 : 51 : rc->x1 = rc->x1 * stretch_x + midx * (1.0 - stretch_x);
452 : 51 : rc->y0 = rc->y0 * stretch_y + midy * (1.0 - stretch_y);
453 : 51 : rc->y1 = rc->y1 * stretch_y + midy * (1.0 - stretch_y);
454 : 51 : }
455 : :
456 : 1 : void pl_rect2df_offset(pl_rect2df *rc, float offset_x, float offset_y)
457 : : {
458 [ + - ]: 1 : if (rc->x1 < rc->x0)
459 : 1 : offset_x = -offset_x;
460 [ + - ]: 1 : if (rc->y1 < rc->y0)
461 : 1 : offset_y = -offset_y;
462 : :
463 : 1 : rc->x0 += offset_x;
464 : 1 : rc->x1 += offset_x;
465 : 1 : rc->y0 += offset_y;
466 : 1 : rc->y1 += offset_y;
467 : 1 : }
468 : :
469 [ + + ]: 1437 : void pl_rect2df_rotate(pl_rect2df *rc, pl_rotation rot)
470 : : {
471 [ + + ]: 1437 : if (!(rot = pl_rotation_normalize(rot)))
472 : : return;
473 : :
474 : 952 : float x0 = rc->x0, y0 = rc->y0, x1 = rc->x1, y1 = rc->y1;
475 [ + + ]: 952 : if (rot >= PL_ROTATION_180) {
476 : 8 : rot -= PL_ROTATION_180;
477 : : PL_SWAP(x0, x1);
478 : : PL_SWAP(y0, y1);
479 : : }
480 : :
481 [ + + - ]: 952 : switch (rot) {
482 : 4 : case PL_ROTATION_0:
483 : 4 : *rc = (pl_rect2df) {
484 : : .x0 = x0,
485 : : .y0 = y0,
486 : : .x1 = x1,
487 : : .y1 = y1,
488 : : };
489 : 4 : return;
490 : 948 : case PL_ROTATION_90:
491 : 948 : *rc = (pl_rect2df) {
492 : : .x0 = y1,
493 : : .y0 = x0,
494 : : .x1 = y0,
495 : : .y1 = x1,
496 : : };
497 : 948 : return;
498 : 0 : default: pl_unreachable();
499 : : }
500 : : }
|