gfx/cairo/libpixman/src/pixman-matrix.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * Copyright © 2008 Keith Packard
michael@0 3 *
michael@0 4 * Permission to use, copy, modify, distribute, and sell this software and its
michael@0 5 * documentation for any purpose is hereby granted without fee, provided that
michael@0 6 * the above copyright notice appear in all copies and that both that copyright
michael@0 7 * notice and this permission notice appear in supporting documentation, and
michael@0 8 * that the name of the copyright holders not be used in advertising or
michael@0 9 * publicity pertaining to distribution of the software without specific,
michael@0 10 * written prior permission. The copyright holders make no representations
michael@0 11 * about the suitability of this software for any purpose. It is provided "as
michael@0 12 * is" without express or implied warranty.
michael@0 13 *
michael@0 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
michael@0 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
michael@0 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
michael@0 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
michael@0 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
michael@0 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
michael@0 20 * OF THIS SOFTWARE.
michael@0 21 */
michael@0 22
michael@0 23 /*
michael@0 24 * Matrix interfaces
michael@0 25 */
michael@0 26
michael@0 27 #ifdef HAVE_CONFIG_H
michael@0 28 #include <config.h>
michael@0 29 #endif
michael@0 30
michael@0 31 #include <math.h>
michael@0 32 #include <string.h>
michael@0 33 #include "pixman-private.h"
michael@0 34
michael@0 35 #define F(x) pixman_int_to_fixed (x)
michael@0 36
michael@0 37 static force_inline int
michael@0 38 count_leading_zeros (uint32_t x)
michael@0 39 {
michael@0 40 #ifdef __GNUC__
michael@0 41 return __builtin_clz (x);
michael@0 42 #else
michael@0 43 int n = 0;
michael@0 44 while (x)
michael@0 45 {
michael@0 46 n++;
michael@0 47 x >>= 1;
michael@0 48 }
michael@0 49 return 32 - n;
michael@0 50 #endif
michael@0 51 }
michael@0 52
michael@0 53 /*
michael@0 54 * Large signed/unsigned integer division with rounding for the platforms with
michael@0 55 * only 64-bit integer data type supported (no 128-bit data type).
michael@0 56 *
michael@0 57 * Arguments:
michael@0 58 * hi, lo - high and low 64-bit parts of the dividend
michael@0 59 * div - 48-bit divisor
michael@0 60 *
michael@0 61 * Returns: lowest 64 bits of the result as a return value and highest 64
michael@0 62 * bits of the result to "result_hi" pointer
michael@0 63 */
michael@0 64
michael@0 65 /* grade-school unsigned division (128-bit by 48-bit) with rounding to nearest */
michael@0 66 static force_inline uint64_t
michael@0 67 rounded_udiv_128_by_48 (uint64_t hi,
michael@0 68 uint64_t lo,
michael@0 69 uint64_t div,
michael@0 70 uint64_t *result_hi)
michael@0 71 {
michael@0 72 uint64_t tmp, remainder, result_lo;
michael@0 73 assert(div < ((uint64_t)1 << 48));
michael@0 74
michael@0 75 remainder = hi % div;
michael@0 76 *result_hi = hi / div;
michael@0 77
michael@0 78 tmp = (remainder << 16) + (lo >> 48);
michael@0 79 result_lo = tmp / div;
michael@0 80 remainder = tmp % div;
michael@0 81
michael@0 82 tmp = (remainder << 16) + ((lo >> 32) & 0xFFFF);
michael@0 83 result_lo = (result_lo << 16) + (tmp / div);
michael@0 84 remainder = tmp % div;
michael@0 85
michael@0 86 tmp = (remainder << 16) + ((lo >> 16) & 0xFFFF);
michael@0 87 result_lo = (result_lo << 16) + (tmp / div);
michael@0 88 remainder = tmp % div;
michael@0 89
michael@0 90 tmp = (remainder << 16) + (lo & 0xFFFF);
michael@0 91 result_lo = (result_lo << 16) + (tmp / div);
michael@0 92 remainder = tmp % div;
michael@0 93
michael@0 94 /* round to nearest */
michael@0 95 if (remainder * 2 >= div && ++result_lo == 0)
michael@0 96 *result_hi += 1;
michael@0 97
michael@0 98 return result_lo;
michael@0 99 }
michael@0 100
michael@0 101 /* signed division (128-bit by 49-bit) with rounding to nearest */
michael@0 102 static inline int64_t
michael@0 103 rounded_sdiv_128_by_49 (int64_t hi,
michael@0 104 uint64_t lo,
michael@0 105 int64_t div,
michael@0 106 int64_t *signed_result_hi)
michael@0 107 {
michael@0 108 uint64_t result_lo, result_hi;
michael@0 109 int sign = 0;
michael@0 110 if (div < 0)
michael@0 111 {
michael@0 112 div = -div;
michael@0 113 sign ^= 1;
michael@0 114 }
michael@0 115 if (hi < 0)
michael@0 116 {
michael@0 117 if (lo != 0)
michael@0 118 hi++;
michael@0 119 hi = -hi;
michael@0 120 lo = -lo;
michael@0 121 sign ^= 1;
michael@0 122 }
michael@0 123 result_lo = rounded_udiv_128_by_48 (hi, lo, div, &result_hi);
michael@0 124 if (sign)
michael@0 125 {
michael@0 126 if (result_lo != 0)
michael@0 127 result_hi++;
michael@0 128 result_hi = -result_hi;
michael@0 129 result_lo = -result_lo;
michael@0 130 }
michael@0 131 if (signed_result_hi)
michael@0 132 {
michael@0 133 *signed_result_hi = result_hi;
michael@0 134 }
michael@0 135 return result_lo;
michael@0 136 }
michael@0 137
michael@0 138 /*
michael@0 139 * Multiply 64.16 fixed point value by (2^scalebits) and convert
michael@0 140 * to 128-bit integer.
michael@0 141 */
michael@0 142 static force_inline void
michael@0 143 fixed_64_16_to_int128 (int64_t hi,
michael@0 144 int64_t lo,
michael@0 145 int64_t *rhi,
michael@0 146 int64_t *rlo,
michael@0 147 int scalebits)
michael@0 148 {
michael@0 149 /* separate integer and fractional parts */
michael@0 150 hi += lo >> 16;
michael@0 151 lo &= 0xFFFF;
michael@0 152
michael@0 153 if (scalebits <= 0)
michael@0 154 {
michael@0 155 *rlo = hi >> (-scalebits);
michael@0 156 *rhi = *rlo >> 63;
michael@0 157 }
michael@0 158 else
michael@0 159 {
michael@0 160 *rhi = hi >> (64 - scalebits);
michael@0 161 *rlo = (uint64_t)hi << scalebits;
michael@0 162 if (scalebits < 16)
michael@0 163 *rlo += lo >> (16 - scalebits);
michael@0 164 else
michael@0 165 *rlo += lo << (scalebits - 16);
michael@0 166 }
michael@0 167 }
michael@0 168
michael@0 169 /*
michael@0 170 * Convert 112.16 fixed point value to 48.16 with clamping for the out
michael@0 171 * of range values.
michael@0 172 */
michael@0 173 static force_inline pixman_fixed_48_16_t
michael@0 174 fixed_112_16_to_fixed_48_16 (int64_t hi, int64_t lo, pixman_bool_t *clampflag)
michael@0 175 {
michael@0 176 if ((lo >> 63) != hi)
michael@0 177 {
michael@0 178 *clampflag = TRUE;
michael@0 179 return hi >= 0 ? INT64_MAX : INT64_MIN;
michael@0 180 }
michael@0 181 else
michael@0 182 {
michael@0 183 return lo;
michael@0 184 }
michael@0 185 }
michael@0 186
michael@0 187 /*
michael@0 188 * Transform a point with 31.16 fixed point coordinates from the destination
michael@0 189 * space to a point with 48.16 fixed point coordinates in the source space.
michael@0 190 * No overflows are possible for affine transformations and the results are
michael@0 191 * accurate including the least significant bit. Projective transformations
michael@0 192 * may overflow, in this case the results are just clamped to return maximum
michael@0 193 * or minimum 48.16 values (so that the caller can at least handle the NONE
michael@0 194 * and PAD repeats correctly) and the return value is FALSE to indicate that
michael@0 195 * such clamping has happened.
michael@0 196 */
michael@0 197 PIXMAN_EXPORT pixman_bool_t
michael@0 198 pixman_transform_point_31_16 (const pixman_transform_t *t,
michael@0 199 const pixman_vector_48_16_t *v,
michael@0 200 pixman_vector_48_16_t *result)
michael@0 201 {
michael@0 202 pixman_bool_t clampflag = FALSE;
michael@0 203 int i;
michael@0 204 int64_t tmp[3][2], divint;
michael@0 205 uint16_t divfrac;
michael@0 206
michael@0 207 /* input vector values must have no more than 31 bits (including sign)
michael@0 208 * in the integer part */
michael@0 209 assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 210 assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 211 assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 212 assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 213 assert (v->v[2] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 214 assert (v->v[2] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 215
michael@0 216 for (i = 0; i < 3; i++)
michael@0 217 {
michael@0 218 tmp[i][0] = (int64_t)t->matrix[i][0] * (v->v[0] >> 16);
michael@0 219 tmp[i][1] = (int64_t)t->matrix[i][0] * (v->v[0] & 0xFFFF);
michael@0 220 tmp[i][0] += (int64_t)t->matrix[i][1] * (v->v[1] >> 16);
michael@0 221 tmp[i][1] += (int64_t)t->matrix[i][1] * (v->v[1] & 0xFFFF);
michael@0 222 tmp[i][0] += (int64_t)t->matrix[i][2] * (v->v[2] >> 16);
michael@0 223 tmp[i][1] += (int64_t)t->matrix[i][2] * (v->v[2] & 0xFFFF);
michael@0 224 }
michael@0 225
michael@0 226 /*
michael@0 227 * separate 64-bit integer and 16-bit fractional parts for the divisor,
michael@0 228 * which is also scaled by 65536 after fixed point multiplication.
michael@0 229 */
michael@0 230 divint = tmp[2][0] + (tmp[2][1] >> 16);
michael@0 231 divfrac = tmp[2][1] & 0xFFFF;
michael@0 232
michael@0 233 if (divint == pixman_fixed_1 && divfrac == 0)
michael@0 234 {
michael@0 235 /*
michael@0 236 * this is a simple affine transformation
michael@0 237 */
michael@0 238 result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16);
michael@0 239 result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16);
michael@0 240 result->v[2] = pixman_fixed_1;
michael@0 241 }
michael@0 242 else if (divint == 0 && divfrac == 0)
michael@0 243 {
michael@0 244 /*
michael@0 245 * handle zero divisor (if the values are non-zero, set the
michael@0 246 * results to maximum positive or minimum negative)
michael@0 247 */
michael@0 248 clampflag = TRUE;
michael@0 249
michael@0 250 result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16);
michael@0 251 result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16);
michael@0 252
michael@0 253 if (result->v[0] > 0)
michael@0 254 result->v[0] = INT64_MAX;
michael@0 255 else if (result->v[0] < 0)
michael@0 256 result->v[0] = INT64_MIN;
michael@0 257
michael@0 258 if (result->v[1] > 0)
michael@0 259 result->v[1] = INT64_MAX;
michael@0 260 else if (result->v[1] < 0)
michael@0 261 result->v[1] = INT64_MIN;
michael@0 262 }
michael@0 263 else
michael@0 264 {
michael@0 265 /*
michael@0 266 * projective transformation, analyze the top 32 bits of the divisor
michael@0 267 */
michael@0 268 int32_t hi32divbits = divint >> 32;
michael@0 269 if (hi32divbits < 0)
michael@0 270 hi32divbits = ~hi32divbits;
michael@0 271
michael@0 272 if (hi32divbits == 0)
michael@0 273 {
michael@0 274 /* the divisor is small, we can actually keep all the bits */
michael@0 275 int64_t hi, rhi, lo, rlo;
michael@0 276 int64_t div = (divint << 16) + divfrac;
michael@0 277
michael@0 278 fixed_64_16_to_int128 (tmp[0][0], tmp[0][1], &hi, &lo, 32);
michael@0 279 rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi);
michael@0 280 result->v[0] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag);
michael@0 281
michael@0 282 fixed_64_16_to_int128 (tmp[1][0], tmp[1][1], &hi, &lo, 32);
michael@0 283 rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi);
michael@0 284 result->v[1] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag);
michael@0 285 }
michael@0 286 else
michael@0 287 {
michael@0 288 /* the divisor needs to be reduced to 48 bits */
michael@0 289 int64_t hi, rhi, lo, rlo, div;
michael@0 290 int shift = 32 - count_leading_zeros (hi32divbits);
michael@0 291 fixed_64_16_to_int128 (divint, divfrac, &hi, &div, 16 - shift);
michael@0 292
michael@0 293 fixed_64_16_to_int128 (tmp[0][0], tmp[0][1], &hi, &lo, 32 - shift);
michael@0 294 rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi);
michael@0 295 result->v[0] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag);
michael@0 296
michael@0 297 fixed_64_16_to_int128 (tmp[1][0], tmp[1][1], &hi, &lo, 32 - shift);
michael@0 298 rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi);
michael@0 299 result->v[1] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag);
michael@0 300 }
michael@0 301 }
michael@0 302 result->v[2] = pixman_fixed_1;
michael@0 303 return !clampflag;
michael@0 304 }
michael@0 305
michael@0 306 PIXMAN_EXPORT void
michael@0 307 pixman_transform_point_31_16_affine (const pixman_transform_t *t,
michael@0 308 const pixman_vector_48_16_t *v,
michael@0 309 pixman_vector_48_16_t *result)
michael@0 310 {
michael@0 311 int64_t hi0, lo0, hi1, lo1;
michael@0 312
michael@0 313 /* input vector values must have no more than 31 bits (including sign)
michael@0 314 * in the integer part */
michael@0 315 assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 316 assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 317 assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 318 assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 319
michael@0 320 hi0 = (int64_t)t->matrix[0][0] * (v->v[0] >> 16);
michael@0 321 lo0 = (int64_t)t->matrix[0][0] * (v->v[0] & 0xFFFF);
michael@0 322 hi0 += (int64_t)t->matrix[0][1] * (v->v[1] >> 16);
michael@0 323 lo0 += (int64_t)t->matrix[0][1] * (v->v[1] & 0xFFFF);
michael@0 324 hi0 += (int64_t)t->matrix[0][2];
michael@0 325
michael@0 326 hi1 = (int64_t)t->matrix[1][0] * (v->v[0] >> 16);
michael@0 327 lo1 = (int64_t)t->matrix[1][0] * (v->v[0] & 0xFFFF);
michael@0 328 hi1 += (int64_t)t->matrix[1][1] * (v->v[1] >> 16);
michael@0 329 lo1 += (int64_t)t->matrix[1][1] * (v->v[1] & 0xFFFF);
michael@0 330 hi1 += (int64_t)t->matrix[1][2];
michael@0 331
michael@0 332 result->v[0] = hi0 + ((lo0 + 0x8000) >> 16);
michael@0 333 result->v[1] = hi1 + ((lo1 + 0x8000) >> 16);
michael@0 334 result->v[2] = pixman_fixed_1;
michael@0 335 }
michael@0 336
michael@0 337 PIXMAN_EXPORT void
michael@0 338 pixman_transform_point_31_16_3d (const pixman_transform_t *t,
michael@0 339 const pixman_vector_48_16_t *v,
michael@0 340 pixman_vector_48_16_t *result)
michael@0 341 {
michael@0 342 int i;
michael@0 343 int64_t tmp[3][2];
michael@0 344
michael@0 345 /* input vector values must have no more than 31 bits (including sign)
michael@0 346 * in the integer part */
michael@0 347 assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 348 assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 349 assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 350 assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 351 assert (v->v[2] < ((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 352 assert (v->v[2] >= -((pixman_fixed_48_16_t)1 << (30 + 16)));
michael@0 353
michael@0 354 for (i = 0; i < 3; i++)
michael@0 355 {
michael@0 356 tmp[i][0] = (int64_t)t->matrix[i][0] * (v->v[0] >> 16);
michael@0 357 tmp[i][1] = (int64_t)t->matrix[i][0] * (v->v[0] & 0xFFFF);
michael@0 358 tmp[i][0] += (int64_t)t->matrix[i][1] * (v->v[1] >> 16);
michael@0 359 tmp[i][1] += (int64_t)t->matrix[i][1] * (v->v[1] & 0xFFFF);
michael@0 360 tmp[i][0] += (int64_t)t->matrix[i][2] * (v->v[2] >> 16);
michael@0 361 tmp[i][1] += (int64_t)t->matrix[i][2] * (v->v[2] & 0xFFFF);
michael@0 362 }
michael@0 363
michael@0 364 result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16);
michael@0 365 result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16);
michael@0 366 result->v[2] = tmp[2][0] + ((tmp[2][1] + 0x8000) >> 16);
michael@0 367 }
michael@0 368
michael@0 369 PIXMAN_EXPORT void
michael@0 370 pixman_transform_init_identity (struct pixman_transform *matrix)
michael@0 371 {
michael@0 372 int i;
michael@0 373
michael@0 374 memset (matrix, '\0', sizeof (struct pixman_transform));
michael@0 375 for (i = 0; i < 3; i++)
michael@0 376 matrix->matrix[i][i] = F (1);
michael@0 377 }
michael@0 378
michael@0 379 typedef pixman_fixed_32_32_t pixman_fixed_34_30_t;
michael@0 380
michael@0 381 PIXMAN_EXPORT pixman_bool_t
michael@0 382 pixman_transform_point_3d (const struct pixman_transform *transform,
michael@0 383 struct pixman_vector * vector)
michael@0 384 {
michael@0 385 pixman_vector_48_16_t tmp;
michael@0 386 tmp.v[0] = vector->vector[0];
michael@0 387 tmp.v[1] = vector->vector[1];
michael@0 388 tmp.v[2] = vector->vector[2];
michael@0 389
michael@0 390 pixman_transform_point_31_16_3d (transform, &tmp, &tmp);
michael@0 391
michael@0 392 vector->vector[0] = tmp.v[0];
michael@0 393 vector->vector[1] = tmp.v[1];
michael@0 394 vector->vector[2] = tmp.v[2];
michael@0 395
michael@0 396 return vector->vector[0] == tmp.v[0] &&
michael@0 397 vector->vector[1] == tmp.v[1] &&
michael@0 398 vector->vector[2] == tmp.v[2];
michael@0 399 }
michael@0 400
michael@0 401 PIXMAN_EXPORT pixman_bool_t
michael@0 402 pixman_transform_point (const struct pixman_transform *transform,
michael@0 403 struct pixman_vector * vector)
michael@0 404 {
michael@0 405 pixman_vector_48_16_t tmp;
michael@0 406 tmp.v[0] = vector->vector[0];
michael@0 407 tmp.v[1] = vector->vector[1];
michael@0 408 tmp.v[2] = vector->vector[2];
michael@0 409
michael@0 410 if (!pixman_transform_point_31_16 (transform, &tmp, &tmp))
michael@0 411 return FALSE;
michael@0 412
michael@0 413 vector->vector[0] = tmp.v[0];
michael@0 414 vector->vector[1] = tmp.v[1];
michael@0 415 vector->vector[2] = tmp.v[2];
michael@0 416
michael@0 417 return vector->vector[0] == tmp.v[0] &&
michael@0 418 vector->vector[1] == tmp.v[1] &&
michael@0 419 vector->vector[2] == tmp.v[2];
michael@0 420 }
michael@0 421
michael@0 422 PIXMAN_EXPORT pixman_bool_t
michael@0 423 pixman_transform_multiply (struct pixman_transform * dst,
michael@0 424 const struct pixman_transform *l,
michael@0 425 const struct pixman_transform *r)
michael@0 426 {
michael@0 427 struct pixman_transform d;
michael@0 428 int dx, dy;
michael@0 429 int o;
michael@0 430
michael@0 431 for (dy = 0; dy < 3; dy++)
michael@0 432 {
michael@0 433 for (dx = 0; dx < 3; dx++)
michael@0 434 {
michael@0 435 pixman_fixed_48_16_t v;
michael@0 436 pixman_fixed_32_32_t partial;
michael@0 437
michael@0 438 v = 0;
michael@0 439 for (o = 0; o < 3; o++)
michael@0 440 {
michael@0 441 partial =
michael@0 442 (pixman_fixed_32_32_t) l->matrix[dy][o] *
michael@0 443 (pixman_fixed_32_32_t) r->matrix[o][dx];
michael@0 444
michael@0 445 v += (partial + 0x8000) >> 16;
michael@0 446 }
michael@0 447
michael@0 448 if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
michael@0 449 return FALSE;
michael@0 450
michael@0 451 d.matrix[dy][dx] = (pixman_fixed_t) v;
michael@0 452 }
michael@0 453 }
michael@0 454
michael@0 455 *dst = d;
michael@0 456 return TRUE;
michael@0 457 }
michael@0 458
michael@0 459 PIXMAN_EXPORT void
michael@0 460 pixman_transform_init_scale (struct pixman_transform *t,
michael@0 461 pixman_fixed_t sx,
michael@0 462 pixman_fixed_t sy)
michael@0 463 {
michael@0 464 memset (t, '\0', sizeof (struct pixman_transform));
michael@0 465
michael@0 466 t->matrix[0][0] = sx;
michael@0 467 t->matrix[1][1] = sy;
michael@0 468 t->matrix[2][2] = F (1);
michael@0 469 }
michael@0 470
michael@0 471 static pixman_fixed_t
michael@0 472 fixed_inverse (pixman_fixed_t x)
michael@0 473 {
michael@0 474 return (pixman_fixed_t) ((((pixman_fixed_48_16_t) F (1)) * F (1)) / x);
michael@0 475 }
michael@0 476
michael@0 477 PIXMAN_EXPORT pixman_bool_t
michael@0 478 pixman_transform_scale (struct pixman_transform *forward,
michael@0 479 struct pixman_transform *reverse,
michael@0 480 pixman_fixed_t sx,
michael@0 481 pixman_fixed_t sy)
michael@0 482 {
michael@0 483 struct pixman_transform t;
michael@0 484
michael@0 485 if (sx == 0 || sy == 0)
michael@0 486 return FALSE;
michael@0 487
michael@0 488 if (forward)
michael@0 489 {
michael@0 490 pixman_transform_init_scale (&t, sx, sy);
michael@0 491 if (!pixman_transform_multiply (forward, &t, forward))
michael@0 492 return FALSE;
michael@0 493 }
michael@0 494
michael@0 495 if (reverse)
michael@0 496 {
michael@0 497 pixman_transform_init_scale (&t, fixed_inverse (sx),
michael@0 498 fixed_inverse (sy));
michael@0 499 if (!pixman_transform_multiply (reverse, reverse, &t))
michael@0 500 return FALSE;
michael@0 501 }
michael@0 502
michael@0 503 return TRUE;
michael@0 504 }
michael@0 505
michael@0 506 PIXMAN_EXPORT void
michael@0 507 pixman_transform_init_rotate (struct pixman_transform *t,
michael@0 508 pixman_fixed_t c,
michael@0 509 pixman_fixed_t s)
michael@0 510 {
michael@0 511 memset (t, '\0', sizeof (struct pixman_transform));
michael@0 512
michael@0 513 t->matrix[0][0] = c;
michael@0 514 t->matrix[0][1] = -s;
michael@0 515 t->matrix[1][0] = s;
michael@0 516 t->matrix[1][1] = c;
michael@0 517 t->matrix[2][2] = F (1);
michael@0 518 }
michael@0 519
michael@0 520 PIXMAN_EXPORT pixman_bool_t
michael@0 521 pixman_transform_rotate (struct pixman_transform *forward,
michael@0 522 struct pixman_transform *reverse,
michael@0 523 pixman_fixed_t c,
michael@0 524 pixman_fixed_t s)
michael@0 525 {
michael@0 526 struct pixman_transform t;
michael@0 527
michael@0 528 if (forward)
michael@0 529 {
michael@0 530 pixman_transform_init_rotate (&t, c, s);
michael@0 531 if (!pixman_transform_multiply (forward, &t, forward))
michael@0 532 return FALSE;
michael@0 533 }
michael@0 534
michael@0 535 if (reverse)
michael@0 536 {
michael@0 537 pixman_transform_init_rotate (&t, c, -s);
michael@0 538 if (!pixman_transform_multiply (reverse, reverse, &t))
michael@0 539 return FALSE;
michael@0 540 }
michael@0 541
michael@0 542 return TRUE;
michael@0 543 }
michael@0 544
michael@0 545 PIXMAN_EXPORT void
michael@0 546 pixman_transform_init_translate (struct pixman_transform *t,
michael@0 547 pixman_fixed_t tx,
michael@0 548 pixman_fixed_t ty)
michael@0 549 {
michael@0 550 memset (t, '\0', sizeof (struct pixman_transform));
michael@0 551
michael@0 552 t->matrix[0][0] = F (1);
michael@0 553 t->matrix[0][2] = tx;
michael@0 554 t->matrix[1][1] = F (1);
michael@0 555 t->matrix[1][2] = ty;
michael@0 556 t->matrix[2][2] = F (1);
michael@0 557 }
michael@0 558
michael@0 559 PIXMAN_EXPORT pixman_bool_t
michael@0 560 pixman_transform_translate (struct pixman_transform *forward,
michael@0 561 struct pixman_transform *reverse,
michael@0 562 pixman_fixed_t tx,
michael@0 563 pixman_fixed_t ty)
michael@0 564 {
michael@0 565 struct pixman_transform t;
michael@0 566
michael@0 567 if (forward)
michael@0 568 {
michael@0 569 pixman_transform_init_translate (&t, tx, ty);
michael@0 570
michael@0 571 if (!pixman_transform_multiply (forward, &t, forward))
michael@0 572 return FALSE;
michael@0 573 }
michael@0 574
michael@0 575 if (reverse)
michael@0 576 {
michael@0 577 pixman_transform_init_translate (&t, -tx, -ty);
michael@0 578
michael@0 579 if (!pixman_transform_multiply (reverse, reverse, &t))
michael@0 580 return FALSE;
michael@0 581 }
michael@0 582 return TRUE;
michael@0 583 }
michael@0 584
michael@0 585 PIXMAN_EXPORT pixman_bool_t
michael@0 586 pixman_transform_bounds (const struct pixman_transform *matrix,
michael@0 587 struct pixman_box16 * b)
michael@0 588
michael@0 589 {
michael@0 590 struct pixman_vector v[4];
michael@0 591 int i;
michael@0 592 int x1, y1, x2, y2;
michael@0 593
michael@0 594 v[0].vector[0] = F (b->x1);
michael@0 595 v[0].vector[1] = F (b->y1);
michael@0 596 v[0].vector[2] = F (1);
michael@0 597
michael@0 598 v[1].vector[0] = F (b->x2);
michael@0 599 v[1].vector[1] = F (b->y1);
michael@0 600 v[1].vector[2] = F (1);
michael@0 601
michael@0 602 v[2].vector[0] = F (b->x2);
michael@0 603 v[2].vector[1] = F (b->y2);
michael@0 604 v[2].vector[2] = F (1);
michael@0 605
michael@0 606 v[3].vector[0] = F (b->x1);
michael@0 607 v[3].vector[1] = F (b->y2);
michael@0 608 v[3].vector[2] = F (1);
michael@0 609
michael@0 610 for (i = 0; i < 4; i++)
michael@0 611 {
michael@0 612 if (!pixman_transform_point (matrix, &v[i]))
michael@0 613 return FALSE;
michael@0 614
michael@0 615 x1 = pixman_fixed_to_int (v[i].vector[0]);
michael@0 616 y1 = pixman_fixed_to_int (v[i].vector[1]);
michael@0 617 x2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[0]));
michael@0 618 y2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[1]));
michael@0 619
michael@0 620 if (i == 0)
michael@0 621 {
michael@0 622 b->x1 = x1;
michael@0 623 b->y1 = y1;
michael@0 624 b->x2 = x2;
michael@0 625 b->y2 = y2;
michael@0 626 }
michael@0 627 else
michael@0 628 {
michael@0 629 if (x1 < b->x1) b->x1 = x1;
michael@0 630 if (y1 < b->y1) b->y1 = y1;
michael@0 631 if (x2 > b->x2) b->x2 = x2;
michael@0 632 if (y2 > b->y2) b->y2 = y2;
michael@0 633 }
michael@0 634 }
michael@0 635
michael@0 636 return TRUE;
michael@0 637 }
michael@0 638
michael@0 639 PIXMAN_EXPORT pixman_bool_t
michael@0 640 pixman_transform_invert (struct pixman_transform * dst,
michael@0 641 const struct pixman_transform *src)
michael@0 642 {
michael@0 643 struct pixman_f_transform m;
michael@0 644
michael@0 645 pixman_f_transform_from_pixman_transform (&m, src);
michael@0 646
michael@0 647 if (!pixman_f_transform_invert (&m, &m))
michael@0 648 return FALSE;
michael@0 649
michael@0 650 if (!pixman_transform_from_pixman_f_transform (dst, &m))
michael@0 651 return FALSE;
michael@0 652
michael@0 653 return TRUE;
michael@0 654 }
michael@0 655
michael@0 656 static pixman_bool_t
michael@0 657 within_epsilon (pixman_fixed_t a,
michael@0 658 pixman_fixed_t b,
michael@0 659 pixman_fixed_t epsilon)
michael@0 660 {
michael@0 661 pixman_fixed_t t = a - b;
michael@0 662
michael@0 663 if (t < 0)
michael@0 664 t = -t;
michael@0 665
michael@0 666 return t <= epsilon;
michael@0 667 }
michael@0 668
michael@0 669 #define EPSILON (pixman_fixed_t) (2)
michael@0 670
michael@0 671 #define IS_SAME(a, b) (within_epsilon (a, b, EPSILON))
michael@0 672 #define IS_ZERO(a) (within_epsilon (a, 0, EPSILON))
michael@0 673 #define IS_ONE(a) (within_epsilon (a, F (1), EPSILON))
michael@0 674 #define IS_UNIT(a) \
michael@0 675 (within_epsilon (a, F (1), EPSILON) || \
michael@0 676 within_epsilon (a, F (-1), EPSILON) || \
michael@0 677 IS_ZERO (a))
michael@0 678 #define IS_INT(a) (IS_ZERO (pixman_fixed_frac (a)))
michael@0 679
michael@0 680 PIXMAN_EXPORT pixman_bool_t
michael@0 681 pixman_transform_is_identity (const struct pixman_transform *t)
michael@0 682 {
michael@0 683 return (IS_SAME (t->matrix[0][0], t->matrix[1][1]) &&
michael@0 684 IS_SAME (t->matrix[0][0], t->matrix[2][2]) &&
michael@0 685 !IS_ZERO (t->matrix[0][0]) &&
michael@0 686 IS_ZERO (t->matrix[0][1]) &&
michael@0 687 IS_ZERO (t->matrix[0][2]) &&
michael@0 688 IS_ZERO (t->matrix[1][0]) &&
michael@0 689 IS_ZERO (t->matrix[1][2]) &&
michael@0 690 IS_ZERO (t->matrix[2][0]) &&
michael@0 691 IS_ZERO (t->matrix[2][1]));
michael@0 692 }
michael@0 693
michael@0 694 PIXMAN_EXPORT pixman_bool_t
michael@0 695 pixman_transform_is_scale (const struct pixman_transform *t)
michael@0 696 {
michael@0 697 return (!IS_ZERO (t->matrix[0][0]) &&
michael@0 698 IS_ZERO (t->matrix[0][1]) &&
michael@0 699 IS_ZERO (t->matrix[0][2]) &&
michael@0 700
michael@0 701 IS_ZERO (t->matrix[1][0]) &&
michael@0 702 !IS_ZERO (t->matrix[1][1]) &&
michael@0 703 IS_ZERO (t->matrix[1][2]) &&
michael@0 704
michael@0 705 IS_ZERO (t->matrix[2][0]) &&
michael@0 706 IS_ZERO (t->matrix[2][1]) &&
michael@0 707 !IS_ZERO (t->matrix[2][2]));
michael@0 708 }
michael@0 709
michael@0 710 PIXMAN_EXPORT pixman_bool_t
michael@0 711 pixman_transform_is_int_translate (const struct pixman_transform *t)
michael@0 712 {
michael@0 713 return (IS_ONE (t->matrix[0][0]) &&
michael@0 714 IS_ZERO (t->matrix[0][1]) &&
michael@0 715 IS_INT (t->matrix[0][2]) &&
michael@0 716
michael@0 717 IS_ZERO (t->matrix[1][0]) &&
michael@0 718 IS_ONE (t->matrix[1][1]) &&
michael@0 719 IS_INT (t->matrix[1][2]) &&
michael@0 720
michael@0 721 IS_ZERO (t->matrix[2][0]) &&
michael@0 722 IS_ZERO (t->matrix[2][1]) &&
michael@0 723 IS_ONE (t->matrix[2][2]));
michael@0 724 }
michael@0 725
michael@0 726 PIXMAN_EXPORT pixman_bool_t
michael@0 727 pixman_transform_is_inverse (const struct pixman_transform *a,
michael@0 728 const struct pixman_transform *b)
michael@0 729 {
michael@0 730 struct pixman_transform t;
michael@0 731
michael@0 732 if (!pixman_transform_multiply (&t, a, b))
michael@0 733 return FALSE;
michael@0 734
michael@0 735 return pixman_transform_is_identity (&t);
michael@0 736 }
michael@0 737
michael@0 738 PIXMAN_EXPORT void
michael@0 739 pixman_f_transform_from_pixman_transform (struct pixman_f_transform * ft,
michael@0 740 const struct pixman_transform *t)
michael@0 741 {
michael@0 742 int i, j;
michael@0 743
michael@0 744 for (j = 0; j < 3; j++)
michael@0 745 {
michael@0 746 for (i = 0; i < 3; i++)
michael@0 747 ft->m[j][i] = pixman_fixed_to_double (t->matrix[j][i]);
michael@0 748 }
michael@0 749 }
michael@0 750
michael@0 751 PIXMAN_EXPORT pixman_bool_t
michael@0 752 pixman_transform_from_pixman_f_transform (struct pixman_transform * t,
michael@0 753 const struct pixman_f_transform *ft)
michael@0 754 {
michael@0 755 int i, j;
michael@0 756
michael@0 757 for (j = 0; j < 3; j++)
michael@0 758 {
michael@0 759 for (i = 0; i < 3; i++)
michael@0 760 {
michael@0 761 double d = ft->m[j][i];
michael@0 762 if (d < -32767.0 || d > 32767.0)
michael@0 763 return FALSE;
michael@0 764 d = d * 65536.0 + 0.5;
michael@0 765 t->matrix[j][i] = (pixman_fixed_t) floor (d);
michael@0 766 }
michael@0 767 }
michael@0 768
michael@0 769 return TRUE;
michael@0 770 }
michael@0 771
michael@0 772 PIXMAN_EXPORT pixman_bool_t
michael@0 773 pixman_f_transform_invert (struct pixman_f_transform * dst,
michael@0 774 const struct pixman_f_transform *src)
michael@0 775 {
michael@0 776 static const int a[3] = { 2, 2, 1 };
michael@0 777 static const int b[3] = { 1, 0, 0 };
michael@0 778 pixman_f_transform_t d;
michael@0 779 double det;
michael@0 780 int i, j;
michael@0 781
michael@0 782 det = 0;
michael@0 783 for (i = 0; i < 3; i++)
michael@0 784 {
michael@0 785 double p;
michael@0 786 int ai = a[i];
michael@0 787 int bi = b[i];
michael@0 788 p = src->m[i][0] * (src->m[ai][2] * src->m[bi][1] -
michael@0 789 src->m[ai][1] * src->m[bi][2]);
michael@0 790 if (i == 1)
michael@0 791 p = -p;
michael@0 792 det += p;
michael@0 793 }
michael@0 794
michael@0 795 if (det == 0)
michael@0 796 return FALSE;
michael@0 797
michael@0 798 det = 1 / det;
michael@0 799 for (j = 0; j < 3; j++)
michael@0 800 {
michael@0 801 for (i = 0; i < 3; i++)
michael@0 802 {
michael@0 803 double p;
michael@0 804 int ai = a[i];
michael@0 805 int aj = a[j];
michael@0 806 int bi = b[i];
michael@0 807 int bj = b[j];
michael@0 808
michael@0 809 p = (src->m[ai][aj] * src->m[bi][bj] -
michael@0 810 src->m[ai][bj] * src->m[bi][aj]);
michael@0 811
michael@0 812 if (((i + j) & 1) != 0)
michael@0 813 p = -p;
michael@0 814
michael@0 815 d.m[j][i] = det * p;
michael@0 816 }
michael@0 817 }
michael@0 818
michael@0 819 *dst = d;
michael@0 820
michael@0 821 return TRUE;
michael@0 822 }
michael@0 823
michael@0 824 PIXMAN_EXPORT pixman_bool_t
michael@0 825 pixman_f_transform_point (const struct pixman_f_transform *t,
michael@0 826 struct pixman_f_vector * v)
michael@0 827 {
michael@0 828 struct pixman_f_vector result;
michael@0 829 int i, j;
michael@0 830 double a;
michael@0 831
michael@0 832 for (j = 0; j < 3; j++)
michael@0 833 {
michael@0 834 a = 0;
michael@0 835 for (i = 0; i < 3; i++)
michael@0 836 a += t->m[j][i] * v->v[i];
michael@0 837 result.v[j] = a;
michael@0 838 }
michael@0 839
michael@0 840 if (!result.v[2])
michael@0 841 return FALSE;
michael@0 842
michael@0 843 for (j = 0; j < 2; j++)
michael@0 844 v->v[j] = result.v[j] / result.v[2];
michael@0 845
michael@0 846 v->v[2] = 1;
michael@0 847
michael@0 848 return TRUE;
michael@0 849 }
michael@0 850
michael@0 851 PIXMAN_EXPORT void
michael@0 852 pixman_f_transform_point_3d (const struct pixman_f_transform *t,
michael@0 853 struct pixman_f_vector * v)
michael@0 854 {
michael@0 855 struct pixman_f_vector result;
michael@0 856 int i, j;
michael@0 857 double a;
michael@0 858
michael@0 859 for (j = 0; j < 3; j++)
michael@0 860 {
michael@0 861 a = 0;
michael@0 862 for (i = 0; i < 3; i++)
michael@0 863 a += t->m[j][i] * v->v[i];
michael@0 864 result.v[j] = a;
michael@0 865 }
michael@0 866
michael@0 867 *v = result;
michael@0 868 }
michael@0 869
michael@0 870 PIXMAN_EXPORT void
michael@0 871 pixman_f_transform_multiply (struct pixman_f_transform * dst,
michael@0 872 const struct pixman_f_transform *l,
michael@0 873 const struct pixman_f_transform *r)
michael@0 874 {
michael@0 875 struct pixman_f_transform d;
michael@0 876 int dx, dy;
michael@0 877 int o;
michael@0 878
michael@0 879 for (dy = 0; dy < 3; dy++)
michael@0 880 {
michael@0 881 for (dx = 0; dx < 3; dx++)
michael@0 882 {
michael@0 883 double v = 0;
michael@0 884 for (o = 0; o < 3; o++)
michael@0 885 v += l->m[dy][o] * r->m[o][dx];
michael@0 886 d.m[dy][dx] = v;
michael@0 887 }
michael@0 888 }
michael@0 889
michael@0 890 *dst = d;
michael@0 891 }
michael@0 892
michael@0 893 PIXMAN_EXPORT void
michael@0 894 pixman_f_transform_init_scale (struct pixman_f_transform *t,
michael@0 895 double sx,
michael@0 896 double sy)
michael@0 897 {
michael@0 898 t->m[0][0] = sx;
michael@0 899 t->m[0][1] = 0;
michael@0 900 t->m[0][2] = 0;
michael@0 901 t->m[1][0] = 0;
michael@0 902 t->m[1][1] = sy;
michael@0 903 t->m[1][2] = 0;
michael@0 904 t->m[2][0] = 0;
michael@0 905 t->m[2][1] = 0;
michael@0 906 t->m[2][2] = 1;
michael@0 907 }
michael@0 908
michael@0 909 PIXMAN_EXPORT pixman_bool_t
michael@0 910 pixman_f_transform_scale (struct pixman_f_transform *forward,
michael@0 911 struct pixman_f_transform *reverse,
michael@0 912 double sx,
michael@0 913 double sy)
michael@0 914 {
michael@0 915 struct pixman_f_transform t;
michael@0 916
michael@0 917 if (sx == 0 || sy == 0)
michael@0 918 return FALSE;
michael@0 919
michael@0 920 if (forward)
michael@0 921 {
michael@0 922 pixman_f_transform_init_scale (&t, sx, sy);
michael@0 923 pixman_f_transform_multiply (forward, &t, forward);
michael@0 924 }
michael@0 925
michael@0 926 if (reverse)
michael@0 927 {
michael@0 928 pixman_f_transform_init_scale (&t, 1 / sx, 1 / sy);
michael@0 929 pixman_f_transform_multiply (reverse, reverse, &t);
michael@0 930 }
michael@0 931
michael@0 932 return TRUE;
michael@0 933 }
michael@0 934
michael@0 935 PIXMAN_EXPORT void
michael@0 936 pixman_f_transform_init_rotate (struct pixman_f_transform *t,
michael@0 937 double c,
michael@0 938 double s)
michael@0 939 {
michael@0 940 t->m[0][0] = c;
michael@0 941 t->m[0][1] = -s;
michael@0 942 t->m[0][2] = 0;
michael@0 943 t->m[1][0] = s;
michael@0 944 t->m[1][1] = c;
michael@0 945 t->m[1][2] = 0;
michael@0 946 t->m[2][0] = 0;
michael@0 947 t->m[2][1] = 0;
michael@0 948 t->m[2][2] = 1;
michael@0 949 }
michael@0 950
michael@0 951 PIXMAN_EXPORT pixman_bool_t
michael@0 952 pixman_f_transform_rotate (struct pixman_f_transform *forward,
michael@0 953 struct pixman_f_transform *reverse,
michael@0 954 double c,
michael@0 955 double s)
michael@0 956 {
michael@0 957 struct pixman_f_transform t;
michael@0 958
michael@0 959 if (forward)
michael@0 960 {
michael@0 961 pixman_f_transform_init_rotate (&t, c, s);
michael@0 962 pixman_f_transform_multiply (forward, &t, forward);
michael@0 963 }
michael@0 964
michael@0 965 if (reverse)
michael@0 966 {
michael@0 967 pixman_f_transform_init_rotate (&t, c, -s);
michael@0 968 pixman_f_transform_multiply (reverse, reverse, &t);
michael@0 969 }
michael@0 970
michael@0 971 return TRUE;
michael@0 972 }
michael@0 973
michael@0 974 PIXMAN_EXPORT void
michael@0 975 pixman_f_transform_init_translate (struct pixman_f_transform *t,
michael@0 976 double tx,
michael@0 977 double ty)
michael@0 978 {
michael@0 979 t->m[0][0] = 1;
michael@0 980 t->m[0][1] = 0;
michael@0 981 t->m[0][2] = tx;
michael@0 982 t->m[1][0] = 0;
michael@0 983 t->m[1][1] = 1;
michael@0 984 t->m[1][2] = ty;
michael@0 985 t->m[2][0] = 0;
michael@0 986 t->m[2][1] = 0;
michael@0 987 t->m[2][2] = 1;
michael@0 988 }
michael@0 989
michael@0 990 PIXMAN_EXPORT pixman_bool_t
michael@0 991 pixman_f_transform_translate (struct pixman_f_transform *forward,
michael@0 992 struct pixman_f_transform *reverse,
michael@0 993 double tx,
michael@0 994 double ty)
michael@0 995 {
michael@0 996 struct pixman_f_transform t;
michael@0 997
michael@0 998 if (forward)
michael@0 999 {
michael@0 1000 pixman_f_transform_init_translate (&t, tx, ty);
michael@0 1001 pixman_f_transform_multiply (forward, &t, forward);
michael@0 1002 }
michael@0 1003
michael@0 1004 if (reverse)
michael@0 1005 {
michael@0 1006 pixman_f_transform_init_translate (&t, -tx, -ty);
michael@0 1007 pixman_f_transform_multiply (reverse, reverse, &t);
michael@0 1008 }
michael@0 1009
michael@0 1010 return TRUE;
michael@0 1011 }
michael@0 1012
michael@0 1013 PIXMAN_EXPORT pixman_bool_t
michael@0 1014 pixman_f_transform_bounds (const struct pixman_f_transform *t,
michael@0 1015 struct pixman_box16 * b)
michael@0 1016 {
michael@0 1017 struct pixman_f_vector v[4];
michael@0 1018 int i;
michael@0 1019 int x1, y1, x2, y2;
michael@0 1020
michael@0 1021 v[0].v[0] = b->x1;
michael@0 1022 v[0].v[1] = b->y1;
michael@0 1023 v[0].v[2] = 1;
michael@0 1024 v[1].v[0] = b->x2;
michael@0 1025 v[1].v[1] = b->y1;
michael@0 1026 v[1].v[2] = 1;
michael@0 1027 v[2].v[0] = b->x2;
michael@0 1028 v[2].v[1] = b->y2;
michael@0 1029 v[2].v[2] = 1;
michael@0 1030 v[3].v[0] = b->x1;
michael@0 1031 v[3].v[1] = b->y2;
michael@0 1032 v[3].v[2] = 1;
michael@0 1033
michael@0 1034 for (i = 0; i < 4; i++)
michael@0 1035 {
michael@0 1036 if (!pixman_f_transform_point (t, &v[i]))
michael@0 1037 return FALSE;
michael@0 1038
michael@0 1039 x1 = floor (v[i].v[0]);
michael@0 1040 y1 = floor (v[i].v[1]);
michael@0 1041 x2 = ceil (v[i].v[0]);
michael@0 1042 y2 = ceil (v[i].v[1]);
michael@0 1043
michael@0 1044 if (i == 0)
michael@0 1045 {
michael@0 1046 b->x1 = x1;
michael@0 1047 b->y1 = y1;
michael@0 1048 b->x2 = x2;
michael@0 1049 b->y2 = y2;
michael@0 1050 }
michael@0 1051 else
michael@0 1052 {
michael@0 1053 if (x1 < b->x1) b->x1 = x1;
michael@0 1054 if (y1 < b->y1) b->y1 = y1;
michael@0 1055 if (x2 > b->x2) b->x2 = x2;
michael@0 1056 if (y2 > b->y2) b->y2 = y2;
michael@0 1057 }
michael@0 1058 }
michael@0 1059
michael@0 1060 return TRUE;
michael@0 1061 }
michael@0 1062
michael@0 1063 PIXMAN_EXPORT void
michael@0 1064 pixman_f_transform_init_identity (struct pixman_f_transform *t)
michael@0 1065 {
michael@0 1066 int i, j;
michael@0 1067
michael@0 1068 for (j = 0; j < 3; j++)
michael@0 1069 {
michael@0 1070 for (i = 0; i < 3; i++)
michael@0 1071 t->m[j][i] = i == j ? 1 : 0;
michael@0 1072 }
michael@0 1073 }

mercurial