wok-6.x diff cairo/stuff/cairo-1.12.2-reduce-broken-stopped-edge-continuation.patch @ rev 14231
freetype: remove wrong error trigger (again)
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Mar 22 08:07:46 2013 +0100 (2013-03-22) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/cairo/stuff/cairo-1.12.2-reduce-broken-stopped-edge-continuation.patch Fri Mar 22 08:07:46 2013 +0100 1.3 @@ -0,0 +1,275 @@ 1.4 +From f228769dfe5a8b5d73c49a41e95e31ed73a77fb3 Mon Sep 17 00:00:00 2001 1.5 +From: Chris Wilson <chris@chris-wilson.co.uk> 1.6 +Date: Fri, 08 Jun 2012 16:22:41 +0000 1.7 +Subject: polygon-reduce: Reduce broken stopped-edge continuation 1.8 + 1.9 +This is hopefully a lesser used path and the attempted optimisation to 1.10 +continue a stopped edge with a colinear stopped edge highly unlikely and 1.11 +lost in the noise of the general inefficiency of the routine. As it was 1.12 +broken, rather than attempt to rectify the "optimisation" remove it. 1.13 + 1.14 +Reported-by: Evangelos Foutras <evangelos@foutrelis.com> 1.15 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50852 1.16 +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> 1.17 +--- 1.18 +diff --git a/src/cairo-polygon-reduce.c b/src/cairo-polygon-reduce.c 1.19 +index 8758070..ea457fe 100644 1.20 +--- a/src/cairo-polygon-reduce.c 1.21 ++++ b/src/cairo-polygon-reduce.c 1.22 +@@ -42,6 +42,8 @@ 1.23 + #include "cairo-freelist-private.h" 1.24 + #include "cairo-combsort-inline.h" 1.25 + 1.26 ++#define DEBUG_POLYGON 0 1.27 ++ 1.28 + typedef cairo_point_t cairo_bo_point32_t; 1.29 + 1.30 + typedef struct _cairo_bo_intersect_ordinate { 1.31 +@@ -114,7 +116,6 @@ typedef struct _cairo_bo_event_queue { 1.32 + 1.33 + typedef struct _cairo_bo_sweep_line { 1.34 + cairo_bo_edge_t *head; 1.35 +- cairo_bo_edge_t *stopped; 1.36 + int32_t current_y; 1.37 + cairo_bo_edge_t *current_edge; 1.38 + } cairo_bo_sweep_line_t; 1.39 +@@ -476,8 +477,8 @@ edges_compare_x_for_y (const cairo_bo_edge_t *a, 1.40 + static inline int 1.41 + _line_equal (const cairo_line_t *a, const cairo_line_t *b) 1.42 + { 1.43 +- return a->p1.x == b->p1.x && a->p1.y == b->p1.y && 1.44 +- a->p2.x == b->p2.x && a->p2.y == b->p2.y; 1.45 ++ return (a->p1.x == b->p1.x && a->p1.y == b->p1.y && 1.46 ++ a->p2.x == b->p2.x && a->p2.y == b->p2.y); 1.47 + } 1.48 + 1.49 + static int 1.50 +@@ -1024,7 +1025,6 @@ static void 1.51 + _cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line) 1.52 + { 1.53 + sweep_line->head = NULL; 1.54 +- sweep_line->stopped = NULL; 1.55 + sweep_line->current_y = INT32_MIN; 1.56 + sweep_line->current_edge = NULL; 1.57 + } 1.58 +@@ -1139,6 +1139,8 @@ edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b) 1.59 + */ 1.60 + if (a->edge.line.p1.y == b->edge.line.p1.y) { 1.61 + return a->edge.line.p1.x == b->edge.line.p1.x; 1.62 ++ } else if (a->edge.line.p2.y == b->edge.line.p2.y) { 1.63 ++ return a->edge.line.p2.x == b->edge.line.p2.x; 1.64 + } else if (a->edge.line.p1.y < b->edge.line.p1.y) { 1.65 + return edge_compare_for_y_against_x (b, 1.66 + a->edge.line.p1.y, 1.67 +@@ -1205,82 +1207,48 @@ _active_edges_to_polygon (cairo_bo_edge_t *left, 1.68 + cairo_polygon_t *polygon) 1.69 + { 1.70 + cairo_bo_edge_t *right; 1.71 ++ unsigned int mask; 1.72 + 1.73 +- if (fill_rule == CAIRO_FILL_RULE_WINDING) { 1.74 +- while (left != NULL) { 1.75 +- int in_out = left->edge.dir; 1.76 +- 1.77 +- right = left->next; 1.78 +- if (left->deferred.right == NULL) { 1.79 +- while (right != NULL && right->deferred.right == NULL) 1.80 +- right = right->next; 1.81 +- 1.82 +- if (right != NULL && edges_colinear (left, right)) { 1.83 +- /* continuation on left */ 1.84 +- left->deferred = right->deferred; 1.85 +- right->deferred.right = NULL; 1.86 +- } 1.87 +- } 1.88 +- 1.89 +- right = left->next; 1.90 +- while (right != NULL) { 1.91 +- if (right->deferred.right != NULL) 1.92 +- _cairo_bo_edge_end (right, top, polygon); 1.93 +- 1.94 +- in_out += right->edge.dir; 1.95 +- if (in_out == 0) { 1.96 +- cairo_bo_edge_t *next; 1.97 +- cairo_bool_t skip = FALSE; 1.98 +- 1.99 +- /* skip co-linear edges */ 1.100 +- next = right->next; 1.101 +- if (next != NULL) 1.102 +- skip = edges_colinear (right, next); 1.103 ++ if (fill_rule == CAIRO_FILL_RULE_WINDING) 1.104 ++ mask = ~0; 1.105 ++ else 1.106 ++ mask = 1; 1.107 + 1.108 +- if (! skip) 1.109 +- break; 1.110 +- } 1.111 ++ while (left != NULL) { 1.112 ++ int in_out = left->edge.dir; 1.113 + 1.114 ++ right = left->next; 1.115 ++ if (left->deferred.right == NULL) { 1.116 ++ while (right != NULL && right->deferred.right == NULL) 1.117 + right = right->next; 1.118 +- } 1.119 +- 1.120 +- _cairo_bo_edge_start_or_continue (left, right, top, polygon); 1.121 + 1.122 +- left = right; 1.123 +- if (left != NULL) 1.124 +- left = left->next; 1.125 ++ if (right != NULL && edges_colinear (left, right)) { 1.126 ++ /* continuation on left */ 1.127 ++ left->deferred = right->deferred; 1.128 ++ right->deferred.right = NULL; 1.129 ++ } 1.130 + } 1.131 +- } else { 1.132 +- while (left != NULL) { 1.133 +- int in_out = 0; 1.134 + 1.135 +- right = left->next; 1.136 +- while (right != NULL) { 1.137 +- if (right->deferred.right != NULL) 1.138 +- _cairo_bo_edge_end (right, top, polygon); 1.139 ++ right = left->next; 1.140 ++ while (right != NULL) { 1.141 ++ if (right->deferred.right != NULL) 1.142 ++ _cairo_bo_edge_end (right, top, polygon); 1.143 + 1.144 +- if ((in_out++ & 1) == 0) { 1.145 +- cairo_bo_edge_t *next; 1.146 +- cairo_bool_t skip = FALSE; 1.147 +- 1.148 +- /* skip co-linear edges */ 1.149 +- next = right->next; 1.150 +- if (next != NULL) 1.151 +- skip = edges_colinear (right, next); 1.152 +- 1.153 +- if (! skip) 1.154 +- break; 1.155 +- } 1.156 +- 1.157 +- right = right->next; 1.158 ++ in_out += right->edge.dir; 1.159 ++ if ((in_out & mask) == 0) { 1.160 ++ /* skip co-linear edges */ 1.161 ++ if (right->next == NULL || !edges_colinear (right, right->next)) 1.162 ++ break; 1.163 + } 1.164 + 1.165 +- _cairo_bo_edge_start_or_continue (left, right, top, polygon); 1.166 +- 1.167 +- left = right; 1.168 +- if (left != NULL) 1.169 +- left = left->next; 1.170 ++ right = right->next; 1.171 + } 1.172 ++ 1.173 ++ _cairo_bo_edge_start_or_continue (left, right, top, polygon); 1.174 ++ 1.175 ++ left = right; 1.176 ++ if (left != NULL) 1.177 ++ left = left->next; 1.178 + } 1.179 + } 1.180 + 1.181 +@@ -1303,12 +1271,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events, 1.182 + 1.183 + while ((event = _cairo_bo_event_dequeue (&event_queue))) { 1.184 + if (event->point.y != sweep_line.current_y) { 1.185 +- for (e1 = sweep_line.stopped; e1; e1 = e1->next) { 1.186 +- if (e1->deferred.right != NULL) 1.187 +- _cairo_bo_edge_end (e1, e1->edge.bottom, polygon); 1.188 +- } 1.189 +- sweep_line.stopped = NULL; 1.190 +- 1.191 + _active_edges_to_polygon (sweep_line.head, 1.192 + sweep_line.current_y, 1.193 + fill_rule, polygon); 1.194 +@@ -1328,23 +1290,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events, 1.195 + if (unlikely (status)) 1.196 + goto unwind; 1.197 + 1.198 +- /* check to see if this is a continuation of a stopped edge */ 1.199 +- /* XXX change to an infinitesimal lengthening rule */ 1.200 +- for (left = sweep_line.stopped; left; left = left->next) { 1.201 +- if (e1->edge.top <= left->edge.bottom && 1.202 +- edges_colinear (e1, left)) 1.203 +- { 1.204 +- e1->deferred = left->deferred; 1.205 +- if (left->prev != NULL) 1.206 +- left->prev = left->next; 1.207 +- else 1.208 +- sweep_line.stopped = left->next; 1.209 +- if (left->next != NULL) 1.210 +- left->next->prev = left->prev; 1.211 +- break; 1.212 +- } 1.213 +- } 1.214 +- 1.215 + left = e1->prev; 1.216 + right = e1->next; 1.217 + 1.218 +@@ -1371,14 +1316,8 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events, 1.219 + 1.220 + _cairo_bo_sweep_line_delete (&sweep_line, e1); 1.221 + 1.222 +- /* first, check to see if we have a continuation via a fresh edge */ 1.223 +- if (e1->deferred.right != NULL) { 1.224 +- e1->next = sweep_line.stopped; 1.225 +- if (sweep_line.stopped != NULL) 1.226 +- sweep_line.stopped->prev = e1; 1.227 +- sweep_line.stopped = e1; 1.228 +- e1->prev = NULL; 1.229 +- } 1.230 ++ if (e1->deferred.right != NULL) 1.231 ++ _cairo_bo_edge_end (e1, e1->edge.bottom, polygon); 1.232 + 1.233 + if (left != NULL && right != NULL) { 1.234 + status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right); 1.235 +@@ -1420,10 +1359,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events, 1.236 + } 1.237 + } 1.238 + 1.239 +- for (e1 = sweep_line.stopped; e1; e1 = e1->next) { 1.240 +- if (e1->deferred.right != NULL) 1.241 +- _cairo_bo_edge_end (e1, e1->edge.bottom, polygon); 1.242 +- } 1.243 + unwind: 1.244 + _cairo_bo_event_queue_fini (&event_queue); 1.245 + 1.246 +@@ -1447,6 +1382,12 @@ _cairo_polygon_reduce (cairo_polygon_t *polygon, 1.247 + if (unlikely (0 == num_events)) 1.248 + return CAIRO_STATUS_SUCCESS; 1.249 + 1.250 ++ if (DEBUG_POLYGON) { 1.251 ++ FILE *file = fopen ("reduce_in.txt", "w"); 1.252 ++ _cairo_debug_print_polygon (file, polygon); 1.253 ++ fclose (file); 1.254 ++ } 1.255 ++ 1.256 + events = stack_events; 1.257 + event_ptrs = stack_event_ptrs; 1.258 + if (num_events > ARRAY_LENGTH (stack_events)) { 1.259 +@@ -1482,10 +1423,16 @@ _cairo_polygon_reduce (cairo_polygon_t *polygon, 1.260 + num_events, 1.261 + fill_rule, 1.262 + polygon); 1.263 +- polygon->num_limits = num_limits; 1.264 ++ polygon->num_limits = num_limits; 1.265 + 1.266 + if (events != stack_events) 1.267 + free (events); 1.268 + 1.269 ++ if (DEBUG_POLYGON) { 1.270 ++ FILE *file = fopen ("reduce_out.txt", "w"); 1.271 ++ _cairo_debug_print_polygon (file, polygon); 1.272 ++ fclose (file); 1.273 ++ } 1.274 ++ 1.275 + return status; 1.276 + } 1.277 +-- 1.278 +cgit v0.9.0.2-2-gbebe