microui  4.0.1
microui
ui_rect_util.c
1 /*
2  * C
3  *
4  * Copyright 2024 MicroEJ Corp. All rights reserved.
5  * Use of this source code is governed by a BSD-style license that can be found with this software.
6  */
7 
8 // --------------------------------------------------------------------------------
9 // Includes
10 // --------------------------------------------------------------------------------
11 
12 #include <assert.h>
13 
14 #include "ui_util.h"
15 #include "ui_rect_util.h"
16 
17 // --------------------------------------------------------------------------------
18 // Functions
19 // --------------------------------------------------------------------------------
20 
21 // See the header file for the function documentation
22 ui_rect_t UI_RECT_get_minimum_bounding_rect(const ui_rect_t rects[], const size_t count) {
23  assert(count > 0u);
24  ui_rect_t result = rects[0];
25  for (size_t i=1; i<count; i++) {
26  result = UI_RECT_get_minimum_bounding_rect_two_rects(&result, &rects[i]);
27  }
28  return result;
29 }
30 
31 // See the header file for the function documentation
32 uint32_t UI_RECT_union(ui_rect_t output[3], const ui_rect_t* first, const ui_rect_t* second) {
33  uint32_t ret;
34  if (UI_RECT_contains_rect(first, second)) {
35  output[0] = *first;
36  UI_RECT_mark_empty(&output[1]);
37  UI_RECT_mark_empty(&output[2]);
38  ret = 1u;
39  } else if (UI_RECT_contains_rect(second, first)) {
40  output[0] = *second;
41  UI_RECT_mark_empty(&output[1]);
42  UI_RECT_mark_empty(&output[2]);
43  ret = 1u;
44  } else if (!UI_RECT_intersects_rect(first, second)) {
45  output[0] = *first;
46  output[1] = *second;
47  UI_RECT_mark_empty(&output[2]);
48  ret = 2u;
49  } else {
50  const ui_rect_t* top_above = (first->y1 < second->y1) ? first : second;
51  const ui_rect_t* top_below = (first->y1 < second->y1) ? second : first;
52  const ui_rect_t* bottom_below = (first->y2 > second->y2) ? first : second;
53  const ui_rect_t* bottom_above = (first->y2 > second->y2) ? second : first;
54 
55  uint32_t count = 0u;
56 
57  output[count] = UI_RECT_new_xyxy(top_above->x1, top_above->y1, top_above->x2, top_below->y1-1);
58  if (!UI_RECT_is_empty(output)) {
59  count++;
60  }
61 
62  output[count] = UI_RECT_new_xyxy(MIN(first->x1, second->x1), top_below->y1, MAX(first->x2, second->x2), bottom_above->y2);
63  if (!UI_RECT_is_empty(output)) {
64  count++;
65  }
66 
67  output[count] = UI_RECT_new_xyxy(bottom_below->x1, bottom_above->y2+1, bottom_below->x2, bottom_below->y2);
68  if (!UI_RECT_is_empty(output)) {
69  count++;
70  }
71 
72  ret = count;
73  }
74  return ret;
75 }
76 
77 // See the header file for the function documentation
78 uint32_t UI_RECT_subtract(ui_rect_t output[4], const ui_rect_t* first, const ui_rect_t* second) {
79  uint32_t ret;
80  if (UI_RECT_contains_rect(first, second)) {
81  output[0] = UI_RECT_new_xyxy(first->x1, first->y1, first->x2, second->y1-1); // Top
82  output[1] = UI_RECT_new_xyxy(first->x1, second->y1, second->x1-1, second->y2); // Left
83  output[2] = UI_RECT_new_xyxy(second->x2+1, second->y1, first->x2, second->y2); // Right
84  output[3] = UI_RECT_new_xyxy(first->x1, second->y2+1, first->x2, first->y2); // Bottom
85  ret = 4u;
86  } else if (UI_RECT_contains_rect(second, first)) {
87  UI_RECT_mark_empty(&output[0]);
88  UI_RECT_mark_empty(&output[1]);
89  UI_RECT_mark_empty(&output[2]);
90  UI_RECT_mark_empty(&output[3]);
91  ret = 0u;
92  } else if (!UI_RECT_intersects_rect(first, second)) {
93  output[0] = *first;
94  UI_RECT_mark_empty(&output[1]);
95  UI_RECT_mark_empty(&output[2]);
96  UI_RECT_mark_empty(&output[3]);
97  ret = 1u;
98  } else {
99  output[0] = UI_RECT_new_xyxy(first->x1, first->y1, first->x2, second->y1-1); // Top
100  output[1] = UI_RECT_new_xyxy(first->x1, MAX(first->y1, second->y1), second->x1-1, MIN(first->y2, second->y2)); // Left
101  output[2] = UI_RECT_new_xyxy(second->x2+1, MAX(first->y1, second->y1), first->x2, MIN(first->y2, second->y2)); // Right
102  output[3] = UI_RECT_new_xyxy(first->x1, second->y2+1, first->x2, first->y2); // Bottom
103  ret = 4u;
104  }
105  return ret;
106 }