BLI_rct: Utilities for sanitizing coordinates (ensuring min <= max)
authorJulian Eisel <eiseljulian@gmail.com>
Tue, 14 Jan 2020 15:18:41 +0000 (16:18 +0100)
committerJulian Eisel <eiseljulian@gmail.com>
Tue, 14 Jan 2020 15:30:38 +0000 (16:30 +0100)
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
source/blender/blenlib/intern/rct.c

index e3cd70f741309c48a499df2dbd3a48804853147b..fdb4fe30f1cd55d77fe41b159070a9c15d5e7195 100644 (file)
@@ -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);
index ecff2ebffef0f10db1b778d38e4d86ce685878c6..5fb33072231902b0973ad79958d506acda63d656 100644 (file)
@@ -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;