forked from enlightenment/efl
Add Eina_Rectangle_Pool support. Typically help for font handling in OpenGL or
any case where you need to split a rectangle in many differents small rectangle. SVN revision: 37252
This commit is contained in:
parent
db296d3d3c
commit
72e45419ec
|
@ -25,6 +25,7 @@ eina_rbtree.h \
|
|||
eina_benchmark.h \
|
||||
eina_inline_rbtree.x \
|
||||
eina_inline_mempool.x \
|
||||
eina_inline_rectangle.x \
|
||||
eina_iterator.h
|
||||
|
||||
installed_mainheaderdir = $(prefix)/include/eina-@VMAJ@
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2007-2008 Jorge Luis Zapata Muga
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EINA_INLINE_RECTANGLE_H__
|
||||
#define EINA_INLINE_RECTANGLE_H__
|
||||
|
||||
static inline int
|
||||
eina_spans_intersect(int c1, int l1, int c2, int l2)
|
||||
{
|
||||
return (!(((c2 + l2) <= c1) || (c2 >= (c1 + l1))));
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_is_empty(Eina_Rectangle *r)
|
||||
{
|
||||
return ((r->w < 1) || (r->h < 1)) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h)
|
||||
{
|
||||
r->x = x;
|
||||
r->y = y;
|
||||
r->w = w;
|
||||
r->h = h;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
eina_rectangles_intersect(Eina_Rectangle *r1, Eina_Rectangle *r2)
|
||||
{
|
||||
return (eina_spans_intersect(r1->x, r1->w, r2->x, r2->w) && eina_spans_intersect(r1->y, r1->h, r2->y, r2->h)) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_xcoord_inside(Eina_Rectangle *r, int x)
|
||||
{
|
||||
return ((x >= r->x) && (x < (r->x + r->w))) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_ycoord_inside(Eina_Rectangle *r, int y)
|
||||
{
|
||||
return ((y >= r->y) && (y < (r->y + r->h))) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_coords_inside(Eina_Rectangle *r, int x, int y)
|
||||
{
|
||||
return (eina_rectangle_xcoord_inside(r, x) && eina_rectangle_ycoord_inside(r, y)) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
eina_rectangle_union(Eina_Rectangle *dst, Eina_Rectangle *src)
|
||||
{
|
||||
/* left */
|
||||
if (dst->x > src->x)
|
||||
{
|
||||
dst->w += dst->x - src->x;
|
||||
dst->x = src->x;
|
||||
}
|
||||
/* right */
|
||||
if ((dst->x + dst->w) < (src->x + src->w))
|
||||
dst->w = src->x + src->w;
|
||||
/* top */
|
||||
if (dst->y > src->y)
|
||||
{
|
||||
dst->h += dst->y - src->y;
|
||||
dst->y = src->y;
|
||||
}
|
||||
/* bottom */
|
||||
if ((dst->y + dst->h) < (src->y + src->h))
|
||||
dst->h = src->y + src->h;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_intersection(Eina_Rectangle *dst, Eina_Rectangle *src)
|
||||
{
|
||||
if (!(eina_rectangles_intersect(dst, src)))
|
||||
return EINA_FALSE;
|
||||
|
||||
/* left */
|
||||
if (dst->x < src->x)
|
||||
{
|
||||
dst->w += dst->x - src->x;
|
||||
dst->x = src->x;
|
||||
if (dst->w < 0)
|
||||
dst->w = 0;
|
||||
}
|
||||
/* right */
|
||||
if ((dst->x + dst->w) > (src->x + src->w))
|
||||
dst->w = src->x + src->w - dst->x;
|
||||
/* top */
|
||||
if (dst->y < src->y)
|
||||
{
|
||||
dst->h += dst->y - src->y;
|
||||
dst->y = src->y;
|
||||
if (dst->h < 0)
|
||||
dst->h = 0;
|
||||
}
|
||||
/* bottom */
|
||||
if ((dst->y + dst->h) > (src->y + src->h))
|
||||
dst->h = src->y + src->h - dst->y;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
eina_rectangle_rescale_in(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
|
||||
{
|
||||
res->x = in->x - out->x;
|
||||
res->y = in->y - out->y;
|
||||
res->w = in->w;
|
||||
res->h = in->h;
|
||||
}
|
||||
|
||||
static inline void
|
||||
eina_rectangle_rescale_out(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
|
||||
{
|
||||
res->x = out->x + in->x;
|
||||
res->y = out->y + in->y;
|
||||
res->w = out->w;
|
||||
res->h = out->h;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -24,6 +24,8 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include "eina_types.h"
|
||||
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
|
@ -36,161 +38,28 @@ typedef struct _Eina_Rectangle
|
|||
int h;
|
||||
} Eina_Rectangle;
|
||||
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
* Is it needed??
|
||||
*/
|
||||
static inline int
|
||||
eina_spans_intersect(int c1, int l1, int c2, int l2)
|
||||
{
|
||||
return (!(((c2 + l2) <= c1) || (c2 >= (c1 + l1))));
|
||||
}
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_is_empty(Eina_Rectangle *r)
|
||||
{
|
||||
return ((r->w < 1) || (r->h < 1)) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
typedef struct _Eina_Rectangle_Pool Eina_Rectangle_Pool;
|
||||
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline void
|
||||
eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h)
|
||||
{
|
||||
r->x = x;
|
||||
r->y = y;
|
||||
r->w = w;
|
||||
r->h = h;
|
||||
}
|
||||
static inline int eina_spans_intersect(int c1, int l1, int c2, int l2);
|
||||
static inline Eina_Bool eina_rectangle_is_empty(Eina_Rectangle *r);
|
||||
static inline void eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h);
|
||||
static inline Eina_Bool eina_rectangles_intersect(Eina_Rectangle *r1, Eina_Rectangle *r2);
|
||||
static inline Eina_Bool eina_rectangle_xcoord_inside(Eina_Rectangle *r, int x);
|
||||
static inline Eina_Bool eina_rectangle_ycoord_inside(Eina_Rectangle *r, int y);
|
||||
static inline Eina_Bool eina_rectangle_coords_inside(Eina_Rectangle *r, int x, int y);
|
||||
static inline void eina_rectangle_union(Eina_Rectangle *dst, Eina_Rectangle *src);
|
||||
static inline Eina_Bool eina_rectangle_intersection(Eina_Rectangle *dst, Eina_Rectangle *src);
|
||||
static inline void eina_rectangle_rescale_in(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res);
|
||||
static inline void eina_rectangle_rescale_out(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res);
|
||||
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline Eina_Bool
|
||||
eina_rectangles_intersect(Eina_Rectangle *r1, Eina_Rectangle *r2)
|
||||
{
|
||||
return (eina_spans_intersect(r1->x, r1->w, r2->x, r2->w) && eina_spans_intersect(r1->y, r1->h, r2->y, r2->h)) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_xcoord_inside(Eina_Rectangle *r, int x)
|
||||
{
|
||||
return ((x >= r->x) && (x < (r->x + r->w))) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_ycoord_inside(Eina_Rectangle *r, int y)
|
||||
{
|
||||
return ((y >= r->y) && (y < (r->y + r->h))) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_coords_inside(Eina_Rectangle *r, int x, int y)
|
||||
{
|
||||
return (eina_rectangle_xcoord_inside(r, x) && eina_rectangle_ycoord_inside(r, y)) ? EINA_TRUE : EINA_FALSE;
|
||||
}
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline void
|
||||
eina_rectangle_union(Eina_Rectangle *dst, Eina_Rectangle *src)
|
||||
{
|
||||
/* left */
|
||||
if (dst->x > src->x)
|
||||
{
|
||||
dst->w += dst->x - src->x;
|
||||
dst->x = src->x;
|
||||
}
|
||||
/* right */
|
||||
if ((dst->x + dst->w) < (src->x + src->w))
|
||||
dst->w = src->x + src->w;
|
||||
/* top */
|
||||
if (dst->y > src->y)
|
||||
{
|
||||
dst->h += dst->y - src->y;
|
||||
dst->y = src->y;
|
||||
}
|
||||
/* bottom */
|
||||
if ((dst->y + dst->h) < (src->y + src->h))
|
||||
dst->h = src->y + src->h;
|
||||
}
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline Eina_Bool
|
||||
eina_rectangle_intersection(Eina_Rectangle *dst, Eina_Rectangle *src)
|
||||
{
|
||||
if (!(eina_rectangles_intersect(dst, src)))
|
||||
return EINA_FALSE;
|
||||
EAPI Eina_Rectangle_Pool *eina_rectangle_pool_add(int w, int h);
|
||||
EAPI void eina_rectangle_pool_delete(Eina_Rectangle_Pool *pool);
|
||||
EAPI int eina_rectangle_pool_count(Eina_Rectangle_Pool *pool);
|
||||
EAPI Eina_Rectangle *eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h);
|
||||
EAPI void eina_rectangle_pool_release(Eina_Rectangle *rect);
|
||||
|
||||
/* left */
|
||||
if (dst->x < src->x)
|
||||
{
|
||||
dst->w += dst->x - src->x;
|
||||
dst->x = src->x;
|
||||
if (dst->w < 0)
|
||||
dst->w = 0;
|
||||
}
|
||||
/* right */
|
||||
if ((dst->x + dst->w) > (src->x + src->w))
|
||||
dst->w = src->x + src->w - dst->x;
|
||||
/* top */
|
||||
if (dst->y < src->y)
|
||||
{
|
||||
dst->h += dst->y - src->y;
|
||||
dst->y = src->y;
|
||||
if (dst->h < 0)
|
||||
dst->h = 0;
|
||||
}
|
||||
/* bottom */
|
||||
if ((dst->y + dst->h) > (src->y + src->h))
|
||||
dst->h = src->y + src->h - dst->y;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescale the coordinates from @in as if it where relative to @out
|
||||
*/
|
||||
static inline void
|
||||
eina_rectangle_rescale_in(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
|
||||
{
|
||||
res->x = in->x - out->x;
|
||||
res->y = in->y - out->y;
|
||||
res->w = in->w;
|
||||
res->h = in->h;
|
||||
}
|
||||
/**
|
||||
* To be documented
|
||||
* FIXME: To be fixed
|
||||
*/
|
||||
static inline void
|
||||
eina_rectangle_rescale_out(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
|
||||
{
|
||||
res->x = out->x + in->x;
|
||||
res->y = out->y + in->y;
|
||||
res->w = out->w;
|
||||
res->h = out->h;
|
||||
}
|
||||
#include "eina_inline_rectangle.x"
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /*_ENESIM_RECTANGLE_H_*/
|
||||
#endif /*_EINA_RECTANGLE_H_*/
|
||||
|
|
|
@ -29,6 +29,7 @@ eina_accessor.c \
|
|||
eina_convert.c \
|
||||
eina_rbtree.c \
|
||||
eina_benchmark.c \
|
||||
eina_rectangle.c \
|
||||
eina_stringshare.c
|
||||
|
||||
if EINA_STATIC_BUILD_CHAINED_POOL
|
||||
|
|
|
@ -30,12 +30,14 @@
|
|||
* API *
|
||||
*============================================================================*/
|
||||
|
||||
static int _eina_main_count = 0;
|
||||
|
||||
EAPI int
|
||||
eina_init(void)
|
||||
{
|
||||
int r;
|
||||
if (_eina_main_count) goto finish_init;
|
||||
|
||||
r = eina_error_init();
|
||||
eina_error_init();
|
||||
eina_hash_init();
|
||||
eina_stringshare_init();
|
||||
eina_list_init();
|
||||
|
@ -44,13 +46,14 @@ eina_init(void)
|
|||
eina_benchmark_init();
|
||||
eina_magic_string_init();
|
||||
|
||||
return r;
|
||||
finish_init:
|
||||
return ++_eina_main_count;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
eina_shutdown(void)
|
||||
{
|
||||
int r;
|
||||
if (_eina_main_count != 1) goto finish_shutdown;
|
||||
|
||||
eina_magic_string_shutdown();
|
||||
eina_benchmark_shutdown();
|
||||
|
@ -59,8 +62,9 @@ eina_shutdown(void)
|
|||
eina_list_shutdown();
|
||||
eina_stringshare_shutdown();
|
||||
eina_hash_shutdown();
|
||||
r = eina_error_shutdown();
|
||||
eina_error_shutdown();
|
||||
|
||||
return r;
|
||||
finish_shutdown:
|
||||
return --_eina_main_count;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,290 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2007-2008 Cedric BAIL, Carsten Haitzler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eina_rectangle.h"
|
||||
#include "eina_magic.h"
|
||||
#include "eina_inlist.h"
|
||||
#include "eina_private.h"
|
||||
|
||||
/*============================================================================*
|
||||
* Local *
|
||||
*============================================================================*/
|
||||
|
||||
/**
|
||||
* @cond LOCAL
|
||||
*/
|
||||
|
||||
#define EINA_RECTANGLE_POOL_MAGIC 0x1578FCB0
|
||||
#define EINA_RECTANGLE_ALLOC_MAGIC 0x1578FCB1
|
||||
|
||||
typedef struct _Eina_Rectangle_Alloc Eina_Rectangle_Alloc;
|
||||
|
||||
struct _Eina_Rectangle_Pool
|
||||
{
|
||||
EINA_MAGIC;
|
||||
|
||||
Eina_Inlist *head;
|
||||
|
||||
unsigned int references;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
struct _Eina_Rectangle_Alloc
|
||||
{
|
||||
EINA_INLIST;
|
||||
EINA_MAGIC;
|
||||
|
||||
Eina_Rectangle_Pool *pool;
|
||||
};
|
||||
|
||||
#define EINA_MAGIC_CHECK_RECTANGLE_POOL(d) \
|
||||
do { \
|
||||
if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_POOL_MAGIC)) \
|
||||
EINA_MAGIC_FAIL((d), EINA_RECTANGLE_POOL_MAGIC); \
|
||||
} while (0);
|
||||
|
||||
#define EINA_MAGIC_CHECK_RECTANGLE_ALLOC(d) \
|
||||
do { \
|
||||
if (!EINA_MAGIC_CHECK((d), EINA_RECTANGLE_ALLOC_MAGIC)) \
|
||||
EINA_MAGIC_FAIL((d), EINA_RECTANGLE_ALLOC_MAGIC); \
|
||||
} while (0);
|
||||
|
||||
static inline Eina_Bool
|
||||
_eina_rectangle_pool_collide(Eina_Rectangle_Alloc *head, Eina_Rectangle_Alloc *current, Eina_Rectangle *test)
|
||||
{
|
||||
Eina_Rectangle_Alloc *collide;
|
||||
|
||||
EINA_INLIST_FOREACH(head, collide)
|
||||
{
|
||||
Eina_Rectangle *colliding_rect = (Eina_Rectangle*) (collide + 1);
|
||||
|
||||
if (collide == current) continue;
|
||||
if (eina_rectangles_intersect(colliding_rect, test))
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eina_rectangle_pool_find(Eina_Rectangle_Alloc *head, int poolw, int poolh, int w, int h, int *x, int *y)
|
||||
{
|
||||
Eina_Rectangle_Alloc *item;
|
||||
Eina_Rectangle tmp = { 0, 0, 0, 0 };
|
||||
|
||||
if (head == NULL) goto on_intersect;
|
||||
|
||||
EINA_INLIST_FOREACH(head, item)
|
||||
{
|
||||
Eina_Rectangle *rect = (Eina_Rectangle*) (item + 1);
|
||||
Eina_Bool t1 = EINA_TRUE;
|
||||
Eina_Bool t2 = EINA_TRUE;
|
||||
Eina_Bool t3 = EINA_TRUE;
|
||||
Eina_Bool t4 = EINA_TRUE;
|
||||
Eina_Bool intersects;
|
||||
|
||||
if ((rect->x + rect->w + w) > poolw) t1 = EINA_FALSE;
|
||||
if ((rect->y + h) > poolh) t1 = EINA_FALSE;
|
||||
if ((rect->y + rect->h + h) > poolh) t2 = EINA_FALSE;
|
||||
if ((rect->x + w) > poolw) t2 = EINA_FALSE;
|
||||
if ((rect->x - w) < 0) t3 = EINA_FALSE;
|
||||
if ((rect->y + h) > poolh) t3 = EINA_FALSE;
|
||||
if ((rect->x + w) > poolw) t4 = EINA_FALSE;
|
||||
if ((rect->y - h) < 0) t4 = EINA_FALSE;
|
||||
|
||||
intersects = EINA_FALSE;
|
||||
if (t1)
|
||||
{
|
||||
/* 1. try here:
|
||||
* +----++--+
|
||||
* |AAAA||??|
|
||||
* |AAAA|+--+
|
||||
* |AAAA|
|
||||
* +----+
|
||||
*/
|
||||
eina_rectangle_coords_from(&tmp, rect->x + rect->w, rect->y, w, h);
|
||||
intersects = _eina_rectangle_pool_collide(head, item, &tmp);
|
||||
|
||||
if (!intersects) goto on_intersect;
|
||||
}
|
||||
intersects = EINA_FALSE;
|
||||
if (t2)
|
||||
{
|
||||
/* 2. try here:
|
||||
* +----+
|
||||
* |AAAA|
|
||||
* |AAAA|
|
||||
* |AAAA|
|
||||
* +----+
|
||||
* +--+
|
||||
* |??|
|
||||
* +--+
|
||||
*/
|
||||
eina_rectangle_coords_from(&tmp, rect->x, rect->y + rect->h, w, h);
|
||||
intersects = _eina_rectangle_pool_collide(head, item, &tmp);
|
||||
|
||||
if (!intersects) goto on_intersect;
|
||||
}
|
||||
intersects = EINA_FALSE;
|
||||
if (t3)
|
||||
{
|
||||
/* 3. try here:
|
||||
* +--++----+
|
||||
* |??||AAAA|
|
||||
* +--+|AAAA|
|
||||
* |AAAA|
|
||||
* +----+
|
||||
*/
|
||||
eina_rectangle_coords_from(&tmp, rect->x - w, rect->y, w, h);
|
||||
intersects = _eina_rectangle_pool_collide(head, item, &tmp);
|
||||
|
||||
if (!intersects) goto on_intersect;
|
||||
}
|
||||
intersects = EINA_FALSE;
|
||||
if (t4)
|
||||
{
|
||||
/* 2. try here:
|
||||
* +--+
|
||||
* |??|
|
||||
* +--+
|
||||
* +----+
|
||||
* |AAAA|
|
||||
* |AAAA|
|
||||
* |AAAA|
|
||||
* +----+
|
||||
*/
|
||||
eina_rectangle_coords_from(&tmp, rect->x, rect->y - h, w, h);
|
||||
intersects = _eina_rectangle_pool_collide(head, item, &tmp);
|
||||
|
||||
if (!intersects) goto on_intersect;
|
||||
}
|
||||
}
|
||||
|
||||
return EINA_FALSE;
|
||||
|
||||
on_intersect:
|
||||
*x = tmp.x;
|
||||
*y = tmp.y;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
/*============================================================================*
|
||||
* Global *
|
||||
*============================================================================*/
|
||||
|
||||
/*============================================================================*
|
||||
* API *
|
||||
*============================================================================*/
|
||||
|
||||
EAPI Eina_Rectangle_Pool *
|
||||
eina_rectangle_pool_add(int w, int h)
|
||||
{
|
||||
Eina_Rectangle_Pool *new;
|
||||
|
||||
new = malloc(sizeof (Eina_Rectangle_Pool));
|
||||
if (!new) return NULL;
|
||||
|
||||
new->head = NULL;
|
||||
new->references = 0;
|
||||
new->w = w;
|
||||
new->h = h;
|
||||
|
||||
EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_rectangle_pool_delete(Eina_Rectangle_Pool *pool)
|
||||
{
|
||||
Eina_Rectangle_Alloc *del;
|
||||
|
||||
while (pool->head)
|
||||
{
|
||||
del = (Eina_Rectangle_Alloc*) pool->head;
|
||||
|
||||
pool->head = (EINA_INLIST_GET(del))->next;
|
||||
|
||||
MAGIC_FREE(del);
|
||||
}
|
||||
|
||||
MAGIC_FREE(pool);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
eina_rectangle_pool_count(Eina_Rectangle_Pool *pool)
|
||||
{
|
||||
return pool->references;
|
||||
}
|
||||
|
||||
EAPI Eina_Rectangle *
|
||||
eina_rectangle_pool_request(Eina_Rectangle_Pool *pool, int w, int h)
|
||||
{
|
||||
Eina_Rectangle_Alloc *new;
|
||||
Eina_Rectangle *rect;
|
||||
Eina_Bool test;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
if (w > pool->w || h > pool->h) return NULL;
|
||||
|
||||
test = _eina_rectangle_pool_find((Eina_Rectangle_Alloc*) pool->head, pool->w, pool->h, w, h, &x, &y);
|
||||
if (!test) return NULL;
|
||||
|
||||
new = malloc(sizeof (Eina_Rectangle_Alloc) + sizeof (Eina_Rectangle));
|
||||
if (!new) return NULL;
|
||||
|
||||
rect = (Eina_Rectangle*) (new + 1);
|
||||
eina_rectangle_coords_from(rect, x, y, w, h);
|
||||
|
||||
pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new));
|
||||
pool->references++;
|
||||
|
||||
new->pool = pool;
|
||||
|
||||
EINA_MAGIC_SET(new, EINA_RECTANGLE_ALLOC_MAGIC);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_rectangle_pool_release(Eina_Rectangle *rect)
|
||||
{
|
||||
Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *) rect) - 1;
|
||||
|
||||
EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era);
|
||||
EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool);
|
||||
|
||||
era->pool->references--;
|
||||
era->pool->head = eina_inlist_remove(era->pool->head, EINA_INLIST_GET(era));
|
||||
|
||||
MAGIC_FREE(era);
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +63,7 @@ eina_test_rbtree.c \
|
|||
eina_test_file.c \
|
||||
eina_test_benchmark.c \
|
||||
eina_test_mempool.c \
|
||||
eina_test_rectangle.c \
|
||||
eina_test_list.c
|
||||
|
||||
eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la
|
||||
|
|
|
@ -45,6 +45,7 @@ static const Eina_Test_Case etc[] = {
|
|||
{ "File", eina_test_file },
|
||||
{ "Benchmark", eina_test_benchmark },
|
||||
{ "Mempool", eina_test_mempool },
|
||||
{ "Rectangle", eina_test_rectangle },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -43,5 +43,6 @@ void eina_test_rbtree(TCase *tc);
|
|||
void eina_test_file(TCase *tc);
|
||||
void eina_test_benchmark(TCase *tc);
|
||||
void eina_test_mempool(TCase *tc);
|
||||
void eina_test_rectangle(TCase *tc);
|
||||
|
||||
#endif /* EINA_SUITE_H_ */
|
||||
|
|
|
@ -27,10 +27,8 @@
|
|||
|
||||
START_TEST(eina_simple)
|
||||
{
|
||||
/* Eina_error as already been initialized by eina_hash
|
||||
that was called by eina_mempool_init that's why we don't have 0 here */
|
||||
fail_if(eina_init() != 2);
|
||||
fail_if(eina_shutdown() != 1);
|
||||
fail_if(eina_init() != 1);
|
||||
fail_if(eina_shutdown() != 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2007-2008 Cedric BAIL, Carsten Haitzler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "eina_rectangle.h"
|
||||
#include "eina_suite.h"
|
||||
|
||||
START_TEST(eina_rectangle_pool)
|
||||
{
|
||||
Eina_Rectangle_Pool *pool;
|
||||
Eina_Rectangle *rects[8][8];
|
||||
Eina_Rectangle *rct;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
pool = eina_rectangle_pool_add(256, 256);
|
||||
fail_if(pool == NULL);
|
||||
|
||||
fail_if(eina_rectangle_pool_request(pool, 1024, 1024) != NULL);
|
||||
|
||||
for (x = 0; x < 8; x++)
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
rects[x][y] = eina_rectangle_pool_request(pool, 32, 32);
|
||||
fail_if(rects[x][y] == NULL);
|
||||
}
|
||||
|
||||
fail_if(eina_rectangle_pool_count(pool) != 64);
|
||||
|
||||
fail_if(eina_rectangle_pool_request(pool, 32, 32) != NULL);
|
||||
fail_if(eina_rectangle_pool_request(pool, 1024, 1024) != NULL);
|
||||
|
||||
for (x = 0; x < 8; x++)
|
||||
eina_rectangle_pool_release(rects[0][x]);
|
||||
|
||||
fail_if(eina_rectangle_pool_request(pool, 16, 16) == NULL);
|
||||
|
||||
eina_rectangle_pool_delete(pool);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eina_test_rectangle(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, eina_rectangle_pool);
|
||||
}
|
||||
|
Loading…
Reference in New Issue