18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/skin/region.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <limits.h>
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>  /* malloc/free */
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*************************************************************************
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *************************************************************************
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****  ASSERTION SUPPORT
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****/
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef UNIT_TEST
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_rpanic(void)
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *((char*)(void*)0) = 1;  /* should SEGFAULT */
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* put a breakpoint here */
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    exit(1);
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  RASSERT(cond)   \
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  ({ if (!(cond)) { fprintf(stderr, "%s:%d:%s: assertion failed: %s", \
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      __FILE__, __LINE__,  __FUNCTION__, #cond ); _rpanic(); } })
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  RASSERT(cond)  ((void)0)
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*************************************************************************
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *************************************************************************
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****  IMPLEMENTATION DETAILS
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****/
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this implementation of regions encodes the the region's spans with the
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   following format:
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   region   ::= yband+ YSENTINEL
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   yband    ::= YTOP YBOTTOM scanline
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   scanline ::= span+  XSENTINEL
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   span     ::= XLEFT XRIGHT
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   XSENTINEL ::= 0x7fff
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   YSENTINEL :=  0x7fff
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   all values are sorted in increasing order, which means that:
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    - YTOP1 < YBOTTOM1 <= YTOP2 < YBOTTOM2 <= .... < YSENTINEL
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    - XLEFT1 < XRIGHT1 < XLEFT2 < XRIGHT2 < .... < XSENTINEL
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (in a given scanline)
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* convenience shortbuts */
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef SkinRegionRun   Run;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef SkinRegion      Region;
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  RUNS_RECT_COUNT  6   /* YTOP YBOT XLEFT XRIGHT XSENTINEL YSENTINEL */
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  XSENTINEL  SKIN_REGION_SENTINEL
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  YSENTINEL  SKIN_REGION_SENTINEL
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  RUNS_EMPTY   ((Run*)(void*)(-1))
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  RUNS_RECT    ((Run*)(void*)(0))
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ int
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectregion_isEmpty( Region*  r )
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return r->runs == RUNS_EMPTY;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ int
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectregion_isRect( Region*  r )
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return r->runs == RUNS_RECT;
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ int
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectregion_isComplex( Region*  r )
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return r->runs != RUNS_EMPTY && r->runs != RUNS_RECT;
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/**  RunStore: ref-counted storage for runs
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  refcount;
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  count;
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} RunStore;
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrunstore_free( RunStore*  s )
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    free(s);
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic RunStore*
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrunstore_alloc( int   count )
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore*  s = malloc( sizeof(*s) + sizeof(Run)*count );
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(s != NULL);
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->count    = count;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->refcount = 1;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s;
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic RunStore*
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrunstore_edit( RunStore*  s )
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore*  s2;
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->refcount == 1)
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return s;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s2 = runstore_alloc( s->count );
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s2) {
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy( s2, s, sizeof(*s) + s->count*sizeof(Run) );
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->refcount -= 1;
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s2->refcount = 1;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s2;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrunstore_unrefp( RunStore*  *ps )
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore*  s = *ps;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s != NULL) {
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (s->refcount <= 0)
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runstore_free(s);
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *ps = NULL;
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic RunStore*
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrunstore_ref( RunStore*  s )
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s) s->refcount += 1;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ RunStore*
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrunstore_from_runs( Run*  runs )
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(runs != RUNS_EMPTY);
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(runs != RUNS_RECT);
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (RunStore*)runs - 1;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ Run*
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectrunstore_to_runs( RunStore*  s )
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(s != NULL);
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (Run*)(s + 1);
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic Run*
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectregion_edit( Region*  r )
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore*  s;
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(region_isComplex(r));
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = runstore_from_runs(r->runs);
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = runstore_edit(s);
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->runs = runstore_to_runs(s);
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return r->runs;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** Run parsing
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic Run*
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_next_scanline( Run*  runs )
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(runs[0] != YSENTINEL && runs[1] != YSENTINEL );
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs += 2;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { runs += 1; } while (runs[-1] != XSENTINEL);
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return runs;
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic Run*
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_find_y( Run*  runs, int  y )
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  ybot, ytop = runs[0];
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (y < ytop)
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return NULL;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ybot = runs[1];
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (y < ybot)
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return runs;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs = runs_next_scanline( runs );
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (runs[0] != YSENTINEL);
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return NULL;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_set_rect( Run*  runs, SkinRect*  rect )
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs[0] = rect->pos.y;
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs[1] = rect->pos.y + rect->size.h;
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs[2] = rect->pos.x;
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs[3] = rect->pos.x + rect->size.w;
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs[4] = XSENTINEL;
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs[5] = YSENTINEL;
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic Run*
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_copy_scanline( Run*  dst, Run*  src )
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(src[0] != YSENTINEL);
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(src[1] != YSENTINEL);
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst[0] = src[0];
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst[1] = src[1];
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    src += 2;
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst += 2;
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { *dst++ = *src++; } while (src[-1] != XSENTINEL);
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dst;
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic Run*
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_copy_scanline_adj( Run*  dst, Run*  src, int  ytop, int  ybot )
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  runs2 = runs_copy_scanline( dst, src );
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst[0] = (Run) ytop;
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst[1] = (Run) ybot;
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return runs2;
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ Run*
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_add_span( Run*  dst, int  left, int  right )
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst[0] = (Run) left;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst[1] = (Run) right;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return dst + 2;
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ int
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_get_count( Run*  runs )
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore*  s = runstore_from_runs(runs);
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s->count;
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_coalesce_band( Run*  *psrc_spans, Run*  *pdst_spans, SkinBox*  minmax )
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  sspan  = *psrc_spans;
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  dspan  = *pdst_spans;
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   pleft  = sspan[0];
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   pright = sspan[1];
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   xleft, xright;
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(pleft != XSENTINEL);
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(pright != XSENTINEL);
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT(pleft < pright);
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (pleft < minmax->x1) minmax->x1 = pleft;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sspan += 2;
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    xleft  = sspan[0];
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (xleft != XSENTINEL)
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xright = sspan[1];
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        RASSERT(xright != XSENTINEL);
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        RASSERT(xleft < xright);
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (xleft == pright) {
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pright = xright;
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dspan[0] = (Run) pleft;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dspan[1] = (Run) pright;
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dspan   += 2;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sspan += 2;
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        xleft = sspan[0];
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dspan[0] = (Run) pleft;
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dspan[1] = (Run) pright;
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dspan[2] = XSENTINEL;
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dspan   += 3;
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sspan   += 1;  /* skip XSENTINEL */
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (pright > minmax->x2) minmax->x2 = pright;
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *psrc_spans = sspan;
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pdst_spans = dspan;
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectruns_coalesce( Run*  dst, Run*  src, SkinBox*  minmax )
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  prev = NULL;
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  dst0 = dst;
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ytop = src[0];
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ybot;
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (ytop != YSENTINEL)
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        Run*  sspan = src + 2;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        Run*  dspan = dst + 2;
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ybot = src[1];
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        RASSERT( ytop < ybot );
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        RASSERT( ybot != YSENTINEL );
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        RASSERT( src[2] != XSENTINEL );
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ytop < minmax->y1) minmax->y1 = ytop;
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ybot > minmax->y2) minmax->y2 = ybot;
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dst[0] = (Run) ytop;
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dst[1] = (Run) ybot;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs_coalesce_band( &sspan, &dspan, minmax );
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (prev && prev[1] == dst[0] && (dst-prev) == (dspan-dst) &&
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            !memcmp(prev+2, dst+2, (dspan-dst-2)*sizeof(Run)))
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* coalesce two identical bands */
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev[1] = dst[1];
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            prev = dst;
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst  = dspan;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        src  = sspan;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ytop = src[0];
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dst[0] = YSENTINEL;
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (dst + 1 - dst0);
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*************************************************************************
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *************************************************************************
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****  PUBLIC API
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ****/
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_init_empty( SkinRegion*  r )
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* empty region */
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.pos.x  = r->bounds.pos.y = 0;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.size.w = r->bounds.size.h = 0;
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->runs = RUNS_EMPTY;
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_init( SkinRegion*  r, int  x1, int  y1, int  x2, int  y2 )
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x1 >= x2 || y1 >= y2) {
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.pos.x  = x1;
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.pos.y  = y1;
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.size.w = x2 - x1;
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.size.h = y2 - y1;
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->runs = RUNS_RECT;
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_init_rect( SkinRegion*  r, SkinRect*  rect )
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (rect == NULL || rect->size.w <= 0 || rect->size.h <= 0) {
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds = rect[0];
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->runs   = RUNS_RECT;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_init_box( SkinRegion*  r, SkinBox*  box )
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (box == NULL || box->x1 >= box->x2 || box->y1 >= box->y2) {
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.pos.x  = box->x1;
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.pos.y  = box->y1;
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.size.w = box->x2 - box->x1;
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->bounds.size.h = box->y2 - box->y1;
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r->runs = RUNS_RECT;
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_init_copy( SkinRegion*  r, SkinRegion*  src )
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (src == NULL || region_isEmpty(src))
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        r[0] = src[0];
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (region_isComplex(src)) {
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            RunStore*  s = runstore_from_runs(r->runs);
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runstore_ref(s);
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_reset( SkinRegion*  r )
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (r != NULL) {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (region_isComplex(r)) {
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            RunStore*  s = runstore_from_runs(r->runs);
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runstore_unrefp( &s );
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_copy( SkinRegion*  r, SkinRegion*  src )
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset(r);
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy(r, src);
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_equals( SkinRegion*  r1, SkinRegion*  r2 )
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run       *runs1, *runs2;
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore  *store1, *store2;
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (r1 == r2)
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!skin_rect_equals( &r1->bounds, &r2->bounds ))
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs1 = r1->runs;
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs2 = r2->runs;
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (runs1 == runs2)  /* empties and rects */
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !region_isComplex(r1) || !region_isComplex(r2) )
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    store1 = runstore_from_runs(runs1);
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    store2 = runstore_from_runs(runs2);
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (store1->count == store2->count &&
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        !memcmp( (char*)runs1, (char*)runs2, store1->count*sizeof(Run) ) )
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_translate( SkinRegion*  r, int  dx, int  dy )
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  runs;
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r))
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_rect_translate( &r->bounds, dx, dy );
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isRect(r))
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs = region_edit(r);
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (runs[0] != YSENTINEL) {
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  ytop = runs[0];
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  ybot = runs[1];
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        RASSERT(ybot != YSENTINEL);
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs[0] = (Run)(ytop + dy);
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs[1] = (Run)(ybot + dy);
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs += 2;
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (runs[0] != XSENTINEL) {
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  xleft  = runs[0];
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  xright = runs[1];
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            RASSERT(xright != YSENTINEL);
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs[0] = (Run)(xleft + dx);
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs[1] = (Run)(xright + dx);
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs += 2;
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs += 1;
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_get_bounds( SkinRegion*  r, SkinRect*  bounds )
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (r != NULL) {
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bounds[0] = r->bounds;
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bounds->pos.x  = bounds->pos.y  = 0;
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bounds->size.w = bounds->size.h = 0;
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_is_empty( SkinRegion*  r )
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return region_isEmpty(r);
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_is_rect( SkinRegion*  r )
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return region_isRect(r);
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_is_complex( SkinRegion*  r )
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return region_isComplex(r);
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_swap( SkinRegion*  r, SkinRegion*  r2 )
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  tmp;
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tmp   = r[0];
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r[0]   = r2[0];
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    r2[0]  = tmp;
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinOverlap
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_contains( SkinRegion*  r, int  x, int  y )
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r))
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_OUTSIDE;
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isRect(r)) {
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return skin_rect_contains(&r->bounds,x,y);
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        Run*  runs = runs_find_y( r->runs, y );
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (runs != NULL) {
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs += 2;
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            do {
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int  xright, xleft = runs[0];
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (x < xleft)  // also x < xleft == XSENTINEL
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                xright = runs[1];
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (xright == XSENTINEL)
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (x < xright)
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return SKIN_INSIDE;
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                runs += 2;
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } while (runs[0] != XSENTINEL);
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_OUTSIDE;
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinOverlap
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_contains_rect( SkinRegion*  r, SkinRect*  rect )
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r2[1];
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_rect( r2, rect );
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return skin_region_test_intersect( r, r2 );
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinOverlap
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_contains_box( SkinRegion*  r, SkinBox*  b )
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r2[1];
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_box( r2, b );
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return skin_region_test_intersect( r, r2 );
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FLAG_REGION_1     (1 << 0)
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FLAG_REGION_2     (1 << 1)
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FLAG_REGION_BOTH  (1 << 2)
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinOverlap
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_test_intersect( SkinRegion*  r1,
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            SkinRegion*  r2 )
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run  *runs1, *runs2;
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run   run2_tmp[ RUNS_RECT_COUNT ];
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRect  r;
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r1) || region_isEmpty(r2))
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_OUTSIDE;
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !skin_rect_intersect( &r, &r1->bounds, &r2->bounds) )
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_OUTSIDE;
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isRect(r1)) {
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (region_isRect(r2)) {
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return skin_rect_contains_rect(&r1->bounds, &r2->bounds);
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            SkinRegion*  tmp = r1;
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            r1 = r2;
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            r2 = tmp;
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* here r1 is guaranteed to be complex, r2 is either rect of complex */
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs1 = r1->runs;
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isRect(r2)) {
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs2 = run2_tmp;
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs_set_rect(runs2, &r2->bounds);
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs2 = r2->runs;
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int   flags = 0;
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (runs1[0] != YSENTINEL && runs2[0] != YSENTINEL)
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  ytop1 = runs1[0];
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  ybot1 = runs1[1];
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  ytop2 = runs2[0];
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  ybot2 = runs2[1];
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ybot1 <= ytop2)
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* band1 over band2 */
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                flags |= FLAG_REGION_1;
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                runs1 = runs_next_scanline( runs1 );
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (ybot2 <= ytop1)
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* band2 over band1 */
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                flags |= FLAG_REGION_2;
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                runs2  = runs_next_scanline( runs2 );
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else  /* band1 and band2 overlap */
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Run*  span1;
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Run*  span2;
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int   ybot;
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ytop1 < ytop2) {
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    flags |= FLAG_REGION_1;
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ytop1 = ytop2;
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else if (ytop2 < ytop1) {
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    flags |= FLAG_REGION_2;
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ytop2 = ytop1;
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ybot = (ybot1 < ybot2) ? ybot1 : ybot2;
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                span1 = runs1 + 2;
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                span2 = runs2 + 2;
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                while (span1[0] != XSENTINEL && span2[0] != XSENTINEL)
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  xleft1  = span1[0];
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  xright1 = span1[1];
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  xleft2  = span2[0];
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  xright2 = span2[1];
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    RASSERT(xright1 != XSENTINEL);
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    RASSERT(xright2 != XSENTINEL);
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (xright1 <= xleft2) {
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        flags |= FLAG_REGION_1;
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span1 += 2;
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else if (xright2 <= xleft1) {
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        flags |= FLAG_REGION_2;
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span2 += 2;
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else {
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        int  xright;
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (xleft1 < xleft2) {
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            flags |= FLAG_REGION_1;
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            xleft1 = xleft2;
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        } else if (xleft2 < xleft1) {
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            flags |= FLAG_REGION_2;
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            xleft2 = xleft1;
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xright = (xright1 < xright2) ? xright1 : xright2;
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        flags |= FLAG_REGION_BOTH;
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (xright == xright1)
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            span1 += 2;
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (xright == xright2)
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            span2 += 2;
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (span1[0] != XSENTINEL) {
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    flags |= FLAG_REGION_1;
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (span2[0] != XSENTINEL) {
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    flags |= FLAG_REGION_2;
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ybot == ybot1)
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    runs1 = runs_next_scanline( runs1 );
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ybot == ybot2)
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    runs2 = runs_next_scanline( runs2 );
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (runs1[0] != YSENTINEL) {
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            flags |= FLAG_REGION_1;
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (runs2[0] != YSENTINEL) {
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            flags |= FLAG_REGION_2;
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !(flags & FLAG_REGION_BOTH) ) {
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* no intersection at all */
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return SKIN_OUTSIDE;
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( (flags & FLAG_REGION_2) != 0 ) {
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* intersection + overlap */
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return SKIN_OVERLAP;
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return SKIN_INSIDE;
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*       runs1;
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*       runs2;
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*       runs_base;
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*       runs;
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore*  store;
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Region     result[1];
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run        runs1_rect[ RUNS_RECT_COUNT ];
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run        runs2_rect[ RUNS_RECT_COUNT ];
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} RegionOperator;
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectregion_operator_init( RegionOperator*  o,
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      Region*          r1,
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      Region*          r2 )
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  run1_count, run2_count;
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  maxruns;
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT( !region_isEmpty(r1) );
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RASSERT( !region_isEmpty(r2) );
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isRect(r1)) {
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        run1_count = RUNS_RECT_COUNT;
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        o->runs1   = o->runs1_rect;
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs_set_rect( o->runs1, &r1->bounds );
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        o->runs1   = r1->runs;
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        run1_count = runs_get_count(r1->runs);
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isRect(r2)) {
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        run2_count = RUNS_RECT_COUNT;
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        o->runs2   = o->runs2_rect;
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        runs_set_rect( o->runs2, &r2->bounds );
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        o->runs2   = r2->runs;
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        run2_count = runs_get_count(r2->runs);
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    maxruns  = run1_count < run2_count ? run2_count : run1_count;
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    o->store = runstore_alloc( 3*maxruns );
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    o->runs_base = runstore_to_runs(o->store);
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectregion_operator_do( RegionOperator*  o, int  wanted )
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  runs1 = o->runs1;
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  runs2 = o->runs2;
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  runs  = o->runs_base;
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ytop1 = runs1[0];
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ytop2 = runs2[0];
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ytop1 != YSENTINEL && ytop2 != YSENTINEL)
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  ybot1, ybot2;
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (ytop1 != YSENTINEL && ytop2 != YSENTINEL)
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int  ybot;
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ybot1 = runs1[1];
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ybot2 = runs2[1];
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            RASSERT(ybot1 != YSENTINEL);
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            RASSERT(ybot2 != YSENTINEL);
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ybot1 <= ytop2) {
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (wanted & FLAG_REGION_1)
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    runs = runs_copy_scanline_adj( runs, runs1, ytop1, ybot1 );
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                runs1   = runs_next_scanline( runs1 );
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ytop1   = runs1[0];
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                continue;
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ybot2 <= ytop1) {
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (wanted & FLAG_REGION_2)
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    runs = runs_copy_scanline_adj( runs, runs2, ytop2, ybot2 );
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                runs2 = runs_next_scanline(runs2);
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ytop2 = runs2[0];
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                continue;
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ytop1 < ytop2) {
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (wanted & FLAG_REGION_1)
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    runs = runs_copy_scanline_adj( runs, runs1, ytop1, ytop2 );
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ytop1 = ytop2;
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (ytop2 < ytop1) {
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (wanted & FLAG_REGION_2)
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    runs = runs_copy_scanline_adj( runs, runs2, ytop2, ytop1 );
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ytop2 = ytop1;
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ybot  = (ybot1 <= ybot2) ? ybot1 : ybot2;
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs[0] = (Run) ytop1;
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs[1] = (Run) ybot;
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* do the common band */
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Run*  span1 = runs1 + 2;
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Run*  span2 = runs2 + 2;
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Run*  span  = runs + 2;
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int   xleft1 = span1[0];
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int   xleft2 = span2[0];
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int   xright1, xright2;
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                while (xleft1 != XSENTINEL && xleft2 != XSENTINEL)
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  xright;
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    xright1 = span1[1];
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    xright2 = span2[1];
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    RASSERT(xright1 != XSENTINEL);
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    RASSERT(xright2 != XSENTINEL);
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (xright1 <= xleft2) {
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (wanted & FLAG_REGION_1)
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            span = runs_add_span( span, xleft1, xright1 );
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span1 += 2;
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft1 = span1[0];
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        continue;
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (xright2 <= xleft1) {
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (wanted & FLAG_REGION_2)
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            span = runs_add_span( span, xleft2, xright2 );
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span2 += 2;
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft2 = span2[0];
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        continue;
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (xleft1 < xleft2) {
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (wanted & FLAG_REGION_1)
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            span = runs_add_span( span, xleft1, xleft2 );
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft1 = xleft2;
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else if (xleft2 < xleft1) {
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (wanted & FLAG_REGION_2)
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            span = runs_add_span( span, xleft2, xleft1 );
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft2 = xleft1;
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    xright = (xright1 <= xright2) ? xright1 : xright2;
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (wanted & FLAG_REGION_BOTH)
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span = runs_add_span( span, xleft1, xright );
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    xleft1 = xleft2 = xright;
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (xright == xright1) {
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span1 += 2;
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft1 = span1[0];
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (xright == xright2) {
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span2 += 2;
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft2 = span2[0];
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (wanted & FLAG_REGION_1) {
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    while (xleft1 != XSENTINEL) {
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        RASSERT(span1[1] != XSENTINEL);
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span[0] = (Run) xleft1;
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span[1] = span1[1];
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span   += 2;
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span1  += 2;
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft1  = span1[0];
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (wanted & FLAG_REGION_2) {
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    while (xleft2 != XSENTINEL) {
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        RASSERT(span2[1] != XSENTINEL);
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span[0] = (Run) xleft2;
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span[1] = span2[1];
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span   += 2;
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        span2  += 2;
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        xleft2  = span2[0];
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (span > runs + 2) {
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    span[0] = XSENTINEL;
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    runs    = span + 1;
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ytop1 = ytop2 = ybot;
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ybot == ybot1) {
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                runs1 = runs_next_scanline( runs1 );
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ytop1 = runs1[0];
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ybot == ybot2) {
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                runs2 = runs_next_scanline( runs2 );
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ytop2 = runs2[0];
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((wanted & FLAG_REGION_1) != 0) {
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (ytop1 != YSENTINEL) {
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs = runs_copy_scanline_adj( runs, runs1, ytop1, runs1[1] );
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs1 = runs_next_scanline(runs1);
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ytop1 = runs1[0];
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((wanted & FLAG_REGION_2) != 0) {
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (ytop2 != YSENTINEL) {
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs = runs_copy_scanline_adj( runs, runs2, ytop2, runs2[1] );
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            runs2 = runs_next_scanline(runs2);
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ytop2 = runs2[0];
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runs[0] = YSENTINEL;
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    o->runs = runs + 1;
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* returns 1 if the result is not empty */
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectregion_operator_done( RegionOperator*  o )
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*       src = o->runs;
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int        count;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinBox    minmax;
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RunStore*  store;
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (src <= o->runs_base + 1) {
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* result is empty */
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty( o->result );
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* coalesce the temp runs in-place and compute the corresponding bounds */
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    minmax.x1 = minmax.y1 = INT_MAX;
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    minmax.x2 = minmax.y2 = INT_MIN;
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    count = runs_coalesce( o->runs_base, o->runs_base, &minmax );
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (count == 1) {
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* result is empty */
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty( o->result );
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_box_to_rect( &minmax, &o->result->bounds );
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (count == RUNS_RECT_COUNT) {
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            o->result->runs = RUNS_RECT;
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* result is complex */
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            store = runstore_alloc( count );
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            o->result->runs = runstore_to_runs(store);
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy( o->result->runs, o->runs_base, count*sizeof(Run) );
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* release temporary runstore */
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    runstore_unrefp( &o->store );
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return region_isEmpty(o->result);
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_intersect( SkinRegion*  r, SkinRegion*  r2 )
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RegionOperator  oper[1];
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r))
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r2))
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( skin_rect_contains_rect( &r->bounds, &r2->bounds ) == SKIN_OUTSIDE ) {
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_init( oper, r, r2 );
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_do( oper, FLAG_REGION_BOTH );
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_done( oper );
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_swap( r, oper->result );
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset( oper->result );
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return region_isEmpty( r );
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* performs r = (intersect r (region+_from_rect rect)), returns true iff
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the resulting region is not empty */
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_intersect_rect( SkinRegion*  r, SkinRect*  rect )
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Region  r2[1];
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_rect( r2, rect );
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return skin_region_intersect( r, r2 );
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* performs r = (union r r2) */
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_union( SkinRegion*  r, SkinRegion*  r2 )
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RegionOperator  oper[1];
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r)) {
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_copy(r, r2);
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r2))
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_init( oper, r, r2 );
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_do( oper, FLAG_REGION_1|FLAG_REGION_2|FLAG_REGION_BOTH );
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_done( oper );
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_swap( r, oper->result );
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset( oper->result );
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_union_rect( SkinRegion*  r, SkinRect*  rect )
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Region  r2[1];
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_rect(r2, rect);
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return skin_region_union( r, r2 );
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* performs r = (difference r r2) */
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_substract( SkinRegion*  r, SkinRegion*  r2 )
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RegionOperator  oper[1];
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r) || region_isEmpty(r2))
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( skin_rect_contains_rect( &r->bounds, &r2->bounds ) == SKIN_OUTSIDE ) {
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_init( oper, r, r2 );
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_do( oper, FLAG_REGION_1 );
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_done( oper );
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_swap( r, oper->result );
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset( oper->result );
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_substract_rect( SkinRegion*  r, SkinRect*  rect )
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Region  r2[1];
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_rect(r2, rect);
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return skin_region_substract( r, r2 );
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* performs r = (xor r r2) */
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_xor( SkinRegion*  r, SkinRegion*  r2 )
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RegionOperator  oper[1];
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r)) {
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_copy(r, r2);
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (region_isEmpty(r2))
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( skin_rect_contains_rect( &r->bounds, &r2->bounds ) == SKIN_OUTSIDE ) {
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init_empty(r);
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_init( oper, r, r2 );
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_do( oper, FLAG_REGION_1 );
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    region_operator_done( oper );
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_swap( r, oper->result );
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_reset( oper->result );
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_iterator_init( SkinRegionIterator*  iter,
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           SkinRegion*          region )
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iter->region = region;
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iter->band   = NULL;
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iter->span   = NULL;
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_iterator_next( SkinRegionIterator*  iter, SkinRect  *rect )
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const Run dummy[ 2 ] = { XSENTINEL, YSENTINEL };
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  span = iter->span;
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Run*  band = iter->band;
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (span == NULL) {
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        Region*  r = iter->region;
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (region_isEmpty(r))
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (region_isRect(r)) {
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rect[0] = r->bounds;
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            iter->span = (Run*) dummy;
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 1;
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        iter->band = band = r->runs;
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        iter->span = span = r->runs + 2;
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (band == NULL)
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (span[0] == XSENTINEL) {
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        band = span + 1;
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (band[0] == YSENTINEL || band[1] == YSENTINEL)
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        iter->band = band;
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        iter->span = span = band + 2;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (span[1] == XSENTINEL)
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    rect->pos.y  = band[0];
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    rect->pos.x  = span[0];
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    rect->size.h = band[1] - band[0];
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    rect->size.w = span[1] - span[0];
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iter->span = span + 2;
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_region_iterator_next_box( SkinRegionIterator*  iter, SkinBox  *box )
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRect  rect;
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int       result = skin_region_iterator_next( iter, &rect );
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (result)
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_box_from_rect( box, &rect );
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef UNIT_TEST
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "skin_rect.c"
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpanic(void)
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *((char*)0) = 1;
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    exit(0);
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_expectCompare( Region*  r, const SkinBox*  boxes, int  count )
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (count == 0) {
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !skin_region_is_empty(r) ) {
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf( " result is not empty\n" );
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            panic();
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (count == 1) {
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinRect  rect1, rect2;
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !skin_region_is_rect(r) ) {
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf( " result is not a rectangle\n" );
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            panic();
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_get_bounds( r, &rect1 );
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_box_to_rect( (SkinBox*)boxes, &rect2 );
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !skin_rect_equals( &rect1, &rect2 ) ) {
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf( " result is (%d,%d,%d,%d), expected (%d,%d,%d,%d)\n",
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    rect1.pos.x, rect1.pos.y,
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    rect1.pos.x + rect1.size.w, rect1.pos.y + rect1.size.h,
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    rect2.pos.x, rect2.pos.y,
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    rect2.pos.x + rect2.size.w, rect2.pos.y + rect2.size.h );
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            panic();
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinRegionIterator  iter;
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        SkinBox             b;
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int                 n;
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_iterator_init( &iter, r );
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        n = 0;
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (n < count) {
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( !skin_region_iterator_next_box( &iter, &b ) ) {
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                printf( "missing region box (%d, %d, %d, %d)\n",
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        boxes->x1, boxes->y1, boxes->x2, boxes->y2 );
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                panic();
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (b.x1 != boxes->x1 || b.x2 != boxes->x2||
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                b.y1 != boxes->y1 || b.y2 != boxes->y2)
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                printf( "invalid region box (%d,%d,%d,%d) expecting (%d,%d,%d,%d)\n",
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        b.x1, b.y1, b.x2, b.y2,
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        boxes->x1, boxes->y1, boxes->x2, boxes->y2 );
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                panic();
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            boxes += 1;
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            n += 1;
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( skin_region_iterator_next_box( &iter, &b ) ) {
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf( "excess region box (%d,%d,%d,%d)\n",
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    b.x1, b.y1, b.x2, b.y2 );
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            panic();
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectexpectEmptyRegion( Region*  r )
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "expectEmptyRegion: " );
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!skin_region_is_empty(r)) {
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf( "region not empty !!\n" );
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        panic();
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "ok\n" );
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectexpectTestIntersect( Region*  r1, Region*  r2, SkinOverlap  overlap )
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinOverlap  result;
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "expectTestIntersect(%d): ", overlap );
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    result = skin_region_test_intersect(r1, r2);
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (result != overlap) {
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf( "bad result %d, expected %d\n", result, overlap );
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        panic();
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "ok\n" );
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectexpectRectRegion( Region*  r, int  x1, int  y1, int  x2, int  y2 )
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRect  rect;
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinBox   b;
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "expectRectRegion(%d,%d,%d,%d): ",x1,y1,x2,y2 );
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!skin_region_is_rect(r)) {
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf( "region not rect !!\n" );
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        panic();
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_get_bounds( r, &rect );
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_box_from_rect( &b, &rect );
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (b.x1 != x1 || b.x2 != x2 || b.y1 != y1 || b.y2 != y2) {
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf( "rect region bounds are (%d,%d,%d,%d), expecting (%d,%d,%d,%d)\n",
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               b.x1, b.y1, b.x2, b.y2, x1, y1, x2, y2 );
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        panic();
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "ok\n" );
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectexpectComplexRegion( Region* r, const SkinBox*  boxes, int  count )
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegionIterator  iter;
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinBox             b;
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int                 n;
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "expectComplexRegion(): " );
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!skin_region_is_complex(r)) {
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf( "region is not complex !!\n" );
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        panic();
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    _expectCompare( r, boxes, count );
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "ok\n" );
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectexpectIntersect( Region*  r1, Region*  r2, const SkinBox*  boxes, int  count )
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1];
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "expectIntersect(%d): ", count );
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy( r, r1 );
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_intersect( r, r2 );
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    _expectCompare( r, boxes, count );
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "ok\n" );
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectexpectUnion( Region*  r1, Region*  r2, const SkinBox*  boxes, int  count )
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1];
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "expectUnion(%d): ", count );
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy( r, r1 );
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_union( r, r2 );
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    _expectCompare( r, boxes, count );
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "ok\n" );
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectexpectSubstract( Region*  r1, Region*  r2, const SkinBox*  boxes, int  count )
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1];
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "expectSubstract(%d): ", count );
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_copy( r, r1 );
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_substract( r, r2 );
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    _expectCompare( r, boxes, count );
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf( "ok\n" );
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint main( void )
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SkinRegion  r[1], r2[1];
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init_empty( r );
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expectEmptyRegion( r );
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init( r, 10, 20, 110, 120 );
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expectRectRegion( r, 10, 20, 110, 120 );
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate( r, 50, 80 );
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expectRectRegion( r, 60, 100, 160, 200 );
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init( r, 10, 10, 40, 40 );
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_init( r2, 20, 20, 50, 50 );
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expectTestIntersect( r, r2, SKIN_OVERLAP );
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate(r2, +20, + 20 );
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expectTestIntersect( r, r2, SKIN_OUTSIDE );
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    skin_region_translate(r2, -30, -30 );
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expectTestIntersect( r, r2, SKIN_INSIDE );
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static const SkinBox  result1[1] = {
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            { 20, 20, 40, 40 }
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        };
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static const SkinBox  result2[3] = {
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            { 10, 10, 40, 20 },
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            { 10, 20, 50, 40 },
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            { 20, 40, 50, 50 },
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        };
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static const SkinBox  result3[2] = {
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            { 10, 10, 40, 20 },
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            { 10, 20, 20, 40 },
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        };
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init( r, 10, 10, 40, 40 );
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        skin_region_init( r2, 20, 20, 50, 50 );
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expectIntersect( r, r2, result1, 1 );
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expectUnion( r, r2, result2, 3 );
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expectSubstract( r, r2, result3, 2 );
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* UNIT_TEST */
1449