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*/
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
{
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)
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)
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)
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;
*/
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;
+
}