/src/cairo/src/cairo-tor-scan-converter.c
Line | Count | Source |
1 | | /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ |
2 | | /* glitter-paths - polygon scan converter |
3 | | * |
4 | | * Copyright (c) 2008 M Joonas Pihlaja |
5 | | * Copyright (c) 2007 David Turner |
6 | | * |
7 | | * Permission is hereby granted, free of charge, to any person |
8 | | * obtaining a copy of this software and associated documentation |
9 | | * files (the "Software"), to deal in the Software without |
10 | | * restriction, including without limitation the rights to use, |
11 | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
12 | | * copies of the Software, and to permit persons to whom the |
13 | | * Software is furnished to do so, subject to the following |
14 | | * conditions: |
15 | | * |
16 | | * The above copyright notice and this permission notice shall be |
17 | | * included in all copies or substantial portions of the Software. |
18 | | * |
19 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
20 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
21 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
22 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
23 | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
24 | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
25 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
26 | | * OTHER DEALINGS IN THE SOFTWARE. |
27 | | */ |
28 | | /* This is the Glitter paths scan converter incorporated into cairo. |
29 | | * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8 |
30 | | * of |
31 | | * |
32 | | * https://gitweb.freedesktop.org/?p=users/joonas/glitter-paths |
33 | | */ |
34 | | /* Glitter-paths is a stand alone polygon rasteriser derived from |
35 | | * David Turner's reimplementation of Tor Anderssons's 15x17 |
36 | | * supersampling rasteriser from the Apparition graphics library. The |
37 | | * main new feature here is cheaply choosing per-scan line between |
38 | | * doing fully analytical coverage computation for an entire row at a |
39 | | * time vs. using a supersampling approach. |
40 | | * |
41 | | * David Turner's code can be found at |
42 | | * |
43 | | * http://david.freetype.org/rasterizer-shootout/raster-comparison-20070813.tar.bz2 |
44 | | * |
45 | | * In particular this file incorporates large parts of ftgrays_tor10.h |
46 | | * from raster-comparison-20070813.tar.bz2 |
47 | | */ |
48 | | /* Overview |
49 | | * |
50 | | * A scan converter's basic purpose to take polygon edges and convert |
51 | | * them into an RLE compressed A8 mask. This one works in two phases: |
52 | | * gathering edges and generating spans. |
53 | | * |
54 | | * 1) As the user feeds the scan converter edges they are vertically |
55 | | * clipped and bucketted into a _polygon_ data structure. The edges |
56 | | * are also snapped from the user's coordinates to the subpixel grid |
57 | | * coordinates used during scan conversion. |
58 | | * |
59 | | * user |
60 | | * | |
61 | | * | edges |
62 | | * V |
63 | | * polygon buckets |
64 | | * |
65 | | * 2) Generating spans works by performing a vertical sweep of pixel |
66 | | * rows from top to bottom and maintaining an _active_list_ of edges |
67 | | * that intersect the row. From the active list the fill rule |
68 | | * determines which edges are the left and right edges of the start of |
69 | | * each span, and their contribution is then accumulated into a pixel |
70 | | * coverage list (_cell_list_) as coverage deltas. Once the coverage |
71 | | * deltas of all edges are known we can form spans of constant pixel |
72 | | * coverage by summing the deltas during a traversal of the cell list. |
73 | | * At the end of a pixel row the cell list is sent to a coverage |
74 | | * blitter for rendering to some target surface. |
75 | | * |
76 | | * The pixel coverages are computed by either supersampling the row |
77 | | * and box filtering a mono rasterisation, or by computing the exact |
78 | | * coverages of edges in the active list. The supersampling method is |
79 | | * used whenever some edge starts or stops within the row or there are |
80 | | * edge intersections in the row. |
81 | | * |
82 | | * polygon bucket for \ |
83 | | * current pixel row | |
84 | | * | | |
85 | | * | activate new edges | Repeat GRID_Y times if we |
86 | | * V \ are supersampling this row, |
87 | | * active list / or just once if we're computing |
88 | | * | | analytical coverage. |
89 | | * | coverage deltas | |
90 | | * V | |
91 | | * pixel coverage list / |
92 | | * | |
93 | | * V |
94 | | * coverage blitter |
95 | | */ |
96 | | #include "cairoint.h" |
97 | | #include "cairo-spans-private.h" |
98 | | #include "cairo-error-private.h" |
99 | | |
100 | | #include <stdlib.h> |
101 | | #include <string.h> |
102 | | #include <limits.h> |
103 | | #include <setjmp.h> |
104 | | |
105 | | /*------------------------------------------------------------------------- |
106 | | * cairo specific config |
107 | | */ |
108 | | #define I static |
109 | | |
110 | | /* Prefer cairo's status type. */ |
111 | | #define GLITTER_HAVE_STATUS_T 1 |
112 | 866 | #define GLITTER_STATUS_SUCCESS CAIRO_STATUS_SUCCESS |
113 | 0 | #define GLITTER_STATUS_NO_MEMORY CAIRO_STATUS_NO_MEMORY |
114 | | typedef cairo_status_t glitter_status_t; |
115 | | |
116 | | /* The input coordinate scale and the rasterisation grid scales. */ |
117 | 104k | #define GLITTER_INPUT_BITS CAIRO_FIXED_FRAC_BITS |
118 | 45.3k | #define GRID_X_BITS CAIRO_FIXED_FRAC_BITS |
119 | 148k | #define GRID_Y 15 |
120 | | |
121 | | /* Set glitter up to use a cairo span renderer to do the coverage |
122 | | * blitting. */ |
123 | | struct pool; |
124 | | struct cell_list; |
125 | | |
126 | | /*------------------------------------------------------------------------- |
127 | | * glitter-paths.h |
128 | | */ |
129 | | |
130 | | /* "Input scaled" numbers are fixed precision reals with multiplier |
131 | | * 2**GLITTER_INPUT_BITS. Input coordinates are given to glitter as |
132 | | * pixel scaled numbers. These get converted to the internal grid |
133 | | * scaled numbers as soon as possible. Internal overflow is possible |
134 | | * if GRID_X/Y inside glitter-paths.c is larger than |
135 | | * 1<<GLITTER_INPUT_BITS. */ |
136 | | #ifndef GLITTER_INPUT_BITS |
137 | | # define GLITTER_INPUT_BITS 8 |
138 | | #endif |
139 | | #define GLITTER_INPUT_SCALE (1<<GLITTER_INPUT_BITS) |
140 | | typedef int glitter_input_scaled_t; |
141 | | |
142 | | #if !GLITTER_HAVE_STATUS_T |
143 | | typedef enum { |
144 | | GLITTER_STATUS_SUCCESS = 0, |
145 | | GLITTER_STATUS_NO_MEMORY |
146 | | } glitter_status_t; |
147 | | #endif |
148 | | |
149 | | #ifndef I |
150 | | # define I /*static*/ |
151 | | #endif |
152 | | |
153 | | /* Opaque type for scan converting. */ |
154 | | typedef struct glitter_scan_converter glitter_scan_converter_t; |
155 | | |
156 | | /* Reset a scan converter to accept polygon edges and set the clip box |
157 | | * in pixels. Allocates O(ymax-ymin) bytes of memory. The clip box |
158 | | * is set to integer pixel coordinates xmin <= x < xmax, ymin <= y < |
159 | | * ymax. */ |
160 | | I glitter_status_t |
161 | | glitter_scan_converter_reset( |
162 | | glitter_scan_converter_t *converter, |
163 | | int xmin, int ymin, |
164 | | int xmax, int ymax); |
165 | | |
166 | | /* Render the polygon in the scan converter to the given A8 format |
167 | | * image raster. Only the pixels accessible as pixels[y*stride+x] for |
168 | | * x,y inside the clip box are written to, where xmin <= x < xmax, |
169 | | * ymin <= y < ymax. The image is assumed to be clear on input. |
170 | | * |
171 | | * If nonzero_fill is true then the interior of the polygon is |
172 | | * computed with the non-zero fill rule. Otherwise the even-odd fill |
173 | | * rule is used. |
174 | | * |
175 | | * The scan converter must be reset or destroyed after this call. */ |
176 | | |
177 | | /*------------------------------------------------------------------------- |
178 | | * glitter-paths.c: Implementation internal types |
179 | | */ |
180 | | #include <stdlib.h> |
181 | | #include <string.h> |
182 | | #include <limits.h> |
183 | | |
184 | | /* All polygon coordinates are snapped onto a subsample grid. "Grid |
185 | | * scaled" numbers are fixed precision reals with multiplier GRID_X or |
186 | | * GRID_Y. */ |
187 | | typedef int grid_scaled_t; |
188 | | typedef int grid_scaled_x_t; |
189 | | typedef int grid_scaled_y_t; |
190 | | |
191 | | /* Default x/y scale factors. |
192 | | * You can either define GRID_X/Y_BITS to get a power-of-two scale |
193 | | * or define GRID_X/Y separately. */ |
194 | | #if !defined(GRID_X) && !defined(GRID_X_BITS) |
195 | | # define GRID_X_BITS 8 |
196 | | #endif |
197 | | #if !defined(GRID_Y) && !defined(GRID_Y_BITS) |
198 | | # define GRID_Y 15 |
199 | | #endif |
200 | | |
201 | | /* Use GRID_X/Y_BITS to define GRID_X/Y if they're available. */ |
202 | | #ifdef GRID_X_BITS |
203 | 45.3k | # define GRID_X (1 << GRID_X_BITS) |
204 | | #endif |
205 | | #ifdef GRID_Y_BITS |
206 | | # define GRID_Y (1 << GRID_Y_BITS) |
207 | | #endif |
208 | | |
209 | | /* The GRID_X_TO_INT_FRAC macro splits a grid scaled coordinate into |
210 | | * integer and fractional parts. The integer part is floored. */ |
211 | | #if defined(GRID_X_TO_INT_FRAC) |
212 | | /* do nothing */ |
213 | | #elif defined(GRID_X_BITS) |
214 | | # define GRID_X_TO_INT_FRAC(x, i, f) \ |
215 | 134k | _GRID_TO_INT_FRAC_shift(x, i, f, GRID_X_BITS) |
216 | | #else |
217 | | # define GRID_X_TO_INT_FRAC(x, i, f) \ |
218 | | _GRID_TO_INT_FRAC_general(x, i, f, GRID_X) |
219 | | #endif |
220 | | |
221 | | #define _GRID_TO_INT_FRAC_general(t, i, f, m) do { \ |
222 | | (i) = (t) / (m); \ |
223 | | (f) = (t) % (m); \ |
224 | | if ((f) < 0) { \ |
225 | | --(i); \ |
226 | | (f) += (m); \ |
227 | | } \ |
228 | | } while (0) |
229 | | |
230 | 134k | #define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \ |
231 | 134k | (f) = (t) & ((1 << (b)) - 1); \ |
232 | 134k | (i) = (t) >> (b); \ |
233 | 134k | } while (0) |
234 | | |
235 | | /* A grid area is a real in [0,1] scaled by 2*GRID_X*GRID_Y. We want |
236 | | * to be able to represent exactly areas of subpixel trapezoids whose |
237 | | * vertices are given in grid scaled coordinates. The scale factor |
238 | | * comes from needing to accurately represent the area 0.5*dx*dy of a |
239 | | * triangle with base dx and height dy in grid scaled numbers. */ |
240 | | #define GRID_XY (2*GRID_X*GRID_Y) /* Unit area on the grid. */ |
241 | | |
242 | | /* GRID_AREA_TO_ALPHA(area): map [0,GRID_XY] to [0,255]. */ |
243 | | #if GRID_XY == 510 |
244 | | # define GRID_AREA_TO_ALPHA(c) (((c)+1) >> 1) |
245 | | #elif GRID_XY == 255 |
246 | | # define GRID_AREA_TO_ALPHA(c) (c) |
247 | | #elif GRID_XY == 64 |
248 | | # define GRID_AREA_TO_ALPHA(c) (((c) << 2) | -(((c) & 0x40) >> 6)) |
249 | | #elif GRID_XY == 128 |
250 | | # define GRID_AREA_TO_ALPHA(c) ((((c) << 1) | -((c) >> 7)) & 255) |
251 | | #elif GRID_XY == 256 |
252 | | # define GRID_AREA_TO_ALPHA(c) (((c) | -((c) >> 8)) & 255) |
253 | | #elif GRID_XY == 15 |
254 | | # define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) |
255 | | #elif GRID_XY == 2*256*15 |
256 | 31.5k | # define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9) |
257 | | #else |
258 | | # define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY) |
259 | | #endif |
260 | | |
261 | 187k | #define UNROLL3(x) x x x |
262 | | |
263 | | struct quorem { |
264 | | int32_t quo; |
265 | | int64_t rem; |
266 | | }; |
267 | | |
268 | | /* Header for a chunk of memory in a memory pool. */ |
269 | | struct _pool_chunk { |
270 | | /* # bytes used in this chunk. */ |
271 | | size_t size; |
272 | | |
273 | | /* # bytes total in this chunk */ |
274 | | size_t capacity; |
275 | | |
276 | | /* Pointer to the previous chunk or %NULL if this is the sentinel |
277 | | * chunk in the pool header. */ |
278 | | struct _pool_chunk *prev_chunk; |
279 | | |
280 | | /* Actual data starts here. Well aligned even for 64 bit types. */ |
281 | | int64_t data; |
282 | | }; |
283 | | |
284 | | /* The int64_t data member of _pool_chunk just exists to enforce alignment, |
285 | | * it shouldn't be included in the allocated size for the struct. */ |
286 | | #define SIZEOF_POOL_CHUNK (sizeof(struct _pool_chunk) - sizeof(int64_t)) |
287 | | |
288 | | /* A memory pool. This is supposed to be embedded on the stack or |
289 | | * within some other structure. It may optionally be followed by an |
290 | | * embedded array from which requests are fulfilled until |
291 | | * malloc needs to be called to allocate a first real chunk. */ |
292 | | struct pool { |
293 | | /* Chunk we're allocating from. */ |
294 | | struct _pool_chunk *current; |
295 | | |
296 | | jmp_buf *jmp; |
297 | | |
298 | | /* Free list of previously allocated chunks. All have >= default |
299 | | * capacity. */ |
300 | | struct _pool_chunk *first_free; |
301 | | |
302 | | /* The default capacity of a chunk. */ |
303 | | size_t default_capacity; |
304 | | |
305 | | /* Header for the sentinel chunk. Directly following the pool |
306 | | * struct should be some space for embedded elements from which |
307 | | * the sentinel chunk allocates from. This is expressed as a char |
308 | | * array so that the 'int64_t data' member of _pool_chunk isn't |
309 | | * included. This way embedding struct pool in other structs works |
310 | | * without wasting space. */ |
311 | | char sentinel[SIZEOF_POOL_CHUNK]; |
312 | | }; |
313 | | |
314 | | /* A polygon edge. */ |
315 | | struct edge { |
316 | | /* Next in y-bucket or active list. */ |
317 | | struct edge *next, *prev; |
318 | | |
319 | | /* The clipped y of the top of the edge. */ |
320 | | grid_scaled_y_t ytop; |
321 | | |
322 | | /* Number of subsample rows remaining to scan convert of this |
323 | | * edge. */ |
324 | | grid_scaled_y_t height_left; |
325 | | |
326 | | /* Original sign of the edge: +1 for downwards, -1 for upwards |
327 | | * edges. */ |
328 | | int dir; |
329 | | int cell; |
330 | | |
331 | | /* Current x coordinate while the edge is on the active |
332 | | * list. Initialised to the x coordinate of the top of the |
333 | | * edge. The quotient is in grid_scaled_x_t units and the |
334 | | * remainder is mod dy in grid_scaled_y_t units.*/ |
335 | | struct quorem x; |
336 | | |
337 | | /* Advance of the current x when moving down a subsample line. */ |
338 | | struct quorem dxdy; |
339 | | |
340 | | /* Advance of the current x when moving down a full pixel |
341 | | * row. Only initialised when the height of the edge is large |
342 | | * enough that there's a chance the edge could be stepped by a |
343 | | * full row's worth of subsample rows at a time. */ |
344 | | struct quorem dxdy_full; |
345 | | |
346 | | /* y2-y1 after orienting the edge downwards. */ |
347 | | int64_t dy; |
348 | | }; |
349 | | |
350 | 13.3k | #define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/GRID_Y) |
351 | | |
352 | | /* A collection of sorted and vertically clipped edges of the polygon. |
353 | | * Edges are moved from the polygon to an active list while scan |
354 | | * converting. */ |
355 | | struct polygon { |
356 | | /* The vertical clip extents. */ |
357 | | grid_scaled_y_t ymin, ymax; |
358 | | |
359 | | /* Array of edges all starting in the same bucket. An edge is put |
360 | | * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when |
361 | | * it is added to the polygon. */ |
362 | | struct edge **y_buckets; |
363 | | struct edge *y_buckets_embedded[64]; |
364 | | |
365 | | struct { |
366 | | struct pool base[1]; |
367 | | struct edge embedded[32]; |
368 | | } edge_pool; |
369 | | }; |
370 | | |
371 | | /* A cell records the effect on pixel coverage of polygon edges |
372 | | * passing through a pixel. It contains two accumulators of pixel |
373 | | * coverage. |
374 | | * |
375 | | * Consider the effects of a polygon edge on the coverage of a pixel |
376 | | * it intersects and that of the following one. The coverage of the |
377 | | * following pixel is the height of the edge multiplied by the width |
378 | | * of the pixel, and the coverage of the pixel itself is the area of |
379 | | * the trapezoid formed by the edge and the right side of the pixel. |
380 | | * |
381 | | * +-----------------------+-----------------------+ |
382 | | * | | | |
383 | | * | | | |
384 | | * |_______________________|_______________________| |
385 | | * | \...................|.......................|\ |
386 | | * | \..................|.......................| | |
387 | | * | \.................|.......................| | |
388 | | * | \....covered.....|.......................| | |
389 | | * | \....area.......|.......................| } covered height |
390 | | * | \..............|.......................| | |
391 | | * |uncovered\.............|.......................| | |
392 | | * | area \............|.......................| | |
393 | | * |___________\...........|.......................|/ |
394 | | * | | | |
395 | | * | | | |
396 | | * | | | |
397 | | * +-----------------------+-----------------------+ |
398 | | * |
399 | | * Since the coverage of the following pixel will always be a multiple |
400 | | * of the width of the pixel, we can store the height of the covered |
401 | | * area instead. The coverage of the pixel itself is the total |
402 | | * coverage minus the area of the uncovered area to the left of the |
403 | | * edge. As it's faster to compute the uncovered area we only store |
404 | | * that and subtract it from the total coverage later when forming |
405 | | * spans to blit. |
406 | | * |
407 | | * The heights and areas are signed, with left edges of the polygon |
408 | | * having positive sign and right edges having negative sign. When |
409 | | * two edges intersect they swap their left/rightness so their |
410 | | * contribution above and below the intersection point must be |
411 | | * computed separately. */ |
412 | | struct cell { |
413 | | struct cell *next; |
414 | | int x; |
415 | | int16_t uncovered_area; |
416 | | int16_t covered_height; |
417 | | }; |
418 | | |
419 | | /* A cell list represents the scan line sparsely as cells ordered by |
420 | | * ascending x. It is geared towards scanning the cells in order |
421 | | * using an internal cursor. */ |
422 | | struct cell_list { |
423 | | /* Sentinel nodes */ |
424 | | struct cell head, tail; |
425 | | |
426 | | /* Cursor state for iterating through the cell list. */ |
427 | | struct cell *cursor, *rewind; |
428 | | |
429 | | /* Cells in the cell list are owned by the cell list and are |
430 | | * allocated from this pool. */ |
431 | | struct { |
432 | | struct pool base[1]; |
433 | | struct cell embedded[32]; |
434 | | } cell_pool; |
435 | | }; |
436 | | |
437 | | struct cell_pair { |
438 | | struct cell *cell1; |
439 | | struct cell *cell2; |
440 | | }; |
441 | | |
442 | | /* The active list contains edges in the current scan line ordered by |
443 | | * the x-coordinate of the intercept of the edge and the scan line. */ |
444 | | struct active_list { |
445 | | /* Leftmost edge on the current scan line. */ |
446 | | struct edge head, tail; |
447 | | |
448 | | /* A lower bound on the height of the active edges is used to |
449 | | * estimate how soon some active edge ends. We can't advance the |
450 | | * scan conversion by a full pixel row if an edge ends somewhere |
451 | | * within it. */ |
452 | | grid_scaled_y_t min_height; |
453 | | int is_vertical; |
454 | | }; |
455 | | |
456 | | struct glitter_scan_converter { |
457 | | struct polygon polygon[1]; |
458 | | struct active_list active[1]; |
459 | | struct cell_list coverages[1]; |
460 | | |
461 | | cairo_half_open_span_t *spans; |
462 | | cairo_half_open_span_t spans_embedded[64]; |
463 | | |
464 | | /* Clip box. */ |
465 | | grid_scaled_x_t xmin, xmax; |
466 | | grid_scaled_y_t ymin, ymax; |
467 | | }; |
468 | | |
469 | | static struct _pool_chunk * |
470 | | _pool_chunk_init( |
471 | | struct _pool_chunk *p, |
472 | | struct _pool_chunk *prev_chunk, |
473 | | size_t capacity) |
474 | 1.03k | { |
475 | 1.03k | p->prev_chunk = prev_chunk; |
476 | 1.03k | p->size = 0; |
477 | 1.03k | p->capacity = capacity; |
478 | 1.03k | return p; |
479 | 1.03k | } |
480 | | |
481 | | static struct _pool_chunk * |
482 | | _pool_chunk_create(struct pool *pool, size_t size) |
483 | 167 | { |
484 | 167 | struct _pool_chunk *p; |
485 | | |
486 | 167 | p = _cairo_malloc (SIZEOF_POOL_CHUNK + size); |
487 | 167 | if (unlikely (NULL == p)) |
488 | 0 | longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY)); |
489 | | |
490 | 167 | return _pool_chunk_init(p, pool->current, size); |
491 | 167 | } |
492 | | |
493 | | static void |
494 | | pool_init(struct pool *pool, |
495 | | jmp_buf *jmp, |
496 | | size_t default_capacity, |
497 | | size_t embedded_capacity) |
498 | 866 | { |
499 | 866 | pool->jmp = jmp; |
500 | 866 | pool->current = (void*) pool->sentinel; |
501 | 866 | pool->first_free = NULL; |
502 | 866 | pool->default_capacity = default_capacity; |
503 | 866 | _pool_chunk_init(pool->current, NULL, embedded_capacity); |
504 | 866 | } |
505 | | |
506 | | static void |
507 | | pool_fini(struct pool *pool) |
508 | 866 | { |
509 | 866 | struct _pool_chunk *p = pool->current; |
510 | 866 | do { |
511 | 1.89k | while (NULL != p) { |
512 | 1.03k | struct _pool_chunk *prev = p->prev_chunk; |
513 | 1.03k | if (p != (void *) pool->sentinel) |
514 | 167 | free(p); |
515 | 1.03k | p = prev; |
516 | 1.03k | } |
517 | 866 | p = pool->first_free; |
518 | 866 | pool->first_free = NULL; |
519 | 866 | } while (NULL != p); |
520 | 866 | } |
521 | | |
522 | | /* Satisfy an allocation by first allocating a new large enough chunk |
523 | | * and adding it to the head of the pool's chunk list. This function |
524 | | * is called as a fallback if pool_alloc() couldn't do a quick |
525 | | * allocation from the current chunk in the pool. */ |
526 | | static void * |
527 | | _pool_alloc_from_new_chunk( |
528 | | struct pool *pool, |
529 | | size_t size) |
530 | 167 | { |
531 | 167 | struct _pool_chunk *chunk; |
532 | 167 | void *obj; |
533 | 167 | size_t capacity; |
534 | | |
535 | | /* If the allocation is smaller than the default chunk size then |
536 | | * try getting a chunk off the free list. Force alloc of a new |
537 | | * chunk for large requests. */ |
538 | 167 | capacity = size; |
539 | 167 | chunk = NULL; |
540 | 167 | if (size < pool->default_capacity) { |
541 | 167 | capacity = pool->default_capacity; |
542 | 167 | chunk = pool->first_free; |
543 | 167 | if (chunk) { |
544 | 0 | pool->first_free = chunk->prev_chunk; |
545 | 0 | _pool_chunk_init(chunk, pool->current, chunk->capacity); |
546 | 0 | } |
547 | 167 | } |
548 | | |
549 | 167 | if (NULL == chunk) |
550 | 167 | chunk = _pool_chunk_create (pool, capacity); |
551 | 167 | pool->current = chunk; |
552 | | |
553 | 167 | obj = ((unsigned char*)&chunk->data + chunk->size); |
554 | 167 | chunk->size += size; |
555 | 167 | return obj; |
556 | 167 | } |
557 | | |
558 | | /* Allocate size bytes from the pool. The first allocated address |
559 | | * returned from a pool is aligned to 8 bytes. Subsequent |
560 | | * addresses will maintain alignment as long as multiples of 8 are |
561 | | * allocated. Returns the address of a new memory area or %NULL on |
562 | | * allocation failures. The pool retains ownership of the returned |
563 | | * memory. */ |
564 | | inline static void * |
565 | | pool_alloc (struct pool *pool, size_t size) |
566 | 34.1k | { |
567 | 34.1k | struct _pool_chunk *chunk = pool->current; |
568 | | |
569 | 34.1k | if (size <= chunk->capacity - chunk->size) { |
570 | 33.9k | void *obj = ((unsigned char*)&chunk->data + chunk->size); |
571 | 33.9k | chunk->size += size; |
572 | 33.9k | return obj; |
573 | 33.9k | } else { |
574 | 167 | return _pool_alloc_from_new_chunk(pool, size); |
575 | 167 | } |
576 | 34.1k | } |
577 | | |
578 | | /* Relinquish all pool_alloced memory back to the pool. */ |
579 | | static void |
580 | | pool_reset (struct pool *pool) |
581 | 5.74k | { |
582 | | /* Transfer all used chunks to the chunk free list. */ |
583 | 5.74k | struct _pool_chunk *chunk = pool->current; |
584 | 5.74k | if (chunk != (void *) pool->sentinel) { |
585 | 0 | while (chunk->prev_chunk != (void *) pool->sentinel) { |
586 | 0 | chunk = chunk->prev_chunk; |
587 | 0 | } |
588 | 0 | chunk->prev_chunk = pool->first_free; |
589 | 0 | pool->first_free = pool->current; |
590 | 0 | } |
591 | | /* Reset the sentinel as the current chunk. */ |
592 | 5.74k | pool->current = (void *) pool->sentinel; |
593 | 5.74k | pool->current->size = 0; |
594 | 5.74k | } |
595 | | |
596 | | /* Rewinds the cell list's cursor to the beginning. After rewinding |
597 | | * we're good to cell_list_find() the cell any x coordinate. */ |
598 | | inline static void |
599 | | cell_list_rewind (struct cell_list *cells) |
600 | 51.4k | { |
601 | 51.4k | cells->cursor = &cells->head; |
602 | 51.4k | } |
603 | | |
604 | | inline static void |
605 | | cell_list_maybe_rewind (struct cell_list *cells, int x) |
606 | 4.39k | { |
607 | 4.39k | if (x < cells->cursor->x) { |
608 | 0 | cells->cursor = cells->rewind; |
609 | 0 | if (x < cells->cursor->x) |
610 | 0 | cells->cursor = &cells->head; |
611 | 0 | } |
612 | 4.39k | } |
613 | | |
614 | | inline static void |
615 | | cell_list_set_rewind (struct cell_list *cells) |
616 | 2.19k | { |
617 | 2.19k | cells->rewind = cells->cursor; |
618 | 2.19k | } |
619 | | |
620 | | static void |
621 | | cell_list_init(struct cell_list *cells, jmp_buf *jmp) |
622 | 433 | { |
623 | 433 | pool_init(cells->cell_pool.base, jmp, |
624 | 433 | 256*sizeof(struct cell), |
625 | 433 | sizeof(cells->cell_pool.embedded)); |
626 | 433 | cells->tail.next = NULL; |
627 | 433 | cells->tail.x = INT_MAX; |
628 | 433 | cells->head.x = INT_MIN; |
629 | 433 | cells->head.next = &cells->tail; |
630 | 433 | cell_list_rewind (cells); |
631 | 433 | } |
632 | | |
633 | | static void |
634 | | cell_list_fini(struct cell_list *cells) |
635 | 433 | { |
636 | 433 | pool_fini (cells->cell_pool.base); |
637 | 433 | } |
638 | | |
639 | | /* Empty the cell list. This is called at the start of every pixel |
640 | | * row. */ |
641 | | inline static void |
642 | | cell_list_reset (struct cell_list *cells) |
643 | 5.31k | { |
644 | 5.31k | cell_list_rewind (cells); |
645 | 5.31k | cells->head.next = &cells->tail; |
646 | 5.31k | pool_reset (cells->cell_pool.base); |
647 | 5.31k | } |
648 | | |
649 | | inline static struct cell * |
650 | | cell_list_alloc (struct cell_list *cells, |
651 | | struct cell *tail, |
652 | | int x) |
653 | 21.1k | { |
654 | 21.1k | struct cell *cell; |
655 | | |
656 | 21.1k | cell = pool_alloc (cells->cell_pool.base, sizeof (struct cell)); |
657 | 21.1k | cell->next = tail->next; |
658 | 21.1k | tail->next = cell; |
659 | 21.1k | cell->x = x; |
660 | 21.1k | *(uint32_t *)&cell->uncovered_area = 0; |
661 | | |
662 | 21.1k | return cell; |
663 | 21.1k | } |
664 | | |
665 | | /* Find a cell at the given x-coordinate. Returns %NULL if a new cell |
666 | | * needed to be allocated but couldn't be. Cells must be found with |
667 | | * non-decreasing x-coordinate until the cell list is rewound using |
668 | | * cell_list_rewind(). Ownership of the returned cell is retained by |
669 | | * the cell list. */ |
670 | | inline static struct cell * |
671 | | cell_list_find (struct cell_list *cells, int x) |
672 | 10.3k | { |
673 | 10.3k | struct cell *tail = cells->cursor; |
674 | | |
675 | 10.3k | if (tail->x == x) |
676 | 1.18k | return tail; |
677 | | |
678 | 9.50k | while (1) { |
679 | 9.50k | UNROLL3({ |
680 | 6.46k | if (tail->next->x > x) |
681 | 6.46k | break; |
682 | 6.46k | tail = tail->next; |
683 | 6.46k | }); |
684 | 6.46k | } |
685 | | |
686 | 9.17k | if (tail->x != x) |
687 | 4.53k | tail = cell_list_alloc (cells, tail, x); |
688 | 9.17k | return cells->cursor = tail; |
689 | | |
690 | 10.3k | } |
691 | | |
692 | | /* Find two cells at x1 and x2. This is exactly equivalent |
693 | | * to |
694 | | * |
695 | | * pair.cell1 = cell_list_find(cells, x1); |
696 | | * pair.cell2 = cell_list_find(cells, x2); |
697 | | * |
698 | | * except with less function call overhead. */ |
699 | | inline static struct cell_pair |
700 | | cell_list_find_pair(struct cell_list *cells, int x1, int x2) |
701 | 57.6k | { |
702 | 57.6k | struct cell_pair pair; |
703 | | |
704 | 57.6k | pair.cell1 = cells->cursor; |
705 | 59.5k | while (1) { |
706 | 59.5k | UNROLL3({ |
707 | 57.4k | if (pair.cell1->next->x > x1) |
708 | 57.4k | break; |
709 | 57.4k | pair.cell1 = pair.cell1->next; |
710 | 57.4k | }); |
711 | 57.4k | } |
712 | 57.6k | if (pair.cell1->x != x1) |
713 | 8.10k | pair.cell1 = cell_list_alloc (cells, pair.cell1, x1); |
714 | | |
715 | 57.6k | pair.cell2 = pair.cell1; |
716 | 62.3k | while (1) { |
717 | 71.0k | UNROLL3({ |
718 | 71.0k | if (pair.cell2->next->x > x2) |
719 | 71.0k | break; |
720 | 71.0k | pair.cell2 = pair.cell2->next; |
721 | 71.0k | }); |
722 | 71.0k | } |
723 | 57.6k | if (pair.cell2->x != x2) |
724 | 8.54k | pair.cell2 = cell_list_alloc (cells, pair.cell2, x2); |
725 | | |
726 | 57.6k | cells->cursor = pair.cell2; |
727 | 57.6k | return pair; |
728 | 57.6k | } |
729 | | |
730 | | /* Add a subpixel span covering [x1, x2) to the coverage cells. */ |
731 | | inline static void |
732 | | cell_list_add_subspan(struct cell_list *cells, |
733 | | grid_scaled_x_t x1, |
734 | | grid_scaled_x_t x2) |
735 | 62.7k | { |
736 | 62.7k | int ix1, fx1; |
737 | 62.7k | int ix2, fx2; |
738 | | |
739 | 62.7k | if (x1 == x2) |
740 | 132 | return; |
741 | | |
742 | 62.6k | GRID_X_TO_INT_FRAC(x1, ix1, fx1); |
743 | 62.6k | GRID_X_TO_INT_FRAC(x2, ix2, fx2); |
744 | | |
745 | 62.6k | if (ix1 != ix2) { |
746 | 55.9k | struct cell_pair p; |
747 | 55.9k | p = cell_list_find_pair(cells, ix1, ix2); |
748 | 55.9k | p.cell1->uncovered_area += 2*fx1; |
749 | 55.9k | ++p.cell1->covered_height; |
750 | 55.9k | p.cell2->uncovered_area -= 2*fx2; |
751 | 55.9k | --p.cell2->covered_height; |
752 | 55.9k | } else { |
753 | 6.63k | struct cell *cell = cell_list_find(cells, ix1); |
754 | 6.63k | cell->uncovered_area += 2*(fx1-fx2); |
755 | 6.63k | } |
756 | 62.6k | } |
757 | | |
758 | | inline static void full_step (struct edge *e) |
759 | 4.40k | { |
760 | 4.40k | if (e->dy == 0) |
761 | 1.06k | return; |
762 | | |
763 | 3.34k | e->x.quo += e->dxdy_full.quo; |
764 | 3.34k | e->x.rem += e->dxdy_full.rem; |
765 | 3.34k | if (e->x.rem < 0) { |
766 | 579 | e->x.quo--; |
767 | 579 | e->x.rem += e->dy; |
768 | 2.76k | } else if (e->x.rem >= e->dy) { |
769 | 1.16k | ++e->x.quo; |
770 | 1.16k | e->x.rem -= e->dy; |
771 | 1.16k | } |
772 | | |
773 | 3.34k | e->cell = e->x.quo + (e->x.rem >= e->dy/2); |
774 | 3.34k | } |
775 | | |
776 | | |
777 | | /* Adds the analytical coverage of an edge crossing the current pixel |
778 | | * row to the coverage cells and advances the edge's x position to the |
779 | | * following row. |
780 | | * |
781 | | * This function is only called when we know that during this pixel row: |
782 | | * |
783 | | * 1) The relative order of all edges on the active list doesn't |
784 | | * change. In particular, no edges intersect within this row to pixel |
785 | | * precision. |
786 | | * |
787 | | * 2) No new edges start in this row. |
788 | | * |
789 | | * 3) No existing edges end mid-row. |
790 | | * |
791 | | * This function depends on being called with all edges from the |
792 | | * active list in the order they appear on the list (i.e. with |
793 | | * non-decreasing x-coordinate.) */ |
794 | | static void |
795 | | cell_list_render_edge(struct cell_list *cells, |
796 | | struct edge *edge, |
797 | | int sign) |
798 | 4.39k | { |
799 | 4.39k | struct quorem x1, x2; |
800 | 4.39k | grid_scaled_x_t fx1, fx2; |
801 | 4.39k | int ix1, ix2; |
802 | | |
803 | 4.39k | x1 = edge->x; |
804 | 4.39k | full_step (edge); |
805 | 4.39k | x2 = edge->x; |
806 | | |
807 | | /* Step back from the sample location (half-subrow) to the pixel origin */ |
808 | 4.39k | if (edge->dy) { |
809 | 3.33k | x1.quo -= edge->dxdy.quo / 2; |
810 | 3.33k | x1.rem -= edge->dxdy.rem / 2; |
811 | 3.33k | if (x1.rem < 0) { |
812 | 381 | --x1.quo; |
813 | 381 | x1.rem += edge->dy; |
814 | 2.95k | } else if (x1.rem >= edge->dy) { |
815 | 298 | ++x1.quo; |
816 | 298 | x1.rem -= edge->dy; |
817 | 298 | } |
818 | | |
819 | 3.33k | x2.quo -= edge->dxdy.quo / 2; |
820 | 3.33k | x2.rem -= edge->dxdy.rem / 2; |
821 | 3.33k | if (x2.rem < 0) { |
822 | 382 | --x2.quo; |
823 | 382 | x2.rem += edge->dy; |
824 | 2.95k | } else if (x2.rem >= edge->dy) { |
825 | 308 | ++x2.quo; |
826 | 308 | x2.rem -= edge->dy; |
827 | 308 | } |
828 | 3.33k | } |
829 | | |
830 | 4.39k | GRID_X_TO_INT_FRAC(x1.quo, ix1, fx1); |
831 | 4.39k | GRID_X_TO_INT_FRAC(x2.quo, ix2, fx2); |
832 | | |
833 | 4.39k | cell_list_maybe_rewind(cells, MIN(ix1, ix2)); |
834 | | |
835 | | /* Edge is entirely within a column? */ |
836 | 4.39k | if (ix1 == ix2) { |
837 | | /* We always know that ix1 is >= the cell list cursor in this |
838 | | * case due to the no-intersections precondition. */ |
839 | 2.74k | struct cell *cell = cell_list_find(cells, ix1); |
840 | 2.74k | cell->covered_height += sign*GRID_Y; |
841 | 2.74k | cell->uncovered_area += sign*(fx1 + fx2)*GRID_Y; |
842 | 2.74k | return; |
843 | 2.74k | } |
844 | | |
845 | | /* Orient the edge left-to-right. */ |
846 | 1.64k | if (ix2 < ix1) { |
847 | 566 | struct quorem tx; |
848 | 566 | int t; |
849 | | |
850 | 566 | t = ix1; |
851 | 566 | ix1 = ix2; |
852 | 566 | ix2 = t; |
853 | | |
854 | 566 | t = fx1; |
855 | 566 | fx1 = fx2; |
856 | 566 | fx2 = t; |
857 | | |
858 | 566 | tx = x1; |
859 | 566 | x1 = x2; |
860 | 566 | x2 = tx; |
861 | 566 | } |
862 | | |
863 | | /* Add coverage for all pixels [ix1,ix2] on this row crossed |
864 | | * by the edge. */ |
865 | 1.64k | { |
866 | 1.64k | struct cell_pair pair; |
867 | 1.64k | struct quorem y; |
868 | 1.64k | int64_t tmp, dx; |
869 | 1.64k | int y_last; |
870 | | |
871 | 1.64k | dx = (x2.quo - x1.quo) * edge->dy + (x2.rem - x1.rem); |
872 | | |
873 | 1.64k | tmp = (ix1 + 1) * GRID_X * edge->dy; |
874 | 1.64k | tmp -= x1.quo * edge->dy + x1.rem; |
875 | 1.64k | tmp *= GRID_Y; |
876 | | |
877 | 1.64k | y.quo = tmp / dx; |
878 | 1.64k | y.rem = tmp % dx; |
879 | | |
880 | | /* When rendering a previous edge on the active list we may |
881 | | * advance the cell list cursor past the leftmost pixel of the |
882 | | * current edge even though the two edges don't intersect. |
883 | | * e.g. consider two edges going down and rightwards: |
884 | | * |
885 | | * --\_+---\_+-----+-----+---- |
886 | | * \_ \_ | | |
887 | | * | \_ | \_ | | |
888 | | * | \_| \_| | |
889 | | * | \_ \_ | |
890 | | * ----+-----+-\---+-\---+---- |
891 | | * |
892 | | * The left edge touches cells past the starting cell of the |
893 | | * right edge. Fortunately such cases are rare. |
894 | | */ |
895 | | |
896 | 1.64k | pair = cell_list_find_pair(cells, ix1, ix1+1); |
897 | 1.64k | pair.cell1->uncovered_area += sign*y.quo*(GRID_X + fx1); |
898 | 1.64k | pair.cell1->covered_height += sign*y.quo; |
899 | 1.64k | y_last = y.quo; |
900 | | |
901 | 1.64k | if (ix1+1 < ix2) { |
902 | 659 | struct cell *cell = pair.cell2; |
903 | 659 | struct quorem dydx_full; |
904 | | |
905 | 659 | dydx_full.quo = GRID_Y * GRID_X * edge->dy / dx; |
906 | 659 | dydx_full.rem = GRID_Y * GRID_X * edge->dy % dx; |
907 | | |
908 | 659 | ++ix1; |
909 | 982 | do { |
910 | 982 | y.quo += dydx_full.quo; |
911 | 982 | y.rem += dydx_full.rem; |
912 | 982 | if (y.rem >= dx) { |
913 | 469 | y.quo++; |
914 | 469 | y.rem -= dx; |
915 | 469 | } |
916 | | |
917 | 982 | cell->uncovered_area += sign*(y.quo - y_last)*GRID_X; |
918 | 982 | cell->covered_height += sign*(y.quo - y_last); |
919 | 982 | y_last = y.quo; |
920 | | |
921 | 982 | ++ix1; |
922 | 982 | cell = cell_list_find(cells, ix1); |
923 | 982 | } while (ix1 != ix2); |
924 | | |
925 | 659 | pair.cell2 = cell; |
926 | 659 | } |
927 | 1.64k | pair.cell2->uncovered_area += sign*(GRID_Y - y_last)*fx2; |
928 | 1.64k | pair.cell2->covered_height += sign*(GRID_Y - y_last); |
929 | 1.64k | } |
930 | 1.64k | } |
931 | | |
932 | | static void |
933 | | polygon_init (struct polygon *polygon, jmp_buf *jmp) |
934 | 433 | { |
935 | 433 | polygon->ymin = polygon->ymax = 0; |
936 | 433 | polygon->y_buckets = polygon->y_buckets_embedded; |
937 | 433 | pool_init (polygon->edge_pool.base, jmp, |
938 | 433 | 8192 - sizeof (struct _pool_chunk), |
939 | 433 | sizeof (polygon->edge_pool.embedded)); |
940 | 433 | } |
941 | | |
942 | | static void |
943 | | polygon_fini (struct polygon *polygon) |
944 | 433 | { |
945 | 433 | if (polygon->y_buckets != polygon->y_buckets_embedded) |
946 | 44 | free (polygon->y_buckets); |
947 | | |
948 | 433 | pool_fini (polygon->edge_pool.base); |
949 | 433 | } |
950 | | |
951 | | /* Empties the polygon of all edges. The polygon is then prepared to |
952 | | * receive new edges and clip them to the vertical range |
953 | | * [ymin,ymax). */ |
954 | | static glitter_status_t |
955 | | polygon_reset (struct polygon *polygon, |
956 | | grid_scaled_y_t ymin, |
957 | | grid_scaled_y_t ymax) |
958 | 433 | { |
959 | 433 | unsigned h = ymax - ymin; |
960 | 433 | unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax + GRID_Y-1, ymin); |
961 | | |
962 | 433 | pool_reset(polygon->edge_pool.base); |
963 | | |
964 | 433 | if (unlikely (h > 0x7FFFFFFFU - GRID_Y)) |
965 | 0 | goto bail_no_mem; /* even if you could, you wouldn't want to. */ |
966 | | |
967 | 433 | if (polygon->y_buckets != polygon->y_buckets_embedded) |
968 | 0 | free (polygon->y_buckets); |
969 | | |
970 | 433 | polygon->y_buckets = polygon->y_buckets_embedded; |
971 | 433 | if (num_buckets > ARRAY_LENGTH (polygon->y_buckets_embedded)) { |
972 | 44 | polygon->y_buckets = _cairo_malloc_ab (num_buckets, |
973 | 44 | sizeof (struct edge *)); |
974 | 44 | if (unlikely (NULL == polygon->y_buckets)) |
975 | 0 | goto bail_no_mem; |
976 | 44 | } |
977 | 433 | memset (polygon->y_buckets, 0, num_buckets * sizeof (struct edge *)); |
978 | | |
979 | 433 | polygon->ymin = ymin; |
980 | 433 | polygon->ymax = ymax; |
981 | 433 | return GLITTER_STATUS_SUCCESS; |
982 | | |
983 | 0 | bail_no_mem: |
984 | 0 | polygon->ymin = 0; |
985 | 0 | polygon->ymax = 0; |
986 | 0 | return GLITTER_STATUS_NO_MEMORY; |
987 | 433 | } |
988 | | |
989 | | static void |
990 | | _polygon_insert_edge_into_its_y_bucket(struct polygon *polygon, |
991 | | struct edge *e) |
992 | 12.9k | { |
993 | 12.9k | unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); |
994 | 12.9k | struct edge **ptail = &polygon->y_buckets[ix]; |
995 | 12.9k | e->next = *ptail; |
996 | 12.9k | *ptail = e; |
997 | 12.9k | } |
998 | | |
999 | | static void |
1000 | | active_list_reset (struct active_list *active) |
1001 | 866 | { |
1002 | 866 | active->head.height_left = INT_MAX; |
1003 | 866 | active->head.dy = 0; |
1004 | 866 | active->head.cell = INT_MIN; |
1005 | 866 | active->head.prev = NULL; |
1006 | 866 | active->head.next = &active->tail; |
1007 | 866 | active->tail.prev = &active->head; |
1008 | 866 | active->tail.next = NULL; |
1009 | 866 | active->tail.cell = INT_MAX; |
1010 | 866 | active->tail.height_left = INT_MAX; |
1011 | 866 | active->tail.dy = 0; |
1012 | 866 | active->min_height = 0; |
1013 | 866 | active->is_vertical = 1; |
1014 | 866 | } |
1015 | | |
1016 | | static void |
1017 | | active_list_init(struct active_list *active) |
1018 | 433 | { |
1019 | 433 | active_list_reset(active); |
1020 | 433 | } |
1021 | | |
1022 | | /* |
1023 | | * Merge two sorted edge lists. |
1024 | | * Input: |
1025 | | * - head_a: The head of the first list. |
1026 | | * - head_b: The head of the second list; head_b cannot be NULL. |
1027 | | * Output: |
1028 | | * Returns the head of the merged list. |
1029 | | * |
1030 | | * Implementation notes: |
1031 | | * To make it fast (in particular, to reduce to an insertion sort whenever |
1032 | | * one of the two input lists only has a single element) we iterate through |
1033 | | * a list until its head becomes greater than the head of the other list, |
1034 | | * then we switch their roles. As soon as one of the two lists is empty, we |
1035 | | * just attach the other one to the current list and exit. |
1036 | | * Writes to memory are only needed to "switch" lists (as it also requires |
1037 | | * attaching to the output list the list which we will be iterating next) and |
1038 | | * to attach the last non-empty list. |
1039 | | */ |
1040 | | static struct edge * |
1041 | | merge_sorted_edges (struct edge *head_a, struct edge *head_b) |
1042 | 9.16k | { |
1043 | 9.16k | struct edge *head, **next, *prev; |
1044 | 9.16k | int32_t x; |
1045 | | |
1046 | 9.16k | prev = head_a->prev; |
1047 | 9.16k | next = &head; |
1048 | 9.16k | if (head_a->cell <= head_b->cell) { |
1049 | 5.18k | head = head_a; |
1050 | 5.18k | } else { |
1051 | 3.98k | head = head_b; |
1052 | 3.98k | head_b->prev = prev; |
1053 | 3.98k | goto start_with_b; |
1054 | 3.98k | } |
1055 | | |
1056 | 6.06k | do { |
1057 | 6.06k | x = head_b->cell; |
1058 | 18.0k | while (head_a != NULL && head_a->cell <= x) { |
1059 | 11.9k | prev = head_a; |
1060 | 11.9k | next = &head_a->next; |
1061 | 11.9k | head_a = head_a->next; |
1062 | 11.9k | } |
1063 | | |
1064 | 6.06k | head_b->prev = prev; |
1065 | 6.06k | *next = head_b; |
1066 | 6.06k | if (head_a == NULL) |
1067 | 303 | return head; |
1068 | | |
1069 | 9.74k | start_with_b: |
1070 | 9.74k | x = head_a->cell; |
1071 | 23.2k | while (head_b != NULL && head_b->cell <= x) { |
1072 | 13.4k | prev = head_b; |
1073 | 13.4k | next = &head_b->next; |
1074 | 13.4k | head_b = head_b->next; |
1075 | 13.4k | } |
1076 | | |
1077 | 9.74k | head_a->prev = prev; |
1078 | 9.74k | *next = head_a; |
1079 | 9.74k | if (head_b == NULL) |
1080 | 8.86k | return head; |
1081 | 9.74k | } while (1); |
1082 | 5.18k | } |
1083 | | |
1084 | | /* |
1085 | | * Sort (part of) a list. |
1086 | | * Input: |
1087 | | * - list: The list to be sorted; list cannot be NULL. |
1088 | | * - limit: Recursion limit. |
1089 | | * Output: |
1090 | | * - head_out: The head of the sorted list containing the first 2^(level+1) elements of the |
1091 | | * input list; if the input list has fewer elements, head_out be a sorted list |
1092 | | * containing all the elements of the input list. |
1093 | | * Returns the head of the list of unprocessed elements (NULL if the sorted list contains |
1094 | | * all the elements of the input list). |
1095 | | * |
1096 | | * Implementation notes: |
1097 | | * Special case single element list, unroll/inline the sorting of the first two elements. |
1098 | | * Some tail recursion is used since we iterate on the bottom-up solution of the problem |
1099 | | * (we start with a small sorted list and keep merging other lists of the same size to it). |
1100 | | */ |
1101 | | static struct edge * |
1102 | | sort_edges (struct edge *list, |
1103 | | unsigned int level, |
1104 | | struct edge **head_out) |
1105 | 9.16k | { |
1106 | 9.16k | struct edge *head_other, *remaining; |
1107 | 9.16k | unsigned int i; |
1108 | | |
1109 | 9.16k | head_other = list->next; |
1110 | | |
1111 | 9.16k | if (head_other == NULL) { |
1112 | 5.42k | *head_out = list; |
1113 | 5.42k | return NULL; |
1114 | 5.42k | } |
1115 | | |
1116 | 3.74k | remaining = head_other->next; |
1117 | 3.74k | if (list->cell <= head_other->cell) { |
1118 | 2.28k | *head_out = list; |
1119 | 2.28k | head_other->next = NULL; |
1120 | 2.28k | } else { |
1121 | 1.46k | *head_out = head_other; |
1122 | 1.46k | head_other->prev = list->prev; |
1123 | 1.46k | head_other->next = list; |
1124 | 1.46k | list->prev = head_other; |
1125 | 1.46k | list->next = NULL; |
1126 | 1.46k | } |
1127 | | |
1128 | 4.42k | for (i = 0; i < level && remaining; i++) { |
1129 | 679 | remaining = sort_edges (remaining, i, &head_other); |
1130 | 679 | *head_out = merge_sorted_edges (*head_out, head_other); |
1131 | 679 | } |
1132 | | |
1133 | 3.74k | return remaining; |
1134 | 9.16k | } |
1135 | | |
1136 | | static struct edge * |
1137 | | merge_unsorted_edges (struct edge *head, struct edge *unsorted) |
1138 | 8.49k | { |
1139 | 8.49k | sort_edges (unsorted, UINT_MAX, &unsorted); |
1140 | 8.49k | return merge_sorted_edges (head, unsorted); |
1141 | 8.49k | } |
1142 | | |
1143 | | /* Test if the edges on the active list can be safely advanced by a |
1144 | | * full row without intersections or any edges ending. */ |
1145 | | inline static int |
1146 | | can_do_full_row (struct active_list *active) |
1147 | 2.07k | { |
1148 | 2.07k | const struct edge *e; |
1149 | 2.07k | int prev_x = INT_MIN; |
1150 | | |
1151 | | /* Recomputes the minimum height of all edges on the active |
1152 | | * list if we have been dropping edges. */ |
1153 | 2.07k | if (active->min_height <= 0) { |
1154 | 619 | int min_height = INT_MAX; |
1155 | 619 | int is_vertical = 1; |
1156 | | |
1157 | 619 | e = active->head.next; |
1158 | 2.81k | while (NULL != e) { |
1159 | 2.19k | if (e->height_left < min_height) |
1160 | 764 | min_height = e->height_left; |
1161 | 2.19k | is_vertical &= e->dy == 0; |
1162 | 2.19k | e = e->next; |
1163 | 2.19k | } |
1164 | | |
1165 | 619 | active->is_vertical = is_vertical; |
1166 | 619 | active->min_height = min_height; |
1167 | 619 | } |
1168 | | |
1169 | 2.07k | if (active->min_height < GRID_Y) |
1170 | 235 | return 0; |
1171 | | |
1172 | | /* Check for intersections as no edges end during the next row. */ |
1173 | 6.24k | for (e = active->head.next; e != &active->tail; e = e->next) { |
1174 | 4.41k | int cell; |
1175 | | |
1176 | 4.41k | if (e->dy) { |
1177 | 3.35k | struct quorem x = e->x; |
1178 | 3.35k | x.quo += e->dxdy_full.quo; |
1179 | 3.35k | x.rem += e->dxdy_full.rem; |
1180 | 3.35k | if (x.rem < 0) { |
1181 | 581 | x.quo--; |
1182 | 581 | x.rem += e->dy; |
1183 | 2.77k | } else if (x.rem >= e->dy) { |
1184 | 1.17k | x.quo++; |
1185 | 1.17k | x.rem -= e->dy; |
1186 | 1.17k | } |
1187 | 3.35k | cell = x.quo + (x.rem >= e->dy/2); |
1188 | 3.35k | } else |
1189 | 1.06k | cell = e->cell; |
1190 | | |
1191 | 4.41k | if (cell < prev_x) |
1192 | 4 | return 0; |
1193 | | |
1194 | 4.41k | prev_x = cell; |
1195 | 4.41k | } |
1196 | | |
1197 | 1.83k | return 1; |
1198 | 1.83k | } |
1199 | | |
1200 | | /* Merges edges on the given subpixel row from the polygon to the |
1201 | | * active_list. */ |
1202 | | inline static void |
1203 | | active_list_merge_edges_from_bucket(struct active_list *active, |
1204 | | struct edge *edges) |
1205 | 8.49k | { |
1206 | 8.49k | active->head.next = merge_unsorted_edges (active->head.next, edges); |
1207 | 8.49k | } |
1208 | | |
1209 | | inline static int |
1210 | | polygon_fill_buckets (struct active_list *active, |
1211 | | struct edge *edge, |
1212 | | int y, |
1213 | | struct edge **buckets) |
1214 | 4.90k | { |
1215 | 4.90k | grid_scaled_y_t min_height = active->min_height; |
1216 | 4.90k | int is_vertical = active->is_vertical; |
1217 | 4.90k | int max_suby = 0; |
1218 | | |
1219 | 17.8k | while (edge) { |
1220 | 12.9k | struct edge *next = edge->next; |
1221 | 12.9k | int suby = edge->ytop - y; |
1222 | 12.9k | if (buckets[suby]) |
1223 | 4.42k | buckets[suby]->prev = edge; |
1224 | 12.9k | edge->next = buckets[suby]; |
1225 | 12.9k | edge->prev = NULL; |
1226 | 12.9k | buckets[suby] = edge; |
1227 | 12.9k | if (edge->height_left < min_height) |
1228 | 127 | min_height = edge->height_left; |
1229 | 12.9k | is_vertical &= edge->dy == 0; |
1230 | 12.9k | edge = next; |
1231 | 12.9k | if (suby > max_suby) |
1232 | 4.74k | max_suby = suby; |
1233 | 12.9k | } |
1234 | | |
1235 | 4.90k | active->is_vertical = is_vertical; |
1236 | 4.90k | active->min_height = min_height; |
1237 | | |
1238 | 4.90k | return max_suby; |
1239 | 4.90k | } |
1240 | | |
1241 | | static void step (struct edge *edge) |
1242 | 113k | { |
1243 | 113k | if (edge->dy == 0) |
1244 | 17.3k | return; |
1245 | | |
1246 | 95.9k | edge->x.quo += edge->dxdy.quo; |
1247 | 95.9k | edge->x.rem += edge->dxdy.rem; |
1248 | 95.9k | if (edge->x.rem < 0) { |
1249 | 20.0k | --edge->x.quo; |
1250 | 20.0k | edge->x.rem += edge->dy; |
1251 | 75.8k | } else if (edge->x.rem >= edge->dy) { |
1252 | 26.4k | ++edge->x.quo; |
1253 | 26.4k | edge->x.rem -= edge->dy; |
1254 | 26.4k | } |
1255 | | |
1256 | 95.9k | edge->cell = edge->x.quo + (edge->x.rem >= edge->dy/2); |
1257 | 95.9k | } |
1258 | | |
1259 | | inline static void |
1260 | | sub_row (struct active_list *active, |
1261 | | struct cell_list *coverages, |
1262 | | unsigned int mask) |
1263 | 45.7k | { |
1264 | 45.7k | struct edge *edge = active->head.next; |
1265 | 45.7k | int xstart = INT_MIN, prev_x = INT_MIN; |
1266 | 45.7k | int winding = 0; |
1267 | | |
1268 | 45.7k | cell_list_rewind (coverages); |
1269 | | |
1270 | 171k | while (&active->tail != edge) { |
1271 | 126k | struct edge *next = edge->next; |
1272 | 126k | int xend = edge->cell; |
1273 | | |
1274 | 126k | if (--edge->height_left) { |
1275 | 113k | step (edge); |
1276 | | |
1277 | 113k | if (edge->cell < prev_x) { |
1278 | 537 | struct edge *pos = edge->prev; |
1279 | 537 | pos->next = next; |
1280 | 537 | next->prev = pos; |
1281 | 563 | do { |
1282 | 563 | pos = pos->prev; |
1283 | 563 | } while (edge->cell < pos->cell); |
1284 | 537 | pos->next->prev = edge; |
1285 | 537 | edge->next = pos->next; |
1286 | 537 | edge->prev = pos; |
1287 | 537 | pos->next = edge; |
1288 | 537 | } else |
1289 | 112k | prev_x = edge->cell; |
1290 | 113k | active->min_height = -1; |
1291 | 113k | } else { |
1292 | 12.8k | edge->prev->next = next; |
1293 | 12.8k | next->prev = edge->prev; |
1294 | 12.8k | } |
1295 | | |
1296 | 126k | winding += edge->dir; |
1297 | 126k | if ((winding & mask) == 0) { |
1298 | 62.8k | if (next->cell != xend) { |
1299 | 62.7k | cell_list_add_subspan (coverages, xstart, xend); |
1300 | 62.7k | xstart = INT_MIN; |
1301 | 62.7k | } |
1302 | 63.2k | } else if (xstart == INT_MIN) |
1303 | 62.7k | xstart = xend; |
1304 | | |
1305 | 126k | edge = next; |
1306 | 126k | } |
1307 | 45.7k | } |
1308 | | |
1309 | | inline static void dec (struct active_list *a, struct edge *e, int h) |
1310 | 4.40k | { |
1311 | 4.40k | e->height_left -= h; |
1312 | 4.40k | if (e->height_left == 0) { |
1313 | 72 | e->prev->next = e->next; |
1314 | 72 | e->next->prev = e->prev; |
1315 | 72 | a->min_height = -1; |
1316 | 72 | } |
1317 | 4.40k | } |
1318 | | |
1319 | | static void |
1320 | | full_row (struct active_list *active, |
1321 | | struct cell_list *coverages, |
1322 | | unsigned int mask) |
1323 | 1.83k | { |
1324 | 1.83k | struct edge *left = active->head.next; |
1325 | | |
1326 | 4.02k | while (&active->tail != left) { |
1327 | 2.19k | struct edge *right; |
1328 | 2.19k | int winding; |
1329 | | |
1330 | 2.19k | dec (active, left, GRID_Y); |
1331 | | |
1332 | 2.19k | winding = left->dir; |
1333 | 2.19k | right = left->next; |
1334 | 2.20k | do { |
1335 | 2.20k | dec (active, right, GRID_Y); |
1336 | | |
1337 | 2.20k | winding += right->dir; |
1338 | 2.20k | if ((winding & mask) == 0 && right->next->cell != right->cell) |
1339 | 2.19k | break; |
1340 | | |
1341 | 10 | full_step (right); |
1342 | | |
1343 | 10 | right = right->next; |
1344 | 10 | } while (1); |
1345 | | |
1346 | 2.19k | cell_list_set_rewind (coverages); |
1347 | 2.19k | cell_list_render_edge (coverages, left, +1); |
1348 | 2.19k | cell_list_render_edge (coverages, right, -1); |
1349 | | |
1350 | 2.19k | left = right->next; |
1351 | 2.19k | } |
1352 | 1.83k | } |
1353 | | |
1354 | | static void |
1355 | | _glitter_scan_converter_init(glitter_scan_converter_t *converter, jmp_buf *jmp) |
1356 | 433 | { |
1357 | 433 | polygon_init(converter->polygon, jmp); |
1358 | 433 | active_list_init(converter->active); |
1359 | 433 | cell_list_init(converter->coverages, jmp); |
1360 | 433 | converter->xmin=0; |
1361 | 433 | converter->ymin=0; |
1362 | 433 | converter->xmax=0; |
1363 | 433 | converter->ymax=0; |
1364 | 433 | } |
1365 | | |
1366 | | static void |
1367 | | _glitter_scan_converter_fini(glitter_scan_converter_t *self) |
1368 | 433 | { |
1369 | 433 | if (self->spans != self->spans_embedded) |
1370 | 107 | free (self->spans); |
1371 | | |
1372 | 433 | polygon_fini(self->polygon); |
1373 | 433 | cell_list_fini(self->coverages); |
1374 | | |
1375 | 433 | self->xmin=0; |
1376 | 433 | self->ymin=0; |
1377 | 433 | self->xmax=0; |
1378 | 433 | self->ymax=0; |
1379 | 433 | } |
1380 | | |
1381 | | static grid_scaled_t |
1382 | | int_to_grid_scaled(int i, int scale) |
1383 | 1.73k | { |
1384 | | /* Clamp to max/min representable scaled number. */ |
1385 | 1.73k | if (i >= 0) { |
1386 | 1.73k | if (i >= INT_MAX/scale) |
1387 | 0 | i = INT_MAX/scale; |
1388 | 1.73k | } |
1389 | 0 | else { |
1390 | 0 | if (i <= INT_MIN/scale) |
1391 | 0 | i = INT_MIN/scale; |
1392 | 0 | } |
1393 | 1.73k | return i*scale; |
1394 | 1.73k | } |
1395 | | |
1396 | 866 | #define int_to_grid_scaled_x(x) int_to_grid_scaled((x), GRID_X) |
1397 | 866 | #define int_to_grid_scaled_y(x) int_to_grid_scaled((x), GRID_Y) |
1398 | | |
1399 | | I glitter_status_t |
1400 | | glitter_scan_converter_reset( |
1401 | | glitter_scan_converter_t *converter, |
1402 | | int xmin, int ymin, |
1403 | | int xmax, int ymax) |
1404 | 433 | { |
1405 | 433 | glitter_status_t status; |
1406 | 433 | int max_num_spans; |
1407 | | |
1408 | 433 | converter->xmin = 0; converter->xmax = 0; |
1409 | 433 | converter->ymin = 0; converter->ymax = 0; |
1410 | | |
1411 | 433 | max_num_spans = xmax - xmin + 1; |
1412 | | |
1413 | 433 | if (max_num_spans > ARRAY_LENGTH(converter->spans_embedded)) { |
1414 | 107 | converter->spans = _cairo_malloc_ab (max_num_spans, |
1415 | 107 | sizeof (cairo_half_open_span_t)); |
1416 | 107 | if (unlikely (converter->spans == NULL)) |
1417 | 0 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
1418 | 107 | } else |
1419 | 326 | converter->spans = converter->spans_embedded; |
1420 | | |
1421 | 433 | xmin = int_to_grid_scaled_x(xmin); |
1422 | 433 | ymin = int_to_grid_scaled_y(ymin); |
1423 | 433 | xmax = int_to_grid_scaled_x(xmax); |
1424 | 433 | ymax = int_to_grid_scaled_y(ymax); |
1425 | | |
1426 | 433 | active_list_reset(converter->active); |
1427 | 433 | cell_list_reset(converter->coverages); |
1428 | 433 | status = polygon_reset(converter->polygon, ymin, ymax); |
1429 | 433 | if (status) |
1430 | 0 | return status; |
1431 | | |
1432 | 433 | converter->xmin = xmin; |
1433 | 433 | converter->xmax = xmax; |
1434 | 433 | converter->ymin = ymin; |
1435 | 433 | converter->ymax = ymax; |
1436 | 433 | return GLITTER_STATUS_SUCCESS; |
1437 | 433 | } |
1438 | | |
1439 | | /* INPUT_TO_GRID_X/Y (in_coord, out_grid_scaled, grid_scale) |
1440 | | * These macros convert an input coordinate in the client's |
1441 | | * device space to the rasterisation grid. |
1442 | | */ |
1443 | | /* Gah.. this bit of ugly defines INPUT_TO_GRID_X/Y so as to use |
1444 | | * shifts if possible, and something saneish if not. |
1445 | | */ |
1446 | | #if !defined(INPUT_TO_GRID_Y) && defined(GRID_Y_BITS) && GRID_Y_BITS <= GLITTER_INPUT_BITS |
1447 | | # define INPUT_TO_GRID_Y(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_Y_BITS) |
1448 | | #else |
1449 | 26.9k | # define INPUT_TO_GRID_Y(in, out) INPUT_TO_GRID_general(in, out, GRID_Y) |
1450 | | #endif |
1451 | | |
1452 | | #if !defined(INPUT_TO_GRID_X) && defined(GRID_X_BITS) && GRID_X_BITS <= GLITTER_INPUT_BITS |
1453 | | # define INPUT_TO_GRID_X(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_X_BITS) |
1454 | | #else |
1455 | | # define INPUT_TO_GRID_X(in, out) INPUT_TO_GRID_general(in, out, GRID_X) |
1456 | | #endif |
1457 | | |
1458 | 26.9k | #define INPUT_TO_GRID_general(in, out, grid_scale) do { \ |
1459 | 26.9k | long long tmp__ = (long long)(grid_scale) * (in); \ |
1460 | 26.9k | tmp__ += 1 << (GLITTER_INPUT_BITS-1); \ |
1461 | 26.9k | tmp__ >>= GLITTER_INPUT_BITS; \ |
1462 | 26.9k | (out) = tmp__; \ |
1463 | 26.9k | } while (0) |
1464 | | |
1465 | | inline static void |
1466 | | polygon_add_edge (struct polygon *polygon, |
1467 | | const cairo_edge_t *edge) |
1468 | 13.4k | { |
1469 | 13.4k | struct edge *e; |
1470 | 13.4k | grid_scaled_y_t ytop, ybot; |
1471 | 13.4k | const cairo_point_t *p1, *p2; |
1472 | | |
1473 | 13.4k | INPUT_TO_GRID_Y (edge->top, ytop); |
1474 | 13.4k | if (ytop < polygon->ymin) |
1475 | 0 | ytop = polygon->ymin; |
1476 | | |
1477 | 13.4k | INPUT_TO_GRID_Y (edge->bottom, ybot); |
1478 | 13.4k | if (ybot > polygon->ymax) |
1479 | 0 | ybot = polygon->ymax; |
1480 | | |
1481 | 13.4k | if (ybot <= ytop) |
1482 | 507 | return; |
1483 | | |
1484 | 12.9k | e = pool_alloc (polygon->edge_pool.base, sizeof (struct edge)); |
1485 | | |
1486 | 12.9k | e->ytop = ytop; |
1487 | 12.9k | e->height_left = ybot - ytop; |
1488 | 12.9k | if (edge->line.p2.y > edge->line.p1.y) { |
1489 | 12.9k | e->dir = edge->dir; |
1490 | 12.9k | p1 = &edge->line.p1; |
1491 | 12.9k | p2 = &edge->line.p2; |
1492 | 12.9k | } else { |
1493 | 0 | e->dir = -edge->dir; |
1494 | 0 | p1 = &edge->line.p2; |
1495 | 0 | p2 = &edge->line.p1; |
1496 | 0 | } |
1497 | | |
1498 | 12.9k | if (p2->x == p1->x) { |
1499 | 824 | e->cell = p1->x; |
1500 | 824 | e->x.quo = p1->x; |
1501 | 824 | e->x.rem = 0; |
1502 | 824 | e->dxdy.quo = e->dxdy.rem = 0; |
1503 | 824 | e->dxdy_full.quo = e->dxdy_full.rem = 0; |
1504 | 824 | e->dy = 0; |
1505 | 12.1k | } else { |
1506 | 12.1k | int64_t Ex, Ey, tmp; |
1507 | | |
1508 | 12.1k | Ex = (int64_t)(p2->x - p1->x) * GRID_X; |
1509 | 12.1k | Ey = (int64_t)(p2->y - p1->y) * GRID_Y * (2 << GLITTER_INPUT_BITS); |
1510 | | |
1511 | 12.1k | e->dxdy.quo = Ex * (2 << GLITTER_INPUT_BITS) / Ey; |
1512 | 12.1k | e->dxdy.rem = Ex * (2 << GLITTER_INPUT_BITS) % Ey; |
1513 | | |
1514 | 12.1k | tmp = (int64_t)(2*ytop + 1) << GLITTER_INPUT_BITS; |
1515 | 12.1k | tmp -= (int64_t)p1->y * GRID_Y * 2; |
1516 | 12.1k | tmp *= Ex; |
1517 | 12.1k | e->x.quo = tmp / Ey; |
1518 | 12.1k | e->x.rem = tmp % Ey; |
1519 | | |
1520 | 12.1k | #if GRID_X_BITS == GLITTER_INPUT_BITS |
1521 | 12.1k | e->x.quo += p1->x; |
1522 | | #else |
1523 | | tmp = (int64_t)p1->x * GRID_X; |
1524 | | e->x.quo += tmp >> GLITTER_INPUT_BITS; |
1525 | | e->x.rem += ((tmp & ((1 << GLITTER_INPUT_BITS) - 1)) * Ey) / (1 << GLITTER_INPUT_BITS); |
1526 | | #endif |
1527 | | |
1528 | 12.1k | if (e->x.rem < 0) { |
1529 | 5.36k | e->x.quo--; |
1530 | 5.36k | e->x.rem += Ey; |
1531 | 6.76k | } else if (e->x.rem >= Ey) { |
1532 | 0 | e->x.quo++; |
1533 | 0 | e->x.rem -= Ey; |
1534 | 0 | } |
1535 | | |
1536 | 12.1k | if (e->height_left >= GRID_Y) { |
1537 | 2.27k | tmp = Ex * (2 * GRID_Y << GLITTER_INPUT_BITS); |
1538 | 2.27k | e->dxdy_full.quo = tmp / Ey; |
1539 | 2.27k | e->dxdy_full.rem = tmp % Ey; |
1540 | 2.27k | } else |
1541 | 9.85k | e->dxdy_full.quo = e->dxdy_full.rem = 0; |
1542 | | |
1543 | 12.1k | e->cell = e->x.quo + (e->x.rem >= Ey/2); |
1544 | 12.1k | e->dy = Ey; |
1545 | 12.1k | } |
1546 | | |
1547 | 12.9k | _polygon_insert_edge_into_its_y_bucket (polygon, e); |
1548 | 12.9k | } |
1549 | | |
1550 | | /* Add a new polygon edge from pixel (x1,y1) to (x2,y2) to the scan |
1551 | | * converter. The coordinates represent pixel positions scaled by |
1552 | | * 2**GLITTER_PIXEL_BITS. If this function fails then the scan |
1553 | | * converter should be reset or destroyed. Dir must be +1 or -1, |
1554 | | * with the latter reversing the orientation of the edge. */ |
1555 | | I void |
1556 | | glitter_scan_converter_add_edge (glitter_scan_converter_t *converter, |
1557 | | const cairo_edge_t *edge) |
1558 | 13.4k | { |
1559 | 13.4k | polygon_add_edge (converter->polygon, edge); |
1560 | 13.4k | } |
1561 | | |
1562 | | static void |
1563 | | step_edges (struct active_list *active, int count) |
1564 | 189 | { |
1565 | 189 | struct edge *edge; |
1566 | | |
1567 | 189 | count *= GRID_Y; |
1568 | 657 | for (edge = active->head.next; edge != &active->tail; edge = edge->next) { |
1569 | 468 | edge->height_left -= count; |
1570 | 468 | if (! edge->height_left) { |
1571 | 28 | edge->prev->next = edge->next; |
1572 | 28 | edge->next->prev = edge->prev; |
1573 | 28 | active->min_height = -1; |
1574 | 28 | } |
1575 | 468 | } |
1576 | 189 | } |
1577 | | |
1578 | | static glitter_status_t |
1579 | | blit_a8 (struct cell_list *cells, |
1580 | | cairo_span_renderer_t *renderer, |
1581 | | cairo_half_open_span_t *spans, |
1582 | | int y, int height, |
1583 | | int xmin, int xmax) |
1584 | 4.88k | { |
1585 | 4.88k | struct cell *cell = cells->head.next; |
1586 | 4.88k | int prev_x = xmin, last_x = -1; |
1587 | 4.88k | int16_t cover = 0, last_cover = 0; |
1588 | 4.88k | unsigned num_spans; |
1589 | | |
1590 | 4.88k | if (cell == &cells->tail) |
1591 | 1 | return CAIRO_STATUS_SUCCESS; |
1592 | | |
1593 | | /* Skip cells to the left of the clip region. */ |
1594 | 4.87k | while (cell->x < xmin) { |
1595 | 0 | cover += cell->covered_height; |
1596 | 0 | cell = cell->next; |
1597 | 0 | } |
1598 | 4.87k | cover *= GRID_X*2; |
1599 | | |
1600 | | /* Form the spans from the coverages and areas. */ |
1601 | 4.87k | num_spans = 0; |
1602 | 25.9k | for (; cell->x < xmax; cell = cell->next) { |
1603 | 21.0k | int x = cell->x; |
1604 | 21.0k | int16_t area; |
1605 | | |
1606 | 21.0k | if (x > prev_x && cover != last_cover) { |
1607 | 5.85k | spans[num_spans].x = prev_x; |
1608 | 5.85k | spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); |
1609 | 5.85k | last_cover = cover; |
1610 | 5.85k | last_x = prev_x; |
1611 | 5.85k | ++num_spans; |
1612 | 5.85k | } |
1613 | | |
1614 | 21.0k | cover += cell->covered_height*GRID_X*2; |
1615 | 21.0k | area = cover - cell->uncovered_area; |
1616 | | |
1617 | 21.0k | if (area != last_cover) { |
1618 | 20.8k | spans[num_spans].x = x; |
1619 | 20.8k | spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area); |
1620 | 20.8k | last_cover = area; |
1621 | 20.8k | last_x = x; |
1622 | 20.8k | ++num_spans; |
1623 | 20.8k | } |
1624 | | |
1625 | 21.0k | prev_x = x+1; |
1626 | 21.0k | } |
1627 | | |
1628 | 4.87k | if (prev_x <= xmax && cover != last_cover) { |
1629 | 4.83k | spans[num_spans].x = prev_x; |
1630 | 4.83k | spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); |
1631 | 4.83k | last_cover = cover; |
1632 | 4.83k | last_x = prev_x; |
1633 | 4.83k | ++num_spans; |
1634 | 4.83k | } |
1635 | | |
1636 | 4.87k | if (last_x < xmax && last_cover) { |
1637 | 110 | spans[num_spans].x = xmax; |
1638 | 110 | spans[num_spans].coverage = 0; |
1639 | 110 | ++num_spans; |
1640 | 110 | } |
1641 | | |
1642 | | /* Dump them into the renderer. */ |
1643 | 4.87k | return renderer->render_rows (renderer, y, height, spans, num_spans); |
1644 | 4.88k | } |
1645 | | |
1646 | 0 | #define GRID_AREA_TO_A1(A) ((GRID_AREA_TO_ALPHA (A) > 127) ? 255 : 0) |
1647 | | static glitter_status_t |
1648 | | blit_a1 (struct cell_list *cells, |
1649 | | cairo_span_renderer_t *renderer, |
1650 | | cairo_half_open_span_t *spans, |
1651 | | int y, int height, |
1652 | | int xmin, int xmax) |
1653 | 0 | { |
1654 | 0 | struct cell *cell = cells->head.next; |
1655 | 0 | int prev_x = xmin, last_x = -1; |
1656 | 0 | int16_t cover = 0; |
1657 | 0 | uint8_t coverage, last_cover = 0; |
1658 | 0 | unsigned num_spans; |
1659 | |
|
1660 | 0 | if (cell == &cells->tail) |
1661 | 0 | return CAIRO_STATUS_SUCCESS; |
1662 | | |
1663 | | /* Skip cells to the left of the clip region. */ |
1664 | 0 | while (cell->x < xmin) { |
1665 | 0 | cover += cell->covered_height; |
1666 | 0 | cell = cell->next; |
1667 | 0 | } |
1668 | 0 | cover *= GRID_X*2; |
1669 | | |
1670 | | /* Form the spans from the coverages and areas. */ |
1671 | 0 | num_spans = 0; |
1672 | 0 | for (; cell->x < xmax; cell = cell->next) { |
1673 | 0 | int x = cell->x; |
1674 | 0 | int16_t area; |
1675 | |
|
1676 | 0 | coverage = GRID_AREA_TO_A1 (cover); |
1677 | 0 | if (x > prev_x && coverage != last_cover) { |
1678 | 0 | last_x = spans[num_spans].x = prev_x; |
1679 | 0 | last_cover = spans[num_spans].coverage = coverage; |
1680 | 0 | ++num_spans; |
1681 | 0 | } |
1682 | |
|
1683 | 0 | cover += cell->covered_height*GRID_X*2; |
1684 | 0 | area = cover - cell->uncovered_area; |
1685 | |
|
1686 | 0 | coverage = GRID_AREA_TO_A1 (area); |
1687 | 0 | if (coverage != last_cover) { |
1688 | 0 | last_x = spans[num_spans].x = x; |
1689 | 0 | last_cover = spans[num_spans].coverage = coverage; |
1690 | 0 | ++num_spans; |
1691 | 0 | } |
1692 | |
|
1693 | 0 | prev_x = x+1; |
1694 | 0 | } |
1695 | |
|
1696 | 0 | coverage = GRID_AREA_TO_A1 (cover); |
1697 | 0 | if (prev_x <= xmax && coverage != last_cover) { |
1698 | 0 | last_x = spans[num_spans].x = prev_x; |
1699 | 0 | last_cover = spans[num_spans].coverage = coverage; |
1700 | 0 | ++num_spans; |
1701 | 0 | } |
1702 | |
|
1703 | 0 | if (last_x < xmax && last_cover) { |
1704 | 0 | spans[num_spans].x = xmax; |
1705 | 0 | spans[num_spans].coverage = 0; |
1706 | 0 | ++num_spans; |
1707 | 0 | } |
1708 | 0 | if (num_spans == 1) |
1709 | 0 | return CAIRO_STATUS_SUCCESS; |
1710 | | |
1711 | | /* Dump them into the renderer. */ |
1712 | 0 | return renderer->render_rows (renderer, y, height, spans, num_spans); |
1713 | 0 | } |
1714 | | |
1715 | | |
1716 | | I void |
1717 | | glitter_scan_converter_render(glitter_scan_converter_t *converter, |
1718 | | unsigned int winding_mask, |
1719 | | int antialias, |
1720 | | cairo_span_renderer_t *renderer) |
1721 | 425 | { |
1722 | 425 | int i, j; |
1723 | 425 | int ymax_i = converter->ymax / GRID_Y; |
1724 | 425 | int ymin_i = converter->ymin / GRID_Y; |
1725 | 425 | int xmin_i, xmax_i; |
1726 | 425 | int h = ymax_i - ymin_i; |
1727 | 425 | struct polygon *polygon = converter->polygon; |
1728 | 425 | struct cell_list *coverages = converter->coverages; |
1729 | 425 | struct active_list *active = converter->active; |
1730 | 425 | struct edge *buckets[GRID_Y] = { 0 }; |
1731 | | |
1732 | 425 | xmin_i = converter->xmin / GRID_X; |
1733 | 425 | xmax_i = converter->xmax / GRID_X; |
1734 | 425 | if (xmin_i >= xmax_i) |
1735 | 0 | return; |
1736 | | |
1737 | | /* Render each pixel row. */ |
1738 | 5.32k | for (i = 0; i < h; i = j) { |
1739 | 4.90k | int do_full_row = 0; |
1740 | | |
1741 | 4.90k | j = i + 1; |
1742 | | |
1743 | | /* Determine if we can ignore this row or use the full pixel |
1744 | | * stepper. */ |
1745 | 4.90k | if (polygon_fill_buckets (active, |
1746 | 4.90k | polygon->y_buckets[i], |
1747 | 4.90k | (i+ymin_i)*GRID_Y, |
1748 | 4.90k | buckets) == 0) { |
1749 | 2.09k | if (buckets[0]) { |
1750 | 90 | active_list_merge_edges_from_bucket (active, buckets[0]); |
1751 | 90 | buckets[0] = NULL; |
1752 | 90 | } |
1753 | | |
1754 | 2.09k | if (active->head.next == &active->tail) { |
1755 | 24 | active->min_height = INT_MAX; |
1756 | 24 | active->is_vertical = 1; |
1757 | 106 | for (; j < h && ! polygon->y_buckets[j]; j++) |
1758 | 82 | ; |
1759 | 24 | continue; |
1760 | 24 | } |
1761 | | |
1762 | 2.07k | do_full_row = can_do_full_row (active); |
1763 | 2.07k | } |
1764 | | |
1765 | 4.88k | if (do_full_row) { |
1766 | | /* Step by a full pixel row's worth. */ |
1767 | 1.83k | full_row (active, coverages, winding_mask); |
1768 | | |
1769 | 1.83k | if (active->is_vertical) { |
1770 | 8.88k | while (j < h && |
1771 | 8.87k | polygon->y_buckets[j] == NULL && |
1772 | 8.79k | active->min_height >= 2*GRID_Y) |
1773 | 8.64k | { |
1774 | 8.64k | active->min_height -= GRID_Y; |
1775 | 8.64k | j++; |
1776 | 8.64k | } |
1777 | 235 | if (j != i + 1) |
1778 | 189 | step_edges (active, j - (i + 1)); |
1779 | 235 | } |
1780 | 3.04k | } else { |
1781 | 3.04k | int sub; |
1782 | | |
1783 | | /* Subsample this row. */ |
1784 | 48.7k | for (sub = 0; sub < GRID_Y; sub++) { |
1785 | 45.7k | if (buckets[sub]) { |
1786 | 8.40k | active_list_merge_edges_from_bucket (active, buckets[sub]); |
1787 | 8.40k | buckets[sub] = NULL; |
1788 | 8.40k | } |
1789 | 45.7k | sub_row (active, coverages, winding_mask); |
1790 | 45.7k | } |
1791 | 3.04k | } |
1792 | | |
1793 | 4.88k | if (antialias) |
1794 | 4.88k | blit_a8 (coverages, renderer, converter->spans, |
1795 | 4.88k | i+ymin_i, j-i, xmin_i, xmax_i); |
1796 | 0 | else |
1797 | 0 | blit_a1 (coverages, renderer, converter->spans, |
1798 | 0 | i+ymin_i, j-i, xmin_i, xmax_i); |
1799 | 4.88k | cell_list_reset (coverages); |
1800 | | |
1801 | 4.88k | active->min_height -= GRID_Y; |
1802 | 4.88k | } |
1803 | 425 | } |
1804 | | |
1805 | | struct _cairo_tor_scan_converter { |
1806 | | cairo_scan_converter_t base; |
1807 | | |
1808 | | glitter_scan_converter_t converter[1]; |
1809 | | cairo_fill_rule_t fill_rule; |
1810 | | cairo_antialias_t antialias; |
1811 | | |
1812 | | jmp_buf jmp; |
1813 | | }; |
1814 | | |
1815 | | typedef struct _cairo_tor_scan_converter cairo_tor_scan_converter_t; |
1816 | | |
1817 | | static void |
1818 | | _cairo_tor_scan_converter_destroy (void *converter) |
1819 | 433 | { |
1820 | 433 | cairo_tor_scan_converter_t *self = converter; |
1821 | 433 | if (self == NULL) { |
1822 | 0 | return; |
1823 | 0 | } |
1824 | 433 | _glitter_scan_converter_fini (self->converter); |
1825 | 433 | free(self); |
1826 | 433 | } |
1827 | | |
1828 | | cairo_status_t |
1829 | | _cairo_tor_scan_converter_add_polygon (void *converter, |
1830 | | const cairo_polygon_t *polygon) |
1831 | 433 | { |
1832 | 433 | cairo_tor_scan_converter_t *self = converter; |
1833 | 433 | cairo_status_t status; |
1834 | 433 | int i; |
1835 | | |
1836 | | #if 0 |
1837 | | FILE *file = fopen ("polygon.txt", "w"); |
1838 | | _cairo_debug_print_polygon (file, polygon); |
1839 | | fclose (file); |
1840 | | #endif |
1841 | | |
1842 | 433 | if ((status = setjmp (self->jmp))) |
1843 | 0 | return _cairo_scan_converter_set_error (self, _cairo_error (status)); |
1844 | | |
1845 | 13.8k | for (i = 0; i < polygon->num_edges; i++) |
1846 | 13.4k | glitter_scan_converter_add_edge (self->converter, &polygon->edges[i]); |
1847 | | |
1848 | 433 | return CAIRO_STATUS_SUCCESS; |
1849 | 433 | } |
1850 | | |
1851 | | static cairo_status_t |
1852 | | _cairo_tor_scan_converter_generate (void *converter, |
1853 | | cairo_span_renderer_t *renderer) |
1854 | 425 | { |
1855 | 425 | cairo_tor_scan_converter_t *self = converter; |
1856 | 425 | cairo_status_t status; |
1857 | | |
1858 | 425 | if ((status = setjmp (self->jmp))) |
1859 | 0 | return _cairo_scan_converter_set_error (self, _cairo_error (status)); |
1860 | | |
1861 | 425 | glitter_scan_converter_render (self->converter, |
1862 | 425 | self->fill_rule == CAIRO_FILL_RULE_WINDING ? ~0 : 1, |
1863 | 425 | self->antialias != CAIRO_ANTIALIAS_NONE, |
1864 | 425 | renderer); |
1865 | 425 | return CAIRO_STATUS_SUCCESS; |
1866 | 425 | } |
1867 | | |
1868 | | cairo_scan_converter_t * |
1869 | | _cairo_tor_scan_converter_create (int xmin, |
1870 | | int ymin, |
1871 | | int xmax, |
1872 | | int ymax, |
1873 | | cairo_fill_rule_t fill_rule, |
1874 | | cairo_antialias_t antialias) |
1875 | 433 | { |
1876 | 433 | cairo_tor_scan_converter_t *self; |
1877 | 433 | cairo_status_t status; |
1878 | | |
1879 | 433 | self = _cairo_calloc (sizeof(struct _cairo_tor_scan_converter)); |
1880 | 433 | if (unlikely (self == NULL)) { |
1881 | 0 | status = _cairo_error (CAIRO_STATUS_NO_MEMORY); |
1882 | 0 | goto bail_nomem; |
1883 | 0 | } |
1884 | | |
1885 | 433 | self->base.destroy = _cairo_tor_scan_converter_destroy; |
1886 | 433 | self->base.generate = _cairo_tor_scan_converter_generate; |
1887 | | |
1888 | 433 | _glitter_scan_converter_init (self->converter, &self->jmp); |
1889 | 433 | status = glitter_scan_converter_reset (self->converter, |
1890 | 433 | xmin, ymin, xmax, ymax); |
1891 | 433 | if (unlikely (status)) |
1892 | 0 | goto bail; |
1893 | | |
1894 | 433 | self->fill_rule = fill_rule; |
1895 | 433 | self->antialias = antialias; |
1896 | | |
1897 | 433 | return &self->base; |
1898 | | |
1899 | 0 | bail: |
1900 | 0 | self->base.destroy(&self->base); |
1901 | 0 | bail_nomem: |
1902 | 0 | return _cairo_scan_converter_create_in_error (status); |
1903 | 0 | } |