Rev 1891 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1891 | Rev 3931 | ||
---|---|---|---|
Line 23... | Line 23... | ||
23 | /* |
23 | /* |
24 | * Matrix interfaces |
24 | * Matrix interfaces |
25 | */ |
25 | */ |
Line 26... | Line 26... | ||
26 | 26 | ||
27 | #ifdef HAVE_CONFIG_H |
27 | #ifdef HAVE_CONFIG_H |
28 | #include "config.h" |
28 | #include |
Line 29... | Line 29... | ||
29 | #endif |
29 | #endif |
30 | 30 | ||
31 | #include |
31 | #include |
Line 32... | Line 32... | ||
32 | #include |
32 | #include |
Line 33... | Line 33... | ||
33 | #include "pixman-private.h" |
33 | #include "pixman-private.h" |
34 | 34 | ||
35 | #define F(x) pixman_int_to_fixed (x) |
35 | #define F(x) pixman_int_to_fixed (x) |
- | 36 | ||
- | 37 | static force_inline int |
|
- | 38 | count_leading_zeros (uint32_t x) |
|
36 | 39 | { |
|
- | 40 | #ifdef __GNUC__ |
|
- | 41 | return __builtin_clz (x); |
|
- | 42 | #else |
|
- | 43 | int n = 0; |
|
- | 44 | while (x) |
|
- | 45 | { |
|
- | 46 | n++; |
|
- | 47 | x >>= 1; |
|
Line -... | Line 48... | ||
- | 48 | } |
|
- | 49 | return 32 - n; |
|
- | 50 | #endif |
|
- | 51 | } |
|
- | 52 | ||
- | 53 | /* |
|
- | 54 | * Large signed/unsigned integer division with rounding for the platforms with |
|
- | 55 | * only 64-bit integer data type supported (no 128-bit data type). |
|
- | 56 | * |
|
37 | PIXMAN_EXPORT void |
57 | * Arguments: |
- | 58 | * hi, lo - high and low 64-bit parts of the dividend |
|
- | 59 | * div - 48-bit divisor |
|
- | 60 | * |
|
- | 61 | * Returns: lowest 64 bits of the result as a return value and highest 64 |
|
- | 62 | * bits of the result to "result_hi" pointer |
|
- | 63 | */ |
|
- | 64 | ||
- | 65 | /* grade-school unsigned division (128-bit by 48-bit) with rounding to nearest */ |
|
- | 66 | static force_inline uint64_t |
|
- | 67 | rounded_udiv_128_by_48 (uint64_t hi, |
|
- | 68 | uint64_t lo, |
|
- | 69 | uint64_t div, |
|
- | 70 | uint64_t *result_hi) |
|
38 | pixman_transform_init_identity (struct pixman_transform *matrix) |
71 | { |
- | 72 | uint64_t tmp, remainder, result_lo; |
|
- | 73 | assert(div < ((uint64_t)1 << 48)); |
|
- | 74 | ||
- | 75 | remainder = hi % div; |
|
- | 76 | *result_hi = hi / div; |
|
- | 77 | ||
- | 78 | tmp = (remainder << 16) + (lo >> 48); |
|
- | 79 | result_lo = tmp / div; |
|
- | 80 | remainder = tmp % div; |
|
- | 81 | ||
- | 82 | tmp = (remainder << 16) + ((lo >> 32) & 0xFFFF); |
|
- | 83 | result_lo = (result_lo << 16) + (tmp / div); |
|
- | 84 | remainder = tmp % div; |
|
- | 85 | ||
- | 86 | tmp = (remainder << 16) + ((lo >> 16) & 0xFFFF); |
|
39 | { |
87 | result_lo = (result_lo << 16) + (tmp / div); |
- | 88 | remainder = tmp % div; |
|
- | 89 | ||
- | 90 | tmp = (remainder << 16) + (lo & 0xFFFF); |
|
- | 91 | result_lo = (result_lo << 16) + (tmp / div); |
|
- | 92 | remainder = tmp % div; |
|
- | 93 | ||
40 | int i; |
94 | /* round to nearest */ |
Line -... | Line 95... | ||
- | 95 | if (remainder * 2 >= div && ++result_lo == 0) |
|
- | 96 | *result_hi += 1; |
|
- | 97 | ||
- | 98 | return result_lo; |
|
- | 99 | } |
|
- | 100 | ||
- | 101 | /* signed division (128-bit by 49-bit) with rounding to nearest */ |
|
- | 102 | static inline int64_t |
|
- | 103 | rounded_sdiv_128_by_49 (int64_t hi, |
|
- | 104 | uint64_t lo, |
|
- | 105 | int64_t div, |
|
- | 106 | int64_t *signed_result_hi) |
|
- | 107 | { |
|
- | 108 | uint64_t result_lo, result_hi; |
|
- | 109 | int sign = 0; |
|
- | 110 | if (div < 0) |
|
- | 111 | { |
|
- | 112 | div = -div; |
|
- | 113 | sign ^= 1; |
|
- | 114 | } |
|
- | 115 | if (hi < 0) |
|
- | 116 | { |
|
- | 117 | if (lo != 0) |
|
- | 118 | hi++; |
|
- | 119 | hi = -hi; |
|
- | 120 | lo = -lo; |
|
- | 121 | sign ^= 1; |
|
- | 122 | } |
|
- | 123 | result_lo = rounded_udiv_128_by_48 (hi, lo, div, &result_hi); |
|
- | 124 | if (sign) |
|
- | 125 | { |
|
- | 126 | if (result_lo != 0) |
|
41 | 127 | result_hi++; |
|
- | 128 | result_hi = -result_hi; |
|
- | 129 | result_lo = -result_lo; |
|
- | 130 | } |
|
Line -... | Line 131... | ||
- | 131 | if (signed_result_hi) |
|
- | 132 | { |
|
- | 133 | *signed_result_hi = result_hi; |
|
- | 134 | } |
|
42 | memset (matrix, '\0', sizeof (struct pixman_transform)); |
135 | return result_lo; |
43 | for (i = 0; i < 3; i++) |
136 | } |
- | 137 | ||
- | 138 | /* |
|
- | 139 | * Multiply 64.16 fixed point value by (2^scalebits) and convert |
|
44 | matrix->matrix[i][i] = F (1); |
140 | * to 128-bit integer. |
- | 141 | */ |
|
- | 142 | static force_inline void |
|
- | 143 | fixed_64_16_to_int128 (int64_t hi, |
|
- | 144 | int64_t lo, |
|
- | 145 | int64_t *rhi, |
|
- | 146 | int64_t *rlo, |
|
45 | } |
147 | int scalebits) |
46 | 148 | { |
|
- | 149 | /* separate integer and fractional parts */ |
|
- | 150 | hi += lo >> 16; |
|
- | 151 | lo &= 0xFFFF; |
|
- | 152 | ||
- | 153 | if (scalebits <= 0) |
|
47 | typedef pixman_fixed_32_32_t pixman_fixed_34_30_t; |
154 | { |
48 | 155 | *rlo = hi >> (-scalebits); |
|
- | 156 | *rhi = *rlo >> 63; |
|
49 | PIXMAN_EXPORT pixman_bool_t |
157 | } |
- | 158 | else |
|
- | 159 | { |
|
- | 160 | *rhi = hi >> (64 - scalebits); |
|
Line -... | Line 161... | ||
- | 161 | *rlo = (uint64_t)hi << scalebits; |
|
- | 162 | if (scalebits < 16) |
|
50 | pixman_transform_point_3d (const struct pixman_transform *transform, |
163 | *rlo += lo >> (16 - scalebits); |
- | 164 | else |
|
- | 165 | *rlo += lo << (scalebits - 16); |
|
- | 166 | } |
|
51 | struct pixman_vector * vector) |
167 | } |
- | 168 | ||
- | 169 | /* |
|
- | 170 | * Convert 112.16 fixed point value to 48.16 with clamping for the out |
|
- | 171 | * of range values. |
|
- | 172 | */ |
|
- | 173 | static force_inline pixman_fixed_48_16_t |
|
52 | { |
174 | fixed_112_16_to_fixed_48_16 (int64_t hi, int64_t lo, pixman_bool_t *clampflag) |
- | 175 | { |
|
- | 176 | if ((lo >> 63) != hi) |
|
- | 177 | { |
|
- | 178 | *clampflag = TRUE; |
|
- | 179 | return hi >= 0 ? INT64_MAX : INT64_MIN; |
|
- | 180 | } |
|
- | 181 | else |
|
- | 182 | { |
|
- | 183 | return lo; |
|
- | 184 | } |
|
- | 185 | } |
|
- | 186 | ||
- | 187 | /* |
|
- | 188 | * Transform a point with 31.16 fixed point coordinates from the destination |
|
- | 189 | * space to a point with 48.16 fixed point coordinates in the source space. |
|
- | 190 | * No overflows are possible for affine transformations and the results are |
|
- | 191 | * accurate including the least significant bit. Projective transformations |
|
- | 192 | * may overflow, in this case the results are just clamped to return maximum |
|
- | 193 | * or minimum 48.16 values (so that the caller can at least handle the NONE |
|
- | 194 | * and PAD repeats correctly) and the return value is FALSE to indicate that |
|
- | 195 | * such clamping has happened. |
|
- | 196 | */ |
|
- | 197 | PIXMAN_EXPORT pixman_bool_t |
|
- | 198 | pixman_transform_point_31_16 (const pixman_transform_t *t, |
|
- | 199 | const pixman_vector_48_16_t *v, |
|
- | 200 | pixman_vector_48_16_t *result) |
|
- | 201 | { |
|
- | 202 | pixman_bool_t clampflag = FALSE; |
|
- | 203 | int i; |
|
- | 204 | int64_t tmp[3][2], divint; |
|
- | 205 | uint16_t divfrac; |
|
- | 206 | ||
- | 207 | /* input vector values must have no more than 31 bits (including sign) |
|
53 | struct pixman_vector result; |
208 | * in the integer part */ |
54 | pixman_fixed_32_32_t partial; |
209 | assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
- | 210 | assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
55 | pixman_fixed_48_16_t v; |
211 | assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
56 | int i, j; |
212 | assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
- | 213 | assert (v->v[2] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
57 | 214 | assert (v->v[2] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 215 | ||
58 | for (j = 0; j < 3; j++) |
216 | for (i = 0; i < 3; i++) |
Line -... | Line 217... | ||
- | 217 | { |
|
- | 218 | tmp[i][0] = (int64_t)t->matrix[i][0] * (v->v[0] >> 16); |
|
59 | { |
219 | tmp[i][1] = (int64_t)t->matrix[i][0] * (v->v[0] & 0xFFFF); |
60 | v = 0; |
220 | tmp[i][0] += (int64_t)t->matrix[i][1] * (v->v[1] >> 16); |
- | 221 | tmp[i][1] += (int64_t)t->matrix[i][1] * (v->v[1] & 0xFFFF); |
|
- | 222 | tmp[i][0] += (int64_t)t->matrix[i][2] * (v->v[2] >> 16); |
|
Line -... | Line 223... | ||
- | 223 | tmp[i][1] += (int64_t)t->matrix[i][2] * (v->v[2] & 0xFFFF); |
|
- | 224 | } |
|
- | 225 | ||
- | 226 | /* |
|
- | 227 | * separate 64-bit integer and 16-bit fractional parts for the divisor, |
|
- | 228 | * which is also scaled by 65536 after fixed point multiplication. |
|
- | 229 | */ |
|
61 | for (i = 0; i < 3; i++) |
230 | divint = tmp[2][0] + (tmp[2][1] >> 16); |
62 | { |
231 | divfrac = tmp[2][1] & 0xFFFF; |
- | 232 | ||
- | 233 | if (divint == pixman_fixed_1 && divfrac == 0) |
|
- | 234 | { |
|
- | 235 | /* |
|
- | 236 | * this is a simple affine transformation |
|
- | 237 | */ |
|
- | 238 | result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16); |
|
Line -... | Line 239... | ||
- | 239 | result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16); |
|
63 | partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] * |
240 | result->v[2] = pixman_fixed_1; |
Line 64... | Line 241... | ||
64 | (pixman_fixed_48_16_t) vector->vector[i]); |
241 | } |
- | 242 | else if (divint == 0 && divfrac == 0) |
|
- | 243 | { |
|
- | 244 | /* |
|
- | 245 | * handle zero divisor (if the values are non-zero, set the |
|
- | 246 | * results to maximum positive or minimum negative) |
|
- | 247 | */ |
|
- | 248 | clampflag = TRUE; |
|
- | 249 | ||
- | 250 | result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16); |
|
- | 251 | result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16); |
|
- | 252 | ||
- | 253 | if (result->v[0] > 0) |
|
- | 254 | result->v[0] = INT64_MAX; |
|
- | 255 | else if (result->v[0] < 0) |
|
- | 256 | result->v[0] = INT64_MIN; |
|
- | 257 | ||
- | 258 | if (result->v[1] > 0) |
|
- | 259 | result->v[1] = INT64_MAX; |
|
- | 260 | else if (result->v[1] < 0) |
|
- | 261 | result->v[1] = INT64_MIN; |
|
- | 262 | } |
|
- | 263 | else |
|
- | 264 | { |
|
- | 265 | /* |
|
- | 266 | * projective transformation, analyze the top 32 bits of the divisor |
|
- | 267 | */ |
|
- | 268 | int32_t hi32divbits = divint >> 32; |
|
- | 269 | if (hi32divbits < 0) |
|
- | 270 | hi32divbits = ~hi32divbits; |
|
- | 271 | ||
- | 272 | if (hi32divbits == 0) |
|
- | 273 | { |
|
- | 274 | /* the divisor is small, we can actually keep all the bits */ |
|
- | 275 | int64_t hi, rhi, lo, rlo; |
|
- | 276 | int64_t div = (divint << 16) + divfrac; |
|
- | 277 | ||
- | 278 | fixed_64_16_to_int128 (tmp[0][0], tmp[0][1], &hi, &lo, 32); |
|
- | 279 | rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); |
|
- | 280 | result->v[0] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); |
|
- | 281 | ||
- | 282 | fixed_64_16_to_int128 (tmp[1][0], tmp[1][1], &hi, &lo, 32); |
|
- | 283 | rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); |
|
- | 284 | result->v[1] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); |
|
- | 285 | } |
|
- | 286 | else |
|
- | 287 | { |
|
- | 288 | /* the divisor needs to be reduced to 48 bits */ |
|
- | 289 | int64_t hi, rhi, lo, rlo, div; |
|
- | 290 | int shift = 32 - count_leading_zeros (hi32divbits); |
|
65 | v += partial >> 16; |
291 | fixed_64_16_to_int128 (divint, divfrac, &hi, &div, 16 - shift); |
- | 292 | ||
Line 66... | Line 293... | ||
66 | } |
293 | fixed_64_16_to_int128 (tmp[0][0], tmp[0][1], &hi, &lo, 32 - shift); |
- | 294 | rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); |
|
- | 295 | result->v[0] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); |
|
- | 296 | ||
- | 297 | fixed_64_16_to_int128 (tmp[1][0], tmp[1][1], &hi, &lo, 32 - shift); |
|
- | 298 | rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); |
|
- | 299 | result->v[1] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); |
|
- | 300 | } |
|
- | 301 | } |
|
- | 302 | result->v[2] = pixman_fixed_1; |
|
- | 303 | return !clampflag; |
|
- | 304 | } |
|
- | 305 | ||
- | 306 | PIXMAN_EXPORT void |
|
- | 307 | pixman_transform_point_31_16_affine (const pixman_transform_t *t, |
|
- | 308 | const pixman_vector_48_16_t *v, |
|
- | 309 | pixman_vector_48_16_t *result) |
|
- | 310 | { |
|
- | 311 | int64_t hi0, lo0, hi1, lo1; |
|
- | 312 | ||
- | 313 | /* input vector values must have no more than 31 bits (including sign) |
|
- | 314 | * in the integer part */ |
|
- | 315 | assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 316 | assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 317 | assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 318 | assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 319 | ||
- | 320 | hi0 = (int64_t)t->matrix[0][0] * (v->v[0] >> 16); |
|
- | 321 | lo0 = (int64_t)t->matrix[0][0] * (v->v[0] & 0xFFFF); |
|
67 | 322 | hi0 += (int64_t)t->matrix[0][1] * (v->v[1] >> 16); |
|
Line 68... | Line 323... | ||
68 | if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16) |
323 | lo0 += (int64_t)t->matrix[0][1] * (v->v[1] & 0xFFFF); |
69 | return FALSE; |
324 | hi0 += (int64_t)t->matrix[0][2]; |
- | 325 | ||
70 | 326 | hi1 = (int64_t)t->matrix[1][0] * (v->v[0] >> 16); |
|
71 | result.vector[j] = (pixman_fixed_t) v; |
327 | lo1 = (int64_t)t->matrix[1][0] * (v->v[0] & 0xFFFF); |
72 | } |
- | |
73 | - | ||
74 | *vector = result; |
328 | hi1 += (int64_t)t->matrix[1][1] * (v->v[1] >> 16); |
75 | 329 | lo1 += (int64_t)t->matrix[1][1] * (v->v[1] & 0xFFFF); |
|
Line -... | Line 330... | ||
- | 330 | hi1 += (int64_t)t->matrix[1][2]; |
|
76 | if (!result.vector[2]) |
331 | |
77 | return FALSE; |
- | |
- | 332 | result->v[0] = hi0 + ((lo0 + 0x8000) >> 16); |
|
78 | 333 | result->v[1] = hi1 + ((lo1 + 0x8000) >> 16); |
|
- | 334 | result->v[2] = pixman_fixed_1; |
|
- | 335 | } |
|
- | 336 | ||
- | 337 | PIXMAN_EXPORT void |
|
Line 79... | Line 338... | ||
79 | return TRUE; |
338 | pixman_transform_point_31_16_3d (const pixman_transform_t *t, |
80 | } |
339 | const pixman_vector_48_16_t *v, |
- | 340 | pixman_vector_48_16_t *result) |
|
81 | 341 | { |
|
82 | PIXMAN_EXPORT pixman_bool_t |
342 | int i; |
- | 343 | int64_t tmp[3][2]; |
|
83 | pixman_transform_point (const struct pixman_transform *transform, |
344 | |
- | 345 | /* input vector values must have no more than 31 bits (including sign) |
|
84 | struct pixman_vector * vector) |
346 | * in the integer part */ |
- | 347 | assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 348 | assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 349 | assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 350 | assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
85 | { |
351 | assert (v->v[2] < ((pixman_fixed_48_16_t)1 << (30 + 16))); |
Line -... | Line 352... | ||
- | 352 | assert (v->v[2] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); |
|
- | 353 | ||
- | 354 | for (i = 0; i < 3; i++) |
|
- | 355 | { |
|
- | 356 | tmp[i][0] = (int64_t)t->matrix[i][0] * (v->v[0] >> 16); |
|
- | 357 | tmp[i][1] = (int64_t)t->matrix[i][0] * (v->v[0] & 0xFFFF); |
|
86 | pixman_fixed_32_32_t partial; |
358 | tmp[i][0] += (int64_t)t->matrix[i][1] * (v->v[1] >> 16); |
87 | pixman_fixed_34_30_t v[3]; |
359 | tmp[i][1] += (int64_t)t->matrix[i][1] * (v->v[1] & 0xFFFF); |
- | 360 | tmp[i][0] += (int64_t)t->matrix[i][2] * (v->v[2] >> 16); |
|
- | 361 | tmp[i][1] += (int64_t)t->matrix[i][2] * (v->v[2] & 0xFFFF); |
|
- | 362 | } |
|
- | 363 | ||
- | 364 | result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16); |
|
- | 365 | result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16); |
|
- | 366 | result->v[2] = tmp[2][0] + ((tmp[2][1] + 0x8000) >> 16); |
|
- | 367 | } |
|
- | 368 | ||
- | 369 | PIXMAN_EXPORT void |
|
- | 370 | pixman_transform_init_identity (struct pixman_transform *matrix) |
|
- | 371 | { |
|
- | 372 | int i; |
|
- | 373 | ||
- | 374 | memset (matrix, '\0', sizeof (struct pixman_transform)); |
|
- | 375 | for (i = 0; i < 3; i++) |
|
- | 376 | matrix->matrix[i][i] = F (1); |
|
- | 377 | } |
|
- | 378 | ||
- | 379 | typedef pixman_fixed_32_32_t pixman_fixed_34_30_t; |
|
- | 380 | ||
- | 381 | PIXMAN_EXPORT pixman_bool_t |
|
- | 382 | pixman_transform_point_3d (const struct pixman_transform *transform, |
|
Line 88... | Line 383... | ||
88 | pixman_fixed_48_16_t quo; |
383 | struct pixman_vector * vector) |
- | 384 | { |
|
- | 385 | pixman_vector_48_16_t tmp; |
|
89 | int i, j; |
386 | tmp.v[0] = vector->vector[0]; |
- | 387 | tmp.v[1] = vector->vector[1]; |
|
- | 388 | tmp.v[2] = vector->vector[2]; |
|
- | 389 | ||
90 | 390 | pixman_transform_point_31_16_3d (transform, &tmp, &tmp); |
|
- | 391 | ||
91 | for (j = 0; j < 3; j++) |
392 | vector->vector[0] = tmp.v[0]; |
92 | { |
393 | vector->vector[1] = tmp.v[1]; |
93 | v[j] = 0; |
- | |
94 | - | ||
Line -... | Line 394... | ||
- | 394 | vector->vector[2] = tmp.v[2]; |
|
95 | for (i = 0; i < 3; i++) |
395 | |
96 | { |
396 | return vector->vector[0] == tmp.v[0] && |
- | 397 | vector->vector[1] == tmp.v[1] && |
|
- | 398 | vector->vector[2] == tmp.v[2]; |
|
- | 399 | } |
|
- | 400 | ||
97 | partial = ((pixman_fixed_32_32_t) transform->matrix[j][i] * |
401 | PIXMAN_EXPORT pixman_bool_t |
Line 98... | Line 402... | ||
98 | (pixman_fixed_32_32_t) vector->vector[i]); |
402 | pixman_transform_point (const struct pixman_transform *transform, |
99 | v[j] += partial >> 2; |
403 | struct pixman_vector * vector) |
100 | } |
404 | { |
Line 136... | Line 440... | ||
136 | { |
440 | { |
137 | partial = |
441 | partial = |
138 | (pixman_fixed_32_32_t) l->matrix[dy][o] * |
442 | (pixman_fixed_32_32_t) l->matrix[dy][o] * |
139 | (pixman_fixed_32_32_t) r->matrix[o][dx]; |
443 | (pixman_fixed_32_32_t) r->matrix[o][dx]; |
Line 140... | Line 444... | ||
140 | 444 | ||
141 | v += partial >> 16; |
445 | v += (partial + 0x8000) >> 16; |
Line 142... | Line 446... | ||
142 | } |
446 | } |
143 | 447 | ||
Line 334... | Line 638... | ||
334 | 638 | ||
335 | PIXMAN_EXPORT pixman_bool_t |
639 | PIXMAN_EXPORT pixman_bool_t |
336 | pixman_transform_invert (struct pixman_transform * dst, |
640 | pixman_transform_invert (struct pixman_transform * dst, |
337 | const struct pixman_transform *src) |
641 | const struct pixman_transform *src) |
338 | { |
642 | { |
Line 339... | Line 643... | ||
339 | struct pixman_f_transform m, r; |
643 | struct pixman_f_transform m; |
Line 340... | Line 644... | ||
340 | 644 | ||
341 | pixman_f_transform_from_pixman_transform (&m, src); |
645 | pixman_f_transform_from_pixman_transform (&m, src); |
Line 342... | Line 646... | ||
342 | 646 | ||
343 | if (!pixman_f_transform_invert (&r, &m)) |
647 | if (!pixman_f_transform_invert (&m, &m)) |
Line 344... | Line 648... | ||
344 | return FALSE; |
648 | return FALSE; |
345 | 649 | ||
Line 423... | Line 727... | ||
423 | pixman_transform_is_inverse (const struct pixman_transform *a, |
727 | pixman_transform_is_inverse (const struct pixman_transform *a, |
424 | const struct pixman_transform *b) |
728 | const struct pixman_transform *b) |
425 | { |
729 | { |
426 | struct pixman_transform t; |
730 | struct pixman_transform t; |
Line 427... | Line 731... | ||
427 | 731 | ||
- | 732 | if (!pixman_transform_multiply (&t, a, b)) |
|
Line 428... | Line 733... | ||
428 | pixman_transform_multiply (&t, a, b); |
733 | return FALSE; |
429 | 734 | ||
Line 430... | Line 735... | ||
430 | return pixman_transform_is_identity (&t); |
735 | return pixman_transform_is_identity (&t); |
Line 462... | Line 767... | ||
462 | } |
767 | } |
Line 463... | Line 768... | ||
463 | 768 | ||
464 | return TRUE; |
769 | return TRUE; |
Line 465... | Line -... | ||
465 | } |
- | |
466 | - | ||
467 | static const int a[3] = { 3, 3, 2 }; |
- | |
468 | static const int b[3] = { 2, 1, 1 }; |
770 | } |
469 | 771 | ||
470 | PIXMAN_EXPORT pixman_bool_t |
772 | PIXMAN_EXPORT pixman_bool_t |
471 | pixman_f_transform_invert (struct pixman_f_transform * dst, |
773 | pixman_f_transform_invert (struct pixman_f_transform * dst, |
- | 774 | const struct pixman_f_transform *src) |
|
- | 775 | { |
|
- | 776 | static const int a[3] = { 2, 2, 1 }; |
|
472 | const struct pixman_f_transform *src) |
777 | static const int b[3] = { 1, 0, 0 }; |
473 | { |
778 | pixman_f_transform_t d; |
474 | double det; |
- | |
475 | int i, j; |
- | |
Line 476... | Line 779... | ||
476 | static int a[3] = { 2, 2, 1 }; |
779 | double det; |
477 | static int b[3] = { 1, 0, 0 }; |
780 | int i, j; |
478 | 781 | ||
479 | det = 0; |
782 | det = 0; |
Line 507... | Line 810... | ||
507 | src->m[ai][bj] * src->m[bi][aj]); |
810 | src->m[ai][bj] * src->m[bi][aj]); |
Line 508... | Line 811... | ||
508 | 811 | ||
509 | if (((i + j) & 1) != 0) |
812 | if (((i + j) & 1) != 0) |
Line 510... | Line 813... | ||
510 | p = -p; |
813 | p = -p; |
511 | 814 | ||
512 | dst->m[j][i] = det * p; |
815 | d.m[j][i] = det * p; |
Line -... | Line 816... | ||
- | 816 | } |
|
- | 817 | } |
|
513 | } |
818 | |
514 | } |
819 | *dst = d; |
Line 515... | Line 820... | ||
515 | 820 | ||
516 | return TRUE; |
821 | return TRUE; |