]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[libply] Add new rectangle type
authorRay Strode <rstrode@redhat.com>
Thu, 20 Aug 2009 03:55:43 +0000 (23:55 -0400)
committerRay Strode <rstrode@redhat.com>
Mon, 28 Sep 2009 15:23:35 +0000 (11:23 -0400)
Previously we were using ply_frame_buffer_area_t even
when not dealing with a frame buffer area.

This commit adds a new general purpose rectangle type
to replace ply_frame_buffer_area_t.  It has some
convenience functions for operating on rectangles as well.

src/libply/Makefile.am
src/libply/ply-rectangle.c [new file with mode: 0644]
src/libply/ply-rectangle.h [new file with mode: 0644]

index 5c9a8bdbddbce97ff8a96a9697eeacc23f788cdf..da145755adc9c58d2362d469119afc8cf7490518 100644 (file)
@@ -23,6 +23,7 @@ libply_HEADERS = \
                    ply-logger.h                                              \
                    ply-key-file.h                                            \
                    ply-progress.h                                            \
+                   ply-rectangle.h                                           \
                    ply-terminal-session.h                                    \
                    ply-trigger.h                                             \
                    ply-utils.h
@@ -44,6 +45,7 @@ libply_la_SOURCES = ply-event-loop.c                                          \
                    ply-logger.c                                              \
                    ply-key-file.c                                            \
                    ply-progress.c                                            \
+                   ply-rectangle.c                                           \
                    ply-terminal-session.c                                    \
                    ply-trigger.c                                             \
                    ply-utils.c
diff --git a/src/libply/ply-rectangle.c b/src/libply/ply-rectangle.c
new file mode 100644 (file)
index 0000000..2209393
--- /dev/null
@@ -0,0 +1,294 @@
+/* ply-rectangle.c
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * Based in part on some work by:
+ *  Copyright (C) 2009 Charlie Brej <cbrej@cs.man.ac.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
+ *             Ray Strode <rstrode@redhat.com>
+ */
+#include "config.h"
+#include "ply-list.h"
+#include "ply-rectangle.h"
+
+bool
+ply_rectangle_contains_point (ply_rectangle_t *rectangle,
+                              long             x,
+                              long             y)
+{
+  long top_edge;
+  long left_edge;
+  long right_edge;
+  long bottom_edge;
+
+  top_edge = rectangle->y;
+  left_edge = rectangle->x;
+  right_edge = rectangle->x + rectangle->width - 1;
+  bottom_edge = rectangle->y + rectangle->height - 1;
+
+  if (x < left_edge)
+    return false;
+
+  if (y < top_edge)
+    return false;
+
+  if (x > right_edge)
+    return false;
+
+  if (y > bottom_edge)
+    return false;
+
+  return true;
+}
+
+bool
+ply_rectangle_is_empty (ply_rectangle_t *rectangle)
+{
+  return rectangle->width == 0 || rectangle->height == 0;
+}
+
+ply_rectangle_overlap_t
+ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
+                            ply_rectangle_t *rectangle2)
+{
+  ply_rectangle_overlap_t overlap;
+
+  long rectangle1_top_edge;
+  long rectangle1_left_edge;
+  long rectangle1_right_edge;
+  long rectangle1_bottom_edge;
+  long rectangle2_top_edge;
+  long rectangle2_left_edge;
+  long rectangle2_right_edge;
+  long rectangle2_bottom_edge;
+
+  rectangle1_top_edge = rectangle1->y;
+  rectangle1_left_edge = rectangle1->x;
+  rectangle1_right_edge = rectangle1->x + rectangle1->width - 1;
+  rectangle1_bottom_edge = rectangle1->y + rectangle1->height - 1;
+
+  rectangle2_top_edge = rectangle2->y;
+  rectangle2_left_edge = rectangle2->x;
+  rectangle2_right_edge = rectangle2->x + rectangle2->width - 1;
+  rectangle2_bottom_edge = rectangle2->y + rectangle2->height - 1;
+
+  overlap = 0;
+
+  /* 1111111
+   * 1122211
+   * 1122211
+   * 1111111
+   */
+  if (ply_rectangle_contains_point (rectangle1,
+                                    rectangle2_left_edge,
+                                    rectangle2_top_edge) &&
+      ply_rectangle_contains_point (rectangle1,
+                                    rectangle2_right_edge,
+                                    rectangle2_bottom_edge))
+    return PLY_RECTANGLE_OVERLAP_NO_EDGES;
+
+  /* 2222222
+   * 2211122
+   * 2211122
+   * 2222222
+   */
+  if (ply_rectangle_contains_point (rectangle2,
+                                    rectangle1_left_edge,
+                                    rectangle1_top_edge) &&
+      ply_rectangle_contains_point (rectangle2,
+                                    rectangle1_right_edge,
+                                    rectangle1_bottom_edge))
+    return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
+
+  /* 1111111
+   * 11112222
+   * 11112222
+   * 1111111
+   */
+  if (ply_rectangle_contains_point (rectangle2,
+                                    rectangle1_right_edge,
+                                    rectangle2_top_edge) &&
+      ply_rectangle_contains_point (rectangle2,
+                                    rectangle1_right_edge,
+                                    rectangle2_bottom_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_RIGHT_EDGE;
+
+  /*   222222
+   * 11112222
+   * 11112222
+   *   222222
+   */
+  if (ply_rectangle_contains_point (rectangle1,
+                                    rectangle2_left_edge,
+                                    rectangle1_top_edge) &&
+      ply_rectangle_contains_point (rectangle1,
+                                    rectangle2_left_edge,
+                                    rectangle1_bottom_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_RIGHT_EDGE;
+
+  /*  1111111
+   * 22221111
+   * 22221111
+   *  1111111
+   */
+  if (ply_rectangle_contains_point (rectangle2,
+                                    rectangle1_left_edge,
+                                    rectangle2_top_edge) &&
+      ply_rectangle_contains_point (rectangle2,
+                                    rectangle1_left_edge,
+                                    rectangle2_bottom_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_LEFT_EDGE;
+
+  /* 222222
+   * 22221111
+   * 22221111
+   * 222222
+   */
+  if (ply_rectangle_contains_point (rectangle1,
+                                    rectangle2_right_edge,
+                                    rectangle1_top_edge) &&
+      ply_rectangle_contains_point (rectangle1,
+                                    rectangle2_right_edge,
+                                    rectangle1_bottom_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_LEFT_EDGE;
+
+  /*
+   *  2222
+   * 122221
+   * 111111
+   * 111111
+   */
+  if (ply_rectangle_contains_point (rectangle2,
+                                    rectangle2_left_edge,
+                                    rectangle1_top_edge) &&
+      ply_rectangle_contains_point (rectangle2,
+                                    rectangle2_right_edge,
+                                    rectangle1_top_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_TOP_EDGE;
+
+  /*
+   * 2222222
+   * 2211122
+   *   111
+   */
+  if (ply_rectangle_contains_point (rectangle1,
+                                    rectangle1_left_edge,
+                                    rectangle2_bottom_edge) &&
+      ply_rectangle_contains_point (rectangle1,
+                                    rectangle1_right_edge,
+                                    rectangle2_bottom_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_TOP_EDGE;
+
+  /*
+   * 111111
+   * 111111
+   * 122221
+   *  2222
+   */
+  if (ply_rectangle_contains_point (rectangle1,
+                                    rectangle1_left_edge,
+                                    rectangle2_top_edge) &&
+      ply_rectangle_contains_point (rectangle1,
+                                    rectangle1_right_edge,
+                                    rectangle2_top_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE;
+
+  /*
+   *   111
+   * 2211122
+   * 2222222
+   */
+  if (ply_rectangle_contains_point (rectangle2,
+                                    rectangle2_left_edge,
+                                    rectangle1_bottom_edge) &&
+      ply_rectangle_contains_point (rectangle2,
+                                    rectangle2_right_edge,
+                                    rectangle1_bottom_edge))
+    overlap |= PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE;
+
+  return overlap;
+}
+
+void
+ply_rectangle_intersect (ply_rectangle_t *rectangle1,
+                         ply_rectangle_t *rectangle2,
+                         ply_rectangle_t *result)
+{
+
+  long rectangle1_top_edge;
+  long rectangle1_left_edge;
+  long rectangle1_right_edge;
+  long rectangle1_bottom_edge;
+  long rectangle2_top_edge;
+  long rectangle2_left_edge;
+  long rectangle2_right_edge;
+  long rectangle2_bottom_edge;
+  long result_top_edge;
+  long result_left_edge;
+  long result_right_edge;
+  long result_bottom_edge;
+
+  if (ply_rectangle_is_empty (rectangle1))
+    {
+      *result = *rectangle1;
+      return;
+    }
+
+  if (ply_rectangle_is_empty (rectangle2))
+    {
+      *result = *rectangle2;
+      return;
+    }
+
+  rectangle1_top_edge = rectangle1->y;
+  rectangle1_left_edge = rectangle1->x;
+  rectangle1_right_edge = rectangle1->x + rectangle1->width - 1;
+  rectangle1_bottom_edge = rectangle1->y + rectangle1->height - 1;
+
+  rectangle2_top_edge = rectangle2->y;
+  rectangle2_left_edge = rectangle2->x;
+  rectangle2_right_edge = rectangle2->x + rectangle2->width - 1;
+  rectangle2_bottom_edge = rectangle2->y + rectangle2->height - 1;
+
+  result_top_edge = MAX (rectangle1_top_edge, rectangle2_top_edge);
+  result_left_edge = MAX (rectangle1_left_edge, rectangle2_left_edge);
+  result_right_edge = MIN (rectangle1_right_edge, rectangle2_right_edge);
+  result_bottom_edge = MIN (rectangle1_bottom_edge, rectangle2_bottom_edge);
+
+  result->x = result_left_edge;
+  result->y = result_top_edge;
+
+  if (result_right_edge >= result_left_edge)
+    result->width = result_right_edge - result_left_edge + 1;
+  else
+    result->width = 0;
+
+  if (result_bottom_edge >= result_top_edge)
+    result->height = result_bottom_edge - result_top_edge + 1;
+  else
+    result->height = 0;
+
+  if (ply_rectangle_is_empty (result))
+    {
+      result->width = 0;
+      result->height = 0;
+    }
+}
+
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/libply/ply-rectangle.h b/src/libply/ply-rectangle.h
new file mode 100644 (file)
index 0000000..bdbb6f4
--- /dev/null
@@ -0,0 +1,105 @@
+/* ply-rectangle.h
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written By: Ray Strode <rstrode@redhat.com>
+ */
+#ifndef PLY_RECTANGLE_H
+#define PLY_RECTANGLE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "ply-utils.h"
+
+typedef struct _ply_rectangle ply_rectangle_t;
+
+struct _ply_rectangle
+{
+  long x;
+  long y;
+  unsigned long width;
+  unsigned long height;
+};
+
+typedef enum
+{
+  PLY_RECTANGLE_OVERLAP_NONE                       = 0,
+  PLY_RECTANGLE_OVERLAP_TOP_EDGE                   = 1 << 0,
+  PLY_RECTANGLE_OVERLAP_LEFT_EDGE                  = 1 << 1,
+  PLY_RECTANGLE_OVERLAP_RIGHT_EDGE                 = 1 << 2,
+  PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE                = 1 << 3,
+  PLY_RECTANGLE_OVERLAP_TOP_AND_LEFT_EDGES         =
+      PLY_RECTANGLE_OVERLAP_TOP_EDGE |
+      PLY_RECTANGLE_OVERLAP_LEFT_EDGE,
+  PLY_RECTANGLE_OVERLAP_TOP_AND_RIGHT_EDGES        =
+      PLY_RECTANGLE_OVERLAP_TOP_EDGE |
+      PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
+  PLY_RECTANGLE_OVERLAP_TOP_AND_SIDE_EDGES         =
+      PLY_RECTANGLE_OVERLAP_TOP_EDGE  |
+      PLY_RECTANGLE_OVERLAP_LEFT_EDGE |
+      PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
+  PLY_RECTANGLE_OVERLAP_BOTTOM_AND_LEFT_EDGES      =
+      PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
+      PLY_RECTANGLE_OVERLAP_LEFT_EDGE,
+  PLY_RECTANGLE_OVERLAP_BOTTOM_AND_RIGHT_EDGES     =
+      PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
+      PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
+  PLY_RECTANGLE_OVERLAP_BOTTOM_AND_SIDE_EDGES      =
+      PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
+      PLY_RECTANGLE_OVERLAP_LEFT_EDGE   |
+      PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
+  PLY_RECTANGLE_OVERLAP_SIDE_EDGES                 =
+      PLY_RECTANGLE_OVERLAP_LEFT_EDGE   |
+      PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
+  PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES       =
+      PLY_RECTANGLE_OVERLAP_TOP_EDGE    |
+      PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
+  PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES  =
+      PLY_RECTANGLE_OVERLAP_TOP_EDGE    |
+      PLY_RECTANGLE_OVERLAP_LEFT_EDGE   |
+      PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
+  PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES =
+      PLY_RECTANGLE_OVERLAP_TOP_EDGE    |
+      PLY_RECTANGLE_OVERLAP_RIGHT_EDGE  |
+      PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE,
+  PLY_RECTANGLE_OVERLAP_ALL_EDGES                  =
+      PLY_RECTANGLE_OVERLAP_TOP_EDGE    |
+      PLY_RECTANGLE_OVERLAP_LEFT_EDGE   |
+      PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
+      PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
+  PLY_RECTANGLE_OVERLAP_NO_EDGES                    = 1 << 4,
+} ply_rectangle_overlap_t;
+
+#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
+bool ply_rectangle_contains_point (ply_rectangle_t *rectangle,
+                                   long             x,
+                                   long             y);
+
+bool ply_rectangle_is_empty (ply_rectangle_t *rectangle);
+
+ply_rectangle_overlap_t ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
+                                                    ply_rectangle_t *rectangle2);
+
+void ply_rectangle_intersect (ply_rectangle_t *rectangle1,
+                              ply_rectangle_t *rectangle2,
+                              ply_rectangle_t *result);
+#endif
+
+#endif /* PLY_RECTANGLE_H */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */