LCOV - code coverage report
Current view: directory - gfx/cairo/libpixman/src - pixman-matrix.c (source / functions) Found Hit Coverage
Test: app.info Lines: 343 26 7.6 %
Date: 2012-06-02 Functions: 32 2 6.2 %

       1                 : /*
       2                 :  * Copyright © 2008 Keith Packard
       3                 :  *
       4                 :  * Permission to use, copy, modify, distribute, and sell this software and its
       5                 :  * documentation for any purpose is hereby granted without fee, provided that
       6                 :  * the above copyright notice appear in all copies and that both that copyright
       7                 :  * notice and this permission notice appear in supporting documentation, and
       8                 :  * that the name of the copyright holders not be used in advertising or
       9                 :  * publicity pertaining to distribution of the software without specific,
      10                 :  * written prior permission.  The copyright holders make no representations
      11                 :  * about the suitability of this software for any purpose.  It is provided "as
      12                 :  * is" without express or implied warranty.
      13                 :  *
      14                 :  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
      15                 :  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
      16                 :  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
      17                 :  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
      18                 :  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
      19                 :  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
      20                 :  * OF THIS SOFTWARE.
      21                 :  */
      22                 : 
      23                 : /*
      24                 :  * Matrix interfaces
      25                 :  */
      26                 : 
      27                 : #ifdef HAVE_CONFIG_H
      28                 : #include "config.h"
      29                 : #endif
      30                 : 
      31                 : #include <math.h>
      32                 : #include <string.h>
      33                 : #include "pixman-private.h"
      34                 : 
      35                 : #define F(x)    pixman_int_to_fixed (x)
      36                 : 
      37                 : PIXMAN_EXPORT void
      38               0 : pixman_transform_init_identity (struct pixman_transform *matrix)
      39                 : {
      40                 :     int i;
      41                 : 
      42               0 :     memset (matrix, '\0', sizeof (struct pixman_transform));
      43               0 :     for (i = 0; i < 3; i++)
      44               0 :         matrix->matrix[i][i] = F (1);
      45               0 : }
      46                 : 
      47                 : typedef pixman_fixed_32_32_t pixman_fixed_34_30_t;
      48                 : 
      49                 : PIXMAN_EXPORT pixman_bool_t
      50              20 : pixman_transform_point_3d (const struct pixman_transform *transform,
      51                 :                            struct pixman_vector *         vector)
      52                 : {
      53                 :     struct pixman_vector result;
      54                 :     pixman_fixed_32_32_t partial;
      55                 :     pixman_fixed_48_16_t v;
      56                 :     int i, j;
      57                 : 
      58              80 :     for (j = 0; j < 3; j++)
      59                 :     {
      60              60 :         v = 0;
      61             240 :         for (i = 0; i < 3; i++)
      62                 :         {
      63             360 :             partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
      64             180 :                        (pixman_fixed_48_16_t) vector->vector[i]);
      65             180 :             v += partial >> 16;
      66                 :         }
      67                 :         
      68              60 :         if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
      69               0 :             return FALSE;
      70                 :         
      71              60 :         result.vector[j] = (pixman_fixed_t) v;
      72                 :     }
      73                 :     
      74              20 :     *vector = result;
      75                 : 
      76              20 :     if (!result.vector[2])
      77               0 :         return FALSE;
      78                 : 
      79              20 :     return TRUE;
      80                 : }
      81                 : 
      82                 : PIXMAN_EXPORT pixman_bool_t
      83              80 : pixman_transform_point (const struct pixman_transform *transform,
      84                 :                         struct pixman_vector *         vector)
      85                 : {
      86                 :     pixman_fixed_32_32_t partial;
      87                 :     pixman_fixed_34_30_t v[3];
      88                 :     pixman_fixed_48_16_t quo;
      89                 :     int i, j;
      90                 : 
      91             320 :     for (j = 0; j < 3; j++)
      92                 :     {
      93             240 :         v[j] = 0;
      94                 :         
      95             960 :         for (i = 0; i < 3; i++)
      96                 :         {
      97            1440 :             partial = ((pixman_fixed_32_32_t) transform->matrix[j][i] *
      98             720 :                        (pixman_fixed_32_32_t) vector->vector[i]);
      99             720 :             v[j] += partial >> 2;
     100                 :         }
     101                 :     }
     102                 :     
     103              80 :     if (!(v[2] >> 16))
     104               0 :         return FALSE;
     105                 : 
     106             240 :     for (j = 0; j < 2; j++)
     107                 :     {
     108             160 :         quo = v[j] / (v[2] >> 16);
     109             160 :         if (quo > pixman_max_fixed_48_16 || quo < pixman_min_fixed_48_16)
     110               0 :             return FALSE;
     111             160 :         vector->vector[j] = (pixman_fixed_t) quo;
     112                 :     }
     113                 :     
     114              80 :     vector->vector[2] = pixman_fixed_1;
     115              80 :     return TRUE;
     116                 : }
     117                 : 
     118                 : PIXMAN_EXPORT pixman_bool_t
     119               0 : pixman_transform_multiply (struct pixman_transform *      dst,
     120                 :                            const struct pixman_transform *l,
     121                 :                            const struct pixman_transform *r)
     122                 : {
     123                 :     struct pixman_transform d;
     124                 :     int dx, dy;
     125                 :     int o;
     126                 : 
     127               0 :     for (dy = 0; dy < 3; dy++)
     128                 :     {
     129               0 :         for (dx = 0; dx < 3; dx++)
     130                 :         {
     131                 :             pixman_fixed_48_16_t v;
     132                 :             pixman_fixed_32_32_t partial;
     133                 :             
     134               0 :             v = 0;
     135               0 :             for (o = 0; o < 3; o++)
     136                 :             {
     137               0 :                 partial =
     138               0 :                     (pixman_fixed_32_32_t) l->matrix[dy][o] *
     139               0 :                     (pixman_fixed_32_32_t) r->matrix[o][dx];
     140                 : 
     141               0 :                 v += partial >> 16;
     142                 :             }
     143                 : 
     144               0 :             if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
     145               0 :                 return FALSE;
     146                 :             
     147               0 :             d.matrix[dy][dx] = (pixman_fixed_t) v;
     148                 :         }
     149                 :     }
     150                 : 
     151               0 :     *dst = d;
     152               0 :     return TRUE;
     153                 : }
     154                 : 
     155                 : PIXMAN_EXPORT void
     156               0 : pixman_transform_init_scale (struct pixman_transform *t,
     157                 :                              pixman_fixed_t           sx,
     158                 :                              pixman_fixed_t           sy)
     159                 : {
     160               0 :     memset (t, '\0', sizeof (struct pixman_transform));
     161                 : 
     162               0 :     t->matrix[0][0] = sx;
     163               0 :     t->matrix[1][1] = sy;
     164               0 :     t->matrix[2][2] = F (1);
     165               0 : }
     166                 : 
     167                 : static pixman_fixed_t
     168               0 : fixed_inverse (pixman_fixed_t x)
     169                 : {
     170               0 :     return (pixman_fixed_t) ((((pixman_fixed_48_16_t) F (1)) * F (1)) / x);
     171                 : }
     172                 : 
     173                 : PIXMAN_EXPORT pixman_bool_t
     174               0 : pixman_transform_scale (struct pixman_transform *forward,
     175                 :                         struct pixman_transform *reverse,
     176                 :                         pixman_fixed_t           sx,
     177                 :                         pixman_fixed_t           sy)
     178                 : {
     179                 :     struct pixman_transform t;
     180                 : 
     181               0 :     if (sx == 0 || sy == 0)
     182               0 :         return FALSE;
     183                 : 
     184               0 :     if (forward)
     185                 :     {
     186               0 :         pixman_transform_init_scale (&t, sx, sy);
     187               0 :         if (!pixman_transform_multiply (forward, &t, forward))
     188               0 :             return FALSE;
     189                 :     }
     190                 :     
     191               0 :     if (reverse)
     192                 :     {
     193               0 :         pixman_transform_init_scale (&t, fixed_inverse (sx),
     194                 :                                      fixed_inverse (sy));
     195               0 :         if (!pixman_transform_multiply (reverse, reverse, &t))
     196               0 :             return FALSE;
     197                 :     }
     198                 :     
     199               0 :     return TRUE;
     200                 : }
     201                 : 
     202                 : PIXMAN_EXPORT void
     203               0 : pixman_transform_init_rotate (struct pixman_transform *t,
     204                 :                               pixman_fixed_t           c,
     205                 :                               pixman_fixed_t           s)
     206                 : {
     207               0 :     memset (t, '\0', sizeof (struct pixman_transform));
     208                 : 
     209               0 :     t->matrix[0][0] = c;
     210               0 :     t->matrix[0][1] = -s;
     211               0 :     t->matrix[1][0] = s;
     212               0 :     t->matrix[1][1] = c;
     213               0 :     t->matrix[2][2] = F (1);
     214               0 : }
     215                 : 
     216                 : PIXMAN_EXPORT pixman_bool_t
     217               0 : pixman_transform_rotate (struct pixman_transform *forward,
     218                 :                          struct pixman_transform *reverse,
     219                 :                          pixman_fixed_t           c,
     220                 :                          pixman_fixed_t           s)
     221                 : {
     222                 :     struct pixman_transform t;
     223                 : 
     224               0 :     if (forward)
     225                 :     {
     226               0 :         pixman_transform_init_rotate (&t, c, s);
     227               0 :         if (!pixman_transform_multiply (forward, &t, forward))
     228               0 :             return FALSE;
     229                 :     }
     230                 : 
     231               0 :     if (reverse)
     232                 :     {
     233               0 :         pixman_transform_init_rotate (&t, c, -s);
     234               0 :         if (!pixman_transform_multiply (reverse, reverse, &t))
     235               0 :             return FALSE;
     236                 :     }
     237                 :     
     238               0 :     return TRUE;
     239                 : }
     240                 : 
     241                 : PIXMAN_EXPORT void
     242               0 : pixman_transform_init_translate (struct pixman_transform *t,
     243                 :                                  pixman_fixed_t           tx,
     244                 :                                  pixman_fixed_t           ty)
     245                 : {
     246               0 :     memset (t, '\0', sizeof (struct pixman_transform));
     247                 : 
     248               0 :     t->matrix[0][0] = F (1);
     249               0 :     t->matrix[0][2] = tx;
     250               0 :     t->matrix[1][1] = F (1);
     251               0 :     t->matrix[1][2] = ty;
     252               0 :     t->matrix[2][2] = F (1);
     253               0 : }
     254                 : 
     255                 : PIXMAN_EXPORT pixman_bool_t
     256               0 : pixman_transform_translate (struct pixman_transform *forward,
     257                 :                             struct pixman_transform *reverse,
     258                 :                             pixman_fixed_t           tx,
     259                 :                             pixman_fixed_t           ty)
     260                 : {
     261                 :     struct pixman_transform t;
     262                 : 
     263               0 :     if (forward)
     264                 :     {
     265               0 :         pixman_transform_init_translate (&t, tx, ty);
     266                 : 
     267               0 :         if (!pixman_transform_multiply (forward, &t, forward))
     268               0 :             return FALSE;
     269                 :     }
     270                 : 
     271               0 :     if (reverse)
     272                 :     {
     273               0 :         pixman_transform_init_translate (&t, -tx, -ty);
     274                 : 
     275               0 :         if (!pixman_transform_multiply (reverse, reverse, &t))
     276               0 :             return FALSE;
     277                 :     }
     278               0 :     return TRUE;
     279                 : }
     280                 : 
     281                 : PIXMAN_EXPORT pixman_bool_t
     282               0 : pixman_transform_bounds (const struct pixman_transform *matrix,
     283                 :                          struct pixman_box16 *          b)
     284                 : 
     285                 : {
     286                 :     struct pixman_vector v[4];
     287                 :     int i;
     288                 :     int x1, y1, x2, y2;
     289                 : 
     290               0 :     v[0].vector[0] = F (b->x1);
     291               0 :     v[0].vector[1] = F (b->y1);
     292               0 :     v[0].vector[2] = F (1);
     293                 : 
     294               0 :     v[1].vector[0] = F (b->x2);
     295               0 :     v[1].vector[1] = F (b->y1);
     296               0 :     v[1].vector[2] = F (1);
     297                 : 
     298               0 :     v[2].vector[0] = F (b->x2);
     299               0 :     v[2].vector[1] = F (b->y2);
     300               0 :     v[2].vector[2] = F (1);
     301                 : 
     302               0 :     v[3].vector[0] = F (b->x1);
     303               0 :     v[3].vector[1] = F (b->y2);
     304               0 :     v[3].vector[2] = F (1);
     305                 : 
     306               0 :     for (i = 0; i < 4; i++)
     307                 :     {
     308               0 :         if (!pixman_transform_point (matrix, &v[i]))
     309               0 :             return FALSE;
     310                 : 
     311               0 :         x1 = pixman_fixed_to_int (v[i].vector[0]);
     312               0 :         y1 = pixman_fixed_to_int (v[i].vector[1]);
     313               0 :         x2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[0]));
     314               0 :         y2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[1]));
     315                 : 
     316               0 :         if (i == 0)
     317                 :         {
     318               0 :             b->x1 = x1;
     319               0 :             b->y1 = y1;
     320               0 :             b->x2 = x2;
     321               0 :             b->y2 = y2;
     322                 :         }
     323                 :         else
     324                 :         {
     325               0 :             if (x1 < b->x1) b->x1 = x1;
     326               0 :             if (y1 < b->y1) b->y1 = y1;
     327               0 :             if (x2 > b->x2) b->x2 = x2;
     328               0 :             if (y2 > b->y2) b->y2 = y2;
     329                 :         }
     330                 :     }
     331                 : 
     332               0 :     return TRUE;
     333                 : }
     334                 : 
     335                 : PIXMAN_EXPORT pixman_bool_t
     336               0 : pixman_transform_invert (struct pixman_transform *      dst,
     337                 :                          const struct pixman_transform *src)
     338                 : {
     339                 :     struct pixman_f_transform m, r;
     340                 : 
     341               0 :     pixman_f_transform_from_pixman_transform (&m, src);
     342                 : 
     343               0 :     if (!pixman_f_transform_invert (&r, &m))
     344               0 :         return FALSE;
     345                 : 
     346               0 :     if (!pixman_transform_from_pixman_f_transform (dst, &r))
     347               0 :         return FALSE;
     348                 : 
     349               0 :     return TRUE;
     350                 : }
     351                 : 
     352                 : static pixman_bool_t
     353               0 : within_epsilon (pixman_fixed_t a,
     354                 :                 pixman_fixed_t b,
     355                 :                 pixman_fixed_t epsilon)
     356                 : {
     357               0 :     pixman_fixed_t t = a - b;
     358                 : 
     359               0 :     if (t < 0)
     360               0 :         t = -t;
     361                 : 
     362               0 :     return t <= epsilon;
     363                 : }
     364                 : 
     365                 : #define EPSILON (pixman_fixed_t) (2)
     366                 : 
     367                 : #define IS_SAME(a, b) (within_epsilon (a, b, EPSILON))
     368                 : #define IS_ZERO(a)    (within_epsilon (a, 0, EPSILON))
     369                 : #define IS_ONE(a)     (within_epsilon (a, F (1), EPSILON))
     370                 : #define IS_UNIT(a)                          \
     371                 :     (within_epsilon (a, F (1), EPSILON) ||  \
     372                 :      within_epsilon (a, F (-1), EPSILON) || \
     373                 :      IS_ZERO (a))
     374                 : #define IS_INT(a)    (IS_ZERO (pixman_fixed_frac (a)))
     375                 : 
     376                 : PIXMAN_EXPORT pixman_bool_t
     377               0 : pixman_transform_is_identity (const struct pixman_transform *t)
     378                 : {
     379               0 :     return (IS_SAME (t->matrix[0][0], t->matrix[1][1]) &&
     380               0 :             IS_SAME (t->matrix[0][0], t->matrix[2][2]) &&
     381               0 :             !IS_ZERO (t->matrix[0][0]) &&
     382               0 :             IS_ZERO (t->matrix[0][1]) &&
     383               0 :             IS_ZERO (t->matrix[0][2]) &&
     384               0 :             IS_ZERO (t->matrix[1][0]) &&
     385               0 :             IS_ZERO (t->matrix[1][2]) &&
     386               0 :             IS_ZERO (t->matrix[2][0]) &&
     387               0 :             IS_ZERO (t->matrix[2][1]));
     388                 : }
     389                 : 
     390                 : PIXMAN_EXPORT pixman_bool_t
     391               0 : pixman_transform_is_scale (const struct pixman_transform *t)
     392                 : {
     393               0 :     return (!IS_ZERO (t->matrix[0][0]) &&
     394               0 :             IS_ZERO (t->matrix[0][1]) &&
     395               0 :             IS_ZERO (t->matrix[0][2]) &&
     396                 : 
     397               0 :             IS_ZERO (t->matrix[1][0]) &&
     398               0 :             !IS_ZERO (t->matrix[1][1]) &&
     399               0 :             IS_ZERO (t->matrix[1][2]) &&
     400                 : 
     401               0 :             IS_ZERO (t->matrix[2][0]) &&
     402               0 :             IS_ZERO (t->matrix[2][1]) &&
     403               0 :             !IS_ZERO (t->matrix[2][2]));
     404                 : }
     405                 : 
     406                 : PIXMAN_EXPORT pixman_bool_t
     407               0 : pixman_transform_is_int_translate (const struct pixman_transform *t)
     408                 : {
     409               0 :     return (IS_ONE (t->matrix[0][0]) &&
     410               0 :             IS_ZERO (t->matrix[0][1]) &&
     411               0 :             IS_INT (t->matrix[0][2]) &&
     412                 : 
     413               0 :             IS_ZERO (t->matrix[1][0]) &&
     414               0 :             IS_ONE (t->matrix[1][1]) &&
     415               0 :             IS_INT (t->matrix[1][2]) &&
     416                 : 
     417               0 :             IS_ZERO (t->matrix[2][0]) &&
     418               0 :             IS_ZERO (t->matrix[2][1]) &&
     419               0 :             IS_ONE (t->matrix[2][2]));
     420                 : }
     421                 : 
     422                 : PIXMAN_EXPORT pixman_bool_t
     423               0 : pixman_transform_is_inverse (const struct pixman_transform *a,
     424                 :                              const struct pixman_transform *b)
     425                 : {
     426                 :     struct pixman_transform t;
     427                 : 
     428               0 :     if (!pixman_transform_multiply (&t, a, b))
     429               0 :         return FALSE;
     430                 : 
     431               0 :     return pixman_transform_is_identity (&t);
     432                 : }
     433                 : 
     434                 : PIXMAN_EXPORT void
     435               0 : pixman_f_transform_from_pixman_transform (struct pixman_f_transform *    ft,
     436                 :                                           const struct pixman_transform *t)
     437                 : {
     438                 :     int i, j;
     439                 : 
     440               0 :     for (j = 0; j < 3; j++)
     441                 :     {
     442               0 :         for (i = 0; i < 3; i++)
     443               0 :             ft->m[j][i] = pixman_fixed_to_double (t->matrix[j][i]);
     444                 :     }
     445               0 : }
     446                 : 
     447                 : PIXMAN_EXPORT pixman_bool_t
     448               0 : pixman_transform_from_pixman_f_transform (struct pixman_transform *        t,
     449                 :                                           const struct pixman_f_transform *ft)
     450                 : {
     451                 :     int i, j;
     452                 : 
     453               0 :     for (j = 0; j < 3; j++)
     454                 :     {
     455               0 :         for (i = 0; i < 3; i++)
     456                 :         {
     457               0 :             double d = ft->m[j][i];
     458               0 :             if (d < -32767.0 || d > 32767.0)
     459               0 :                 return FALSE;
     460               0 :             d = d * 65536.0 + 0.5;
     461               0 :             t->matrix[j][i] = (pixman_fixed_t) floor (d);
     462                 :         }
     463                 :     }
     464                 :     
     465               0 :     return TRUE;
     466                 : }
     467                 : 
     468                 : PIXMAN_EXPORT pixman_bool_t
     469               0 : pixman_f_transform_invert (struct pixman_f_transform *      dst,
     470                 :                            const struct pixman_f_transform *src)
     471                 : {
     472                 :     double det;
     473                 :     int i, j;
     474                 :     static int a[3] = { 2, 2, 1 };
     475                 :     static int b[3] = { 1, 0, 0 };
     476                 : 
     477               0 :     det = 0;
     478               0 :     for (i = 0; i < 3; i++)
     479                 :     {
     480                 :         double p;
     481               0 :         int ai = a[i];
     482               0 :         int bi = b[i];
     483               0 :         p = src->m[i][0] * (src->m[ai][2] * src->m[bi][1] -
     484               0 :                             src->m[ai][1] * src->m[bi][2]);
     485               0 :         if (i == 1)
     486               0 :             p = -p;
     487               0 :         det += p;
     488                 :     }
     489                 :     
     490               0 :     if (det == 0)
     491               0 :         return FALSE;
     492                 :     
     493               0 :     det = 1 / det;
     494               0 :     for (j = 0; j < 3; j++)
     495                 :     {
     496               0 :         for (i = 0; i < 3; i++)
     497                 :         {
     498                 :             double p;
     499               0 :             int ai = a[i];
     500               0 :             int aj = a[j];
     501               0 :             int bi = b[i];
     502               0 :             int bj = b[j];
     503                 : 
     504               0 :             p = (src->m[ai][aj] * src->m[bi][bj] -
     505               0 :                  src->m[ai][bj] * src->m[bi][aj]);
     506                 :             
     507               0 :             if (((i + j) & 1) != 0)
     508               0 :                 p = -p;
     509                 :             
     510               0 :             dst->m[j][i] = det * p;
     511                 :         }
     512                 :     }
     513                 : 
     514               0 :     return TRUE;
     515                 : }
     516                 : 
     517                 : PIXMAN_EXPORT pixman_bool_t
     518               0 : pixman_f_transform_point (const struct pixman_f_transform *t,
     519                 :                           struct pixman_f_vector *         v)
     520                 : {
     521                 :     struct pixman_f_vector result;
     522                 :     int i, j;
     523                 :     double a;
     524                 : 
     525               0 :     for (j = 0; j < 3; j++)
     526                 :     {
     527               0 :         a = 0;
     528               0 :         for (i = 0; i < 3; i++)
     529               0 :             a += t->m[j][i] * v->v[i];
     530               0 :         result.v[j] = a;
     531                 :     }
     532                 :     
     533               0 :     if (!result.v[2])
     534               0 :         return FALSE;
     535                 : 
     536               0 :     for (j = 0; j < 2; j++)
     537               0 :         v->v[j] = result.v[j] / result.v[2];
     538                 : 
     539               0 :     v->v[2] = 1;
     540                 : 
     541               0 :     return TRUE;
     542                 : }
     543                 : 
     544                 : PIXMAN_EXPORT void
     545               0 : pixman_f_transform_point_3d (const struct pixman_f_transform *t,
     546                 :                              struct pixman_f_vector *         v)
     547                 : {
     548                 :     struct pixman_f_vector result;
     549                 :     int i, j;
     550                 :     double a;
     551                 : 
     552               0 :     for (j = 0; j < 3; j++)
     553                 :     {
     554               0 :         a = 0;
     555               0 :         for (i = 0; i < 3; i++)
     556               0 :             a += t->m[j][i] * v->v[i];
     557               0 :         result.v[j] = a;
     558                 :     }
     559                 :     
     560               0 :     *v = result;
     561               0 : }
     562                 : 
     563                 : PIXMAN_EXPORT void
     564               0 : pixman_f_transform_multiply (struct pixman_f_transform *      dst,
     565                 :                              const struct pixman_f_transform *l,
     566                 :                              const struct pixman_f_transform *r)
     567                 : {
     568                 :     struct pixman_f_transform d;
     569                 :     int dx, dy;
     570                 :     int o;
     571                 : 
     572               0 :     for (dy = 0; dy < 3; dy++)
     573                 :     {
     574               0 :         for (dx = 0; dx < 3; dx++)
     575                 :         {
     576               0 :             double v = 0;
     577               0 :             for (o = 0; o < 3; o++)
     578               0 :                 v += l->m[dy][o] * r->m[o][dx];
     579               0 :             d.m[dy][dx] = v;
     580                 :         }
     581                 :     }
     582                 :     
     583               0 :     *dst = d;
     584               0 : }
     585                 : 
     586                 : PIXMAN_EXPORT void
     587               0 : pixman_f_transform_init_scale (struct pixman_f_transform *t,
     588                 :                                double                     sx,
     589                 :                                double                     sy)
     590                 : {
     591               0 :     t->m[0][0] = sx;
     592               0 :     t->m[0][1] = 0;
     593               0 :     t->m[0][2] = 0;
     594               0 :     t->m[1][0] = 0;
     595               0 :     t->m[1][1] = sy;
     596               0 :     t->m[1][2] = 0;
     597               0 :     t->m[2][0] = 0;
     598               0 :     t->m[2][1] = 0;
     599               0 :     t->m[2][2] = 1;
     600               0 : }
     601                 : 
     602                 : PIXMAN_EXPORT pixman_bool_t
     603               0 : pixman_f_transform_scale (struct pixman_f_transform *forward,
     604                 :                           struct pixman_f_transform *reverse,
     605                 :                           double                     sx,
     606                 :                           double                     sy)
     607                 : {
     608                 :     struct pixman_f_transform t;
     609                 : 
     610               0 :     if (sx == 0 || sy == 0)
     611               0 :         return FALSE;
     612                 : 
     613               0 :     if (forward)
     614                 :     {
     615               0 :         pixman_f_transform_init_scale (&t, sx, sy);
     616               0 :         pixman_f_transform_multiply (forward, &t, forward);
     617                 :     }
     618                 :     
     619               0 :     if (reverse)
     620                 :     {
     621               0 :         pixman_f_transform_init_scale (&t, 1 / sx, 1 / sy);
     622               0 :         pixman_f_transform_multiply (reverse, reverse, &t);
     623                 :     }
     624                 :     
     625               0 :     return TRUE;
     626                 : }
     627                 : 
     628                 : PIXMAN_EXPORT void
     629               0 : pixman_f_transform_init_rotate (struct pixman_f_transform *t,
     630                 :                                 double                     c,
     631                 :                                 double                     s)
     632                 : {
     633               0 :     t->m[0][0] = c;
     634               0 :     t->m[0][1] = -s;
     635               0 :     t->m[0][2] = 0;
     636               0 :     t->m[1][0] = s;
     637               0 :     t->m[1][1] = c;
     638               0 :     t->m[1][2] = 0;
     639               0 :     t->m[2][0] = 0;
     640               0 :     t->m[2][1] = 0;
     641               0 :     t->m[2][2] = 1;
     642               0 : }
     643                 : 
     644                 : PIXMAN_EXPORT pixman_bool_t
     645               0 : pixman_f_transform_rotate (struct pixman_f_transform *forward,
     646                 :                            struct pixman_f_transform *reverse,
     647                 :                            double                     c,
     648                 :                            double                     s)
     649                 : {
     650                 :     struct pixman_f_transform t;
     651                 : 
     652               0 :     if (forward)
     653                 :     {
     654               0 :         pixman_f_transform_init_rotate (&t, c, s);
     655               0 :         pixman_f_transform_multiply (forward, &t, forward);
     656                 :     }
     657                 :     
     658               0 :     if (reverse)
     659                 :     {
     660               0 :         pixman_f_transform_init_rotate (&t, c, -s);
     661               0 :         pixman_f_transform_multiply (reverse, reverse, &t);
     662                 :     }
     663                 : 
     664               0 :     return TRUE;
     665                 : }
     666                 : 
     667                 : PIXMAN_EXPORT void
     668               0 : pixman_f_transform_init_translate (struct pixman_f_transform *t,
     669                 :                                    double                     tx,
     670                 :                                    double                     ty)
     671                 : {
     672               0 :     t->m[0][0] = 1;
     673               0 :     t->m[0][1] = 0;
     674               0 :     t->m[0][2] = tx;
     675               0 :     t->m[1][0] = 0;
     676               0 :     t->m[1][1] = 1;
     677               0 :     t->m[1][2] = ty;
     678               0 :     t->m[2][0] = 0;
     679               0 :     t->m[2][1] = 0;
     680               0 :     t->m[2][2] = 1;
     681               0 : }
     682                 : 
     683                 : PIXMAN_EXPORT pixman_bool_t
     684               0 : pixman_f_transform_translate (struct pixman_f_transform *forward,
     685                 :                               struct pixman_f_transform *reverse,
     686                 :                               double                     tx,
     687                 :                               double                     ty)
     688                 : {
     689                 :     struct pixman_f_transform t;
     690                 : 
     691               0 :     if (forward)
     692                 :     {
     693               0 :         pixman_f_transform_init_translate (&t, tx, ty);
     694               0 :         pixman_f_transform_multiply (forward, &t, forward);
     695                 :     }
     696                 : 
     697               0 :     if (reverse)
     698                 :     {
     699               0 :         pixman_f_transform_init_translate (&t, -tx, -ty);
     700               0 :         pixman_f_transform_multiply (reverse, reverse, &t);
     701                 :     }
     702                 : 
     703               0 :     return TRUE;
     704                 : }
     705                 : 
     706                 : PIXMAN_EXPORT pixman_bool_t
     707               0 : pixman_f_transform_bounds (const struct pixman_f_transform *t,
     708                 :                            struct pixman_box16 *            b)
     709                 : {
     710                 :     struct pixman_f_vector v[4];
     711                 :     int i;
     712                 :     int x1, y1, x2, y2;
     713                 : 
     714               0 :     v[0].v[0] = b->x1;
     715               0 :     v[0].v[1] = b->y1;
     716               0 :     v[0].v[2] = 1;
     717               0 :     v[1].v[0] = b->x2;
     718               0 :     v[1].v[1] = b->y1;
     719               0 :     v[1].v[2] = 1;
     720               0 :     v[2].v[0] = b->x2;
     721               0 :     v[2].v[1] = b->y2;
     722               0 :     v[2].v[2] = 1;
     723               0 :     v[3].v[0] = b->x1;
     724               0 :     v[3].v[1] = b->y2;
     725               0 :     v[3].v[2] = 1;
     726                 : 
     727               0 :     for (i = 0; i < 4; i++)
     728                 :     {
     729               0 :         if (!pixman_f_transform_point (t, &v[i]))
     730               0 :             return FALSE;
     731                 : 
     732               0 :         x1 = floor (v[i].v[0]);
     733               0 :         y1 = floor (v[i].v[1]);
     734               0 :         x2 = ceil (v[i].v[0]);
     735               0 :         y2 = ceil (v[i].v[1]);
     736                 : 
     737               0 :         if (i == 0)
     738                 :         {
     739               0 :             b->x1 = x1;
     740               0 :             b->y1 = y1;
     741               0 :             b->x2 = x2;
     742               0 :             b->y2 = y2;
     743                 :         }
     744                 :         else
     745                 :         {
     746               0 :             if (x1 < b->x1) b->x1 = x1;
     747               0 :             if (y1 < b->y1) b->y1 = y1;
     748               0 :             if (x2 > b->x2) b->x2 = x2;
     749               0 :             if (y2 > b->y2) b->y2 = y2;
     750                 :         }
     751                 :     }
     752                 : 
     753               0 :     return TRUE;
     754                 : }
     755                 : 
     756                 : PIXMAN_EXPORT void
     757               0 : pixman_f_transform_init_identity (struct pixman_f_transform *t)
     758                 : {
     759                 :     int i, j;
     760                 : 
     761               0 :     for (j = 0; j < 3; j++)
     762                 :     {
     763               0 :         for (i = 0; i < 3; i++)
     764               0 :             t->m[j][i] = i == j ? 1 : 0;
     765                 :     }
     766               0 : }

Generated by: LCOV version 1.7