eina: add a substraction in rectangles and more helpers

Also add functions to cut a rectangle in the different
lengths/coordinates.
Add helper macros to printf a rectangle
This commit is contained in:
Jorge Zapata 2013-09-23 21:13:52 +02:00 committed by Cedric Bail
parent e5231de7eb
commit b98ee971f3
2 changed files with 148 additions and 0 deletions

View File

@ -247,6 +247,144 @@ eina_rectangle_rescale_out(const Eina_Rectangle *out, const Eina_Rectangle *in,
res->h = out->h;
}
static inline Eina_Bool
eina_rectangle_is_valid(const Eina_Rectangle *r)
{
if (r->w <= 0 || r->h <= 0)
return EINA_FALSE;
return EINA_TRUE;
}
static inline int
eina_rectangle_max_x(Eina_Rectangle *thiz)
{
return thiz->x + thiz->w;
}
static inline int
eina_rectangle_max_y(Eina_Rectangle *thiz)
{
return thiz->y + thiz->h;
}
static inline Eina_Bool
eina_rectangle_x_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *leftover, int amount)
{
Eina_Rectangle tmp1, tmp2;
if (amount > thiz->w)
return EINA_FALSE;
eina_rectangle_coords_from(&tmp1, thiz->x, thiz->y, amount, thiz->h);
eina_rectangle_coords_from(&tmp2, thiz->x + amount, thiz->y, thiz->w - amount, thiz->h);
if (slice) *slice = tmp1;
if (leftover) *leftover = tmp2;
return EINA_TRUE;
}
static inline Eina_Bool
eina_rectangle_y_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *leftover, int amount)
{
Eina_Rectangle tmp1, tmp2;
if (amount > thiz->h)
return EINA_FALSE;
eina_rectangle_coords_from(&tmp1, thiz->x, thiz->y, thiz->w, amount);
eina_rectangle_coords_from(&tmp2, thiz->x, thiz->y + amount, thiz->w, thiz->h - amount);
if (slice) *slice = tmp1;
if (leftover) *leftover = tmp2;
return EINA_TRUE;
}
static inline Eina_Bool
eina_rectangle_width_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *leftover, int amount)
{
Eina_Rectangle tmp1, tmp2;
if (thiz->w - amount < 0)
return EINA_FALSE;
eina_rectangle_coords_from(&tmp1, thiz->x + (thiz->w - amount), thiz->y, amount, thiz->h);
eina_rectangle_coords_from(&tmp2, thiz->x, thiz->y, thiz->w - amount, thiz->h);
if (slice) *slice = tmp1;
if (leftover) *leftover = tmp2;
return EINA_TRUE;
}
static inline Eina_Bool
eina_rectangle_height_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *leftover, int amount)
{
Eina_Rectangle tmp1, tmp2;
if (thiz->h - amount < 0)
return EINA_FALSE;
eina_rectangle_coords_from(&tmp1, thiz->x, thiz->y + (thiz->h - amount), thiz->w, amount);
eina_rectangle_coords_from(&tmp2, thiz->x, thiz->y, thiz->w, thiz->h - amount);
if (slice) *slice = tmp1;
if (leftover) *leftover = tmp2;
return EINA_TRUE;
}
/**
* @brief Subtract two rectangles.
*
* @param thiz The minuend rectangle
* @param src The subtrahend rectangle
*
* This function subtract two rectangles. The difference is stored on @p out
* There will be at most four differences, use eina_rectangle_is_valid to
* confirm the number of differences.
*/
static inline Eina_Bool
eina_rectangle_subtract(Eina_Rectangle *thiz, Eina_Rectangle *other, Eina_Rectangle out[4])
{
Eina_Rectangle intersection;
Eina_Rectangle leftover = EINA_RECTANGLE_INIT;
Eina_Rectangle tmp;
int cut = 0;
if (!eina_rectangle_is_valid(thiz))
return EINA_FALSE;
eina_rectangle_coords_from(&out[0], 0, 0, 0, 0);
eina_rectangle_coords_from(&out[1], 0, 0, 0, 0);
eina_rectangle_coords_from(&out[2], 0, 0, 0, 0);
eina_rectangle_coords_from(&out[3], 0, 0, 0, 0);
intersection = *thiz;
if (!eina_rectangle_intersection(&intersection, other))
{
out[0] = *thiz;
return EINA_TRUE;
}
/* cut in height */
{
cut = thiz->h - (intersection.y - thiz->y);
if (cut > thiz->h) { cut = thiz->h; }
eina_rectangle_height_cut(thiz, &leftover, &out[0], cut);
}
/* cut in y */
tmp = leftover;
if (eina_rectangle_intersection(&tmp, &intersection))
{
cut = leftover.h - (eina_rectangle_max_y(&leftover) - eina_rectangle_max_y(&tmp));
if (cut > leftover.h) { cut = leftover.h; }
eina_rectangle_y_cut(&leftover, &leftover, &out[1], cut);
}
/* cut in width */
tmp = leftover;
if (eina_rectangle_intersection(&tmp, &intersection))
{
cut = leftover.w - (tmp.x - leftover.x);
if (cut > leftover.w) { cut = leftover.w; }
eina_rectangle_width_cut(&leftover, &leftover, &out[2], cut);
}
/* cut in x */
tmp = leftover;
if (eina_rectangle_intersection(&tmp, &intersection))
{
cut = leftover.w - (eina_rectangle_max_x(&leftover) - eina_rectangle_max_x(&tmp));
if (cut > leftover.w) { cut = leftover.w; }
eina_rectangle_x_cut(&leftover, &leftover, &out[3], cut);
}
return EINA_TRUE;
}
/**
* @}
*/

View File

@ -39,6 +39,10 @@
* @{
*/
#define EINA_RECTANGLE_INIT { 0, 0, 0, 0}
#define EINA_RECTANGLE_FORMAT "dx%d - %dx%d"
#define EINA_RECTANGLE_ARGS(r) (r)->x, (r)->y, (r)->w, (r)->h
/**
* @typedef Eina_Rectangle
* Simple rectangle structure.
@ -68,6 +72,12 @@ static inline void eina_rectangle_union(Eina_Rectangle *dst, const Eina_R
static inline Eina_Bool eina_rectangle_intersection(Eina_Rectangle *dst, const Eina_Rectangle *src) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
static inline void eina_rectangle_rescale_in(const Eina_Rectangle *out, const Eina_Rectangle *in, Eina_Rectangle *res) EINA_ARG_NONNULL(1, 2, 3);
static inline void eina_rectangle_rescale_out(const Eina_Rectangle *out, const Eina_Rectangle *in, Eina_Rectangle *res) EINA_ARG_NONNULL(1, 2, 3);
static inline Eina_Bool eina_rectangle_is_valid(const Eina_Rectangle *r) EINA_ARG_NONNULL(1);
static inline Eina_Bool eina_rectangle_x_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *remainder, int amount) EINA_ARG_NONNULL(1);
static inline Eina_Bool eina_rectangle_y_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *remainder, int amount) EINA_ARG_NONNULL(1);
static inline Eina_Bool eina_rectangle_width_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *remainder, int amount) EINA_ARG_NONNULL(1);
static inline Eina_Bool eina_rectangle_height_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rectangle *remainder, int amount) EINA_ARG_NONNULL(1);
static inline Eina_Bool eina_rectangle_subtract(Eina_Rectangle *thiz, Eina_Rectangle *other, Eina_Rectangle out[4]) EINA_ARG_NONNULL(1);
/**