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.
27 #include "pixman-private.h"
28 #include "pixman-mmx.h"
31 pixman_transform_point_3d (pixman_transform_t *transform,
32 pixman_vector_t *vector)
34 pixman_vector_t result;
36 pixman_fixed_32_32_t partial;
37 pixman_fixed_48_16_t v;
39 for (j = 0; j < 3; j++)
42 for (i = 0; i < 3; i++)
44 partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
45 (pixman_fixed_48_16_t) vector->vector[i]);
49 if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
52 result.vector[j] = (pixman_fixed_48_16_t) v;
55 if (!result.vector[2])
63 pixman_blt (uint32_t *src_bits,
71 int width, int height)
74 if (pixman_have_mmx())
76 return pixman_blt_mmx (src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
77 src_x, src_y, dst_x, dst_y, width, height);
85 pixman_fill8 (uint32_t *bits,
93 int byte_stride = stride * (int) sizeof (uint32_t);
94 uint8_t *dst = (uint8_t *) bits;
95 uint8_t v = xor & 0xff;
98 dst = dst + y * byte_stride + x;
102 for (i = 0; i < width; ++i)
110 pixman_fill16 (uint32_t *bits,
118 int short_stride = (stride * (int) sizeof (uint32_t)) / (int) sizeof (uint16_t);
119 uint16_t *dst = (uint16_t *)bits;
120 uint16_t v = xor & 0xffff;
123 dst = dst + y * short_stride + x;
127 for (i = 0; i < width; ++i)
135 pixman_fill32 (uint32_t *bits,
145 bits = bits + y * stride + x;
149 for (i = 0; i < width; ++i)
157 pixman_fill (uint32_t *bits,
167 printf ("filling: %d %d %d %d (stride: %d, bpp: %d) pixel: %x\n",
168 x, y, width, height, stride, bpp, xor);
172 if (!pixman_have_mmx() || !pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
178 pixman_fill8 (bits, stride, x, y, width, height, xor);
182 pixman_fill16 (bits, stride, x, y, width, height, xor);
186 pixman_fill32 (bits, stride, x, y, width, height, xor);
200 * Compute the smallest value no less than y which is on a
205 pixman_sample_ceil_y (pixman_fixed_t y, int n)
207 pixman_fixed_t f = pixman_fixed_frac(y);
208 pixman_fixed_t i = pixman_fixed_floor(y);
210 f = ((f + Y_FRAC_FIRST(n)) / STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
211 if (f > Y_FRAC_LAST(n))
219 #define _div(a,b) ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b)))
222 * Compute the largest value no greater than y which is on a
226 pixman_sample_floor_y (pixman_fixed_t y, int n)
228 pixman_fixed_t f = pixman_fixed_frac(y);
229 pixman_fixed_t i = pixman_fixed_floor (y);
231 f = _div(f - Y_FRAC_FIRST(n), STEP_Y_SMALL(n)) * STEP_Y_SMALL(n) + Y_FRAC_FIRST(n);
232 if (f < Y_FRAC_FIRST(n))
241 * Step an edge by any amount (including negative values)
244 pixman_edge_step (pixman_edge_t *e, int n)
246 pixman_fixed_48_16_t ne;
248 e->x += n * e->stepx;
250 ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
256 int nx = (ne + e->dy - 1) / e->dy;
257 e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
258 e->x += nx * e->signdx;
265 int nx = (-ne) / e->dy;
266 e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
267 e->x -= nx * e->signdx;
273 * A private routine to initialize the multi-step
274 * elements of an edge structure
277 _pixman_edge_tMultiInit (pixman_edge_t *e, int n, pixman_fixed_t *stepx_p, pixman_fixed_t *dx_p)
279 pixman_fixed_t stepx;
280 pixman_fixed_48_16_t ne;
282 ne = n * (pixman_fixed_48_16_t) e->dx;
283 stepx = n * e->stepx;
288 stepx += nx * e->signdx;
295 * Initialize one edge structure given the line endpoints and a
299 pixman_edge_init (pixman_edge_t *e,
301 pixman_fixed_t y_start,
302 pixman_fixed_t x_top,
303 pixman_fixed_t y_top,
304 pixman_fixed_t x_bot,
305 pixman_fixed_t y_bot)
307 pixman_fixed_t dx, dy;
327 e->stepx = -(-dx / dy);
332 _pixman_edge_tMultiInit (e, STEP_Y_SMALL(n), &e->stepx_small, &e->dx_small);
333 _pixman_edge_tMultiInit (e, STEP_Y_BIG(n), &e->stepx_big, &e->dx_big);
335 pixman_edge_step (e, y_start - y_top);
339 * Initialize one edge structure given a line, starting y value
340 * and a pixel offset for the line
343 pixman_line_fixed_edge_init (pixman_edge_t *e,
346 const pixman_line_fixed_t *line,
350 pixman_fixed_t x_off_fixed = pixman_int_to_fixed(x_off);
351 pixman_fixed_t y_off_fixed = pixman_int_to_fixed(y_off);
352 const pixman_point_fixed_t *top, *bot;
354 if (line->p1.y <= line->p2.y)
364 pixman_edge_init (e, n, y,
365 top->x + x_off_fixed,
366 top->y + y_off_fixed,
367 bot->x + x_off_fixed,
368 bot->y + y_off_fixed);
372 pixman_malloc_ab(unsigned int a,
375 if (a >= INT32_MAX / b)
378 return malloc (a * b);
382 pixman_malloc_abc (unsigned int a,
386 if (a >= INT32_MAX / b)
388 else if (a * b >= INT32_MAX / c)
391 return malloc (a * b * c);