• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
skin_pos_rotate(SkinPos * dst,SkinPos * src,SkinRotation rotation)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
skin_size_contains(SkinSize * size,int x,int y)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
skin_size_rotate(SkinSize * dst,SkinSize * src,SkinRotation rot)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
skin_rect_init(SkinRect * r,int x,int y,int w,int h)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
skin_rect_translate(SkinRect * r,int dx,int dy)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
skin_rect_rotate(SkinRect * dst,SkinRect * src,SkinRotation rot)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
skin_rect_contains(SkinRect * r,int x,int y)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
skin_rect_contains_rect(SkinRect * r1,SkinRect * r2)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
skin_rect_intersect(SkinRect * result,SkinRect * r1,SkinRect * r2)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
skin_rect_equals(SkinRect * r1,SkinRect * r2)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
skin_box_minmax_init(SkinBox * box)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
skin_box_minmax_update(SkinBox * a,SkinRect * r)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
skin_box_minmax_to_rect(SkinBox * box,SkinRect * r)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
skin_box_from_rect(SkinBox * box,SkinRect * r)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
skin_box_to_rect(SkinBox * box,SkinRect * r)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