Home | History | Annotate | Download | only in skin
      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