2 * Copyright © 2000 SuSE, Inc.
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
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of SuSE not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. SuSE makes no representations about the
11 * suitability of this software for any purpose. It is provided "as is"
12 * without express or implied warranty.
14 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
16 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Author: Keith Packard, SuSE, Inc.
30 #include "pixman-private.h"
31 #include "pixman-mmx.h"
34 pixman_transform_point_3d (pixman_transform_t *transform,
35 pixman_vector_t *vector)
37 pixman_vector_t result;
39 pixman_fixed_32_32_t partial;
40 pixman_fixed_48_16_t v;
42 for (j = 0; j < 3; j++)
45 for (i = 0; i < 3; i++)
47 partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
48 (pixman_fixed_48_16_t) vector->vector[i]);
52 if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
55 result.vector[j] = (pixman_fixed_48_16_t) v;
58 if (!result.vector[2])
66 pixman_blt (uint32_t *src_bits,
74 int width, int height)
77 if (pixman_have_mmx())
79 return pixman_blt_mmx (src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
80 src_x, src_y, dst_x, dst_y, width, height);
88 pixman_fill8 (uint32_t *bits,
96 int byte_stride = stride * (int) sizeof (uint32_t);
97 uint8_t *dst = (uint8_t *) bits;
98 uint8_t v = xor & 0xff;
101 dst = dst + y * byte_stride + x;
105 for (i = 0; i < width; ++i)
113 pixman_fill16 (uint32_t *bits,
121 int short_stride = (stride * (int) sizeof (uint32_t)) / (int) sizeof (uint16_t);
122 uint16_t *dst = (uint16_t *)bits;
123 uint16_t v = xor & 0xffff;
126 dst = dst + y * short_stride + x;
130 for (i = 0; i < width; ++i)
138 pixman_fill32 (uint32_t *bits,
148 bits = bits + y * stride + x;
152 for (i = 0; i < width; ++i)
160 pixman_fill (uint32_t *bits,
170 printf ("filling: %d %d %d %d (stride: %d, bpp: %d) pixel: %x\n",
171 x, y, width, height, stride, bpp, xor);
175 if (!pixman_have_mmx() || !pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
181 pixman_fill8 (bits, stride, x, y, width, height, xor);
185 pixman_fill16 (bits, stride, x, y, width, height, xor);
189 pixman_fill32 (bits, stride, x, y, width, height, xor);
203 * Compute the smallest value no less than y which is on a
208 pixman_sample_ceil_y (pixman_fixed_t y, int n)
210 pixman_fixed_t f = pixman_fixed_frac(y);
211 pixman_fixed_t i = pixman_fixed_floor(y);
213 f = ((f + Y_FRAC_FIRST(n)) / STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
214 if (f > Y_FRAC_LAST(n))
222 #define _div(a,b) ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b)))
225 * Compute the largest value no greater than y which is on a
229 pixman_sample_floor_y (pixman_fixed_t y, int n)
231 pixman_fixed_t f = pixman_fixed_frac(y);
232 pixman_fixed_t i = pixman_fixed_floor (y);
234 f = _div(f - Y_FRAC_FIRST(n), STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
235 if (f < Y_FRAC_FIRST(n))
244 * Step an edge by any amount (including negative values)
247 pixman_edge_step (pixman_edge_t *e, int n)
249 pixman_fixed_48_16_t ne;
251 e->x += n * e->stepx;
253 ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
259 int nx = (ne + e->dy - 1) / e->dy;
260 e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
261 e->x += nx * e->signdx;
268 int nx = (-ne) / e->dy;
269 e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
270 e->x -= nx * e->signdx;
276 * A private routine to initialize the multi-step
277 * elements of an edge structure
280 _pixman_edge_tMultiInit (pixman_edge_t *e, int n, pixman_fixed_t *stepx_p, pixman_fixed_t *dx_p)
282 pixman_fixed_t stepx;
283 pixman_fixed_48_16_t ne;
285 ne = n * (pixman_fixed_48_16_t) e->dx;
286 stepx = n * e->stepx;
291 stepx += nx * e->signdx;
298 * Initialize one edge structure given the line endpoints and a
302 pixman_edge_init (pixman_edge_t *e,
304 pixman_fixed_t y_start,
305 pixman_fixed_t x_top,
306 pixman_fixed_t y_top,
307 pixman_fixed_t x_bot,
308 pixman_fixed_t y_bot)
310 pixman_fixed_t dx, dy;
330 e->stepx = -(-dx / dy);
335 _pixman_edge_tMultiInit (e, STEP_Y_SMALL(n), &e->stepx_small, &e->dx_small);
336 _pixman_edge_tMultiInit (e, STEP_Y_BIG(n), &e->stepx_big, &e->dx_big);
338 pixman_edge_step (e, y_start - y_top);
342 * Initialize one edge structure given a line, starting y value
343 * and a pixel offset for the line
346 pixman_line_fixed_edge_init (pixman_edge_t *e,
349 const pixman_line_fixed_t *line,
353 pixman_fixed_t x_off_fixed = pixman_int_to_fixed(x_off);
354 pixman_fixed_t y_off_fixed = pixman_int_to_fixed(y_off);
355 const pixman_point_fixed_t *top, *bot;
357 if (line->p1.y <= line->p2.y)
367 pixman_edge_init (e, n, y,
368 top->x + x_off_fixed,
369 top->y + y_off_fixed,
370 bot->x + x_off_fixed,
371 bot->y + y_off_fixed);
375 pixman_multiply_overflows_int (unsigned int a,
378 return a >= INT32_MAX / b;
382 pixman_addition_overflows_int (unsigned int a,
385 return a > INT32_MAX - b;
389 pixman_malloc_ab(unsigned int a,
392 if (a >= INT32_MAX / b)
395 return malloc (a * b);
399 pixman_malloc_abc (unsigned int a,
403 if (a >= INT32_MAX / b)
405 else if (a * b >= INT32_MAX / c)
408 return malloc (a * b * c);