Subversion Repositories Kolibri OS

Rev

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

Rev 1891 Rev 3931
Line 1... Line 1...
1
/*
1
/*
-
 
2
 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
2
 * Copyright © 2004 Keith Packard
3
 * Copyright © 2004 Keith Packard
3
 *
4
 *
4
 * Permission to use, copy, modify, distribute, and sell this software and its
5
 * Permission to use, copy, modify, distribute, and sell this software and its
5
 * documentation for any purpose is hereby granted without fee, provided that
6
 * documentation for any purpose is hereby granted without fee, provided that
6
 * the above copyright notice appear in all copies and that both that
7
 * the above copyright notice appear in all copies and that both that
Line 23... Line 24...
23
#ifdef HAVE_CONFIG_H
24
#ifdef HAVE_CONFIG_H
24
#include 
25
#include 
25
#endif
26
#endif
Line 26... Line 27...
26
 
27
 
-
 
28
#include 
27
#include 
29
#include 
Line 28... Line 30...
28
#include "pixman-private.h"
30
#include "pixman-private.h"
29
 
31
 
30
/*
32
/*
Line 135... Line 137...
135
    stepx = n * e->stepx;
137
    stepx = n * e->stepx;
Line 136... Line 138...
136
 
138
 
137
    if (ne > 0)
139
    if (ne > 0)
138
    {
140
    {
139
	int nx = ne / e->dy;
141
	int nx = ne / e->dy;
140
	ne -= nx * e->dy;
142
	ne -= nx * (pixman_fixed_48_16_t)e->dy;
141
	stepx += nx * e->signdx;
143
	stepx += nx * e->signdx;
Line 142... Line 144...
142
    }
144
    }
143
 
145
 
Line 230... Line 232...
230
PIXMAN_EXPORT void
232
PIXMAN_EXPORT void
231
pixman_add_traps (pixman_image_t * image,
233
pixman_add_traps (pixman_image_t *     image,
232
                  int16_t          x_off,
234
                  int16_t              x_off,
233
                  int16_t          y_off,
235
                  int16_t              y_off,
234
                  int              ntrap,
236
                  int                  ntrap,
235
                  pixman_trap_t *  traps)
237
                  const pixman_trap_t *traps)
236
{
238
{
237
    int bpp;
239
    int bpp;
238
    int width;
-
 
239
    int height;
240
    int height;
Line 240... Line 241...
240
 
241
 
241
    pixman_fixed_t x_off_fixed;
242
    pixman_fixed_t x_off_fixed;
242
    pixman_fixed_t y_off_fixed;
243
    pixman_fixed_t y_off_fixed;
243
    pixman_edge_t l, r;
244
    pixman_edge_t l, r;
Line 244... Line 245...
244
    pixman_fixed_t t, b;
245
    pixman_fixed_t t, b;
Line 245... Line -...
245
 
-
 
246
    _pixman_image_validate (image);
246
 
247
    
247
    _pixman_image_validate (image);
Line 248... Line 248...
248
    width = image->bits.width;
248
    
249
    height = image->bits.height;
249
    height = image->bits.height;
Line 347... Line 347...
347
                            const pixman_trapezoid_t *trap,
347
                            const pixman_trapezoid_t *trap,
348
                            int                       x_off,
348
                            int                       x_off,
349
                            int                       y_off)
349
                            int                       y_off)
350
{
350
{
351
    int bpp;
351
    int bpp;
352
    int width;
-
 
353
    int height;
352
    int height;
Line 354... Line -...
354
 
-
 
355
    pixman_fixed_t x_off_fixed;
353
 
356
    pixman_fixed_t y_off_fixed;
354
    pixman_fixed_t y_off_fixed;
357
    pixman_edge_t l, r;
355
    pixman_edge_t l, r;
Line 358... Line 356...
358
    pixman_fixed_t t, b;
356
    pixman_fixed_t t, b;
Line 362... Line 360...
362
    _pixman_image_validate (image);
360
    _pixman_image_validate (image);
Line 363... Line 361...
363
    
361
    
364
    if (!pixman_trapezoid_valid (trap))
362
    if (!pixman_trapezoid_valid (trap))
Line 365... Line -...
365
	return;
-
 
366
 
363
	return;
367
    width = image->bits.width;
364
 
Line 368... Line -...
368
    height = image->bits.height;
-
 
369
    bpp = PIXMAN_FORMAT_BPP (image->bits.format);
365
    height = image->bits.height;
Line 370... Line 366...
370
 
366
    bpp = PIXMAN_FORMAT_BPP (image->bits.format);
371
    x_off_fixed = pixman_int_to_fixed (x_off);
367
 
372
    y_off_fixed = pixman_int_to_fixed (y_off);
368
    y_off_fixed = pixman_int_to_fixed (y_off);
Line 388... Line 384...
388
	pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
384
	pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
Line 389... Line 385...
389
 
385
 
390
	pixman_rasterize_edges (image, &l, &r, t, b);
386
	pixman_rasterize_edges (image, &l, &r, t, b);
391
    }
387
    }
-
 
388
}
-
 
389
 
-
 
390
static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] =
-
 
391
{
-
 
392
    FALSE,	/* Clear		0			0    */
-
 
393
    FALSE,	/* Src			1			0    */
-
 
394
    TRUE,	/* Dst			0			1    */
-
 
395
    TRUE,	/* Over			1			1-Aa */
-
 
396
    TRUE,	/* OverReverse		1-Ab			1    */
-
 
397
    FALSE,	/* In			Ab			0    */
-
 
398
    FALSE,	/* InReverse		0			Aa   */
-
 
399
    FALSE,	/* Out			1-Ab			0    */
-
 
400
    TRUE,	/* OutReverse		0			1-Aa */
-
 
401
    TRUE,	/* Atop			Ab			1-Aa */
-
 
402
    FALSE,	/* AtopReverse		1-Ab			Aa   */
-
 
403
    TRUE,	/* Xor			1-Ab			1-Aa */
-
 
404
    TRUE,	/* Add			1			1    */
-
 
405
};
-
 
406
 
-
 
407
static pixman_bool_t
-
 
408
get_trap_extents (pixman_op_t op, pixman_image_t *dest,
-
 
409
		  const pixman_trapezoid_t *traps, int n_traps,
-
 
410
		  pixman_box32_t *box)
-
 
411
{
-
 
412
    int i;
-
 
413
 
-
 
414
    /* When the operator is such that a zero source has an
-
 
415
     * effect on the underlying image, we have to
-
 
416
     * composite across the entire destination
-
 
417
     */
-
 
418
    if (!zero_src_has_no_effect [op])
-
 
419
    {
-
 
420
	box->x1 = 0;
-
 
421
	box->y1 = 0;
-
 
422
	box->x2 = dest->bits.width;
-
 
423
	box->y2 = dest->bits.height;
-
 
424
	return TRUE;
-
 
425
    }
-
 
426
    
-
 
427
    box->x1 = INT32_MAX;
-
 
428
    box->y1 = INT32_MAX;
-
 
429
    box->x2 = INT32_MIN;
-
 
430
    box->y2 = INT32_MIN;
-
 
431
	
-
 
432
    for (i = 0; i < n_traps; ++i)
-
 
433
    {
-
 
434
	const pixman_trapezoid_t *trap = &(traps[i]);
-
 
435
	int y1, y2;
-
 
436
	    
-
 
437
	if (!pixman_trapezoid_valid (trap))
-
 
438
	    continue;
-
 
439
	    
-
 
440
	y1 = pixman_fixed_to_int (trap->top);
-
 
441
	if (y1 < box->y1)
-
 
442
	    box->y1 = y1;
-
 
443
	    
-
 
444
	y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
-
 
445
	if (y2 > box->y2)
-
 
446
	    box->y2 = y2;
-
 
447
	    
-
 
448
#define EXTEND_MIN(x)							\
-
 
449
	if (pixman_fixed_to_int ((x)) < box->x1)			\
-
 
450
	    box->x1 = pixman_fixed_to_int ((x));
-
 
451
#define EXTEND_MAX(x)							\
-
 
452
	if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2)	\
-
 
453
	    box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
-
 
454
	    
-
 
455
#define EXTEND(x)							\
-
 
456
	EXTEND_MIN(x);							\
-
 
457
	EXTEND_MAX(x);
-
 
458
	    
-
 
459
	EXTEND(trap->left.p1.x);
-
 
460
	EXTEND(trap->left.p2.x);
-
 
461
	EXTEND(trap->right.p1.x);
-
 
462
	EXTEND(trap->right.p2.x);
-
 
463
    }
-
 
464
	
-
 
465
    if (box->x1 >= box->x2 || box->y1 >= box->y2)
-
 
466
	return FALSE;
-
 
467
 
-
 
468
    return TRUE;
-
 
469
}
-
 
470
 
-
 
471
/*
-
 
472
 * pixman_composite_trapezoids()
-
 
473
 *
-
 
474
 * All the trapezoids are conceptually rendered to an infinitely big image.
-
 
475
 * The (0, 0) coordinates of this image are then aligned with the (x, y)
-
 
476
 * coordinates of the source image, and then both images are aligned with
-
 
477
 * the (x, y) coordinates of the destination. Then these three images are
-
 
478
 * composited across the entire destination.
-
 
479
 */
-
 
480
PIXMAN_EXPORT void
-
 
481
pixman_composite_trapezoids (pixman_op_t		op,
-
 
482
			     pixman_image_t *		src,
-
 
483
			     pixman_image_t *		dst,
-
 
484
			     pixman_format_code_t	mask_format,
-
 
485
			     int			x_src,
-
 
486
			     int			y_src,
-
 
487
			     int			x_dst,
-
 
488
			     int			y_dst,
-
 
489
			     int			n_traps,
-
 
490
			     const pixman_trapezoid_t *	traps)
-
 
491
{
-
 
492
    int i;
-
 
493
 
-
 
494
    return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A);
-
 
495
    
-
 
496
    if (n_traps <= 0)
-
 
497
	return;
-
 
498
 
-
 
499
    _pixman_image_validate (src);
-
 
500
    _pixman_image_validate (dst);
-
 
501
 
-
 
502
    if (op == PIXMAN_OP_ADD &&
-
 
503
	(src->common.flags & FAST_PATH_IS_OPAQUE)		&&
-
 
504
	(mask_format == dst->common.extended_format_code)	&&
-
 
505
	!(dst->common.have_clip_region))
-
 
506
    {
-
 
507
	for (i = 0; i < n_traps; ++i)
-
 
508
	{
-
 
509
	    const pixman_trapezoid_t *trap = &(traps[i]);
-
 
510
	    
-
 
511
	    if (!pixman_trapezoid_valid (trap))
-
 
512
		continue;
-
 
513
	    
-
 
514
	    pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst);
-
 
515
	}
-
 
516
    }
-
 
517
    else
-
 
518
    {
-
 
519
	pixman_image_t *tmp;
-
 
520
	pixman_box32_t box;
-
 
521
	int i;
-
 
522
 
-
 
523
	if (!get_trap_extents (op, dst, traps, n_traps, &box))
-
 
524
	    return;
-
 
525
	
-
 
526
	if (!(tmp = pixman_image_create_bits (
-
 
527
		  mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1)))
-
 
528
	    return;
-
 
529
	
-
 
530
	for (i = 0; i < n_traps; ++i)
-
 
531
	{
-
 
532
	    const pixman_trapezoid_t *trap = &(traps[i]);
-
 
533
	    
-
 
534
	    if (!pixman_trapezoid_valid (trap))
-
 
535
		continue;
-
 
536
	    
-
 
537
	    pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
-
 
538
	}
-
 
539
	
-
 
540
	pixman_image_composite (op, src, tmp, dst,
-
 
541
				x_src + box.x1, y_src + box.y1,
-
 
542
				0, 0,
-
 
543
				x_dst + box.x1, y_dst + box.y1,
-
 
544
				box.x2 - box.x1, box.y2 - box.y1);
-
 
545
	
-
 
546
	pixman_image_unref (tmp);
-
 
547
    }
-
 
548
}
-
 
549
 
-
 
550
static int
-
 
551
greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b)
-
 
552
{
-
 
553
    if (a->y == b->y)
-
 
554
	return a->x > b->x;
-
 
555
    return a->y > b->y;
-
 
556
}
-
 
557
 
-
 
558
/*
-
 
559
 * Note that the definition of this function is a bit odd because
-
 
560
 * of the X coordinate space (y increasing downwards).
-
 
561
 */
-
 
562
static int
-
 
563
clockwise (const pixman_point_fixed_t *ref,
-
 
564
	   const pixman_point_fixed_t *a,
-
 
565
	   const pixman_point_fixed_t *b)
-
 
566
{
-
 
567
    pixman_point_fixed_t	ad, bd;
-
 
568
 
-
 
569
    ad.x = a->x - ref->x;
-
 
570
    ad.y = a->y - ref->y;
-
 
571
    bd.x = b->x - ref->x;
-
 
572
    bd.y = b->y - ref->y;
-
 
573
 
-
 
574
    return ((pixman_fixed_32_32_t) bd.y * ad.x -
-
 
575
	    (pixman_fixed_32_32_t) ad.y * bd.x) < 0;
-
 
576
}
-
 
577
 
-
 
578
static void
-
 
579
triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps)
-
 
580
{
-
 
581
    const pixman_point_fixed_t *top, *left, *right, *tmp;
-
 
582
 
-
 
583
    top = &tri->p1;
-
 
584
    left = &tri->p2;
-
 
585
    right = &tri->p3;
-
 
586
 
-
 
587
    if (greater_y (top, left))
-
 
588
    {
-
 
589
	tmp = left;
-
 
590
	left = top;
-
 
591
	top = tmp;
-
 
592
    }
-
 
593
 
-
 
594
    if (greater_y (top, right))
-
 
595
    {
-
 
596
	tmp = right;
-
 
597
	right = top;
-
 
598
	top = tmp;
-
 
599
    }
-
 
600
 
-
 
601
    if (clockwise (top, right, left))
-
 
602
    {
-
 
603
	tmp = right;
-
 
604
	right = left;
-
 
605
	left = tmp;
-
 
606
    }
-
 
607
    
-
 
608
    /*
-
 
609
     * Two cases:
-
 
610
     *
-
 
611
     *		+		+
-
 
612
     *	       / \             / \
-
 
613
     *	      /   \           /	  \
-
 
614
     *	     /     +         +	   \
-
 
615
     *      /    --           --    \
-
 
616
     *     /   --               --   \
-
 
617
     *    / ---                   --- \
-
 
618
     *	 +--                         --+
-
 
619
     */
-
 
620
 
-
 
621
    traps->top = top->y;
-
 
622
    traps->left.p1 = *top;
-
 
623
    traps->left.p2 = *left;
-
 
624
    traps->right.p1 = *top;
-
 
625
    traps->right.p2 = *right;
-
 
626
 
-
 
627
    if (right->y < left->y)
-
 
628
	traps->bottom = right->y;
-
 
629
    else
-
 
630
	traps->bottom = left->y;
-
 
631
 
-
 
632
    traps++;
-
 
633
 
-
 
634
    *traps = *(traps - 1);
-
 
635
    
-
 
636
    if (right->y < left->y)
-
 
637
    {
-
 
638
	traps->top = right->y;
-
 
639
	traps->bottom = left->y;
-
 
640
	traps->right.p1 = *right;
-
 
641
	traps->right.p2 = *left;
-
 
642
    }
-
 
643
    else
-
 
644
    {
-
 
645
	traps->top = left->y;
-
 
646
	traps->bottom = right->y;
-
 
647
	traps->left.p1 = *left;
-
 
648
	traps->left.p2 = *right;
-
 
649
    }
-
 
650
}
-
 
651
 
-
 
652
static pixman_trapezoid_t *
-
 
653
convert_triangles (int n_tris, const pixman_triangle_t *tris)
-
 
654
{
-
 
655
    pixman_trapezoid_t *traps;
-
 
656
    int i;
-
 
657
 
-
 
658
    if (n_tris <= 0)
-
 
659
	return NULL;
-
 
660
    
-
 
661
    traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t));
-
 
662
    if (!traps)
-
 
663
	return NULL;
-
 
664
 
-
 
665
    for (i = 0; i < n_tris; ++i)
-
 
666
	triangle_to_trapezoids (&(tris[i]), traps + 2 * i);
-
 
667
 
-
 
668
    return traps;
-
 
669
}
-
 
670
 
-
 
671
PIXMAN_EXPORT void
-
 
672
pixman_composite_triangles (pixman_op_t			op,
-
 
673
			    pixman_image_t *		src,
-
 
674
			    pixman_image_t *		dst,
-
 
675
			    pixman_format_code_t	mask_format,
-
 
676
			    int				x_src,
-
 
677
			    int				y_src,
-
 
678
			    int				x_dst,
-
 
679
			    int				y_dst,
-
 
680
			    int				n_tris,
-
 
681
			    const pixman_triangle_t *	tris)
-
 
682
{
-
 
683
    pixman_trapezoid_t *traps;
-
 
684
 
-
 
685
    if ((traps = convert_triangles (n_tris, tris)))
-
 
686
    {
-
 
687
	pixman_composite_trapezoids (op, src, dst, mask_format,
-
 
688
				     x_src, y_src, x_dst, y_dst,
-
 
689
				     n_tris * 2, traps);
-
 
690
	
-
 
691
	free (traps);
-
 
692
    }
-
 
693
}
-
 
694
 
-
 
695
PIXMAN_EXPORT void
-
 
696
pixman_add_triangles (pixman_image_t          *image,
-
 
697
		      int32_t	               x_off,
-
 
698
		      int32_t	               y_off,
-
 
699
		      int	               n_tris,
-
 
700
		      const pixman_triangle_t *tris)
-
 
701
{
-
 
702
    pixman_trapezoid_t *traps;
-
 
703
 
-
 
704
    if ((traps = convert_triangles (n_tris, tris)))
-
 
705
    {
-
 
706
	pixman_add_trapezoids (image, x_off, y_off,
-
 
707
			       n_tris * 2, traps);
-
 
708
 
-
 
709
	free (traps);
-
 
710
    }