~ubuntu-branches/debian/squeeze/pixman/squeeze

« back to all changes in this revision

Viewing changes to pixman/pixman-utils.c

  • Committer: Bazaar Package Importer
  • Author(s): David Nusinow
  • Date: 2007-08-09 22:15:45 UTC
  • Revision ID: james.westby@ubuntu.com-20070809221545-b3rj83wnluotrybv
Tags: upstream-0.9.4
Import upstream version 0.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2000 SuSE, Inc.
 
3
 *
 
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.
 
13
 *
 
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.
 
20
 *
 
21
 * Author:  Keith Packard, SuSE, Inc.
 
22
 */
 
23
 
 
24
#include <config.h>
 
25
#include <stdlib.h>
 
26
#include "pixman.h"
 
27
#include "pixman-private.h"
 
28
#include "pixman-mmx.h"
 
29
 
 
30
pixman_bool_t
 
31
pixman_transform_point_3d (pixman_transform_t *transform,
 
32
                           pixman_vector_t *vector)
 
33
{
 
34
    pixman_vector_t             result;
 
35
    int                         i, j;
 
36
    pixman_fixed_32_32_t        partial;
 
37
    pixman_fixed_48_16_t        v;
 
38
 
 
39
    for (j = 0; j < 3; j++)
 
40
    {
 
41
        v = 0;
 
42
        for (i = 0; i < 3; i++)
 
43
        {
 
44
            partial = ((pixman_fixed_48_16_t) transform->matrix[j][i] *
 
45
                       (pixman_fixed_48_16_t) vector->vector[i]);
 
46
            v += partial >> 16;
 
47
        }
 
48
 
 
49
        if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16)
 
50
            return FALSE;
 
51
 
 
52
        result.vector[j] = (pixman_fixed_48_16_t) v;
 
53
    }
 
54
    
 
55
    if (!result.vector[2])
 
56
        return FALSE;
 
57
    
 
58
    *vector = result;
 
59
    return TRUE;
 
60
}
 
61
 
 
62
pixman_bool_t
 
63
pixman_blt (uint32_t *src_bits,
 
64
            uint32_t *dst_bits,
 
65
            int src_stride,
 
66
            int dst_stride,
 
67
            int src_bpp,
 
68
            int dst_bpp,
 
69
            int src_x, int src_y,
 
70
            int dst_x, int dst_y,
 
71
            int width, int height)
 
72
{
 
73
#ifdef USE_MMX
 
74
    if (pixman_have_mmx())
 
75
    {
 
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);
 
78
    }
 
79
    else
 
80
#endif
 
81
        return FALSE;
 
82
}
 
83
 
 
84
static void
 
85
pixman_fill8 (uint32_t  *bits,
 
86
              int       stride,
 
87
              int       x,
 
88
              int       y,
 
89
              int       width,
 
90
              int       height,
 
91
              uint32_t  xor)
 
92
{
 
93
    int byte_stride = stride * sizeof (uint32_t);
 
94
    uint8_t *dst = (uint8_t *) bits;
 
95
    uint8_t v = xor & 0xff;
 
96
    int i;
 
97
 
 
98
    dst = dst + y * byte_stride + x;
 
99
 
 
100
    while (height--)
 
101
    {
 
102
        for (i = 0; i < width; ++i)
 
103
            dst[i] = v;
 
104
 
 
105
        dst += byte_stride;
 
106
    }
 
107
}
 
108
 
 
109
static void
 
110
pixman_fill16 (uint32_t *bits,
 
111
               int       stride,
 
112
               int       x,
 
113
               int       y,
 
114
               int       width,
 
115
               int       height,
 
116
               uint32_t  xor)
 
117
{
 
118
    int short_stride = (stride * sizeof (uint32_t)) / sizeof (uint16_t);
 
119
    uint16_t *dst = (uint16_t *)bits;
 
120
    uint16_t v = xor & 0xffff;
 
121
    int i;
 
122
 
 
123
    dst = dst + y * short_stride + x;
 
124
 
 
125
    while (height--)
 
126
    {
 
127
        for (i = 0; i < width; ++i)
 
128
            dst[i] = v;
 
129
 
 
130
        dst += short_stride;
 
131
    }
 
132
}
 
133
 
 
134
static void
 
135
pixman_fill32 (uint32_t *bits,
 
136
               int       stride,
 
137
               int       x,
 
138
               int       y,
 
139
               int       width,
 
140
               int       height,
 
141
               uint32_t  xor)
 
142
{
 
143
    int i;
 
144
    
 
145
    bits = bits + y * stride + x;
 
146
    
 
147
    while (height--)
 
148
    {
 
149
        for (i = 0; i < width; ++i)
 
150
            bits[i] = xor;
 
151
 
 
152
        bits += stride;
 
153
    }
 
154
}
 
155
 
 
156
pixman_bool_t
 
157
pixman_fill (uint32_t *bits,
 
158
             int stride,
 
159
             int bpp,
 
160
             int x,
 
161
             int y,
 
162
             int width,
 
163
             int height,
 
164
             uint32_t xor)
 
165
{
 
166
#if 0
 
167
    printf ("filling: %d %d %d %d (stride: %d, bpp: %d)   pixel: %x\n",
 
168
            x, y, width, height, stride, bpp, xor);
 
169
#endif
 
170
    
 
171
#ifdef USE_MMX
 
172
    if (!pixman_have_mmx() || !pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
 
173
#endif
 
174
    {
 
175
        switch (bpp)
 
176
        {
 
177
        case 8:
 
178
            pixman_fill8 (bits, stride, x, y, width, height, xor);
 
179
            break;
 
180
            
 
181
        case 16:
 
182
            pixman_fill16 (bits, stride, x, y, width, height, xor);
 
183
            break;
 
184
            
 
185
        case 32:
 
186
            pixman_fill32 (bits, stride, x, y, width, height, xor);
 
187
            break;
 
188
 
 
189
        default:
 
190
            return FALSE;
 
191
            break;
 
192
        }
 
193
    }
 
194
        
 
195
    return TRUE;
 
196
}
 
197
            
 
198
 
 
199
/*
 
200
 * Compute the smallest value no less than y which is on a
 
201
 * grid row
 
202
 */
 
203
 
 
204
pixman_fixed_t
 
205
pixman_sample_ceil_y (pixman_fixed_t y, int n)
 
206
{
 
207
    pixman_fixed_t   f = pixman_fixed_frac(y);
 
208
    pixman_fixed_t   i = pixman_fixed_floor(y);
 
209
    
 
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))
 
212
    {
 
213
        f = Y_FRAC_FIRST(n);
 
214
        i += pixman_fixed_1;
 
215
    }
 
216
    return (i | f);
 
217
}
 
218
 
 
219
#define _div(a,b)    ((a) >= 0 ? (a) / (b) : -((-(a) + (b) - 1) / (b)))
 
220
 
 
221
/*
 
222
 * Compute the largest value no greater than y which is on a
 
223
 * grid row
 
224
 */
 
225
pixman_fixed_t
 
226
pixman_sample_floor_y (pixman_fixed_t y, int n)
 
227
{
 
228
    pixman_fixed_t   f = pixman_fixed_frac(y);
 
229
    pixman_fixed_t   i = pixman_fixed_floor (y);
 
230
    
 
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))
 
233
    {
 
234
        f = Y_FRAC_LAST(n);
 
235
        i -= pixman_fixed_1;
 
236
    }
 
237
    return (i | f);
 
238
}
 
239
 
 
240
/*
 
241
 * Step an edge by any amount (including negative values)
 
242
 */
 
243
void
 
244
pixman_edge_step (pixman_edge_t *e, int n)
 
245
{
 
246
    pixman_fixed_48_16_t        ne;
 
247
 
 
248
    e->x += n * e->stepx;
 
249
    
 
250
    ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
 
251
    
 
252
    if (n >= 0)
 
253
    {
 
254
        if (ne > 0)
 
255
        {
 
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;
 
259
        }
 
260
    }
 
261
    else
 
262
    {
 
263
        if (ne <= -e->dy)
 
264
        {
 
265
            int nx = (-ne) / e->dy;
 
266
            e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
 
267
            e->x -= nx * e->signdx;
 
268
        }
 
269
    }
 
270
}
 
271
 
 
272
/*
 
273
 * A private routine to initialize the multi-step
 
274
 * elements of an edge structure
 
275
 */
 
276
static void
 
277
_pixman_edge_tMultiInit (pixman_edge_t *e, int n, pixman_fixed_t *stepx_p, pixman_fixed_t *dx_p)
 
278
{
 
279
    pixman_fixed_t      stepx;
 
280
    pixman_fixed_48_16_t        ne;
 
281
    
 
282
    ne = n * (pixman_fixed_48_16_t) e->dx;
 
283
    stepx = n * e->stepx;
 
284
    if (ne > 0)
 
285
    {
 
286
        int nx = ne / e->dy;
 
287
        ne -= nx * e->dy;
 
288
        stepx += nx * e->signdx;
 
289
    }
 
290
    *dx_p = ne;
 
291
    *stepx_p = stepx;
 
292
}
 
293
 
 
294
/*
 
295
 * Initialize one edge structure given the line endpoints and a
 
296
 * starting y value
 
297
 */
 
298
void
 
299
pixman_edge_init (pixman_edge_t *e,
 
300
                  int           n,
 
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)
 
306
{
 
307
    pixman_fixed_t      dx, dy;
 
308
 
 
309
    e->x = x_top;
 
310
    e->e = 0;
 
311
    dx = x_bot - x_top;
 
312
    dy = y_bot - y_top;
 
313
    e->dy = dy;
 
314
    e->dx = 0;
 
315
    if (dy)
 
316
    {
 
317
        if (dx >= 0)
 
318
        {
 
319
            e->signdx = 1;
 
320
            e->stepx = dx / dy;
 
321
            e->dx = dx % dy;
 
322
            e->e = -dy;
 
323
        }
 
324
        else
 
325
        {
 
326
            e->signdx = -1;
 
327
            e->stepx = -(-dx / dy);
 
328
            e->dx = -dx % dy;
 
329
            e->e = 0;
 
330
        }
 
331
    
 
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);
 
334
    }
 
335
    pixman_edge_step (e, y_start - y_top);
 
336
}
 
337
 
 
338
/*
 
339
 * Initialize one edge structure given a line, starting y value
 
340
 * and a pixel offset for the line
 
341
 */
 
342
void
 
343
pixman_line_fixed_edge_init (pixman_edge_t *e,
 
344
                             int            n,
 
345
                             pixman_fixed_t         y,
 
346
                             const pixman_line_fixed_t *line,
 
347
                             int            x_off,
 
348
                             int            y_off)
 
349
{
 
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;
 
353
 
 
354
    if (line->p1.y <= line->p2.y)
 
355
    {
 
356
        top = &line->p1;
 
357
        bot = &line->p2;
 
358
    }
 
359
    else
 
360
    {
 
361
        top = &line->p2;
 
362
        bot = &line->p1;
 
363
    }
 
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);
 
369
}
 
370
 
 
371
void *
 
372
pixman_malloc_ab(unsigned int a,
 
373
                 unsigned int b)
 
374
{
 
375
    if (a >= INT32_MAX / b)
 
376
        return NULL;
 
377
 
 
378
    return malloc (a * b);
 
379
}
 
380
 
 
381
void *
 
382
pixman_malloc_abc (unsigned int a,
 
383
                   unsigned int b,
 
384
                   unsigned int c)
 
385
{
 
386
    if (a >= INT32_MAX / b)
 
387
        return NULL;
 
388
    else if (a * b >= INT32_MAX / c)
 
389
        return NULL;
 
390
    else
 
391
        return malloc (a * b * c);
 
392
}