~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to fb/fbbltone.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Id: fbbltone.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
 
3
 *
 
4
 * Copyright Ā© 1998 Keith Packard
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of Keith Packard not be used in
 
11
 * advertising or publicity pertaining to distribution of the software without
 
12
 * specific, written prior permission.  Keith Packard makes no
 
13
 * representations about the suitability of this software for any purpose.  It
 
14
 * is provided "as is" without express or implied warranty.
 
15
 *
 
16
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
18
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
20
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
21
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
22
 * PERFORMANCE OF THIS SOFTWARE.
 
23
 */
 
24
/* $XFree86: xc/programs/Xserver/fb/fbbltone.c,v 1.11 2001/09/07 15:15:31 keithp Exp $ */
 
25
 
 
26
#ifdef HAVE_DIX_CONFIG_H
 
27
#include <dix-config.h>
 
28
#endif
 
29
 
 
30
#include "fb.h"
 
31
 
 
32
/*
 
33
 *  Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8)
 
34
 *
 
35
 *      **** **** **** **** **** **** **** ****
 
36
 *                      ^
 
37
 *      ********  ********  ********  ********
 
38
 *                ^
 
39
 *  leftShift = 12
 
40
 *  rightShift = 20
 
41
 *
 
42
 *  Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8)
 
43
 *
 
44
 *      **** **** **** **** **** **** **** ****
 
45
 *      ^               
 
46
 *      ********  ********  ********  ********
 
47
 *                ^
 
48
 *
 
49
 *  leftShift = 24
 
50
 *  rightShift = 8
 
51
 */
 
52
 
 
53
#define LoadBits {\
 
54
    if (leftShift) { \
 
55
        bitsRight = (src != srcEnd ? *src++ : 0); \
 
56
        bits = (FbStipLeft (bitsLeft, leftShift) | \
 
57
                FbStipRight(bitsRight, rightShift)); \
 
58
        bitsLeft = bitsRight; \
 
59
    } else \
 
60
        bits = (src != srcEnd ? *src++ : 0); \
 
61
}
 
62
    
 
63
#ifndef FBNOPIXADDR
 
64
    
 
65
#define LaneCases1(n,a)     case n: (void)FbLaneCase(n,a); break
 
66
#define LaneCases2(n,a)     LaneCases1(n,a); LaneCases1(n+1,a)
 
67
#define LaneCases4(n,a)     LaneCases2(n,a); LaneCases2(n+2,a)
 
68
#define LaneCases8(n,a)     LaneCases4(n,a); LaneCases4(n+4,a)
 
69
#define LaneCases16(n,a)    LaneCases8(n,a); LaneCases8(n+8,a)
 
70
#define LaneCases32(n,a)    LaneCases16(n,a); LaneCases16(n+16,a)
 
71
#define LaneCases64(n,a)    LaneCases32(n,a); LaneCases32(n+32,a)
 
72
#define LaneCases128(n,a)   LaneCases64(n,a); LaneCases64(n+64,a)
 
73
#define LaneCases256(n,a)   LaneCases128(n,a); LaneCases128(n+128,a)
 
74
    
 
75
#if FB_SHIFT == 6
 
76
#define LaneCases(a)        LaneCases256(0,a)
 
77
#endif
 
78
    
 
79
#if FB_SHIFT == 5
 
80
#define LaneCases(a)        LaneCases16(0,a)
 
81
#endif
 
82
                                                           
 
83
#if FB_SHIFT == 6
 
84
CARD8   fb8Lane[256] = {
 
85
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
 
86
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
 
87
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
 
88
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
 
89
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
 
90
98, 99, 100, 101, 102,103,104,105,106,107,108,109,110,111,112,113,114,115,
 
91
116, 117, 118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,
 
92
134, 135, 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,
 
93
152, 153, 154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,
 
94
170, 171, 172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,
 
95
188, 189, 190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
 
96
206, 207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
 
97
224, 225, 226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
 
98
242, 243, 244,245,246,247,248,249,250,251,252,253,254,255,
 
99
};
 
100
 
 
101
CARD8   fb16Lane[256] = {
 
102
    0x00, 0x03, 0x0c, 0x0f,
 
103
    0x30, 0x33, 0x3c, 0x3f,
 
104
    0xc0, 0xc3, 0xcc, 0xcf,
 
105
    0xf0, 0xf3, 0xfc, 0xff,
 
106
};
 
107
 
 
108
CARD8   fb32Lane[16] = {
 
109
    0x00, 0x0f, 0xf0, 0xff,
 
110
};
 
111
#endif
 
112
 
 
113
#if FB_SHIFT == 5
 
114
CARD8   fb8Lane[16] = {
 
115
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
 
116
};
 
117
 
 
118
CARD8   fb16Lane[16] = {
 
119
    0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 
120
};
 
121
 
 
122
CARD8   fb32Lane[16] = {
 
123
    0, 15,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
124
};
 
125
#endif
 
126
 
 
127
CARD8   *fbLaneTable[33] = {
 
128
    0, 0, 0, 0, 0, 0, 0, 0,
 
129
    fb8Lane,  0, 0, 0, 0, 0, 0, 0, 
 
130
    fb16Lane, 0, 0, 0, 0, 0, 0, 0,
 
131
    0, 0, 0, 0, 0, 0, 0, 0,
 
132
    fb32Lane
 
133
};
 
134
#endif
 
135
 
 
136
void
 
137
fbBltOne (FbStip    *src,
 
138
          FbStride  srcStride,      /* FbStip units per scanline */
 
139
          int       srcX,           /* bit position of source */
 
140
          FbBits    *dst,
 
141
          FbStride  dstStride,      /* FbBits units per scanline */
 
142
          int       dstX,           /* bit position of dest */
 
143
          int       dstBpp,         /* bits per destination unit */
 
144
 
 
145
          int       width,          /* width in bits of destination */
 
146
          int       height,         /* height in scanlines */
 
147
 
 
148
          FbBits    fgand,          /* rrop values */
 
149
          FbBits    fgxor,
 
150
          FbBits    bgand,
 
151
          FbBits    bgxor)
 
152
{
 
153
    const FbBits    *fbBits;
 
154
    FbBits          *srcEnd;
 
155
    int             pixelsPerDst;               /* dst pixels per FbBits */
 
156
    int             unitsPerSrc;                /* src patterns per FbStip */
 
157
    int             leftShift, rightShift;      /* align source with dest */
 
158
    FbBits          startmask, endmask;         /* dest scanline masks */
 
159
    FbStip          bits=0, bitsLeft, bitsRight;/* source bits */
 
160
    FbStip          left;
 
161
    FbBits          mask;
 
162
    int             nDst;                       /* dest longwords (w.o. end) */
 
163
    int             w;
 
164
    int             n, nmiddle;
 
165
    int             dstS;                       /* stipple-relative dst X coordinate */
 
166
    Bool            copy;                       /* accelerate dest-invariant */
 
167
    Bool            transparent;                /* accelerate 0 nop */
 
168
    int             srcinc;                     /* source units consumed */
 
169
    Bool            endNeedsLoad = FALSE;       /* need load for endmask */
 
170
#ifndef FBNOPIXADDR
 
171
    CARD8           *fbLane;
 
172
#endif
 
173
    int             startbyte, endbyte;
 
174
 
 
175
#ifdef FB_24BIT
 
176
    if (dstBpp == 24)
 
177
    {
 
178
        fbBltOne24 (src, srcStride, srcX,
 
179
                    dst, dstStride, dstX, dstBpp,
 
180
                    width, height,
 
181
                    fgand, fgxor, bgand, bgxor);
 
182
        return;
 
183
    }
 
184
#endif
 
185
 
 
186
    /*
 
187
     * Do not read past the end of the buffer!
 
188
     */
 
189
    srcEnd = src + height * srcStride;
 
190
 
 
191
    /*
 
192
     * Number of destination units in FbBits == number of stipple pixels
 
193
     * used each time
 
194
     */
 
195
    pixelsPerDst = FB_UNIT / dstBpp;
 
196
 
 
197
    /*
 
198
     * Number of source stipple patterns in FbStip 
 
199
     */
 
200
    unitsPerSrc = FB_STIP_UNIT / pixelsPerDst;
 
201
    
 
202
    copy = FALSE;
 
203
    transparent = FALSE;
 
204
    if (bgand == 0 && fgand == 0)
 
205
        copy = TRUE;
 
206
    else if (bgand == FB_ALLONES && bgxor == 0)
 
207
        transparent = TRUE;
 
208
 
 
209
    /*
 
210
     * Adjust source and dest to nearest FbBits boundary
 
211
     */
 
212
    src += srcX >> FB_STIP_SHIFT;
 
213
    dst += dstX >> FB_SHIFT;
 
214
    srcX &= FB_STIP_MASK;
 
215
    dstX &= FB_MASK;
 
216
 
 
217
    FbMaskBitsBytes(dstX, width, copy, 
 
218
                    startmask, startbyte, nmiddle, endmask, endbyte);
 
219
 
 
220
    /*
 
221
     * Compute effective dest alignment requirement for
 
222
     * source -- must align source to dest unit boundary
 
223
     */
 
224
    dstS = dstX / dstBpp;
 
225
    /*
 
226
     * Compute shift constants for effective alignement
 
227
     */
 
228
    if (srcX >= dstS)
 
229
    {
 
230
        leftShift = srcX - dstS;
 
231
        rightShift = FB_STIP_UNIT - leftShift;
 
232
    }
 
233
    else
 
234
    {
 
235
        rightShift = dstS - srcX;
 
236
        leftShift = FB_STIP_UNIT - rightShift;
 
237
    }
 
238
    /*
 
239
     * Get pointer to stipple mask array for this depth
 
240
     */
 
241
    fbBits = 0; /* unused */
 
242
    if (pixelsPerDst <= 8)
 
243
        fbBits = fbStippleTable[pixelsPerDst];
 
244
#ifndef FBNOPIXADDR
 
245
    fbLane = 0;
 
246
    if (transparent && fgand == 0 && dstBpp >= 8)
 
247
        fbLane = fbLaneTable[dstBpp];
 
248
#endif
 
249
    
 
250
    /*
 
251
     * Compute total number of destination words written, but 
 
252
     * don't count endmask 
 
253
     */
 
254
    nDst = nmiddle;
 
255
    if (startmask)
 
256
        nDst++;
 
257
    
 
258
    dstStride -= nDst;
 
259
 
 
260
    /*
 
261
     * Compute total number of source words consumed
 
262
     */
 
263
    
 
264
    srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc;
 
265
    
 
266
    if (srcX > dstS)
 
267
        srcinc++;
 
268
    if (endmask)
 
269
    {
 
270
        endNeedsLoad = nmiddle % unitsPerSrc == 0;
 
271
        if (endNeedsLoad)
 
272
            srcinc++;
 
273
    }
 
274
 
 
275
    srcStride -= srcinc;
 
276
    
 
277
    /*
 
278
     * Copy rectangle
 
279
     */
 
280
    while (height--)
 
281
    {
 
282
        w = nDst;           /* total units across scanline */
 
283
        n = unitsPerSrc;    /* units avail in single stipple */
 
284
        if (n > w)
 
285
            n = w;
 
286
        
 
287
        bitsLeft = 0;
 
288
        if (srcX > dstS)
 
289
            bitsLeft = *src++;
 
290
        if (n)
 
291
        {
 
292
            /*
 
293
             * Load first set of stipple bits
 
294
             */
 
295
            LoadBits;
 
296
 
 
297
            /*
 
298
             * Consume stipple bits for startmask
 
299
             */
 
300
            if (startmask)
 
301
            {
 
302
#if FB_UNIT > 32
 
303
                if (pixelsPerDst == 16)
 
304
                    mask = FbStipple16Bits(FbLeftStipBits(bits,16));
 
305
                else
 
306
#endif
 
307
                    mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
 
308
#ifndef FBNOPIXADDR             
 
309
                if (fbLane)
 
310
                {
 
311
                    fbTransparentSpan (dst, mask & startmask, fgxor, 1);
 
312
                }
 
313
                else
 
314
#endif
 
315
                {
 
316
                    if (mask || !transparent)
 
317
                        FbDoLeftMaskByteStippleRRop (dst, mask,
 
318
                                                     fgand, fgxor, bgand, bgxor,
 
319
                                                     startbyte, startmask);
 
320
                }
 
321
                bits = FbStipLeft (bits, pixelsPerDst);
 
322
                dst++;
 
323
                n--;
 
324
                w--;
 
325
            }
 
326
            /*
 
327
             * Consume stipple bits across scanline
 
328
             */
 
329
            for (;;)
 
330
            {
 
331
                w -= n;
 
332
                if (copy)
 
333
                {
 
334
                    while (n--)
 
335
                    {
 
336
#if FB_UNIT > 32
 
337
                        if (pixelsPerDst == 16)
 
338
                            mask = FbStipple16Bits(FbLeftStipBits(bits,16));
 
339
                        else
 
340
#endif
 
341
                            mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
 
342
                        *dst = FbOpaqueStipple (mask, fgxor, bgxor);
 
343
                        dst++;
 
344
                        bits = FbStipLeft(bits, pixelsPerDst);
 
345
                    }
 
346
                }
 
347
                else
 
348
                {
 
349
#ifndef FBNOPIXADDR
 
350
                    if (fbLane)
 
351
                    {
 
352
                        while (bits && n)
 
353
                        {
 
354
                            switch (fbLane[FbLeftStipBits(bits,pixelsPerDst)]) {
 
355
                                LaneCases((CARD8 *) dst);
 
356
                            }
 
357
                            bits = FbStipLeft(bits,pixelsPerDst);
 
358
                            dst++;
 
359
                            n--;
 
360
                        }
 
361
                        dst += n;
 
362
                    }
 
363
                    else
 
364
#endif
 
365
                    {
 
366
                        while (n--)
 
367
                        {
 
368
                            left = FbLeftStipBits(bits,pixelsPerDst);
 
369
                            if (left || !transparent)
 
370
                            {
 
371
                                mask = fbBits[left];
 
372
                                *dst = FbStippleRRop (*dst, mask,
 
373
                                                      fgand, fgxor, bgand, bgxor);
 
374
                            }
 
375
                            dst++;
 
376
                            bits = FbStipLeft(bits, pixelsPerDst);
 
377
                        }
 
378
                    }
 
379
                }
 
380
                if (!w)
 
381
                    break;
 
382
                /*
 
383
                 * Load another set and reset number of available units
 
384
                 */
 
385
                LoadBits;
 
386
                n = unitsPerSrc;
 
387
                if (n > w)
 
388
                    n = w;
 
389
            }
 
390
        }
 
391
        /*
 
392
         * Consume stipple bits for endmask
 
393
         */
 
394
        if (endmask)
 
395
        {
 
396
            if (endNeedsLoad)
 
397
            {
 
398
                LoadBits;
 
399
            }
 
400
#if FB_UNIT > 32
 
401
            if (pixelsPerDst == 16)
 
402
                mask = FbStipple16Bits(FbLeftStipBits(bits,16));
 
403
            else
 
404
#endif
 
405
                mask = fbBits[FbLeftStipBits(bits,pixelsPerDst)];
 
406
#ifndef FBNOPIXADDR
 
407
            if (fbLane)
 
408
            {
 
409
                fbTransparentSpan (dst, mask & endmask, fgxor, 1);
 
410
            }
 
411
            else
 
412
#endif
 
413
            {
 
414
                if (mask || !transparent)
 
415
                    FbDoRightMaskByteStippleRRop (dst, mask, 
 
416
                                                  fgand, fgxor, bgand, bgxor,
 
417
                                                  endbyte, endmask);
 
418
            }
 
419
        }
 
420
        dst += dstStride;
 
421
        src += srcStride;
 
422
    }
 
423
}
 
424
 
 
425
#ifdef FB_24BIT
 
426
 
 
427
/*
 
428
 * Crufty macros to initialize the mask array, most of this
 
429
 * is to avoid compile-time warnings about shift overflow
 
430
 */
 
431
 
 
432
#if BITMAP_BIT_ORDER == MSBFirst
 
433
#define Mask24Pos(x,r) ((x)*24-(r))
 
434
#else
 
435
#define Mask24Pos(x,r) ((x)*24-((r) ? 24 - (r) : 0))
 
436
#endif
 
437
 
 
438
#define Mask24Neg(x,r)  (Mask24Pos(x,r) < 0 ? -Mask24Pos(x,r) : 0)
 
439
#define Mask24Check(x,r)    (Mask24Pos(x,r) < 0 ? 0 : \
 
440
                             Mask24Pos(x,r) >= FB_UNIT ? 0 : Mask24Pos(x,r))
 
441
 
 
442
#define Mask24(x,r) (Mask24Pos(x,r) < FB_UNIT ? \
 
443
                     (Mask24Pos(x,r) < 0 ? \
 
444
                      0xffffff >> Mask24Neg (x,r) : \
 
445
                      0xffffff << Mask24Check(x,r)) : 0)
 
446
 
 
447
#define SelMask24(b,n,r)        ((((b) >> n) & 1) * Mask24(n,r))
 
448
 
 
449
/*
 
450
 * Untested for MSBFirst or FB_UNIT == 32
 
451
 */
 
452
 
 
453
#if FB_UNIT == 64
 
454
#define C4_24(b,r) \
 
455
    (SelMask24(b,0,r) | \
 
456
     SelMask24(b,1,r) | \
 
457
     SelMask24(b,2,r) | \
 
458
     SelMask24(b,3,r))
 
459
 
 
460
#define FbStip24New(rot)    (2 + (rot != 0))
 
461
#define FbStip24Len         4
 
462
 
 
463
const FbBits    fbStipple24Bits[3][1 << FbStip24Len] = {
 
464
    /* rotate 0 */
 
465
    {
 
466
        C4_24( 0, 0), C4_24( 1, 0), C4_24( 2, 0), C4_24( 3, 0),
 
467
        C4_24( 4, 0), C4_24( 5, 0), C4_24( 6, 0), C4_24( 7, 0),
 
468
        C4_24( 8, 0), C4_24( 9, 0), C4_24(10, 0), C4_24(11, 0),
 
469
        C4_24(12, 0), C4_24(13, 0), C4_24(14, 0), C4_24(15, 0),
 
470
    },
 
471
    /* rotate 8 */
 
472
    {
 
473
        C4_24( 0, 8), C4_24( 1, 8), C4_24( 2, 8), C4_24( 3, 8),
 
474
        C4_24( 4, 8), C4_24( 5, 8), C4_24( 6, 8), C4_24( 7, 8),
 
475
        C4_24( 8, 8), C4_24( 9, 8), C4_24(10, 8), C4_24(11, 8),
 
476
        C4_24(12, 8), C4_24(13, 8), C4_24(14, 8), C4_24(15, 8),
 
477
    },
 
478
    /* rotate 16 */
 
479
    {
 
480
        C4_24( 0,16), C4_24( 1,16), C4_24( 2,16), C4_24( 3,16),
 
481
        C4_24( 4,16), C4_24( 5,16), C4_24( 6,16), C4_24( 7,16),
 
482
        C4_24( 8,16), C4_24( 9,16), C4_24(10,16), C4_24(11,16),
 
483
        C4_24(12,16), C4_24(13,16), C4_24(14,16), C4_24(15,16),
 
484
    }
 
485
};
 
486
 
 
487
#endif
 
488
 
 
489
#if FB_UNIT == 32
 
490
#define C2_24(b,r)  \
 
491
    (SelMask24(b,0,r) | \
 
492
     SelMask24(b,1,r))
 
493
 
 
494
#define FbStip24Len         2
 
495
#if BITMAP_BIT_ORDER == MSBFirst
 
496
#define FbStip24New(rot)    (1 + (rot == 0))
 
497
#else
 
498
#define FbStip24New(rot)    (1 + (rot == 8))
 
499
#endif
 
500
 
 
501
const FbBits    fbStipple24Bits[3][1 << FbStip24Len] = {
 
502
    /* rotate 0 */
 
503
    {
 
504
        C2_24( 0, 0), C2_24 ( 1, 0), C2_24 ( 2, 0), C2_24 ( 3, 0),
 
505
    },
 
506
    /* rotate 8 */
 
507
    {
 
508
        C2_24( 0, 8), C2_24 ( 1, 8), C2_24 ( 2, 8), C2_24 ( 3, 8),
 
509
    },
 
510
    /* rotate 16 */
 
511
    {
 
512
        C2_24( 0,16), C2_24 ( 1,16), C2_24 ( 2,16), C2_24 ( 3,16),
 
513
    }
 
514
};
 
515
#endif
 
516
 
 
517
#if BITMAP_BIT_ORDER == LSBFirst
 
518
 
 
519
#define FbMergeStip24Bits(left, right, new) \
 
520
        (FbStipLeft (left, new) | FbStipRight ((right), (FbStip24Len - (new))))
 
521
 
 
522
#define FbMergePartStip24Bits(left, right, llen, rlen) \
 
523
        (left | FbStipRight(right, llen))
 
524
 
 
525
#else
 
526
 
 
527
#define FbMergeStip24Bits(left, right, new) \
 
528
        ((FbStipLeft (left, new) & ((1 << FbStip24Len) - 1)) | right)
 
529
 
 
530
#define FbMergePartStip24Bits(left, right, llen, rlen) \
 
531
        (FbStipLeft(left, rlen) | right)
 
532
 
 
533
#endif
 
534
 
 
535
#define fbFirstStipBits(len,stip) {\
 
536
    int __len = (len); \
 
537
    if (len <= remain) { \
 
538
        stip = FbLeftStipBits(bits, len); \
 
539
    } else { \
 
540
        stip = FbLeftStipBits(bits, remain); \
 
541
        bits = (src != srcEnd ? *src++ : 0); \
 
542
        __len = (len) - remain; \
 
543
        stip = FbMergePartStip24Bits(stip, FbLeftStipBits(bits, __len), \
 
544
                                     remain, __len); \
 
545
        remain = FB_STIP_UNIT; \
 
546
    } \
 
547
    bits = FbStipLeft (bits, __len); \
 
548
    remain -= __len; \
 
549
}
 
550
 
 
551
#define fbInitStipBits(offset,len,stip) {\
 
552
    bits = FbStipLeft (*src++,offset); \
 
553
    remain = FB_STIP_UNIT - offset; \
 
554
    fbFirstStipBits(len,stip); \
 
555
    stip = FbMergeStip24Bits (0, stip, len); \
 
556
}
 
557
    
 
558
#define fbNextStipBits(rot,stip) {\
 
559
    int     __new = FbStip24New(rot); \
 
560
    FbStip  __right; \
 
561
    fbFirstStipBits(__new, __right); \
 
562
    stip = FbMergeStip24Bits (stip, __right, __new); \
 
563
    rot = FbNext24Rot (rot); \
 
564
}
 
565
 
 
566
/*
 
567
 * Use deep mask tables that incorporate rotation, pull
 
568
 * a variable number of bits out of the stipple and
 
569
 * reuse the right bits as needed for the next write
 
570
 *
 
571
 * Yes, this is probably too much code, but most 24-bpp screens
 
572
 * have no acceleration so this code is used for stipples, copyplane
 
573
 * and text
 
574
 */
 
575
void
 
576
fbBltOne24 (FbStip      *srcLine,
 
577
            FbStride    srcStride,  /* FbStip units per scanline */
 
578
            int         srcX,       /* bit position of source */
 
579
            FbBits      *dst,
 
580
            FbStride    dstStride,  /* FbBits units per scanline */
 
581
            int         dstX,       /* bit position of dest */
 
582
            int         dstBpp,     /* bits per destination unit */
 
583
 
 
584
            int         width,      /* width in bits of destination */
 
585
            int         height,     /* height in scanlines */
 
586
 
 
587
            FbBits      fgand,      /* rrop values */
 
588
            FbBits      fgxor,
 
589
            FbBits      bgand,
 
590
            FbBits      bgxor)
 
591
{
 
592
    FbStip      *src, *srcEnd;
 
593
    FbBits      leftMask, rightMask, mask;
 
594
    int         nlMiddle, nl;
 
595
    FbStip      stip, bits;
 
596
    int         remain;
 
597
    int         dstS;
 
598
    int         firstlen;
 
599
    int         rot0, rot;
 
600
    int         nDst;
 
601
    
 
602
    /*
 
603
     * Do not read past the end of the buffer!
 
604
     */
 
605
    srcEnd = srcLine + height * srcStride;
 
606
 
 
607
    srcLine += srcX >> FB_STIP_SHIFT;
 
608
    dst += dstX >> FB_SHIFT;
 
609
    srcX &= FB_STIP_MASK;
 
610
    dstX &= FB_MASK;
 
611
    rot0 = FbFirst24Rot (dstX);
 
612
    
 
613
    FbMaskBits (dstX, width, leftMask, nlMiddle, rightMask);
 
614
    
 
615
    dstS = (dstX + 23) / 24;
 
616
    firstlen = FbStip24Len - dstS;
 
617
    
 
618
    nDst = nlMiddle;
 
619
    if (leftMask)
 
620
        nDst++;
 
621
    dstStride -= nDst;
 
622
    
 
623
    /* opaque copy */
 
624
    if (bgand == 0 && fgand == 0)
 
625
    {
 
626
        while (height--)
 
627
        {
 
628
            rot = rot0;
 
629
            src = srcLine;
 
630
            srcLine += srcStride;
 
631
            fbInitStipBits (srcX,firstlen, stip);
 
632
            if (leftMask)
 
633
            {
 
634
                mask = fbStipple24Bits[rot >> 3][stip];
 
635
                *dst = (*dst & ~leftMask) | (FbOpaqueStipple (mask,
 
636
                                                              FbRot24(fgxor, rot),
 
637
                                                              FbRot24(bgxor, rot))
 
638
                                             & leftMask);
 
639
                dst++;
 
640
                fbNextStipBits(rot,stip);
 
641
            }
 
642
            nl = nlMiddle;
 
643
            while (nl--)
 
644
            {
 
645
                mask = fbStipple24Bits[rot>>3][stip];
 
646
                *dst = FbOpaqueStipple (mask, 
 
647
                                        FbRot24(fgxor, rot),
 
648
                                        FbRot24(bgxor, rot));
 
649
                dst++;
 
650
                fbNextStipBits(rot,stip);
 
651
            }
 
652
            if (rightMask)
 
653
            {
 
654
                mask = fbStipple24Bits[rot >> 3][stip];
 
655
                *dst = (*dst & ~rightMask) | (FbOpaqueStipple (mask,
 
656
                                                               FbRot24(fgxor, rot),
 
657
                                                               FbRot24(bgxor, rot))
 
658
                                              & rightMask);
 
659
            }
 
660
            dst += dstStride;
 
661
            src += srcStride;
 
662
        }
 
663
    }
 
664
    /* transparent copy */
 
665
    else if (bgand == FB_ALLONES && bgxor == 0 && fgand == 0)
 
666
    {
 
667
        while (height--)
 
668
        {
 
669
            rot = rot0;
 
670
            src = srcLine;
 
671
            srcLine += srcStride;
 
672
            fbInitStipBits (srcX, firstlen, stip);
 
673
            if (leftMask)
 
674
            {
 
675
                if (stip)
 
676
                {
 
677
                    mask = fbStipple24Bits[rot >> 3][stip] & leftMask;
 
678
                    *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
 
679
                }
 
680
                dst++;
 
681
                fbNextStipBits (rot, stip);
 
682
            }
 
683
            nl = nlMiddle;
 
684
            while (nl--)
 
685
            {
 
686
                if (stip)
 
687
                {
 
688
                    mask = fbStipple24Bits[rot>>3][stip];
 
689
                    *dst = (*dst & ~mask) | (FbRot24(fgxor,rot) & mask);
 
690
                }
 
691
                dst++;
 
692
                fbNextStipBits (rot, stip);
 
693
            }
 
694
            if (rightMask)
 
695
            {
 
696
                if (stip)
 
697
                {
 
698
                    mask = fbStipple24Bits[rot >> 3][stip] & rightMask;
 
699
                    *dst = (*dst & ~mask) | (FbRot24(fgxor, rot) & mask);
 
700
                }
 
701
            }
 
702
            dst += dstStride;
 
703
        }
 
704
    }
 
705
    else
 
706
    {
 
707
        while (height--)
 
708
        {
 
709
            rot = rot0;
 
710
            src = srcLine;
 
711
            srcLine += srcStride;
 
712
            fbInitStipBits (srcX, firstlen, stip);
 
713
            if (leftMask)
 
714
            {
 
715
                mask = fbStipple24Bits[rot >> 3][stip];
 
716
                *dst = FbStippleRRopMask (*dst, mask,
 
717
                                          FbRot24(fgand, rot),
 
718
                                          FbRot24(fgxor, rot),
 
719
                                          FbRot24(bgand, rot),
 
720
                                          FbRot24(bgxor, rot),
 
721
                                          leftMask);
 
722
                dst++;
 
723
                fbNextStipBits(rot,stip);
 
724
            }
 
725
            nl = nlMiddle;
 
726
            while (nl--)
 
727
            {
 
728
                mask = fbStipple24Bits[rot >> 3][stip];
 
729
                *dst = FbStippleRRop (*dst, mask,
 
730
                                      FbRot24(fgand, rot),
 
731
                                      FbRot24(fgxor, rot),
 
732
                                      FbRot24(bgand, rot),
 
733
                                      FbRot24(bgxor, rot));
 
734
                dst++;
 
735
                fbNextStipBits(rot,stip);
 
736
            }
 
737
            if (rightMask)
 
738
            {
 
739
                mask = fbStipple24Bits[rot >> 3][stip];
 
740
                *dst = FbStippleRRopMask (*dst, mask,
 
741
                                          FbRot24(fgand, rot),
 
742
                                          FbRot24(fgxor, rot),
 
743
                                          FbRot24(bgand, rot),
 
744
                                          FbRot24(bgxor, rot),
 
745
                                          rightMask);
 
746
            }
 
747
            dst += dstStride;
 
748
        }
 
749
    }
 
750
}
 
751
#endif
 
752
 
 
753
/*
 
754
 * Not very efficient, but simple -- copy a single plane
 
755
 * from an N bit image to a 1 bit image
 
756
 */
 
757
 
 
758
void
 
759
fbBltPlane (FbBits          *src,
 
760
            FbStride        srcStride,
 
761
            int             srcX,
 
762
            int             srcBpp,
 
763
 
 
764
            FbStip          *dst,
 
765
            FbStride        dstStride,
 
766
            int             dstX,
 
767
            
 
768
            int             width,
 
769
            int             height,
 
770
            
 
771
            FbStip          fgand,
 
772
            FbStip          fgxor,
 
773
            FbStip          bgand,
 
774
            FbStip          bgxor,
 
775
            Pixel           planeMask)
 
776
{
 
777
    FbBits      *s;
 
778
    FbBits      pm;
 
779
    FbBits      srcMask;
 
780
    FbBits      srcMaskFirst;
 
781
    FbBits      srcMask0 = 0;
 
782
    FbBits      srcBits;
 
783
    
 
784
    FbStip      dstBits;
 
785
    FbStip      *d;
 
786
    FbStip      dstMask;
 
787
    FbStip      dstMaskFirst;
 
788
    FbStip      dstUnion;
 
789
    int         w;
 
790
    int         wt;
 
791
    int         rot0;
 
792
 
 
793
    if (!width)
 
794
        return;
 
795
    
 
796
    src += srcX >> FB_SHIFT;
 
797
    srcX &= FB_MASK;
 
798
 
 
799
    dst += dstX >> FB_STIP_SHIFT;
 
800
    dstX &= FB_STIP_MASK;
 
801
    
 
802
    w = width / srcBpp;
 
803
 
 
804
    pm = fbReplicatePixel (planeMask, srcBpp);
 
805
#ifdef FB_24BIT
 
806
    if (srcBpp == 24)
 
807
    {
 
808
        int w = 24;
 
809
 
 
810
        rot0 = FbFirst24Rot (srcX);
 
811
        if (srcX + w > FB_UNIT)
 
812
            w = FB_UNIT - srcX;
 
813
        srcMaskFirst = FbRot24(pm,rot0) & FbBitsMask(srcX,w);
 
814
    }
 
815
    else
 
816
#endif
 
817
    {
 
818
        rot0 = 0;
 
819
        srcMaskFirst = pm & FbBitsMask(srcX, srcBpp);
 
820
        srcMask0 = pm & FbBitsMask(0, srcBpp);
 
821
    }
 
822
    
 
823
    dstMaskFirst = FbStipMask(dstX,1); 
 
824
    while (height--)
 
825
    {
 
826
        d = dst;
 
827
        dst += dstStride;
 
828
        s = src;
 
829
        src += srcStride;
 
830
        
 
831
        srcMask = srcMaskFirst;
 
832
#ifdef FB_24BIT
 
833
        if (srcBpp == 24)
 
834
            srcMask0 = FbRot24(pm,rot0) & FbBitsMask(0, srcBpp);
 
835
#endif
 
836
        srcBits = *s++;
 
837
 
 
838
        dstMask = dstMaskFirst;
 
839
        dstUnion = 0;
 
840
        dstBits = 0;
 
841
        
 
842
        wt = w;
 
843
        
 
844
        while (wt--)
 
845
        {
 
846
            if (!srcMask)
 
847
            {
 
848
                srcBits = *s++;
 
849
#ifdef FB_24BIT
 
850
                if (srcBpp == 24)
 
851
                    srcMask0 = FbNext24Pix(srcMask0) & FbBitsMask(0,24);
 
852
#endif
 
853
                srcMask = srcMask0;
 
854
            }
 
855
            if (!dstMask)
 
856
            {
 
857
                *d = FbStippleRRopMask(*d, dstBits,
 
858
                                       fgand, fgxor, bgand, bgxor,
 
859
                                       dstUnion);
 
860
                d++;
 
861
                dstMask = FbStipMask(0,1);
 
862
                dstUnion = 0;
 
863
                dstBits = 0;
 
864
            }
 
865
            if (srcBits & srcMask)
 
866
                dstBits |= dstMask;
 
867
            dstUnion |= dstMask;
 
868
            if (srcBpp == FB_UNIT)
 
869
                srcMask = 0;
 
870
            else
 
871
                srcMask = FbScrRight(srcMask,srcBpp);
 
872
            dstMask = FbStipRight(dstMask,1);
 
873
        }
 
874
        if (dstUnion)
 
875
            *d = FbStippleRRopMask(*d,dstBits,
 
876
                                   fgand, fgxor, bgand, bgxor,
 
877
                                   dstUnion);
 
878
    }
 
879
}
 
880