.gitignore | 6 Makefile.am | 25 RELEASING | 79 TODO | 80 configure.ac | 228 + pixman-1-uninstalled.pc.in | 5 pixman/Makefile.am | 64 pixman/Makefile.win32 | 86 pixman/combine.h.inc | 213 + pixman/combine.inc | 1269 +++++++++++ pixman/combine.pl | 81 pixman/pixman-access.c | 328 ++ pixman/pixman-arm-simd.c | 409 +++ pixman/pixman-arm-simd.h | 94 pixman/pixman-combine.c | 1260 ---------- pixman/pixman-compose.c | 249 +- pixman/pixman-compute-region.c | 105 pixman/pixman-edge.c | 2 pixman/pixman-image.c | 195 + pixman/pixman-matrix.c | 626 +++++ pixman/pixman-mmx.c | 167 - pixman/pixman-pict.c | 609 ++++- pixman/pixman-private.h | 352 +-- pixman/pixman-region.c | 837 +------ pixman/pixman-region16.c | 83 pixman/pixman-region32.c | 73 pixman/pixman-source.c | 28 pixman/pixman-sse.c | 51 pixman/pixman-sse.h | 53 pixman/pixman-sse2.c | 4717 +++++++++++++++++++++++++++++++++++++++++ pixman/pixman-sse2.h | 358 +++ pixman/pixman-transformed.c | 761 ++---- pixman/pixman-trap.c | 16 pixman/pixman-utils.c | 116 - pixman/pixman-vmx.c | 1064 +++++++++ pixman/pixman-vmx.h | 308 ++ pixman/pixman.h | 606 +++-- test/Makefile.am | 8 test/clip-test.c | 159 + test/region-test.c | 23 40 files changed, 12381 insertions(+), 3412 deletions(-)
New commits: commit 6df6a43dc7119a510cf9db2e62fcc970a539e5a3 Author: Søren Sandmann Pedersen <sandm...@redhat.com> Date: Fri Feb 6 17:31:32 2009 -0500 Bump version number pre release diff --git a/configure.ac b/configure.ac index 0dd055e..fa64800 100644 --- a/configure.ac +++ b/configure.ac @@ -53,8 +53,8 @@ AC_PREREQ([2.57]) # m4_define([pixman_major], 0) -m4_define([pixman_minor], 13) -m4_define([pixman_micro], 3) +m4_define([pixman_minor], 14) +m4_define([pixman_micro], 0) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) commit 6e6c7ac5e0bce2e1893675eb45a8d98876085794 Author: Søren Sandmann Pedersen <sandm...@redhat.com> Date: Fri Feb 6 17:30:24 2009 -0500 Comment out SrcScaledNearest optimization that hasn't been tested much diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c index 42a0454..6c43208 100644 --- a/pixman/pixman-pict.c +++ b/pixman/pixman-pict.c @@ -1208,18 +1208,18 @@ fbCompositeSrc_8888xx888 (pixman_op_t op, } static void -fbCompositeSrcScaleNearest (pixman_op_t op, - pixman_image_t * pSrc, - pixman_image_t * pMask, - pixman_image_t * pDst, - int16_t xSrc, - int16_t ySrc, - int16_t xMask, - int16_t yMask, - int16_t xDst, - int16_t yDst, - uint16_t width, - uint16_t height) +fbCompositeSrcScaleNearest (pixman_op_t op, + pixman_image_t *pSrc, + pixman_image_t *pMask, + pixman_image_t *pDst, + int16_t xSrc, + int16_t ySrc, + int16_t xMask, + int16_t yMask, + int16_t xDst, + int16_t yDst, + uint16_t width, + uint16_t height) { uint32_t *dst; uint32_t *src; @@ -1941,6 +1941,7 @@ pixman_image_composite (pixman_op_t op, if(op == PIXMAN_OP_DST) return; +#if 0 if (pSrc->type == BITS && srcTransform && !pMask @@ -1961,7 +1962,9 @@ pixman_image_composite (pixman_op_t op, pSrc->common.transform->matrix[2][2] == pixman_fixed_1) { func = fbCompositeSrcScaleNearest; } - } else if ((pSrc->type == BITS || pixman_image_can_get_solid (pSrc)) && (!pMask || pMask->type == BITS) + } else +#endif + if ((pSrc->type == BITS || pixman_image_can_get_solid (pSrc)) && (!pMask || pMask->type == BITS) && !srcTransform && !maskTransform && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap && (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION) commit e651118b67111d36193f55a752d13e66df5ca953 Author: Søren Sandmann Pedersen <sandm...@redhat.com> Date: Fri Feb 6 17:29:04 2009 -0500 Fix release targets to remove all hashfiles before generating tar balls diff --git a/Makefile.am b/Makefile.am index 2cf692d..3fbff14 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,8 @@ $(gpg_file): $(sha1_tgz) @echo "Please enter your GPG password to sign the checksum." gpg --armor --sign $^ +HASHFILES = $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(md5_tbz2) + release-verify-newer: @echo -n "Checking that no $(VERSION) release already exists at $(RELEASE_XORG_HOST)..." @ssh $(RELEASE_XORG_HOST) test ! -e $(RELEASE_XORG_DIR)/$(tar_gz) \ @@ -61,16 +63,16 @@ release-verify-newer: @echo "Good." release-remove-old: - $(RM) $(tar_gz) $(tar_bz2) $(sha1_tgz) $(gpg_file) + $(RM) $(tar_gz) $(tar_bz2) $(HASHFILES) $(gpg_file) ensure-prev: @if [[ "$(PREV)" == "" ]]; then \ echo "" && \ echo "You must set the PREV variable on the make command line to" && \ - echo "the last version." && \ + echo "the last version." && \ echo "" && \ echo "For example:" && \ - echo " make PREV=0.7.3" && \ + echo " make PREV=0.7.3" && \ echo "" && \ false; \ fi @@ -80,13 +82,13 @@ release-check: ensure-prev release-verify-newer release-remove-old distcheck release-tag: git-tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION) -release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(gpg_file) +release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(gpg_file) mkdir -p releases scp $(tar_gz) $(sha1_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR) scp $(tar_gz) $(tar_bz2) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR) ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)" -release-publish-message: $(sha1_tgz) $(md5_tgz) $(sha1_tbz2) $(md5_tbz2) ensure-prev +release-publish-message: $(HASHFILES) ensure-prev @echo "Please follow the instructions in RELEASING to push stuff out and" @echo "send out the announcement mails. Here is the excerpt you need:" @echo "" commit 072d848f592530973f1f0a0066a320ec5965625c Author: Jeff Muizelaar <jmuizel...@mozilla.com> Date: Fri Jan 9 12:48:22 2009 -0500 Add pixman-matrix.c to Makefile.win32 diff --git a/pixman/Makefile.win32 b/pixman/Makefile.win32 index ad30f8c..208bb2e 100644 --- a/pixman/Makefile.win32 +++ b/pixman/Makefile.win32 @@ -49,6 +49,7 @@ SOURCES = \ pixman-trap.c \ pixman-compute-region.c \ pixman-timer.c \ + pixman-matrix.c \ $(NULL) # MMX compilation flags commit c55db2905706ae78364bfb63dcfa62c00cc486c7 Author: Jeff Muizelaar <jmuizel...@mozilla.com> Date: Fri Jan 9 12:48:20 2009 -0500 Conditionally include config.h in pixman-matrix.c to fix win32 build diff --git a/pixman/pixman-matrix.c b/pixman/pixman-matrix.c index fb1e49a..8e3a3c0 100644 --- a/pixman/pixman-matrix.c +++ b/pixman/pixman-matrix.c @@ -24,7 +24,10 @@ * Matrix interfaces */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include <math.h> #include <string.h> #include "pixman-private.h" commit 8f98ffadf58de1e28294b3ab2c09f380ccc535e5 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Sat Dec 20 17:18:51 2008 +0000 Fix pixman-1-uninstalled.pc to point to the libtool library Otherwise we fail to link when compiling cairo against the uninstalled library. diff --git a/pixman-1-uninstalled.pc.in b/pixman-1-uninstalled.pc.in index 9a2afa1..e0347d0 100644 --- a/pixman-1-uninstalled.pc.in +++ b/pixman-1-uninstalled.pc.in @@ -1,11 +1,5 @@ -pref...@prefix@ -exec_pref...@exec_prefix@ -libd...@libdir@ -included...@includedir@ - Name: Pixman Description: The pixman library (version 1) Version: @PACKAGE_VERSION@ Cflags: -I${pc_top_builddir}/${pcfiledir}/pixman -Libs: ${pc_top_builddir}/${pcfiledir}/libpixman-1-so.a - +Libs: ${pc_top_builddir}/${pcfiledir}/pixman/libpixman-1.la commit 9d726712c22d8555d00b9f1ebacd5425dc9a5b61 Author: Chris Wilson <ch...@chris-wilson.co.uk> Date: Fri Nov 21 01:20:38 2008 +0000 Allocate initial array of RegionInfo on the stack. The region validate() code is frequently called by cairo as it is used to extract regions from the trapezoids for fast-paths through the drawing code and also for fast-path clipping and the RegionInfo allocation (as well as the pixman_rect_alloc during the final union) appears as a hot spot on application memory profiles. diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c index 3718d65..01a28be 100644 --- a/pixman/pixman-region.c +++ b/pixman/pixman-region.c @@ -1330,6 +1330,8 @@ validate (region_type_t * badreg, int curBand; } RegionInfo; + RegionInfo stack_regions[64]; + int numRects; /* Original numRects for badreg */ RegionInfo *ri; /* Array of current regions */ int numRI; /* Number of entries used in ri */ @@ -1379,10 +1381,8 @@ validate (region_type_t * badreg, /* Set up the first region to be the first rectangle in badreg */ /* Note that step 2 code will never overflow the ri[0].reg rects array */ - ri = (RegionInfo *) pixman_malloc_ab (4, sizeof(RegionInfo)); - if (!ri) - return pixman_break (badreg); - sizeRI = 4; + ri = stack_regions; + sizeRI = sizeof (stack_regions) / sizeof (stack_regions[0]); numRI = 1; ri[0].prevBand = 0; ri[0].curBand = 0; @@ -1451,9 +1451,16 @@ validate (region_type_t * badreg, data_size = sizeRI * sizeof(RegionInfo); if (data_size / sizeRI != sizeof(RegionInfo)) goto bail; - rit = (RegionInfo *) realloc(ri, data_size); - if (!rit) - goto bail; + if (ri == stack_regions) { + rit = malloc (data_size); + if (!rit) + goto bail; + memcpy (rit, ri, numRI * sizeof (RegionInfo)); + } else { + rit = (RegionInfo *) realloc(ri, data_size); + if (!rit) + goto bail; + } ri = rit; rit = &ri[numRI]; } @@ -1509,13 +1516,15 @@ NextRect: ; goto bail; } *badreg = ri[0].reg; - free(ri); + if (ri != stack_regions) + free(ri); good(badreg); return ret; bail: for (i = 0; i < numRI; i++) freeData(&ri[i].reg); - free (ri); + if (ri != stack_regions) + free (ri); return pixman_break (badreg); } commit 08530f5bf23386355a19b83db88173302c7a5300 Author: Aaron Plattner <aplatt...@nvidia.com> Date: Wed Dec 17 10:35:03 2008 -0800 Don't treat PIXMAN_TYPE_YUY2 and PIXMAN_TYPE_YV12 as PIXMAN_FORMAT_COLOR. Various pieces of code expect PIXMAN_FORMAT_COLOR (and its less cool older brother, PICT_FORMAT_COLOR) formats to have ARGB bits, and the YUV formats do not. diff --git a/pixman/pixman.h b/pixman/pixman.h index 6c523f2..49c39d5 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -648,7 +648,9 @@ struct pixman_indexed #define PIXMAN_TYPE_YUY2 6 #define PIXMAN_TYPE_YV12 7 -#define PIXMAN_FORMAT_COLOR(f) (PIXMAN_FORMAT_TYPE(f) & 2) +#define PIXMAN_FORMAT_COLOR(f) \ + (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \ + PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR) /* 32bpp formats */ typedef enum { commit 4546234c18f5bb5e2d193d2fa8ff5c3ca78bc716 Author: Jeff Muizelaar <jmuizel...@mozilla.com> Date: Fri Dec 5 12:01:03 2008 -0500 [arm-simd] Add a comment about aligning source and destination pointers. diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c index f595325..ceef1a8 100644 --- a/pixman/pixman-arm-simd.c +++ b/pixman/pixman-arm-simd.c @@ -60,6 +60,8 @@ fbCompositeSrcAdd_8000x8000arm (pixman_op_t op, srcLine += srcStride; w = width; + /* ensure both src and dst are properly aligned before doing 32 bit reads + * we'll stay in this loop if src and dst have differing alignments */ while (w && (((unsigned long)dst & 3) || ((unsigned long)src & 3))) { s = *src; commit 985829f26b15aaa3e336127412c771027577313f Author: Jeff Muizelaar <jmuizel...@mozilla.com> Date: Fri Dec 5 11:45:03 2008 -0500 Check alignment of 'src' pointer in optimized ARM routines fbCompositeSrcAdd_8000x8000arm() tries to align 'dst' already but must check 'src' too. Otherwise, the next 4-byte copy loop might access an odd 'src' address causing an alignment trap. Patch from Enrico Scholz diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c index 8aa81d2..f595325 100644 --- a/pixman/pixman-arm-simd.c +++ b/pixman/pixman-arm-simd.c @@ -60,7 +60,7 @@ fbCompositeSrcAdd_8000x8000arm (pixman_op_t op, srcLine += srcStride; w = width; - while (w && (unsigned long)dst & 3) + while (w && (((unsigned long)dst & 3) || ((unsigned long)src & 3))) { s = *src; d = *dst; commit bfa76d47ac85c88fbb9d7226f09c6c6654b10342 Author: Keith Packard <kei...@keithp.com> Date: Tue Nov 25 22:03:55 2008 -0800 Bump to 0.13.3 after 0.13.2 release diff --git a/configure.ac b/configure.ac index 063f6eb..0dd055e 100644 --- a/configure.ac +++ b/configure.ac @@ -54,7 +54,7 @@ AC_PREREQ([2.57]) m4_define([pixman_major], 0) m4_define([pixman_minor], 13) -m4_define([pixman_micro], 2) +m4_define([pixman_micro], 3) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) commit 0191d1a41ea273e5b1920ed83dfa33820870ebae Author: Keith Packard <kei...@keithp.com> Date: Tue Nov 25 21:37:54 2008 -0800 Bump version to 0.13.2 for release diff --git a/configure.ac b/configure.ac index 7937f95..063f6eb 100644 --- a/configure.ac +++ b/configure.ac @@ -54,7 +54,7 @@ AC_PREREQ([2.57]) m4_define([pixman_major], 0) m4_define([pixman_minor], 13) -m4_define([pixman_micro], 1) +m4_define([pixman_micro], 2) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) commit 6002963ea32d05592da05a6eeafd5d8ee9d9d496 Author: Keith Packard <kei...@keithp.com> Date: Mon Nov 24 11:49:32 2008 -0800 Move matrix operations from X server to pixman Signed-off-by: Keith Packard <kei...@keithp.com> diff --git a/pixman/Makefile.am b/pixman/Makefile.am index 6d5a643..c4612ea 100644 --- a/pixman/Makefile.am +++ b/pixman/Makefile.am @@ -26,7 +26,8 @@ libpixman_1_la_SOURCES = \ pixman-edge-imp.h \ pixman-trap.c \ pixman-compute-region.c \ - pixman-timer.c + pixman-timer.c \ + pixman-matrix.c libpixmanincludedir = $(includedir)/pixman-1/ libpixmaninclude_HEADERS = pixman.h pixman-version.h diff --git a/pixman/pixman-matrix.c b/pixman/pixman-matrix.c new file mode 100644 index 0000000..fb1e49a --- /dev/null +++ b/pixman/pixman-matrix.c @@ -0,0 +1,623 @@ +/* + * 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 + */ + +#include "config.h" +#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]) + 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; -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org