forked from KolibriOS/kolibrios
pixman-1.0
git-svn-id: svn://kolibrios.org@1891 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
acec52c402
commit
4dd0483a93
54
programs/develop/libraries/pixman/Makefile
Normal file
54
programs/develop/libraries/pixman/Makefile
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
LIBRARY = pixman-1
|
||||
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -c -O2 -mmmx -Winline
|
||||
|
||||
DEFINES = -DHAVE_CONFIG_H -DPACKAGE -DPIXMAN_NO_TLS -DUSE_MMX
|
||||
|
||||
INCLUDES = -I../pixman -I../newlib/include -I../newlib/include/sys
|
||||
|
||||
SOURCES = \
|
||||
pixman-image.c \
|
||||
pixman-access.c \
|
||||
pixman-access-accessors.c \
|
||||
pixman-region16.c \
|
||||
pixman-region32.c \
|
||||
pixman-combine32.c \
|
||||
pixman-combine64.c \
|
||||
pixman-utils.c \
|
||||
pixman-edge.c \
|
||||
pixman-edge-accessors.c \
|
||||
pixman-trap.c \
|
||||
pixman-timer.c \
|
||||
pixman-matrix.c \
|
||||
pixman-gradient-walker.c \
|
||||
pixman-linear-gradient.c \
|
||||
pixman-radial-gradient.c \
|
||||
pixman-bits-image.c \
|
||||
pixman.c \
|
||||
pixman-cpu.c \
|
||||
pixman-fast-path.c \
|
||||
pixman-implementation.c \
|
||||
pixman-solid-fill.c \
|
||||
pixman-general.c \
|
||||
pixman-mmx.c \
|
||||
$(NULL)
|
||||
|
||||
OBJECTS = $(patsubst %.c, %.o, $(SOURCES))
|
||||
|
||||
# targets
|
||||
|
||||
all:$(LIBRARY).a
|
||||
|
||||
|
||||
$(LIBRARY).a: $(OBJECTS) Makefile
|
||||
ar cvrs $(LIBRARY).a $(OBJECTS)
|
||||
|
||||
%.o: %.c $(SOURCES) Makefile
|
||||
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
#define PIXMAN_FB_ACCESSORS
|
||||
|
||||
#include "pixman-access.c"
|
2989
programs/develop/libraries/pixman/pixman-access.c
Normal file
2989
programs/develop/libraries/pixman/pixman-access.c
Normal file
File diff suppressed because it is too large
Load Diff
40
programs/develop/libraries/pixman/pixman-accessor.h
Normal file
40
programs/develop/libraries/pixman/pixman-accessor.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifdef PIXMAN_FB_ACCESSORS
|
||||
|
||||
#define ACCESS(sym) sym##_accessors
|
||||
|
||||
#define READ(img, ptr) \
|
||||
(((bits_image_t *)(img))->read_func ((ptr), sizeof(*(ptr))))
|
||||
#define WRITE(img, ptr,val) \
|
||||
(((bits_image_t *)(img))->write_func ((ptr), (val), sizeof (*(ptr))))
|
||||
|
||||
#define MEMCPY_WRAPPED(img, dst, src, size) \
|
||||
do { \
|
||||
size_t _i; \
|
||||
uint8_t *_dst = (uint8_t*)(dst), *_src = (uint8_t*)(src); \
|
||||
for(_i = 0; _i < size; _i++) { \
|
||||
WRITE((img), _dst +_i, READ((img), _src + _i)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
do { \
|
||||
size_t _i; \
|
||||
uint8_t *_dst = (uint8_t*)(dst); \
|
||||
for(_i = 0; _i < (size_t) size; _i++) { \
|
||||
WRITE((img), _dst +_i, (val)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define ACCESS(sym) sym
|
||||
|
||||
#define READ(img, ptr) (*(ptr))
|
||||
#define WRITE(img, ptr, val) (*(ptr) = (val))
|
||||
#define MEMCPY_WRAPPED(img, dst, src, size) \
|
||||
memcpy(dst, src, size)
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
memset(dst, val, size)
|
||||
|
||||
#endif
|
||||
|
1331
programs/develop/libraries/pixman/pixman-bits-image.c
Normal file
1331
programs/develop/libraries/pixman/pixman-bits-image.c
Normal file
File diff suppressed because it is too large
Load Diff
2465
programs/develop/libraries/pixman/pixman-combine32.c
Normal file
2465
programs/develop/libraries/pixman/pixman-combine32.c
Normal file
File diff suppressed because it is too large
Load Diff
230
programs/develop/libraries/pixman/pixman-combine32.h
Normal file
230
programs/develop/libraries/pixman/pixman-combine32.h
Normal file
@ -0,0 +1,230 @@
|
||||
/* WARNING: This file is generated by combine.pl from combine.inc.
|
||||
Please edit one of those files rather than this one. */
|
||||
|
||||
#line 1 "pixman-combine.c.template"
|
||||
|
||||
#define COMPONENT_SIZE 8
|
||||
#define MASK 0xff
|
||||
#define ONE_HALF 0x80
|
||||
|
||||
#define A_SHIFT 8 * 3
|
||||
#define R_SHIFT 8 * 2
|
||||
#define G_SHIFT 8
|
||||
#define A_MASK 0xff000000
|
||||
#define R_MASK 0xff0000
|
||||
#define G_MASK 0xff00
|
||||
|
||||
#define RB_MASK 0xff00ff
|
||||
#define AG_MASK 0xff00ff00
|
||||
#define RB_ONE_HALF 0x800080
|
||||
#define RB_MASK_PLUS_ONE 0x10000100
|
||||
|
||||
#define ALPHA_8(x) ((x) >> A_SHIFT)
|
||||
#define RED_8(x) (((x) >> R_SHIFT) & MASK)
|
||||
#define GREEN_8(x) (((x) >> G_SHIFT) & MASK)
|
||||
#define BLUE_8(x) ((x) & MASK)
|
||||
|
||||
/*
|
||||
* Helper macros.
|
||||
*/
|
||||
|
||||
#define MUL_UN8(a, b, t) \
|
||||
((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
|
||||
|
||||
#define DIV_UN8(a, b) \
|
||||
(((uint16_t) (a) * MASK) / (b))
|
||||
|
||||
#define ADD_UN8(x, y, t) \
|
||||
((t) = (x) + (y), \
|
||||
(uint32_t) (uint8_t) ((t) | (0 - ((t) >> G_SHIFT))))
|
||||
|
||||
#define DIV_ONE_UN8(x) \
|
||||
(((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
|
||||
|
||||
/*
|
||||
* The methods below use some tricks to be able to do two color
|
||||
* components at the same time.
|
||||
*/
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a) / 255
|
||||
*/
|
||||
#define UN8_rb_MUL_UN8(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) & RB_MASK) * (a); \
|
||||
t += RB_ONE_HALF; \
|
||||
x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x &= RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_rb = min (x_rb + y_rb, 255)
|
||||
*/
|
||||
#define UN8_rb_ADD_UN8_rb(x, y, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) + (y)); \
|
||||
t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
|
||||
x = (t & RB_MASK); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a_rb) / 255
|
||||
*/
|
||||
#define UN8_rb_MUL_UN8_rb(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = (x & MASK) * (a & MASK); \
|
||||
t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \
|
||||
t += RB_ONE_HALF; \
|
||||
t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x = t & RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255 + y_c
|
||||
*/
|
||||
#define UN8x4_MUL_UN8_ADD_UN8x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a + y_c * b) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y); \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
UN8_rb_MUL_UN8 (r2__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((y) >> G_SHIFT); \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
UN8_rb_MUL_UN8 (r3__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255 + y_c
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4_ADD_UN8x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((a) >> G_SHIFT); \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c + y_c * b) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
r2__ = (y); \
|
||||
UN8_rb_MUL_UN8 (r2__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
r3__ = (y) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8 (r3__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = min(x_c + y_c, 255)
|
||||
*/
|
||||
#define UN8x4_ADD_UN8x4(x, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x) & RB_MASK; \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT) & RB_MASK; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
2465
programs/develop/libraries/pixman/pixman-combine64.c
Normal file
2465
programs/develop/libraries/pixman/pixman-combine64.c
Normal file
File diff suppressed because it is too large
Load Diff
230
programs/develop/libraries/pixman/pixman-combine64.h
Normal file
230
programs/develop/libraries/pixman/pixman-combine64.h
Normal file
@ -0,0 +1,230 @@
|
||||
/* WARNING: This file is generated by combine.pl from combine.inc.
|
||||
Please edit one of those files rather than this one. */
|
||||
|
||||
#line 1 "pixman-combine.c.template"
|
||||
|
||||
#define COMPONENT_SIZE 16
|
||||
#define MASK 0xffffULL
|
||||
#define ONE_HALF 0x8000ULL
|
||||
|
||||
#define A_SHIFT 16 * 3
|
||||
#define R_SHIFT 16 * 2
|
||||
#define G_SHIFT 16
|
||||
#define A_MASK 0xffff000000000000ULL
|
||||
#define R_MASK 0xffff00000000ULL
|
||||
#define G_MASK 0xffff0000ULL
|
||||
|
||||
#define RB_MASK 0xffff0000ffffULL
|
||||
#define AG_MASK 0xffff0000ffff0000ULL
|
||||
#define RB_ONE_HALF 0x800000008000ULL
|
||||
#define RB_MASK_PLUS_ONE 0x10000000010000ULL
|
||||
|
||||
#define ALPHA_16(x) ((x) >> A_SHIFT)
|
||||
#define RED_16(x) (((x) >> R_SHIFT) & MASK)
|
||||
#define GREEN_16(x) (((x) >> G_SHIFT) & MASK)
|
||||
#define BLUE_16(x) ((x) & MASK)
|
||||
|
||||
/*
|
||||
* Helper macros.
|
||||
*/
|
||||
|
||||
#define MUL_UN16(a, b, t) \
|
||||
((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
|
||||
|
||||
#define DIV_UN16(a, b) \
|
||||
(((uint32_t) (a) * MASK) / (b))
|
||||
|
||||
#define ADD_UN16(x, y, t) \
|
||||
((t) = (x) + (y), \
|
||||
(uint64_t) (uint16_t) ((t) | (0 - ((t) >> G_SHIFT))))
|
||||
|
||||
#define DIV_ONE_UN16(x) \
|
||||
(((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
|
||||
|
||||
/*
|
||||
* The methods below use some tricks to be able to do two color
|
||||
* components at the same time.
|
||||
*/
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a) / 255
|
||||
*/
|
||||
#define UN16_rb_MUL_UN16(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) & RB_MASK) * (a); \
|
||||
t += RB_ONE_HALF; \
|
||||
x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x &= RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_rb = min (x_rb + y_rb, 255)
|
||||
*/
|
||||
#define UN16_rb_ADD_UN16_rb(x, y, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) + (y)); \
|
||||
t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
|
||||
x = (t & RB_MASK); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a_rb) / 255
|
||||
*/
|
||||
#define UN16_rb_MUL_UN16_rb(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = (x & MASK) * (a & MASK); \
|
||||
t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \
|
||||
t += RB_ONE_HALF; \
|
||||
t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x = t & RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255
|
||||
*/
|
||||
#define UN16x4_MUL_UN16(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint64_t r1__, r2__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
UN16_rb_MUL_UN16 (r1__, (a), t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
UN16_rb_MUL_UN16 (r2__, (a), t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255 + y_c
|
||||
*/
|
||||
#define UN16x4_MUL_UN16_ADD_UN16x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint64_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN16_rb_MUL_UN16 (r1__, (a), t__); \
|
||||
UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN16_rb_MUL_UN16 (r2__, (a), t__); \
|
||||
UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a + y_c * b) / 255
|
||||
*/
|
||||
#define UN16x4_MUL_UN16_ADD_UN16x4_MUL_UN16(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint64_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y); \
|
||||
UN16_rb_MUL_UN16 (r1__, (a), t__); \
|
||||
UN16_rb_MUL_UN16 (r2__, (b), t__); \
|
||||
UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((y) >> G_SHIFT); \
|
||||
UN16_rb_MUL_UN16 (r2__, (a), t__); \
|
||||
UN16_rb_MUL_UN16 (r3__, (b), t__); \
|
||||
UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255
|
||||
*/
|
||||
#define UN16x4_MUL_UN16x4(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint64_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN16_rb_MUL_UN16_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN16_rb_MUL_UN16_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255 + y_c
|
||||
*/
|
||||
#define UN16x4_MUL_UN16x4_ADD_UN16x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint64_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN16_rb_MUL_UN16_rb (r1__, r2__, t__); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((a) >> G_SHIFT); \
|
||||
UN16_rb_MUL_UN16_rb (r2__, r3__, t__); \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c + y_c * b) / 255
|
||||
*/
|
||||
#define UN16x4_MUL_UN16x4_ADD_UN16x4_MUL_UN16(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint64_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN16_rb_MUL_UN16_rb (r1__, r2__, t__); \
|
||||
r2__ = (y); \
|
||||
UN16_rb_MUL_UN16 (r2__, (b), t__); \
|
||||
UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN16_rb_MUL_UN16_rb (r2__, r3__, t__); \
|
||||
r3__ = (y) >> G_SHIFT; \
|
||||
UN16_rb_MUL_UN16 (r3__, (b), t__); \
|
||||
UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = min(x_c + y_c, 255)
|
||||
*/
|
||||
#define UN16x4_ADD_UN16x4(x, y) \
|
||||
do \
|
||||
{ \
|
||||
uint64_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x) & RB_MASK; \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN16_rb_ADD_UN16_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT) & RB_MASK; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN16_rb_ADD_UN16_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
204
programs/develop/libraries/pixman/pixman-compiler.h
Normal file
204
programs/develop/libraries/pixman/pixman-compiler.h
Normal file
@ -0,0 +1,204 @@
|
||||
/* Pixman uses some non-standard compiler features. This file ensures
|
||||
* they exist
|
||||
*
|
||||
* The features are:
|
||||
*
|
||||
* FUNC must be defined to expand to the current function
|
||||
* PIXMAN_EXPORT should be defined to whatever is required to
|
||||
* export functions from a shared library
|
||||
* limits limits for various types must be defined
|
||||
* inline must be defined
|
||||
* force_inline must be defined
|
||||
*/
|
||||
#if defined (__GNUC__)
|
||||
# define FUNC ((const char*) (__PRETTY_FUNCTION__))
|
||||
#elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
# define FUNC ((const char*) (__func__))
|
||||
#else
|
||||
# define FUNC ((const char*) ("???"))
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MIN
|
||||
# define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MAX
|
||||
# define INT16_MAX (32767)
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MIN
|
||||
# define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MAX
|
||||
# define INT32_MAX (2147483647)
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MIN
|
||||
# define UINT32_MIN (0)
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* 'inline' is available only in C++ in MSVC */
|
||||
# define inline __inline
|
||||
# define force_inline __forceinline
|
||||
# define noinline __declspec(noinline)
|
||||
#elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
|
||||
# define inline __inline__
|
||||
# define force_inline __inline__ __attribute__ ((__always_inline__))
|
||||
# define noinline __attribute__((noinline))
|
||||
#else
|
||||
# ifndef force_inline
|
||||
# define force_inline inline
|
||||
# endif
|
||||
# ifndef noinline
|
||||
# define noinline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* GCC visibility */
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32)
|
||||
# define PIXMAN_EXPORT __attribute__ ((visibility("default")))
|
||||
/* Sun Studio 8 visibility */
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
# define PIXMAN_EXPORT __global
|
||||
#else
|
||||
# define PIXMAN_EXPORT
|
||||
#endif
|
||||
|
||||
/* TLS */
|
||||
#if defined(PIXMAN_NO_TLS)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static type name
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(TOOLCHAIN_SUPPORTS__THREAD)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static __thread type name
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
|
||||
# define _NO_W32_PSEUDO_MODIFIERS
|
||||
# include <windows.h>
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static volatile int tls_ ## name ## _initialized = 0; \
|
||||
static void *tls_ ## name ## _mutex = NULL; \
|
||||
static unsigned tls_ ## name ## _index; \
|
||||
\
|
||||
static type * \
|
||||
tls_ ## name ## _alloc (void) \
|
||||
{ \
|
||||
type *value = calloc (1, sizeof (type)); \
|
||||
if (value) \
|
||||
TlsSetValue (tls_ ## name ## _index, value); \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
static force_inline type * \
|
||||
tls_ ## name ## _get (void) \
|
||||
{ \
|
||||
type *value; \
|
||||
if (!tls_ ## name ## _initialized) \
|
||||
{ \
|
||||
if (!tls_ ## name ## _mutex) \
|
||||
{ \
|
||||
void *mutex = CreateMutexA (NULL, 0, NULL); \
|
||||
if (InterlockedCompareExchangePointer ( \
|
||||
&tls_ ## name ## _mutex, mutex, NULL) != NULL) \
|
||||
{ \
|
||||
CloseHandle (mutex); \
|
||||
} \
|
||||
} \
|
||||
WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \
|
||||
if (!tls_ ## name ## _initialized) \
|
||||
{ \
|
||||
tls_ ## name ## _index = TlsAlloc (); \
|
||||
tls_ ## name ## _initialized = 1; \
|
||||
} \
|
||||
ReleaseMutex (tls_ ## name ## _mutex); \
|
||||
} \
|
||||
if (tls_ ## name ## _index == 0xFFFFFFFF) \
|
||||
return NULL; \
|
||||
value = TlsGetValue (tls_ ## name ## _index); \
|
||||
if (!value) \
|
||||
value = tls_ ## name ## _alloc (); \
|
||||
return value; \
|
||||
}
|
||||
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
tls_ ## name ## _get ()
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static __declspec(thread) type name
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(HAVE_PTHREAD_SETSPECIFIC)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
|
||||
static pthread_key_t tls_ ## name ## _key; \
|
||||
\
|
||||
static void \
|
||||
tls_ ## name ## _destroy_value (void *value) \
|
||||
{ \
|
||||
free (value); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
tls_ ## name ## _make_key (void) \
|
||||
{ \
|
||||
pthread_key_create (&tls_ ## name ## _key, \
|
||||
tls_ ## name ## _destroy_value); \
|
||||
} \
|
||||
\
|
||||
static type * \
|
||||
tls_ ## name ## _alloc (void) \
|
||||
{ \
|
||||
type *value = calloc (1, sizeof (type)); \
|
||||
if (value) \
|
||||
pthread_setspecific (tls_ ## name ## _key, value); \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
static force_inline type * \
|
||||
tls_ ## name ## _get (void) \
|
||||
{ \
|
||||
type *value = NULL; \
|
||||
if (pthread_once (&tls_ ## name ## _once_control, \
|
||||
tls_ ## name ## _make_key) == 0) \
|
||||
{ \
|
||||
value = pthread_getspecific (tls_ ## name ## _key); \
|
||||
if (!value) \
|
||||
value = tls_ ## name ## _alloc (); \
|
||||
} \
|
||||
return value; \
|
||||
} \
|
||||
extern int no_such_variable
|
||||
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
tls_ ## name ## _get ()
|
||||
|
||||
#else
|
||||
|
||||
# error "Unknown thread local support for this system. Pixman will not work with multiple threads. Define PIXMAN_NO_TLS to acknowledge and accept this limitation and compile pixman without thread-safety support."
|
||||
|
||||
#endif
|
198
programs/develop/libraries/pixman/pixman-conical-gradient.c
Normal file
198
programs/develop/libraries/pixman/pixman-conical-gradient.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static force_inline double
|
||||
coordinates_to_parameter (double x, double y, double angle)
|
||||
{
|
||||
double t;
|
||||
|
||||
t = atan2 (y, x) + angle;
|
||||
|
||||
while (t < 0)
|
||||
t += 2 * M_PI;
|
||||
|
||||
while (t >= 2 * M_PI)
|
||||
t -= 2 * M_PI;
|
||||
|
||||
return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and
|
||||
* make rotation CCW
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
conical_gradient_get_scanline_32 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask)
|
||||
{
|
||||
source_image_t *source = (source_image_t *)image;
|
||||
gradient_t *gradient = (gradient_t *)source;
|
||||
conical_gradient_t *conical = (conical_gradient_t *)image;
|
||||
uint32_t *end = buffer + width;
|
||||
pixman_gradient_walker_t walker;
|
||||
pixman_bool_t affine = TRUE;
|
||||
double cx = 1.;
|
||||
double cy = 0.;
|
||||
double cz = 0.;
|
||||
double rx = x + 0.5;
|
||||
double ry = y + 0.5;
|
||||
double rz = 1.;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
|
||||
|
||||
if (source->common.transform)
|
||||
{
|
||||
pixman_vector_t v;
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (!pixman_transform_point_3d (source->common.transform, &v))
|
||||
return;
|
||||
|
||||
cx = source->common.transform->matrix[0][0] / 65536.;
|
||||
cy = source->common.transform->matrix[1][0] / 65536.;
|
||||
cz = source->common.transform->matrix[2][0] / 65536.;
|
||||
|
||||
rx = v.vector[0] / 65536.;
|
||||
ry = v.vector[1] / 65536.;
|
||||
rz = v.vector[2] / 65536.;
|
||||
|
||||
affine =
|
||||
source->common.transform->matrix[2][0] == 0 &&
|
||||
v.vector[2] == pixman_fixed_1;
|
||||
}
|
||||
|
||||
if (affine)
|
||||
{
|
||||
rx -= conical->center.x / 65536.;
|
||||
ry -= conical->center.y / 65536.;
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
double t = coordinates_to_parameter (rx, ry, conical->angle);
|
||||
|
||||
*buffer = _pixman_gradient_walker_pixel (
|
||||
&walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
|
||||
}
|
||||
|
||||
++buffer;
|
||||
|
||||
rx += cx;
|
||||
ry += cy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (buffer < end)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
double t;
|
||||
|
||||
if (rz != 0)
|
||||
{
|
||||
x = rx / rz;
|
||||
y = ry / rz;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = y = 0.;
|
||||
}
|
||||
|
||||
x -= conical->center.x / 65536.;
|
||||
y -= conical->center.y / 65536.;
|
||||
|
||||
t = coordinates_to_parameter (x, y, conical->angle);
|
||||
|
||||
*buffer = _pixman_gradient_walker_pixel (
|
||||
&walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
|
||||
}
|
||||
|
||||
++buffer;
|
||||
|
||||
rx += cx;
|
||||
ry += cy;
|
||||
rz += cz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
conical_gradient_property_changed (pixman_image_t *image)
|
||||
{
|
||||
image->common.get_scanline_32 = conical_gradient_get_scanline_32;
|
||||
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_conical_gradient (pixman_point_fixed_t * center,
|
||||
pixman_fixed_t angle,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image = _pixman_image_allocate ();
|
||||
conical_gradient_t *conical;
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
conical = &image->conical;
|
||||
|
||||
if (!_pixman_init_gradient (&conical->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
angle = MOD (angle, pixman_int_to_fixed (360));
|
||||
|
||||
image->type = CONICAL;
|
||||
|
||||
conical->center = *center;
|
||||
conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;
|
||||
|
||||
image->common.property_changed = conical_gradient_property_changed;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
598
programs/develop/libraries/pixman/pixman-cpu.c
Normal file
598
programs/develop/libraries/pixman/pixman-cpu.c
Normal file
@ -0,0 +1,598 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(USE_ARM_SIMD) && defined(_MSC_VER)
|
||||
/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#ifdef USE_VMX
|
||||
|
||||
/* The CPU detection code needs to be in a file not compiled with
|
||||
* "-maltivec -mabi=altivec", as gcc would try to save vector register
|
||||
* across function calls causing SIGILL on cpus without Altivec/vmx.
|
||||
*/
|
||||
static pixman_bool_t initialized = FALSE;
|
||||
static volatile pixman_bool_t have_vmx = TRUE;
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
size_t length = sizeof(have_vmx);
|
||||
int error =
|
||||
sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
|
||||
|
||||
if (error)
|
||||
have_vmx = FALSE;
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
|
||||
size_t length = sizeof(have_vmx);
|
||||
int error =
|
||||
sysctl (mib, 2, &have_vmx, &length, NULL, 0);
|
||||
|
||||
if (error != 0)
|
||||
have_vmx = FALSE;
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__linux__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <linux/auxvec.h>
|
||||
#include <asm/cputable.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
char fname[64];
|
||||
unsigned long buf[64];
|
||||
ssize_t count = 0;
|
||||
pid_t pid;
|
||||
int fd, i;
|
||||
|
||||
pid = getpid ();
|
||||
snprintf (fname, sizeof(fname) - 1, "/proc/%d/auxv", pid);
|
||||
|
||||
fd = open (fname, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
for (i = 0; i <= (count / sizeof(unsigned long)); i += 2)
|
||||
{
|
||||
/* Read more if buf is empty... */
|
||||
if (i == (count / sizeof(unsigned long)))
|
||||
{
|
||||
count = read (fd, buf, sizeof(buf));
|
||||
if (count <= 0)
|
||||
break;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (buf[i] == AT_HWCAP)
|
||||
{
|
||||
have_vmx = !!(buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC);
|
||||
initialized = TRUE;
|
||||
break;
|
||||
}
|
||||
else if (buf[i] == AT_NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
if (!initialized)
|
||||
{
|
||||
/* Something went wrong. Assume 'no' rather than playing
|
||||
fragile tricks with catching SIGILL. */
|
||||
have_vmx = FALSE;
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
static jmp_buf jump_env;
|
||||
|
||||
static void
|
||||
vmx_test (int sig,
|
||||
siginfo_t *si,
|
||||
void * unused)
|
||||
{
|
||||
longjmp (jump_env, 1);
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
struct sigaction sa, osa;
|
||||
int jmp_result;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sa.sa_sigaction = vmx_test;
|
||||
sigaction (SIGILL, &sa, &osa);
|
||||
jmp_result = setjmp (jump_env);
|
||||
if (jmp_result == 0)
|
||||
{
|
||||
asm volatile ( "vor 0, 0, 0" );
|
||||
}
|
||||
sigaction (SIGILL, &osa, NULL);
|
||||
have_vmx = (jmp_result == 0);
|
||||
initialized = TRUE;
|
||||
}
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
#endif /* USE_VMX */
|
||||
|
||||
#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#if defined(USE_ARM_SIMD)
|
||||
extern int pixman_msvc_try_arm_simd_op ();
|
||||
|
||||
pixman_bool_t
|
||||
pixman_have_arm_simd (void)
|
||||
{
|
||||
static pixman_bool_t initialized = FALSE;
|
||||
static pixman_bool_t have_arm_simd = FALSE;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
__try {
|
||||
pixman_msvc_try_arm_simd_op ();
|
||||
have_arm_simd = TRUE;
|
||||
} __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) {
|
||||
have_arm_simd = FALSE;
|
||||
}
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return have_arm_simd;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_SIMD */
|
||||
|
||||
#if defined(USE_ARM_NEON)
|
||||
extern int pixman_msvc_try_arm_neon_op ();
|
||||
|
||||
pixman_bool_t
|
||||
pixman_have_arm_neon (void)
|
||||
{
|
||||
static pixman_bool_t initialized = FALSE;
|
||||
static pixman_bool_t have_arm_neon = FALSE;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
__try
|
||||
{
|
||||
pixman_msvc_try_arm_neon_op ();
|
||||
have_arm_neon = TRUE;
|
||||
}
|
||||
__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
have_arm_neon = FALSE;
|
||||
}
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return have_arm_neon;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_NEON */
|
||||
|
||||
#else /* linux ELF */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
|
||||
static pixman_bool_t arm_has_v7 = FALSE;
|
||||
static pixman_bool_t arm_has_v6 = FALSE;
|
||||
static pixman_bool_t arm_has_vfp = FALSE;
|
||||
static pixman_bool_t arm_has_neon = FALSE;
|
||||
static pixman_bool_t arm_has_iwmmxt = FALSE;
|
||||
static pixman_bool_t arm_tests_initialized = FALSE;
|
||||
|
||||
static void
|
||||
pixman_arm_read_auxv ()
|
||||
{
|
||||
int fd;
|
||||
Elf32_auxv_t aux;
|
||||
|
||||
fd = open ("/proc/self/auxv", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
|
||||
{
|
||||
if (aux.a_type == AT_HWCAP)
|
||||
{
|
||||
uint32_t hwcap = aux.a_un.a_val;
|
||||
/* hardcode these values to avoid depending on specific
|
||||
* versions of the hwcap header, e.g. HWCAP_NEON
|
||||
*/
|
||||
arm_has_vfp = (hwcap & 64) != 0;
|
||||
arm_has_iwmmxt = (hwcap & 512) != 0;
|
||||
/* this flag is only present on kernel 2.6.29 */
|
||||
arm_has_neon = (hwcap & 4096) != 0;
|
||||
}
|
||||
else if (aux.a_type == AT_PLATFORM)
|
||||
{
|
||||
const char *plat = (const char*) aux.a_un.a_val;
|
||||
if (strncmp (plat, "v7l", 3) == 0)
|
||||
{
|
||||
arm_has_v7 = TRUE;
|
||||
arm_has_v6 = TRUE;
|
||||
}
|
||||
else if (strncmp (plat, "v6l", 3) == 0)
|
||||
{
|
||||
arm_has_v6 = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (fd);
|
||||
}
|
||||
|
||||
arm_tests_initialized = TRUE;
|
||||
}
|
||||
|
||||
#if defined(USE_ARM_SIMD)
|
||||
pixman_bool_t
|
||||
pixman_have_arm_simd (void)
|
||||
{
|
||||
if (!arm_tests_initialized)
|
||||
pixman_arm_read_auxv ();
|
||||
|
||||
return arm_has_v6;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_SIMD */
|
||||
|
||||
#if defined(USE_ARM_NEON)
|
||||
pixman_bool_t
|
||||
pixman_have_arm_neon (void)
|
||||
{
|
||||
if (!arm_tests_initialized)
|
||||
pixman_arm_read_auxv ();
|
||||
|
||||
return arm_has_neon;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_NEON */
|
||||
|
||||
#endif /* linux */
|
||||
|
||||
#endif /* USE_ARM_SIMD || USE_ARM_NEON */
|
||||
|
||||
#if defined(USE_MMX) || defined(USE_SSE2)
|
||||
/* The CPU detection code needs to be in a file not compiled with
|
||||
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
|
||||
* that would lead to SIGILL instructions on old CPUs that don't have
|
||||
* it.
|
||||
*/
|
||||
#if !defined(__amd64__) && !defined(__x86_64__) && !defined(_M_AMD64)
|
||||
|
||||
#ifdef HAVE_GETISAX
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NO_FEATURES = 0,
|
||||
MMX = 0x1,
|
||||
MMX_EXTENSIONS = 0x2,
|
||||
SSE = 0x6,
|
||||
SSE2 = 0x8,
|
||||
CMOV = 0x10
|
||||
} cpu_features_t;
|
||||
|
||||
|
||||
static unsigned int
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
unsigned int features = 0;
|
||||
unsigned int result = 0;
|
||||
|
||||
#ifdef HAVE_GETISAX
|
||||
if (getisax (&result, 1))
|
||||
{
|
||||
if (result & AV_386_CMOV)
|
||||
features |= CMOV;
|
||||
if (result & AV_386_MMX)
|
||||
features |= MMX;
|
||||
if (result & AV_386_AMD_MMX)
|
||||
features |= MMX_EXTENSIONS;
|
||||
if (result & AV_386_SSE)
|
||||
features |= SSE;
|
||||
if (result & AV_386_SSE2)
|
||||
features |= SSE2;
|
||||
}
|
||||
#else
|
||||
char vendor[13];
|
||||
#ifdef _MSC_VER
|
||||
int vendor0 = 0, vendor1, vendor2;
|
||||
#endif
|
||||
vendor[0] = 0;
|
||||
vendor[12] = 0;
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* see p. 118 of amd64 instruction set manual Vol3 */
|
||||
/* We need to be careful about the handling of %ebx and
|
||||
* %esp here. We can't declare either one as clobbered
|
||||
* since they are special registers (%ebx is the "PIC
|
||||
* register" holding an offset to global data, %esp the
|
||||
* stack pointer), so we need to make sure they have their
|
||||
* original values when we access the output operands.
|
||||
*/
|
||||
__asm__ (
|
||||
"pushf\n"
|
||||
"pop %%eax\n"
|
||||
"mov %%eax, %%ecx\n"
|
||||
"xor $0x00200000, %%eax\n"
|
||||
"push %%eax\n"
|
||||
"popf\n"
|
||||
"pushf\n"
|
||||
"pop %%eax\n"
|
||||
"mov $0x0, %%edx\n"
|
||||
"xor %%ecx, %%eax\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"mov $0x00000000, %%eax\n"
|
||||
"push %%ebx\n"
|
||||
"cpuid\n"
|
||||
"mov %%ebx, %%eax\n"
|
||||
"pop %%ebx\n"
|
||||
"mov %%eax, %1\n"
|
||||
"mov %%edx, %2\n"
|
||||
"mov %%ecx, %3\n"
|
||||
"mov $0x00000001, %%eax\n"
|
||||
"push %%ebx\n"
|
||||
"cpuid\n"
|
||||
"pop %%ebx\n"
|
||||
"1:\n"
|
||||
"mov %%edx, %0\n"
|
||||
: "=r" (result),
|
||||
"=m" (vendor[0]),
|
||||
"=m" (vendor[4]),
|
||||
"=m" (vendor[8])
|
||||
:
|
||||
: "%eax", "%ecx", "%edx"
|
||||
);
|
||||
|
||||
#elif defined (_MSC_VER)
|
||||
|
||||
_asm {
|
||||
pushfd
|
||||
pop eax
|
||||
mov ecx, eax
|
||||
xor eax, 00200000h
|
||||
push eax
|
||||
popfd
|
||||
pushfd
|
||||
pop eax
|
||||
mov edx, 0
|
||||
xor eax, ecx
|
||||
jz nocpuid
|
||||
|
||||
mov eax, 0
|
||||
push ebx
|
||||
cpuid
|
||||
mov eax, ebx
|
||||
pop ebx
|
||||
mov vendor0, eax
|
||||
mov vendor1, edx
|
||||
mov vendor2, ecx
|
||||
mov eax, 1
|
||||
push ebx
|
||||
cpuid
|
||||
pop ebx
|
||||
nocpuid:
|
||||
mov result, edx
|
||||
}
|
||||
memmove (vendor + 0, &vendor0, 4);
|
||||
memmove (vendor + 4, &vendor1, 4);
|
||||
memmove (vendor + 8, &vendor2, 4);
|
||||
|
||||
#else
|
||||
# error unsupported compiler
|
||||
#endif
|
||||
|
||||
features = 0;
|
||||
if (result)
|
||||
{
|
||||
/* result now contains the standard feature bits */
|
||||
if (result & (1 << 15))
|
||||
features |= CMOV;
|
||||
if (result & (1 << 23))
|
||||
features |= MMX;
|
||||
if (result & (1 << 25))
|
||||
features |= SSE;
|
||||
if (result & (1 << 26))
|
||||
features |= SSE2;
|
||||
if ((features & MMX) && !(features & SSE) &&
|
||||
(strcmp (vendor, "AuthenticAMD") == 0 ||
|
||||
strcmp (vendor, "Geode by NSC") == 0))
|
||||
{
|
||||
/* check for AMD MMX extensions */
|
||||
#ifdef __GNUC__
|
||||
__asm__ (
|
||||
" push %%ebx\n"
|
||||
" mov $0x80000000, %%eax\n"
|
||||
" cpuid\n"
|
||||
" xor %%edx, %%edx\n"
|
||||
" cmp $0x1, %%eax\n"
|
||||
" jge 2f\n"
|
||||
" mov $0x80000001, %%eax\n"
|
||||
" cpuid\n"
|
||||
"2:\n"
|
||||
" pop %%ebx\n"
|
||||
" mov %%edx, %0\n"
|
||||
: "=r" (result)
|
||||
:
|
||||
: "%eax", "%ecx", "%edx"
|
||||
);
|
||||
#elif defined _MSC_VER
|
||||
_asm {
|
||||
push ebx
|
||||
mov eax, 80000000h
|
||||
cpuid
|
||||
xor edx, edx
|
||||
cmp eax, 1
|
||||
jge notamd
|
||||
mov eax, 80000001h
|
||||
cpuid
|
||||
notamd:
|
||||
pop ebx
|
||||
mov result, edx
|
||||
}
|
||||
#endif
|
||||
if (result & (1 << 22))
|
||||
features |= MMX_EXTENSIONS;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_GETISAX */
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_mmx (void)
|
||||
{
|
||||
static pixman_bool_t initialized = FALSE;
|
||||
static pixman_bool_t mmx_present;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
unsigned int features = detect_cpu_features ();
|
||||
mmx_present = (features & (MMX | MMX_EXTENSIONS)) == (MMX | MMX_EXTENSIONS);
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return mmx_present;
|
||||
}
|
||||
|
||||
#ifdef USE_SSE2
|
||||
static pixman_bool_t
|
||||
pixman_have_sse2 (void)
|
||||
{
|
||||
static pixman_bool_t initialized = FALSE;
|
||||
static pixman_bool_t sse2_present;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
unsigned int features = detect_cpu_features ();
|
||||
sse2_present = (features & (MMX | MMX_EXTENSIONS | SSE | SSE2)) == (MMX | MMX_EXTENSIONS | SSE | SSE2);
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return sse2_present;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else /* __amd64__ */
|
||||
#ifdef USE_MMX
|
||||
#define pixman_have_mmx() TRUE
|
||||
#endif
|
||||
#ifdef USE_SSE2
|
||||
#define pixman_have_sse2() TRUE
|
||||
#endif
|
||||
#endif /* __amd64__ */
|
||||
#endif
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_choose_implementation (void)
|
||||
{
|
||||
#ifdef USE_SSE2
|
||||
if (pixman_have_sse2 ())
|
||||
return _pixman_implementation_create_sse2 ();
|
||||
#endif
|
||||
#ifdef USE_MMX
|
||||
if (pixman_have_mmx ())
|
||||
return _pixman_implementation_create_mmx ();
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_NEON
|
||||
if (pixman_have_arm_neon ())
|
||||
return _pixman_implementation_create_arm_neon ();
|
||||
#endif
|
||||
#ifdef USE_ARM_SIMD
|
||||
if (pixman_have_arm_simd ())
|
||||
return _pixman_implementation_create_arm_simd ();
|
||||
#endif
|
||||
#ifdef USE_VMX
|
||||
if (pixman_have_vmx ())
|
||||
return _pixman_implementation_create_vmx ();
|
||||
#endif
|
||||
|
||||
return _pixman_implementation_create_fast_path ();
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
|
||||
#define PIXMAN_FB_ACCESSORS
|
||||
|
||||
#include "pixman-edge.c"
|
182
programs/develop/libraries/pixman/pixman-edge-imp.h
Normal file
182
programs/develop/libraries/pixman/pixman-edge-imp.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef rasterize_span
|
||||
#endif
|
||||
|
||||
static void
|
||||
RASTERIZE_EDGES (pixman_image_t *image,
|
||||
pixman_edge_t *l,
|
||||
pixman_edge_t *r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
pixman_fixed_t y = t;
|
||||
uint32_t *line;
|
||||
uint32_t *buf = (image)->bits.bits;
|
||||
int stride = (image)->bits.rowstride;
|
||||
int width = (image)->bits.width;
|
||||
|
||||
line = buf + pixman_fixed_to_int (y) * stride;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
pixman_fixed_t lx;
|
||||
pixman_fixed_t rx;
|
||||
int lxi;
|
||||
int rxi;
|
||||
|
||||
lx = l->x;
|
||||
rx = r->x;
|
||||
#if N_BITS == 1
|
||||
/* For the non-antialiased case, round the coordinates up, in effect
|
||||
* sampling just slightly to the left of the pixel. This is so that
|
||||
* when the sample point lies exactly on the line, we round towards
|
||||
* north-west.
|
||||
*
|
||||
* (The AA case does a similar adjustment in RENDER_SAMPLES_X)
|
||||
*/
|
||||
lx += X_FRAC_FIRST(1) - pixman_fixed_e;
|
||||
rx += X_FRAC_FIRST(1) - pixman_fixed_e;
|
||||
#endif
|
||||
/* clip X */
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
if (pixman_fixed_to_int (rx) >= width)
|
||||
#if N_BITS == 1
|
||||
rx = pixman_int_to_fixed (width);
|
||||
#else
|
||||
/* Use the last pixel of the scanline, covered 100%.
|
||||
* We can't use the first pixel following the scanline,
|
||||
* because accessing it could result in a buffer overrun.
|
||||
*/
|
||||
rx = pixman_int_to_fixed (width) - 1;
|
||||
#endif
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx)
|
||||
{
|
||||
|
||||
/* Find pixel bounds for span */
|
||||
lxi = pixman_fixed_to_int (lx);
|
||||
rxi = pixman_fixed_to_int (rx);
|
||||
|
||||
#if N_BITS == 1
|
||||
{
|
||||
|
||||
#define LEFT_MASK(x) \
|
||||
(((x) & 0x1f) ? \
|
||||
SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0)
|
||||
#define RIGHT_MASK(x) \
|
||||
(((32 - (x)) & 0x1f) ? \
|
||||
SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0)
|
||||
|
||||
#define MASK_BITS(x,w,l,n,r) { \
|
||||
n = (w); \
|
||||
r = RIGHT_MASK ((x) + n); \
|
||||
l = LEFT_MASK (x); \
|
||||
if (l) { \
|
||||
n -= 32 - ((x) & 0x1f); \
|
||||
if (n < 0) { \
|
||||
n = 0; \
|
||||
l &= r; \
|
||||
r = 0; \
|
||||
} \
|
||||
} \
|
||||
n >>= 5; \
|
||||
}
|
||||
|
||||
uint32_t *a = line;
|
||||
uint32_t startmask;
|
||||
uint32_t endmask;
|
||||
int nmiddle;
|
||||
int width = rxi - lxi;
|
||||
int x = lxi;
|
||||
|
||||
a += x >> 5;
|
||||
x &= 0x1f;
|
||||
|
||||
MASK_BITS (x, width, startmask, nmiddle, endmask);
|
||||
|
||||
if (startmask) {
|
||||
WRITE(image, a, READ(image, a) | startmask);
|
||||
a++;
|
||||
}
|
||||
while (nmiddle--)
|
||||
WRITE(image, a++, 0xffffffff);
|
||||
if (endmask)
|
||||
WRITE(image, a, READ(image, a) | endmask);
|
||||
}
|
||||
#else
|
||||
{
|
||||
DEFINE_ALPHA(line,lxi);
|
||||
int lxs;
|
||||
int rxs;
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RENDER_SAMPLES_X (lx, N_BITS);
|
||||
rxs = RENDER_SAMPLES_X (rx, N_BITS);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi)
|
||||
{
|
||||
ADD_ALPHA (rxs - lxs);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xi;
|
||||
|
||||
ADD_ALPHA (N_X_FRAC(N_BITS) - lxs);
|
||||
STEP_ALPHA;
|
||||
for (xi = lxi + 1; xi < rxi; xi++)
|
||||
{
|
||||
ADD_ALPHA (N_X_FRAC(N_BITS));
|
||||
STEP_ALPHA;
|
||||
}
|
||||
ADD_ALPHA (rxs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (y == b)
|
||||
break;
|
||||
|
||||
#if N_BITS > 1
|
||||
if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
|
||||
{
|
||||
RENDER_EDGE_STEP_SMALL (l);
|
||||
RENDER_EDGE_STEP_SMALL (r);
|
||||
y += STEP_Y_SMALL(N_BITS);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RENDER_EDGE_STEP_BIG (l);
|
||||
RENDER_EDGE_STEP_BIG (r);
|
||||
y += STEP_Y_BIG(N_BITS);
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef rasterize_span
|
384
programs/develop/libraries/pixman/pixman-edge.c
Normal file
384
programs/develop/libraries/pixman/pixman-edge.c
Normal file
@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-accessor.h"
|
||||
|
||||
/*
|
||||
* Step across a small sample grid gap
|
||||
*/
|
||||
#define RENDER_EDGE_STEP_SMALL(edge) \
|
||||
{ \
|
||||
edge->x += edge->stepx_small; \
|
||||
edge->e += edge->dx_small; \
|
||||
if (edge->e > 0) \
|
||||
{ \
|
||||
edge->e -= edge->dy; \
|
||||
edge->x += edge->signdx; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Step across a large sample grid gap
|
||||
*/
|
||||
#define RENDER_EDGE_STEP_BIG(edge) \
|
||||
{ \
|
||||
edge->x += edge->stepx_big; \
|
||||
edge->e += edge->dx_big; \
|
||||
if (edge->e > 0) \
|
||||
{ \
|
||||
edge->e -= edge->dy; \
|
||||
edge->x += edge->signdx; \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef PIXMAN_FB_ACCESSORS
|
||||
#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors
|
||||
#else
|
||||
#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_no_accessors
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 4
|
||||
#define RASTERIZE_EDGES rasterize_edges_4
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
#define SHIFT_4(o) ((o) << 2)
|
||||
#else
|
||||
#define SHIFT_4(o) ((1 - (o)) << 2)
|
||||
#endif
|
||||
|
||||
#define GET_4(x, o) (((x) >> SHIFT_4 (o)) & 0xf)
|
||||
#define PUT_4(x, o, v) \
|
||||
(((x) & ~(0xf << SHIFT_4 (o))) | (((v) & 0xf) << SHIFT_4 (o)))
|
||||
|
||||
#define DEFINE_ALPHA(line, x) \
|
||||
uint8_t *__ap = (uint8_t *) line + ((x) >> 1); \
|
||||
int __ao = (x) & 1
|
||||
|
||||
#define STEP_ALPHA ((__ap += __ao), (__ao ^= 1))
|
||||
|
||||
#define ADD_ALPHA(a) \
|
||||
{ \
|
||||
uint8_t __o = READ (image, __ap); \
|
||||
uint8_t __a = (a) + GET_4 (__o, __ao); \
|
||||
WRITE (image, __ap, PUT_4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
|
||||
}
|
||||
|
||||
#include "pixman-edge-imp.h"
|
||||
|
||||
#undef ADD_ALPHA
|
||||
#undef STEP_ALPHA
|
||||
#undef DEFINE_ALPHA
|
||||
#undef RASTERIZE_EDGES
|
||||
#undef N_BITS
|
||||
|
||||
|
||||
/*
|
||||
* 1 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 1
|
||||
#define RASTERIZE_EDGES rasterize_edges_1
|
||||
|
||||
#include "pixman-edge-imp.h"
|
||||
|
||||
#undef RASTERIZE_EDGES
|
||||
#undef N_BITS
|
||||
|
||||
/*
|
||||
* 8 bit alpha
|
||||
*/
|
||||
|
||||
static force_inline uint8_t
|
||||
clip255 (int x)
|
||||
{
|
||||
if (x > 255)
|
||||
return 255;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#define ADD_SATURATE_8(buf, val, length) \
|
||||
do \
|
||||
{ \
|
||||
int i__ = (length); \
|
||||
uint8_t *buf__ = (buf); \
|
||||
int val__ = (val); \
|
||||
\
|
||||
while (i__--) \
|
||||
{ \
|
||||
WRITE (image, (buf__), clip255 (READ (image, (buf__)) + (val__))); \
|
||||
(buf__)++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* We want to detect the case where we add the same value to a long
|
||||
* span of pixels. The triangles on the end are filled in while we
|
||||
* count how many sub-pixel scanlines contribute to the middle section.
|
||||
*
|
||||
* +--------------------------+
|
||||
* fill_height =| \ /
|
||||
* +------------------+
|
||||
* |================|
|
||||
* fill_start fill_end
|
||||
*/
|
||||
static void
|
||||
rasterize_edges_8 (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
pixman_fixed_t y = t;
|
||||
uint32_t *line;
|
||||
int fill_start = -1, fill_end = -1;
|
||||
int fill_size = 0;
|
||||
uint32_t *buf = (image)->bits.bits;
|
||||
int stride = (image)->bits.rowstride;
|
||||
int width = (image)->bits.width;
|
||||
|
||||
line = buf + pixman_fixed_to_int (y) * stride;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
uint8_t *ap = (uint8_t *) line;
|
||||
pixman_fixed_t lx, rx;
|
||||
int lxi, rxi;
|
||||
|
||||
/* clip X */
|
||||
lx = l->x;
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
|
||||
rx = r->x;
|
||||
|
||||
if (pixman_fixed_to_int (rx) >= width)
|
||||
{
|
||||
/* Use the last pixel of the scanline, covered 100%.
|
||||
* We can't use the first pixel following the scanline,
|
||||
* because accessing it could result in a buffer overrun.
|
||||
*/
|
||||
rx = pixman_int_to_fixed (width) - 1;
|
||||
}
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx)
|
||||
{
|
||||
int lxs, rxs;
|
||||
|
||||
/* Find pixel bounds for span. */
|
||||
lxi = pixman_fixed_to_int (lx);
|
||||
rxi = pixman_fixed_to_int (rx);
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RENDER_SAMPLES_X (lx, 8);
|
||||
rxs = RENDER_SAMPLES_X (rx, 8);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi)
|
||||
{
|
||||
WRITE (image, ap + lxi,
|
||||
clip255 (READ (image, ap + lxi) + rxs - lxs));
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE (image, ap + lxi,
|
||||
clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs));
|
||||
|
||||
/* Move forward so that lxi/rxi is the pixel span */
|
||||
lxi++;
|
||||
|
||||
/* Don't bother trying to optimize the fill unless
|
||||
* the span is longer than 4 pixels. */
|
||||
if (rxi - lxi > 4)
|
||||
{
|
||||
if (fill_start < 0)
|
||||
{
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lxi >= fill_end || rxi < fill_start)
|
||||
{
|
||||
/* We're beyond what we saved, just fill it */
|
||||
ADD_SATURATE_8 (ap + fill_start,
|
||||
fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update fill_start */
|
||||
if (lxi > fill_start)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start,
|
||||
fill_size * N_X_FRAC (8),
|
||||
lxi - fill_start);
|
||||
fill_start = lxi;
|
||||
}
|
||||
else if (lxi < fill_start)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8),
|
||||
fill_start - lxi);
|
||||
}
|
||||
|
||||
/* Update fill_end */
|
||||
if (rxi < fill_end)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + rxi,
|
||||
fill_size * N_X_FRAC (8),
|
||||
fill_end - rxi);
|
||||
fill_end = rxi;
|
||||
}
|
||||
else if (fill_end < rxi)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_end,
|
||||
N_X_FRAC (8),
|
||||
rxi - fill_end);
|
||||
}
|
||||
fill_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi);
|
||||
}
|
||||
|
||||
WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs));
|
||||
}
|
||||
}
|
||||
|
||||
if (y == b)
|
||||
{
|
||||
/* We're done, make sure we clean up any remaining fill. */
|
||||
if (fill_start != fill_end)
|
||||
{
|
||||
if (fill_size == N_Y_FRAC (8))
|
||||
{
|
||||
MEMSET_WRAPPED (image, ap + fill_start,
|
||||
0xff, fill_end - fill_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pixman_fixed_frac (y) != Y_FRAC_LAST (8))
|
||||
{
|
||||
RENDER_EDGE_STEP_SMALL (l);
|
||||
RENDER_EDGE_STEP_SMALL (r);
|
||||
y += STEP_Y_SMALL (8);
|
||||
}
|
||||
else
|
||||
{
|
||||
RENDER_EDGE_STEP_BIG (l);
|
||||
RENDER_EDGE_STEP_BIG (r);
|
||||
y += STEP_Y_BIG (8);
|
||||
if (fill_start != fill_end)
|
||||
{
|
||||
if (fill_size == N_Y_FRAC (8))
|
||||
{
|
||||
MEMSET_WRAPPED (image, ap + fill_start,
|
||||
0xff, fill_end - fill_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
|
||||
fill_start = fill_end = -1;
|
||||
fill_size = 0;
|
||||
}
|
||||
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PIXMAN_FB_ACCESSORS
|
||||
static
|
||||
#endif
|
||||
void
|
||||
PIXMAN_RASTERIZE_EDGES (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
switch (PIXMAN_FORMAT_BPP (image->bits.format))
|
||||
{
|
||||
case 1:
|
||||
rasterize_edges_1 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rasterize_edges_4 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
rasterize_edges_8 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PIXMAN_FB_ACCESSORS
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_rasterize_edges (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
return_if_fail (image->type == BITS);
|
||||
|
||||
if (image->bits.read_func || image->bits.write_func)
|
||||
pixman_rasterize_edges_accessors (image, l, r, t, b);
|
||||
else
|
||||
pixman_rasterize_edges_no_accessors (image, l, r, t, b);
|
||||
}
|
||||
|
||||
#endif
|
1852
programs/develop/libraries/pixman/pixman-fast-path.c
Normal file
1852
programs/develop/libraries/pixman/pixman-fast-path.c
Normal file
File diff suppressed because it is too large
Load Diff
451
programs/develop/libraries/pixman/pixman-fast-path.h
Normal file
451
programs/develop/libraries/pixman/pixman-fast-path.h
Normal file
@ -0,0 +1,451 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Keith Packard, SuSE, Inc.
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_FAST_PATH_H__
|
||||
#define PIXMAN_FAST_PATH_H__
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#define PIXMAN_REPEAT_COVER -1
|
||||
|
||||
static force_inline pixman_bool_t
|
||||
repeat (pixman_repeat_t repeat, int *c, int size)
|
||||
{
|
||||
if (repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (*c < 0 || *c >= size)
|
||||
return FALSE;
|
||||
}
|
||||
else if (repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
while (*c >= size)
|
||||
*c -= size;
|
||||
while (*c < 0)
|
||||
*c += size;
|
||||
}
|
||||
else if (repeat == PIXMAN_REPEAT_PAD)
|
||||
{
|
||||
*c = CLIP (*c, 0, size - 1);
|
||||
}
|
||||
else /* REFLECT */
|
||||
{
|
||||
*c = MOD (*c, size * 2);
|
||||
if (*c >= size)
|
||||
*c = size * 2 - *c - 1;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* For each scanline fetched from source image with PAD repeat:
|
||||
* - calculate how many pixels need to be padded on the left side
|
||||
* - calculate how many pixels need to be padded on the right side
|
||||
* - update width to only count pixels which are fetched from the image
|
||||
* All this information is returned via 'width', 'left_pad', 'right_pad'
|
||||
* arguments. The code is assuming that 'unit_x' is positive.
|
||||
*
|
||||
* Note: 64-bit math is used in order to avoid potential overflows, which
|
||||
* is probably excessive in many cases. This particular function
|
||||
* may need its own correctness test and performance tuning.
|
||||
*/
|
||||
static force_inline void
|
||||
pad_repeat_get_scanline_bounds (int32_t source_image_width,
|
||||
pixman_fixed_t vx,
|
||||
pixman_fixed_t unit_x,
|
||||
int32_t * width,
|
||||
int32_t * left_pad,
|
||||
int32_t * right_pad)
|
||||
{
|
||||
int64_t max_vx = (int64_t) source_image_width << 16;
|
||||
int64_t tmp;
|
||||
if (vx < 0)
|
||||
{
|
||||
tmp = ((int64_t) unit_x - 1 - vx) / unit_x;
|
||||
if (tmp > *width)
|
||||
{
|
||||
*left_pad = *width;
|
||||
*width = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*left_pad = (int32_t) tmp;
|
||||
*width -= (int32_t) tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*left_pad = 0;
|
||||
}
|
||||
tmp = ((int64_t) unit_x - 1 - vx + max_vx) / unit_x - *left_pad;
|
||||
if (tmp < 0)
|
||||
{
|
||||
*right_pad = *width;
|
||||
*width = 0;
|
||||
}
|
||||
else if (tmp >= *width)
|
||||
{
|
||||
*right_pad = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*right_pad = *width - (int32_t) tmp;
|
||||
*width = (int32_t) tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* A macroified version of specialized nearest scalers for some
|
||||
* common 8888 and 565 formats. It supports SRC and OVER ops.
|
||||
*
|
||||
* There are two repeat versions, one that handles repeat normal,
|
||||
* and one without repeat handling that only works if the src region
|
||||
* used is completely covered by the pre-repeated source samples.
|
||||
*
|
||||
* The loops are unrolled to process two pixels per iteration for better
|
||||
* performance on most CPU architectures (superscalar processors
|
||||
* can issue several operations simultaneously, other processors can hide
|
||||
* instructions latencies by pipelining operations). Unrolling more
|
||||
* does not make much sense because the compiler will start running out
|
||||
* of spare registers soon.
|
||||
*/
|
||||
|
||||
#define GET_8888_ALPHA(s) ((s) >> 24)
|
||||
/* This is not actually used since we don't have an OVER with
|
||||
565 source, but it is needed to build. */
|
||||
#define GET_0565_ALPHA(s) 0xff
|
||||
|
||||
#define FAST_NEAREST_SCANLINE(scanline_func_name, SRC_FORMAT, DST_FORMAT, \
|
||||
src_type_t, dst_type_t, OP, repeat_mode) \
|
||||
static force_inline void \
|
||||
scanline_func_name (dst_type_t *dst, \
|
||||
src_type_t *src, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx) \
|
||||
{ \
|
||||
uint32_t d; \
|
||||
src_type_t s1, s2; \
|
||||
uint8_t a1, a2; \
|
||||
int x1, x2; \
|
||||
\
|
||||
if (PIXMAN_OP_ ## OP != PIXMAN_OP_SRC && PIXMAN_OP_ ## OP != PIXMAN_OP_OVER) \
|
||||
abort(); \
|
||||
\
|
||||
while ((w -= 2) >= 0) \
|
||||
{ \
|
||||
x1 = vx >> 16; \
|
||||
vx += unit_x; \
|
||||
if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \
|
||||
{ \
|
||||
/* This works because we know that unit_x is positive */ \
|
||||
while (vx >= max_vx) \
|
||||
vx -= max_vx; \
|
||||
} \
|
||||
s1 = src[x1]; \
|
||||
\
|
||||
x2 = vx >> 16; \
|
||||
vx += unit_x; \
|
||||
if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \
|
||||
{ \
|
||||
/* This works because we know that unit_x is positive */ \
|
||||
while (vx >= max_vx) \
|
||||
vx -= max_vx; \
|
||||
} \
|
||||
s2 = src[x2]; \
|
||||
\
|
||||
if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER) \
|
||||
{ \
|
||||
a1 = GET_ ## SRC_FORMAT ## _ALPHA(s1); \
|
||||
a2 = GET_ ## SRC_FORMAT ## _ALPHA(s2); \
|
||||
\
|
||||
if (a1 == 0xff) \
|
||||
{ \
|
||||
*dst = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \
|
||||
} \
|
||||
else if (s1) \
|
||||
{ \
|
||||
d = CONVERT_ ## DST_FORMAT ## _TO_8888 (*dst); \
|
||||
s1 = CONVERT_ ## SRC_FORMAT ## _TO_8888 (s1); \
|
||||
a1 ^= 0xff; \
|
||||
UN8x4_MUL_UN8_ADD_UN8x4 (d, a1, s1); \
|
||||
*dst = CONVERT_8888_TO_ ## DST_FORMAT (d); \
|
||||
} \
|
||||
dst++; \
|
||||
\
|
||||
if (a2 == 0xff) \
|
||||
{ \
|
||||
*dst = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s2); \
|
||||
} \
|
||||
else if (s2) \
|
||||
{ \
|
||||
d = CONVERT_## DST_FORMAT ## _TO_8888 (*dst); \
|
||||
s2 = CONVERT_## SRC_FORMAT ## _TO_8888 (s2); \
|
||||
a2 ^= 0xff; \
|
||||
UN8x4_MUL_UN8_ADD_UN8x4 (d, a2, s2); \
|
||||
*dst = CONVERT_8888_TO_ ## DST_FORMAT (d); \
|
||||
} \
|
||||
dst++; \
|
||||
} \
|
||||
else /* PIXMAN_OP_SRC */ \
|
||||
{ \
|
||||
*dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \
|
||||
*dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s2); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (w & 1) \
|
||||
{ \
|
||||
x1 = vx >> 16; \
|
||||
s1 = src[x1]; \
|
||||
\
|
||||
if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER) \
|
||||
{ \
|
||||
a1 = GET_ ## SRC_FORMAT ## _ALPHA(s1); \
|
||||
\
|
||||
if (a1 == 0xff) \
|
||||
{ \
|
||||
*dst = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \
|
||||
} \
|
||||
else if (s1) \
|
||||
{ \
|
||||
d = CONVERT_## DST_FORMAT ## _TO_8888 (*dst); \
|
||||
s1 = CONVERT_ ## SRC_FORMAT ## _TO_8888 (s1); \
|
||||
a1 ^= 0xff; \
|
||||
UN8x4_MUL_UN8_ADD_UN8x4 (d, a1, s1); \
|
||||
*dst = CONVERT_8888_TO_ ## DST_FORMAT (d); \
|
||||
} \
|
||||
dst++; \
|
||||
} \
|
||||
else /* PIXMAN_OP_SRC */ \
|
||||
{ \
|
||||
*dst++ = CONVERT_ ## SRC_FORMAT ## _TO_ ## DST_FORMAT (s1); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FAST_NEAREST_MAINLOOP_INT(scale_func_name, scanline_func, src_type_t, dst_type_t, \
|
||||
repeat_mode) \
|
||||
static void \
|
||||
fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, \
|
||||
pixman_op_t op, \
|
||||
pixman_image_t * src_image, \
|
||||
pixman_image_t * mask_image, \
|
||||
pixman_image_t * dst_image, \
|
||||
int32_t src_x, \
|
||||
int32_t src_y, \
|
||||
int32_t mask_x, \
|
||||
int32_t mask_y, \
|
||||
int32_t dst_x, \
|
||||
int32_t dst_y, \
|
||||
int32_t width, \
|
||||
int32_t height) \
|
||||
{ \
|
||||
dst_type_t *dst_line; \
|
||||
src_type_t *src_first_line; \
|
||||
int y; \
|
||||
pixman_fixed_t max_vx = max_vx; /* suppress uninitialized variable warning */ \
|
||||
pixman_fixed_t max_vy; \
|
||||
pixman_vector_t v; \
|
||||
pixman_fixed_t vx, vy; \
|
||||
pixman_fixed_t unit_x, unit_y; \
|
||||
int32_t left_pad, right_pad; \
|
||||
\
|
||||
src_type_t *src; \
|
||||
dst_type_t *dst; \
|
||||
int src_stride, dst_stride; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dst_image, dst_x, dst_y, dst_type_t, dst_stride, dst_line, 1); \
|
||||
/* pass in 0 instead of src_x and src_y because src_x and src_y need to be \
|
||||
* transformed from destination space to source space */ \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, src_type_t, src_stride, src_first_line, 1); \
|
||||
\
|
||||
/* reference point is the center of the pixel */ \
|
||||
v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2; \
|
||||
v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2; \
|
||||
v.vector[2] = pixman_fixed_1; \
|
||||
\
|
||||
if (!pixman_transform_point_3d (src_image->common.transform, &v)) \
|
||||
return; \
|
||||
\
|
||||
unit_x = src_image->common.transform->matrix[0][0]; \
|
||||
unit_y = src_image->common.transform->matrix[1][1]; \
|
||||
\
|
||||
/* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */ \
|
||||
v.vector[0] -= pixman_fixed_e; \
|
||||
v.vector[1] -= pixman_fixed_e; \
|
||||
\
|
||||
vx = v.vector[0]; \
|
||||
vy = v.vector[1]; \
|
||||
\
|
||||
if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \
|
||||
{ \
|
||||
/* Clamp repeating positions inside the actual samples */ \
|
||||
max_vx = src_image->bits.width << 16; \
|
||||
max_vy = src_image->bits.height << 16; \
|
||||
\
|
||||
repeat (PIXMAN_REPEAT_NORMAL, &vx, max_vx); \
|
||||
repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy); \
|
||||
} \
|
||||
\
|
||||
if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD || \
|
||||
PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \
|
||||
{ \
|
||||
pad_repeat_get_scanline_bounds (src_image->bits.width, vx, unit_x, \
|
||||
&width, &left_pad, &right_pad); \
|
||||
vx += left_pad * unit_x; \
|
||||
} \
|
||||
\
|
||||
while (--height >= 0) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
\
|
||||
y = vy >> 16; \
|
||||
vy += unit_y; \
|
||||
if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \
|
||||
repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy); \
|
||||
if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD) \
|
||||
{ \
|
||||
repeat (PIXMAN_REPEAT_PAD, &y, src_image->bits.height); \
|
||||
src = src_first_line + src_stride * y; \
|
||||
if (left_pad > 0) \
|
||||
{ \
|
||||
scanline_func (dst, src, left_pad, 0, 0, 0); \
|
||||
} \
|
||||
if (width > 0) \
|
||||
{ \
|
||||
scanline_func (dst + left_pad, src, width, vx, unit_x, 0); \
|
||||
} \
|
||||
if (right_pad > 0) \
|
||||
{ \
|
||||
scanline_func (dst + left_pad + width, src + src_image->bits.width - 1, \
|
||||
right_pad, 0, 0, 0); \
|
||||
} \
|
||||
} \
|
||||
else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \
|
||||
{ \
|
||||
static src_type_t zero = 0; \
|
||||
if (y < 0 || y >= src_image->bits.height) \
|
||||
{ \
|
||||
scanline_func (dst, &zero, left_pad + width + right_pad, 0, 0, 0); \
|
||||
continue; \
|
||||
} \
|
||||
src = src_first_line + src_stride * y; \
|
||||
if (left_pad > 0) \
|
||||
{ \
|
||||
scanline_func (dst, &zero, left_pad, 0, 0, 0); \
|
||||
} \
|
||||
if (width > 0) \
|
||||
{ \
|
||||
scanline_func (dst + left_pad, src, width, vx, unit_x, 0); \
|
||||
} \
|
||||
if (right_pad > 0) \
|
||||
{ \
|
||||
scanline_func (dst + left_pad + width, &zero, right_pad, 0, 0, 0); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
src = src_first_line + src_stride * y; \
|
||||
scanline_func (dst, src, width, vx, unit_x, max_vx); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* A workaround for old sun studio, see: https://bugs.freedesktop.org/show_bug.cgi?id=32764 */
|
||||
#define FAST_NEAREST_MAINLOOP(scale_func_name, scanline_func, src_type_t, dst_type_t, \
|
||||
repeat_mode) \
|
||||
FAST_NEAREST_MAINLOOP_INT(_ ## scale_func_name, scanline_func, src_type_t, dst_type_t, \
|
||||
repeat_mode) \
|
||||
|
||||
#define FAST_NEAREST(scale_func_name, SRC_FORMAT, DST_FORMAT, \
|
||||
src_type_t, dst_type_t, OP, repeat_mode) \
|
||||
FAST_NEAREST_SCANLINE(scaled_nearest_scanline_ ## scale_func_name ## _ ## OP, \
|
||||
SRC_FORMAT, DST_FORMAT, src_type_t, dst_type_t, \
|
||||
OP, repeat_mode) \
|
||||
FAST_NEAREST_MAINLOOP_INT(_ ## scale_func_name ## _ ## OP, \
|
||||
scaled_nearest_scanline_ ## scale_func_name ## _ ## OP, \
|
||||
src_type_t, dst_type_t, repeat_mode) \
|
||||
\
|
||||
extern int no_such_variable
|
||||
|
||||
|
||||
#define SCALED_NEAREST_FLAGS \
|
||||
(FAST_PATH_SCALE_TRANSFORM | \
|
||||
FAST_PATH_NO_ALPHA_MAP | \
|
||||
FAST_PATH_NEAREST_FILTER | \
|
||||
FAST_PATH_NO_ACCESSORS | \
|
||||
FAST_PATH_NARROW_FORMAT)
|
||||
|
||||
#define SIMPLE_NEAREST_FAST_PATH_NORMAL(op,s,d,func) \
|
||||
{ PIXMAN_OP_ ## op, \
|
||||
PIXMAN_ ## s, \
|
||||
(SCALED_NEAREST_FLAGS | \
|
||||
FAST_PATH_NORMAL_REPEAT | \
|
||||
FAST_PATH_X_UNIT_POSITIVE), \
|
||||
PIXMAN_null, 0, \
|
||||
PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
|
||||
fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \
|
||||
}
|
||||
|
||||
#define SIMPLE_NEAREST_FAST_PATH_PAD(op,s,d,func) \
|
||||
{ PIXMAN_OP_ ## op, \
|
||||
PIXMAN_ ## s, \
|
||||
(SCALED_NEAREST_FLAGS | \
|
||||
FAST_PATH_PAD_REPEAT | \
|
||||
FAST_PATH_X_UNIT_POSITIVE), \
|
||||
PIXMAN_null, 0, \
|
||||
PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
|
||||
fast_composite_scaled_nearest_ ## func ## _pad ## _ ## op, \
|
||||
}
|
||||
|
||||
#define SIMPLE_NEAREST_FAST_PATH_NONE(op,s,d,func) \
|
||||
{ PIXMAN_OP_ ## op, \
|
||||
PIXMAN_ ## s, \
|
||||
(SCALED_NEAREST_FLAGS | \
|
||||
FAST_PATH_NONE_REPEAT | \
|
||||
FAST_PATH_X_UNIT_POSITIVE), \
|
||||
PIXMAN_null, 0, \
|
||||
PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
|
||||
fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \
|
||||
}
|
||||
|
||||
#define SIMPLE_NEAREST_FAST_PATH_COVER(op,s,d,func) \
|
||||
{ PIXMAN_OP_ ## op, \
|
||||
PIXMAN_ ## s, \
|
||||
SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP, \
|
||||
PIXMAN_null, 0, \
|
||||
PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \
|
||||
fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op, \
|
||||
}
|
||||
|
||||
/* Prefer the use of 'cover' variant, because it is faster */
|
||||
#define SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \
|
||||
SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func), \
|
||||
SIMPLE_NEAREST_FAST_PATH_NORMAL (op,s,d,func)
|
||||
|
||||
#endif
|
315
programs/develop/libraries/pixman/pixman-general.c
Normal file
315
programs/develop/libraries/pixman/pixman-general.c
Normal file
@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* 2008 Aaron Plattner, NVIDIA Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-combine32.h"
|
||||
#include "pixman-private.h"
|
||||
|
||||
#define SCANLINE_BUFFER_LENGTH 8192
|
||||
|
||||
static void
|
||||
general_composite_rect (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_image_t * src,
|
||||
pixman_image_t * mask,
|
||||
pixman_image_t * dest,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t mask_x,
|
||||
int32_t mask_y,
|
||||
int32_t dest_x,
|
||||
int32_t dest_y,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
|
||||
uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
|
||||
uint8_t *src_buffer, *mask_buffer, *dest_buffer;
|
||||
fetch_scanline_t fetch_src = NULL, fetch_mask = NULL, fetch_dest = NULL;
|
||||
pixman_combine_32_func_t compose;
|
||||
store_scanline_t store;
|
||||
source_image_class_t src_class, mask_class;
|
||||
pixman_bool_t component_alpha;
|
||||
uint32_t *bits;
|
||||
int32_t stride;
|
||||
int narrow, Bpp;
|
||||
int i;
|
||||
|
||||
narrow =
|
||||
(src->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(dest->common.flags & FAST_PATH_NARROW_FORMAT);
|
||||
Bpp = narrow ? 4 : 8;
|
||||
|
||||
if (width * Bpp > SCANLINE_BUFFER_LENGTH)
|
||||
{
|
||||
scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
|
||||
|
||||
if (!scanline_buffer)
|
||||
return;
|
||||
}
|
||||
|
||||
src_buffer = scanline_buffer;
|
||||
mask_buffer = src_buffer + width * Bpp;
|
||||
dest_buffer = mask_buffer + width * Bpp;
|
||||
|
||||
src_class = _pixman_image_classify (src,
|
||||
src_x, src_y,
|
||||
width, height);
|
||||
|
||||
mask_class = SOURCE_IMAGE_CLASS_UNKNOWN;
|
||||
|
||||
if (mask)
|
||||
{
|
||||
mask_class = _pixman_image_classify (mask,
|
||||
src_x, src_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
if (op == PIXMAN_OP_CLEAR)
|
||||
fetch_src = NULL;
|
||||
else if (narrow)
|
||||
fetch_src = _pixman_image_get_scanline_32;
|
||||
else
|
||||
fetch_src = _pixman_image_get_scanline_64;
|
||||
|
||||
if (!mask || op == PIXMAN_OP_CLEAR)
|
||||
fetch_mask = NULL;
|
||||
else if (narrow)
|
||||
fetch_mask = _pixman_image_get_scanline_32;
|
||||
else
|
||||
fetch_mask = _pixman_image_get_scanline_64;
|
||||
|
||||
if (op == PIXMAN_OP_CLEAR || op == PIXMAN_OP_SRC)
|
||||
fetch_dest = NULL;
|
||||
else if (narrow)
|
||||
fetch_dest = _pixman_image_get_scanline_32;
|
||||
else
|
||||
fetch_dest = _pixman_image_get_scanline_64;
|
||||
|
||||
if (narrow)
|
||||
store = _pixman_image_store_scanline_32;
|
||||
else
|
||||
store = _pixman_image_store_scanline_64;
|
||||
|
||||
/* Skip the store step and composite directly into the
|
||||
* destination if the output format of the compose func matches
|
||||
* the destination format.
|
||||
*
|
||||
* If the destination format is a8r8g8b8 then we can always do
|
||||
* this. If it is x8r8g8b8, then we can only do it if the
|
||||
* operator doesn't make use of destination alpha.
|
||||
*/
|
||||
if ((dest->bits.format == PIXMAN_a8r8g8b8) ||
|
||||
(dest->bits.format == PIXMAN_x8r8g8b8 &&
|
||||
(op == PIXMAN_OP_OVER ||
|
||||
op == PIXMAN_OP_ADD ||
|
||||
op == PIXMAN_OP_SRC ||
|
||||
op == PIXMAN_OP_CLEAR ||
|
||||
op == PIXMAN_OP_IN_REVERSE ||
|
||||
op == PIXMAN_OP_OUT_REVERSE ||
|
||||
op == PIXMAN_OP_DST)))
|
||||
{
|
||||
if (narrow &&
|
||||
!dest->common.alpha_map &&
|
||||
!dest->bits.write_func)
|
||||
{
|
||||
store = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!store)
|
||||
{
|
||||
bits = dest->bits.bits;
|
||||
stride = dest->bits.rowstride;
|
||||
}
|
||||
else
|
||||
{
|
||||
bits = NULL;
|
||||
stride = 0;
|
||||
}
|
||||
|
||||
component_alpha =
|
||||
fetch_src &&
|
||||
fetch_mask &&
|
||||
mask &&
|
||||
mask->common.type == BITS &&
|
||||
mask->common.component_alpha &&
|
||||
PIXMAN_FORMAT_RGB (mask->bits.format);
|
||||
|
||||
if (narrow)
|
||||
{
|
||||
if (component_alpha)
|
||||
compose = _pixman_implementation_combine_32_ca;
|
||||
else
|
||||
compose = _pixman_implementation_combine_32;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (component_alpha)
|
||||
compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
|
||||
else
|
||||
compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64;
|
||||
}
|
||||
|
||||
if (!compose)
|
||||
return;
|
||||
|
||||
if (!fetch_mask)
|
||||
mask_buffer = NULL;
|
||||
|
||||
for (i = 0; i < height; ++i)
|
||||
{
|
||||
/* fill first half of scanline with source */
|
||||
if (fetch_src)
|
||||
{
|
||||
if (fetch_mask)
|
||||
{
|
||||
/* fetch mask before source so that fetching of
|
||||
source can be optimized */
|
||||
fetch_mask (mask, mask_x, mask_y + i,
|
||||
width, (void *)mask_buffer, 0);
|
||||
|
||||
if (mask_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
|
||||
fetch_mask = NULL;
|
||||
}
|
||||
|
||||
if (src_class == SOURCE_IMAGE_CLASS_HORIZONTAL)
|
||||
{
|
||||
fetch_src (src, src_x, src_y + i,
|
||||
width, (void *)src_buffer, 0);
|
||||
fetch_src = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch_src (src, src_x, src_y + i,
|
||||
width, (void *)src_buffer, (void *)mask_buffer);
|
||||
}
|
||||
}
|
||||
else if (fetch_mask)
|
||||
{
|
||||
fetch_mask (mask, mask_x, mask_y + i,
|
||||
width, (void *)mask_buffer, 0);
|
||||
}
|
||||
|
||||
if (store)
|
||||
{
|
||||
/* fill dest into second half of scanline */
|
||||
if (fetch_dest)
|
||||
{
|
||||
fetch_dest (dest, dest_x, dest_y + i,
|
||||
width, (void *)dest_buffer, 0);
|
||||
}
|
||||
|
||||
/* blend */
|
||||
compose (imp->toplevel, op,
|
||||
(void *)dest_buffer,
|
||||
(void *)src_buffer,
|
||||
(void *)mask_buffer,
|
||||
width);
|
||||
|
||||
/* write back */
|
||||
store (&(dest->bits), dest_x, dest_y + i, width,
|
||||
(void *)dest_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* blend */
|
||||
compose (imp->toplevel, op,
|
||||
bits + (dest_y + i) * stride + dest_x,
|
||||
(void *)src_buffer, (void *)mask_buffer, width);
|
||||
}
|
||||
}
|
||||
|
||||
if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
|
||||
free (scanline_buffer);
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t general_fast_path[] =
|
||||
{
|
||||
{ PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
|
||||
{ PIXMAN_OP_NONE }
|
||||
};
|
||||
|
||||
static pixman_bool_t
|
||||
general_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
/* We can't blit unless we have sse2 or mmx */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
general_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t xor)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_general (void)
|
||||
{
|
||||
pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
|
||||
|
||||
_pixman_setup_combiner_functions_32 (imp);
|
||||
_pixman_setup_combiner_functions_64 (imp);
|
||||
|
||||
imp->blt = general_blt;
|
||||
imp->fill = general_fill;
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
254
programs/develop/libraries/pixman/pixman-gradient-walker.c
Normal file
254
programs/develop/libraries/pixman/pixman-gradient-walker.c
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
|
||||
gradient_t * gradient,
|
||||
unsigned int spread)
|
||||
{
|
||||
walker->num_stops = gradient->n_stops;
|
||||
walker->stops = gradient->stops;
|
||||
walker->left_x = 0;
|
||||
walker->right_x = 0x10000;
|
||||
walker->stepper = 0;
|
||||
walker->left_ag = 0;
|
||||
walker->left_rb = 0;
|
||||
walker->right_ag = 0;
|
||||
walker->right_rb = 0;
|
||||
walker->spread = spread;
|
||||
|
||||
walker->need_reset = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t pos)
|
||||
{
|
||||
int32_t x, left_x, right_x;
|
||||
pixman_color_t *left_c, *right_c;
|
||||
int n, count = walker->num_stops;
|
||||
pixman_gradient_stop_t * stops = walker->stops;
|
||||
|
||||
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
|
||||
|
||||
switch (walker->spread)
|
||||
{
|
||||
case PIXMAN_REPEAT_NORMAL:
|
||||
x = (int32_t)pos & 0xFFFF;
|
||||
for (n = 0; n < count; n++)
|
||||
if (x < stops[n].x)
|
||||
break;
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = stops[count - 1].x - 0x10000;
|
||||
left_c = &stops[count - 1].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
}
|
||||
|
||||
if (n == count)
|
||||
{
|
||||
right_x = stops[0].x + 0x10000;
|
||||
right_c = &stops[0].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
for (n = 0; n < count; n++)
|
||||
if (pos < stops[n].x)
|
||||
break;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = INT32_MIN;
|
||||
left_c = &stops[0].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
}
|
||||
|
||||
if (n == count)
|
||||
{
|
||||
right_x = INT32_MAX;
|
||||
right_c = &stops[n - 1].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
x = (int32_t)pos & 0xFFFF;
|
||||
if ((int32_t)pos & 0x10000)
|
||||
x = 0x10000 - x;
|
||||
for (n = 0; n < count; n++)
|
||||
if (x < stops[n].x)
|
||||
break;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = -stops[0].x;
|
||||
left_c = &stops[0].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
}
|
||||
|
||||
if (n == count)
|
||||
{
|
||||
right_x = 0x20000 - stops[n - 1].x;
|
||||
right_c = &stops[n - 1].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
|
||||
if ((int32_t)pos & 0x10000)
|
||||
{
|
||||
pixman_color_t *tmp_c;
|
||||
int32_t tmp_x;
|
||||
|
||||
tmp_x = 0x10000 - right_x;
|
||||
right_x = 0x10000 - left_x;
|
||||
left_x = tmp_x;
|
||||
|
||||
tmp_c = right_c;
|
||||
right_c = left_c;
|
||||
left_c = tmp_c;
|
||||
|
||||
x = 0x10000 - x;
|
||||
}
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
break;
|
||||
|
||||
default: /* REPEAT_NONE */
|
||||
for (n = 0; n < count; n++)
|
||||
if (pos < stops[n].x)
|
||||
break;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = INT32_MIN;
|
||||
right_x = stops[0].x;
|
||||
left_c = right_c = (pixman_color_t*) &transparent_black;
|
||||
}
|
||||
else if (n == count)
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
right_x = INT32_MAX;
|
||||
left_c = right_c = (pixman_color_t*) &transparent_black;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
right_x = stops[n].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
}
|
||||
|
||||
walker->left_x = left_x;
|
||||
walker->right_x = right_x;
|
||||
walker->left_ag = ((left_c->alpha >> 8) << 16) | (left_c->green >> 8);
|
||||
walker->left_rb = ((left_c->red & 0xff00) << 8) | (left_c->blue >> 8);
|
||||
walker->right_ag = ((right_c->alpha >> 8) << 16) | (right_c->green >> 8);
|
||||
walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
|
||||
|
||||
if (walker->left_x == walker->right_x ||
|
||||
( walker->left_ag == walker->right_ag &&
|
||||
walker->left_rb == walker->right_rb ) )
|
||||
{
|
||||
walker->stepper = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t width = right_x - left_x;
|
||||
walker->stepper = ((1 << 24) + width / 2) / width;
|
||||
}
|
||||
|
||||
walker->need_reset = FALSE;
|
||||
}
|
||||
|
||||
#define PIXMAN_GRADIENT_WALKER_NEED_RESET(w, x) \
|
||||
( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
|
||||
|
||||
|
||||
/* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
|
||||
uint32_t
|
||||
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t x)
|
||||
{
|
||||
int dist, idist;
|
||||
uint32_t t1, t2, a, color;
|
||||
|
||||
if (PIXMAN_GRADIENT_WALKER_NEED_RESET (walker, x))
|
||||
_pixman_gradient_walker_reset (walker, x);
|
||||
|
||||
dist = ((int)(x - walker->left_x) * walker->stepper) >> 16;
|
||||
idist = 256 - dist;
|
||||
|
||||
/* combined INTERPOLATE and premultiply */
|
||||
t1 = walker->left_rb * idist + walker->right_rb * dist;
|
||||
t1 = (t1 >> 8) & 0xff00ff;
|
||||
|
||||
t2 = walker->left_ag * idist + walker->right_ag * dist;
|
||||
t2 &= 0xff00ff00;
|
||||
|
||||
color = t2 & 0xff000000;
|
||||
a = t2 >> 24;
|
||||
|
||||
t1 = t1 * a + 0x800080;
|
||||
t1 = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
|
||||
|
||||
t2 = (t2 >> 8) * a + 0x800080;
|
||||
t2 = (t2 + ((t2 >> 8) & 0xff00ff));
|
||||
|
||||
return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
|
||||
}
|
||||
|
846
programs/develop/libraries/pixman/pixman-image.c
Normal file
846
programs/develop/libraries/pixman/pixman-image.c
Normal file
@ -0,0 +1,846 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-combine32.h"
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_init_gradient (gradient_t * gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
return_val_if_fail (n_stops > 0, FALSE);
|
||||
|
||||
gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
|
||||
if (!gradient->stops)
|
||||
return FALSE;
|
||||
|
||||
memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
|
||||
|
||||
gradient->n_stops = n_stops;
|
||||
|
||||
gradient->stop_range = 0xffff;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* By default, just evaluate the image at 32bpp and expand. Individual image
|
||||
* types can plug in a better scanline getter if they want to. For example
|
||||
* we could produce smoother gradients by evaluating them at higher color
|
||||
* depth, but that's a project for the future.
|
||||
*/
|
||||
void
|
||||
_pixman_image_get_scanline_generic_64 (pixman_image_t * image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t * mask)
|
||||
{
|
||||
uint32_t *mask8 = NULL;
|
||||
|
||||
/* Contract the mask image, if one exists, so that the 32-bit fetch
|
||||
* function can use it.
|
||||
*/
|
||||
if (mask)
|
||||
{
|
||||
mask8 = pixman_malloc_ab (width, sizeof(uint32_t));
|
||||
if (!mask8)
|
||||
return;
|
||||
|
||||
pixman_contract (mask8, (uint64_t *)mask, width);
|
||||
}
|
||||
|
||||
/* Fetch the source image into the first half of buffer. */
|
||||
_pixman_image_get_scanline_32 (image, x, y, width, (uint32_t*)buffer, mask8);
|
||||
|
||||
/* Expand from 32bpp to 64bpp in place. */
|
||||
pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, width);
|
||||
|
||||
free (mask8);
|
||||
}
|
||||
|
||||
pixman_image_t *
|
||||
_pixman_image_allocate (void)
|
||||
{
|
||||
pixman_image_t *image = malloc (sizeof (pixman_image_t));
|
||||
|
||||
if (image)
|
||||
{
|
||||
image_common_t *common = &image->common;
|
||||
|
||||
pixman_region32_init (&common->clip_region);
|
||||
|
||||
common->alpha_count = 0;
|
||||
common->have_clip_region = FALSE;
|
||||
common->clip_sources = FALSE;
|
||||
common->transform = NULL;
|
||||
common->repeat = PIXMAN_REPEAT_NONE;
|
||||
common->filter = PIXMAN_FILTER_NEAREST;
|
||||
common->filter_params = NULL;
|
||||
common->n_filter_params = 0;
|
||||
common->alpha_map = NULL;
|
||||
common->component_alpha = FALSE;
|
||||
common->ref_count = 1;
|
||||
common->classify = NULL;
|
||||
common->client_clip = FALSE;
|
||||
common->destroy_func = NULL;
|
||||
common->destroy_data = NULL;
|
||||
common->dirty = TRUE;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
source_image_class_t
|
||||
_pixman_image_classify (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (image->common.classify)
|
||||
return image->common.classify (image, x, y, width, height);
|
||||
else
|
||||
return SOURCE_IMAGE_CLASS_UNKNOWN;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_get_scanline_32 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask)
|
||||
{
|
||||
image->common.get_scanline_32 (image, x, y, width, buffer, mask);
|
||||
}
|
||||
|
||||
/* Even thought the type of buffer is uint32_t *, the function actually expects
|
||||
* a uint64_t *buffer.
|
||||
*/
|
||||
void
|
||||
_pixman_image_get_scanline_64 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *unused)
|
||||
{
|
||||
image->common.get_scanline_64 (image, x, y, width, buffer, unused);
|
||||
}
|
||||
|
||||
static void
|
||||
image_property_changed (pixman_image_t *image)
|
||||
{
|
||||
image->common.dirty = TRUE;
|
||||
}
|
||||
|
||||
/* Ref Counting */
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_ref (pixman_image_t *image)
|
||||
{
|
||||
image->common.ref_count++;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/* returns TRUE when the image is freed */
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_unref (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
common->ref_count--;
|
||||
|
||||
if (common->ref_count == 0)
|
||||
{
|
||||
if (image->common.destroy_func)
|
||||
image->common.destroy_func (image, image->common.destroy_data);
|
||||
|
||||
pixman_region32_fini (&common->clip_region);
|
||||
|
||||
if (common->transform)
|
||||
free (common->transform);
|
||||
|
||||
if (common->filter_params)
|
||||
free (common->filter_params);
|
||||
|
||||
if (common->alpha_map)
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
|
||||
if (image->type == LINEAR ||
|
||||
image->type == RADIAL ||
|
||||
image->type == CONICAL)
|
||||
{
|
||||
if (image->gradient.stops)
|
||||
free (image->gradient.stops);
|
||||
}
|
||||
|
||||
if (image->type == BITS && image->bits.free_me)
|
||||
free (image->bits.free_me);
|
||||
|
||||
free (image);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_destroy_function (pixman_image_t * image,
|
||||
pixman_image_destroy_func_t func,
|
||||
void * data)
|
||||
{
|
||||
image->common.destroy_func = func;
|
||||
image->common.destroy_data = data;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void *
|
||||
pixman_image_get_destroy_data (pixman_image_t *image)
|
||||
{
|
||||
return image->common.destroy_data;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_reset_clip_region (pixman_image_t *image)
|
||||
{
|
||||
image->common.have_clip_region = FALSE;
|
||||
}
|
||||
|
||||
static pixman_bool_t out_of_bounds_workaround = TRUE;
|
||||
|
||||
/* Old X servers rely on out-of-bounds accesses when they are asked
|
||||
* to composite with a window as the source. They create a pixman image
|
||||
* pointing to some bogus position in memory, but then they set a clip
|
||||
* region to the position where the actual bits are.
|
||||
*
|
||||
* Due to a bug in old versions of pixman, where it would not clip
|
||||
* against the image bounds when a clip region was set, this would
|
||||
* actually work. So by default we allow certain out-of-bound access
|
||||
* to happen unless explicitly disabled.
|
||||
*
|
||||
* Fixed X servers should call this function to disable the workaround.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_disable_out_of_bounds_workaround (void)
|
||||
{
|
||||
out_of_bounds_workaround = FALSE;
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
source_image_needs_out_of_bounds_workaround (bits_image_t *image)
|
||||
{
|
||||
if (image->common.clip_sources &&
|
||||
image->common.repeat == PIXMAN_REPEAT_NONE &&
|
||||
image->common.have_clip_region &&
|
||||
out_of_bounds_workaround)
|
||||
{
|
||||
if (!image->common.client_clip)
|
||||
{
|
||||
/* There is no client clip, so if the clip region extends beyond the
|
||||
* drawable geometry, it must be because the X server generated the
|
||||
* bogus clip region.
|
||||
*/
|
||||
const pixman_box32_t *extents =
|
||||
pixman_region32_extents (&image->common.clip_region);
|
||||
|
||||
if (extents->x1 >= 0 && extents->x2 <= image->width &&
|
||||
extents->y1 >= 0 && extents->y2 <= image->height)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
compute_image_info (pixman_image_t *image)
|
||||
{
|
||||
pixman_format_code_t code;
|
||||
uint32_t flags = 0;
|
||||
|
||||
/* Transform */
|
||||
if (!image->common.transform)
|
||||
{
|
||||
flags |= (FAST_PATH_ID_TRANSFORM |
|
||||
FAST_PATH_X_UNIT_POSITIVE |
|
||||
FAST_PATH_Y_UNIT_ZERO |
|
||||
FAST_PATH_AFFINE_TRANSFORM);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= FAST_PATH_HAS_TRANSFORM;
|
||||
|
||||
if (image->common.transform->matrix[2][0] == 0 &&
|
||||
image->common.transform->matrix[2][1] == 0 &&
|
||||
image->common.transform->matrix[2][2] == pixman_fixed_1)
|
||||
{
|
||||
flags |= FAST_PATH_AFFINE_TRANSFORM;
|
||||
|
||||
if (image->common.transform->matrix[0][1] == 0 &&
|
||||
image->common.transform->matrix[1][0] == 0)
|
||||
{
|
||||
flags |= FAST_PATH_SCALE_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
if (image->common.transform->matrix[0][0] > 0)
|
||||
flags |= FAST_PATH_X_UNIT_POSITIVE;
|
||||
|
||||
if (image->common.transform->matrix[1][0] == 0)
|
||||
flags |= FAST_PATH_Y_UNIT_ZERO;
|
||||
}
|
||||
|
||||
/* Filter */
|
||||
switch (image->common.filter)
|
||||
{
|
||||
case PIXMAN_FILTER_NEAREST:
|
||||
case PIXMAN_FILTER_FAST:
|
||||
flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_BILINEAR:
|
||||
case PIXMAN_FILTER_GOOD:
|
||||
case PIXMAN_FILTER_BEST:
|
||||
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_CONVOLUTION:
|
||||
break;
|
||||
|
||||
default:
|
||||
flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Repeat mode */
|
||||
switch (image->common.repeat)
|
||||
{
|
||||
case PIXMAN_REPEAT_NONE:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
flags |=
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Component alpha */
|
||||
if (image->common.component_alpha)
|
||||
flags |= FAST_PATH_COMPONENT_ALPHA;
|
||||
else
|
||||
flags |= FAST_PATH_UNIFIED_ALPHA;
|
||||
|
||||
flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
|
||||
|
||||
/* Type specific checks */
|
||||
switch (image->type)
|
||||
{
|
||||
case SOLID:
|
||||
code = PIXMAN_solid;
|
||||
|
||||
if (image->solid.color.alpha == 0xffff)
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
break;
|
||||
|
||||
case BITS:
|
||||
if (image->bits.width == 1 &&
|
||||
image->bits.height == 1 &&
|
||||
image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
code = PIXMAN_solid;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = image->bits.format;
|
||||
}
|
||||
|
||||
if (!PIXMAN_FORMAT_A (image->bits.format) &&
|
||||
PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY &&
|
||||
PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
|
||||
{
|
||||
flags |= FAST_PATH_SAMPLES_OPAQUE;
|
||||
|
||||
if (image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
}
|
||||
|
||||
if (source_image_needs_out_of_bounds_workaround (&image->bits))
|
||||
flags |= FAST_PATH_NEEDS_WORKAROUND;
|
||||
|
||||
if (image->bits.read_func || image->bits.write_func)
|
||||
flags &= ~FAST_PATH_NO_ACCESSORS;
|
||||
|
||||
if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
|
||||
flags &= ~FAST_PATH_NARROW_FORMAT;
|
||||
break;
|
||||
|
||||
case RADIAL:
|
||||
code = PIXMAN_unknown;
|
||||
|
||||
/*
|
||||
* As explained in pixman-radial-gradient.c, every point of
|
||||
* the plane has a valid associated radius (and thus will be
|
||||
* colored) if and only if a is negative (i.e. one of the two
|
||||
* circles contains the other one).
|
||||
*/
|
||||
|
||||
if (image->radial.a >= 0)
|
||||
break;
|
||||
|
||||
/* Fall through */
|
||||
|
||||
case LINEAR:
|
||||
code = PIXMAN_unknown;
|
||||
|
||||
if (image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
int i;
|
||||
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
for (i = 0; i < image->gradient.n_stops; ++i)
|
||||
{
|
||||
if (image->gradient.stops[i].color.alpha != 0xffff)
|
||||
{
|
||||
flags &= ~FAST_PATH_IS_OPAQUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
code = PIXMAN_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Alpha map */
|
||||
if (!image->common.alpha_map)
|
||||
{
|
||||
flags |= FAST_PATH_NO_ALPHA_MAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
|
||||
flags &= ~FAST_PATH_NARROW_FORMAT;
|
||||
}
|
||||
|
||||
/* Both alpha maps and convolution filters can introduce
|
||||
* non-opaqueness in otherwise opaque images. Also
|
||||
* an image with component alpha turned on is only opaque
|
||||
* if all channels are opaque, so we simply turn it off
|
||||
* unconditionally for those images.
|
||||
*/
|
||||
if (image->common.alpha_map ||
|
||||
image->common.filter == PIXMAN_FILTER_CONVOLUTION ||
|
||||
image->common.component_alpha)
|
||||
{
|
||||
flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
|
||||
}
|
||||
|
||||
image->common.flags = flags;
|
||||
image->common.extended_format_code = code;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_validate (pixman_image_t *image)
|
||||
{
|
||||
if (image->common.dirty)
|
||||
{
|
||||
compute_image_info (image);
|
||||
|
||||
/* It is important that property_changed is
|
||||
* called *after* compute_image_info() because
|
||||
* property_changed() can make use of the flags
|
||||
* to set up accessors etc.
|
||||
*/
|
||||
image->common.property_changed (image);
|
||||
|
||||
image->common.dirty = FALSE;
|
||||
}
|
||||
|
||||
if (image->common.alpha_map)
|
||||
_pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_clip_region32 (pixman_image_t * image,
|
||||
pixman_region32_t *region)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (region)
|
||||
{
|
||||
if ((result = pixman_region32_copy (&common->clip_region, region)))
|
||||
image->common.have_clip_region = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pixman_image_reset_clip_region (image);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_clip_region (pixman_image_t * image,
|
||||
pixman_region16_t *region)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (region)
|
||||
{
|
||||
if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
|
||||
image->common.have_clip_region = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pixman_image_reset_clip_region (image);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_has_client_clip (pixman_image_t *image,
|
||||
pixman_bool_t client_clip)
|
||||
{
|
||||
image->common.client_clip = client_clip;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_transform (pixman_image_t * image,
|
||||
const pixman_transform_t *transform)
|
||||
{
|
||||
static const pixman_transform_t id =
|
||||
{
|
||||
{ { pixman_fixed_1, 0, 0 },
|
||||
{ 0, pixman_fixed_1, 0 },
|
||||
{ 0, 0, pixman_fixed_1 } }
|
||||
};
|
||||
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (common->transform == transform)
|
||||
return TRUE;
|
||||
|
||||
if (memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
|
||||
{
|
||||
free (common->transform);
|
||||
common->transform = NULL;
|
||||
result = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (common->transform == NULL)
|
||||
common->transform = malloc (sizeof (pixman_transform_t));
|
||||
|
||||
if (common->transform == NULL)
|
||||
{
|
||||
result = FALSE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy (common->transform, transform, sizeof(pixman_transform_t));
|
||||
|
||||
result = TRUE;
|
||||
|
||||
out:
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
image->common.repeat = repeat;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_filter (pixman_image_t * image,
|
||||
pixman_filter_t filter,
|
||||
const pixman_fixed_t *params,
|
||||
int n_params)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_fixed_t *new_params;
|
||||
|
||||
if (params == common->filter_params && filter == common->filter)
|
||||
return TRUE;
|
||||
|
||||
new_params = NULL;
|
||||
if (params)
|
||||
{
|
||||
new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
|
||||
if (!new_params)
|
||||
return FALSE;
|
||||
|
||||
memcpy (new_params,
|
||||
params, n_params * sizeof (pixman_fixed_t));
|
||||
}
|
||||
|
||||
common->filter = filter;
|
||||
|
||||
if (common->filter_params)
|
||||
free (common->filter_params);
|
||||
|
||||
common->filter_params = new_params;
|
||||
common->n_filter_params = n_params;
|
||||
|
||||
image_property_changed (image);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_source_clipping (pixman_image_t *image,
|
||||
pixman_bool_t clip_sources)
|
||||
{
|
||||
image->common.clip_sources = clip_sources;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
/* Unlike all the other property setters, this function does not
|
||||
* copy the content of indexed. Doing this copying is simply
|
||||
* way, way too expensive.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_indexed (pixman_image_t * image,
|
||||
const pixman_indexed_t *indexed)
|
||||
{
|
||||
bits_image_t *bits = (bits_image_t *)image;
|
||||
|
||||
bits->indexed = indexed;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_alpha_map (pixman_image_t *image,
|
||||
pixman_image_t *alpha_map,
|
||||
int16_t x,
|
||||
int16_t y)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
return_if_fail (!alpha_map || alpha_map->type == BITS);
|
||||
|
||||
if (alpha_map && common->alpha_count > 0)
|
||||
{
|
||||
/* If this image is being used as an alpha map itself,
|
||||
* then you can't give it an alpha map of its own.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (alpha_map && alpha_map->common.alpha_map)
|
||||
{
|
||||
/* If the image has an alpha map of its own,
|
||||
* then it can't be used as an alpha map itself
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (common->alpha_map != (bits_image_t *)alpha_map)
|
||||
{
|
||||
if (common->alpha_map)
|
||||
{
|
||||
common->alpha_map->common.alpha_count--;
|
||||
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
}
|
||||
|
||||
if (alpha_map)
|
||||
{
|
||||
common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
|
||||
|
||||
common->alpha_map->common.alpha_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
common->alpha_map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
common->alpha_origin_x = x;
|
||||
common->alpha_origin_y = y;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_component_alpha (pixman_image_t *image,
|
||||
pixman_bool_t component_alpha)
|
||||
{
|
||||
image->common.component_alpha = component_alpha;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_get_component_alpha (pixman_image_t *image)
|
||||
{
|
||||
return image->common.component_alpha;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_accessors (pixman_image_t * image,
|
||||
pixman_read_memory_func_t read_func,
|
||||
pixman_write_memory_func_t write_func)
|
||||
{
|
||||
return_if_fail (image != NULL);
|
||||
|
||||
if (image->type == BITS)
|
||||
{
|
||||
image->bits.read_func = read_func;
|
||||
image->bits.write_func = write_func;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT uint32_t *
|
||||
pixman_image_get_data (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.bits;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_width (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_height (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_stride (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.rowstride * (int) sizeof (uint32_t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_depth (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return PIXMAN_FORMAT_DEPTH (image->bits.format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_format_code_t
|
||||
pixman_image_get_format (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.format;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
_pixman_image_get_solid (pixman_image_t * image,
|
||||
pixman_format_code_t format)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
_pixman_image_get_scanline_32 (image, 0, 0, 1, &result, NULL);
|
||||
|
||||
/* If necessary, convert RGB <--> BGR. */
|
||||
if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
|
||||
{
|
||||
result = (((result & 0xff000000) >> 0) |
|
||||
((result & 0x00ff0000) >> 16) |
|
||||
((result & 0x0000ff00) >> 0) |
|
||||
((result & 0x000000ff) << 16));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
227
programs/develop/libraries/pixman/pixman-implementation.c
Normal file
227
programs/develop/libraries/pixman/pixman-implementation.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static void
|
||||
delegate_combine_32 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_32 (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_combine_64 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_64 (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_combine_32_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_32_ca (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_combine_64_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_64_ca (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
delegate_blt (pixman_implementation_t * imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return _pixman_implementation_blt (
|
||||
imp->delegate, src_bits, dst_bits, src_stride, dst_stride,
|
||||
src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
delegate_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t xor)
|
||||
{
|
||||
return _pixman_implementation_fill (
|
||||
imp->delegate, bits, stride, bpp, x, y, width, height, xor);
|
||||
}
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create (pixman_implementation_t *delegate,
|
||||
const pixman_fast_path_t *fast_paths)
|
||||
{
|
||||
pixman_implementation_t *imp = malloc (sizeof (pixman_implementation_t));
|
||||
pixman_implementation_t *d;
|
||||
int i;
|
||||
|
||||
if (!imp)
|
||||
return NULL;
|
||||
|
||||
assert (fast_paths);
|
||||
|
||||
/* Make sure the whole delegate chain has the right toplevel */
|
||||
imp->delegate = delegate;
|
||||
for (d = imp; d != NULL; d = d->delegate)
|
||||
d->toplevel = imp;
|
||||
|
||||
/* Fill out function pointers with ones that just delegate
|
||||
*/
|
||||
imp->blt = delegate_blt;
|
||||
imp->fill = delegate_fill;
|
||||
|
||||
for (i = 0; i < PIXMAN_N_OPERATORS; ++i)
|
||||
{
|
||||
imp->combine_32[i] = delegate_combine_32;
|
||||
imp->combine_64[i] = delegate_combine_64;
|
||||
imp->combine_32_ca[i] = delegate_combine_32_ca;
|
||||
imp->combine_64_ca[i] = delegate_combine_64_ca;
|
||||
}
|
||||
|
||||
imp->fast_paths = fast_paths;
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_32 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
(*imp->combine_32[op]) (imp, op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_64 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
(*imp->combine_64[op]) (imp, op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_32_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
(*imp->combine_32_ca[op]) (imp, op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_64_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
(*imp->combine_64_ca[op]) (imp, op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_blt (pixman_implementation_t * imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
|
||||
src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t xor)
|
||||
{
|
||||
return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor);
|
||||
}
|
||||
|
262
programs/develop/libraries/pixman/pixman-linear-gradient.c
Normal file
262
programs/develop/libraries/pixman/pixman-linear-gradient.c
Normal file
@ -0,0 +1,262 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static source_image_class_t
|
||||
linear_gradient_classify (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
source_image_t *source = (source_image_t *)image;
|
||||
linear_gradient_t *linear = (linear_gradient_t *)image;
|
||||
pixman_vector_t v;
|
||||
pixman_fixed_32_32_t l;
|
||||
pixman_fixed_48_16_t dx, dy;
|
||||
double inc;
|
||||
source_image_class_t class;
|
||||
|
||||
class = SOURCE_IMAGE_CLASS_UNKNOWN;
|
||||
|
||||
if (source->common.transform)
|
||||
{
|
||||
/* projective transformation */
|
||||
if (source->common.transform->matrix[2][0] != 0 ||
|
||||
source->common.transform->matrix[2][1] != 0 ||
|
||||
source->common.transform->matrix[2][2] == 0)
|
||||
{
|
||||
return class;
|
||||
}
|
||||
|
||||
v.vector[0] = source->common.transform->matrix[0][1];
|
||||
v.vector[1] = source->common.transform->matrix[1][1];
|
||||
v.vector[2] = source->common.transform->matrix[2][2];
|
||||
}
|
||||
else
|
||||
{
|
||||
v.vector[0] = 0;
|
||||
v.vector[1] = pixman_fixed_1;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
}
|
||||
|
||||
dx = linear->p2.x - linear->p1.x;
|
||||
dy = linear->p2.y - linear->p1.y;
|
||||
|
||||
l = dx * dx + dy * dy;
|
||||
|
||||
if (l == 0)
|
||||
return class;
|
||||
|
||||
/*
|
||||
* compute how much the input of the gradient walked changes
|
||||
* when moving vertically through the whole image
|
||||
*/
|
||||
inc = height * (double) pixman_fixed_1 * pixman_fixed_1 *
|
||||
(dx * v.vector[0] + dy * v.vector[1]) /
|
||||
(v.vector[2] * (double) l);
|
||||
|
||||
/* check that casting to integer would result in 0 */
|
||||
if (-1 < inc && inc < 1)
|
||||
class = SOURCE_IMAGE_CLASS_HORIZONTAL;
|
||||
|
||||
return class;
|
||||
}
|
||||
|
||||
static void
|
||||
linear_gradient_get_scanline_32 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask)
|
||||
{
|
||||
pixman_vector_t v, unit;
|
||||
pixman_fixed_32_32_t l;
|
||||
pixman_fixed_48_16_t dx, dy;
|
||||
gradient_t *gradient = (gradient_t *)image;
|
||||
source_image_t *source = (source_image_t *)image;
|
||||
linear_gradient_t *linear = (linear_gradient_t *)image;
|
||||
uint32_t *end = buffer + width;
|
||||
pixman_gradient_walker_t walker;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (source->common.transform)
|
||||
{
|
||||
if (!pixman_transform_point_3d (source->common.transform, &v))
|
||||
return;
|
||||
|
||||
unit.vector[0] = source->common.transform->matrix[0][0];
|
||||
unit.vector[1] = source->common.transform->matrix[1][0];
|
||||
unit.vector[2] = source->common.transform->matrix[2][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
unit.vector[0] = pixman_fixed_1;
|
||||
unit.vector[1] = 0;
|
||||
unit.vector[2] = 0;
|
||||
}
|
||||
|
||||
dx = linear->p2.x - linear->p1.x;
|
||||
dy = linear->p2.y - linear->p1.y;
|
||||
|
||||
l = dx * dx + dy * dy;
|
||||
|
||||
if (l == 0 || unit.vector[2] == 0)
|
||||
{
|
||||
/* affine transformation only */
|
||||
pixman_fixed_32_32_t t, next_inc;
|
||||
double inc;
|
||||
|
||||
if (l == 0 || v.vector[2] == 0)
|
||||
{
|
||||
t = 0;
|
||||
inc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double invden, v2;
|
||||
|
||||
invden = pixman_fixed_1 * (double) pixman_fixed_1 /
|
||||
(l * (double) v.vector[2]);
|
||||
v2 = v.vector[2] * (1. / pixman_fixed_1);
|
||||
t = ((dx * v.vector[0] + dy * v.vector[1]) -
|
||||
(dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
|
||||
inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden;
|
||||
}
|
||||
next_inc = 0;
|
||||
|
||||
if (((pixman_fixed_32_32_t )(inc * width)) == 0)
|
||||
{
|
||||
register uint32_t color;
|
||||
|
||||
color = _pixman_gradient_walker_pixel (&walker, t);
|
||||
while (buffer < end)
|
||||
*buffer++ = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
*buffer = _pixman_gradient_walker_pixel (&walker,
|
||||
t + next_inc);
|
||||
}
|
||||
i++;
|
||||
next_inc = inc * i;
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* projective transformation */
|
||||
double t;
|
||||
|
||||
t = 0;
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
if (v.vector[2] != 0)
|
||||
{
|
||||
double invden, v2;
|
||||
|
||||
invden = pixman_fixed_1 * (double) pixman_fixed_1 /
|
||||
(l * (double) v.vector[2]);
|
||||
v2 = v.vector[2] * (1. / pixman_fixed_1);
|
||||
t = ((dx * v.vector[0] + dy * v.vector[1]) -
|
||||
(dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
|
||||
}
|
||||
|
||||
*buffer = _pixman_gradient_walker_pixel (&walker, t);
|
||||
}
|
||||
|
||||
++buffer;
|
||||
|
||||
v.vector[0] += unit.vector[0];
|
||||
v.vector[1] += unit.vector[1];
|
||||
v.vector[2] += unit.vector[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
linear_gradient_property_changed (pixman_image_t *image)
|
||||
{
|
||||
image->common.get_scanline_32 = linear_gradient_get_scanline_32;
|
||||
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_linear_gradient (pixman_point_fixed_t * p1,
|
||||
pixman_point_fixed_t * p2,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
linear_gradient_t *linear;
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
linear = &image->linear;
|
||||
|
||||
if (!_pixman_init_gradient (&linear->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
linear->p1 = *p1;
|
||||
linear->p2 = *p2;
|
||||
|
||||
image->type = LINEAR;
|
||||
image->common.classify = linear_gradient_classify;
|
||||
image->common.property_changed = linear_gradient_property_changed;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
768
programs/develop/libraries/pixman/pixman-matrix.c
Normal file
768
programs/develop/libraries/pixman/pixman-matrix.c
Normal file
@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright © 2008 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting documentation, and
|
||||
* that the name of the copyright holders not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no representations
|
||||
* about the suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Matrix interfaces
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
#define F(x) pixman_int_to_fixed (x)
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_transform_init_identity (struct pixman_transform *matrix)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (matrix, '\0', sizeof (struct pixman_transform));
|
||||
for (i = 0; i < 3; i++)
|
||||
matrix->matrix[i][i] = F (1);
|
||||
}
|
||||
|
||||
typedef pixman_fixed_32_32_t pixman_fixed_34_30_t;
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_point_3d (const struct pixman_transform *transform,
|
||||
struct pixman_vector * vector)
|
||||
{
|
||||
struct pixman_vector result;
|
||||
pixman_fixed_32_32_t partial;
|
||||
pixman_fixed_48_16_t v;
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
v = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
|
||||
(pixman_fixed_48_16_t) vector->vector[i]);
|
||||
v += partial >> 16;
|
||||
}
|
||||
|
||||
if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
|
||||
return FALSE;
|
||||
|
||||
result.vector[j] = (pixman_fixed_t) v;
|
||||
}
|
||||
|
||||
*vector = result;
|
||||
|
||||
if (!result.vector[2])
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_point (const struct pixman_transform *transform,
|
||||
struct pixman_vector * vector)
|
||||
{
|
||||
pixman_fixed_32_32_t partial;
|
||||
pixman_fixed_34_30_t v[3];
|
||||
pixman_fixed_48_16_t quo;
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
v[j] = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
partial = ((pixman_fixed_32_32_t) transform->matrix[j][i] *
|
||||
(pixman_fixed_32_32_t) vector->vector[i]);
|
||||
v[j] += partial >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(v[2] >> 16))
|
||||
return FALSE;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
quo = v[j] / (v[2] >> 16);
|
||||
if (quo > pixman_max_fixed_48_16 || quo < pixman_min_fixed_48_16)
|
||||
return FALSE;
|
||||
vector->vector[j] = (pixman_fixed_t) quo;
|
||||
}
|
||||
|
||||
vector->vector[2] = pixman_fixed_1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_multiply (struct pixman_transform * dst,
|
||||
const struct pixman_transform *l,
|
||||
const struct pixman_transform *r)
|
||||
{
|
||||
struct pixman_transform d;
|
||||
int dx, dy;
|
||||
int o;
|
||||
|
||||
for (dy = 0; dy < 3; dy++)
|
||||
{
|
||||
for (dx = 0; dx < 3; dx++)
|
||||
{
|
||||
pixman_fixed_48_16_t v;
|
||||
pixman_fixed_32_32_t partial;
|
||||
|
||||
v = 0;
|
||||
for (o = 0; o < 3; o++)
|
||||
{
|
||||
partial =
|
||||
(pixman_fixed_32_32_t) l->matrix[dy][o] *
|
||||
(pixman_fixed_32_32_t) r->matrix[o][dx];
|
||||
|
||||
v += partial >> 16;
|
||||
}
|
||||
|
||||
if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
|
||||
return FALSE;
|
||||
|
||||
d.matrix[dy][dx] = (pixman_fixed_t) v;
|
||||
}
|
||||
}
|
||||
|
||||
*dst = d;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_transform_init_scale (struct pixman_transform *t,
|
||||
pixman_fixed_t sx,
|
||||
pixman_fixed_t sy)
|
||||
{
|
||||
memset (t, '\0', sizeof (struct pixman_transform));
|
||||
|
||||
t->matrix[0][0] = sx;
|
||||
t->matrix[1][1] = sy;
|
||||
t->matrix[2][2] = F (1);
|
||||
}
|
||||
|
||||
static pixman_fixed_t
|
||||
fixed_inverse (pixman_fixed_t x)
|
||||
{
|
||||
return (pixman_fixed_t) ((((pixman_fixed_48_16_t) F (1)) * F (1)) / x);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_scale (struct pixman_transform *forward,
|
||||
struct pixman_transform *reverse,
|
||||
pixman_fixed_t sx,
|
||||
pixman_fixed_t sy)
|
||||
{
|
||||
struct pixman_transform t;
|
||||
|
||||
if (sx == 0 || sy == 0)
|
||||
return FALSE;
|
||||
|
||||
if (forward)
|
||||
{
|
||||
pixman_transform_init_scale (&t, sx, sy);
|
||||
if (!pixman_transform_multiply (forward, &t, forward))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
pixman_transform_init_scale (&t, fixed_inverse (sx),
|
||||
fixed_inverse (sy));
|
||||
if (!pixman_transform_multiply (reverse, reverse, &t))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_transform_init_rotate (struct pixman_transform *t,
|
||||
pixman_fixed_t c,
|
||||
pixman_fixed_t s)
|
||||
{
|
||||
memset (t, '\0', sizeof (struct pixman_transform));
|
||||
|
||||
t->matrix[0][0] = c;
|
||||
t->matrix[0][1] = -s;
|
||||
t->matrix[1][0] = s;
|
||||
t->matrix[1][1] = c;
|
||||
t->matrix[2][2] = F (1);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_rotate (struct pixman_transform *forward,
|
||||
struct pixman_transform *reverse,
|
||||
pixman_fixed_t c,
|
||||
pixman_fixed_t s)
|
||||
{
|
||||
struct pixman_transform t;
|
||||
|
||||
if (forward)
|
||||
{
|
||||
pixman_transform_init_rotate (&t, c, s);
|
||||
if (!pixman_transform_multiply (forward, &t, forward))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
pixman_transform_init_rotate (&t, c, -s);
|
||||
if (!pixman_transform_multiply (reverse, reverse, &t))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_transform_init_translate (struct pixman_transform *t,
|
||||
pixman_fixed_t tx,
|
||||
pixman_fixed_t ty)
|
||||
{
|
||||
memset (t, '\0', sizeof (struct pixman_transform));
|
||||
|
||||
t->matrix[0][0] = F (1);
|
||||
t->matrix[0][2] = tx;
|
||||
t->matrix[1][1] = F (1);
|
||||
t->matrix[1][2] = ty;
|
||||
t->matrix[2][2] = F (1);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_translate (struct pixman_transform *forward,
|
||||
struct pixman_transform *reverse,
|
||||
pixman_fixed_t tx,
|
||||
pixman_fixed_t ty)
|
||||
{
|
||||
struct pixman_transform t;
|
||||
|
||||
if (forward)
|
||||
{
|
||||
pixman_transform_init_translate (&t, tx, ty);
|
||||
|
||||
if (!pixman_transform_multiply (forward, &t, forward))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
pixman_transform_init_translate (&t, -tx, -ty);
|
||||
|
||||
if (!pixman_transform_multiply (reverse, reverse, &t))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_bounds (const struct pixman_transform *matrix,
|
||||
struct pixman_box16 * b)
|
||||
|
||||
{
|
||||
struct pixman_vector v[4];
|
||||
int i;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
v[0].vector[0] = F (b->x1);
|
||||
v[0].vector[1] = F (b->y1);
|
||||
v[0].vector[2] = F (1);
|
||||
|
||||
v[1].vector[0] = F (b->x2);
|
||||
v[1].vector[1] = F (b->y1);
|
||||
v[1].vector[2] = F (1);
|
||||
|
||||
v[2].vector[0] = F (b->x2);
|
||||
v[2].vector[1] = F (b->y2);
|
||||
v[2].vector[2] = F (1);
|
||||
|
||||
v[3].vector[0] = F (b->x1);
|
||||
v[3].vector[1] = F (b->y2);
|
||||
v[3].vector[2] = F (1);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!pixman_transform_point (matrix, &v[i]))
|
||||
return FALSE;
|
||||
|
||||
x1 = pixman_fixed_to_int (v[i].vector[0]);
|
||||
y1 = pixman_fixed_to_int (v[i].vector[1]);
|
||||
x2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[0]));
|
||||
y2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[1]));
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
b->x1 = x1;
|
||||
b->y1 = y1;
|
||||
b->x2 = x2;
|
||||
b->y2 = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x1 < b->x1) b->x1 = x1;
|
||||
if (y1 < b->y1) b->y1 = y1;
|
||||
if (x2 > b->x2) b->x2 = x2;
|
||||
if (y2 > b->y2) b->y2 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_invert (struct pixman_transform * dst,
|
||||
const struct pixman_transform *src)
|
||||
{
|
||||
struct pixman_f_transform m, r;
|
||||
|
||||
pixman_f_transform_from_pixman_transform (&m, src);
|
||||
|
||||
if (!pixman_f_transform_invert (&r, &m))
|
||||
return FALSE;
|
||||
|
||||
if (!pixman_transform_from_pixman_f_transform (dst, &r))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
within_epsilon (pixman_fixed_t a,
|
||||
pixman_fixed_t b,
|
||||
pixman_fixed_t epsilon)
|
||||
{
|
||||
pixman_fixed_t t = a - b;
|
||||
|
||||
if (t < 0)
|
||||
t = -t;
|
||||
|
||||
return t <= epsilon;
|
||||
}
|
||||
|
||||
#define EPSILON (pixman_fixed_t) (2)
|
||||
|
||||
#define IS_SAME(a, b) (within_epsilon (a, b, EPSILON))
|
||||
#define IS_ZERO(a) (within_epsilon (a, 0, EPSILON))
|
||||
#define IS_ONE(a) (within_epsilon (a, F (1), EPSILON))
|
||||
#define IS_UNIT(a) \
|
||||
(within_epsilon (a, F (1), EPSILON) || \
|
||||
within_epsilon (a, F (-1), EPSILON) || \
|
||||
IS_ZERO (a))
|
||||
#define IS_INT(a) (IS_ZERO (pixman_fixed_frac (a)))
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_is_identity (const struct pixman_transform *t)
|
||||
{
|
||||
return (IS_SAME (t->matrix[0][0], t->matrix[1][1]) &&
|
||||
IS_SAME (t->matrix[0][0], t->matrix[2][2]) &&
|
||||
!IS_ZERO (t->matrix[0][0]) &&
|
||||
IS_ZERO (t->matrix[0][1]) &&
|
||||
IS_ZERO (t->matrix[0][2]) &&
|
||||
IS_ZERO (t->matrix[1][0]) &&
|
||||
IS_ZERO (t->matrix[1][2]) &&
|
||||
IS_ZERO (t->matrix[2][0]) &&
|
||||
IS_ZERO (t->matrix[2][1]));
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_is_scale (const struct pixman_transform *t)
|
||||
{
|
||||
return (!IS_ZERO (t->matrix[0][0]) &&
|
||||
IS_ZERO (t->matrix[0][1]) &&
|
||||
IS_ZERO (t->matrix[0][2]) &&
|
||||
|
||||
IS_ZERO (t->matrix[1][0]) &&
|
||||
!IS_ZERO (t->matrix[1][1]) &&
|
||||
IS_ZERO (t->matrix[1][2]) &&
|
||||
|
||||
IS_ZERO (t->matrix[2][0]) &&
|
||||
IS_ZERO (t->matrix[2][1]) &&
|
||||
!IS_ZERO (t->matrix[2][2]));
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_is_int_translate (const struct pixman_transform *t)
|
||||
{
|
||||
return (IS_ONE (t->matrix[0][0]) &&
|
||||
IS_ZERO (t->matrix[0][1]) &&
|
||||
IS_INT (t->matrix[0][2]) &&
|
||||
|
||||
IS_ZERO (t->matrix[1][0]) &&
|
||||
IS_ONE (t->matrix[1][1]) &&
|
||||
IS_INT (t->matrix[1][2]) &&
|
||||
|
||||
IS_ZERO (t->matrix[2][0]) &&
|
||||
IS_ZERO (t->matrix[2][1]) &&
|
||||
IS_ONE (t->matrix[2][2]));
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_is_inverse (const struct pixman_transform *a,
|
||||
const struct pixman_transform *b)
|
||||
{
|
||||
struct pixman_transform t;
|
||||
|
||||
pixman_transform_multiply (&t, a, b);
|
||||
|
||||
return pixman_transform_is_identity (&t);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_f_transform_from_pixman_transform (struct pixman_f_transform * ft,
|
||||
const struct pixman_transform *t)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
ft->m[j][i] = pixman_fixed_to_double (t->matrix[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_transform_from_pixman_f_transform (struct pixman_transform * t,
|
||||
const struct pixman_f_transform *ft)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
double d = ft->m[j][i];
|
||||
if (d < -32767.0 || d > 32767.0)
|
||||
return FALSE;
|
||||
d = d * 65536.0 + 0.5;
|
||||
t->matrix[j][i] = (pixman_fixed_t) floor (d);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const int a[3] = { 3, 3, 2 };
|
||||
static const int b[3] = { 2, 1, 1 };
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_f_transform_invert (struct pixman_f_transform * dst,
|
||||
const struct pixman_f_transform *src)
|
||||
{
|
||||
double det;
|
||||
int i, j;
|
||||
static int a[3] = { 2, 2, 1 };
|
||||
static int b[3] = { 1, 0, 0 };
|
||||
|
||||
det = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
double p;
|
||||
int ai = a[i];
|
||||
int bi = b[i];
|
||||
p = src->m[i][0] * (src->m[ai][2] * src->m[bi][1] -
|
||||
src->m[ai][1] * src->m[bi][2]);
|
||||
if (i == 1)
|
||||
p = -p;
|
||||
det += p;
|
||||
}
|
||||
|
||||
if (det == 0)
|
||||
return FALSE;
|
||||
|
||||
det = 1 / det;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
double p;
|
||||
int ai = a[i];
|
||||
int aj = a[j];
|
||||
int bi = b[i];
|
||||
int bj = b[j];
|
||||
|
||||
p = (src->m[ai][aj] * src->m[bi][bj] -
|
||||
src->m[ai][bj] * src->m[bi][aj]);
|
||||
|
||||
if (((i + j) & 1) != 0)
|
||||
p = -p;
|
||||
|
||||
dst->m[j][i] = det * p;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_f_transform_point (const struct pixman_f_transform *t,
|
||||
struct pixman_f_vector * v)
|
||||
{
|
||||
struct pixman_f_vector result;
|
||||
int i, j;
|
||||
double a;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
a = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
a += t->m[j][i] * v->v[i];
|
||||
result.v[j] = a;
|
||||
}
|
||||
|
||||
if (!result.v[2])
|
||||
return FALSE;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
v->v[j] = result.v[j] / result.v[2];
|
||||
|
||||
v->v[2] = 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_f_transform_point_3d (const struct pixman_f_transform *t,
|
||||
struct pixman_f_vector * v)
|
||||
{
|
||||
struct pixman_f_vector result;
|
||||
int i, j;
|
||||
double a;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
a = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
a += t->m[j][i] * v->v[i];
|
||||
result.v[j] = a;
|
||||
}
|
||||
|
||||
*v = result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_f_transform_multiply (struct pixman_f_transform * dst,
|
||||
const struct pixman_f_transform *l,
|
||||
const struct pixman_f_transform *r)
|
||||
{
|
||||
struct pixman_f_transform d;
|
||||
int dx, dy;
|
||||
int o;
|
||||
|
||||
for (dy = 0; dy < 3; dy++)
|
||||
{
|
||||
for (dx = 0; dx < 3; dx++)
|
||||
{
|
||||
double v = 0;
|
||||
for (o = 0; o < 3; o++)
|
||||
v += l->m[dy][o] * r->m[o][dx];
|
||||
d.m[dy][dx] = v;
|
||||
}
|
||||
}
|
||||
|
||||
*dst = d;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_f_transform_init_scale (struct pixman_f_transform *t,
|
||||
double sx,
|
||||
double sy)
|
||||
{
|
||||
t->m[0][0] = sx;
|
||||
t->m[0][1] = 0;
|
||||
t->m[0][2] = 0;
|
||||
t->m[1][0] = 0;
|
||||
t->m[1][1] = sy;
|
||||
t->m[1][2] = 0;
|
||||
t->m[2][0] = 0;
|
||||
t->m[2][1] = 0;
|
||||
t->m[2][2] = 1;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_f_transform_scale (struct pixman_f_transform *forward,
|
||||
struct pixman_f_transform *reverse,
|
||||
double sx,
|
||||
double sy)
|
||||
{
|
||||
struct pixman_f_transform t;
|
||||
|
||||
if (sx == 0 || sy == 0)
|
||||
return FALSE;
|
||||
|
||||
if (forward)
|
||||
{
|
||||
pixman_f_transform_init_scale (&t, sx, sy);
|
||||
pixman_f_transform_multiply (forward, &t, forward);
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
pixman_f_transform_init_scale (&t, 1 / sx, 1 / sy);
|
||||
pixman_f_transform_multiply (reverse, reverse, &t);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_f_transform_init_rotate (struct pixman_f_transform *t,
|
||||
double c,
|
||||
double s)
|
||||
{
|
||||
t->m[0][0] = c;
|
||||
t->m[0][1] = -s;
|
||||
t->m[0][2] = 0;
|
||||
t->m[1][0] = s;
|
||||
t->m[1][1] = c;
|
||||
t->m[1][2] = 0;
|
||||
t->m[2][0] = 0;
|
||||
t->m[2][1] = 0;
|
||||
t->m[2][2] = 1;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_f_transform_rotate (struct pixman_f_transform *forward,
|
||||
struct pixman_f_transform *reverse,
|
||||
double c,
|
||||
double s)
|
||||
{
|
||||
struct pixman_f_transform t;
|
||||
|
||||
if (forward)
|
||||
{
|
||||
pixman_f_transform_init_rotate (&t, c, s);
|
||||
pixman_f_transform_multiply (forward, &t, forward);
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
pixman_f_transform_init_rotate (&t, c, -s);
|
||||
pixman_f_transform_multiply (reverse, reverse, &t);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_f_transform_init_translate (struct pixman_f_transform *t,
|
||||
double tx,
|
||||
double ty)
|
||||
{
|
||||
t->m[0][0] = 1;
|
||||
t->m[0][1] = 0;
|
||||
t->m[0][2] = tx;
|
||||
t->m[1][0] = 0;
|
||||
t->m[1][1] = 1;
|
||||
t->m[1][2] = ty;
|
||||
t->m[2][0] = 0;
|
||||
t->m[2][1] = 0;
|
||||
t->m[2][2] = 1;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_f_transform_translate (struct pixman_f_transform *forward,
|
||||
struct pixman_f_transform *reverse,
|
||||
double tx,
|
||||
double ty)
|
||||
{
|
||||
struct pixman_f_transform t;
|
||||
|
||||
if (forward)
|
||||
{
|
||||
pixman_f_transform_init_translate (&t, tx, ty);
|
||||
pixman_f_transform_multiply (forward, &t, forward);
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
pixman_f_transform_init_translate (&t, -tx, -ty);
|
||||
pixman_f_transform_multiply (reverse, reverse, &t);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_f_transform_bounds (const struct pixman_f_transform *t,
|
||||
struct pixman_box16 * b)
|
||||
{
|
||||
struct pixman_f_vector v[4];
|
||||
int i;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
v[0].v[0] = b->x1;
|
||||
v[0].v[1] = b->y1;
|
||||
v[0].v[2] = 1;
|
||||
v[1].v[0] = b->x2;
|
||||
v[1].v[1] = b->y1;
|
||||
v[1].v[2] = 1;
|
||||
v[2].v[0] = b->x2;
|
||||
v[2].v[1] = b->y2;
|
||||
v[2].v[2] = 1;
|
||||
v[3].v[0] = b->x1;
|
||||
v[3].v[1] = b->y2;
|
||||
v[3].v[2] = 1;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!pixman_f_transform_point (t, &v[i]))
|
||||
return FALSE;
|
||||
|
||||
x1 = floor (v[i].v[0]);
|
||||
y1 = floor (v[i].v[1]);
|
||||
x2 = ceil (v[i].v[0]);
|
||||
y2 = ceil (v[i].v[1]);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
b->x1 = x1;
|
||||
b->y1 = y1;
|
||||
b->x2 = x2;
|
||||
b->y2 = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x1 < b->x1) b->x1 = x1;
|
||||
if (y1 < b->y1) b->y1 = y1;
|
||||
if (x2 > b->x2) b->x2 = x2;
|
||||
if (y2 > b->y2) b->y2 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_f_transform_init_identity (struct pixman_f_transform *t)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
t->m[j][i] = i == j ? 1 : 0;
|
||||
}
|
||||
}
|
3378
programs/develop/libraries/pixman/pixman-mmx.c
Normal file
3378
programs/develop/libraries/pixman/pixman-mmx.c
Normal file
File diff suppressed because it is too large
Load Diff
873
programs/develop/libraries/pixman/pixman-private.h
Normal file
873
programs/develop/libraries/pixman/pixman-private.h
Normal file
@ -0,0 +1,873 @@
|
||||
|
||||
#ifndef PIXMAN_PRIVATE_H
|
||||
#define PIXMAN_PRIVATE_H
|
||||
|
||||
#define PIXMAN_DISABLE_DEPRECATED
|
||||
#define PIXMAN_USE_INTERNAL_API
|
||||
|
||||
#include "pixman.h"
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pixman-compiler.h"
|
||||
|
||||
/*
|
||||
* Images
|
||||
*/
|
||||
typedef struct image_common image_common_t;
|
||||
typedef struct source_image source_image_t;
|
||||
typedef struct solid_fill solid_fill_t;
|
||||
typedef struct gradient gradient_t;
|
||||
typedef struct linear_gradient linear_gradient_t;
|
||||
typedef struct horizontal_gradient horizontal_gradient_t;
|
||||
typedef struct vertical_gradient vertical_gradient_t;
|
||||
typedef struct conical_gradient conical_gradient_t;
|
||||
typedef struct radial_gradient radial_gradient_t;
|
||||
typedef struct bits_image bits_image_t;
|
||||
typedef struct circle circle_t;
|
||||
|
||||
typedef void (*fetch_scanline_t) (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t *buffer,
|
||||
const uint32_t *mask);
|
||||
|
||||
typedef uint32_t (*fetch_pixel_32_t) (bits_image_t *image,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
typedef uint64_t (*fetch_pixel_64_t) (bits_image_t *image,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
typedef void (*store_scanline_t) (bits_image_t * image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
const uint32_t *values);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BITS,
|
||||
LINEAR,
|
||||
CONICAL,
|
||||
RADIAL,
|
||||
SOLID
|
||||
} image_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOURCE_IMAGE_CLASS_UNKNOWN,
|
||||
SOURCE_IMAGE_CLASS_HORIZONTAL,
|
||||
} source_image_class_t;
|
||||
|
||||
typedef source_image_class_t (*classify_func_t) (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
typedef void (*property_changed_func_t) (pixman_image_t *image);
|
||||
|
||||
struct image_common
|
||||
{
|
||||
image_type_t type;
|
||||
int32_t ref_count;
|
||||
pixman_region32_t clip_region;
|
||||
int32_t alpha_count; /* How many times this image is being used as an alpha map */
|
||||
pixman_bool_t have_clip_region; /* FALSE if there is no clip */
|
||||
pixman_bool_t client_clip; /* Whether the source clip was
|
||||
set by a client */
|
||||
pixman_bool_t clip_sources; /* Whether the clip applies when
|
||||
* the image is used as a source
|
||||
*/
|
||||
pixman_bool_t dirty;
|
||||
pixman_transform_t * transform;
|
||||
pixman_repeat_t repeat;
|
||||
pixman_filter_t filter;
|
||||
pixman_fixed_t * filter_params;
|
||||
int n_filter_params;
|
||||
bits_image_t * alpha_map;
|
||||
int alpha_origin_x;
|
||||
int alpha_origin_y;
|
||||
pixman_bool_t component_alpha;
|
||||
classify_func_t classify;
|
||||
property_changed_func_t property_changed;
|
||||
fetch_scanline_t get_scanline_32;
|
||||
fetch_scanline_t get_scanline_64;
|
||||
|
||||
pixman_image_destroy_func_t destroy_func;
|
||||
void * destroy_data;
|
||||
|
||||
uint32_t flags;
|
||||
pixman_format_code_t extended_format_code;
|
||||
};
|
||||
|
||||
struct source_image
|
||||
{
|
||||
image_common_t common;
|
||||
};
|
||||
|
||||
struct solid_fill
|
||||
{
|
||||
source_image_t common;
|
||||
pixman_color_t color;
|
||||
|
||||
uint32_t color_32;
|
||||
uint64_t color_64;
|
||||
};
|
||||
|
||||
struct gradient
|
||||
{
|
||||
source_image_t common;
|
||||
int n_stops;
|
||||
pixman_gradient_stop_t *stops;
|
||||
int stop_range;
|
||||
};
|
||||
|
||||
struct linear_gradient
|
||||
{
|
||||
gradient_t common;
|
||||
pixman_point_fixed_t p1;
|
||||
pixman_point_fixed_t p2;
|
||||
};
|
||||
|
||||
struct circle
|
||||
{
|
||||
pixman_fixed_t x;
|
||||
pixman_fixed_t y;
|
||||
pixman_fixed_t radius;
|
||||
};
|
||||
|
||||
struct radial_gradient
|
||||
{
|
||||
gradient_t common;
|
||||
|
||||
circle_t c1;
|
||||
circle_t c2;
|
||||
|
||||
circle_t delta;
|
||||
double a;
|
||||
double inva;
|
||||
double mindr;
|
||||
};
|
||||
|
||||
struct conical_gradient
|
||||
{
|
||||
gradient_t common;
|
||||
pixman_point_fixed_t center;
|
||||
double angle;
|
||||
};
|
||||
|
||||
struct bits_image
|
||||
{
|
||||
image_common_t common;
|
||||
pixman_format_code_t format;
|
||||
const pixman_indexed_t * indexed;
|
||||
int width;
|
||||
int height;
|
||||
uint32_t * bits;
|
||||
uint32_t * free_me;
|
||||
int rowstride; /* in number of uint32_t's */
|
||||
|
||||
fetch_scanline_t fetch_scanline_32;
|
||||
fetch_pixel_32_t fetch_pixel_32;
|
||||
store_scanline_t store_scanline_32;
|
||||
|
||||
fetch_scanline_t fetch_scanline_64;
|
||||
fetch_pixel_64_t fetch_pixel_64;
|
||||
store_scanline_t store_scanline_64;
|
||||
|
||||
/* Used for indirect access to the bits */
|
||||
pixman_read_memory_func_t read_func;
|
||||
pixman_write_memory_func_t write_func;
|
||||
};
|
||||
|
||||
union pixman_image
|
||||
{
|
||||
image_type_t type;
|
||||
image_common_t common;
|
||||
bits_image_t bits;
|
||||
source_image_t source;
|
||||
gradient_t gradient;
|
||||
linear_gradient_t linear;
|
||||
conical_gradient_t conical;
|
||||
radial_gradient_t radial;
|
||||
solid_fill_t solid;
|
||||
};
|
||||
|
||||
void
|
||||
_pixman_bits_image_setup_accessors (bits_image_t *image);
|
||||
|
||||
void
|
||||
_pixman_image_get_scanline_generic_64 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask);
|
||||
|
||||
source_image_class_t
|
||||
_pixman_image_classify (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void
|
||||
_pixman_image_get_scanline_32 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask);
|
||||
|
||||
/* Even thought the type of buffer is uint32_t *, the function actually expects
|
||||
* a uint64_t *buffer.
|
||||
*/
|
||||
void
|
||||
_pixman_image_get_scanline_64 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *unused);
|
||||
|
||||
void
|
||||
_pixman_image_store_scanline_32 (bits_image_t * image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
const uint32_t *buffer);
|
||||
|
||||
/* Even though the type of buffer is uint32_t *, the function
|
||||
* actually expects a uint64_t *buffer.
|
||||
*/
|
||||
void
|
||||
_pixman_image_store_scanline_64 (bits_image_t * image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
const uint32_t *buffer);
|
||||
|
||||
pixman_image_t *
|
||||
_pixman_image_allocate (void);
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_init_gradient (gradient_t * gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
void
|
||||
_pixman_image_reset_clip_region (pixman_image_t *image);
|
||||
|
||||
void
|
||||
_pixman_image_validate (pixman_image_t *image);
|
||||
|
||||
uint32_t
|
||||
_pixman_image_get_solid (pixman_image_t * image,
|
||||
pixman_format_code_t format);
|
||||
|
||||
#define PIXMAN_IMAGE_GET_LINE(image, x, y, type, out_stride, line, mul) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t *__bits__; \
|
||||
int __stride__; \
|
||||
\
|
||||
__bits__ = image->bits.bits; \
|
||||
__stride__ = image->bits.rowstride; \
|
||||
(out_stride) = \
|
||||
__stride__ * (int) sizeof (uint32_t) / (int) sizeof (type); \
|
||||
(line) = \
|
||||
((type *) __bits__) + (out_stride) * (y) + (mul) * (x); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Gradient walker
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t left_ag;
|
||||
uint32_t left_rb;
|
||||
uint32_t right_ag;
|
||||
uint32_t right_rb;
|
||||
int32_t left_x;
|
||||
int32_t right_x;
|
||||
int32_t stepper;
|
||||
|
||||
pixman_gradient_stop_t *stops;
|
||||
int num_stops;
|
||||
unsigned int spread;
|
||||
|
||||
int need_reset;
|
||||
} pixman_gradient_walker_t;
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
|
||||
gradient_t * gradient,
|
||||
unsigned int spread);
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t pos);
|
||||
|
||||
uint32_t
|
||||
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t x);
|
||||
|
||||
/*
|
||||
* Edges
|
||||
*/
|
||||
|
||||
#define MAX_ALPHA(n) ((1 << (n)) - 1)
|
||||
#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)
|
||||
#define N_X_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) + 1)
|
||||
|
||||
#define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC (n))
|
||||
#define STEP_Y_BIG(n) (pixman_fixed_1 - (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
|
||||
|
||||
#define Y_FRAC_FIRST(n) (STEP_Y_BIG (n) / 2)
|
||||
#define Y_FRAC_LAST(n) (Y_FRAC_FIRST (n) + (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n))
|
||||
|
||||
#define STEP_X_SMALL(n) (pixman_fixed_1 / N_X_FRAC (n))
|
||||
#define STEP_X_BIG(n) (pixman_fixed_1 - (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
|
||||
|
||||
#define X_FRAC_FIRST(n) (STEP_X_BIG (n) / 2)
|
||||
#define X_FRAC_LAST(n) (X_FRAC_FIRST (n) + (N_X_FRAC (n) - 1) * STEP_X_SMALL (n))
|
||||
|
||||
#define RENDER_SAMPLES_X(x, n) \
|
||||
((n) == 1? 0 : (pixman_fixed_frac (x) + \
|
||||
X_FRAC_FIRST (n)) / STEP_X_SMALL (n))
|
||||
|
||||
void
|
||||
pixman_rasterize_edges_accessors (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b);
|
||||
|
||||
/*
|
||||
* Implementations
|
||||
*/
|
||||
typedef struct pixman_implementation_t pixman_implementation_t;
|
||||
|
||||
typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width);
|
||||
|
||||
typedef void (*pixman_combine_64_func_t) (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width);
|
||||
|
||||
typedef void (*pixman_composite_func_t) (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_image_t * src,
|
||||
pixman_image_t * mask,
|
||||
pixman_image_t * dest,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t mask_x,
|
||||
int32_t mask_y,
|
||||
int32_t dest_x,
|
||||
int32_t dest_y,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height);
|
||||
typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t xor);
|
||||
|
||||
void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
|
||||
void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pixman_op_t op;
|
||||
pixman_format_code_t src_format;
|
||||
uint32_t src_flags;
|
||||
pixman_format_code_t mask_format;
|
||||
uint32_t mask_flags;
|
||||
pixman_format_code_t dest_format;
|
||||
uint32_t dest_flags;
|
||||
pixman_composite_func_t func;
|
||||
} pixman_fast_path_t;
|
||||
|
||||
struct pixman_implementation_t
|
||||
{
|
||||
pixman_implementation_t * toplevel;
|
||||
pixman_implementation_t * delegate;
|
||||
const pixman_fast_path_t * fast_paths;
|
||||
|
||||
pixman_blt_func_t blt;
|
||||
pixman_fill_func_t fill;
|
||||
|
||||
pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS];
|
||||
pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS];
|
||||
pixman_combine_64_func_t combine_64[PIXMAN_N_OPERATORS];
|
||||
pixman_combine_64_func_t combine_64_ca[PIXMAN_N_OPERATORS];
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create (pixman_implementation_t *delegate,
|
||||
const pixman_fast_path_t *fast_paths);
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_32 (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width);
|
||||
void
|
||||
_pixman_implementation_combine_64 (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width);
|
||||
void
|
||||
_pixman_implementation_combine_32_ca (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width);
|
||||
void
|
||||
_pixman_implementation_combine_64_ca (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width);
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t xor);
|
||||
|
||||
/* Specific implementations */
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_general (void);
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_fast_path (void);
|
||||
|
||||
#ifdef USE_MMX
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_mmx (void);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSE2
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_sse2 (void);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_SIMD
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_arm_simd (void);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_NEON
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_arm_neon (void);
|
||||
#endif
|
||||
|
||||
#ifdef USE_VMX
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_vmx (void);
|
||||
#endif
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_choose_implementation (void);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Utilities
|
||||
*/
|
||||
|
||||
/* These "formats" all have depth 0, so they
|
||||
* will never clash with any real ones
|
||||
*/
|
||||
#define PIXMAN_null PIXMAN_FORMAT (0, 0, 0, 0, 0, 0)
|
||||
#define PIXMAN_solid PIXMAN_FORMAT (0, 1, 0, 0, 0, 0)
|
||||
#define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0)
|
||||
#define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0)
|
||||
#define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0)
|
||||
#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0)
|
||||
|
||||
#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1)
|
||||
|
||||
#define FAST_PATH_ID_TRANSFORM (1 << 0)
|
||||
#define FAST_PATH_NO_ALPHA_MAP (1 << 1)
|
||||
#define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2)
|
||||
#define FAST_PATH_NO_PAD_REPEAT (1 << 3)
|
||||
#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4)
|
||||
#define FAST_PATH_NO_ACCESSORS (1 << 5)
|
||||
#define FAST_PATH_NARROW_FORMAT (1 << 6)
|
||||
#define FAST_PATH_COMPONENT_ALPHA (1 << 8)
|
||||
#define FAST_PATH_SAMPLES_OPAQUE (1 << 7)
|
||||
#define FAST_PATH_UNIFIED_ALPHA (1 << 9)
|
||||
#define FAST_PATH_SCALE_TRANSFORM (1 << 10)
|
||||
#define FAST_PATH_NEAREST_FILTER (1 << 11)
|
||||
#define FAST_PATH_HAS_TRANSFORM (1 << 12)
|
||||
#define FAST_PATH_IS_OPAQUE (1 << 13)
|
||||
#define FAST_PATH_NEEDS_WORKAROUND (1 << 14)
|
||||
#define FAST_PATH_NO_NONE_REPEAT (1 << 15)
|
||||
#define FAST_PATH_SAMPLES_COVER_CLIP (1 << 16)
|
||||
#define FAST_PATH_X_UNIT_POSITIVE (1 << 17)
|
||||
#define FAST_PATH_AFFINE_TRANSFORM (1 << 18)
|
||||
#define FAST_PATH_Y_UNIT_ZERO (1 << 19)
|
||||
#define FAST_PATH_BILINEAR_FILTER (1 << 20)
|
||||
#define FAST_PATH_NO_NORMAL_REPEAT (1 << 21)
|
||||
|
||||
#define FAST_PATH_PAD_REPEAT \
|
||||
(FAST_PATH_NO_NONE_REPEAT | \
|
||||
FAST_PATH_NO_NORMAL_REPEAT | \
|
||||
FAST_PATH_NO_REFLECT_REPEAT)
|
||||
|
||||
#define FAST_PATH_NORMAL_REPEAT \
|
||||
(FAST_PATH_NO_NONE_REPEAT | \
|
||||
FAST_PATH_NO_PAD_REPEAT | \
|
||||
FAST_PATH_NO_REFLECT_REPEAT)
|
||||
|
||||
#define FAST_PATH_NONE_REPEAT \
|
||||
(FAST_PATH_NO_NORMAL_REPEAT | \
|
||||
FAST_PATH_NO_PAD_REPEAT | \
|
||||
FAST_PATH_NO_REFLECT_REPEAT)
|
||||
|
||||
#define FAST_PATH_REFLECT_REPEAT \
|
||||
(FAST_PATH_NO_NONE_REPEAT | \
|
||||
FAST_PATH_NO_NORMAL_REPEAT | \
|
||||
FAST_PATH_NO_PAD_REPEAT)
|
||||
|
||||
#define FAST_PATH_STANDARD_FLAGS \
|
||||
(FAST_PATH_NO_CONVOLUTION_FILTER | \
|
||||
FAST_PATH_NO_ACCESSORS | \
|
||||
FAST_PATH_NO_ALPHA_MAP | \
|
||||
FAST_PATH_NARROW_FORMAT)
|
||||
|
||||
#define FAST_PATH_STD_DEST_FLAGS \
|
||||
(FAST_PATH_NO_ACCESSORS | \
|
||||
FAST_PATH_NO_ALPHA_MAP | \
|
||||
FAST_PATH_NARROW_FORMAT)
|
||||
|
||||
#define SOURCE_FLAGS(format) \
|
||||
(FAST_PATH_STANDARD_FLAGS | \
|
||||
((PIXMAN_ ## format == PIXMAN_solid) ? \
|
||||
0 : (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_ID_TRANSFORM)))
|
||||
|
||||
#define MASK_FLAGS(format, extra) \
|
||||
((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra))
|
||||
|
||||
#define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \
|
||||
PIXMAN_OP_ ## op, \
|
||||
PIXMAN_ ## src, \
|
||||
src_flags, \
|
||||
PIXMAN_ ## mask, \
|
||||
mask_flags, \
|
||||
PIXMAN_ ## dest, \
|
||||
dest_flags, \
|
||||
func
|
||||
|
||||
#define PIXMAN_STD_FAST_PATH(op, src, mask, dest, func) \
|
||||
{ FAST_PATH ( \
|
||||
op, \
|
||||
src, SOURCE_FLAGS (src), \
|
||||
mask, MASK_FLAGS (mask, FAST_PATH_UNIFIED_ALPHA), \
|
||||
dest, FAST_PATH_STD_DEST_FLAGS, \
|
||||
func) }
|
||||
|
||||
#define PIXMAN_STD_FAST_PATH_CA(op, src, mask, dest, func) \
|
||||
{ FAST_PATH ( \
|
||||
op, \
|
||||
src, SOURCE_FLAGS (src), \
|
||||
mask, MASK_FLAGS (mask, FAST_PATH_COMPONENT_ALPHA), \
|
||||
dest, FAST_PATH_STD_DEST_FLAGS, \
|
||||
func) }
|
||||
|
||||
/* Memory allocation helpers */
|
||||
void *
|
||||
pixman_malloc_ab (unsigned int n, unsigned int b);
|
||||
|
||||
void *
|
||||
pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
|
||||
|
||||
pixman_bool_t
|
||||
pixman_multiply_overflows_int (unsigned int a, unsigned int b);
|
||||
|
||||
pixman_bool_t
|
||||
pixman_addition_overflows_int (unsigned int a, unsigned int b);
|
||||
|
||||
/* Compositing utilities */
|
||||
void
|
||||
pixman_expand (uint64_t * dst,
|
||||
const uint32_t * src,
|
||||
pixman_format_code_t format,
|
||||
int width);
|
||||
|
||||
void
|
||||
pixman_contract (uint32_t * dst,
|
||||
const uint64_t *src,
|
||||
int width);
|
||||
|
||||
|
||||
/* Region Helpers */
|
||||
pixman_bool_t
|
||||
pixman_region32_copy_from_region16 (pixman_region32_t *dst,
|
||||
pixman_region16_t *src);
|
||||
|
||||
pixman_bool_t
|
||||
pixman_region16_copy_from_region32 (pixman_region16_t *dst,
|
||||
pixman_region32_t *src);
|
||||
|
||||
|
||||
/* Misc macros */
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a, b) ((a < b) ? a : b)
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) ((a > b) ? a : b)
|
||||
#endif
|
||||
|
||||
/* Integer division that rounds towards -infinity */
|
||||
#define DIV(a, b) \
|
||||
((((a) < 0) == ((b) < 0)) ? (a) / (b) : \
|
||||
((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
|
||||
|
||||
/* Modulus that produces the remainder wrt. DIV */
|
||||
#define MOD(a, b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
|
||||
|
||||
#define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v)))
|
||||
|
||||
/* Conversion between 8888 and 0565 */
|
||||
|
||||
#define CONVERT_8888_TO_0565(s) \
|
||||
((((s) >> 3) & 0x001f) | \
|
||||
(((s) >> 5) & 0x07e0) | \
|
||||
(((s) >> 8) & 0xf800))
|
||||
|
||||
#define CONVERT_0565_TO_0888(s) \
|
||||
(((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
|
||||
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
|
||||
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
|
||||
|
||||
#define CONVERT_0565_TO_8888(s) (CONVERT_0565_TO_0888(s) | 0xff000000)
|
||||
|
||||
/* Trivial versions that are useful in macros */
|
||||
#define CONVERT_8888_TO_8888(s) (s)
|
||||
#define CONVERT_0565_TO_0565(s) (s)
|
||||
|
||||
#define PIXMAN_FORMAT_IS_WIDE(f) \
|
||||
(PIXMAN_FORMAT_A (f) > 8 || \
|
||||
PIXMAN_FORMAT_R (f) > 8 || \
|
||||
PIXMAN_FORMAT_G (f) > 8 || \
|
||||
PIXMAN_FORMAT_B (f) > 8)
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
|
||||
# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
|
||||
#else
|
||||
# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
|
||||
# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Various debugging code
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#define COMPILE_TIME_ASSERT(x) \
|
||||
do { typedef int compile_time_assertion [(x)?1:-1]; } while (0)
|
||||
|
||||
/* Turn on debugging depending on what type of release this is
|
||||
*/
|
||||
#if (((PIXMAN_VERSION_MICRO % 2) == 0) && ((PIXMAN_VERSION_MINOR % 2) == 1))
|
||||
|
||||
/* Debugging gets turned on for development releases because these
|
||||
* are the things that end up in bleeding edge distributions such
|
||||
* as Rawhide etc.
|
||||
*
|
||||
* For performance reasons we don't turn it on for stable releases or
|
||||
* random git checkouts. (Random git checkouts are often used for
|
||||
* performance work).
|
||||
*/
|
||||
|
||||
# define DEBUG
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
void
|
||||
_pixman_log_error (const char *function, const char *message);
|
||||
|
||||
#define return_if_fail(expr) \
|
||||
do \
|
||||
{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
_pixman_log_error (FUNC, "The expression " # expr " was false"); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define return_val_if_fail(expr, retval) \
|
||||
do \
|
||||
{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
_pixman_log_error (FUNC, "The expression " # expr " was false"); \
|
||||
return (retval); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define critical_if_fail(expr) \
|
||||
do \
|
||||
{ \
|
||||
if (!(expr)) \
|
||||
_pixman_log_error (FUNC, "The expression " # expr " was false"); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define _pixman_log_error(f,m) do { } while (0) \
|
||||
|
||||
#define return_if_fail(expr) \
|
||||
do \
|
||||
{ \
|
||||
if (!(expr)) \
|
||||
return; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define return_val_if_fail(expr, retval) \
|
||||
do \
|
||||
{ \
|
||||
if (!(expr)) \
|
||||
return (retval); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define critical_if_fail(expr) \
|
||||
do \
|
||||
{ \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Timers
|
||||
*/
|
||||
|
||||
#ifdef PIXMAN_TIMERS
|
||||
|
||||
static inline uint64_t
|
||||
oil_profile_stamp_rdtsc (void)
|
||||
{
|
||||
uint64_t ts;
|
||||
|
||||
__asm__ __volatile__ ("rdtsc\n" : "=A" (ts));
|
||||
return ts;
|
||||
}
|
||||
|
||||
#define OIL_STAMP oil_profile_stamp_rdtsc
|
||||
|
||||
typedef struct pixman_timer_t pixman_timer_t;
|
||||
|
||||
struct pixman_timer_t
|
||||
{
|
||||
int initialized;
|
||||
const char * name;
|
||||
uint64_t n_times;
|
||||
uint64_t total;
|
||||
pixman_timer_t *next;
|
||||
};
|
||||
|
||||
extern int timer_defined;
|
||||
|
||||
void pixman_timer_register (pixman_timer_t *timer);
|
||||
|
||||
#define TIMER_BEGIN(tname) \
|
||||
{ \
|
||||
static pixman_timer_t timer ## tname; \
|
||||
uint64_t begin ## tname; \
|
||||
\
|
||||
if (!timer ## tname.initialized) \
|
||||
{ \
|
||||
timer ## tname.initialized = 1; \
|
||||
timer ## tname.name = # tname; \
|
||||
pixman_timer_register (&timer ## tname); \
|
||||
} \
|
||||
\
|
||||
timer ## tname.n_times++; \
|
||||
begin ## tname = OIL_STAMP ();
|
||||
|
||||
#define TIMER_END(tname) \
|
||||
timer ## tname.total += OIL_STAMP () - begin ## tname; \
|
||||
}
|
||||
|
||||
#endif /* PIXMAN_TIMERS */
|
||||
|
||||
#endif /* PIXMAN_PRIVATE_H */
|
448
programs/develop/libraries/pixman/pixman-radial-gradient.c
Normal file
448
programs/develop/libraries/pixman/pixman-radial-gradient.c
Normal file
@ -0,0 +1,448 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static inline pixman_fixed_32_32_t
|
||||
dot (pixman_fixed_48_16_t x1,
|
||||
pixman_fixed_48_16_t y1,
|
||||
pixman_fixed_48_16_t z1,
|
||||
pixman_fixed_48_16_t x2,
|
||||
pixman_fixed_48_16_t y2,
|
||||
pixman_fixed_48_16_t z2)
|
||||
{
|
||||
/*
|
||||
* Exact computation, assuming that the input values can
|
||||
* be represented as pixman_fixed_16_16_t
|
||||
*/
|
||||
return x1 * x2 + y1 * y2 + z1 * z2;
|
||||
}
|
||||
|
||||
static inline double
|
||||
fdot (double x1,
|
||||
double y1,
|
||||
double z1,
|
||||
double x2,
|
||||
double y2,
|
||||
double z2)
|
||||
{
|
||||
/*
|
||||
* Error can be unbound in some special cases.
|
||||
* Using clever dot product algorithms (for example compensated
|
||||
* dot product) would improve this but make the code much less
|
||||
* obvious
|
||||
*/
|
||||
return x1 * x2 + y1 * y2 + z1 * z2;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
radial_compute_color (double a,
|
||||
double b,
|
||||
double c,
|
||||
double inva,
|
||||
double dr,
|
||||
double mindr,
|
||||
pixman_gradient_walker_t *walker,
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
/*
|
||||
* In this function error propagation can lead to bad results:
|
||||
* - det can have an unbound error (if b*b-a*c is very small),
|
||||
* potentially making it the opposite sign of what it should have been
|
||||
* (thus clearing a pixel that would have been colored or vice-versa)
|
||||
* or propagating the error to sqrtdet;
|
||||
* if det has the wrong sign or b is very small, this can lead to bad
|
||||
* results
|
||||
*
|
||||
* - the algorithm used to compute the solutions of the quadratic
|
||||
* equation is not numerically stable (but saves one division compared
|
||||
* to the numerically stable one);
|
||||
* this can be a problem if a*c is much smaller than b*b
|
||||
*
|
||||
* - the above problems are worse if a is small (as inva becomes bigger)
|
||||
*/
|
||||
double det;
|
||||
|
||||
if (a == 0)
|
||||
{
|
||||
double t;
|
||||
|
||||
if (b == 0)
|
||||
return 0;
|
||||
|
||||
t = pixman_fixed_1 / 2 * c / b;
|
||||
if (repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (0 <= t && t <= pixman_fixed_1)
|
||||
return _pixman_gradient_walker_pixel (walker, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t * dr > mindr)
|
||||
return _pixman_gradient_walker_pixel (walker, t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
det = fdot (b, a, 0, b, -c, 0);
|
||||
if (det >= 0)
|
||||
{
|
||||
double sqrtdet, t0, t1;
|
||||
|
||||
sqrtdet = sqrt (det);
|
||||
t0 = (b + sqrtdet) * inva;
|
||||
t1 = (b - sqrtdet) * inva;
|
||||
|
||||
if (repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (0 <= t0 && t0 <= pixman_fixed_1)
|
||||
return _pixman_gradient_walker_pixel (walker, t0);
|
||||
else if (0 <= t1 && t1 <= pixman_fixed_1)
|
||||
return _pixman_gradient_walker_pixel (walker, t1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t0 * dr > mindr)
|
||||
return _pixman_gradient_walker_pixel (walker, t0);
|
||||
else if (t1 * dr > mindr)
|
||||
return _pixman_gradient_walker_pixel (walker, t1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
radial_gradient_get_scanline_32 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask)
|
||||
{
|
||||
/*
|
||||
* Implementation of radial gradients following the PDF specification.
|
||||
* See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference
|
||||
* Manual (PDF 32000-1:2008 at the time of this writing).
|
||||
*
|
||||
* In the radial gradient problem we are given two circles (c₁,r₁) and
|
||||
* (c₂,r₂) that define the gradient itself.
|
||||
*
|
||||
* Mathematically the gradient can be defined as the family of circles
|
||||
*
|
||||
* ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂)
|
||||
*
|
||||
* excluding those circles whose radius would be < 0. When a point
|
||||
* belongs to more than one circle, the one with a bigger t is the only
|
||||
* one that contributes to its color. When a point does not belong
|
||||
* to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0).
|
||||
* Further limitations on the range of values for t are imposed when
|
||||
* the gradient is not repeated, namely t must belong to [0,1].
|
||||
*
|
||||
* The graphical result is the same as drawing the valid (radius > 0)
|
||||
* circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient
|
||||
* is not repeated) using SOURCE operatior composition.
|
||||
*
|
||||
* It looks like a cone pointing towards the viewer if the ending circle
|
||||
* is smaller than the starting one, a cone pointing inside the page if
|
||||
* the starting circle is the smaller one and like a cylinder if they
|
||||
* have the same radius.
|
||||
*
|
||||
* What we actually do is, given the point whose color we are interested
|
||||
* in, compute the t values for that point, solving for t in:
|
||||
*
|
||||
* length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂
|
||||
*
|
||||
* Let's rewrite it in a simpler way, by defining some auxiliary
|
||||
* variables:
|
||||
*
|
||||
* cd = c₂ - c₁
|
||||
* pd = p - c₁
|
||||
* dr = r₂ - r₁
|
||||
* lenght(t·cd - pd) = r₁ + t·dr
|
||||
*
|
||||
* which actually means
|
||||
*
|
||||
* hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr
|
||||
*
|
||||
* or
|
||||
*
|
||||
* ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr.
|
||||
*
|
||||
* If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes:
|
||||
*
|
||||
* (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)²
|
||||
*
|
||||
* where we can actually expand the squares and solve for t:
|
||||
*
|
||||
* t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² =
|
||||
* = r₁² + 2·r₁·t·dr + t²·dr²
|
||||
*
|
||||
* (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t +
|
||||
* (pdx² + pdy² - r₁²) = 0
|
||||
*
|
||||
* A = cdx² + cdy² - dr²
|
||||
* B = pdx·cdx + pdy·cdy + r₁·dr
|
||||
* C = pdx² + pdy² - r₁²
|
||||
* At² - 2Bt + C = 0
|
||||
*
|
||||
* The solutions (unless the equation degenerates because of A = 0) are:
|
||||
*
|
||||
* t = (B ± ⎷(B² - A·C)) / A
|
||||
*
|
||||
* The solution we are going to prefer is the bigger one, unless the
|
||||
* radius associated to it is negative (or it falls outside the valid t
|
||||
* range).
|
||||
*
|
||||
* Additional observations (useful for optimizations):
|
||||
* A does not depend on p
|
||||
*
|
||||
* A < 0 <=> one of the two circles completely contains the other one
|
||||
* <=> for every p, the radiuses associated with the two t solutions
|
||||
* have opposite sign
|
||||
*/
|
||||
|
||||
gradient_t *gradient = (gradient_t *)image;
|
||||
source_image_t *source = (source_image_t *)image;
|
||||
radial_gradient_t *radial = (radial_gradient_t *)image;
|
||||
uint32_t *end = buffer + width;
|
||||
pixman_gradient_walker_t walker;
|
||||
pixman_vector_t v, unit;
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
|
||||
|
||||
if (source->common.transform)
|
||||
{
|
||||
if (!pixman_transform_point_3d (source->common.transform, &v))
|
||||
return;
|
||||
|
||||
unit.vector[0] = source->common.transform->matrix[0][0];
|
||||
unit.vector[1] = source->common.transform->matrix[1][0];
|
||||
unit.vector[2] = source->common.transform->matrix[2][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
unit.vector[0] = pixman_fixed_1;
|
||||
unit.vector[1] = 0;
|
||||
unit.vector[2] = 0;
|
||||
}
|
||||
|
||||
if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)
|
||||
{
|
||||
/*
|
||||
* Given:
|
||||
*
|
||||
* t = (B ± ⎷(B² - A·C)) / A
|
||||
*
|
||||
* where
|
||||
*
|
||||
* A = cdx² + cdy² - dr²
|
||||
* B = pdx·cdx + pdy·cdy + r₁·dr
|
||||
* C = pdx² + pdy² - r₁²
|
||||
* det = B² - A·C
|
||||
*
|
||||
* Since we have an affine transformation, we know that (pdx, pdy)
|
||||
* increase linearly with each pixel,
|
||||
*
|
||||
* pdx = pdx₀ + n·ux,
|
||||
* pdy = pdy₀ + n·uy,
|
||||
*
|
||||
* we can then express B, C and det through multiple differentiation.
|
||||
*/
|
||||
pixman_fixed_32_32_t b, db, c, dc, ddc;
|
||||
|
||||
/* warning: this computation may overflow */
|
||||
v.vector[0] -= radial->c1.x;
|
||||
v.vector[1] -= radial->c1.y;
|
||||
|
||||
/*
|
||||
* B and C are computed and updated exactly.
|
||||
* If fdot was used instead of dot, in the worst case it would
|
||||
* lose 11 bits of precision in each of the multiplication and
|
||||
* summing up would zero out all the bit that were preserved,
|
||||
* thus making the result 0 instead of the correct one.
|
||||
* This would mean a worst case of unbound relative error or
|
||||
* about 2^10 absolute error
|
||||
*/
|
||||
b = dot (v.vector[0], v.vector[1], radial->c1.radius,
|
||||
radial->delta.x, radial->delta.y, radial->delta.radius);
|
||||
db = dot (unit.vector[0], unit.vector[1], 0,
|
||||
radial->delta.x, radial->delta.y, 0);
|
||||
|
||||
c = dot (v.vector[0], v.vector[1],
|
||||
-((pixman_fixed_48_16_t) radial->c1.radius),
|
||||
v.vector[0], v.vector[1], radial->c1.radius);
|
||||
dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0],
|
||||
2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1],
|
||||
0,
|
||||
unit.vector[0], unit.vector[1], 0);
|
||||
ddc = 2 * dot (unit.vector[0], unit.vector[1], 0,
|
||||
unit.vector[0], unit.vector[1], 0);
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
*buffer = radial_compute_color (radial->a, b, c,
|
||||
radial->inva,
|
||||
radial->delta.radius,
|
||||
radial->mindr,
|
||||
&walker,
|
||||
source->common.repeat);
|
||||
}
|
||||
|
||||
b += db;
|
||||
c += dc;
|
||||
dc += ddc;
|
||||
++buffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* projective */
|
||||
/* Warning:
|
||||
* error propagation guarantees are much looser than in the affine case
|
||||
*/
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
if (v.vector[2] != 0)
|
||||
{
|
||||
double pdx, pdy, invv2, b, c;
|
||||
|
||||
invv2 = 1. * pixman_fixed_1 / v.vector[2];
|
||||
|
||||
pdx = v.vector[0] * invv2 - radial->c1.x;
|
||||
/* / pixman_fixed_1 */
|
||||
|
||||
pdy = v.vector[1] * invv2 - radial->c1.y;
|
||||
/* / pixman_fixed_1 */
|
||||
|
||||
b = fdot (pdx, pdy, radial->c1.radius,
|
||||
radial->delta.x, radial->delta.y,
|
||||
radial->delta.radius);
|
||||
/* / pixman_fixed_1 / pixman_fixed_1 */
|
||||
|
||||
c = fdot (pdx, pdy, -radial->c1.radius,
|
||||
pdx, pdy, radial->c1.radius);
|
||||
/* / pixman_fixed_1 / pixman_fixed_1 */
|
||||
|
||||
*buffer = radial_compute_color (radial->a, b, c,
|
||||
radial->inva,
|
||||
radial->delta.radius,
|
||||
radial->mindr,
|
||||
&walker,
|
||||
source->common.repeat);
|
||||
}
|
||||
else
|
||||
{
|
||||
*buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
++buffer;
|
||||
|
||||
v.vector[0] += unit.vector[0];
|
||||
v.vector[1] += unit.vector[1];
|
||||
v.vector[2] += unit.vector[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
radial_gradient_property_changed (pixman_image_t *image)
|
||||
{
|
||||
image->common.get_scanline_32 = radial_gradient_get_scanline_32;
|
||||
image->common.get_scanline_64 = _pixman_image_get_scanline_generic_64;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_radial_gradient (pixman_point_fixed_t * inner,
|
||||
pixman_point_fixed_t * outer,
|
||||
pixman_fixed_t inner_radius,
|
||||
pixman_fixed_t outer_radius,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
radial_gradient_t *radial;
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
radial = &image->radial;
|
||||
|
||||
if (!_pixman_init_gradient (&radial->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image->type = RADIAL;
|
||||
|
||||
radial->c1.x = inner->x;
|
||||
radial->c1.y = inner->y;
|
||||
radial->c1.radius = inner_radius;
|
||||
radial->c2.x = outer->x;
|
||||
radial->c2.y = outer->y;
|
||||
radial->c2.radius = outer_radius;
|
||||
|
||||
/* warning: this computations may overflow */
|
||||
radial->delta.x = radial->c2.x - radial->c1.x;
|
||||
radial->delta.y = radial->c2.y - radial->c1.y;
|
||||
radial->delta.radius = radial->c2.radius - radial->c1.radius;
|
||||
|
||||
/* computed exactly, then cast to double -> every bit of the double
|
||||
representation is correct (53 bits) */
|
||||
radial->a = dot (radial->delta.x, radial->delta.y, -radial->delta.radius,
|
||||
radial->delta.x, radial->delta.y, radial->delta.radius);
|
||||
if (radial->a != 0)
|
||||
radial->inva = 1. * pixman_fixed_1 / radial->a;
|
||||
|
||||
radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius;
|
||||
|
||||
image->common.property_changed = radial_gradient_property_changed;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
2769
programs/develop/libraries/pixman/pixman-region.c
Normal file
2769
programs/develop/libraries/pixman/pixman-region.c
Normal file
File diff suppressed because it is too large
Load Diff
67
programs/develop/libraries/pixman/pixman-region16.c
Normal file
67
programs/develop/libraries/pixman/pixman-region16.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@redhat.com>
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#undef PIXMAN_DISABLE_DEPRECATED
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef pixman_box16_t box_type_t;
|
||||
typedef pixman_region16_data_t region_data_type_t;
|
||||
typedef pixman_region16_t region_type_t;
|
||||
typedef int32_t overflow_int_t;
|
||||
|
||||
typedef struct {
|
||||
int x, y;
|
||||
} point_type_t;
|
||||
|
||||
#define PREFIX(x) pixman_region##x
|
||||
|
||||
#define PIXMAN_REGION_MAX INT16_MAX
|
||||
#define PIXMAN_REGION_MIN INT16_MIN
|
||||
|
||||
#include "pixman-region.c"
|
||||
|
||||
/* This function exists only to make it possible to preserve the X ABI -
|
||||
* it should go away at first opportunity.
|
||||
*
|
||||
* The problem is that the X ABI exports the three structs and has used
|
||||
* them through macros. So the X server calls this function with
|
||||
* the addresses of those structs which makes the existing code continue to
|
||||
* work.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_region_set_static_pointers (pixman_box16_t *empty_box,
|
||||
pixman_region16_data_t *empty_data,
|
||||
pixman_region16_data_t *broken_data)
|
||||
{
|
||||
pixman_region_empty_box = empty_box;
|
||||
pixman_region_empty_data = empty_data;
|
||||
pixman_broken_data = broken_data;
|
||||
}
|
47
programs/develop/libraries/pixman/pixman-region32.c
Normal file
47
programs/develop/libraries/pixman/pixman-region32.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of
|
||||
* Red Hat, Inc. not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. Red Hat, Inc. makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@redhat.com>
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef pixman_box32_t box_type_t;
|
||||
typedef pixman_region32_data_t region_data_type_t;
|
||||
typedef pixman_region32_t region_type_t;
|
||||
typedef int64_t overflow_int_t;
|
||||
|
||||
typedef struct {
|
||||
int x, y;
|
||||
} point_type_t;
|
||||
|
||||
#define PREFIX(x) pixman_region32##x
|
||||
|
||||
#define PIXMAN_REGION_MAX INT32_MAX
|
||||
#define PIXMAN_REGION_MIN INT32_MIN
|
||||
|
||||
#include "pixman-region.c"
|
117
programs/develop/libraries/pixman/pixman-solid-fill.c
Normal file
117
programs/develop/libraries/pixman/pixman-solid-fill.c
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007, 2009 Red Hat, Inc.
|
||||
* Copyright © 2009 Soren Sandmann
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
static void
|
||||
solid_fill_get_scanline_32 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask)
|
||||
{
|
||||
uint32_t *end = buffer + width;
|
||||
uint32_t color = image->solid.color_32;
|
||||
|
||||
while (buffer < end)
|
||||
*(buffer++) = color;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
solid_fill_get_scanline_64 (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t *mask)
|
||||
{
|
||||
uint64_t *b = (uint64_t *)buffer;
|
||||
uint64_t *e = b + width;
|
||||
uint64_t color = image->solid.color_64;
|
||||
|
||||
while (b < e)
|
||||
*(b++) = color;
|
||||
}
|
||||
|
||||
static source_image_class_t
|
||||
solid_fill_classify (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return SOURCE_IMAGE_CLASS_HORIZONTAL;
|
||||
}
|
||||
|
||||
static void
|
||||
solid_fill_property_changed (pixman_image_t *image)
|
||||
{
|
||||
image->common.get_scanline_32 = solid_fill_get_scanline_32;
|
||||
image->common.get_scanline_64 = solid_fill_get_scanline_64;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
color_to_uint32 (const pixman_color_t *color)
|
||||
{
|
||||
return
|
||||
(color->alpha >> 8 << 24) |
|
||||
(color->red >> 8 << 16) |
|
||||
(color->green & 0xff00) |
|
||||
(color->blue >> 8);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
color_to_uint64 (const pixman_color_t *color)
|
||||
{
|
||||
return
|
||||
((uint64_t)color->alpha << 48) |
|
||||
((uint64_t)color->red << 32) |
|
||||
((uint64_t)color->green << 16) |
|
||||
((uint64_t)color->blue);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_solid_fill (pixman_color_t *color)
|
||||
{
|
||||
pixman_image_t *img = _pixman_image_allocate ();
|
||||
|
||||
if (!img)
|
||||
return NULL;
|
||||
|
||||
img->type = SOLID;
|
||||
img->solid.color = *color;
|
||||
img->solid.color_32 = color_to_uint32 (color);
|
||||
img->solid.color_64 = color_to_uint64 (color);
|
||||
|
||||
img->common.classify = solid_fill_classify;
|
||||
img->common.property_changed = solid_fill_property_changed;
|
||||
|
||||
return img;
|
||||
}
|
||||
|
66
programs/develop/libraries/pixman/pixman-timer.c
Normal file
66
programs/develop/libraries/pixman/pixman-timer.c
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
#ifdef PIXMAN_TIMERS
|
||||
|
||||
static pixman_timer_t *timers;
|
||||
|
||||
static void
|
||||
dump_timers (void)
|
||||
{
|
||||
pixman_timer_t *timer;
|
||||
|
||||
for (timer = timers; timer != NULL; timer = timer->next)
|
||||
{
|
||||
printf ("%s: total: %llu n: %llu avg: %f\n",
|
||||
timer->name,
|
||||
timer->total,
|
||||
timer->n_times,
|
||||
timer->total / (double)timer->n_times);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pixman_timer_register (pixman_timer_t *timer)
|
||||
{
|
||||
static int initialized;
|
||||
|
||||
int atexit (void (*function)(void));
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
atexit (dump_timers);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
timer->next = timers;
|
||||
timers = timer;
|
||||
}
|
||||
|
||||
#endif
|
392
programs/develop/libraries/pixman/pixman-trap.c
Normal file
392
programs/develop/libraries/pixman/pixman-trap.c
Normal file
@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
/*
|
||||
* Compute the smallest value greater than or equal to y which is on a
|
||||
* grid row.
|
||||
*/
|
||||
|
||||
PIXMAN_EXPORT pixman_fixed_t
|
||||
pixman_sample_ceil_y (pixman_fixed_t y, int n)
|
||||
{
|
||||
pixman_fixed_t f = pixman_fixed_frac (y);
|
||||
pixman_fixed_t i = pixman_fixed_floor (y);
|
||||
|
||||
f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
|
||||
Y_FRAC_FIRST (n);
|
||||
|
||||
if (f > Y_FRAC_LAST (n))
|
||||
{
|
||||
if (pixman_fixed_to_int (i) == 0x7fff)
|
||||
{
|
||||
f = 0xffff; /* saturate */
|
||||
}
|
||||
else
|
||||
{
|
||||
f = Y_FRAC_FIRST (n);
|
||||
i += pixman_fixed_1;
|
||||
}
|
||||
}
|
||||
return (i | f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the largest value strictly less than y which is on a
|
||||
* grid row.
|
||||
*/
|
||||
PIXMAN_EXPORT pixman_fixed_t
|
||||
pixman_sample_floor_y (pixman_fixed_t y,
|
||||
int n)
|
||||
{
|
||||
pixman_fixed_t f = pixman_fixed_frac (y);
|
||||
pixman_fixed_t i = pixman_fixed_floor (y);
|
||||
|
||||
f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
|
||||
Y_FRAC_FIRST (n);
|
||||
|
||||
if (f < Y_FRAC_FIRST (n))
|
||||
{
|
||||
if (pixman_fixed_to_int (i) == 0x8000)
|
||||
{
|
||||
f = 0; /* saturate */
|
||||
}
|
||||
else
|
||||
{
|
||||
f = Y_FRAC_LAST (n);
|
||||
i -= pixman_fixed_1;
|
||||
}
|
||||
}
|
||||
return (i | f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Step an edge by any amount (including negative values)
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_edge_step (pixman_edge_t *e,
|
||||
int n)
|
||||
{
|
||||
pixman_fixed_48_16_t ne;
|
||||
|
||||
e->x += n * e->stepx;
|
||||
|
||||
ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
|
||||
|
||||
if (n >= 0)
|
||||
{
|
||||
if (ne > 0)
|
||||
{
|
||||
int nx = (ne + e->dy - 1) / e->dy;
|
||||
e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
|
||||
e->x += nx * e->signdx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ne <= -e->dy)
|
||||
{
|
||||
int nx = (-ne) / e->dy;
|
||||
e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
|
||||
e->x -= nx * e->signdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A private routine to initialize the multi-step
|
||||
* elements of an edge structure
|
||||
*/
|
||||
static void
|
||||
_pixman_edge_multi_init (pixman_edge_t * e,
|
||||
int n,
|
||||
pixman_fixed_t *stepx_p,
|
||||
pixman_fixed_t *dx_p)
|
||||
{
|
||||
pixman_fixed_t stepx;
|
||||
pixman_fixed_48_16_t ne;
|
||||
|
||||
ne = n * (pixman_fixed_48_16_t) e->dx;
|
||||
stepx = n * e->stepx;
|
||||
|
||||
if (ne > 0)
|
||||
{
|
||||
int nx = ne / e->dy;
|
||||
ne -= nx * e->dy;
|
||||
stepx += nx * e->signdx;
|
||||
}
|
||||
|
||||
*dx_p = ne;
|
||||
*stepx_p = stepx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize one edge structure given the line endpoints and a
|
||||
* starting y value
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_edge_init (pixman_edge_t *e,
|
||||
int n,
|
||||
pixman_fixed_t y_start,
|
||||
pixman_fixed_t x_top,
|
||||
pixman_fixed_t y_top,
|
||||
pixman_fixed_t x_bot,
|
||||
pixman_fixed_t y_bot)
|
||||
{
|
||||
pixman_fixed_t dx, dy;
|
||||
|
||||
e->x = x_top;
|
||||
e->e = 0;
|
||||
dx = x_bot - x_top;
|
||||
dy = y_bot - y_top;
|
||||
e->dy = dy;
|
||||
e->dx = 0;
|
||||
|
||||
if (dy)
|
||||
{
|
||||
if (dx >= 0)
|
||||
{
|
||||
e->signdx = 1;
|
||||
e->stepx = dx / dy;
|
||||
e->dx = dx % dy;
|
||||
e->e = -dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->signdx = -1;
|
||||
e->stepx = -(-dx / dy);
|
||||
e->dx = -dx % dy;
|
||||
e->e = 0;
|
||||
}
|
||||
|
||||
_pixman_edge_multi_init (e, STEP_Y_SMALL (n),
|
||||
&e->stepx_small, &e->dx_small);
|
||||
|
||||
_pixman_edge_multi_init (e, STEP_Y_BIG (n),
|
||||
&e->stepx_big, &e->dx_big);
|
||||
}
|
||||
pixman_edge_step (e, y_start - y_top);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize one edge structure given a line, starting y value
|
||||
* and a pixel offset for the line
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_line_fixed_edge_init (pixman_edge_t * e,
|
||||
int n,
|
||||
pixman_fixed_t y,
|
||||
const pixman_line_fixed_t *line,
|
||||
int x_off,
|
||||
int y_off)
|
||||
{
|
||||
pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off);
|
||||
pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off);
|
||||
const pixman_point_fixed_t *top, *bot;
|
||||
|
||||
if (line->p1.y <= line->p2.y)
|
||||
{
|
||||
top = &line->p1;
|
||||
bot = &line->p2;
|
||||
}
|
||||
else
|
||||
{
|
||||
top = &line->p2;
|
||||
bot = &line->p1;
|
||||
}
|
||||
|
||||
pixman_edge_init (e, n, y,
|
||||
top->x + x_off_fixed,
|
||||
top->y + y_off_fixed,
|
||||
bot->x + x_off_fixed,
|
||||
bot->y + y_off_fixed);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_add_traps (pixman_image_t * image,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
int ntrap,
|
||||
pixman_trap_t * traps)
|
||||
{
|
||||
int bpp;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
pixman_fixed_t x_off_fixed;
|
||||
pixman_fixed_t y_off_fixed;
|
||||
pixman_edge_t l, r;
|
||||
pixman_fixed_t t, b;
|
||||
|
||||
_pixman_image_validate (image);
|
||||
|
||||
width = image->bits.width;
|
||||
height = image->bits.height;
|
||||
bpp = PIXMAN_FORMAT_BPP (image->bits.format);
|
||||
|
||||
x_off_fixed = pixman_int_to_fixed (x_off);
|
||||
y_off_fixed = pixman_int_to_fixed (y_off);
|
||||
|
||||
while (ntrap--)
|
||||
{
|
||||
t = traps->top.y + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = pixman_sample_ceil_y (t, bpp);
|
||||
|
||||
b = traps->bot.y + y_off_fixed;
|
||||
if (pixman_fixed_to_int (b) >= height)
|
||||
b = pixman_int_to_fixed (height) - 1;
|
||||
b = pixman_sample_floor_y (b, bpp);
|
||||
|
||||
if (b >= t)
|
||||
{
|
||||
/* initialize edge walkers */
|
||||
pixman_edge_init (&l, bpp, t,
|
||||
traps->top.l + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.l + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
pixman_edge_init (&r, bpp, t,
|
||||
traps->top.r + x_off_fixed,
|
||||
traps->top.y + y_off_fixed,
|
||||
traps->bot.r + x_off_fixed,
|
||||
traps->bot.y + y_off_fixed);
|
||||
|
||||
pixman_rasterize_edges (image, &l, &r, t, b);
|
||||
}
|
||||
|
||||
traps++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
dump_image (pixman_image_t *image,
|
||||
const char * title)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!image->type == BITS)
|
||||
printf ("%s is not a regular image\n", title);
|
||||
|
||||
if (!image->bits.format == PIXMAN_a8)
|
||||
printf ("%s is not an alpha mask\n", title);
|
||||
|
||||
printf ("\n\n\n%s: \n", title);
|
||||
|
||||
for (i = 0; i < image->bits.height; ++i)
|
||||
{
|
||||
uint8_t *line =
|
||||
(uint8_t *)&(image->bits.bits[i * image->bits.rowstride]);
|
||||
|
||||
for (j = 0; j < image->bits.width; ++j)
|
||||
printf ("%c", line[j] ? '#' : ' ');
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_add_trapezoids (pixman_image_t * image,
|
||||
int16_t x_off,
|
||||
int y_off,
|
||||
int ntraps,
|
||||
const pixman_trapezoid_t *traps)
|
||||
{
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
dump_image (image, "before");
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ntraps; ++i)
|
||||
{
|
||||
const pixman_trapezoid_t *trap = &(traps[i]);
|
||||
|
||||
if (!pixman_trapezoid_valid (trap))
|
||||
continue;
|
||||
|
||||
pixman_rasterize_trapezoid (image, trap, x_off, y_off);
|
||||
}
|
||||
|
||||
#if 0
|
||||
dump_image (image, "after");
|
||||
#endif
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_rasterize_trapezoid (pixman_image_t * image,
|
||||
const pixman_trapezoid_t *trap,
|
||||
int x_off,
|
||||
int y_off)
|
||||
{
|
||||
int bpp;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
pixman_fixed_t x_off_fixed;
|
||||
pixman_fixed_t y_off_fixed;
|
||||
pixman_edge_t l, r;
|
||||
pixman_fixed_t t, b;
|
||||
|
||||
return_if_fail (image->type == BITS);
|
||||
|
||||
_pixman_image_validate (image);
|
||||
|
||||
if (!pixman_trapezoid_valid (trap))
|
||||
return;
|
||||
|
||||
width = image->bits.width;
|
||||
height = image->bits.height;
|
||||
bpp = PIXMAN_FORMAT_BPP (image->bits.format);
|
||||
|
||||
x_off_fixed = pixman_int_to_fixed (x_off);
|
||||
y_off_fixed = pixman_int_to_fixed (y_off);
|
||||
|
||||
t = trap->top + y_off_fixed;
|
||||
if (t < 0)
|
||||
t = 0;
|
||||
t = pixman_sample_ceil_y (t, bpp);
|
||||
|
||||
b = trap->bottom + y_off_fixed;
|
||||
if (pixman_fixed_to_int (b) >= height)
|
||||
b = pixman_int_to_fixed (height) - 1;
|
||||
b = pixman_sample_floor_y (b, bpp);
|
||||
|
||||
if (b >= t)
|
||||
{
|
||||
/* initialize edge walkers */
|
||||
pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off);
|
||||
pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
|
||||
|
||||
pixman_rasterize_edges (image, &l, &r, t, b);
|
||||
}
|
||||
}
|
258
programs/develop/libraries/pixman/pixman-utils.c
Normal file
258
programs/develop/libraries/pixman/pixman-utils.c
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 1999 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Author: Keith Packard, SuSE, Inc.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
pixman_bool_t
|
||||
pixman_multiply_overflows_int (unsigned int a,
|
||||
unsigned int b)
|
||||
{
|
||||
return a >= INT32_MAX / b;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
pixman_addition_overflows_int (unsigned int a,
|
||||
unsigned int b)
|
||||
{
|
||||
return a > INT32_MAX - b;
|
||||
}
|
||||
|
||||
void *
|
||||
pixman_malloc_ab (unsigned int a,
|
||||
unsigned int b)
|
||||
{
|
||||
if (a >= INT32_MAX / b)
|
||||
return NULL;
|
||||
|
||||
return malloc (a * b);
|
||||
}
|
||||
|
||||
void *
|
||||
pixman_malloc_abc (unsigned int a,
|
||||
unsigned int b,
|
||||
unsigned int c)
|
||||
{
|
||||
if (a >= INT32_MAX / b)
|
||||
return NULL;
|
||||
else if (a * b >= INT32_MAX / c)
|
||||
return NULL;
|
||||
else
|
||||
return malloc (a * b * c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper routine to expand a color component from 0 < n <= 8 bits to 16
|
||||
* bits by replication.
|
||||
*/
|
||||
static inline uint64_t
|
||||
expand16 (const uint8_t val, int nbits)
|
||||
{
|
||||
/* Start out with the high bit of val in the high bit of result. */
|
||||
uint16_t result = (uint16_t)val << (16 - nbits);
|
||||
|
||||
if (nbits == 0)
|
||||
return 0;
|
||||
|
||||
/* Copy the bits in result, doubling the number of bits each time, until
|
||||
* we fill all 16 bits.
|
||||
*/
|
||||
while (nbits < 16)
|
||||
{
|
||||
result |= result >> nbits;
|
||||
nbits *= 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function expands images from ARGB8 format to ARGB16. To preserve
|
||||
* precision, it needs to know the original source format. For example, if the
|
||||
* source was PIXMAN_x1r5g5b5 and the red component contained bits 12345, then
|
||||
* the expanded value is 12345123. To correctly expand this to 16 bits, it
|
||||
* should be 1234512345123451 and not 1234512312345123.
|
||||
*/
|
||||
void
|
||||
pixman_expand (uint64_t * dst,
|
||||
const uint32_t * src,
|
||||
pixman_format_code_t format,
|
||||
int width)
|
||||
{
|
||||
/*
|
||||
* Determine the sizes of each component and the masks and shifts
|
||||
* required to extract them from the source pixel.
|
||||
*/
|
||||
const int a_size = PIXMAN_FORMAT_A (format),
|
||||
r_size = PIXMAN_FORMAT_R (format),
|
||||
g_size = PIXMAN_FORMAT_G (format),
|
||||
b_size = PIXMAN_FORMAT_B (format);
|
||||
const int a_shift = 32 - a_size,
|
||||
r_shift = 24 - r_size,
|
||||
g_shift = 16 - g_size,
|
||||
b_shift = 8 - b_size;
|
||||
const uint8_t a_mask = ~(~0 << a_size),
|
||||
r_mask = ~(~0 << r_size),
|
||||
g_mask = ~(~0 << g_size),
|
||||
b_mask = ~(~0 << b_size);
|
||||
int i;
|
||||
|
||||
/* Start at the end so that we can do the expansion in place
|
||||
* when src == dst
|
||||
*/
|
||||
for (i = width - 1; i >= 0; i--)
|
||||
{
|
||||
const uint32_t pixel = src[i];
|
||||
const uint8_t a = (pixel >> a_shift) & a_mask,
|
||||
r = (pixel >> r_shift) & r_mask,
|
||||
g = (pixel >> g_shift) & g_mask,
|
||||
b = (pixel >> b_shift) & b_mask;
|
||||
const uint64_t a16 = a_size ? expand16 (a, a_size) : 0xffff,
|
||||
r16 = expand16 (r, r_size),
|
||||
g16 = expand16 (g, g_size),
|
||||
b16 = expand16 (b, b_size);
|
||||
|
||||
dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Contracting is easier than expanding. We just need to truncate the
|
||||
* components.
|
||||
*/
|
||||
void
|
||||
pixman_contract (uint32_t * dst,
|
||||
const uint64_t *src,
|
||||
int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Start at the beginning so that we can do the contraction in
|
||||
* place when src == dst
|
||||
*/
|
||||
for (i = 0; i < width; i++)
|
||||
{
|
||||
const uint8_t a = src[i] >> 56,
|
||||
r = src[i] >> 40,
|
||||
g = src[i] >> 24,
|
||||
b = src[i] >> 8;
|
||||
|
||||
dst[i] = a << 24 | r << 16 | g << 8 | b;
|
||||
}
|
||||
}
|
||||
|
||||
#define N_TMP_BOXES (16)
|
||||
|
||||
pixman_bool_t
|
||||
pixman_region16_copy_from_region32 (pixman_region16_t *dst,
|
||||
pixman_region32_t *src)
|
||||
{
|
||||
int n_boxes, i;
|
||||
pixman_box32_t *boxes32;
|
||||
pixman_box16_t *boxes16;
|
||||
pixman_bool_t retval;
|
||||
|
||||
boxes32 = pixman_region32_rectangles (src, &n_boxes);
|
||||
|
||||
boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t));
|
||||
|
||||
if (!boxes16)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_boxes; ++i)
|
||||
{
|
||||
boxes16[i].x1 = boxes32[i].x1;
|
||||
boxes16[i].y1 = boxes32[i].y1;
|
||||
boxes16[i].x2 = boxes32[i].x2;
|
||||
boxes16[i].y2 = boxes32[i].y2;
|
||||
}
|
||||
|
||||
pixman_region_fini (dst);
|
||||
retval = pixman_region_init_rects (dst, boxes16, n_boxes);
|
||||
free (boxes16);
|
||||
return retval;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
pixman_region32_copy_from_region16 (pixman_region32_t *dst,
|
||||
pixman_region16_t *src)
|
||||
{
|
||||
int n_boxes, i;
|
||||
pixman_box16_t *boxes16;
|
||||
pixman_box32_t *boxes32;
|
||||
pixman_box32_t tmp_boxes[N_TMP_BOXES];
|
||||
pixman_bool_t retval;
|
||||
|
||||
boxes16 = pixman_region_rectangles (src, &n_boxes);
|
||||
|
||||
if (n_boxes > N_TMP_BOXES)
|
||||
boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t));
|
||||
else
|
||||
boxes32 = tmp_boxes;
|
||||
|
||||
if (!boxes32)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < n_boxes; ++i)
|
||||
{
|
||||
boxes32[i].x1 = boxes16[i].x1;
|
||||
boxes32[i].y1 = boxes16[i].y1;
|
||||
boxes32[i].x2 = boxes16[i].x2;
|
||||
boxes32[i].y2 = boxes16[i].y2;
|
||||
}
|
||||
|
||||
pixman_region32_fini (dst);
|
||||
retval = pixman_region32_init_rects (dst, boxes32, n_boxes);
|
||||
|
||||
if (boxes32 != tmp_boxes)
|
||||
free (boxes32);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
void
|
||||
_pixman_log_error (const char *function, const char *message)
|
||||
{
|
||||
static int n_messages = 0;
|
||||
|
||||
if (n_messages < 10)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"*** BUG ***\n"
|
||||
"In %s: %s\n"
|
||||
"Set a breakpoint on '_pixman_log_error' to debug\n\n",
|
||||
function, message);
|
||||
|
||||
n_messages++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
50
programs/develop/libraries/pixman/pixman-version.h
Normal file
50
programs/develop/libraries/pixman/pixman-version.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_VERSION_H__
|
||||
#define PIXMAN_VERSION_H__
|
||||
|
||||
#ifndef PIXMAN_H__
|
||||
# error pixman-version.h should only be included by pixman.h
|
||||
#endif
|
||||
|
||||
#define PIXMAN_VERSION_MAJOR 0
|
||||
#define PIXMAN_VERSION_MINOR 20
|
||||
#define PIXMAN_VERSION_MICRO 2
|
||||
|
||||
#define PIXMAN_VERSION_STRING "0.20.2"
|
||||
|
||||
#define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \
|
||||
((major) * 10000) \
|
||||
+ ((minor) * 100) \
|
||||
+ ((micro) * 1))
|
||||
|
||||
#define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \
|
||||
PIXMAN_VERSION_MAJOR, \
|
||||
PIXMAN_VERSION_MINOR, \
|
||||
PIXMAN_VERSION_MICRO)
|
||||
|
||||
#endif /* PIXMAN_VERSION_H__ */
|
263
programs/develop/libraries/pixman/pixman-x64-mmx-emulation.h
Normal file
263
programs/develop/libraries/pixman/pixman-x64-mmx-emulation.h
Normal file
@ -0,0 +1,263 @@
|
||||
#ifndef MMX_X64_H_INCLUDED
|
||||
#define MMX_X64_H_INCLUDED
|
||||
|
||||
/* Implementation of x64 MMX substitition functions, before
|
||||
* pixman is reimplemented not to use __m64 type on Visual C++
|
||||
*
|
||||
* Copyright (C)2009 by George Yohng
|
||||
* Released in public domain.
|
||||
*/
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
#define M64C(a) (*(const __m64 *)(&a))
|
||||
#define M64U(a) (*(const unsigned long long *)(&a))
|
||||
|
||||
__inline __m64
|
||||
_m_from_int (int a)
|
||||
{
|
||||
long long i64 = a;
|
||||
|
||||
return M64C (i64);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_mm_setzero_si64 ()
|
||||
{
|
||||
long long i64 = 0;
|
||||
|
||||
return M64C (i64);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_mm_set_pi32 (int i1, int i0)
|
||||
{
|
||||
unsigned long long i64 = ((unsigned)i0) + (((unsigned long long)(unsigned)i1) << 32);
|
||||
|
||||
return M64C (i64);
|
||||
}
|
||||
|
||||
__inline void
|
||||
_m_empty ()
|
||||
{
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_mm_set1_pi16 (short w)
|
||||
{
|
||||
unsigned long long i64 = ((unsigned long long)(unsigned short)(w)) * 0x0001000100010001ULL;
|
||||
|
||||
return M64C (i64);
|
||||
}
|
||||
|
||||
__inline int
|
||||
_m_to_int (__m64 m)
|
||||
{
|
||||
return m.m64_i32[0];
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_mm_movepi64_pi64 (__m128i a)
|
||||
{
|
||||
return M64C (a.m128i_i64[0]);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_pand (__m64 a, __m64 b)
|
||||
{
|
||||
unsigned long long i64 = M64U (a) & M64U (b);
|
||||
|
||||
return M64C (i64);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_por (__m64 a, __m64 b)
|
||||
{
|
||||
unsigned long long i64 = M64U (a) | M64U (b);
|
||||
|
||||
return M64C (i64);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_pxor (__m64 a, __m64 b)
|
||||
{
|
||||
unsigned long long i64 = M64U (a) ^ M64U (b);
|
||||
|
||||
return M64C (i64);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_pmulhuw (__m64 a, __m64 b) /* unoptimized */
|
||||
{
|
||||
unsigned short d[4] =
|
||||
{
|
||||
(unsigned short)((((unsigned)a.m64_u16[0]) * b.m64_u16[0]) >> 16),
|
||||
(unsigned short)((((unsigned)a.m64_u16[1]) * b.m64_u16[1]) >> 16),
|
||||
(unsigned short)((((unsigned)a.m64_u16[2]) * b.m64_u16[2]) >> 16),
|
||||
(unsigned short)((((unsigned)a.m64_u16[3]) * b.m64_u16[3]) >> 16)
|
||||
};
|
||||
|
||||
return M64C (d[0]);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_pmullw2 (__m64 a, __m64 b) /* unoptimized */
|
||||
{
|
||||
unsigned short d[4] =
|
||||
{
|
||||
(unsigned short)((((unsigned)a.m64_u16[0]) * b.m64_u16[0])),
|
||||
(unsigned short)((((unsigned)a.m64_u16[1]) * b.m64_u16[1])),
|
||||
(unsigned short)((((unsigned)a.m64_u16[2]) * b.m64_u16[2])),
|
||||
(unsigned short)((((unsigned)a.m64_u16[3]) * b.m64_u16[3]))
|
||||
};
|
||||
|
||||
return M64C (d[0]);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_pmullw (__m64 a, __m64 b) /* unoptimized */
|
||||
{
|
||||
unsigned long long x =
|
||||
((unsigned long long)(unsigned short)((((unsigned)a.m64_u16[0]) * b.m64_u16[0]))) +
|
||||
(((unsigned long long)(unsigned short)((((unsigned)a.m64_u16[1]) * b.m64_u16[1]))) << 16) +
|
||||
(((unsigned long long)(unsigned short)((((unsigned)a.m64_u16[2]) * b.m64_u16[2]))) << 32) +
|
||||
(((unsigned long long)(unsigned short)((((unsigned)a.m64_u16[3]) * b.m64_u16[3]))) << 48);
|
||||
|
||||
return M64C (x);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_paddusb (__m64 a, __m64 b) /* unoptimized */
|
||||
{
|
||||
unsigned long long x = (M64U (a) & 0x00FF00FF00FF00FFULL) +
|
||||
(M64U (b) & 0x00FF00FF00FF00FFULL);
|
||||
|
||||
unsigned long long y = ((M64U (a) >> 8) & 0x00FF00FF00FF00FFULL) +
|
||||
((M64U (b) >> 8) & 0x00FF00FF00FF00FFULL);
|
||||
|
||||
x |= ((x & 0xFF00FF00FF00FF00ULL) >> 8) * 0xFF;
|
||||
y |= ((y & 0xFF00FF00FF00FF00ULL) >> 8) * 0xFF;
|
||||
|
||||
x = (x & 0x00FF00FF00FF00FFULL) | ((y & 0x00FF00FF00FF00FFULL) << 8);
|
||||
|
||||
return M64C (x);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_paddusw (__m64 a, __m64 b) /* unoptimized */
|
||||
{
|
||||
unsigned long long x = (M64U (a) & 0x0000FFFF0000FFFFULL) +
|
||||
(M64U (b) & 0x0000FFFF0000FFFFULL);
|
||||
|
||||
unsigned long long y = ((M64U (a) >> 16) & 0x0000FFFF0000FFFFULL) +
|
||||
((M64U (b) >> 16) & 0x0000FFFF0000FFFFULL);
|
||||
|
||||
x |= ((x & 0xFFFF0000FFFF0000) >> 16) * 0xFFFF;
|
||||
y |= ((y & 0xFFFF0000FFFF0000) >> 16) * 0xFFFF;
|
||||
|
||||
x = (x & 0x0000FFFF0000FFFFULL) | ((y & 0x0000FFFF0000FFFFULL) << 16);
|
||||
|
||||
return M64C (x);
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_pshufw (__m64 a, int n) /* unoptimized */
|
||||
{
|
||||
unsigned short d[4] =
|
||||
{
|
||||
a.m64_u16[n & 3],
|
||||
a.m64_u16[(n >> 2) & 3],
|
||||
a.m64_u16[(n >> 4) & 3],
|
||||
a.m64_u16[(n >> 6) & 3]
|
||||
};
|
||||
|
||||
return M64C (d[0]);
|
||||
}
|
||||
|
||||
__inline unsigned char
|
||||
sat16 (unsigned short d)
|
||||
{
|
||||
if (d > 0xFF) return 0xFF;
|
||||
else return d & 0xFF;
|
||||
}
|
||||
|
||||
__inline __m64
|
||||
_m_packuswb (__m64 m1, __m64 m2) /* unoptimized */
|
||||
{
|
||||
unsigned char d[8] =
|
||||
{
|
||||
sat16 (m1.m64_u16[0]),
|
||||
sat16 (m1.m64_u16[1]),
|
||||
sat16 (m1.m64_u16[2]),
|
||||
sat16 (m1.m64_u16[3]),
|
||||
sat16 (m2.m64_u16[0]),
|
||||
sat16 (m2.m64_u16[1]),
|
||||
sat16 (m2.m64_u16[2]),
|
||||
sat16 (m2.m64_u16[3])
|
||||
};
|
||||
|
||||
return M64C (d[0]);
|
||||
}
|
||||
|
||||
__inline __m64 _m_punpcklbw (__m64 m1, __m64 m2) /* unoptimized */
|
||||
{
|
||||
unsigned char d[8] =
|
||||
{
|
||||
m1.m64_u8[0],
|
||||
m2.m64_u8[0],
|
||||
m1.m64_u8[1],
|
||||
m2.m64_u8[1],
|
||||
m1.m64_u8[2],
|
||||
m2.m64_u8[2],
|
||||
m1.m64_u8[3],
|
||||
m2.m64_u8[3],
|
||||
};
|
||||
|
||||
return M64C (d[0]);
|
||||
}
|
||||
|
||||
__inline __m64 _m_punpckhbw (__m64 m1, __m64 m2) /* unoptimized */
|
||||
{
|
||||
unsigned char d[8] =
|
||||
{
|
||||
m1.m64_u8[4],
|
||||
m2.m64_u8[4],
|
||||
m1.m64_u8[5],
|
||||
m2.m64_u8[5],
|
||||
m1.m64_u8[6],
|
||||
m2.m64_u8[6],
|
||||
m1.m64_u8[7],
|
||||
m2.m64_u8[7],
|
||||
};
|
||||
|
||||
return M64C (d[0]);
|
||||
}
|
||||
|
||||
__inline __m64 _m_psrlwi (__m64 a, int n) /* unoptimized */
|
||||
{
|
||||
unsigned short d[4] =
|
||||
{
|
||||
a.m64_u16[0] >> n,
|
||||
a.m64_u16[1] >> n,
|
||||
a.m64_u16[2] >> n,
|
||||
a.m64_u16[3] >> n
|
||||
};
|
||||
|
||||
return M64C (d[0]);
|
||||
}
|
||||
|
||||
__inline __m64 _m_psrlqi (__m64 m, int n)
|
||||
{
|
||||
unsigned long long x = M64U (m) >> n;
|
||||
|
||||
return M64C (x);
|
||||
}
|
||||
|
||||
__inline __m64 _m_psllqi (__m64 m, int n)
|
||||
{
|
||||
unsigned long long x = M64U (m) << n;
|
||||
|
||||
return M64C (x);
|
||||
}
|
||||
|
||||
#endif /* MMX_X64_H_INCLUDED */
|
1274
programs/develop/libraries/pixman/pixman.c
Normal file
1274
programs/develop/libraries/pixman/pixman.c
Normal file
File diff suppressed because it is too large
Load Diff
950
programs/develop/libraries/pixman/pixman.h
Normal file
950
programs/develop/libraries/pixman/pixman.h
Normal file
@ -0,0 +1,950 @@
|
||||
/***********************************************************
|
||||
|
||||
Copyright 1987, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of The Open Group shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from The Open Group.
|
||||
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Digital not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
/*
|
||||
* Copyright © 1998, 2004 Keith Packard
|
||||
* Copyright 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_H__
|
||||
#define PIXMAN_H__
|
||||
|
||||
#include <pixman-version.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define PIXMAN_BEGIN_DECLS extern "C" {
|
||||
#define PIXMAN_END_DECLS }
|
||||
#else
|
||||
#define PIXMAN_BEGIN_DECLS
|
||||
#define PIXMAN_END_DECLS
|
||||
#endif
|
||||
|
||||
PIXMAN_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* Standard integers
|
||||
*/
|
||||
|
||||
#if !defined (PIXMAN_DONT_DEFINE_STDINT)
|
||||
|
||||
#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined (__HP_cc)
|
||||
# include <inttypes.h>
|
||||
/* VS 2010 (_MSC_VER 1600) has stdint.h */
|
||||
#elif defined (_MSC_VER) && _MSC_VER < 1600
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#elif defined (_AIX)
|
||||
# include <sys/inttypes.h>
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Boolean
|
||||
*/
|
||||
typedef int pixman_bool_t;
|
||||
|
||||
/*
|
||||
* Fixpoint numbers
|
||||
*/
|
||||
typedef int64_t pixman_fixed_32_32_t;
|
||||
typedef pixman_fixed_32_32_t pixman_fixed_48_16_t;
|
||||
typedef uint32_t pixman_fixed_1_31_t;
|
||||
typedef uint32_t pixman_fixed_1_16_t;
|
||||
typedef int32_t pixman_fixed_16_16_t;
|
||||
typedef pixman_fixed_16_16_t pixman_fixed_t;
|
||||
|
||||
#define pixman_fixed_e ((pixman_fixed_t) 1)
|
||||
#define pixman_fixed_1 (pixman_int_to_fixed(1))
|
||||
#define pixman_fixed_1_minus_e (pixman_fixed_1 - pixman_fixed_e)
|
||||
#define pixman_fixed_minus_1 (pixman_int_to_fixed(-1))
|
||||
#define pixman_fixed_to_int(f) ((int) ((f) >> 16))
|
||||
#define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16))
|
||||
#define pixman_fixed_to_double(f) (double) ((f) / (double) pixman_fixed_1)
|
||||
#define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0))
|
||||
#define pixman_fixed_frac(f) ((f) & pixman_fixed_1_minus_e)
|
||||
#define pixman_fixed_floor(f) ((f) & ~pixman_fixed_1_minus_e)
|
||||
#define pixman_fixed_ceil(f) pixman_fixed_floor ((f) + pixman_fixed_1_minus_e)
|
||||
#define pixman_fixed_fraction(f) ((f) & pixman_fixed_1_minus_e)
|
||||
#define pixman_fixed_mod_2(f) ((f) & (pixman_fixed1 | pixman_fixed_1_minus_e))
|
||||
#define pixman_max_fixed_48_16 ((pixman_fixed_48_16_t) 0x7fffffff)
|
||||
#define pixman_min_fixed_48_16 (-((pixman_fixed_48_16_t) 1 << 31))
|
||||
|
||||
/*
|
||||
* Misc structs
|
||||
*/
|
||||
typedef struct pixman_color pixman_color_t;
|
||||
typedef struct pixman_point_fixed pixman_point_fixed_t;
|
||||
typedef struct pixman_line_fixed pixman_line_fixed_t;
|
||||
typedef struct pixman_vector pixman_vector_t;
|
||||
typedef struct pixman_transform pixman_transform_t;
|
||||
|
||||
struct pixman_color
|
||||
{
|
||||
uint16_t red;
|
||||
uint16_t green;
|
||||
uint16_t blue;
|
||||
uint16_t alpha;
|
||||
};
|
||||
|
||||
struct pixman_point_fixed
|
||||
{
|
||||
pixman_fixed_t x;
|
||||
pixman_fixed_t y;
|
||||
};
|
||||
|
||||
struct pixman_line_fixed
|
||||
{
|
||||
pixman_point_fixed_t p1, p2;
|
||||
};
|
||||
|
||||
/*
|
||||
* Fixed point matrices
|
||||
*/
|
||||
|
||||
struct pixman_vector
|
||||
{
|
||||
pixman_fixed_t vector[3];
|
||||
};
|
||||
|
||||
struct pixman_transform
|
||||
{
|
||||
pixman_fixed_t matrix[3][3];
|
||||
};
|
||||
|
||||
/* forward declaration (sorry) */
|
||||
struct pixman_box16;
|
||||
typedef union pixman_image pixman_image_t;
|
||||
|
||||
void pixman_transform_init_identity (struct pixman_transform *matrix);
|
||||
pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform,
|
||||
struct pixman_vector *vector);
|
||||
pixman_bool_t pixman_transform_point (const struct pixman_transform *transform,
|
||||
struct pixman_vector *vector);
|
||||
pixman_bool_t pixman_transform_multiply (struct pixman_transform *dst,
|
||||
const struct pixman_transform *l,
|
||||
const struct pixman_transform *r);
|
||||
void pixman_transform_init_scale (struct pixman_transform *t,
|
||||
pixman_fixed_t sx,
|
||||
pixman_fixed_t sy);
|
||||
pixman_bool_t pixman_transform_scale (struct pixman_transform *forward,
|
||||
struct pixman_transform *reverse,
|
||||
pixman_fixed_t sx,
|
||||
pixman_fixed_t sy);
|
||||
void pixman_transform_init_rotate (struct pixman_transform *t,
|
||||
pixman_fixed_t cos,
|
||||
pixman_fixed_t sin);
|
||||
pixman_bool_t pixman_transform_rotate (struct pixman_transform *forward,
|
||||
struct pixman_transform *reverse,
|
||||
pixman_fixed_t c,
|
||||
pixman_fixed_t s);
|
||||
void pixman_transform_init_translate (struct pixman_transform *t,
|
||||
pixman_fixed_t tx,
|
||||
pixman_fixed_t ty);
|
||||
pixman_bool_t pixman_transform_translate (struct pixman_transform *forward,
|
||||
struct pixman_transform *reverse,
|
||||
pixman_fixed_t tx,
|
||||
pixman_fixed_t ty);
|
||||
pixman_bool_t pixman_transform_bounds (const struct pixman_transform *matrix,
|
||||
struct pixman_box16 *b);
|
||||
pixman_bool_t pixman_transform_invert (struct pixman_transform *dst,
|
||||
const struct pixman_transform *src);
|
||||
pixman_bool_t pixman_transform_is_identity (const struct pixman_transform *t);
|
||||
pixman_bool_t pixman_transform_is_scale (const struct pixman_transform *t);
|
||||
pixman_bool_t pixman_transform_is_int_translate (const struct pixman_transform *t);
|
||||
pixman_bool_t pixman_transform_is_inverse (const struct pixman_transform *a,
|
||||
const struct pixman_transform *b);
|
||||
|
||||
/*
|
||||
* Floating point matrices
|
||||
*/
|
||||
struct pixman_f_vector
|
||||
{
|
||||
double v[3];
|
||||
};
|
||||
|
||||
struct pixman_f_transform
|
||||
{
|
||||
double m[3][3];
|
||||
};
|
||||
|
||||
pixman_bool_t pixman_transform_from_pixman_f_transform (struct pixman_transform *t,
|
||||
const struct pixman_f_transform *ft);
|
||||
void pixman_f_transform_from_pixman_transform (struct pixman_f_transform *ft,
|
||||
const struct pixman_transform *t);
|
||||
pixman_bool_t pixman_f_transform_invert (struct pixman_f_transform *dst,
|
||||
const struct pixman_f_transform *src);
|
||||
pixman_bool_t pixman_f_transform_point (const struct pixman_f_transform *t,
|
||||
struct pixman_f_vector *v);
|
||||
void pixman_f_transform_point_3d (const struct pixman_f_transform *t,
|
||||
struct pixman_f_vector *v);
|
||||
void pixman_f_transform_multiply (struct pixman_f_transform *dst,
|
||||
const struct pixman_f_transform *l,
|
||||
const struct pixman_f_transform *r);
|
||||
void pixman_f_transform_init_scale (struct pixman_f_transform *t,
|
||||
double sx,
|
||||
double sy);
|
||||
pixman_bool_t pixman_f_transform_scale (struct pixman_f_transform *forward,
|
||||
struct pixman_f_transform *reverse,
|
||||
double sx,
|
||||
double sy);
|
||||
void pixman_f_transform_init_rotate (struct pixman_f_transform *t,
|
||||
double cos,
|
||||
double sin);
|
||||
pixman_bool_t pixman_f_transform_rotate (struct pixman_f_transform *forward,
|
||||
struct pixman_f_transform *reverse,
|
||||
double c,
|
||||
double s);
|
||||
void pixman_f_transform_init_translate (struct pixman_f_transform *t,
|
||||
double tx,
|
||||
double ty);
|
||||
pixman_bool_t pixman_f_transform_translate (struct pixman_f_transform *forward,
|
||||
struct pixman_f_transform *reverse,
|
||||
double tx,
|
||||
double ty);
|
||||
pixman_bool_t pixman_f_transform_bounds (const struct pixman_f_transform *t,
|
||||
struct pixman_box16 *b);
|
||||
void pixman_f_transform_init_identity (struct pixman_f_transform *t);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIXMAN_REPEAT_NONE,
|
||||
PIXMAN_REPEAT_NORMAL,
|
||||
PIXMAN_REPEAT_PAD,
|
||||
PIXMAN_REPEAT_REFLECT
|
||||
} pixman_repeat_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIXMAN_FILTER_FAST,
|
||||
PIXMAN_FILTER_GOOD,
|
||||
PIXMAN_FILTER_BEST,
|
||||
PIXMAN_FILTER_NEAREST,
|
||||
PIXMAN_FILTER_BILINEAR,
|
||||
PIXMAN_FILTER_CONVOLUTION
|
||||
} pixman_filter_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIXMAN_OP_CLEAR = 0x00,
|
||||
PIXMAN_OP_SRC = 0x01,
|
||||
PIXMAN_OP_DST = 0x02,
|
||||
PIXMAN_OP_OVER = 0x03,
|
||||
PIXMAN_OP_OVER_REVERSE = 0x04,
|
||||
PIXMAN_OP_IN = 0x05,
|
||||
PIXMAN_OP_IN_REVERSE = 0x06,
|
||||
PIXMAN_OP_OUT = 0x07,
|
||||
PIXMAN_OP_OUT_REVERSE = 0x08,
|
||||
PIXMAN_OP_ATOP = 0x09,
|
||||
PIXMAN_OP_ATOP_REVERSE = 0x0a,
|
||||
PIXMAN_OP_XOR = 0x0b,
|
||||
PIXMAN_OP_ADD = 0x0c,
|
||||
PIXMAN_OP_SATURATE = 0x0d,
|
||||
|
||||
PIXMAN_OP_DISJOINT_CLEAR = 0x10,
|
||||
PIXMAN_OP_DISJOINT_SRC = 0x11,
|
||||
PIXMAN_OP_DISJOINT_DST = 0x12,
|
||||
PIXMAN_OP_DISJOINT_OVER = 0x13,
|
||||
PIXMAN_OP_DISJOINT_OVER_REVERSE = 0x14,
|
||||
PIXMAN_OP_DISJOINT_IN = 0x15,
|
||||
PIXMAN_OP_DISJOINT_IN_REVERSE = 0x16,
|
||||
PIXMAN_OP_DISJOINT_OUT = 0x17,
|
||||
PIXMAN_OP_DISJOINT_OUT_REVERSE = 0x18,
|
||||
PIXMAN_OP_DISJOINT_ATOP = 0x19,
|
||||
PIXMAN_OP_DISJOINT_ATOP_REVERSE = 0x1a,
|
||||
PIXMAN_OP_DISJOINT_XOR = 0x1b,
|
||||
|
||||
PIXMAN_OP_CONJOINT_CLEAR = 0x20,
|
||||
PIXMAN_OP_CONJOINT_SRC = 0x21,
|
||||
PIXMAN_OP_CONJOINT_DST = 0x22,
|
||||
PIXMAN_OP_CONJOINT_OVER = 0x23,
|
||||
PIXMAN_OP_CONJOINT_OVER_REVERSE = 0x24,
|
||||
PIXMAN_OP_CONJOINT_IN = 0x25,
|
||||
PIXMAN_OP_CONJOINT_IN_REVERSE = 0x26,
|
||||
PIXMAN_OP_CONJOINT_OUT = 0x27,
|
||||
PIXMAN_OP_CONJOINT_OUT_REVERSE = 0x28,
|
||||
PIXMAN_OP_CONJOINT_ATOP = 0x29,
|
||||
PIXMAN_OP_CONJOINT_ATOP_REVERSE = 0x2a,
|
||||
PIXMAN_OP_CONJOINT_XOR = 0x2b,
|
||||
|
||||
PIXMAN_OP_MULTIPLY = 0x30,
|
||||
PIXMAN_OP_SCREEN = 0x31,
|
||||
PIXMAN_OP_OVERLAY = 0x32,
|
||||
PIXMAN_OP_DARKEN = 0x33,
|
||||
PIXMAN_OP_LIGHTEN = 0x34,
|
||||
PIXMAN_OP_COLOR_DODGE = 0x35,
|
||||
PIXMAN_OP_COLOR_BURN = 0x36,
|
||||
PIXMAN_OP_HARD_LIGHT = 0x37,
|
||||
PIXMAN_OP_SOFT_LIGHT = 0x38,
|
||||
PIXMAN_OP_DIFFERENCE = 0x39,
|
||||
PIXMAN_OP_EXCLUSION = 0x3a,
|
||||
PIXMAN_OP_HSL_HUE = 0x3b,
|
||||
PIXMAN_OP_HSL_SATURATION = 0x3c,
|
||||
PIXMAN_OP_HSL_COLOR = 0x3d,
|
||||
PIXMAN_OP_HSL_LUMINOSITY = 0x3e
|
||||
|
||||
#ifdef PIXMAN_USE_INTERNAL_API
|
||||
,
|
||||
PIXMAN_N_OPERATORS,
|
||||
PIXMAN_OP_NONE = PIXMAN_N_OPERATORS
|
||||
#endif
|
||||
} pixman_op_t;
|
||||
|
||||
/*
|
||||
* Regions
|
||||
*/
|
||||
typedef struct pixman_region16_data pixman_region16_data_t;
|
||||
typedef struct pixman_box16 pixman_box16_t;
|
||||
typedef struct pixman_rectangle16 pixman_rectangle16_t;
|
||||
typedef struct pixman_region16 pixman_region16_t;
|
||||
|
||||
struct pixman_region16_data {
|
||||
long size;
|
||||
long numRects;
|
||||
/* pixman_box16_t rects[size]; in memory but not explicitly declared */
|
||||
};
|
||||
|
||||
struct pixman_rectangle16
|
||||
{
|
||||
int16_t x, y;
|
||||
uint16_t width, height;
|
||||
};
|
||||
|
||||
struct pixman_box16
|
||||
{
|
||||
int16_t x1, y1, x2, y2;
|
||||
};
|
||||
|
||||
struct pixman_region16
|
||||
{
|
||||
pixman_box16_t extents;
|
||||
pixman_region16_data_t *data;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIXMAN_REGION_OUT,
|
||||
PIXMAN_REGION_IN,
|
||||
PIXMAN_REGION_PART
|
||||
} pixman_region_overlap_t;
|
||||
|
||||
/* This function exists only to make it possible to preserve
|
||||
* the X ABI - it should go away at first opportunity.
|
||||
*/
|
||||
void pixman_region_set_static_pointers (pixman_box16_t *empty_box,
|
||||
pixman_region16_data_t *empty_data,
|
||||
pixman_region16_data_t *broken_data);
|
||||
|
||||
/* creation/destruction */
|
||||
void pixman_region_init (pixman_region16_t *region);
|
||||
void pixman_region_init_rect (pixman_region16_t *region,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
pixman_bool_t pixman_region_init_rects (pixman_region16_t *region,
|
||||
const pixman_box16_t *boxes,
|
||||
int count);
|
||||
void pixman_region_init_with_extents (pixman_region16_t *region,
|
||||
pixman_box16_t *extents);
|
||||
void pixman_region_init_from_image (pixman_region16_t *region,
|
||||
pixman_image_t *image);
|
||||
void pixman_region_fini (pixman_region16_t *region);
|
||||
|
||||
|
||||
/* manipulation */
|
||||
void pixman_region_translate (pixman_region16_t *region,
|
||||
int x,
|
||||
int y);
|
||||
pixman_bool_t pixman_region_copy (pixman_region16_t *dest,
|
||||
pixman_region16_t *source);
|
||||
pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg,
|
||||
pixman_region16_t *reg1,
|
||||
pixman_region16_t *reg2);
|
||||
pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
|
||||
pixman_region16_t *reg1,
|
||||
pixman_region16_t *reg2);
|
||||
pixman_bool_t pixman_region_union_rect (pixman_region16_t *dest,
|
||||
pixman_region16_t *source,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
pixman_bool_t pixman_region_intersect_rect (pixman_region16_t *dest,
|
||||
pixman_region16_t *source,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
|
||||
pixman_region16_t *reg_m,
|
||||
pixman_region16_t *reg_s);
|
||||
pixman_bool_t pixman_region_inverse (pixman_region16_t *new_reg,
|
||||
pixman_region16_t *reg1,
|
||||
pixman_box16_t *inv_rect);
|
||||
pixman_bool_t pixman_region_contains_point (pixman_region16_t *region,
|
||||
int x,
|
||||
int y,
|
||||
pixman_box16_t *box);
|
||||
pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *region,
|
||||
pixman_box16_t *prect);
|
||||
pixman_bool_t pixman_region_not_empty (pixman_region16_t *region);
|
||||
pixman_box16_t * pixman_region_extents (pixman_region16_t *region);
|
||||
int pixman_region_n_rects (pixman_region16_t *region);
|
||||
pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region,
|
||||
int *n_rects);
|
||||
pixman_bool_t pixman_region_equal (pixman_region16_t *region1,
|
||||
pixman_region16_t *region2);
|
||||
pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region);
|
||||
void pixman_region_reset (pixman_region16_t *region,
|
||||
pixman_box16_t *box);
|
||||
/*
|
||||
* 32 bit regions
|
||||
*/
|
||||
typedef struct pixman_region32_data pixman_region32_data_t;
|
||||
typedef struct pixman_box32 pixman_box32_t;
|
||||
typedef struct pixman_rectangle32 pixman_rectangle32_t;
|
||||
typedef struct pixman_region32 pixman_region32_t;
|
||||
|
||||
struct pixman_region32_data {
|
||||
long size;
|
||||
long numRects;
|
||||
/* pixman_box32_t rects[size]; in memory but not explicitly declared */
|
||||
};
|
||||
|
||||
struct pixman_rectangle32
|
||||
{
|
||||
int32_t x, y;
|
||||
uint32_t width, height;
|
||||
};
|
||||
|
||||
struct pixman_box32
|
||||
{
|
||||
int32_t x1, y1, x2, y2;
|
||||
};
|
||||
|
||||
struct pixman_region32
|
||||
{
|
||||
pixman_box32_t extents;
|
||||
pixman_region32_data_t *data;
|
||||
};
|
||||
|
||||
/* creation/destruction */
|
||||
void pixman_region32_init (pixman_region32_t *region);
|
||||
void pixman_region32_init_rect (pixman_region32_t *region,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
pixman_bool_t pixman_region32_init_rects (pixman_region32_t *region,
|
||||
const pixman_box32_t *boxes,
|
||||
int count);
|
||||
void pixman_region32_init_with_extents (pixman_region32_t *region,
|
||||
pixman_box32_t *extents);
|
||||
void pixman_region32_init_from_image (pixman_region32_t *region,
|
||||
pixman_image_t *image);
|
||||
void pixman_region32_fini (pixman_region32_t *region);
|
||||
|
||||
|
||||
/* manipulation */
|
||||
void pixman_region32_translate (pixman_region32_t *region,
|
||||
int x,
|
||||
int y);
|
||||
pixman_bool_t pixman_region32_copy (pixman_region32_t *dest,
|
||||
pixman_region32_t *source);
|
||||
pixman_bool_t pixman_region32_intersect (pixman_region32_t *new_reg,
|
||||
pixman_region32_t *reg1,
|
||||
pixman_region32_t *reg2);
|
||||
pixman_bool_t pixman_region32_union (pixman_region32_t *new_reg,
|
||||
pixman_region32_t *reg1,
|
||||
pixman_region32_t *reg2);
|
||||
pixman_bool_t pixman_region32_intersect_rect (pixman_region32_t *dest,
|
||||
pixman_region32_t *source,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
pixman_bool_t pixman_region32_union_rect (pixman_region32_t *dest,
|
||||
pixman_region32_t *source,
|
||||
int x,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height);
|
||||
pixman_bool_t pixman_region32_subtract (pixman_region32_t *reg_d,
|
||||
pixman_region32_t *reg_m,
|
||||
pixman_region32_t *reg_s);
|
||||
pixman_bool_t pixman_region32_inverse (pixman_region32_t *new_reg,
|
||||
pixman_region32_t *reg1,
|
||||
pixman_box32_t *inv_rect);
|
||||
pixman_bool_t pixman_region32_contains_point (pixman_region32_t *region,
|
||||
int x,
|
||||
int y,
|
||||
pixman_box32_t *box);
|
||||
pixman_region_overlap_t pixman_region32_contains_rectangle (pixman_region32_t *region,
|
||||
pixman_box32_t *prect);
|
||||
pixman_bool_t pixman_region32_not_empty (pixman_region32_t *region);
|
||||
pixman_box32_t * pixman_region32_extents (pixman_region32_t *region);
|
||||
int pixman_region32_n_rects (pixman_region32_t *region);
|
||||
pixman_box32_t * pixman_region32_rectangles (pixman_region32_t *region,
|
||||
int *n_rects);
|
||||
pixman_bool_t pixman_region32_equal (pixman_region32_t *region1,
|
||||
pixman_region32_t *region2);
|
||||
pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region);
|
||||
void pixman_region32_reset (pixman_region32_t *region,
|
||||
pixman_box32_t *box);
|
||||
|
||||
|
||||
/* Copy / Fill / Misc */
|
||||
pixman_bool_t pixman_blt (uint32_t *src_bits,
|
||||
uint32_t *dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int width,
|
||||
int height);
|
||||
pixman_bool_t pixman_fill (uint32_t *bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t _xor);
|
||||
|
||||
int pixman_version (void);
|
||||
const char* pixman_version_string (void);
|
||||
|
||||
/*
|
||||
* Images
|
||||
*/
|
||||
typedef struct pixman_indexed pixman_indexed_t;
|
||||
typedef struct pixman_gradient_stop pixman_gradient_stop_t;
|
||||
|
||||
typedef uint32_t (* pixman_read_memory_func_t) (const void *src, int size);
|
||||
typedef void (* pixman_write_memory_func_t) (void *dst, uint32_t value, int size);
|
||||
|
||||
typedef void (* pixman_image_destroy_func_t) (pixman_image_t *image, void *data);
|
||||
|
||||
struct pixman_gradient_stop {
|
||||
pixman_fixed_t x;
|
||||
pixman_color_t color;
|
||||
};
|
||||
|
||||
#define PIXMAN_MAX_INDEXED 256 /* XXX depth must be <= 8 */
|
||||
|
||||
#if PIXMAN_MAX_INDEXED <= 256
|
||||
typedef uint8_t pixman_index_type;
|
||||
#endif
|
||||
|
||||
struct pixman_indexed
|
||||
{
|
||||
pixman_bool_t color;
|
||||
uint32_t rgba[PIXMAN_MAX_INDEXED];
|
||||
pixman_index_type ent[32768];
|
||||
};
|
||||
|
||||
/*
|
||||
* While the protocol is generous in format support, the
|
||||
* sample implementation allows only packed RGB and GBR
|
||||
* representations for data to simplify software rendering,
|
||||
*/
|
||||
#define PIXMAN_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \
|
||||
((type) << 16) | \
|
||||
((a) << 12) | \
|
||||
((r) << 8) | \
|
||||
((g) << 4) | \
|
||||
((b)))
|
||||
|
||||
#define PIXMAN_FORMAT_BPP(f) (((f) >> 24) )
|
||||
#define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0xff)
|
||||
#define PIXMAN_FORMAT_A(f) (((f) >> 12) & 0x0f)
|
||||
#define PIXMAN_FORMAT_R(f) (((f) >> 8) & 0x0f)
|
||||
#define PIXMAN_FORMAT_G(f) (((f) >> 4) & 0x0f)
|
||||
#define PIXMAN_FORMAT_B(f) (((f) ) & 0x0f)
|
||||
#define PIXMAN_FORMAT_RGB(f) (((f) ) & 0xfff)
|
||||
#define PIXMAN_FORMAT_VIS(f) (((f) ) & 0xffff)
|
||||
#define PIXMAN_FORMAT_DEPTH(f) (PIXMAN_FORMAT_A(f) + \
|
||||
PIXMAN_FORMAT_R(f) + \
|
||||
PIXMAN_FORMAT_G(f) + \
|
||||
PIXMAN_FORMAT_B(f))
|
||||
|
||||
#define PIXMAN_TYPE_OTHER 0
|
||||
#define PIXMAN_TYPE_A 1
|
||||
#define PIXMAN_TYPE_ARGB 2
|
||||
#define PIXMAN_TYPE_ABGR 3
|
||||
#define PIXMAN_TYPE_COLOR 4
|
||||
#define PIXMAN_TYPE_GRAY 5
|
||||
#define PIXMAN_TYPE_YUY2 6
|
||||
#define PIXMAN_TYPE_YV12 7
|
||||
#define PIXMAN_TYPE_BGRA 8
|
||||
|
||||
#define PIXMAN_FORMAT_COLOR(f) \
|
||||
(PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \
|
||||
PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \
|
||||
PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA)
|
||||
|
||||
/* 32bpp formats */
|
||||
typedef enum {
|
||||
PIXMAN_a8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,8,8,8,8),
|
||||
PIXMAN_x8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8),
|
||||
PIXMAN_a8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8),
|
||||
PIXMAN_x8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,8,8,8),
|
||||
PIXMAN_b8g8r8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,8,8,8,8),
|
||||
PIXMAN_b8g8r8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,0,8,8,8),
|
||||
PIXMAN_x14r6g6b6 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,6,6,6),
|
||||
PIXMAN_x2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,10,10,10),
|
||||
PIXMAN_a2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,2,10,10,10),
|
||||
PIXMAN_x2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,10,10,10),
|
||||
PIXMAN_a2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,2,10,10,10),
|
||||
|
||||
/* 24bpp formats */
|
||||
PIXMAN_r8g8b8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ARGB,0,8,8,8),
|
||||
PIXMAN_b8g8r8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ABGR,0,8,8,8),
|
||||
|
||||
/* 16bpp formats */
|
||||
PIXMAN_r5g6b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,6,5),
|
||||
PIXMAN_b5g6r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,6,5),
|
||||
|
||||
PIXMAN_a1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,1,5,5,5),
|
||||
PIXMAN_x1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,5,5),
|
||||
PIXMAN_a1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,1,5,5,5),
|
||||
PIXMAN_x1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,5,5),
|
||||
PIXMAN_a4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,4,4,4,4),
|
||||
PIXMAN_x4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,4,4,4),
|
||||
PIXMAN_a4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,4,4,4,4),
|
||||
PIXMAN_x4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,4,4,4),
|
||||
|
||||
/* 8bpp formats */
|
||||
PIXMAN_a8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,8,0,0,0),
|
||||
PIXMAN_r3g3b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,0,3,3,2),
|
||||
PIXMAN_b2g3r3 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,0,3,3,2),
|
||||
PIXMAN_a2r2g2b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,2,2,2,2),
|
||||
PIXMAN_a2b2g2r2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,2,2,2,2),
|
||||
|
||||
PIXMAN_c8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0),
|
||||
PIXMAN_g8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0),
|
||||
|
||||
PIXMAN_x4a4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,4,0,0,0),
|
||||
|
||||
PIXMAN_x4c4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0),
|
||||
PIXMAN_x4g4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0),
|
||||
|
||||
/* 4bpp formats */
|
||||
PIXMAN_a4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_A,4,0,0,0),
|
||||
PIXMAN_r1g2b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,0,1,2,1),
|
||||
PIXMAN_b1g2r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,0,1,2,1),
|
||||
PIXMAN_a1r1g1b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,1,1,1,1),
|
||||
PIXMAN_a1b1g1r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,1,1,1,1),
|
||||
|
||||
PIXMAN_c4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_COLOR,0,0,0,0),
|
||||
PIXMAN_g4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_GRAY,0,0,0,0),
|
||||
|
||||
/* 1bpp formats */
|
||||
PIXMAN_a1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_A,1,0,0,0),
|
||||
|
||||
PIXMAN_g1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_GRAY,0,0,0,0),
|
||||
|
||||
/* YUV formats */
|
||||
PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0),
|
||||
PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0)
|
||||
} pixman_format_code_t;
|
||||
|
||||
/* Querying supported format values. */
|
||||
pixman_bool_t pixman_format_supported_destination (pixman_format_code_t format);
|
||||
pixman_bool_t pixman_format_supported_source (pixman_format_code_t format);
|
||||
|
||||
/* Constructors */
|
||||
pixman_image_t *pixman_image_create_solid_fill (pixman_color_t *color);
|
||||
pixman_image_t *pixman_image_create_linear_gradient (pixman_point_fixed_t *p1,
|
||||
pixman_point_fixed_t *p2,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
pixman_image_t *pixman_image_create_radial_gradient (pixman_point_fixed_t *inner,
|
||||
pixman_point_fixed_t *outer,
|
||||
pixman_fixed_t inner_radius,
|
||||
pixman_fixed_t outer_radius,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
pixman_image_t *pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
|
||||
pixman_fixed_t angle,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops);
|
||||
pixman_image_t *pixman_image_create_bits (pixman_format_code_t format,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t *bits,
|
||||
int rowstride_bytes);
|
||||
|
||||
/* Destructor */
|
||||
pixman_image_t *pixman_image_ref (pixman_image_t *image);
|
||||
pixman_bool_t pixman_image_unref (pixman_image_t *image);
|
||||
|
||||
void pixman_image_set_destroy_function (pixman_image_t *image,
|
||||
pixman_image_destroy_func_t function,
|
||||
void *data);
|
||||
void * pixman_image_get_destroy_data (pixman_image_t *image);
|
||||
|
||||
/* Set properties */
|
||||
pixman_bool_t pixman_image_set_clip_region (pixman_image_t *image,
|
||||
pixman_region16_t *region);
|
||||
pixman_bool_t pixman_image_set_clip_region32 (pixman_image_t *image,
|
||||
pixman_region32_t *region);
|
||||
void pixman_image_set_has_client_clip (pixman_image_t *image,
|
||||
pixman_bool_t clien_clip);
|
||||
pixman_bool_t pixman_image_set_transform (pixman_image_t *image,
|
||||
const pixman_transform_t *transform);
|
||||
void pixman_image_set_repeat (pixman_image_t *image,
|
||||
pixman_repeat_t repeat);
|
||||
pixman_bool_t pixman_image_set_filter (pixman_image_t *image,
|
||||
pixman_filter_t filter,
|
||||
const pixman_fixed_t *filter_params,
|
||||
int n_filter_params);
|
||||
void pixman_image_set_source_clipping (pixman_image_t *image,
|
||||
pixman_bool_t source_clipping);
|
||||
void pixman_image_set_alpha_map (pixman_image_t *image,
|
||||
pixman_image_t *alpha_map,
|
||||
int16_t x,
|
||||
int16_t y);
|
||||
void pixman_image_set_component_alpha (pixman_image_t *image,
|
||||
pixman_bool_t component_alpha);
|
||||
pixman_bool_t pixman_image_get_component_alpha (pixman_image_t *image);
|
||||
void pixman_image_set_accessors (pixman_image_t *image,
|
||||
pixman_read_memory_func_t read_func,
|
||||
pixman_write_memory_func_t write_func);
|
||||
void pixman_image_set_indexed (pixman_image_t *image,
|
||||
const pixman_indexed_t *indexed);
|
||||
uint32_t *pixman_image_get_data (pixman_image_t *image);
|
||||
int pixman_image_get_width (pixman_image_t *image);
|
||||
int pixman_image_get_height (pixman_image_t *image);
|
||||
int pixman_image_get_stride (pixman_image_t *image); /* in bytes */
|
||||
int pixman_image_get_depth (pixman_image_t *image);
|
||||
pixman_format_code_t pixman_image_get_format (pixman_image_t *image);
|
||||
pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op,
|
||||
pixman_image_t *image,
|
||||
pixman_color_t *color,
|
||||
int n_rects,
|
||||
const pixman_rectangle16_t *rects);
|
||||
pixman_bool_t pixman_image_fill_boxes (pixman_op_t op,
|
||||
pixman_image_t *dest,
|
||||
pixman_color_t *color,
|
||||
int n_boxes,
|
||||
const pixman_box32_t *boxes);
|
||||
|
||||
/* Composite */
|
||||
pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region,
|
||||
pixman_image_t *src_image,
|
||||
pixman_image_t *mask_image,
|
||||
pixman_image_t *dst_image,
|
||||
int16_t src_x,
|
||||
int16_t src_y,
|
||||
int16_t mask_x,
|
||||
int16_t mask_y,
|
||||
int16_t dest_x,
|
||||
int16_t dest_y,
|
||||
uint16_t width,
|
||||
uint16_t height);
|
||||
void pixman_image_composite (pixman_op_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *mask,
|
||||
pixman_image_t *dest,
|
||||
int16_t src_x,
|
||||
int16_t src_y,
|
||||
int16_t mask_x,
|
||||
int16_t mask_y,
|
||||
int16_t dest_x,
|
||||
int16_t dest_y,
|
||||
uint16_t width,
|
||||
uint16_t height);
|
||||
void pixman_image_composite32 (pixman_op_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *mask,
|
||||
pixman_image_t *dest,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t mask_x,
|
||||
int32_t mask_y,
|
||||
int32_t dest_x,
|
||||
int32_t dest_y,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
|
||||
/* Old X servers rely on out-of-bounds accesses when they are asked
|
||||
* to composite with a window as the source. They create a pixman image
|
||||
* pointing to some bogus position in memory, but then they set a clip
|
||||
* region to the position where the actual bits are.
|
||||
*
|
||||
* Due to a bug in old versions of pixman, where it would not clip
|
||||
* against the image bounds when a clip region was set, this would
|
||||
* actually work. So by default we allow certain out-of-bound access
|
||||
* to happen unless explicitly disabled.
|
||||
*
|
||||
* Fixed X servers should call this function to disable the workaround.
|
||||
*/
|
||||
void pixman_disable_out_of_bounds_workaround (void);
|
||||
|
||||
/*
|
||||
* Trapezoids
|
||||
*/
|
||||
typedef struct pixman_edge pixman_edge_t;
|
||||
typedef struct pixman_trapezoid pixman_trapezoid_t;
|
||||
typedef struct pixman_trap pixman_trap_t;
|
||||
typedef struct pixman_span_fix pixman_span_fix_t;
|
||||
|
||||
/*
|
||||
* An edge structure. This represents a single polygon edge
|
||||
* and can be quickly stepped across small or large gaps in the
|
||||
* sample grid
|
||||
*/
|
||||
struct pixman_edge
|
||||
{
|
||||
pixman_fixed_t x;
|
||||
pixman_fixed_t e;
|
||||
pixman_fixed_t stepx;
|
||||
pixman_fixed_t signdx;
|
||||
pixman_fixed_t dy;
|
||||
pixman_fixed_t dx;
|
||||
|
||||
pixman_fixed_t stepx_small;
|
||||
pixman_fixed_t stepx_big;
|
||||
pixman_fixed_t dx_small;
|
||||
pixman_fixed_t dx_big;
|
||||
};
|
||||
|
||||
struct pixman_trapezoid
|
||||
{
|
||||
pixman_fixed_t top, bottom;
|
||||
pixman_line_fixed_t left, right;
|
||||
};
|
||||
|
||||
|
||||
/* whether 't' is a well defined not obviously empty trapezoid */
|
||||
#define pixman_trapezoid_valid(t) \
|
||||
((t)->left.p1.y != (t)->left.p2.y && \
|
||||
(t)->right.p1.y != (t)->right.p2.y && \
|
||||
(int) ((t)->bottom - (t)->top) > 0)
|
||||
|
||||
struct pixman_span_fix
|
||||
{
|
||||
pixman_fixed_t l, r, y;
|
||||
};
|
||||
|
||||
struct pixman_trap
|
||||
{
|
||||
pixman_span_fix_t top, bot;
|
||||
};
|
||||
|
||||
pixman_fixed_t pixman_sample_ceil_y (pixman_fixed_t y,
|
||||
int bpp);
|
||||
pixman_fixed_t pixman_sample_floor_y (pixman_fixed_t y,
|
||||
int bpp);
|
||||
void pixman_edge_step (pixman_edge_t *e,
|
||||
int n);
|
||||
void pixman_edge_init (pixman_edge_t *e,
|
||||
int bpp,
|
||||
pixman_fixed_t y_start,
|
||||
pixman_fixed_t x_top,
|
||||
pixman_fixed_t y_top,
|
||||
pixman_fixed_t x_bot,
|
||||
pixman_fixed_t y_bot);
|
||||
void pixman_line_fixed_edge_init (pixman_edge_t *e,
|
||||
int bpp,
|
||||
pixman_fixed_t y,
|
||||
const pixman_line_fixed_t *line,
|
||||
int x_off,
|
||||
int y_off);
|
||||
void pixman_rasterize_edges (pixman_image_t *image,
|
||||
pixman_edge_t *l,
|
||||
pixman_edge_t *r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b);
|
||||
void pixman_add_traps (pixman_image_t *image,
|
||||
int16_t x_off,
|
||||
int16_t y_off,
|
||||
int ntrap,
|
||||
pixman_trap_t *traps);
|
||||
void pixman_add_trapezoids (pixman_image_t *image,
|
||||
int16_t x_off,
|
||||
int y_off,
|
||||
int ntraps,
|
||||
const pixman_trapezoid_t *traps);
|
||||
void pixman_rasterize_trapezoid (pixman_image_t *image,
|
||||
const pixman_trapezoid_t *trap,
|
||||
int x_off,
|
||||
int y_off);
|
||||
|
||||
PIXMAN_END_DECLS
|
||||
|
||||
#endif /* PIXMAN_H__ */
|
173
programs/develop/libraries/pixman/test/window-test.c
Normal file
173
programs/develop/libraries/pixman/test/window-test.c
Normal file
@ -0,0 +1,173 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <config.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/* Randomly decide between 32 and 16 bit
|
||||
*
|
||||
* Allocate bits with random width, stride and height
|
||||
*
|
||||
* Then make up some random offset (dx, dy)
|
||||
*
|
||||
* Then make an image with those values.
|
||||
*
|
||||
* Do this for both source and destination
|
||||
*
|
||||
* Composite them together using OVER.
|
||||
*
|
||||
* The bits in the source and the destination should have
|
||||
* recognizable colors so that the result can be verified.
|
||||
*
|
||||
* Ie., walk the bits and verify that they have been composited.
|
||||
*/
|
||||
|
||||
static int
|
||||
get_rand (int bound)
|
||||
{
|
||||
return rand () % bound;
|
||||
}
|
||||
|
||||
static pixman_image_t *
|
||||
make_image (int width, int height, pixman_bool_t src, int *rx, int *ry)
|
||||
{
|
||||
pixman_format_code_t format;
|
||||
pixman_image_t *image;
|
||||
pixman_region32_t region;
|
||||
uint8_t *bits;
|
||||
int stride;
|
||||
int bpp;
|
||||
int dx, dy;
|
||||
int i, j;
|
||||
|
||||
if (src)
|
||||
format = PIXMAN_a8r8g8b8;
|
||||
else
|
||||
format = PIXMAN_r5g6b5;
|
||||
|
||||
bpp = PIXMAN_FORMAT_BPP (format) / 8;
|
||||
|
||||
stride = width + get_rand (width);
|
||||
stride += (stride & 1); /* Make it an even number */
|
||||
|
||||
bits = malloc (height * stride * bpp);
|
||||
|
||||
for (j = 0; j < height; ++j)
|
||||
{
|
||||
for (i = 0; i < width; ++i)
|
||||
{
|
||||
uint8_t *pixel = bits + (stride * j + i) * bpp;
|
||||
|
||||
if (src)
|
||||
*(uint32_t *)pixel = 0x7f00007f;
|
||||
else
|
||||
*(uint16_t *)pixel = 0xf100;
|
||||
}
|
||||
}
|
||||
|
||||
dx = dy = 0;
|
||||
|
||||
dx = get_rand (500);
|
||||
dy = get_rand (500);
|
||||
|
||||
if (!src)
|
||||
{
|
||||
/* Now simulate the bogus X server translations */
|
||||
bits -= (dy * stride + dx) * bpp;
|
||||
}
|
||||
|
||||
image = pixman_image_create_bits (
|
||||
format, width, height, (uint32_t *)bits, stride * bpp);
|
||||
|
||||
if (!src)
|
||||
{
|
||||
/* And add the bogus clip region */
|
||||
pixman_region32_init_rect (®ion, dx, dy, dx + width, dy + height);
|
||||
|
||||
pixman_image_set_clip_region32 (image, ®ion);
|
||||
}
|
||||
|
||||
pixman_image_set_source_clipping (image, TRUE);
|
||||
|
||||
if (src)
|
||||
{
|
||||
pixman_transform_t trans;
|
||||
|
||||
pixman_transform_init_identity (&trans);
|
||||
|
||||
pixman_transform_translate (&trans,
|
||||
NULL,
|
||||
- pixman_int_to_fixed (width / 2),
|
||||
- pixman_int_to_fixed (height / 2));
|
||||
|
||||
pixman_transform_scale (&trans,
|
||||
NULL,
|
||||
pixman_double_to_fixed (0.5),
|
||||
pixman_double_to_fixed (0.5));
|
||||
|
||||
pixman_transform_translate (&trans,
|
||||
NULL,
|
||||
pixman_int_to_fixed (width / 2),
|
||||
pixman_int_to_fixed (height / 2));
|
||||
|
||||
pixman_image_set_transform (image, &trans);
|
||||
pixman_image_set_filter (image, PIXMAN_FILTER_BILINEAR, NULL, 0);
|
||||
pixman_image_set_repeat (image, PIXMAN_REPEAT_PAD);
|
||||
}
|
||||
|
||||
if (!src)
|
||||
{
|
||||
*rx = dx;
|
||||
*ry = dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rx = *ry = 0;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
pixman_image_t *src, *dest;
|
||||
int src_x, src_y, dest_x, dest_y;
|
||||
int i, j;
|
||||
int width = get_rand (499) + 1;
|
||||
int height = get_rand (499) + 1;
|
||||
|
||||
src = make_image (width, height, TRUE, &src_x, &src_y);
|
||||
dest = make_image (width, height, FALSE, &dest_x, &dest_y);
|
||||
|
||||
pixman_image_composite (
|
||||
PIXMAN_OP_OVER, src, NULL, dest,
|
||||
src_x, src_y,
|
||||
-1, -1,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
for (i = 0; i < height; ++i)
|
||||
{
|
||||
for (j = 0; j < width; ++j)
|
||||
{
|
||||
uint8_t *bits = (uint8_t *)dest->bits.bits;
|
||||
int bpp = PIXMAN_FORMAT_BPP (dest->bits.format) / 8;
|
||||
int stride = dest->bits.rowstride * 4;
|
||||
|
||||
uint8_t *pixel =
|
||||
bits + (i + dest_y) * stride + (j + dest_x) * bpp;
|
||||
|
||||
if (*(uint16_t *)pixel != 0x788f)
|
||||
{
|
||||
printf ("bad pixel %x\n", *(uint16_t *)pixel);
|
||||
assert (*(uint16_t *)pixel == 0x788f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user