1 /* Copyright (C) 2007-2008 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 #include "android/skin/rect.h" 13 #include <limits.h> 14 15 #define SKIN_POS_INITIALIZER { 0, 0 } 16 17 void 18 skin_pos_rotate( SkinPos* dst, SkinPos* src, SkinRotation rotation ) 19 { 20 int x = src->x; 21 int y = src->y; 22 23 switch ( rotation & 3 ) { 24 case SKIN_ROTATION_0: 25 dst->x = x; 26 dst->y = y; 27 break; 28 29 case SKIN_ROTATION_90: 30 dst->x = -y; 31 dst->y = x; 32 break; 33 34 case SKIN_ROTATION_180: 35 dst->x = -x; 36 dst->y = -y; 37 break; 38 39 default: 40 dst->x = y; 41 dst->y = -x; 42 } 43 } 44 45 46 #define SKIN_SIZE_INITIALIZER { 0, 0 } 47 48 int 49 skin_size_contains( SkinSize* size, int x, int y ) 50 { 51 return ( (unsigned) x < (unsigned) size->w && 52 (unsigned) y < (unsigned) size->h ); 53 } 54 55 void 56 skin_size_rotate( SkinSize* dst, SkinSize* src, SkinRotation rot ) 57 { 58 int w = src->w; 59 int h = src->h; 60 61 if ((rot & 1) != 0) { 62 dst->w = h; 63 dst->h = w; 64 } else { 65 dst->w = w; 66 dst->h = h; 67 } 68 } 69 70 /** SKIN RECTANGLES 71 **/ 72 #define SKIN_RECT_INITIALIZER { SKIN_POS_INITIALIZER, SKIN_SIZE_INITIALIZER } 73 74 void 75 skin_rect_init( SkinRect* r, int x, int y, int w, int h ) 76 { 77 if (w < 0 || h < 0) 78 x = y = w = h = 0; 79 80 r->pos.x = x; 81 r->pos.y = y; 82 r->size.w = w; 83 r->size.h = h; 84 } 85 86 87 void 88 skin_rect_translate( SkinRect* r, int dx, int dy ) 89 { 90 r->pos.x += dx; 91 r->pos.y += dy; 92 } 93 94 95 void 96 skin_rect_rotate( SkinRect* dst, SkinRect* src, SkinRotation rot ) 97 { 98 int x, y, w, h; 99 100 switch (rot & 3) { 101 case SKIN_ROTATION_90: 102 x = src->pos.x; 103 y = src->pos.y; 104 w = src->size.w; 105 h = src->size.h; 106 dst->pos.x = -(y + h); 107 dst->pos.y = x; 108 dst->size.w = h; 109 dst->size.h = w; 110 break; 111 112 case SKIN_ROTATION_180: 113 dst->pos.x = -(src->pos.x + src->size.w); 114 dst->pos.y = -(src->pos.y + src->size.h); 115 dst->size = src->size; 116 break; 117 118 case SKIN_ROTATION_270: 119 x = src->pos.x; 120 y = src->pos.y; 121 w = src->size.w; 122 h = src->size.h; 123 dst->pos.x = y; 124 dst->pos.y = -(x + w); 125 dst->size.w = h; 126 dst->size.h = w; 127 break; 128 129 default: 130 dst[0] = src[0]; 131 } 132 } 133 134 135 int 136 skin_rect_contains( SkinRect* r, int x, int y ) 137 { 138 return ( (unsigned)(x - r->pos.x) < (unsigned)r->size.w && 139 (unsigned)(y - r->pos.y) < (unsigned)r->size.h ); 140 } 141 142 SkinOverlap 143 skin_rect_contains_rect( SkinRect *r1, SkinRect *r2 ) 144 { 145 SkinBox a, b; 146 147 skin_box_from_rect( &a, r1 ); 148 skin_box_from_rect( &b, r2 ); 149 150 if (a.x2 <= b.x1 || b.x2 <= a.x1 || a.y2 <= b.y1 || b.y2 <= a.y1) { 151 return SKIN_OUTSIDE; 152 } 153 154 if (b.x1 >= a.x1 && b.x2 <= a.x2 && b.y1 >= a.y1 && b.y2 <= a.y2) { 155 return SKIN_INSIDE; 156 } 157 158 return SKIN_OVERLAP; 159 } 160 161 162 int 163 skin_rect_intersect( SkinRect* result, SkinRect* r1, SkinRect* r2 ) 164 { 165 SkinBox a, b, r; 166 167 skin_box_from_rect( &a, r1 ); 168 skin_box_from_rect( &b, r2 ); 169 170 if (a.x2 <= b.x1 || b.x2 <= a.x1 || a.y2 <= b.y1 || b.y2 <= a.y1) { 171 result->pos.x = result->pos.y = result->size.w = result->size.h = 0; 172 return 0; 173 } 174 175 r.x1 = (a.x1 > b.x1) ? a.x1 : b.x1; 176 r.x2 = (a.x2 < b.x2) ? a.x2 : b.x2; 177 r.y1 = (a.y1 > b.y1) ? a.y1 : b.y1; 178 r.y2 = (a.y2 < b.y2) ? a.y2 : b.y2; 179 180 skin_box_to_rect( &r, result ); 181 return 1; 182 } 183 184 int 185 skin_rect_equals( SkinRect* r1, SkinRect* r2 ) 186 { 187 return (r1->pos.x == r2->pos.x && r1->pos.y == r2->pos.y && 188 r1->size.w == r2->size.w && r2->size.h == r2->size.h); 189 } 190 191 /** SKIN BOXES 192 **/ 193 void 194 skin_box_minmax_init( SkinBox* box ) 195 { 196 box->x1 = box->y1 = INT_MAX; 197 box->x2 = box->y2 = INT_MIN; 198 } 199 200 void 201 skin_box_minmax_update( SkinBox* a, SkinRect* r ) 202 { 203 SkinBox b[1]; 204 205 skin_box_from_rect(b, r); 206 207 if (b->x1 < a->x1) a->x1 = b->x1; 208 if (b->y1 < a->y1) a->y1 = b->y1; 209 if (b->x2 > a->x2) a->x2 = b->x2; 210 if (b->y2 > a->y2) a->y2 = b->y2; 211 } 212 213 int 214 skin_box_minmax_to_rect( SkinBox* box, SkinRect* r ) 215 { 216 if (box->x1 > box->x2) { 217 r->pos.x = r->pos.y = r->size.w = r->size.h = 0; 218 return 0; 219 } 220 skin_box_to_rect( box, r ); 221 return 1; 222 } 223 224 void 225 skin_box_from_rect( SkinBox* box, SkinRect* r ) 226 { 227 box->x1 = r->pos.x; 228 box->y1 = r->pos.y; 229 box->x2 = r->size.w + box->x1; 230 box->y2 = r->size.h + box->y1; 231 } 232 233 void 234 skin_box_to_rect( SkinBox* box, SkinRect* r ) 235 { 236 r->pos.x = box->x1; 237 r->pos.y = box->y1; 238 r->size.w = box->x2 - box->x1; 239 r->size.h = box->y2 - box->y1; 240 } 241 242