cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=b98ee971f3b139b94a09c136ff2a6f709067d594
commit b98ee971f3b139b94a09c136ff2a6f709067d594 Author: Jorge Zapata <jorgeluis.zap...@gmail.com> Date: Mon Sep 23 21:13:52 2013 +0200 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 --- src/lib/eina/eina_inline_rectangle.x | 138 +++++++++++++++++++++++++++++++++++ src/lib/eina/eina_rectangle.h | 10 +++ 2 files changed, 148 insertions(+) diff --git a/src/lib/eina/eina_inline_rectangle.x b/src/lib/eina/eina_inline_rectangle.x index dbd7f11..42a87f8 100644 --- a/src/lib/eina/eina_inline_rectangle.x +++ b/src/lib/eina/eina_inline_rectangle.x @@ -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; +} + /** * @} */ diff --git a/src/lib/eina/eina_rectangle.h b/src/lib/eina/eina_rectangle.h index c8dd388..d3e2443 100644 --- a/src/lib/eina/eina_rectangle.h +++ b/src/lib/eina/eina_rectangle.h @@ -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); /** --