1
/* $XFree86: xc/programs/Xserver/cfb/cfbmskbits.h,v 3.13tsi Exp $ */
2
/************************************************************
3
Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
7
Permission to use, copy, modify, and distribute this
8
software and its documentation for any purpose and without
9
fee is hereby granted, provided that the above copyright no-
10
tice appear in all copies and that both that copyright no-
11
tice and this permission notice appear in supporting docu-
12
mentation, and that the names of Sun or The Open Group
13
not be used in advertising or publicity pertaining to
14
distribution of the software without specific prior
15
written permission. Sun and The Open Group make no
16
representations about the suitability of this software for
17
any purpose. It is provided "as is" without any express or
20
SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
22
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
23
ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
24
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
25
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
27
THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
********************************************************/
31
/* $Xorg: cfbmskbits.h,v 1.3 2000/08/17 19:48:14 cpqbld Exp $ */
32
/* Optimizations for PSZ == 32 added by Kyle Marvin (marvin@vitec.com) */
37
#if defined(XFREE86) || ( defined(__OpenBSD__) && defined(__alpha__) ) \
38
|| (defined(__bsdi__))
39
#include "xf86_ansic.h"
44
* ==========================================================================
45
* Converted from mfb to support memory-mapped color framebuffer by smarks@sun,
48
* The way I did the conversion was to consider each longword as an
49
* array of four bytes instead of an array of 32 one-bit pixels. So
50
* getbits() and putbits() retain much the same calling sequence, but
51
* they move bytes around instead of bits. Of course, this entails the
52
* removal of all of the one-bit-pixel dependencies from the other
53
* files, but the major bit-hacking stuff should be covered here.
55
* I've created some new macros that make it easier to understand what's
56
* going on in the pixel calculations, and that make it easier to change the
61
* PSZ pixel size (in bits)
62
* PGSZ pixel group size (in bits)
63
* PGSZB pixel group size (in bytes)
64
* PGSZBMSK mask with lowest PGSZB bits set to 1
65
* PPW pixels per word (pixels per pixel group)
66
* PPWMSK mask with lowest PPW bits set to 1
67
* PLST index of last pixel in a word (should be PPW-1)
68
* PIM pixel index mask (index within a pixel group)
69
* PWSH pixel-to-word shift (should be log2(PPW))
70
* PMSK mask with lowest PSZ bits set to 1
73
* Here are some sample values. In the notation cfbA,B: A is PSZ, and
74
* B is PGSZB. All the other values are derived from these
75
* two. This table does not show all combinations!
77
* name cfb8,4 cfb24,4 cfb32,4 cfb8,8 cfb24,8 cfb32,8
78
* ---- ------ ------- ------ ------ ------ -------
80
* PGSZ 32 32 32 64 64 64
82
* PGSZBMSK 0xF 0xF? 0xF 0xFF 0xFF 0xFF
84
* PPWMSK 0xF 0x1 0x1 0xFF 0x3? 0x3
86
* PIM 0x3 0x0 0x0 0x7 0x1? 0x1
88
* PMSK 0xFF 0xFFFFFF 0xFFFFFFFF 0xFF 0xFFFFFF 0xFFFFFFFF
91
* I have also added a new macro, PFILL, that takes one pixel and
92
* replicates it throughout a word. This macro definition is dependent
93
* upon pixel and word size; it doesn't use macros like PPW and so
94
* forth. Examples: for monochrome, PFILL(1) => 0xffffffff, PFILL(0) =>
95
* 0x00000000. For 8-bit color, PFILL(0x5d) => 0x5d5d5d5d. This macro
96
* is used primarily for replicating a plane mask into a word.
98
* Color framebuffers operations also support the notion of a plane
99
* mask. This mask determines which planes of the framebuffer can be
100
* altered; the others are left unchanged. I have added another
101
* parameter to the putbits and putbitsrop macros that is the plane
103
* ==========================================================================
105
* Keith Packard (keithp@suse.com)
106
* 64bit code is no longer supported; it requires DIX support
107
* for repadding images which significantly impacts performance
111
* PSZ needs to be defined before we get here. Usually it comes from a
112
* -DPSZ=foo on the compilation command line.
120
* PixelGroup is the data type used to operate on groups of pixels.
121
* We typedef it here to CARD32 with the assumption that you
122
* want to manipulate 32 bits worth of pixels at a time as you can. If CARD32
123
* is not appropriate for your server, define it to something else
124
* before including this file. In this case you will also have to define
125
* PGSZB to the size in bytes of PixelGroup.
128
#define PixelGroup CARD32
130
#endif /* PixelGroup */
133
#define CfbBits CARD32
136
#define PGSZ (PGSZB << 3)
137
#define PPW (PGSZ/PSZ)
140
#define PMSK (((PixelGroup)1 << PSZ) - 1)
141
#define PPWMSK (((PixelGroup)1 << PPW) - 1) /* instead of BITMSK */
142
#define PGSZBMSK (((PixelGroup)1 << PGSZB) - 1)
144
/* set PWSH = log2(PPW) using brute force */
160
#endif /* PPW == 16 */
161
#endif /* PPW == 8 */
162
#endif /* PPW == 4 */
163
#endif /* PPW == 2 */
164
#endif /* PPW == 1 */
166
/* Defining PIXEL_ADDR means that individual pixels are addressable by this
167
* machine (as type PixelType). A possible CFB architecture which supported
168
* 8-bits-per-pixel on a non byte-addressable machine would not have this
171
* Defining FOUR_BIT_CODE means that cfb knows how to stipple on this machine;
172
* eventually, stippling code for 16 and 32 bit devices should be written
173
* which would allow them to also use FOUR_BIT_CODE. There isn't that
174
* much to do in those cases, but it would make them quite a bit faster.
179
typedef CARD8 PixelType;
180
#define FOUR_BIT_CODE
185
typedef CARD16 PixelType;
190
#define PMSK 0xFFFFFF
194
typedef CARD32 PixelType;
199
#define PMSK 0xFFFFFFFF
201
typedef CARD32 PixelType;
205
/* the following notes use the following conventions:
206
SCREEN LEFT SCREEN RIGHT
207
in this file and maskbits.c, left and right refer to screen coordinates,
208
NOT bit numbering in registers.
211
pixels[0,n-1] = 0's pixels[n,PPW-1] = 1's
213
pixels[0,n-1] = 1's pixels[n,PPW-1] = 0's
215
cfbstartpartial[], cfbendpartial[]
216
these are used as accelerators for doing putbits and masking out
217
bits that are all contained between longword boudaries. the extra
218
256 bytes of data seems a small price to pay -- code is smaller,
219
and narrow things (e.g. window borders) go faster.
221
the names may seem misleading; they are derived not from which end
222
of the word the bits are turned on, but at which end of a scanline
223
the table tends to be used.
225
look at the tables and macros to understand boundary conditions.
226
(careful readers will note that starttab[n] = ~endtab[n] for n != 0)
228
-----------------------------------------------------------------------
229
these two macros depend on the screen's bit ordering.
230
in both of them x is a screen position. they are used to
231
combine bits collected from multiple longwords into a
232
single destination longword, and to unpack a single
233
source longword into multiple destinations.
236
takes dst[x, PPW] and moves them to dst[0, PPW-x]
237
the contents of the rest of dst are 0 ONLY IF
239
is cast as an unsigned.
240
this is a right shift on the VAX, left shift on
244
takes dst[0,x] and moves them to dst[PPW-x, PPW]
245
the contents of the rest of dst are 0 ONLY IF
247
this is a left shift on the VAX, right shift on
251
the remaining macros are cpu-independent; all bit order dependencies
252
are built into the tables and the two macros above.
254
maskbits(x, w, startmask, endmask, nlw)
255
for a span of width w starting at position x, returns
256
a mask for ragged pixels at start, mask for ragged pixels at end,
257
and the number of whole longwords between the ends.
259
maskpartialbits(x, w, mask)
260
works like maskbits(), except all the pixels are in the
261
same longword (i.e. (x&0xPIM + w) <= PPW)
263
mask32bits(x, w, startmask, endmask, nlw)
264
as maskbits, but does not calculate nlw. it is used by
265
cfbGlyphBlt to put down glyphs <= PPW bits wide.
267
getbits(psrc, x, w, dst)
268
starting at position x in psrc (x < PPW), collect w
269
pixels and put them in the screen left portion of dst.
270
psrc is a longword pointer. this may span longword boundaries.
271
it special-cases fetching all w bits from one longword.
273
+--------+--------+ +--------+
274
| | m |n| | ==> | m |n| |
275
+--------+--------+ +--------+
282
get m pixels, move to screen-left of dst, zeroing rest of dst;
283
get n pixels from next word, move screen-right by m, zeroing
284
lower m pixels of word.
285
OR the two things together.
287
putbits(src, x, w, pdst, planemask)
288
starting at position x in pdst, put down the screen-leftmost
289
w bits of src. pdst is a longword pointer. this may
290
span longword boundaries.
291
it special-cases putting all w bits into the same longword.
293
+--------+ +--------+--------+
294
| m |n| | ==> | | m |n| |
295
+--------+ +--------+--------+
302
get m pixels, shift screen-right by x, zero screen-leftmost x
303
pixels; zero rightmost m bits of *pdst and OR in stuff
304
from before the semicolon.
305
shift src screen-left by m, zero bits n-32;
306
zero leftmost n pixels of *(pdst+1) and OR in the
307
stuff from before the semicolon.
309
putbitsrop(src, x, w, pdst, planemask, ROP)
310
like putbits but calls DoRop with the rasterop ROP (see cfb.h for
313
getleftbits(psrc, w, dst)
314
get the leftmost w (w<=PPW) bits from *psrc and put them
315
in dst. this is used by the cfbGlyphBlt code for glyphs
319
#if (BITMAP_BIT_ORDER == MSBFirst)
320
#define BitRight(lw,n) ((lw) >> (n))
321
#define BitLeft(lw,n) ((lw) << (n))
322
#else /* (BITMAP_BIT_ORDER == LSBFirst) */
323
#define BitRight(lw,n) ((lw) << (n))
324
#define BitLeft(lw,n) ((lw) >> (n))
325
#endif /* (BITMAP_BIT_ORDER == MSBFirst) */
327
#define SCRLEFT(lw, n) BitLeft (lw, (n) * PSZ)
328
#define SCRRIGHT(lw, n) BitRight(lw, (n) * PSZ)
331
* Note that the shift direction is independent of the byte ordering of the
332
* machine. The following is portable code.
335
#define PFILL(p) ( ((p)&PMSK) | \
336
((p)&PMSK) << PSZ | \
337
((p)&PMSK) << 2*PSZ | \
338
((p)&PMSK) << 3*PSZ | \
339
((p)&PMSK) << 4*PSZ | \
340
((p)&PMSK) << 5*PSZ | \
341
((p)&PMSK) << 6*PSZ | \
342
((p)&PMSK) << 7*PSZ | \
343
((p)&PMSK) << 8*PSZ | \
344
((p)&PMSK) << 9*PSZ | \
345
((p)&PMSK) << 10*PSZ | \
346
((p)&PMSK) << 11*PSZ | \
347
((p)&PMSK) << 12*PSZ | \
348
((p)&PMSK) << 13*PSZ | \
349
((p)&PMSK) << 14*PSZ | \
350
((p)&PMSK) << 15*PSZ )
351
#define PFILL2(p, pf) { \
354
pf |= (pf << 2*PSZ); \
355
pf |= (pf << 4*PSZ); \
356
pf |= (pf << 8*PSZ); \
358
#endif /* PPW == 16 */
360
#define PFILL(p) ( ((p)&PMSK) | \
361
((p)&PMSK) << PSZ | \
362
((p)&PMSK) << 2*PSZ | \
363
((p)&PMSK) << 3*PSZ | \
364
((p)&PMSK) << 4*PSZ | \
365
((p)&PMSK) << 5*PSZ | \
366
((p)&PMSK) << 6*PSZ | \
367
((p)&PMSK) << 7*PSZ )
368
#define PFILL2(p, pf) { \
371
pf |= (pf << 2*PSZ); \
372
pf |= (pf << 4*PSZ); \
376
#define PFILL(p) ( ((p)&PMSK) | \
377
((p)&PMSK) << PSZ | \
378
((p)&PMSK) << 2*PSZ | \
379
((p)&PMSK) << 3*PSZ )
380
#define PFILL2(p, pf) { \
383
pf |= (pf << 2*PSZ); \
387
#define PFILL(p) ( ((p)&PMSK) | \
389
#define PFILL2(p, pf) { \
396
#define PFILL2(p,pf) (pf = (p))
400
* Reduced raster op - using precomputed values, perform the above
401
* in three instructions
404
#define DoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
406
#define DoMaskRRop(dst, and, xor, mask) \
407
(((dst) & ((and) | ~(mask))) ^ (xor & mask))
409
#if PSZ != 32 || PPW != 1
411
# if (PSZ == 24 && PPW == 1)
412
#define maskbits(x, w, startmask, endmask, nlw) {\
413
startmask = cfbstarttab[(x)&3]; \
414
endmask = cfbendtab[((x)+(w)) & 3]; \
415
nlw = ((((x)+(w))*3)>>2) - (((x)*3 +3)>>2); \
418
#define mask32bits(x, w, startmask, endmask) \
419
startmask = cfbstarttab[(x)&3]; \
420
endmask = cfbendtab[((x)+(w)) & 3];
422
#define maskpartialbits(x, w, mask) \
423
mask = cfbstartpartial[(x) & 3] & cfbendpartial[((x)+(w)) & 3];
425
#define maskbits24(x, w, startmask, endmask, nlw) \
426
startmask = cfbstarttab24[(x) & 3]; \
427
endmask = cfbendtab24[((x)+(w)) & 3]; \
429
nlw = (((w) - (4 - ((x) & 3))) >> 2); \
434
#define getbits24(psrc, dst, index) {\
436
switch(idx = ((index)&3)<<1){ \
438
dst = (*(psrc) &cfbmask[idx]); \
441
dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]); \
444
dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]) | \
445
BitRight(((*((psrc)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
449
#define putbits24(src, w, pdst, planemask, index) {\
450
register PixelGroup dstpixel; \
451
register unsigned int idx; \
452
switch(idx = ((index)&3)<<1){ \
454
dstpixel = (*(pdst) &cfbmask[idx]); \
457
dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
460
dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
461
BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
463
dstpixel &= ~(planemask); \
464
dstpixel |= (src & planemask); \
465
*(pdst) &= cfbrmask[idx]; \
468
*(pdst) |= (dstpixel & cfbmask[idx]); \
473
*(pdst) = ((*(pdst)) & cfbrmask[idx]) | \
474
(BitLeft(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
477
*(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
482
#define putbitsrop24(src, x, pdst, planemask, rop) \
484
register PixelGroup t1, dstpixel; \
485
register unsigned int idx; \
486
switch(idx = (x)<<1){ \
488
dstpixel = (*(pdst) &cfbmask[idx]); \
491
dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
494
dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
495
BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
497
DoRop(t1, rop, (src), dstpixel); \
498
dstpixel &= ~planemask; \
499
dstpixel |= (t1 & planemask); \
500
*(pdst) &= cfbrmask[idx]; \
503
*(pdst) |= (dstpixel & cfbmask[idx]); \
507
*((pdst)+1) = ((*((pdst)+1)) & cfbrmask[idx+1]) | \
508
(BitLeft(dstpixel, cfb24Shift[idx+1]) & (cfbmask[idx+1])); \
510
*(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
513
# else /* PSZ == 24 && PPW == 1 */
514
#define maskbits(x, w, startmask, endmask, nlw) \
515
startmask = cfbstarttab[(x)&PIM]; \
516
endmask = cfbendtab[((x)+(w)) & PIM]; \
518
nlw = (((w) - (PPW - ((x)&PIM))) >> PWSH); \
522
#define maskpartialbits(x, w, mask) \
523
mask = cfbstartpartial[(x) & PIM] & cfbendpartial[((x) + (w)) & PIM];
525
#define mask32bits(x, w, startmask, endmask) \
526
startmask = cfbstarttab[(x)&PIM]; \
527
endmask = cfbendtab[((x)+(w)) & PIM];
530
#define maskbits24(x, w, startmask, endmask, nlw) \
532
#define getbits24(psrc, dst, index) \
534
#define putbits24(src, w, pdst, planemask, index) \
536
#define putbitsrop24(src, x, pdst, planemask, rop) \
539
#endif /* PSZ == 24 && PPW == 1 */
541
#define getbits(psrc, x, w, dst) \
542
if ( ((x) + (w)) <= PPW) \
544
dst = SCRLEFT(*(psrc), (x)); \
550
dst = (SCRLEFT(*(psrc), (x)) & cfbendtab[m]) | \
551
(SCRRIGHT(*((psrc)+1), m) & cfbstarttab[m]); \
555
#define putbits(src, x, w, pdst, planemask) \
556
if ( ((x)+(w)) <= PPW) \
558
PixelGroup tmpmask; \
559
maskpartialbits((x), (w), tmpmask); \
560
tmpmask &= PFILL(planemask); \
561
*(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \
567
PixelGroup pm = PFILL(planemask); \
570
*(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | \
571
(SCRRIGHT(src, x) & (cfbstarttab[x] & pm)); \
572
*((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
573
(SCRLEFT(src, m) & (cfbendtab[n] & pm)); \
575
#if defined(__GNUC__) && defined(mc68020)
577
#define FASTGETBITS(psrc, x, w, dst) \
578
asm ("bfextu %3{%1:%2},%0" \
579
: "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
581
#define getbits(psrc,x,w,dst) \
583
FASTGETBITS(psrc, (x) * PSZ, (w) * PSZ, dst); \
584
dst = SCRLEFT(dst,PPW-(w)); \
587
#define FASTPUTBITS(src, x, w, pdst) \
588
asm ("bfins %3,%0{%1:%2}" \
589
: "=o" (*(char *)(pdst)) \
590
: "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
593
#define putbits(src, x, w, pdst, planemask) \
595
if (planemask != PMSK) { \
596
PixelGroup _m, _pm; \
597
FASTGETBITS(pdst, (x) * PSZ , (w) * PSZ, _m); \
598
PFILL2(planemask, _pm); \
600
_m |= (SCRRIGHT(src, PPW-(w)) & _pm); \
601
FASTPUTBITS(_m, (x) * PSZ, (w) * PSZ, pdst); \
603
FASTPUTBITS(SCRRIGHT(src, PPW-(w)), (x) * PSZ, (w) * PSZ, pdst); \
610
#define putbitsrop(src, x, w, pdst, planemask, rop) \
611
if ( ((x)+(w)) <= PPW) \
613
PixelGroup tmpmask; \
615
maskpartialbits((x), (w), tmpmask); \
616
PFILL2(planemask, t1); \
618
t1 = SCRRIGHT((src), (x)); \
619
DoRop(t2, rop, t1, *(pdst)); \
620
*(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
628
PFILL2(planemask, pm); \
631
t1 = SCRRIGHT((src), (x)); \
632
DoRop(t2, rop, t1, *(pdst)); \
633
*(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | (t2 & (cfbstarttab[x] & pm));\
634
t1 = SCRLEFT((src), m); \
635
DoRop(t2, rop, t1, *((pdst) + 1)); \
636
*((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
637
(t2 & (cfbendtab[n] & pm)); \
640
#else /* PSZ == 32 && PPW == 1*/
643
* These macros can be optimized for 32-bit pixels since there is no
644
* need to worry about left/right edge masking. These macros were
645
* derived from the above using the following reductions:
647
* - x & PIW = 0 [since PIW = 0]
648
* - all masking tables are only indexed by 0 [ due to above ]
649
* - cfbstartab[0] and cfbendtab[0] = 0 [ no left/right edge masks]
650
* - cfbstartpartial[0] and cfbendpartial[0] = ~0 [no partial pixel mask]
652
* Macro reduction based upon constants cannot be performed automatically
653
* by the compiler since it does not know the contents of the masking
654
* arrays in cfbmskbits.c.
656
#define maskbits(x, w, startmask, endmask, nlw) \
657
startmask = endmask = 0; \
660
#define maskpartialbits(x, w, mask) \
663
#define mask32bits(x, w, startmask, endmask) \
664
startmask = endmask = 0;
667
* For 32-bit operations, getbits(), putbits(), and putbitsrop()
668
* will only be invoked with x = 0 and w = PPW (1). The getbits()
669
* macro is only called within left/right edge logic, which doesn't
670
* happen for 32-bit pixels.
672
#define getbits(psrc, x, w, dst) (dst) = *(psrc)
674
#define putbits(src, x, w, pdst, planemask) \
675
*(pdst) = (*(pdst) & ~planemask) | (src & planemask);
677
#define putbitsrop(src, x, w, pdst, planemask, rop) \
680
DoRop(t1, rop, (src), *(pdst)); \
681
*(pdst) = (*(pdst) & ~planemask) | (t1 & planemask); \
684
#endif /* PSZ != 32 */
687
* Use these macros only when you're using the MergeRop stuff
688
* in ../mfb/mergerop.h
691
/* useful only when not spanning destination longwords */
693
#define putbitsmropshort24(src,x,w,pdst,index) {\
694
PixelGroup _tmpmask; \
696
maskpartialbits ((x), (w), _tmpmask); \
697
_t1 = SCRRIGHT((src), (x)); \
698
DoMaskMergeRop24(_t1, pdst, _tmpmask, index); \
701
#define putbitsmropshort(src,x,w,pdst) {\
702
PixelGroup _tmpmask; \
704
maskpartialbits ((x), (w), _tmpmask); \
705
_t1 = SCRRIGHT((src), (x)); \
706
*pdst = DoMaskMergeRop(_t1, *pdst, _tmpmask); \
709
/* useful only when spanning destination longwords */
710
#define putbitsmroplong(src,x,w,pdst) { \
711
PixelGroup _startmask, _endmask; \
715
_startmask = cfbstarttab[x]; \
716
_endmask = cfbendtab[(w) - _m]; \
717
_t1 = SCRRIGHT((src), (x)); \
718
pdst[0] = DoMaskMergeRop(_t1,pdst[0],_startmask); \
719
_t1 = SCRLEFT ((src),_m); \
720
pdst[1] = DoMaskMergeRop(_t1,pdst[1],_endmask); \
723
#define putbitsmrop(src,x,w,pdst) \
724
if ((x) + (w) <= PPW) {\
725
putbitsmropshort(src,x,w,pdst); \
727
putbitsmroplong(src,x,w,pdst); \
730
#if GETLEFTBITS_ALIGNMENT == 1
731
#define getleftbits(psrc, w, dst) dst = *((unsigned int *) psrc)
732
#define getleftbits24(psrc, w, dst, idx){ \
733
regiseter int index; \
734
switch(index = ((idx)&3)<<1){ \
736
dst = (*((unsigned int *) psrc))&cfbmask[index]; \
740
dst = BitLeft(((*((unsigned int *) psrc))&cfbmask[index]), cfb24Shift[index]); \
741
dst |= BitRight(((*((unsigned int *) psrc)+1)&cfbmask[index]), cfb4Shift[index]); \
744
dst = BitLeft((*((unsigned int *) psrc)),cfb24Shift[index]); \
748
#endif /* GETLEFTBITS_ALIGNMENT == 1 */
750
#define getglyphbits(psrc, x, w, dst) \
752
dst = BitLeft((unsigned) *(psrc), (x)); \
753
if ( ((x) + (w)) > 32) \
754
dst |= (BitRight((unsigned) *((psrc)+1), 32-(x))); \
756
#if GETLEFTBITS_ALIGNMENT == 2
757
#define getleftbits(psrc, w, dst) \
759
if ( ((int)(psrc)) & 0x01 ) \
760
getglyphbits( ((unsigned int *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
762
dst = *((unsigned int *) psrc); \
764
#endif /* GETLEFTBITS_ALIGNMENT == 2 */
766
#if GETLEFTBITS_ALIGNMENT == 4
767
#define getleftbits(psrc, w, dst) \
770
off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
772
(unsigned int *)( ((char *)(psrc)) - off), \
773
(off_b), (w), (dst) \
776
#endif /* GETLEFTBITS_ALIGNMENT == 4 */
779
* getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix )
781
* Converts bits to pixels in a reasonable way. Takes w (1 <= w <= PPW)
782
* bits from *psrcstip, starting at bit x; call this a quartet of bits.
783
* Then, takes the pixels from *psrcpix corresponding to the one-bits (if
784
* ones is TRUE) or the zero-bits (if ones is FALSE) of the quartet
785
* and puts these pixels into destpix.
789
* getstipplepixels( &(0x08192A3B), 17, 4, 1, &(0x4C5D6E7F), dest )
791
* 0x08192A3B = 0000 1000 0001 1001 0010 1010 0011 1011
793
* This will take 4 bits starting at bit 17, so the quartet is 0x5 = 0101.
794
* It will take pixels from 0x4C5D6E7F corresponding to the one-bits in this
795
* quartet, so dest = 0x005D007F.
797
* XXX Works with both byte order.
798
* XXX This works for all values of x and w within a doubleword.
800
#if (BITMAP_BIT_ORDER == MSBFirst)
801
#define getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) \
805
if ((m = ((x) - ((PPW*PSZ)-PPW))) > 0) { \
806
q = (*(psrcstip)) << m; \
807
if ( (x)+(w) > (PPW*PSZ) ) \
808
q |= *((psrcstip)+1) >> ((PPW*PSZ)-m); \
811
q = (*(psrcstip)) >> -m; \
812
q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
813
*(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
815
/* I just copied this to get the linker satisfied on PowerPC,
816
* so this may not be correct at all.
818
#define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
821
q = *(psrcstip) >> (xt); \
822
q = ((ones) ? q : ~q) & 1; \
823
*(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
825
#else /* BITMAP_BIT_ORDER == LSB */
827
/* this must load 32 bits worth; for most machines, thats an int */
828
#define CfbFetchUnaligned(x) ldl_u(x)
830
#define getstipplepixels( psrcstip, xt, w, ones, psrcpix, destpix ) \
833
q = CfbFetchUnaligned(psrcstip) >> (xt); \
834
if ( ((xt)+(w)) > (PPW*PSZ) ) \
835
q |= (CfbFetchUnaligned((psrcstip)+1)) << ((PPW*PSZ)-(xt)); \
836
q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
837
*(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
841
#define getstipplepixels24(psrcstip,xt,w,ones,psrcpix,destpix,stipindex,srcindex,dstindex) \
845
register unsigned int sidx; \
846
register unsigned int didx; \
847
sidx = ((srcindex) & 3)<<1; \
848
didx = ((dstindex) & 3)<<1; \
849
q = *(psrcstip) >> (xt); \
850
/* if((srcindex)!=0)*/ \
851
/* src = (((*(psrcpix)) << cfb24Shift[sidx]) & (cfbmask[sidx])) |*/ \
852
/* (((*((psrcpix)+1)) << cfb24Shift[sidx+1]) & (cfbmask[sidx+1])); */\
854
src = (*(psrcpix))&0xFFFFFF; \
855
if ( ((xt)+(w)) > PGSZ ) \
856
q |= (*((psrcstip)+1)) << (PGSZ -(xt)); \
857
q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
858
src &= QuartetPixelMaskTable[q]; \
859
*(destpix) &= cfbrmask[didx]; \
862
*(destpix) |= (src &cfbmask[didx]); \
867
*(destpix) = ((*(destpix)) & (cfbrmask[didx]))| \
868
(BitLeft(src, cfb24Shift[didx]) & (cfbmask[didx])); \
871
*(destpix) |= (BitRight(src, cfb24Shift[didx]) & cfbmask[didx]); \
876
#define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
879
q = *(psrcstip) >> (xt); \
880
q = ((ones) ? q : ~q) & 1; \
881
*(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
884
#endif /* PSZ == 24 */
887
extern PixelGroup cfbstarttab[];
888
extern PixelGroup cfbendtab[];
889
extern PixelGroup cfbstartpartial[];
890
extern PixelGroup cfbendpartial[];
891
extern PixelGroup cfbrmask[];
892
extern PixelGroup cfbmask[];
893
extern PixelGroup QuartetBitsTable[];
894
extern PixelGroup QuartetPixelMaskTable[];
896
extern int cfb24Shift[];