]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[rectangle] Add exact overlap detection
authorCharlie Brej <cbrej@cs.man.ac.uk>
Mon, 23 Nov 2009 00:23:22 +0000 (00:23 +0000)
committerCharlie Brej <cbrej@cs.man.ac.uk>
Mon, 23 Nov 2009 00:23:22 +0000 (00:23 +0000)
If the width and X position of the two rectangles is the same, we can merge
them together. The new set of exact overlaps detects this and determines the
direction the rectangle should be extended.

The region code now uses this. WARNING, when expanding rectangles, these have
to be merged with the other rectangles down the list as there may be overlap.

src/libply/ply-rectangle.c
src/libply/ply-rectangle.h
src/libply/ply-region.c

index 77f30f2327010c3e820f29039a6e5eb1b39c453a..8fdd89e57b441a4cb6b720ea8cb46bd53236104f 100644 (file)
@@ -67,14 +67,19 @@ ply_rectangle_overlap_t
 ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
                             ply_rectangle_t *rectangle2)
 {
-  enum {H_COLLISION_NONE, H_COLLISION_LEFT, H_COLLISION_RIGHT, H_COLLISION_BOTH, H_COLLISION_CONTAINED}
+  ply_rectangle_overlap_t overlap;
+
+  enum {H_COLLISION_NONE, H_COLLISION_LEFT, H_COLLISION_RIGHT, H_COLLISION_BOTH, H_COLLISION_CONTAINED, H_COLLISION_EXACT}
         h_collision = H_COLLISION_NONE;
-  enum {V_COLLISION_NONE, V_COLLISION_TOP, V_COLLISION_BOTTOM, V_COLLISION_BOTH, V_COLLISION_CONTAINED}
+  enum {V_COLLISION_NONE, V_COLLISION_TOP, V_COLLISION_BOTTOM, V_COLLISION_BOTH, V_COLLISION_CONTAINED, V_COLLISION_EXACT}
         v_collision = V_COLLISION_NONE;
 
   if (rectangle2->x >= rectangle1->x && (rectangle2->x + (int)rectangle2->width) <= (rectangle1->x + (int)rectangle1->width))
     {
-      h_collision = H_COLLISION_CONTAINED;
+      if (rectangle2->x == rectangle1->x && rectangle2->width == rectangle1->width)
+        h_collision = H_COLLISION_EXACT;
+      else
+        h_collision = H_COLLISION_CONTAINED;
     }
   else
     {                                       /* Remember: x+width points to the first pixel outside the rectangle*/
@@ -97,7 +102,10 @@ ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
       
       if (rectangle2->y >= rectangle1->y && (rectangle2->y + (int)rectangle2->height) <= (rectangle1->y + (int)rectangle1->height))
         {
-          v_collision = V_COLLISION_CONTAINED;
+          if (rectangle2->y == rectangle1->y && rectangle2->height == rectangle1->height)
+            v_collision = V_COLLISION_EXACT;
+          else
+            v_collision = V_COLLISION_CONTAINED;
         }
       else
         {
@@ -132,6 +140,8 @@ ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
                 return PLY_RECTANGLE_OVERLAP_TOP_LEFT_AND_BOTTOM_EDGES;
             case V_COLLISION_CONTAINED:
                 return PLY_RECTANGLE_OVERLAP_LEFT_EDGE;
+            case V_COLLISION_EXACT:
+                return PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE;
           }
       case H_COLLISION_RIGHT:
         switch (v_collision)
@@ -146,6 +156,8 @@ ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
                 return PLY_RECTANGLE_OVERLAP_TOP_RIGHT_AND_BOTTOM_EDGES;
             case V_COLLISION_CONTAINED:
                 return PLY_RECTANGLE_OVERLAP_RIGHT_EDGE;
+            case V_COLLISION_EXACT:
+                return PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE;
           }
       case H_COLLISION_BOTH:
         switch (v_collision)
@@ -160,6 +172,8 @@ ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
                 return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
             case V_COLLISION_CONTAINED:
                 return PLY_RECTANGLE_OVERLAP_SIDE_EDGES;
+            case V_COLLISION_EXACT:
+                return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
           }
       case H_COLLISION_CONTAINED:
         switch (v_collision)
@@ -174,6 +188,24 @@ ply_rectangle_find_overlap (ply_rectangle_t *rectangle1,
                 return PLY_RECTANGLE_OVERLAP_TOP_AND_BOTTOM_EDGES;
             case V_COLLISION_CONTAINED:
                 return PLY_RECTANGLE_OVERLAP_NO_EDGES;
+            case V_COLLISION_EXACT:
+                return PLY_RECTANGLE_OVERLAP_NO_EDGES;
+          }
+      case H_COLLISION_EXACT:
+        switch (v_collision)
+          {
+            case V_COLLISION_NONE:
+                return PLY_RECTANGLE_OVERLAP_NONE;
+            case V_COLLISION_TOP:
+                return PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE;
+            case V_COLLISION_BOTTOM:
+                return PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE;
+            case V_COLLISION_BOTH:
+                return PLY_RECTANGLE_OVERLAP_ALL_EDGES;
+            case V_COLLISION_CONTAINED:
+                return PLY_RECTANGLE_OVERLAP_NO_EDGES;
+            case V_COLLISION_EXACT:
+                return PLY_RECTANGLE_OVERLAP_NO_EDGES;
           }
     }
   return PLY_RECTANGLE_OVERLAP_NONE;
index bdbb6f4cfff0fa66000f4169b05de6b55b069b81..85ee71105e5fc0982a6621de42f3af54dc9a68c8 100644 (file)
@@ -84,6 +84,11 @@ typedef enum
       PLY_RECTANGLE_OVERLAP_BOTTOM_EDGE |
       PLY_RECTANGLE_OVERLAP_RIGHT_EDGE,
   PLY_RECTANGLE_OVERLAP_NO_EDGES                    = 1 << 4,
+  PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE,
+  PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE,
+  PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE,
+  PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE,
+  
 } ply_rectangle_overlap_t;
 
 #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
index c590913dbd1dbd81dc76f54b0661a74d36a48eef..a235f3384998915922fd629c9ffa472b8549057e 100644 (file)
@@ -361,7 +361,64 @@ merge_rectangle_with_sub_list (ply_region_t    *region,
            */
           case PLY_RECTANGLE_OVERLAP_NO_EDGES:
             free (new_area);
-            return;
+          return;
+
+          /*  NNNNN We expand the old rectangle up and throw away the new.
+           *  NNNNN We must merge it because the new region may have overlapped
+           *  NNNNN something further down the list.
+           *  OOOOO
+           */
+          case PLY_RECTANGLE_OVERLAP_EXACT_TOP_EDGE:
+            {
+              old_area->height = (old_area->y + old_area->height) - new_area->y;
+              old_area->y = new_area->y;
+              free (new_area);
+              merge_rectangle_with_sub_list (region, old_area, next_node);
+              ply_list_remove_node (region->rectangle_list, node);
+            }
+          return;
+
+          /*  OOOOO We expand the old rectangle down and throw away the new.
+           *  NNNNN We must merge it because the new region may have overlapped
+           *  NNNNN something further down the list.
+           *  NNNNN
+           */
+          case PLY_RECTANGLE_OVERLAP_EXACT_BOTTOM_EDGE:
+            {
+              old_area->height = (new_area->y + new_area->height) - old_area->y;
+              free (new_area);
+              merge_rectangle_with_sub_list (region, old_area, next_node);
+              ply_list_remove_node (region->rectangle_list, node);
+            }
+          return;
+
+          /*  NNNNNO We expand the old rectangle left and throw away the new.
+           *  NNNNNO We must merge it because the new region may have overlapped
+           *  NNNNNO something further down the list.
+           */
+          case PLY_RECTANGLE_OVERLAP_EXACT_LEFT_EDGE:
+            {
+              old_area->width = (old_area->x + old_area->width) - new_area->x;
+              old_area->x = new_area->x;
+              free (new_area);
+              merge_rectangle_with_sub_list (region, old_area, next_node);
+              ply_list_remove_node (region->rectangle_list, node);
+            }
+          return;
+
+          /*  ONNNNN We expand the old rectangle right and throw away the new.
+           *  ONNNNN We must merge it because the new region may have overlapped
+           *  ONNNNN something further down the list.
+           */
+          case PLY_RECTANGLE_OVERLAP_EXACT_RIGHT_EDGE:
+            {
+              old_area->width = (new_area->x + new_area->width) - old_area->x;
+              free (new_area);
+              merge_rectangle_with_sub_list (region, old_area, next_node);
+              ply_list_remove_node (region->rectangle_list, node);
+            }
+          return;
+
 
         }