[cairo-commit] src/cairo-bentley-ottmann-rectangular.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Aug 9 10:03:52 PDT 2011


 src/cairo-bentley-ottmann-rectangular.c |   25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

New commits:
commit 17e34b6eab1faecf46795ae7bf51eee9ffea5d75
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Aug 9 17:57:43 2011 +0100

    bo-rectangular: Correctly mergesort a doubly-linked list
    
    Saves having to fixup the pointers afterwards by only having to update
    them on the list boundaries during merge.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-bentley-ottmann-rectangular.c b/src/cairo-bentley-ottmann-rectangular.c
index 9adf4a5..7baec13 100644
--- a/src/cairo-bentley-ottmann-rectangular.c
+++ b/src/cairo-bentley-ottmann-rectangular.c
@@ -326,16 +326,15 @@ edge_start_or_continue_box (sweep_line_t *sweep_line,
 static edge_t *
 merge_sorted_edges (edge_t *head_a, edge_t *head_b)
 {
-    edge_t *head, **next;
+    edge_t *head, **next, *prev;
     int32_t x;
 
-    if (head_a == NULL)
-	return head_b;
-
+    prev = head_a->prev;
     next = &head;
     if (head_a->x <= head_b->x) {
 	head = head_a;
     } else {
+	head_b->prev = prev;
 	head = head_b;
 	goto start_with_b;
     }
@@ -343,10 +342,12 @@ merge_sorted_edges (edge_t *head_a, edge_t *head_b)
     do {
 	x = head_b->x;
 	while (head_a != NULL && head_a->x <= x) {
+	    prev = head_a;
 	    next = &head_a->next;
 	    head_a = head_a->next;
 	}
 
+	head_b->prev = prev;
 	*next = head_b;
 	if (head_a == NULL)
 	    return head;
@@ -354,10 +355,12 @@ merge_sorted_edges (edge_t *head_a, edge_t *head_b)
 start_with_b:
 	x = head_a->x;
 	while (head_b != NULL && head_b->x <= x) {
+	    prev = head_b;
 	    next = &head_b->next;
 	    head_b = head_b->next;
 	}
 
+	head_a->prev = prev;
 	*next = head_a;
 	if (head_b == NULL)
 	    return head;
@@ -402,19 +405,17 @@ sort_edges (edge_t  *list,
 	head_other->next = NULL;
     } else {
 	*head_out = head_other;
+	head_other->prev = list->prev;
 	head_other->next = list;
+	list->prev = head_other;
 	list->next = NULL;
     }
 
     for (i = 0; i < level && remaining; i++) {
-	/* Extract a sorted list of the same size as *head_out
-	 * (2^(i+1) elements) from the list of remaining elements. */
 	remaining = sort_edges (remaining, i, &head_other);
 	*head_out = merge_sorted_edges (*head_out, head_other);
     }
 
-    /* *head_out now contains (at most) 2^(level+1) elements. */
-
     return remaining;
 }
 
@@ -446,10 +447,6 @@ active_edges_insert (sweep_line_t *sweep)
     sweep->cursor = sweep->insert;
     sweep->insert = NULL;
     sweep->insert_x = INT_MAX;
-
-    /* update links within sort? */
-    for (edge = prev->next; edge; prev = edge, edge = edge->next)
-	edge->prev = prev;
 }
 
 static inline void
@@ -587,8 +584,12 @@ sweep_line_delete (sweep_line_t	*sweep, rectangle_t	*rectangle)
 static inline void
 sweep_line_insert (sweep_line_t	*sweep, rectangle_t *rectangle)
 {
+    if (sweep->insert)
+	sweep->insert->prev = &rectangle->right;
     rectangle->right.next = sweep->insert;
+    rectangle->right.prev = &rectangle->left;
     rectangle->left.next = &rectangle->right;
+    rectangle->left.prev = NULL;
     sweep->insert = &rectangle->left;
     if (rectangle->left.x < sweep->insert_x)
 	sweep->insert_x = rectangle->left.x;


More information about the cairo-commit mailing list