.gitignore                  |    6 
 TODO                        |    4 
 configure.ac                |   42 ++
 pixman/Makefile.am          |   15 -
 pixman/combine.h.inc        |   50 +--
 pixman/combine.inc          |   34 +-
 pixman/combine.pl           |    4 
 pixman/pixman-access.c      |    2 
 pixman/pixman-arm-simd.c    |  407 ++++++++++++++++++++++++++++
 pixman/pixman-arm-simd.h    |   94 ++++++
 pixman/pixman-compose.c     |   10 
 pixman/pixman-matrix.c      |  623 ++++++++++++++++++++++++++++++++++++++++++++
 pixman/pixman-mmx.c         |   47 +--
 pixman/pixman-pict.c        |  244 ++++++++++++++++-
 pixman/pixman-private.h     |   11 
 pixman/pixman-region.c      |    9 
 pixman/pixman-sse2.c        |  169 +++++------
 pixman/pixman-transformed.c |  600 ++++++++++++++----------------------------
 pixman/pixman-utils.c       |   90 ++----
 pixman/pixman-vmx.c         |   16 -
 pixman/pixman.h             |  152 ++++++++++
 21 files changed, 1978 insertions(+), 651 deletions(-)

New commits:
commit bfa76d47ac85c88fbb9d7226f09c6c6654b10342
Author: Keith Packard <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
Date:   Mon Nov 24 11:49:32 2008 -0800

    Move matrix operations from X server to pixman
    
    Signed-off-by: Keith Packard <[EMAIL PROTECTED]>

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;
+}
+
+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;
+}
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index adb3e20..6e04df6 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -31,38 +31,6 @@
 #include "pixman-mmx.h"
 #include "pixman-sse2.h"
 
-PIXMAN_EXPORT pixman_bool_t
-pixman_transform_point_3d (pixman_transform_t *transform,
-                          pixman_vector_t *vector)
-{
-    pixman_vector_t            result;
-    int                                i, j;
-    pixman_fixed_32_32_t       partial;
-    pixman_fixed_48_16_t       v;
-
-    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_48_16_t) v;
-    }
-
-    if (!result.vector[2])
-       return FALSE;
-
-    *vector = result;
-    return TRUE;
-}
-
 #if defined(USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && 
!defined(__amd64__)
 __attribute__((__force_align_arg_pointer__))
 #endif
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 26ed0cb..6c523f2 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -149,6 +149,10 @@ struct pixman_line_fixed
     pixman_point_fixed_t       p1, p2;
 };
 
+/*
+ * Fixed point matrices
+ */
+
 struct pixman_vector
 {
     pixman_fixed_t     vector[3];
@@ -159,6 +163,149 @@ struct pixman_transform
     pixman_fixed_t     matrix[3][3];
 };
 
+/* forward declaration (sorry) */
+struct pixman_box16;
+
+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_transform_from_pixman_f_transform (struct pixman_transform *t,
+                                         const struct pixman_f_transform *ft);
+
+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);
+
 /* Don't blame me, blame XRender */
 typedef enum
 {
@@ -436,9 +583,6 @@ pixman_bool_t pixman_fill               (uint32_t           
*bits,
                                         int                 height,
                                         uint32_t            _xor);
 
-pixman_bool_t pixman_transform_point_3d (pixman_transform_t *transform,
-                                        pixman_vector_t    *vector);
-
 int           pixman_version            (void);
 const char*   pixman_version_string     (void);
 

commit d625ca5f291c01b3672648e5897f30a17326367f
Author: Jeff Muizelaar <[EMAIL PROTECTED]>
Date:   Mon Nov 24 15:11:24 2008 -0500

    Optimize rectilinear nearest-neighbour scaling
    
    Add a special case for a source transformation that is only a scale and
    preserves rectangular pixels and doesn't rotate the image. Currently, only
    SOURCE is special cased, however I plan to do more work in this area as 
needed.
    The biggest advantage the specialization currently has is writing directly 
to
    the destination surface instead of a temporary scanline buffer. However, it 
is
    still pretty unoptimized but I want to keep things simple for now.

diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 1388517..42a0454 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1208,6 +1208,93 @@ 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)
+{
+    uint32_t       *dst;
+    uint32_t       *src;
+    int             dstStride, srcStride;
+    int             i, j;
+    pixman_vector_t v;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
+    /* pass in 0 instead of xSrc and ySrc because xSrc and ySrc need to be
+     * transformed from destination space to source space */
+    fbComposeGetStart (pSrc, 0, 0, uint32_t, srcStride, src, 1);
+
+    /* reference point is the center of the pixel */
+    v.vector[0] = pixman_int_to_fixed(xSrc) + pixman_fixed_1 / 2;
+    v.vector[1] = pixman_int_to_fixed(ySrc) + pixman_fixed_1 / 2;
+    v.vector[2] = pixman_fixed_1;
+
+    if (!pixman_transform_point_3d (pSrc->common.transform, &v))
+        return;
+
+    /* 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;
+
+    for (j = 0; j < height; j++) {
+        pixman_fixed_t vx = v.vector[0];
+        pixman_fixed_t vy = v.vector[1];
+        for (i = 0; i < width; ++i) {
+            pixman_bool_t inside_bounds;
+            uint32_t result;
+            int x, y;
+            x = vx >> 16;
+            y = vy >> 16;


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to