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

« back to all changes in this revision

Viewing changes to mfb/maskbits.h

  • 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
/* $XFree86: xc/programs/Xserver/mfb/maskbits.h,v 3.8tsi Exp $ */
 
2
/* Combined Purdue/PurduePlus patches, level 2.1, 1/24/89 */
 
3
/***********************************************************
 
4
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 
5
 
 
6
                        All Rights Reserved
 
7
 
 
8
Permission to use, copy, modify, and distribute this software and its
 
9
documentation for any purpose and without fee is hereby granted,
 
10
provided that the above copyright notice appear in all copies and that
 
11
both that copyright notice and this permission notice appear in
 
12
supporting documentation, and that the name of Digital not be
 
13
used in advertising or publicity pertaining to distribution of the
 
14
software without specific, written prior permission.
 
15
 
 
16
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
17
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
18
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
19
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
20
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
21
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
22
SOFTWARE.
 
23
 
 
24
******************************************************************/
 
25
/* $Xorg: maskbits.h,v 1.3 2000/08/17 19:53:34 cpqbld Exp $ */
 
26
 
 
27
#ifdef HAVE_DIX_CONFIG_H
 
28
#include <dix-config.h>
 
29
#endif
 
30
 
 
31
#include <X11/X.h>
 
32
#include <X11/Xmd.h>
 
33
#include "servermd.h"
 
34
 
 
35
 
 
36
/* the following notes use the following conventions:
 
37
SCREEN LEFT                             SCREEN RIGHT
 
38
in this file and maskbits.c, left and right refer to screen coordinates,
 
39
NOT bit numbering in registers.
 
40
 
 
41
starttab[n]
 
42
        bits[0,n-1] = 0 bits[n,PLST] = 1
 
43
endtab[n] =
 
44
        bits[0,n-1] = 1 bits[n,PLST] = 0
 
45
 
 
46
startpartial[], endpartial[]
 
47
        these are used as accelerators for doing putbits and masking out
 
48
bits that are all contained between longword boudaries.  the extra
 
49
256 bytes of data seems a small price to pay -- code is smaller,
 
50
and narrow things (e.g. window borders) go faster.
 
51
 
 
52
the names may seem misleading; they are derived not from which end
 
53
of the word the bits are turned on, but at which end of a scanline
 
54
the table tends to be used.
 
55
 
 
56
look at the tables and macros to understand boundary conditions.
 
57
(careful readers will note that starttab[n] = ~endtab[n] for n != 0)
 
58
 
 
59
-----------------------------------------------------------------------
 
60
these two macros depend on the screen's bit ordering.
 
61
in both of them x is a screen position.  they are used to
 
62
combine bits collected from multiple longwords into a
 
63
single destination longword, and to unpack a single
 
64
source longword into multiple destinations.
 
65
 
 
66
SCRLEFT(dst, x)
 
67
        takes dst[x, PPW] and moves them to dst[0, PPW-x]
 
68
        the contents of the rest of dst are 0.
 
69
        this is a right shift on LSBFirst (forward-thinking)
 
70
        machines like the VAX, and left shift on MSBFirst
 
71
        (backwards) machines like the 680x0 and pc/rt.
 
72
 
 
73
SCRRIGHT(dst, x)
 
74
        takes dst[0,x] and moves them to dst[PPW-x, PPW]
 
75
        the contents of the rest of dst are 0.
 
76
        this is a left shift on LSBFirst, right shift
 
77
        on MSBFirst.
 
78
 
 
79
 
 
80
the remaining macros are cpu-independent; all bit order dependencies
 
81
are built into the tables and the two macros above.
 
82
 
 
83
maskbits(x, w, startmask, endmask, nlw)
 
84
        for a span of width w starting at position x, returns
 
85
a mask for ragged bits at start, mask for ragged bits at end,
 
86
and the number of whole longwords between the ends.
 
87
 
 
88
maskpartialbits(x, w, mask)
 
89
        works like maskbits(), except all the bits are in the
 
90
        same longword (i.e. (x&PIM + w) <= PPW)
 
91
 
 
92
maskPPWbits(x, w, startmask, endmask, nlw)
 
93
        as maskbits, but does not calculate nlw.  it is used by
 
94
        mfbGlyphBlt to put down glyphs <= PPW bits wide.
 
95
 
 
96
-------------------------------------------------------------------
 
97
 
 
98
NOTE
 
99
        any pointers passed to the following 4 macros are
 
100
        guranteed to be PPW-bit aligned.
 
101
        The only non-PPW-bit-aligned references ever made are
 
102
        to font glyphs, and those are made with getleftbits()
 
103
        and getshiftedleftbits (qq.v.)
 
104
 
 
105
        For 64-bit server, it is assumed that we will never have font padding
 
106
        of more than 4 bytes. The code uses int's to access the fonts
 
107
        intead of longs.
 
108
 
 
109
getbits(psrc, x, w, dst)
 
110
        starting at position x in psrc (x < PPW), collect w
 
111
        bits and put them in the screen left portion of dst.
 
112
        psrc is a longword pointer.  this may span longword boundaries.
 
113
        it special-cases fetching all w bits from one longword.
 
114
 
 
115
        +--------+--------+             +--------+
 
116
        |    | m |n|      |     ==>     | m |n|  |
 
117
        +--------+--------+             +--------+
 
118
            x      x+w                  0     w
 
119
        psrc     psrc+1                 dst
 
120
                        m = PPW - x
 
121
                        n = w - m
 
122
 
 
123
        implementation:
 
124
        get m bits, move to screen-left of dst, zeroing rest of dst;
 
125
        get n bits from next word, move screen-right by m, zeroing
 
126
                 lower m bits of word.
 
127
        OR the two things together.
 
128
 
 
129
putbits(src, x, w, pdst)
 
130
        starting at position x in pdst, put down the screen-leftmost
 
131
        w bits of src.  pdst is a longword pointer.  this may
 
132
        span longword boundaries.
 
133
        it special-cases putting all w bits into the same longword.
 
134
 
 
135
        +--------+                      +--------+--------+
 
136
        | m |n|  |              ==>     |    | m |n|      |
 
137
        +--------+                      +--------+--------+
 
138
        0     w                              x     x+w
 
139
        dst                             pdst     pdst+1
 
140
                        m = PPW - x
 
141
                        n = w - m
 
142
 
 
143
        implementation:
 
144
        get m bits, shift screen-right by x, zero screen-leftmost x
 
145
                bits; zero rightmost m bits of *pdst and OR in stuff
 
146
                from before the semicolon.
 
147
        shift src screen-left by m, zero bits n-PPW;
 
148
                zero leftmost n bits of *(pdst+1) and OR in the
 
149
                stuff from before the semicolon.
 
150
 
 
151
putbitsrop(src, x, w, pdst, ROP)
 
152
        like putbits but calls DoRop with the rasterop ROP (see mfb.h for
 
153
        DoRop)
 
154
 
 
155
putbitsrrop(src, x, w, pdst, ROP)
 
156
        like putbits but calls DoRRop with the reduced rasterop ROP
 
157
        (see mfb.h for DoRRop)
 
158
 
 
159
-----------------------------------------------------------------------
 
160
        The two macros below are used only for getting bits from glyphs
 
161
in fonts, and glyphs in fonts are gotten only with the following two
 
162
mcros.
 
163
        You should tune these macros toyour font format and cpu
 
164
byte ordering.
 
165
 
 
166
NOTE
 
167
getleftbits(psrc, w, dst)
 
168
        get the leftmost w (w<=32) bits from *psrc and put them
 
169
        in dst.  this is used by the mfbGlyphBlt code for glyphs
 
170
        <=PPW bits wide.
 
171
        psrc is declared (unsigned char *)
 
172
 
 
173
        psrc is NOT guaranteed to be PPW-bit aligned.  on  many
 
174
        machines this will cause problems, so there are several
 
175
        versions of this macro.
 
176
 
 
177
        this macro is called ONLY for getting bits from font glyphs,
 
178
        and depends on the server-natural font padding.
 
179
 
 
180
        for blazing text performance, you want this macro
 
181
        to touch memory as infrequently as possible (e.g.
 
182
        fetch longwords) and as efficiently as possible
 
183
        (e.g. don't fetch misaligned longwords)
 
184
 
 
185
getshiftedleftbits(psrc, offset, w, dst)
 
186
        used by the font code; like getleftbits, but shifts the
 
187
        bits SCRLEFT by offset.
 
188
        this is implemented portably, calling getleftbits()
 
189
        and SCRLEFT().
 
190
        psrc is declared (unsigned char *).
 
191
*/
 
192
 
 
193
/* to match CFB and allow algorithm sharing ...
 
194
 * name    mfb32  mfb64  explanation
 
195
 * ----    ------ -----  -----------
 
196
 * PGSZ    32      64    pixel group size (in bits; same as PPW for mfb)
 
197
 * PGSZB    4      8     pixel group size (in bytes)
 
198
 * PPW     32     64     pixels per word (pixels per pixel group)
 
199
 * PLST    31     63     index of last pixel in a word (should be PPW-1)
 
200
 * PIM     0x1f   0x3f   pixel index mask (index within a pixel group)
 
201
 * PWSH    5       6     pixel-to-word shift (should be log2(PPW))
 
202
 *
 
203
 * The MFB_ versions are here so that cfb can include maskbits.h to get
 
204
 * the bitmap constants without conflicting with its own P* constants.
 
205
 * 
 
206
 * Keith Packard (keithp@suse.com):
 
207
 * Note mfb64 is no longer supported; it requires DIX support
 
208
 * for realigning images which costs too much
 
209
 */         
 
210
 
 
211
/* warning: PixelType definition duplicated in mfb.h */
 
212
#ifndef PixelType
 
213
#define PixelType CARD32
 
214
#endif /* PixelType */
 
215
#ifndef MfbBits
 
216
#define MfbBits CARD32
 
217
#endif
 
218
 
 
219
#define MFB_PGSZB 4
 
220
#define MFB_PPW         (MFB_PGSZB<<3) /* assuming 8 bits per byte */
 
221
#define MFB_PGSZ        MFB_PPW
 
222
#define MFB_PLST        (MFB_PPW-1)
 
223
#define MFB_PIM         MFB_PLST
 
224
 
 
225
/* set PWSH = log2(PPW) using brute force */
 
226
 
 
227
#if MFB_PPW == 32
 
228
#define MFB_PWSH 5
 
229
#endif /* MFB_PPW == 32 */
 
230
 
 
231
/* XXX don't use these five */
 
232
extern PixelType starttab[];
 
233
extern PixelType endtab[];
 
234
extern PixelType partmasks[MFB_PPW][MFB_PPW];
 
235
extern PixelType rmask[];
 
236
extern PixelType mask[];
 
237
/* XXX use these five */
 
238
extern PixelType mfbGetstarttab(int);
 
239
extern PixelType mfbGetendtab(int);
 
240
extern PixelType mfbGetpartmasks(int, int);
 
241
extern PixelType mfbGetrmask(int);
 
242
extern PixelType mfbGetmask(int);
 
243
 
 
244
#ifndef MFB_CONSTS_ONLY
 
245
 
 
246
#define PGSZB   MFB_PGSZB
 
247
#define PPW     MFB_PPW
 
248
#define PGSZ    MFB_PGSZ
 
249
#define PLST    MFB_PLST
 
250
#define PIM     MFB_PIM
 
251
#define PWSH    MFB_PWSH
 
252
 
 
253
#define BitLeft(b,s)    SCRLEFT(b,s)
 
254
#define BitRight(b,s)   SCRRIGHT(b,s)
 
255
 
 
256
#ifdef XFree86Server
 
257
#define LONG2CHARSSAMEORDER(x) ((MfbBits)(x))
 
258
#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \
 
259
                        | ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \
 
260
                        | ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \
 
261
                        | ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) )
 
262
#endif /* XFree86Server */
 
263
 
 
264
#if (BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER)
 
265
#define LONG2CHARS(x) ((MfbBits)(x))
 
266
#else
 
267
/*
 
268
 *  the unsigned case below is for compilers like
 
269
 *  the Danbury C and i386cc
 
270
 */
 
271
#define LONG2CHARS( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \
 
272
                        | ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \
 
273
                        | ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \
 
274
                        | ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) )
 
275
#endif /* BITMAP_BIT_ORDER */
 
276
 
 
277
#ifdef STRICT_ANSI_SHIFT
 
278
#define SHL(x,y)    ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) << (y)))
 
279
#define SHR(x,y)    ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) >> (y)))
 
280
#else
 
281
#define SHL(x,y)    LONG2CHARS(LONG2CHARS(x) << (y))
 
282
#define SHR(x,y)    LONG2CHARS(LONG2CHARS(x) >> (y))
 
283
#endif
 
284
 
 
285
#if (BITMAP_BIT_ORDER == MSBFirst)      /* pc/rt, 680x0 */
 
286
#define SCRLEFT(lw, n)  SHL((PixelType)(lw),(n))
 
287
#define SCRRIGHT(lw, n) SHR((PixelType)(lw),(n))
 
288
#else                                   /* vax, intel */
 
289
#define SCRLEFT(lw, n)  SHR((PixelType)(lw),(n))
 
290
#define SCRRIGHT(lw, n) SHL((PixelType)(lw),(n))
 
291
#endif
 
292
 
 
293
#define DoRRop(alu, src, dst) \
 
294
(((alu) == RROP_BLACK) ? ((dst) & ~(src)) : \
 
295
 ((alu) == RROP_WHITE) ? ((dst) | (src)) : \
 
296
 ((alu) == RROP_INVERT) ? ((dst) ^ (src)) : \
 
297
  (dst))
 
298
 
 
299
/* A generalized form of a x4 Duff's Device */
 
300
#define Duff(counter, block) { \
 
301
  while (counter >= 4) {\
 
302
     { block; } \
 
303
     { block; } \
 
304
     { block; } \
 
305
     { block; } \
 
306
     counter -= 4; \
 
307
  } \
 
308
     switch (counter & 3) { \
 
309
     case 3:    { block; } \
 
310
     case 2:    { block; } \
 
311
     case 1:    { block; } \
 
312
     case 0: \
 
313
     counter = 0; \
 
314
   } \
 
315
}
 
316
 
 
317
#define maskbits(x, w, startmask, endmask, nlw) \
 
318
    startmask = mfbGetstarttab((x) & PIM); \
 
319
    endmask = mfbGetendtab(((x)+(w)) & PIM); \
 
320
    if (startmask) \
 
321
        nlw = (((w) - (PPW - ((x) & PIM))) >> PWSH); \
 
322
    else \
 
323
        nlw = (w) >> PWSH;
 
324
 
 
325
#define maskpartialbits(x, w, mask) \
 
326
    mask = mfbGetpartmasks((x) & PIM, (w) & PIM);
 
327
 
 
328
#define maskPPWbits(x, w, startmask, endmask) \
 
329
    startmask = mfbGetstarttab((x) & PIM); \
 
330
    endmask = mfbGetendtab(((x)+(w)) & PIM);
 
331
 
 
332
#ifdef __GNUC__ /* XXX don't want for Alpha? */
 
333
#ifdef vax
 
334
#define FASTGETBITS(psrc,x,w,dst) \
 
335
    __asm ("extzv %1,%2,%3,%0" \
 
336
         : "=g" (dst) \
 
337
         : "g" (x), "g" (w), "m" (*(char *)(psrc)))
 
338
#define getbits(psrc,x,w,dst) FASTGETBITS(psrc,x,w,dst)
 
339
 
 
340
#define FASTPUTBITS(src, x, w, pdst) \
 
341
    __asm ("insv %3,%1,%2,%0" \
 
342
         : "=m" (*(char *)(pdst)) \
 
343
         : "g" (x), "g" (w), "g" (src))
 
344
#define putbits(src, x, w, pdst) FASTPUTBITS(src, x, w, pdst)
 
345
#endif /* vax */
 
346
#ifdef mc68020
 
347
#define FASTGETBITS(psrc, x, w, dst) \
 
348
    __asm ("bfextu %3{%1:%2},%0" \
 
349
    : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
 
350
 
 
351
#define getbits(psrc,x,w,dst) \
 
352
{ \
 
353
    FASTGETBITS(psrc, x, w, dst);\
 
354
    dst = SHL(dst,(32-(w))); \
 
355
}
 
356
 
 
357
#define FASTPUTBITS(src, x, w, pdst) \
 
358
    __asm ("bfins %3,%0{%1:%2}" \
 
359
         : "=o" (*(char *)(pdst)) \
 
360
         : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
 
361
 
 
362
#define putbits(src, x, w, pdst) FASTPUTBITS(SHR((src),32-(w)), x, w, pdst)
 
363
 
 
364
#endif /* mc68020 */
 
365
#endif /* __GNUC__ */
 
366
 
 
367
/*  The following flag is used to override a bugfix for sun 3/60+CG4 machines,
 
368
 */
 
369
 
 
370
/*  We don't need to be careful about this unless we're dealing with sun3's 
 
371
 *  We will default its usage for those who do not know anything, but will
 
372
 *  override its effect if the machine doesn't look like a sun3 
 
373
 */
 
374
#if !defined(mc68020) || !defined(sun)
 
375
#define NO_3_60_CG4
 
376
#endif
 
377
 
 
378
/* This is gross.  We want to #define u_putbits as something which can be used
 
379
 * in the case of the 3/60+CG4, but if we use /bin/cc or are on another
 
380
 * machine type, we want nothing to do with u_putbits.  What a hastle.  Here
 
381
 * I used slo_putbits as something which either u_putbits or putbits could be
 
382
 * defined as.
 
383
 *
 
384
 * putbits gets it iff it is not already defined with FASTPUTBITS above.
 
385
 * u_putbits gets it if we have FASTPUTBITS (putbits) from above and have not
 
386
 *      overridden the NO_3_60_CG4 flag.
 
387
 */
 
388
 
 
389
#define slo_putbits(src, x, w, pdst) \
 
390
{ \
 
391
    register int n = (x)+(w)-PPW; \
 
392
    \
 
393
    if (n <= 0) \
 
394
    { \
 
395
        register PixelType tmpmask; \
 
396
        maskpartialbits((x), (w), tmpmask); \
 
397
        *(pdst) = (*(pdst) & ~tmpmask) | \
 
398
                (SCRRIGHT(src, x) & tmpmask); \
 
399
    } \
 
400
    else \
 
401
    { \
 
402
        register int d = PPW-(x); \
 
403
        *(pdst) = (*(pdst) & mfbGetendtab(x)) | (SCRRIGHT((src), x)); \
 
404
        (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | \
 
405
                (SCRLEFT(src, d) & mfbGetendtab(n)); \
 
406
    } \
 
407
}
 
408
 
 
409
#if defined(putbits) && !defined(NO_3_60_CG4)
 
410
#define u_putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
 
411
#else
 
412
#define u_putbits(src, x, w, pdst) putbits(src, x, w, pdst)
 
413
#endif
 
414
 
 
415
#if !defined(putbits) 
 
416
#define putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
 
417
#endif
 
418
 
 
419
/* Now if we have not gotten any really good bitfield macros, try some
 
420
 * moderately fast macros.  Alas, I don't know how to do asm instructions
 
421
 * without gcc.
 
422
 */
 
423
 
 
424
#ifndef getbits
 
425
#define getbits(psrc, x, w, dst) \
 
426
{ \
 
427
    dst = SCRLEFT(*(psrc), (x)); \
 
428
    if ( ((x) + (w)) > PPW) \
 
429
        dst |= (SCRRIGHT(*((psrc)+1), PPW-(x))); \
 
430
}
 
431
#endif
 
432
 
 
433
/*  We have to special-case putbitsrop because of 3/60+CG4 combos
 
434
 */
 
435
 
 
436
#define u_putbitsrop(src, x, w, pdst, rop) \
 
437
{\
 
438
        register PixelType t1, t2; \
 
439
        register int n = (x)+(w)-PPW; \
 
440
        \
 
441
        t1 = SCRRIGHT((src), (x)); \
 
442
        DoRop(t2, rop, t1, *(pdst)); \
 
443
        \
 
444
    if (n <= 0) \
 
445
    { \
 
446
        register PixelType tmpmask; \
 
447
        \
 
448
        maskpartialbits((x), (w), tmpmask); \
 
449
        *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
 
450
    } \
 
451
    else \
 
452
    { \
 
453
        int m = PPW-(x); \
 
454
        *(pdst) = (*(pdst) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \
 
455
        t1 = SCRLEFT((src), m); \
 
456
        DoRop(t2, rop, t1, (pdst)[1]); \
 
457
        (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(n)); \
 
458
    } \
 
459
}
 
460
 
 
461
/* If our getbits and putbits are FAST enough,
 
462
 * do this brute force, it's faster
 
463
 */
 
464
 
 
465
#if defined(FASTPUTBITS) && defined(FASTGETBITS) && defined(NO_3_60_CG4)
 
466
#if (BITMAP_BIT_ORDER == MSBFirst)
 
467
#define putbitsrop(src, x, w, pdst, rop) \
 
468
{ \
 
469
  register PixelType _tmp, _tmp2; \
 
470
  FASTGETBITS(pdst, x, w, _tmp); \
 
471
  _tmp2 = SCRRIGHT(src, PPW-(w)); \
 
472
  DoRop(_tmp, rop, _tmp2, _tmp) \
 
473
  FASTPUTBITS(_tmp, x, w, pdst); \
 
474
}
 
475
#define putbitsrrop(src, x, w, pdst, rop) \
 
476
{ \
 
477
  register PixelType _tmp, _tmp2; \
 
478
 \
 
479
  FASTGETBITS(pdst, x, w, _tmp); \
 
480
  _tmp2 = SCRRIGHT(src, PPW-(w)); \
 
481
  _tmp= DoRRop(rop, _tmp2, _tmp); \
 
482
  FASTPUTBITS(_tmp, x, w, pdst); \
 
483
}
 
484
#undef u_putbitsrop
 
485
#else
 
486
#define putbitsrop(src, x, w, pdst, rop) \
 
487
{ \
 
488
  register PixelType _tmp; \
 
489
  FASTGETBITS(pdst, x, w, _tmp); \
 
490
  DoRop(_tmp, rop, src, _tmp) \
 
491
  FASTPUTBITS(_tmp, x, w, pdst); \
 
492
}
 
493
#define putbitsrrop(src, x, w, pdst, rop) \
 
494
{ \
 
495
  register PixelType _tmp; \
 
496
 \
 
497
  FASTGETBITS(pdst, x, w, _tmp); \
 
498
  _tmp= DoRRop(rop, src, _tmp); \
 
499
  FASTPUTBITS(_tmp, x, w, pdst); \
 
500
}
 
501
#undef u_putbitsrop
 
502
#endif
 
503
#endif
 
504
 
 
505
#ifndef putbitsrop
 
506
#define putbitsrop(src, x, w, pdst, rop)  u_putbitsrop(src, x, w, pdst, rop)
 
507
#endif 
 
508
 
 
509
#ifndef putbitsrrop
 
510
#define putbitsrrop(src, x, w, pdst, rop) \
 
511
{\
 
512
        register PixelType t1, t2; \
 
513
        register int n = (x)+(w)-PPW; \
 
514
        \
 
515
        t1 = SCRRIGHT((src), (x)); \
 
516
        t2 = DoRRop(rop, t1, *(pdst)); \
 
517
        \
 
518
    if (n <= 0) \
 
519
    { \
 
520
        register PixelType tmpmask; \
 
521
        \
 
522
        maskpartialbits((x), (w), tmpmask); \
 
523
        *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
 
524
    } \
 
525
    else \
 
526
    { \
 
527
        int m = PPW-(x); \
 
528
        *(pdst) = (*(pdst) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \
 
529
        t1 = SCRLEFT((src), m); \
 
530
        t2 = DoRRop(rop, t1, (pdst)[1]); \
 
531
        (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(n)); \
 
532
    } \
 
533
}
 
534
#endif
 
535
 
 
536
#if GETLEFTBITS_ALIGNMENT == 1
 
537
#define getleftbits(psrc, w, dst)       dst = *((CARD32 *)(pointer) psrc)
 
538
#endif /* GETLEFTBITS_ALIGNMENT == 1 */
 
539
 
 
540
#if GETLEFTBITS_ALIGNMENT == 2
 
541
#define getleftbits(psrc, w, dst) \
 
542
    { \
 
543
        if ( ((int)(psrc)) & 0x01 ) \
 
544
                getbits( ((CARD32 *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
 
545
        else \
 
546
                getbits(psrc, 0, w, dst); \
 
547
    }
 
548
#endif /* GETLEFTBITS_ALIGNMENT == 2 */
 
549
 
 
550
#if GETLEFTBITS_ALIGNMENT == 4
 
551
#define getleftbits(psrc, w, dst) \
 
552
    { \
 
553
        int off, off_b; \
 
554
        off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
 
555
        getbits( \
 
556
                (CARD32 *)( ((char *)(psrc)) - off), \
 
557
                (off_b), (w), (dst) \
 
558
               ); \
 
559
    }
 
560
#endif /* GETLEFTBITS_ALIGNMENT == 4 */
 
561
 
 
562
 
 
563
#define getshiftedleftbits(psrc, offset, w, dst) \
 
564
        getleftbits((psrc), (w), (dst)); \
 
565
        dst = SCRLEFT((dst), (offset));
 
566
 
 
567
/* FASTGETBITS and FASTPUTBITS are not necessarily correct implementations of
 
568
 * getbits and putbits, but they work if used together.
 
569
 *
 
570
 * On a MSBFirst machine, a cpu bitfield extract instruction (like bfextu)
 
571
 * could normally assign its result to a 32-bit word register in the screen
 
572
 * right position.  This saves canceling register shifts by not fighting the
 
573
 * natural cpu byte order.
 
574
 *
 
575
 * Unfortunately, these fail on a 3/60+CG4 and cannot be used unmodified. Sigh.
 
576
 */
 
577
#if defined(FASTGETBITS) && defined(FASTPUTBITS)
 
578
#ifdef NO_3_60_CG4
 
579
#define u_FASTPUT(aa, bb, cc, dd)  FASTPUTBITS(aa, bb, cc, dd)
 
580
#else
 
581
#define u_FASTPUT(aa, bb, cc, dd)  u_putbits(SCRLEFT(aa, PPW-(cc)), bb, cc, dd)
 
582
#endif
 
583
 
 
584
#define getandputbits(psrc, srcbit, dstbit, width, pdst) \
 
585
{ \
 
586
    register PixelType _tmpbits; \
 
587
    FASTGETBITS(psrc, srcbit, width, _tmpbits); \
 
588
    u_FASTPUT(_tmpbits, dstbit, width, pdst); \
 
589
}
 
590
 
 
591
#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
 
592
{ \
 
593
  register PixelType _tmpsrc, _tmpdst; \
 
594
  FASTGETBITS(pdst, dstbit, width, _tmpdst); \
 
595
  FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
 
596
  DoRop(_tmpdst, rop, _tmpsrc, _tmpdst); \
 
597
  u_FASTPUT(_tmpdst, dstbit, width, pdst); \
 
598
}
 
599
 
 
600
#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
 
601
{ \
 
602
  register PixelType _tmpsrc, _tmpdst; \
 
603
  FASTGETBITS(pdst, dstbit, width, _tmpdst); \
 
604
  FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
 
605
  _tmpdst = DoRRop(rop, _tmpsrc, _tmpdst); \
 
606
  u_FASTPUT(_tmpdst, dstbit, width, pdst); \
 
607
}
 
608
 
 
609
#define getandputbits0(psrc, srcbit, width, pdst) \
 
610
        getandputbits(psrc, srcbit, 0, width, pdst)
 
611
 
 
612
#define getandputrop0(psrc, srcbit, width, pdst, rop) \
 
613
        getandputrop(psrc, srcbit, 0, width, pdst, rop)
 
614
 
 
615
#define getandputrrop0(psrc, srcbit, width, pdst, rop) \
 
616
        getandputrrop(psrc, srcbit, 0, width, pdst, rop)
 
617
 
 
618
 
 
619
#else /* Slow poke */
 
620
 
 
621
/* pairs of getbits/putbits happen frequently. Some of the code can
 
622
 * be shared or avoided in a few specific instances.  It gets us a
 
623
 * small advantage, so we do it.  The getandput...0 macros are the only ones
 
624
 * which speed things here.  The others are here for compatibility w/the above
 
625
 * FAST ones
 
626
 */
 
627
 
 
628
#define getandputbits(psrc, srcbit, dstbit, width, pdst) \
 
629
{ \
 
630
    register PixelType _tmpbits; \
 
631
    getbits(psrc, srcbit, width, _tmpbits); \
 
632
    putbits(_tmpbits, dstbit, width, pdst); \
 
633
}
 
634
 
 
635
#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
 
636
{ \
 
637
    register PixelType _tmpbits; \
 
638
    getbits(psrc, srcbit, width, _tmpbits) \
 
639
    putbitsrop(_tmpbits, dstbit, width, pdst, rop) \
 
640
}
 
641
 
 
642
#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
 
643
{ \
 
644
    register PixelType _tmpbits; \
 
645
    getbits(psrc, srcbit, width, _tmpbits) \
 
646
    putbitsrrop(_tmpbits, dstbit, width, pdst, rop) \
 
647
}
 
648
 
 
649
 
 
650
#define getandputbits0(psrc, sbindex, width, pdst) \
 
651
{                       /* unroll the whole damn thing to see how it * behaves */ \
 
652
    register int          _flag = PPW - (sbindex); \
 
653
    register PixelType _src; \
 
654
 \
 
655
    _src = SCRLEFT (*(psrc), (sbindex)); \
 
656
    if ((width) > _flag) \
 
657
        _src |=  SCRRIGHT (*((psrc) + 1), _flag); \
 
658
 \
 
659
    *(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
 
660
}
 
661
 
 
662
 
 
663
#define getandputrop0(psrc, sbindex, width, pdst, rop) \
 
664
{                       \
 
665
    register int          _flag = PPW - (sbindex); \
 
666
    register PixelType _src; \
 
667
 \
 
668
    _src = SCRLEFT (*(psrc), (sbindex)); \
 
669
    if ((width) > _flag) \
 
670
        _src |=  SCRRIGHT (*((psrc) + 1), _flag); \
 
671
    DoRop(_src, rop, _src, *(pdst)); \
 
672
 \
 
673
    *(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
 
674
}
 
675
 
 
676
#define getandputrrop0(psrc, sbindex, width, pdst, rop) \
 
677
{ \
 
678
    int             _flag = PPW - (sbindex); \
 
679
    register PixelType _src; \
 
680
 \
 
681
    _src = SCRLEFT (*(psrc), (sbindex)); \
 
682
    if ((width) > _flag) \
 
683
        _src |=  SCRRIGHT (*((psrc) + 1), _flag); \
 
684
    _src = DoRRop(rop, _src, *(pdst)); \
 
685
 \
 
686
    *(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
 
687
}
 
688
 
 
689
#endif  /* FASTGETBITS && FASTPUTBITS */
 
690
 
 
691
#endif /* MFB_CONSTS_ONLY */