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 * 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 * sizeof (uint32_t)) / 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);