From 388d43d85a5d9dfc5261848c91c12dd883ea1f59 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 14 Jan 2020 16:18:41 +0100 Subject: [PATCH] BLI_rct: Utilities for sanitizing coordinates (ensuring min <= max) This might be useful in some places. Much of the code makes the implicit assumption that the rectangle has valid coordinate order, good to make it more explicit. --- source/blender/blenlib/BLI_rect.h | 4 +++ source/blender/blenlib/intern/rct.c | 44 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index e3cd70f7413..fdb4fe30f1c 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -39,6 +39,10 @@ bool BLI_rcti_is_empty(const struct rcti *rect); bool BLI_rctf_is_empty(const struct rctf *rect); void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax); void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax); +bool BLI_rctf_is_valid(const struct rctf *rect); +bool BLI_rcti_is_valid(const struct rcti *rect); +void BLI_rctf_sanitize(struct rctf *rect); +void BLI_rcti_sanitize(struct rcti *rect); void BLI_rctf_init_pt_radius(struct rctf *rect, const float xy[2], float size); void BLI_rcti_init_pt_radius(struct rcti *rect, const int xy[2], int size); void BLI_rcti_init_minmax(struct rcti *rect); diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index ecff2ebffef..5fb33072231 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -477,6 +477,50 @@ void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax) } } +/** + * Check if X-min and Y-min are less than or equal to X-max and Y-max, respectively. + * If this returns false, #BLI_rctf_sanitize() can be called to address this. + * + * This is not a hard constraint or invariant for rectangles, in some cases it may be useful to + * have max < min. Usually this is what you'd want though. + */ +bool BLI_rctf_is_valid(const rctf *rect) +{ + return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax); +} + +bool BLI_rcti_is_valid(const rcti *rect) +{ + return (rect->xmin <= rect->xmax) && (rect->ymin <= rect->ymax); +} + +/** + * Ensure X-min and Y-min are less than or equal to X-max and Y-max, respectively. + */ +void BLI_rctf_sanitize(rctf *rect) +{ + if (rect->xmin > rect->xmax) { + SWAP(float, rect->xmin, rect->xmax); + } + if (rect->ymin > rect->ymax) { + SWAP(float, rect->ymin, rect->ymax); + } + + BLI_assert(BLI_rctf_is_valid(rect)); +} + +void BLI_rcti_sanitize(rcti *rect) +{ + if (rect->xmin > rect->xmax) { + SWAP(int, rect->xmin, rect->xmax); + } + if (rect->ymin > rect->ymax) { + SWAP(int, rect->ymin, rect->ymax); + } + + BLI_assert(BLI_rcti_is_valid(rect)); +} + void BLI_rctf_init_pt_radius(rctf *rect, const float xy[2], float size) { rect->xmin = xy[0] - size;