forked from enlightenment/efl
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:
parent
e5231de7eb
commit
b98ee971f3
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue