Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1892 Rev 3959
Line 31... Line 31...
31
 *	Chris Wilson 
31
 *	Chris Wilson 
32
 */
32
 */
Line 33... Line 33...
33
 
33
 
Line -... Line 34...
-
 
34
#include "cairoint.h"
34
#include "cairoint.h"
35
 
35
 
36
#include "cairo-box-inline.h"
Line 36... Line 37...
36
#include "cairo-boxes-private.h"
37
#include "cairo-boxes-private.h"
37
#include "cairo-error-private.h"
38
#include "cairo-error-private.h"
Line 51... Line 52...
51
 
52
 
52
    boxes->is_pixel_aligned = TRUE;
53
    boxes->is_pixel_aligned = TRUE;
Line 53... Line 54...
53
}
54
}
-
 
55
 
-
 
56
void
-
 
57
_cairo_boxes_init_from_rectangle (cairo_boxes_t *boxes,
-
 
58
				  int x, int y, int w, int h)
-
 
59
{
-
 
60
    _cairo_boxes_init (boxes);
-
 
61
 
-
 
62
    _cairo_box_from_integers (&boxes->chunks.base[0], x, y, w, h);
-
 
63
    boxes->num_boxes = 1;
-
 
64
}
-
 
65
 
-
 
66
void
-
 
67
_cairo_boxes_init_with_clip (cairo_boxes_t *boxes,
-
 
68
			     cairo_clip_t *clip)
-
 
69
{
-
 
70
    _cairo_boxes_init (boxes);
-
 
71
    if (clip)
-
 
72
	_cairo_boxes_limit (boxes, clip->boxes, clip->num_boxes);
-
 
73
}
54
 
74
 
55
void
75
void
56
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
76
_cairo_boxes_init_for_array (cairo_boxes_t *boxes,
57
			     cairo_box_t *array,
77
			     cairo_box_t *array,
58
			     int num_boxes)
78
			     int num_boxes)
Line 143... Line 163...
143
    }
163
    }
Line 144... Line 164...
144
 
164
 
145
    chunk->base[chunk->count++] = *box;
165
    chunk->base[chunk->count++] = *box;
Line 146... Line 166...
146
    boxes->num_boxes++;
166
    boxes->num_boxes++;
147
 
167
 
148
    if (boxes->is_pixel_aligned) {
-
 
149
	boxes->is_pixel_aligned =
-
 
150
	    _cairo_fixed_is_integer (box->p1.x) &&
-
 
151
	    _cairo_fixed_is_integer (box->p1.y) &&
-
 
152
	    _cairo_fixed_is_integer (box->p2.x) &&
-
 
153
	    _cairo_fixed_is_integer (box->p2.y);
168
    if (boxes->is_pixel_aligned)
Line 154... Line 169...
154
    }
169
	boxes->is_pixel_aligned = _cairo_box_is_pixel_aligned (box);
155
}
170
}
-
 
171
 
156
 
172
cairo_status_t
157
cairo_status_t
173
_cairo_boxes_add (cairo_boxes_t *boxes,
-
 
174
		  cairo_antialias_t antialias,
-
 
175
		  const cairo_box_t *box)
-
 
176
{
-
 
177
    cairo_box_t b;
-
 
178
 
-
 
179
    if (antialias == CAIRO_ANTIALIAS_NONE) {
-
 
180
	b.p1.x = _cairo_fixed_round_down (box->p1.x);
-
 
181
	b.p1.y = _cairo_fixed_round_down (box->p1.y);
-
 
182
	b.p2.x = _cairo_fixed_round_down (box->p2.x);
-
 
183
	b.p2.y = _cairo_fixed_round_down (box->p2.y);
158
_cairo_boxes_add (cairo_boxes_t *boxes,
184
	box = &b;
159
		  const cairo_box_t *box)
185
    }
Line 160... Line 186...
160
{
186
 
161
    if (box->p1.y == box->p2.y)
187
    if (box->p1.y == box->p2.y)
Line 239... Line 265...
239
    return boxes->status;
265
    return boxes->status;
240
}
266
}
Line 241... Line 267...
241
 
267
 
242
void
268
void
243
_cairo_boxes_extents (const cairo_boxes_t *boxes,
269
_cairo_boxes_extents (const cairo_boxes_t *boxes,
244
		      cairo_rectangle_int_t *extents)
270
		      cairo_box_t *box)
245
{
271
{
246
    const struct _cairo_boxes_chunk *chunk;
272
    const struct _cairo_boxes_chunk *chunk;
247
    cairo_box_t box;
273
    cairo_box_t b;
Line 248... Line 274...
248
    int i;
274
    int i;
249
 
275
 
-
 
276
    if (boxes->num_boxes == 0) {
-
 
277
	box->p1.x = box->p1.y = box->p2.x = box->p2.y = 0;
Line -... Line 278...
-
 
278
	return;
250
    box.p1.y = box.p1.x = INT_MAX;
279
    }
251
    box.p2.y = box.p2.x = INT_MIN;
-
 
252
 
280
 
253
    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
281
    b = boxes->chunks.base[0];
254
	const cairo_box_t *b = chunk->base;
282
    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
Line 255... Line 283...
255
	for (i = 0; i < chunk->count; i++) {
283
	for (i = 0; i < chunk->count; i++) {
256
	    if (b[i].p1.x < box.p1.x)
284
	    if (chunk->base[i].p1.x < b.p1.x)
Line 257... Line 285...
257
		box.p1.x = b[i].p1.x;
285
		b.p1.x = chunk->base[i].p1.x;
258
 
286
 
Line 259... Line 287...
259
	    if (b[i].p1.y < box.p1.y)
287
	    if (chunk->base[i].p1.y < b.p1.y)
260
		box.p1.y = b[i].p1.y;
288
		b.p1.y = chunk->base[i].p1.y;
261
 
289
 
262
	    if (b[i].p2.x > box.p2.x)
290
	    if (chunk->base[i].p2.x > b.p2.x)
263
		box.p2.x = b[i].p2.x;
-
 
264
 
291
		b.p2.x = chunk->base[i].p2.x;
265
	    if (b[i].p2.y > box.p2.y)
292
 
Line 266... Line 293...
266
		box.p2.y = b[i].p2.y;
293
	    if (chunk->base[i].p2.y > b.p2.y)
267
	}
294
		b.p2.y = chunk->base[i].p2.y;
268
    }
295
	}
Line 281... Line 308...
281
    }
308
    }
Line 282... Line 309...
282
 
309
 
283
    boxes->tail = &boxes->chunks;
310
    boxes->tail = &boxes->chunks;
284
    boxes->chunks.next = 0;
311
    boxes->chunks.next = 0;
-
 
312
    boxes->chunks.count = 0;
-
 
313
    boxes->chunks.base = boxes->boxes_embedded;
285
    boxes->chunks.count = 0;
314
    boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded);
Line 286... Line 315...
286
    boxes->num_boxes = 0;
315
    boxes->num_boxes = 0;
287
 
316
 
Line -... Line 317...
-
 
317
    boxes->is_pixel_aligned = TRUE;
-
 
318
}
-
 
319
 
-
 
320
cairo_box_t *
-
 
321
_cairo_boxes_to_array (const cairo_boxes_t *boxes,
-
 
322
		       int *num_boxes,
-
 
323
		       cairo_bool_t force_allocation)
-
 
324
{
-
 
325
    const struct _cairo_boxes_chunk *chunk;
-
 
326
    cairo_box_t *box;
-
 
327
    int i, j;
-
 
328
 
-
 
329
    *num_boxes = boxes->num_boxes;
-
 
330
    if (boxes->chunks.next == NULL && ! force_allocation)
-
 
331
	    return boxes->chunks.base;
-
 
332
 
-
 
333
    box = _cairo_malloc_ab (boxes->num_boxes, sizeof (cairo_box_t));
-
 
334
    if (box == NULL) {
-
 
335
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-
 
336
	return NULL;
-
 
337
    }
-
 
338
 
-
 
339
    j = 0;
-
 
340
    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
-
 
341
	for (i = 0; i < chunk->count; i++)
-
 
342
	    box[j++] = chunk->base[i];
-
 
343
    }
-
 
344
 
288
    boxes->is_pixel_aligned = TRUE;
345
    return box;
289
}
346
}
290
 
347
 
291
void
348
void
Line 292... Line 349...
292
_cairo_boxes_fini (cairo_boxes_t *boxes)
349
_cairo_boxes_fini (cairo_boxes_t *boxes)
293
{
350
{
294
    struct _cairo_boxes_chunk *chunk, *next;
351
    struct _cairo_boxes_chunk *chunk, *next;
295
 
352
 
296
    for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
353
    for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) {
-
 
354
	next = chunk->next;
-
 
355
	free (chunk);
-
 
356
    }
-
 
357
}
-
 
358
 
-
 
359
cairo_bool_t
-
 
360
_cairo_boxes_for_each_box (cairo_boxes_t *boxes,
-
 
361
			   cairo_bool_t (*func) (cairo_box_t *box, void *data),
-
 
362
			   void *data)
-
 
363
{
-
 
364
    struct _cairo_boxes_chunk *chunk;
-
 
365
    int i;
-
 
366
 
-
 
367
    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
-
 
368
	for (i = 0; i < chunk->count; i++)
-
 
369
	    if (! func (&chunk->base[i], data))
-
 
370
		return FALSE;
-
 
371
    }
-
 
372
 
-
 
373
    return TRUE;
-
 
374
}
-
 
375
 
-
 
376
struct cairo_box_renderer {
-
 
377
    cairo_span_renderer_t base;
-
 
378
    cairo_boxes_t *boxes;
-
 
379
};
-
 
380
 
-
 
381
static cairo_status_t
-
 
382
span_to_boxes (void *abstract_renderer, int y, int h,
-
 
383
	       const cairo_half_open_span_t *spans, unsigned num_spans)
-
 
384
{
-
 
385
    struct cairo_box_renderer *r = abstract_renderer;
-
 
386
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
-
 
387
    cairo_box_t box;
-
 
388
 
-
 
389
    if (num_spans == 0)
-
 
390
	return CAIRO_STATUS_SUCCESS;
-
 
391
 
-
 
392
    box.p1.y = _cairo_fixed_from_int (y);
-
 
393
    box.p2.y = _cairo_fixed_from_int (y + h);
-
 
394
    do {
-
 
395
	if (spans[0].coverage) {
-
 
396
	    box.p1.x = _cairo_fixed_from_int(spans[0].x);
-
 
397
	    box.p2.x = _cairo_fixed_from_int(spans[1].x);
-
 
398
	    status = _cairo_boxes_add (r->boxes, CAIRO_ANTIALIAS_DEFAULT, &box);
-
 
399
	}
-
 
400
	spans++;
-
 
401
    } while (--num_spans > 1 && status == CAIRO_STATUS_SUCCESS);
-
 
402
 
-
 
403
    return status;
-
 
404
}
-
 
405
 
-
 
406
cairo_status_t
-
 
407
_cairo_rasterise_polygon_to_boxes (cairo_polygon_t			*polygon,
-
 
408
				   cairo_fill_rule_t			 fill_rule,
-
 
409
				   cairo_boxes_t *boxes)
-
 
410
{
-
 
411
    struct cairo_box_renderer renderer;
-
 
412
    cairo_scan_converter_t *converter;
-
 
413
    cairo_int_status_t status;
-
 
414
    cairo_rectangle_int_t r;
-
 
415
 
-
 
416
    TRACE ((stderr, "%s: fill_rule=%d\n", __FUNCTION__, fill_rule));
-
 
417
 
-
 
418
    _cairo_box_round_to_rectangle (&polygon->extents, &r);
-
 
419
    converter = _cairo_mono_scan_converter_create (r.x, r.y,
-
 
420
						   r.x + r.width,
-
 
421
						   r.y + r.height,
-
 
422
						   fill_rule);
-
 
423
    status = _cairo_mono_scan_converter_add_polygon (converter, polygon);
-
 
424
    if (unlikely (status))
-
 
425
	goto cleanup_converter;
-
 
426
 
-
 
427
    renderer.boxes = boxes;
-
 
428
    renderer.base.render_rows = span_to_boxes;
-
 
429
 
-
 
430
    status = converter->generate (converter, &renderer.base);
-
 
431
cleanup_converter:
-
 
432
    converter->destroy (converter);
-
 
433
    return status;
-
 
434
}
-
 
435
 
-
 
436
void
-
 
437
_cairo_debug_print_boxes (FILE *stream, const cairo_boxes_t *boxes)
-
 
438
{
-
 
439
    const struct _cairo_boxes_chunk *chunk;
-
 
440
    cairo_box_t extents;
-
 
441
    int i;
-
 
442
 
-
 
443
    _cairo_boxes_extents (boxes, &extents);
-
 
444
    fprintf (stream, "boxes x %d: (%f, %f) x (%f, %f)\n",
-
 
445
	     boxes->num_boxes,
-
 
446
	     _cairo_fixed_to_double (extents.p1.x),
-
 
447
	     _cairo_fixed_to_double (extents.p1.y),
-
 
448
	     _cairo_fixed_to_double (extents.p2.x),
-
 
449
	     _cairo_fixed_to_double (extents.p2.y));
-
 
450
 
-
 
451
    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
-
 
452
	for (i = 0; i < chunk->count; i++) {
-
 
453
	    fprintf (stderr, "  box[%d]: (%f, %f), (%f, %f)\n", i,
-
 
454
		     _cairo_fixed_to_double (chunk->base[i].p1.x),
-
 
455
		     _cairo_fixed_to_double (chunk->base[i].p1.y),
-
 
456
		     _cairo_fixed_to_double (chunk->base[i].p2.x),