1999-09-16 18:31:56 -07:00
|
|
|
#include "common.h"
|
|
|
|
#include "updates.h"
|
|
|
|
|
|
|
|
enum _t_used
|
|
|
|
{
|
|
|
|
T_UNUSED = 0,
|
1999-09-18 00:50:37 -07:00
|
|
|
T_USED = 1
|
1999-09-16 18:31:56 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _tile
|
|
|
|
{
|
|
|
|
enum _t_used used;
|
|
|
|
};
|
|
|
|
|
1999-09-26 14:36:51 -07:00
|
|
|
#define TBITS 5
|
|
|
|
#define TB TBITS
|
|
|
|
#define TM ((1 << TBITS) - 1)
|
|
|
|
#define TS (1 << TBITS)
|
|
|
|
|
1999-09-16 18:31:56 -07:00
|
|
|
#define T(x, y) t[((y) * tw) + (x)]
|
|
|
|
#define CLIP(x, y, w, h, xx, yy, ww, hh) \
|
|
|
|
if (x < xx) {w += x; x = xx;} \
|
|
|
|
if (y < yy) {h += y; y = yy;} \
|
|
|
|
if ((x + w) > ww) {w = ww - x;} \
|
|
|
|
if ((y + h) > hh) {h = hh - y;}
|
|
|
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
|
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
|
|
|
|
|
|
|
ImlibUpdate *
|
|
|
|
__imlib_MergeUpdate(ImlibUpdate *u, int w, int h)
|
|
|
|
{
|
|
|
|
ImlibUpdate *nu = NULL, *uu;
|
|
|
|
struct _tile *t;
|
1999-09-18 00:50:37 -07:00
|
|
|
int tw, th, x, y, i;
|
1999-09-16 18:47:49 -07:00
|
|
|
|
|
|
|
/* if theres no rects to process.. return NULL */
|
|
|
|
if (!u)
|
|
|
|
return NULL;
|
|
|
|
/* if theres only one rect - return it - no point cleaning up 1 rect */
|
1999-09-16 18:31:56 -07:00
|
|
|
if (!u->next)
|
|
|
|
return u;
|
|
|
|
tw = w >> TB;
|
|
|
|
if (w & TM)
|
|
|
|
tw++;
|
|
|
|
th = h >> TB;
|
|
|
|
if (h & TM)
|
|
|
|
th++;
|
|
|
|
t = malloc(tw * th * sizeof(struct _tile));
|
|
|
|
/* fill in tiles to be all not used */
|
1999-09-18 00:50:37 -07:00
|
|
|
for (i = 0, y = 0; y < th; y++)
|
1999-09-16 18:31:56 -07:00
|
|
|
{
|
|
|
|
for (x = 0; x < tw; x++)
|
|
|
|
t[i++].used = T_UNUSED;
|
|
|
|
}
|
1999-09-26 14:36:51 -07:00
|
|
|
/* fill in all tiles*/
|
1999-09-16 18:31:56 -07:00
|
|
|
for (uu = u; uu; uu = uu->next)
|
|
|
|
{
|
|
|
|
CLIP(uu->x, uu->y, uu->w, uu->h, 0, 0, w, h);
|
1999-09-26 14:36:51 -07:00
|
|
|
for (y = uu->y >> TB; y <= ((uu->y + uu->h - 1) >> TB); y++)
|
1999-09-16 18:31:56 -07:00
|
|
|
{
|
1999-09-26 14:36:51 -07:00
|
|
|
for (x = uu->x >> TB; x <= ((uu->x + uu->w - 1) >> TB); x++)
|
1999-09-18 00:50:37 -07:00
|
|
|
T(x, y).used = T_USED;
|
1999-09-16 18:31:56 -07:00
|
|
|
}
|
|
|
|
}
|
1999-09-16 18:47:49 -07:00
|
|
|
for (y = 0; y < th; y++)
|
|
|
|
{
|
1999-09-26 14:36:51 -07:00
|
|
|
for (x = 0; x < tw; x++)
|
1999-09-16 18:47:49 -07:00
|
|
|
{
|
1999-09-26 14:36:51 -07:00
|
|
|
if (T(x, y).used & T_USED)
|
1999-09-18 00:50:37 -07:00
|
|
|
{
|
|
|
|
int xx, yy, ww, hh, ok;
|
|
|
|
|
1999-09-26 14:36:51 -07:00
|
|
|
for (xx = x + 1, ww = 1;
|
|
|
|
(T(xx, y).used & T_USED) && (xx < tw);
|
1999-09-18 00:50:37 -07:00
|
|
|
xx++, ww++);
|
1999-09-26 14:36:51 -07:00
|
|
|
for (yy = y + 1, hh = 1, ok = 1;
|
|
|
|
(yy < th) && (ok);
|
|
|
|
yy++, hh++)
|
1999-09-18 00:50:37 -07:00
|
|
|
{
|
1999-09-26 14:36:51 -07:00
|
|
|
for (xx = x; xx < (x + ww); xx++)
|
1999-09-18 00:50:37 -07:00
|
|
|
{
|
|
|
|
if (!(T(xx, yy).used & T_USED))
|
|
|
|
{
|
|
|
|
ok = 0;
|
1999-09-26 14:36:51 -07:00
|
|
|
xx = x + ww;
|
|
|
|
hh--;
|
1999-09-18 00:50:37 -07:00
|
|
|
}
|
|
|
|
}
|
1999-09-26 14:36:51 -07:00
|
|
|
}
|
|
|
|
for (yy = y; yy < (y + hh); yy++)
|
|
|
|
{
|
|
|
|
for (xx = x; xx < (x + ww); xx++)
|
|
|
|
T(xx, yy).used = T_UNUSED;
|
1999-09-18 00:50:37 -07:00
|
|
|
}
|
|
|
|
nu = __imlib_AddUpdate(nu, (x << TB), (y << TB),
|
|
|
|
(ww << TB), (hh << TB));
|
|
|
|
}
|
1999-09-16 18:47:49 -07:00
|
|
|
}
|
|
|
|
}
|
1999-09-16 18:31:56 -07:00
|
|
|
free(t);
|
|
|
|
__imlib_FreeUpdates(u);
|
|
|
|
return nu;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImlibUpdate *
|
|
|
|
__imlib_AddUpdate(ImlibUpdate *u, int x, int y, int w, int h)
|
|
|
|
{
|
|
|
|
ImlibUpdate *nu;
|
|
|
|
|
|
|
|
if ((w < 1) || (h < 1) || ((x + w) < 1) || ((y + h) < 1))
|
|
|
|
return u;
|
|
|
|
nu = malloc(sizeof(ImlibUpdate));
|
|
|
|
nu->x = x;
|
|
|
|
nu->y = y;
|
|
|
|
nu->w = w;
|
|
|
|
nu->h = h;
|
|
|
|
nu->next = u;
|
|
|
|
return nu;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__imlib_FreeUpdates(ImlibUpdate *u)
|
|
|
|
{
|
|
|
|
ImlibUpdate *uu;
|
|
|
|
|
|
|
|
uu = u;
|
|
|
|
while (uu)
|
|
|
|
{
|
|
|
|
u = uu;
|
|
|
|
uu = uu->next;
|
|
|
|
free(u);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|