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 34... Line 34...
34
#include "cairoint.h"
34
#include "cairoint.h"
35
 
35
 
36
#include "cairo-combsort-private.h"
36
#include "cairo-combsort-inline.h"
37
#include "cairo-error-private.h"
37
#include "cairo-error-private.h"
38
#include "cairo-freelist-private.h"
38
#include "cairo-freelist-private.h"
Line 377... Line 377...
377
    prev_coverage = coverage = 0;
377
    prev_coverage = coverage = 0;
378
    prev_x = INT_MIN;
378
    prev_x = INT_MIN;
379
    for (cell = sweep->coverage.head.next; cell != &sweep->coverage.tail; cell = cell->next) {
379
    for (cell = sweep->coverage.head.next; cell != &sweep->coverage.tail; cell = cell->next) {
380
	if (cell->x != prev_x && coverage != prev_coverage) {
380
	if (cell->x != prev_x && coverage != prev_coverage) {
381
	    int n = sweep->num_spans++;
381
	    int n = sweep->num_spans++;
-
 
382
	    int c = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8);
382
	    sweep->spans[n].x = prev_x;
383
	    sweep->spans[n].x = prev_x;
383
	    sweep->spans[n].coverage = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8);
384
	    sweep->spans[n].inverse = 0;
384
	    sweep->spans[n].coverage -= sweep->spans[n].coverage >> 8;
385
	    sweep->spans[n].coverage = c - (c >> 8);
385
	    prev_coverage = coverage;
386
	    prev_coverage = coverage;
386
	}
387
	}
Line 387... Line 388...
387
 
388
 
388
	coverage += cell->covered;
389
	coverage += cell->covered;
389
	if (coverage != prev_coverage) {
390
	if (coverage != prev_coverage) {
-
 
391
	    int n = sweep->num_spans++;
390
	    int n = sweep->num_spans++;
392
	    int c = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8);
391
	    sweep->spans[n].x = cell->x;
393
	    sweep->spans[n].x = cell->x;
392
	    sweep->spans[n].coverage = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8);
394
	    sweep->spans[n].inverse = 0;
393
	    sweep->spans[n].coverage -= sweep->spans[n].coverage >> 8;
395
	    sweep->spans[n].coverage = c - (c >> 8);
394
	    prev_coverage = coverage;
396
	    prev_coverage = coverage;
395
	}
397
	}
396
	coverage += cell->uncovered;
398
	coverage += cell->uncovered;
397
	prev_x = cell->x + 1;
399
	prev_x = cell->x + 1;
398
    }
400
    }
Line 399... Line 401...
399
    _cairo_freepool_reset (&sweep->coverage.pool);
401
    _cairo_freepool_reset (&sweep->coverage.pool);
400
 
402
 
401
    if (sweep->num_spans) {
403
    if (sweep->num_spans) {
-
 
404
	if (prev_x <= sweep->xmax) {
402
	if (prev_x <= sweep->xmax) {
405
	    int n = sweep->num_spans++;
-
 
406
	    int c = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8);
403
	    int n = sweep->num_spans++;
407
	    sweep->spans[n].x = prev_x;
404
	    sweep->spans[n].x = prev_x;
408
	    sweep->spans[n].inverse = 0;
Line 405... Line 409...
405
	    sweep->spans[n].coverage = coverage;
409
	    sweep->spans[n].coverage = c - (c >> 8);
406
	}
410
	}
407
 
411
 
-
 
412
	if (coverage && prev_x < sweep->xmax) {
408
	if (coverage && prev_x < sweep->xmax) {
413
	    int n = sweep->num_spans++;
409
	    int n = sweep->num_spans++;
414
	    sweep->spans[n].x = sweep->xmax;
410
	    sweep->spans[n].x = sweep->xmax;
415
	    sweep->spans[n].inverse = 1;
411
	    sweep->spans[n].coverage = 0;
416
	    sweep->spans[n].coverage = 0;
Line 487... Line 492...
487
    sweep_line_t sweep_line;
492
    sweep_line_t sweep_line;
488
    rectangle_t *start, *stop;
493
    rectangle_t *start, *stop;
489
    cairo_status_t status;
494
    cairo_status_t status;
Line 490... Line 495...
490
 
495
 
491
    sweep_line_init (&sweep_line);
496
    sweep_line_init (&sweep_line);
492
    sweep_line.xmin = self->xmin;
497
    sweep_line.xmin = _cairo_fixed_integer_part (self->extents.p1.x);
493
    sweep_line.xmax = self->xmax;
498
    sweep_line.xmax = _cairo_fixed_integer_part (self->extents.p2.x);
494
    sweep_line.start = rectangles;
499
    sweep_line.start = rectangles;
495
    if ((status = setjmp (sweep_line.jmpbuf)))
500
    if ((status = setjmp (sweep_line.jmpbuf)))
Line 496... Line 501...
496
	goto BAIL;
501
	goto out;
497
 
502
 
498
    sweep_line.current_y = self->ymin;
503
    sweep_line.current_y = _cairo_fixed_integer_part (self->extents.p1.y);
499
    start = *sweep_line.start++;
504
    start = *sweep_line.start++;
500
    do {
505
    do {
501
	if (start->top_y != sweep_line.current_y) {
506
	if (start->top_y != sweep_line.current_y) {
Line 552... Line 557...
552
	stop = peek_stop (&sweep_line);
557
	stop = peek_stop (&sweep_line);
553
	if (stop == NULL)
558
	if (stop == NULL)
554
	    goto out;
559
	    goto out;
555
    }
560
    }
Line 556... Line 561...
556
 
561
 
557
    sweep_line.current_y++;
-
 
558
 
-
 
559
    do {
562
    while (++sweep_line.current_y < _cairo_fixed_integer_part (self->extents.p2.y)) {
560
	if (stop->bottom_y != sweep_line.current_y) {
563
	if (stop->bottom_y != sweep_line.current_y) {
561
	    render_rows (&sweep_line, renderer,
564
	    render_rows (&sweep_line, renderer,
562
			 stop->bottom_y - sweep_line.current_y);
565
			 stop->bottom_y - sweep_line.current_y);
563
	    sweep_line.current_y = stop->bottom_y;
566
	    sweep_line.current_y = stop->bottom_y;
Line 570... Line 573...
570
	    stop = peek_stop (&sweep_line);
573
	    stop = peek_stop (&sweep_line);
571
	    if (stop == NULL)
574
	    if (stop == NULL)
572
		goto out;
575
		goto out;
573
	} while (stop->bottom_y == sweep_line.current_y);
576
	} while (stop->bottom_y == sweep_line.current_y);
Line 574... Line -...
574
 
-
 
575
	sweep_line.current_y++;
577
 
Line 576... Line 578...
576
    } while (TRUE);
578
    }
577
 
-
 
578
  out:
-
 
579
    status =  renderer->render_rows (renderer,
-
 
580
				     sweep_line.current_y,
-
 
581
				     self->ymax - sweep_line.current_y,
-
 
582
				     NULL, 0);
-
 
583
 
579
 
Line 584... Line 580...
584
  BAIL:
580
  out:
585
    sweep_line_fini (&sweep_line);
581
    sweep_line_fini (&sweep_line);
-
 
582
 
-
 
583
    return status;
-
 
584
}
-
 
585
static void generate_row(cairo_span_renderer_t *renderer,
-
 
586
			 const rectangle_t *r,
-
 
587
			 int y, int h,
-
 
588
			 uint16_t coverage)
-
 
589
{
-
 
590
    cairo_half_open_span_t spans[4];
-
 
591
    unsigned int num_spans = 0;
-
 
592
    int x1 = _cairo_fixed_integer_part (r->left);
-
 
593
    int x2 = _cairo_fixed_integer_part (r->right);
-
 
594
    if (x2 > x1) {
-
 
595
	if (! _cairo_fixed_is_integer (r->left)) {
-
 
596
	    spans[num_spans].x = x1;
-
 
597
	    spans[num_spans].coverage =
-
 
598
		coverage * (256 - _cairo_fixed_fractional_part (r->left)) >> 8;
-
 
599
	    num_spans++;
-
 
600
	    x1++;
-
 
601
	}
-
 
602
 
-
 
603
	if (x2 > x1) {
-
 
604
	    spans[num_spans].x = x1;
-
 
605
	    spans[num_spans].coverage = coverage - (coverage >> 8);
-
 
606
	    num_spans++;
-
 
607
	}
-
 
608
 
-
 
609
	if (! _cairo_fixed_is_integer (r->right)) {
-
 
610
	    spans[num_spans].x = x2++;
-
 
611
	    spans[num_spans].coverage =
-
 
612
		coverage * _cairo_fixed_fractional_part (r->right) >> 8;
-
 
613
	    num_spans++;
-
 
614
	}
-
 
615
    } else {
-
 
616
	spans[num_spans].x = x2++;
-
 
617
	spans[num_spans].coverage = coverage * (r->right - r->left) >> 8;
-
 
618
	num_spans++;
-
 
619
    }
-
 
620
 
-
 
621
    spans[num_spans].x = x2;
-
 
622
    spans[num_spans].coverage = 0;
-
 
623
    num_spans++;
-
 
624
 
-
 
625
    renderer->render_rows (renderer, y, h, spans, num_spans);
-
 
626
}
-
 
627
 
-
 
628
static cairo_status_t
-
 
629
generate_box (cairo_rectangular_scan_converter_t *self,
-
 
630
	      cairo_span_renderer_t	*renderer)
-
 
631
{
-
 
632
    const rectangle_t *r = self->chunks.base;
-
 
633
    int y1 = _cairo_fixed_integer_part (r->top);
-
 
634
    int y2 = _cairo_fixed_integer_part (r->bottom);
-
 
635
    if (y2 > y1) {
-
 
636
	if (! _cairo_fixed_is_integer (r->top)) {
-
 
637
	    generate_row(renderer, r, y1, 1,
-
 
638
			 256 - _cairo_fixed_fractional_part (r->top));
-
 
639
	    y1++;
-
 
640
	}
-
 
641
 
-
 
642
	if (y2 > y1)
-
 
643
	    generate_row(renderer, r, y1, y2-y1, 256);
-
 
644
 
-
 
645
	if (! _cairo_fixed_is_integer (r->bottom))
-
 
646
	    generate_row(renderer, r, y2, 1,
-
 
647
			 _cairo_fixed_fractional_part (r->bottom));
-
 
648
    } else
-
 
649
	generate_row(renderer, r, y1, 1, r->bottom - r->top);
Line 586... Line 650...
586
 
650
 
587
    return status;
651
    return CAIRO_STATUS_SUCCESS;
588
}
652
}
589
 
653
 
Line 598... Line 662...
598
    cairo_status_t status;
662
    cairo_status_t status;
599
    int i, j;
663
    int i, j;
Line 600... Line 664...
600
 
664
 
601
    if (unlikely (self->num_rectangles == 0)) {
665
    if (unlikely (self->num_rectangles == 0)) {
602
	return renderer->render_rows (renderer,
666
	return renderer->render_rows (renderer,
-
 
667
				      _cairo_fixed_integer_part (self->extents.p1.y),
603
				      self->ymin, self->ymax - self->ymin,
668
				      _cairo_fixed_integer_part (self->extents.p2.y - self->extents.p1.y),
604
				      NULL, 0);
669
				      NULL, 0);
Line -... Line 670...
-
 
670
    }
-
 
671
 
-
 
672
    if (self->num_rectangles == 1)
605
    }
673
	return generate_box (self, renderer);
606
 
674
 
607
    rectangles = rectangles_stack;
675
    rectangles = rectangles_stack;
608
    if (unlikely (self->num_rectangles >= ARRAY_LENGTH (rectangles_stack))) {
676
    if (unlikely (self->num_rectangles >= ARRAY_LENGTH (rectangles_stack))) {
609
	rectangles = _cairo_malloc_ab (self->num_rectangles + 1,
677
	rectangles = _cairo_malloc_ab (self->num_rectangles + 1,
Line 670... Line 738...
670
 
738
 
671
    rectangle = _allocate_rectangle (self);
739
    rectangle = _allocate_rectangle (self);
672
    if (unlikely (rectangle == NULL))
740
    if (unlikely (rectangle == NULL))
Line 673... Line -...
673
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
674
 
-
 
675
    rectangle->left  = box->p1.x;
741
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
742
 
-
 
743
    rectangle->dir = dir;
-
 
744
    rectangle->left  = MAX (box->p1.x, self->extents.p1.x);
-
 
745
    rectangle->right = MIN (box->p2.x, self->extents.p2.x);
-
 
746
    if (unlikely (rectangle->right <= rectangle->left)) {
-
 
747
	self->tail->count--;
Line 676... Line 748...
676
    rectangle->right = box->p2.x;
748
	return CAIRO_STATUS_SUCCESS;
677
    rectangle->dir = dir;
749
    }
678
 
750
 
679
    rectangle->top = box->p1.y;
751
    rectangle->top = MAX (box->p1.y, self->extents.p1.y);
680
    rectangle->top_y  = _cairo_fixed_integer_floor (box->p1.y);
752
    rectangle->top_y  = _cairo_fixed_integer_floor (rectangle->top);
681
    rectangle->bottom = box->p2.y;
-
 
682
    rectangle->bottom_y = _cairo_fixed_integer_floor (box->p2.y);
753
    rectangle->bottom = MIN (box->p2.y, self->extents.p2.y);
-
 
754
    rectangle->bottom_y = _cairo_fixed_integer_floor (rectangle->bottom);
-
 
755
    if (likely (rectangle->bottom > rectangle->top))
Line 683... Line 756...
683
    assert (rectangle->bottom_y >= rectangle->top_y);
756
	self->num_rectangles++;
684
 
757
    else
Line 685... Line 758...
685
    self->num_rectangles++;
758
	self->tail->count--;
Line 702... Line 775...
702
void
775
void
703
_cairo_rectangular_scan_converter_init (cairo_rectangular_scan_converter_t *self,
776
_cairo_rectangular_scan_converter_init (cairo_rectangular_scan_converter_t *self,
704
					const cairo_rectangle_int_t *extents)
777
					const cairo_rectangle_int_t *extents)
705
{
778
{
706
    self->base.destroy = _cairo_rectangular_scan_converter_destroy;
779
    self->base.destroy = _cairo_rectangular_scan_converter_destroy;
707
    self->base.add_edge = NULL;
-
 
708
    self->base.add_polygon = NULL;
-
 
709
    self->base.generate = _cairo_rectangular_scan_converter_generate;
780
    self->base.generate = _cairo_rectangular_scan_converter_generate;
Line 710... Line -...
710
 
-
 
711
    self->xmin = extents->x;
-
 
712
    self->xmax = extents->x + extents->width;
-
 
713
    self->ymin = extents->y;
781
 
Line 714... Line 782...
714
    self->ymax = extents->y + extents->height;
782
    _cairo_box_from_rectangle (&self->extents, extents);
715
 
783
 
716
    self->chunks.base = self->buf;
784
    self->chunks.base = self->buf;
717
    self->chunks.next = NULL;
785
    self->chunks.next = NULL;