[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

pixman: Changes to 'upstream-unstable'



 .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 <sandmann@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 <sandmann@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 <sandmann@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 <jmuizelaar@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 <jmuizelaar@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 <chris@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 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@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 <chris@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 <aplattner@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 <jmuizelaar@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 <jmuizelaar@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 <keithp@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 <keithp@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 <keithp@keithp.com>
Date:   Mon Nov 24 11:49:32 2008 -0800

    Move matrix operations from X server to pixman
    
    Signed-off-by: Keith Packard <keithp@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;


Reply to: