[gegl] buffer: add gegl_rectangle_align[_to_buffer]()
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] buffer: add gegl_rectangle_align[_to_buffer]()
- Date: Mon, 29 Jul 2019 20:19:16 +0000 (UTC)
commit 8776cd17e49071fdc01d3ddcb874bb023dd93e1f
Author: Ell <ell_se yahoo com>
Date: Mon Jul 29 22:16:13 2019 +0300
buffer: add gegl_rectangle_align[_to_buffer]()
... which align a rectangle to a regular tile grid, specified
either using a representative tile rect, or using a GeglBuffer.
The result can be either the biggest aligned subset of, the
smallest aligned superset of, or the nearest aligned rectangle to
the input.
gegl/buffer/gegl-buffer-enums.c | 26 +++++++++++
gegl/buffer/gegl-buffer-enums.h | 10 +++++
gegl/buffer/gegl-rectangle.c | 97 +++++++++++++++++++++++++++++++++++++++++
gegl/buffer/gegl-rectangle.h | 51 ++++++++++++++++++++++
4 files changed, 184 insertions(+)
---
diff --git a/gegl/buffer/gegl-buffer-enums.c b/gegl/buffer/gegl-buffer-enums.c
index 1dfcbf6f3..9b3113758 100644
--- a/gegl/buffer/gegl-buffer-enums.c
+++ b/gegl/buffer/gegl-buffer-enums.c
@@ -105,3 +105,29 @@ gegl_sampler_type_get_type (void)
return etype;
}
+
+GType
+gegl_rectangle_alignment_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0)
+ {
+ static GEnumValue values[] = {
+ { GEGL_RECTANGLE_ALIGNMENT_SUBSET, N_("Subset"), "subset" },
+ { GEGL_RECTANGLE_ALIGNMENT_SUPERSET, N_("Superset"), "superset" },
+ { GEGL_RECTANGLE_ALIGNMENT_NEAREST, N_("Nesrest"), "nesrest" },
+ { 0, NULL, NULL }
+ };
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (values); i++)
+ if (values[i].value_name)
+ values[i].value_name =
+ dgettext (GETTEXT_PACKAGE, values[i].value_name);
+
+ etype = g_enum_register_static ("GeglRectangleAlignment", values);
+ }
+
+ return etype;
+}
diff --git a/gegl/buffer/gegl-buffer-enums.h b/gegl/buffer/gegl-buffer-enums.h
index aa110c6dd..0f756dc6a 100644
--- a/gegl/buffer/gegl-buffer-enums.h
+++ b/gegl/buffer/gegl-buffer-enums.h
@@ -87,6 +87,16 @@ GType gegl_sampler_type_get_type (void) G_GNUC_CONST;
#define GEGL_TYPE_SAMPLER_TYPE (gegl_sampler_type_get_type ())
+typedef enum {
+ GEGL_RECTANGLE_ALIGNMENT_SUBSET,
+ GEGL_RECTANGLE_ALIGNMENT_SUPERSET,
+ GEGL_RECTANGLE_ALIGNMENT_NEAREST
+} GeglRectangleAlignment;
+
+GType gegl_rectangle_alignment_get_type (void) G_GNUC_CONST;
+
+#define GEGL_TYPE_RECTANGLE_ALIGNMENT (gegl_rectangle_alignment_get_type ())
+
G_END_DECLS
#endif /* __GEGL_ENUMS_H__ */
diff --git a/gegl/buffer/gegl-rectangle.c b/gegl/buffer/gegl-rectangle.c
index dde4c8fc5..99e69da3e 100644
--- a/gegl/buffer/gegl-rectangle.c
+++ b/gegl/buffer/gegl-rectangle.c
@@ -21,6 +21,7 @@
#include <string.h>
#include <glib-object.h>
#include "gegl-buffer.h"
+#include "gegl-buffer-private.h"
#include "gegl-rectangle.h"
GeglRectangle *
@@ -52,6 +53,102 @@ gegl_rectangle_set (GeglRectangle *r,
r->height = h;
}
+gboolean
+gegl_rectangle_align (GeglRectangle *dest,
+ const GeglRectangle *rectangle,
+ const GeglRectangle *tile,
+ GeglRectangleAlignment alignment)
+{
+ gint x1, x2;
+ gint y1, y2;
+
+ x1 = rectangle->x - tile->x;
+ x2 = x1 + rectangle->width;
+
+ y1 = rectangle->y - tile->y;
+ y2 = y1 + rectangle->height;
+
+ switch (alignment)
+ {
+ case GEGL_RECTANGLE_ALIGNMENT_SUBSET:
+ if (x1 > 0) x1 += tile->width - 1;
+ if (x2 < 0) x2 -= tile->width - 1;
+
+ if (y1 > 0) y1 += tile->height - 1;
+ if (y2 < 0) y2 -= tile->height - 1;
+
+ break;
+
+ case GEGL_RECTANGLE_ALIGNMENT_SUPERSET:
+ if (x1 < 0) x1 -= tile->width - 1;
+ if (x2 > 0) x2 += tile->width - 1;
+
+ if (y1 < 0) y1 -= tile->height - 1;
+ if (y2 > 0) y2 += tile->height - 1;
+
+ break;
+
+ case GEGL_RECTANGLE_ALIGNMENT_NEAREST:
+ if (x1 > 0) x1 += tile->width / 2;
+ else x1 -= tile->width / 2;
+ if (x2 > 0) x2 += tile->width / 2;
+ else x2 -= tile->width / 2;
+
+ if (y1 > 0) y1 += tile->height / 2;
+ else y1 -= tile->height / 2;
+ if (y2 > 0) y2 += tile->height / 2;
+ else y2 -= tile->height / 2;
+
+ break;
+ }
+
+ if (tile->width)
+ {
+ x1 = x1 / tile->width * tile->width;
+ x2 = x2 / tile->width * tile->width;
+ }
+ if (tile->height)
+ {
+ y1 = y1 / tile->height * tile->height;
+ y2 = y2 / tile->height * tile->height;
+ }
+
+ if (x1 > x2 && y1 > y2)
+ {
+ if (dest)
+ {
+ gegl_rectangle_set (dest,
+ tile->x + x1,
+ tile->y + y1,
+ x2 - x1,
+ y2 - y1);
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ if (dest)
+ gegl_rectangle_set (dest, 0, 0, 0, 0);
+
+ return FALSE;
+ }
+}
+
+gboolean
+gegl_rectangle_align_to_buffer (GeglRectangle *dest,
+ const GeglRectangle *rectangle,
+ GeglBuffer *buffer,
+ GeglRectangleAlignment alignment)
+{
+ return gegl_rectangle_align (dest, rectangle,
+ GEGL_RECTANGLE (buffer->shift_x,
+ buffer->shift_y,
+ buffer->tile_width,
+ buffer->tile_height),
+ alignment);
+}
+
void
gegl_rectangle_bounding_box (GeglRectangle *dest,
const GeglRectangle *src1,
diff --git a/gegl/buffer/gegl-rectangle.h b/gegl/buffer/gegl-rectangle.h
index 36174cba7..7e164c1c9 100644
--- a/gegl/buffer/gegl-rectangle.h
+++ b/gegl/buffer/gegl-rectangle.h
@@ -156,6 +156,57 @@ GeglRectangle *gegl_rectangle_dup (const GeglRectangle *rectangle);
void gegl_rectangle_copy (GeglRectangle *destination,
const GeglRectangle *source);
+/**
+ * gegl_rectangle_align:
+ * @destination: a #GeglRectangle
+ * @rectangle: a #GeglRectangle
+ * @tile: a #GeglRectangle
+ * @alignment: a #GeglRectangleAlignment value
+ *
+ * Aligns @rectangle to a regular tile grid, of which @tile is a representative
+ * tile, and stores the result in @destination.
+ *
+ * @alignment can be one of:
+ *
+ * GEGL_RECTANGLE_ALIGNMENT_SUBSET: Calculate the biggest aligned rectangle
+ * contained in @rectangle.
+ *
+ * GEGL_RECTANGLE_ALIGNMENT_SUPERSET: Calculate the smallest aligned
+ * rectangle containing @rectangle.
+ *
+ * GEGL_RECTANGLE_ALIGNMENT_NEAREST: Calculate the nearest aligned rectangle
+ * to @rectangle.
+ *
+ * @destination may point to the same object as @rectangle or @tile.
+ *
+ * Returns TRUE if the result is not empty.
+ */
+gboolean gegl_rectangle_align (GeglRectangle *destination,
+ const GeglRectangle *rectangle,
+ const GeglRectangle *tile,
+ GeglRectangleAlignment alignment);
+
+/**
+ * gegl_rectangle_align_to_buffer:
+ * @destination: a #GeglRectangle
+ * @rectangle: a #GeglRectangle
+ * @buffer: a #GeglBuffer
+ * @alignment: a #GeglRectangleAlignment value
+ *
+ * Aligns @rectangle to the tile grid of @buffer, and stores the result in
+ * @destination.
+ *
+ * @alignment has the same meaning as for gegl_rectangle_align().
+ *
+ * @destination may point to the same object as @rectangle.
+ *
+ * Returns TRUE if the result is not empty.
+ */
+gboolean gegl_rectangle_align_to_buffer (GeglRectangle *destination,
+ const GeglRectangle *rectangle,
+ GeglBuffer *buffer,
+ GeglRectangleAlignment alignment);
+
/**
* gegl_rectangle_bounding_box:
* @destination: a #GeglRectangle
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]