2008-10-27 13:24:12 -07:00
|
|
|
/* 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
|
|
|
|
|
2009-06-05 21:22:21 -07:00
|
|
|
#include <stdio.h>
|
2008-10-27 13:24:12 -07:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2017-09-22 03:06:10 -07:00
|
|
|
#ifdef _WIN32
|
2009-12-19 02:30:49 -08:00
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2009-06-08 01:27:33 -07:00
|
|
|
#include "eina_config.h"
|
2009-08-28 05:03:34 -07:00
|
|
|
#include "eina_private.h"
|
2008-10-27 13:24:12 -07:00
|
|
|
#include "eina_magic.h"
|
|
|
|
#include "eina_inlist.h"
|
2009-04-09 08:51:32 -07:00
|
|
|
#include "eina_mempool.h"
|
2009-06-22 06:16:51 -07:00
|
|
|
#include "eina_list.h"
|
2009-08-18 06:35:33 -07:00
|
|
|
#include "eina_trash.h"
|
2010-10-01 05:18:39 -07:00
|
|
|
#include "eina_log.h"
|
2016-04-25 12:48:08 -07:00
|
|
|
#include "eina_lock.h"
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
|
|
|
|
#include "eina_safety_checks.h"
|
|
|
|
#include "eina_rectangle.h"
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
/*============================================================================*
|
2010-07-27 19:37:05 -07:00
|
|
|
* Local *
|
|
|
|
*============================================================================*/
|
2008-10-27 13:24:12 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @cond LOCAL
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define EINA_RECTANGLE_POOL_MAGIC 0x1578FCB0
|
|
|
|
#define EINA_RECTANGLE_ALLOC_MAGIC 0x1578FCB1
|
|
|
|
|
2009-08-18 06:35:33 -07:00
|
|
|
#define BUCKET_THRESHOLD 110
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
typedef struct _Eina_Rectangle_Alloc Eina_Rectangle_Alloc;
|
|
|
|
|
|
|
|
struct _Eina_Rectangle_Pool
|
|
|
|
{
|
|
|
|
Eina_Inlist *head;
|
2009-06-22 06:16:51 -07:00
|
|
|
Eina_List *empty;
|
2008-10-28 08:28:46 -07:00
|
|
|
void *data;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
Eina_Compare_Cb eina_rectangle_compare_func;
|
|
|
|
|
2009-08-18 06:35:33 -07:00
|
|
|
Eina_Trash *bucket;
|
|
|
|
unsigned int bucket_count;
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
Eina_Rectangle_Packing type;
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
unsigned int references;
|
|
|
|
int w;
|
|
|
|
int h;
|
2009-06-24 06:38:25 -07:00
|
|
|
|
|
|
|
Eina_Bool sorted;
|
* eina/src/include/eina_array.h,
* eina/src/include/eina_f16p16.h,
* eina/src/include/eina_accessor.h,
* eina/src/include/eina_list.h,
* eina/src/include/eina_iterator.h,
* eina/src/lib/eina_rectangle.c,
* eina/src/lib/eina_list.c,
* eina/src/lib/eina_array.c,
* eina/src/lib/eina_hash.c,
* eina/src/lib/eina_module.c,
* eina/src/lib/eina_stringshare.c,
* eina/src/lib/eina_benchmark.c: Fix for windows compilation.
SVN revision: 38663
2009-01-20 07:56:48 -08:00
|
|
|
EINA_MAGIC
|
2008-10-27 13:24:12 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _Eina_Rectangle_Alloc
|
|
|
|
{
|
|
|
|
EINA_INLIST;
|
|
|
|
Eina_Rectangle_Pool *pool;
|
* eina/src/include/eina_array.h,
* eina/src/include/eina_f16p16.h,
* eina/src/include/eina_accessor.h,
* eina/src/include/eina_list.h,
* eina/src/include/eina_iterator.h,
* eina/src/lib/eina_rectangle.c,
* eina/src/lib/eina_list.c,
* eina/src/lib/eina_array.c,
* eina/src/lib/eina_hash.c,
* eina/src/lib/eina_module.c,
* eina/src/lib/eina_stringshare.c,
* eina/src/lib/eina_benchmark.c: Fix for windows compilation.
SVN revision: 38663
2009-01-20 07:56:48 -08:00
|
|
|
EINA_MAGIC
|
2008-10-27 13:24:12 -07:00
|
|
|
};
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
#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)
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
#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)
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2009-06-22 06:16:51 -07:00
|
|
|
static Eina_Mempool *_eina_rectangle_alloc_mp = NULL;
|
2009-04-09 08:51:32 -07:00
|
|
|
static Eina_Mempool *_eina_rectangle_mp = NULL;
|
|
|
|
|
2016-04-25 12:48:08 -07:00
|
|
|
static Eina_Spinlock _eina_spinlock;
|
2009-08-18 06:35:33 -07:00
|
|
|
static Eina_Trash *_eina_rectangles = NULL;
|
|
|
|
static unsigned int _eina_rectangles_count = 0;
|
2009-09-03 19:11:44 -07:00
|
|
|
static int _eina_rectangle_log_dom = -1;
|
|
|
|
|
2009-09-06 21:23:05 -07:00
|
|
|
#ifdef ERR
|
|
|
|
#undef ERR
|
|
|
|
#endif
|
2009-09-03 19:11:44 -07:00
|
|
|
#define ERR(...) EINA_LOG_DOM_ERR(_eina_rectangle_log_dom, __VA_ARGS__)
|
2009-09-06 21:23:05 -07:00
|
|
|
|
|
|
|
#ifdef DBG
|
|
|
|
#undef DBG
|
|
|
|
#endif
|
2009-09-03 19:11:44 -07:00
|
|
|
#define DBG(...) EINA_LOG_DOM_DBG(_eina_rectangle_log_dom, __VA_ARGS__)
|
2009-08-18 06:35:33 -07:00
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
static int
|
2014-06-19 05:35:37 -07:00
|
|
|
_eina_rectangle_cmp(const void *data1, const void *data2)
|
2008-10-27 13:24:12 -07:00
|
|
|
{
|
2014-06-19 05:35:37 -07:00
|
|
|
Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
|
|
|
|
Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
|
2009-06-24 06:38:25 -07:00
|
|
|
return (r2->w * r2->h) - (r1->w * r1->h);
|
2008-10-27 13:24:12 -07:00
|
|
|
}
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
static int
|
|
|
|
_eina_rectangle_cmp_asc(const void *data1, const void *data2)
|
|
|
|
{
|
|
|
|
Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
|
|
|
|
Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
|
|
|
|
return (r1->w * r1->h) - (r2->w * r2->h);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_eina_rectangle_cmp_bl(const void *data1, const void *data2)
|
|
|
|
{
|
|
|
|
Eina_Rectangle *r1 = (Eina_Rectangle *) data1;
|
|
|
|
Eina_Rectangle *r2 = (Eina_Rectangle *) data2;
|
|
|
|
if (r1->y != r2->y)
|
|
|
|
return (r1->y) - (r2->y);
|
|
|
|
else
|
|
|
|
return (r1->x) - (r2->x);
|
|
|
|
}
|
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
static Eina_List *
|
2014-06-19 05:35:37 -07:00
|
|
|
_eina_rectangle_merge_list(Eina_List *empty, Eina_Rectangle_Packing type, Eina_Rectangle *r)
|
2008-10-27 13:24:12 -07:00
|
|
|
{
|
2014-06-19 05:35:37 -07:00
|
|
|
Eina_Rectangle *match, *r1;
|
2009-06-24 06:38:25 -07:00
|
|
|
Eina_List *l;
|
2009-07-07 04:24:44 -07:00
|
|
|
int xw;
|
|
|
|
int yh;
|
2014-06-19 05:35:37 -07:00
|
|
|
int x2 ,y2 ,w2 ,h2;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
if (r->w == 0 || r->h == 0)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_rectangle_free(r);
|
|
|
|
return empty;
|
2009-06-24 06:38:25 -07:00
|
|
|
}
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
start_again:
|
2009-07-07 04:24:44 -07:00
|
|
|
xw = r->x + r->w;
|
|
|
|
yh = r->y + r->h;
|
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
EINA_LIST_FOREACH(empty, l, match)
|
2010-07-27 19:37:05 -07:00
|
|
|
{
|
|
|
|
if (match->x == r->x && match->w == r->w
|
|
|
|
&& (match->y == yh || r->y == match->y + match->h))
|
|
|
|
{
|
|
|
|
if (match->y > r->y)
|
|
|
|
match->y = r->y;
|
2009-06-24 06:38:25 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
match->h += r->h;
|
2009-06-24 06:38:25 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_rectangle_free(r);
|
2009-06-24 06:38:25 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
empty = eina_list_remove_list(empty, l);
|
2009-07-07 04:24:44 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
r = match;
|
2009-06-24 06:38:25 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
goto start_again;
|
|
|
|
}
|
|
|
|
else if (match->y == r->y && match->h == r->h
|
|
|
|
&& (match->x == xw || r->x == match->x + match->w))
|
|
|
|
{
|
|
|
|
if (match->x > r->x)
|
|
|
|
match->x = r->x;
|
2009-06-24 06:38:25 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
match->w += r->w;
|
2009-06-24 06:38:25 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_rectangle_free(r);
|
2009-07-07 04:24:44 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
empty = eina_list_remove_list(empty, l);
|
|
|
|
|
|
|
|
r = match;
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
goto start_again;
|
|
|
|
}
|
|
|
|
else if (match->y > r->y && type == Eina_Packing_Bottom_Left_Skyline
|
|
|
|
&& (match->y + match->h == r->y + r->h) &&
|
|
|
|
(match->x + match->w == r->x || r->x + r->w == match->x))
|
|
|
|
{
|
|
|
|
|
|
|
|
if (r->x < match->x)
|
|
|
|
match->x = r->x;
|
|
|
|
|
|
|
|
match->w += r->w;
|
|
|
|
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y;
|
|
|
|
w2 = r->w;
|
|
|
|
h2 = match->y - r->y;
|
|
|
|
|
|
|
|
eina_rectangle_free(r);
|
|
|
|
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
|
|
|
|
empty = eina_list_remove_list(empty, l);
|
|
|
|
|
|
|
|
if (r1)
|
|
|
|
empty = eina_list_append(empty, r1);
|
|
|
|
|
|
|
|
r = match;
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
goto start_again;
|
|
|
|
}
|
|
|
|
}
|
2009-06-24 06:38:25 -07:00
|
|
|
|
|
|
|
return eina_list_append(empty, r);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
2014-06-19 05:35:37 -07:00
|
|
|
_eina_rectangle_empty_space_find(Eina_List *empty, Eina_Rectangle_Packing type, int w, int h, int *x, int *y)
|
2009-06-24 06:38:25 -07:00
|
|
|
{
|
|
|
|
Eina_Rectangle *r;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(empty, l, r)
|
2010-07-27 19:37:05 -07:00
|
|
|
{
|
|
|
|
if (r->w >= w && r->h >= h)
|
|
|
|
{
|
|
|
|
/* Remove l from empty */
|
|
|
|
empty = eina_list_remove_list(empty, l);
|
|
|
|
/* Remember x and y */
|
|
|
|
*x = r->x;
|
|
|
|
*y = r->y;
|
|
|
|
/* Split r in 2 rectangle if needed (only the empty one) and insert them */
|
|
|
|
if (r->w == w)
|
|
|
|
{
|
|
|
|
r->y += h;
|
|
|
|
r->h -= h;
|
|
|
|
}
|
|
|
|
else if (r->h == h)
|
|
|
|
{
|
|
|
|
r->x += w;
|
|
|
|
r->w -= w;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int rx1, ry1, rw1, rh1;
|
|
|
|
int x2, y2, w2, h2;
|
|
|
|
|
|
|
|
rx1 = r->x + w;
|
|
|
|
ry1 = r->y;
|
|
|
|
rw1 = r->w - w;
|
|
|
|
/* h1 could be h or r->h */
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y + h;
|
|
|
|
/* w2 could be w or r->w */
|
|
|
|
h2 = r->h - h;
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
if ((rw1 * r->h > h2 * r->w) || type == Eina_Packing_Bottom_Left || type == Eina_Packing_Bottom_Left_Skyline)
|
2010-07-27 19:37:05 -07:00
|
|
|
{
|
|
|
|
rh1 = r->h;
|
|
|
|
w2 = w;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rh1 = h;
|
|
|
|
w2 = r->w;
|
|
|
|
}
|
2014-06-19 05:35:37 -07:00
|
|
|
if (type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
|
|
|
{
|
|
|
|
rh1 = r->h;
|
|
|
|
w2 = r->w;
|
|
|
|
}
|
2010-07-27 19:37:05 -07:00
|
|
|
|
|
|
|
EINA_RECTANGLE_SET(r, rx1, ry1, rw1, rh1);
|
2014-06-19 05:35:37 -07:00
|
|
|
empty = _eina_rectangle_merge_list(empty, type, r);
|
2010-07-27 19:37:05 -07:00
|
|
|
|
|
|
|
r = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r)
|
2010-07-27 20:03:25 -07:00
|
|
|
{
|
2014-06-19 05:35:37 -07:00
|
|
|
empty = _eina_rectangle_merge_list(empty, type, r); /* Return empty */
|
2010-07-27 20:03:25 -07:00
|
|
|
|
|
|
|
}
|
2010-07-27 19:37:05 -07:00
|
|
|
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
}
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
*x = -1;
|
|
|
|
*y = -1;
|
|
|
|
return empty;
|
2008-10-27 13:24:12 -07:00
|
|
|
}
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
static Eina_List *
|
|
|
|
_eina_rectangle_skyline_merge_list(Eina_List *empty, Eina_Rectangle *r)
|
|
|
|
{
|
|
|
|
Eina_Rectangle *match;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(empty, l, match)
|
|
|
|
{
|
|
|
|
if (match->x == r->x + r->w)
|
|
|
|
{
|
|
|
|
match->x = r->x;
|
|
|
|
match->w = r->w + match->w;
|
|
|
|
}
|
|
|
|
else if (match->y == r->y + r->h)
|
|
|
|
{
|
|
|
|
match->y = r->y;
|
|
|
|
match->h = r->h + match->h;
|
|
|
|
}
|
|
|
|
else if (match->x + match->w == r->x)
|
|
|
|
{
|
|
|
|
match->w = r->w + match->w;
|
|
|
|
}
|
|
|
|
else if (match->y + match->h == r->y )
|
|
|
|
{
|
|
|
|
match->h = r->h + match->h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
_eina_rectangle_skyline_list_update(Eina_List *empty, Eina_Rectangle *rect)
|
|
|
|
{
|
|
|
|
Eina_Rectangle *r, *r1;
|
|
|
|
Eina_List *l;
|
|
|
|
int x2, y2, w2, h2;
|
|
|
|
|
|
|
|
start_again :
|
|
|
|
EINA_LIST_FOREACH(empty, l, r)
|
|
|
|
{
|
|
|
|
if (eina_rectangles_intersect(rect, r))
|
|
|
|
{
|
|
|
|
/* Remove l from empty */
|
|
|
|
empty = eina_list_remove_list(empty, l);
|
|
|
|
|
|
|
|
if (r->y > rect->y)
|
|
|
|
{
|
|
|
|
if (r->y + r->h > rect->y + rect->h)
|
|
|
|
{
|
|
|
|
w2 = r->w;
|
|
|
|
h2 = (r->y +r->h) - (rect->y + rect->h);
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = (r->y +r->h) - h2;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
if ( r->x + r->w > rect->x + rect->w )
|
|
|
|
{
|
|
|
|
w2 = (r->x +r->w) - (rect->x + rect->w);
|
|
|
|
h2 = r->h;
|
|
|
|
x2 = rect->x + rect->w;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
if ( rect->x - r->x)
|
|
|
|
{
|
|
|
|
w2 = rect->x - r->x;
|
|
|
|
h2 = r->h;
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (r->x > rect->x)
|
|
|
|
{
|
|
|
|
if (r->x + r->w > rect->x + rect->w)
|
|
|
|
{
|
|
|
|
w2 = (r->x + r->w) - (rect->x + rect->w);
|
|
|
|
h2 = r->h;
|
|
|
|
x2 = (r->x +r->w) - w2;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
if ( r->y + r->h > rect->y + rect->y )
|
|
|
|
{
|
|
|
|
w2 = r->w;
|
|
|
|
h2 = (r->y +r->h) - (rect->y + rect->h);
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = rect->y + rect->h;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
if ( rect->y > r->y)
|
|
|
|
{
|
|
|
|
w2 = r->w;;
|
|
|
|
h2 = rect->y - r->y;
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (r->x == rect->x && r->y < rect->y)
|
|
|
|
{
|
|
|
|
if (rect->y + rect->h < r->y + r->h)
|
|
|
|
{
|
|
|
|
w2 = r->w;
|
|
|
|
h2 = (r->y +r->h) - (rect->y + rect->h);
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = rect->y + rect->h;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
w2 = r->w;
|
|
|
|
h2 = rect->y - r->y;
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
else if (r->y == rect->y && r->x < rect->x)
|
|
|
|
{
|
|
|
|
if (rect->w + rect->x < r->w + r->x)
|
|
|
|
{
|
|
|
|
w2 = (r->x + r->w) - (rect->x + rect->w);
|
|
|
|
h2 = r->h;
|
|
|
|
x2 = rect->x + rect->w;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
w2 = rect->x - r->x;
|
|
|
|
h2 = r->h;;
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
else if (r->x < rect->x && r->y < rect->y)
|
|
|
|
{
|
|
|
|
w2 = rect->x - r->x;
|
|
|
|
h2 = r->h;
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
w2 = r->w;
|
|
|
|
h2 = rect->y - r->y;
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
else if (r->x == rect->x && r->y == rect->y)
|
|
|
|
{
|
|
|
|
if (r->w > rect->w )
|
|
|
|
{
|
|
|
|
w2 = r->w - rect->w;
|
|
|
|
h2 = r->h;
|
|
|
|
x2 = rect->x + rect->w;
|
|
|
|
y2 = r->y;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
if (r->h > rect->h )
|
|
|
|
{
|
|
|
|
w2 = r->w;
|
|
|
|
h2 = r->h - rect->h;
|
|
|
|
x2 = r->x;
|
|
|
|
y2 = rect->y + rect->h;
|
|
|
|
r1 = eina_rectangle_new(x2, y2, w2, h2);
|
|
|
|
empty = eina_list_prepend(empty, r1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
goto start_again;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
_eina_rectangle_skyline_list_update_duplicate(Eina_List *empty)
|
|
|
|
{
|
|
|
|
Eina_Rectangle *r, *r1;
|
|
|
|
Eina_List *l, *l1, *l2;
|
|
|
|
|
|
|
|
start_again:
|
|
|
|
EINA_LIST_FOREACH(empty, l, r)
|
|
|
|
{
|
|
|
|
l1 = eina_list_next(l);
|
|
|
|
EINA_LIST_FOREACH(l1, l2, r1)
|
|
|
|
{
|
|
|
|
if ((r->x <= r1->x) && (r->y <= r1->y) && (r->x + r->w >= r1->x + r1->w) && (r->y + r->h >= r1->y + r1->h))
|
|
|
|
{
|
|
|
|
empty = eina_list_remove_list(empty, l2);
|
|
|
|
goto start_again;
|
|
|
|
}
|
|
|
|
else if ((r->x >= r1->x) && (r->y >= r1->y) && (r->x + r->w <= r1->x + r1->w) && (r->y + r->h <= r1->y + r1->h))
|
|
|
|
{
|
|
|
|
empty = eina_list_remove_list(empty, l);
|
|
|
|
goto start_again;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return empty;
|
|
|
|
}
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
/**
|
|
|
|
* @endcond
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*============================================================================*
|
2010-07-27 19:37:05 -07:00
|
|
|
* Global *
|
|
|
|
*============================================================================*/
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
Eina_Bool
|
2009-06-27 23:29:11 -07:00
|
|
|
eina_rectangle_init(void)
|
|
|
|
{
|
2009-09-06 15:21:56 -07:00
|
|
|
const char *choice, *tmp;
|
2009-09-03 19:11:44 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
_eina_rectangle_log_dom = eina_log_domain_register("eina_rectangle",
|
|
|
|
EINA_LOG_COLOR_DEFAULT);
|
2009-09-03 19:11:44 -07:00
|
|
|
if (_eina_rectangle_log_dom < 0)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
EINA_LOG_ERR("Could not register log domain: eina_rectangle");
|
|
|
|
return EINA_FALSE;
|
2009-07-20 18:55:31 -07:00
|
|
|
}
|
|
|
|
|
2009-06-27 23:29:11 -07:00
|
|
|
#ifdef EINA_DEFAULT_MEMPOOL
|
|
|
|
choice = "pass_through";
|
|
|
|
#else
|
2009-09-06 15:21:56 -07:00
|
|
|
choice = "chained_mempool";
|
2009-06-27 23:29:11 -07:00
|
|
|
#endif
|
2009-09-06 15:21:56 -07:00
|
|
|
tmp = getenv("EINA_MEMPOOL");
|
|
|
|
if (tmp && tmp[0])
|
2010-07-27 19:37:05 -07:00
|
|
|
choice = tmp;
|
2009-06-27 23:29:11 -07:00
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
_eina_rectangle_alloc_mp = eina_mempool_add
|
2010-07-27 19:37:05 -07:00
|
|
|
(choice, "rectangle-alloc", NULL,
|
2012-06-16 18:51:27 -07:00
|
|
|
sizeof(Eina_Rectangle_Alloc) + sizeof(Eina_Rectangle), 64);
|
2009-06-27 23:29:11 -07:00
|
|
|
if (!_eina_rectangle_alloc_mp)
|
|
|
|
{
|
2009-09-03 19:11:44 -07:00
|
|
|
ERR("Mempool for rectangle cannot be allocated in rectangle init.");
|
2009-06-27 23:29:11 -07:00
|
|
|
goto init_error;
|
|
|
|
}
|
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
_eina_rectangle_mp = eina_mempool_add
|
2012-06-16 18:51:27 -07:00
|
|
|
(choice, "rectangle", NULL, sizeof(Eina_Rectangle), 32);
|
2009-06-27 23:29:11 -07:00
|
|
|
if (!_eina_rectangle_mp)
|
|
|
|
{
|
2009-09-03 19:11:44 -07:00
|
|
|
ERR("Mempool for rectangle cannot be allocated in rectangle init.");
|
2009-06-27 23:29:11 -07:00
|
|
|
goto init_error;
|
|
|
|
}
|
|
|
|
|
2016-04-25 12:48:08 -07:00
|
|
|
eina_spinlock_new(&_eina_spinlock);
|
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
return EINA_TRUE;
|
2009-06-27 23:29:11 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
init_error:
|
2009-09-03 19:11:44 -07:00
|
|
|
eina_log_domain_unregister(_eina_rectangle_log_dom);
|
|
|
|
_eina_rectangle_log_dom = -1;
|
2009-06-27 23:29:11 -07:00
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
return EINA_FALSE;
|
2009-06-27 23:29:11 -07:00
|
|
|
}
|
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
Eina_Bool
|
2009-06-27 23:29:11 -07:00
|
|
|
eina_rectangle_shutdown(void)
|
|
|
|
{
|
2009-08-18 06:35:33 -07:00
|
|
|
Eina_Rectangle *del;
|
|
|
|
|
2016-04-25 12:48:08 -07:00
|
|
|
eina_spinlock_free(&_eina_spinlock);
|
2009-08-23 13:37:17 -07:00
|
|
|
while ((del = eina_trash_pop(&_eina_rectangles)))
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_mempool_free(_eina_rectangle_mp, del);
|
2009-08-18 06:35:33 -07:00
|
|
|
_eina_rectangles_count = 0;
|
|
|
|
|
2009-06-27 23:29:11 -07:00
|
|
|
eina_mempool_del(_eina_rectangle_alloc_mp);
|
|
|
|
eina_mempool_del(_eina_rectangle_mp);
|
|
|
|
|
2009-09-03 19:11:44 -07:00
|
|
|
eina_log_domain_unregister(_eina_rectangle_log_dom);
|
|
|
|
_eina_rectangle_log_dom = -1;
|
2009-06-27 23:29:11 -07:00
|
|
|
|
2009-09-06 15:21:56 -07:00
|
|
|
return EINA_TRUE;
|
2009-06-27 23:29:11 -07:00
|
|
|
}
|
|
|
|
|
2009-12-27 00:45:30 -08:00
|
|
|
/*============================================================================*
|
2010-07-27 19:37:05 -07:00
|
|
|
* API *
|
|
|
|
*============================================================================*/
|
2009-12-27 00:45:30 -08:00
|
|
|
|
2009-06-22 06:16:51 -07:00
|
|
|
EAPI Eina_Rectangle *
|
|
|
|
eina_rectangle_new(int x, int y, int w, int h)
|
|
|
|
{
|
2018-01-16 09:35:43 -08:00
|
|
|
Eina_Rectangle *rect = NULL;
|
2009-06-22 06:16:51 -07:00
|
|
|
|
2009-08-18 06:35:33 -07:00
|
|
|
if (_eina_rectangles)
|
|
|
|
{
|
2016-04-25 12:48:08 -07:00
|
|
|
eina_spinlock_take(&_eina_spinlock);
|
2010-07-27 19:37:05 -07:00
|
|
|
rect = eina_trash_pop(&_eina_rectangles);
|
|
|
|
_eina_rectangles_count--;
|
2018-01-16 09:35:43 -08:00
|
|
|
eina_spinlock_release(&_eina_spinlock);
|
2009-08-18 06:35:33 -07:00
|
|
|
}
|
2010-07-27 19:37:05 -07:00
|
|
|
|
|
|
|
if (!rect)
|
2018-01-16 09:35:43 -08:00
|
|
|
rect = eina_mempool_malloc(_eina_rectangle_mp, sizeof (Eina_Rectangle));
|
|
|
|
|
|
|
|
if (!rect)
|
|
|
|
return NULL;
|
2009-06-22 06:16:51 -07:00
|
|
|
|
|
|
|
EINA_RECTANGLE_SET(rect, x, y, w, h);
|
|
|
|
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
eina_rectangle_free(Eina_Rectangle *rect)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(rect);
|
2009-08-18 06:35:33 -07:00
|
|
|
|
|
|
|
if (_eina_rectangles_count > BUCKET_THRESHOLD)
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_mempool_free(_eina_rectangle_mp, rect);
|
2009-08-18 06:35:33 -07:00
|
|
|
else
|
|
|
|
{
|
2016-04-25 12:48:08 -07:00
|
|
|
eina_spinlock_take(&_eina_spinlock);
|
2010-07-27 19:37:05 -07:00
|
|
|
eina_trash_push(&_eina_rectangles, rect);
|
|
|
|
_eina_rectangles_count++;
|
2018-01-16 09:35:43 -08:00
|
|
|
eina_spinlock_release(&_eina_spinlock);
|
2009-08-18 06:35:33 -07:00
|
|
|
}
|
2009-06-22 06:16:51 -07:00
|
|
|
}
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
EAPI Eina_Rectangle_Pool *
|
2009-06-22 06:16:51 -07:00
|
|
|
eina_rectangle_pool_new(int w, int h)
|
2008-10-27 13:24:12 -07:00
|
|
|
{
|
|
|
|
Eina_Rectangle_Pool *new;
|
|
|
|
|
2012-09-12 00:33:36 -07:00
|
|
|
if ((w <= 0) || (h <= 0))
|
|
|
|
return NULL;
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
new = malloc(sizeof (Eina_Rectangle_Pool));
|
2010-07-27 19:37:05 -07:00
|
|
|
if (!new)
|
|
|
|
return NULL;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
|
|
|
new->head = NULL;
|
2009-06-22 06:46:05 -07:00
|
|
|
new->empty = eina_list_append(NULL, eina_rectangle_new(0, 0, w, h));
|
2008-10-27 13:24:12 -07:00
|
|
|
new->references = 0;
|
2009-08-05 07:46:21 -07:00
|
|
|
new->sorted = EINA_FALSE;
|
2008-10-27 13:24:12 -07:00
|
|
|
new->w = w;
|
|
|
|
new->h = h;
|
2009-08-18 06:35:33 -07:00
|
|
|
new->bucket = NULL;
|
|
|
|
new->bucket_count = 0;
|
2014-06-19 05:35:37 -07:00
|
|
|
new->eina_rectangle_compare_func = _eina_rectangle_cmp;
|
|
|
|
new->type = Eina_Packing_Ascending;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
|
|
|
EINA_MAGIC_SET(new, EINA_RECTANGLE_POOL_MAGIC);
|
2009-09-03 19:11:44 -07:00
|
|
|
DBG("pool=%p, size=(%d, %d)", new, w, h);
|
2008-10-27 13:24:12 -07:00
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2009-06-22 06:16:51 -07:00
|
|
|
eina_rectangle_pool_free(Eina_Rectangle_Pool *pool)
|
2008-10-27 13:24:12 -07:00
|
|
|
{
|
|
|
|
Eina_Rectangle_Alloc *del;
|
2014-06-19 05:35:37 -07:00
|
|
|
Eina_Rectangle *r;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(pool);
|
2009-09-03 19:11:44 -07:00
|
|
|
DBG("pool=%p, size=(%d, %d), references=%u",
|
|
|
|
pool, pool->w, pool->h, pool->references);
|
2014-06-20 01:12:03 -07:00
|
|
|
EINA_LIST_FREE(pool->empty, r)
|
|
|
|
eina_rectangle_free(r);
|
2008-10-27 13:24:12 -07:00
|
|
|
while (pool->head)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
del = (Eina_Rectangle_Alloc *)pool->head;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
pool->head = (EINA_INLIST_GET(del))->next;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
EINA_MAGIC_SET(del, EINA_MAGIC_NONE);
|
|
|
|
eina_mempool_free(_eina_rectangle_alloc_mp, del);
|
2008-10-27 13:24:12 -07:00
|
|
|
}
|
|
|
|
|
2009-08-18 06:35:33 -07:00
|
|
|
while (pool->bucket)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
del = eina_trash_pop(&pool->bucket);
|
|
|
|
eina_mempool_free(_eina_rectangle_alloc_mp, del);
|
2009-08-18 06:35:33 -07:00
|
|
|
}
|
|
|
|
|
2016-04-25 12:48:08 -07:00
|
|
|
MAGIC_FREE(pool);
|
2008-10-27 13:24:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
eina_rectangle_pool_count(Eina_Rectangle_Pool *pool)
|
|
|
|
{
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pool, 0);
|
2008-10-27 13:24:12 -07:00
|
|
|
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;
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL);
|
|
|
|
|
2009-09-03 19:11:44 -07:00
|
|
|
DBG("pool=%p, size=(%d, %d), references=%u",
|
|
|
|
pool, pool->w, pool->h, pool->references);
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
if (w <= 0 || h <= 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (w > pool->w || h > pool->h)
|
|
|
|
return NULL;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
/* Sort empty if dirty */
|
2014-02-13 17:01:30 -08:00
|
|
|
if (!pool->sorted)
|
2009-06-24 06:38:25 -07:00
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
pool->empty =
|
2014-06-19 05:35:37 -07:00
|
|
|
eina_list_sort(pool->empty, 0, pool->eina_rectangle_compare_func);
|
2010-07-27 19:37:05 -07:00
|
|
|
pool->sorted = EINA_TRUE;
|
2009-06-24 06:38:25 -07:00
|
|
|
}
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
if (pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
|
|
|
pool->empty = _eina_rectangle_skyline_list_update_duplicate(pool->empty);
|
|
|
|
pool->empty = _eina_rectangle_empty_space_find(pool->empty, pool->type, w, h, &x, &y);
|
2010-07-27 19:37:05 -07:00
|
|
|
if (x == -1)
|
|
|
|
return NULL;
|
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
pool->sorted = EINA_FALSE;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2009-08-18 06:35:33 -07:00
|
|
|
if (pool->bucket_count > 0)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
new = eina_trash_pop(&pool->bucket);
|
|
|
|
pool->bucket_count--;
|
2009-08-18 06:35:33 -07:00
|
|
|
}
|
|
|
|
else
|
2010-07-27 19:37:05 -07:00
|
|
|
new = eina_mempool_malloc(_eina_rectangle_alloc_mp,
|
|
|
|
sizeof (Eina_Rectangle_Alloc) +
|
|
|
|
sizeof (Eina_Rectangle));
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
if (!new)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
rect = (Eina_Rectangle *)(new + 1);
|
2008-10-27 13:24:12 -07:00
|
|
|
eina_rectangle_coords_from(rect, x, y, w, h);
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
if (pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
|
|
|
pool->empty = _eina_rectangle_skyline_list_update(pool->empty, rect);
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
pool->head = eina_inlist_prepend(pool->head, EINA_INLIST_GET(new));
|
|
|
|
pool->references++;
|
|
|
|
|
|
|
|
new->pool = pool;
|
|
|
|
|
|
|
|
EINA_MAGIC_SET(new, EINA_RECTANGLE_ALLOC_MAGIC);
|
2009-09-03 19:11:44 -07:00
|
|
|
DBG("rect=%p pool=%p, size=(%d, %d), references=%u",
|
|
|
|
rect, pool, pool->w, pool->h, pool->references);
|
2008-10-27 13:24:12 -07:00
|
|
|
|
|
|
|
return rect;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
eina_rectangle_pool_release(Eina_Rectangle *rect)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1;
|
2014-06-19 05:35:37 -07:00
|
|
|
Eina_Rectangle_Alloc *new;
|
2009-06-24 06:38:25 -07:00
|
|
|
Eina_Rectangle *r;
|
2014-06-19 05:35:37 -07:00
|
|
|
Eina_Rectangle *match;
|
2008-10-27 13:24:12 -07:00
|
|
|
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(rect);
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era);
|
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool);
|
|
|
|
|
2009-09-03 19:11:44 -07:00
|
|
|
DBG("rect=%p pool=%p, size=(%d, %d), references=%u",
|
|
|
|
rect, era->pool, era->pool->w, era->pool->h, era->pool->references);
|
|
|
|
|
2008-10-27 13:24:12 -07:00
|
|
|
era->pool->references--;
|
|
|
|
era->pool->head = eina_inlist_remove(era->pool->head, EINA_INLIST_GET(era));
|
|
|
|
|
2009-06-24 06:38:25 -07:00
|
|
|
r = eina_rectangle_new(rect->x, rect->y, rect->w, rect->h);
|
|
|
|
if (r)
|
|
|
|
{
|
2014-06-19 05:35:37 -07:00
|
|
|
if (era->pool->type == Eina_Packing_Bottom_Left_Skyline_Improved)
|
|
|
|
{
|
|
|
|
era->pool->empty = _eina_rectangle_skyline_merge_list(era->pool->empty, r);
|
|
|
|
era->pool->empty = _eina_rectangle_skyline_list_update_duplicate(era->pool->empty);
|
|
|
|
EINA_INLIST_FOREACH(era->pool->head, new)
|
|
|
|
{
|
|
|
|
match =(Eina_Rectangle *) (new + 1);
|
|
|
|
if (match)
|
|
|
|
era->pool->empty = _eina_rectangle_skyline_list_update(era->pool->empty, match);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
era->pool->empty = _eina_rectangle_merge_list(era->pool->empty, era->pool->type, r);
|
|
|
|
era->pool->sorted = EINA_FALSE;
|
2009-06-24 06:38:25 -07:00
|
|
|
}
|
|
|
|
|
2009-08-18 06:35:33 -07:00
|
|
|
if (era->pool->bucket_count < BUCKET_THRESHOLD)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
Eina_Rectangle_Pool *pool;
|
2009-08-18 06:35:33 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
pool = era->pool;
|
2009-08-18 06:35:33 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
pool->bucket_count++;
|
|
|
|
eina_trash_push(&pool->bucket, era);
|
2009-08-18 06:35:33 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
EINA_MAGIC_SET(era, EINA_MAGIC_NONE);
|
|
|
|
eina_mempool_free(_eina_rectangle_alloc_mp, era);
|
2009-08-18 06:35:33 -07:00
|
|
|
}
|
2008-10-27 13:24:12 -07:00
|
|
|
}
|
|
|
|
|
2008-10-28 08:28:46 -07:00
|
|
|
EAPI Eina_Rectangle_Pool *
|
|
|
|
eina_rectangle_pool_get(Eina_Rectangle *rect)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
Eina_Rectangle_Alloc *era = ((Eina_Rectangle_Alloc *)rect) - 1;
|
2008-10-28 08:28:46 -07:00
|
|
|
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(rect, NULL);
|
2008-10-28 08:28:46 -07:00
|
|
|
|
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_ALLOC(era);
|
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_POOL(era->pool);
|
|
|
|
|
|
|
|
return era->pool;
|
|
|
|
}
|
|
|
|
|
2014-06-19 05:35:37 -07:00
|
|
|
EAPI void
|
|
|
|
eina_rectangle_pool_packing_set(Eina_Rectangle_Pool *pool, Eina_Rectangle_Packing type)
|
|
|
|
{
|
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_POOL(pool);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(pool);
|
|
|
|
|
|
|
|
DBG("type=%d pool=%p, size=(%d, %d), references=%u",
|
|
|
|
type, pool, pool->w, pool->h, pool->references);
|
|
|
|
pool->type =type;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case Eina_Packing_Ascending:
|
|
|
|
pool->eina_rectangle_compare_func = _eina_rectangle_cmp_asc;
|
|
|
|
break;
|
|
|
|
case Eina_Packing_Descending:
|
|
|
|
pool->eina_rectangle_compare_func = _eina_rectangle_cmp;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pool->eina_rectangle_compare_func = _eina_rectangle_cmp_bl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-28 08:28:46 -07:00
|
|
|
EAPI void
|
|
|
|
eina_rectangle_pool_data_set(Eina_Rectangle_Pool *pool, const void *data)
|
|
|
|
{
|
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_POOL(pool);
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(pool);
|
2008-10-28 08:28:46 -07:00
|
|
|
|
2009-09-03 19:11:44 -07:00
|
|
|
DBG("data=%p pool=%p, size=(%d, %d), references=%u",
|
|
|
|
data, pool, pool->w, pool->h, pool->references);
|
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
pool->data = (void *)data;
|
2008-10-28 08:28:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void *
|
|
|
|
eina_rectangle_pool_data_get(Eina_Rectangle_Pool *pool)
|
|
|
|
{
|
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_POOL(pool);
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pool, NULL);
|
2008-10-28 08:28:46 -07:00
|
|
|
|
|
|
|
return pool->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
eina_rectangle_pool_geometry_get(Eina_Rectangle_Pool *pool, int *w, int *h)
|
|
|
|
{
|
2010-07-27 19:37:05 -07:00
|
|
|
if (!pool)
|
|
|
|
return EINA_FALSE;
|
2008-10-28 08:28:46 -07:00
|
|
|
|
|
|
|
EINA_MAGIC_CHECK_RECTANGLE_POOL(pool);
|
2008-12-26 10:31:14 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(pool, EINA_FALSE);
|
2008-10-28 08:28:46 -07:00
|
|
|
|
2010-07-27 19:37:05 -07:00
|
|
|
if (w)
|
|
|
|
*w = pool->w;
|
|
|
|
|
|
|
|
if (h)
|
|
|
|
*h = pool->h;
|
2008-10-28 08:28:46 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2016-12-20 16:04:29 -08:00
|
|
|
|
|
|
|
EAPI Eina_Rectangle_Outside
|
|
|
|
eina_rectangle_outside_position(Eina_Rectangle *rect1, Eina_Rectangle *rect2)
|
|
|
|
{
|
|
|
|
Eina_Rectangle_Outside ret = 0;
|
|
|
|
|
|
|
|
if (rect1->y > rect2->y)
|
|
|
|
ret |= EINA_RECTANGLE_OUTSIDE_TOP;
|
|
|
|
if (rect1->x > rect2->x)
|
|
|
|
ret |= EINA_RECTANGLE_OUTSIDE_LEFT;
|
|
|
|
if (rect1->y + rect1->h < rect2->y + rect2->h)
|
|
|
|
ret |= EINA_RECTANGLE_OUTSIDE_BOTTOM;
|
|
|
|
if (rect1->x + rect1->w < rect2->x + rect2->w)
|
|
|
|
ret |= EINA_RECTANGLE_OUTSIDE_RIGHT;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|