1 /************************************************************
2 Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
6 Permission to use, copy, modify, and distribute this
7 software and its documentation for any purpose and without
8 fee is hereby granted, provided that the above copyright no-
9 tice appear in all copies and that both that copyright no-
10 tice and this permission notice appear in supporting docu-
11 mentation, and that the names of Sun or The Open Group
12 not be used in advertising or publicity pertaining to
13 distribution of the software without specific prior
14 written permission. Sun and The Open Group make no
15 representations about the suitability of this software for
16 any purpose. It is provided "as is" without any express or
19 SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
21 NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
22 ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
24 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
26 THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 ********************************************************/
30 /* Optimizations for PSZ == 32 added by Kyle Marvin (marvin@vitec.com) */
38 * ==========================================================================
39 * Converted from mfb to support memory-mapped color framebuffer by smarks@sun,
42 * The way I did the conversion was to consider each longword as an
43 * array of four bytes instead of an array of 32 one-bit pixels. So
44 * getbits() and putbits() retain much the same calling sequence, but
45 * they move bytes around instead of bits. Of course, this entails the
46 * removal of all of the one-bit-pixel dependencies from the other
47 * files, but the major bit-hacking stuff should be covered here.
49 * I've created some new macros that make it easier to understand what's
50 * going on in the pixel calculations, and that make it easier to change the
55 * PSZ pixel size (in bits)
56 * PGSZ pixel group size (in bits)
57 * PGSZB pixel group size (in bytes)
58 * PGSZBMSK mask with lowest PGSZB bits set to 1
59 * PPW pixels per word (pixels per pixel group)
60 * PPWMSK mask with lowest PPW bits set to 1
61 * PLST index of last pixel in a word (should be PPW-1)
62 * PIM pixel index mask (index within a pixel group)
63 * PWSH pixel-to-word shift (should be log2(PPW))
64 * PMSK mask with lowest PSZ bits set to 1
67 * Here are some sample values. In the notation cfbA,B: A is PSZ, and
68 * B is PGSZB. All the other values are derived from these
69 * two. This table does not show all combinations!
71 * name cfb8,4 cfb24,4 cfb32,4 cfb8,8 cfb24,8 cfb32,8
72 * ---- ------ ------- ------ ------ ------ -------
74 * PGSZ 32 32 32 64 64 64
76 * PGSZBMSK 0xF 0xF? 0xF 0xFF 0xFF 0xFF
78 * PPWMSK 0xF 0x1 0x1 0xFF 0x3? 0x3
80 * PIM 0x3 0x0 0x0 0x7 0x1? 0x1
82 * PMSK 0xFF 0xFFFFFF 0xFFFFFFFF 0xFF 0xFFFFFF 0xFFFFFFFF
85 * I have also added a new macro, PFILL, that takes one pixel and
86 * replicates it throughout a word. This macro definition is dependent
87 * upon pixel and word size; it doesn't use macros like PPW and so
88 * forth. Examples: for monochrome, PFILL(1) => 0xffffffff, PFILL(0) =>
89 * 0x00000000. For 8-bit color, PFILL(0x5d) => 0x5d5d5d5d. This macro
90 * is used primarily for replicating a plane mask into a word.
92 * Color framebuffers operations also support the notion of a plane
93 * mask. This mask determines which planes of the framebuffer can be
94 * altered; the others are left unchanged. I have added another
95 * parameter to the putbits and putbitsrop macros that is the plane
97 * ==========================================================================
99 * Keith Packard (keithp@suse.com)
100 * 64bit code is no longer supported; it requires DIX support
101 * for repadding images which significantly impacts performance
105 * PSZ needs to be defined before we get here. Usually it comes from a
106 * -DPSZ=foo on the compilation command line.
114 * PixelGroup is the data type used to operate on groups of pixels.
115 * We typedef it here to CARD32 with the assumption that you
116 * want to manipulate 32 bits worth of pixels at a time as you can. If CARD32
117 * is not appropriate for your server, define it to something else
118 * before including this file. In this case you will also have to define
119 * PGSZB to the size in bytes of PixelGroup.
122 #define PixelGroup CARD32
124 #endif /* PixelGroup */
127 #define CfbBits CARD32
130 #define PGSZ (PGSZB << 3)
131 #define PPW (PGSZ/PSZ)
134 #define PMSK (((PixelGroup)1 << PSZ) - 1)
135 #define PPWMSK (((PixelGroup)1 << PPW) - 1) /* instead of BITMSK */
136 #define PGSZBMSK (((PixelGroup)1 << PGSZB) - 1)
138 /* set PWSH = log2(PPW) using brute force */
154 #endif /* PPW == 16 */
155 #endif /* PPW == 8 */
156 #endif /* PPW == 4 */
157 #endif /* PPW == 2 */
158 #endif /* PPW == 1 */
160 /* Defining PIXEL_ADDR means that individual pixels are addressable by this
161 * machine (as type PixelType). A possible CFB architecture which supported
162 * 8-bits-per-pixel on a non byte-addressable machine would not have this
165 * Defining FOUR_BIT_CODE means that cfb knows how to stipple on this machine;
166 * eventually, stippling code for 16 and 32 bit devices should be written
167 * which would allow them to also use FOUR_BIT_CODE. There isn't that
168 * much to do in those cases, but it would make them quite a bit faster.
173 typedef CARD8 PixelType
;
174 #define FOUR_BIT_CODE
179 typedef CARD16 PixelType
;
184 #define PMSK 0xFFFFFF
188 typedef CARD32 PixelType
;
193 #define PMSK 0xFFFFFFFF
195 typedef CARD32 PixelType
;
199 /* the following notes use the following conventions:
200 SCREEN LEFT SCREEN RIGHT
201 in this file and maskbits.c, left and right refer to screen coordinates,
202 NOT bit numbering in registers.
205 pixels[0,n-1] = 0's pixels[n,PPW-1] = 1's
207 pixels[0,n-1] = 1's pixels[n,PPW-1] = 0's
209 cfbstartpartial[], cfbendpartial[]
210 these are used as accelerators for doing putbits and masking out
211 bits that are all contained between longword boudaries. the extra
212 256 bytes of data seems a small price to pay -- code is smaller,
213 and narrow things (e.g. window borders) go faster.
215 the names may seem misleading; they are derived not from which end
216 of the word the bits are turned on, but at which end of a scanline
217 the table tends to be used.
219 look at the tables and macros to understand boundary conditions.
220 (careful readers will note that starttab[n] = ~endtab[n] for n != 0)
222 -----------------------------------------------------------------------
223 these two macros depend on the screen's bit ordering.
224 in both of them x is a screen position. they are used to
225 combine bits collected from multiple longwords into a
226 single destination longword, and to unpack a single
227 source longword into multiple destinations.
230 takes dst[x, PPW] and moves them to dst[0, PPW-x]
231 the contents of the rest of dst are 0 ONLY IF
233 is cast as an unsigned.
234 this is a right shift on the VAX, left shift on
238 takes dst[0,x] and moves them to dst[PPW-x, PPW]
239 the contents of the rest of dst are 0 ONLY IF
241 this is a left shift on the VAX, right shift on
245 the remaining macros are cpu-independent; all bit order dependencies
246 are built into the tables and the two macros above.
248 maskbits(x, w, startmask, endmask, nlw)
249 for a span of width w starting at position x, returns
250 a mask for ragged pixels at start, mask for ragged pixels at end,
251 and the number of whole longwords between the ends.
253 maskpartialbits(x, w, mask)
254 works like maskbits(), except all the pixels are in the
255 same longword (i.e. (x&0xPIM + w) <= PPW)
257 mask32bits(x, w, startmask, endmask, nlw)
258 as maskbits, but does not calculate nlw. it is used by
259 cfbGlyphBlt to put down glyphs <= PPW bits wide.
261 getbits(psrc, x, w, dst)
262 starting at position x in psrc (x < PPW), collect w
263 pixels and put them in the screen left portion of dst.
264 psrc is a longword pointer. this may span longword boundaries.
265 it special-cases fetching all w bits from one longword.
267 +--------+--------+ +--------+
268 | | m |n| | ==> | m |n| |
269 +--------+--------+ +--------+
276 get m pixels, move to screen-left of dst, zeroing rest of dst;
277 get n pixels from next word, move screen-right by m, zeroing
278 lower m pixels of word.
279 OR the two things together.
281 putbits(src, x, w, pdst, planemask)
282 starting at position x in pdst, put down the screen-leftmost
283 w bits of src. pdst is a longword pointer. this may
284 span longword boundaries.
285 it special-cases putting all w bits into the same longword.
287 +--------+ +--------+--------+
288 | m |n| | ==> | | m |n| |
289 +--------+ +--------+--------+
296 get m pixels, shift screen-right by x, zero screen-leftmost x
297 pixels; zero rightmost m bits of *pdst and OR in stuff
298 from before the semicolon.
299 shift src screen-left by m, zero bits n-32;
300 zero leftmost n pixels of *(pdst+1) and OR in the
301 stuff from before the semicolon.
303 putbitsrop(src, x, w, pdst, planemask, ROP)
304 like putbits but calls DoRop with the rasterop ROP (see cfb.h for
307 getleftbits(psrc, w, dst)
308 get the leftmost w (w<=PPW) bits from *psrc and put them
309 in dst. this is used by the cfbGlyphBlt code for glyphs
313 #if (BITMAP_BIT_ORDER == MSBFirst)
314 #define BitRight(lw,n) ((lw) >> (n))
315 #define BitLeft(lw,n) ((lw) << (n))
316 #else /* (BITMAP_BIT_ORDER == LSBFirst) */
317 #define BitRight(lw,n) ((lw) << (n))
318 #define BitLeft(lw,n) ((lw) >> (n))
319 #endif /* (BITMAP_BIT_ORDER == MSBFirst) */
321 #define SCRLEFT(lw, n) BitLeft (lw, (n) * PSZ)
322 #define SCRRIGHT(lw, n) BitRight(lw, (n) * PSZ)
325 * Note that the shift direction is independent of the byte ordering of the
326 * machine. The following is portable code.
329 #define PFILL(p) ( ((p)&PMSK) | \
330 ((p)&PMSK) << PSZ | \
331 ((p)&PMSK) << 2*PSZ | \
332 ((p)&PMSK) << 3*PSZ | \
333 ((p)&PMSK) << 4*PSZ | \
334 ((p)&PMSK) << 5*PSZ | \
335 ((p)&PMSK) << 6*PSZ | \
336 ((p)&PMSK) << 7*PSZ | \
337 ((p)&PMSK) << 8*PSZ | \
338 ((p)&PMSK) << 9*PSZ | \
339 ((p)&PMSK) << 10*PSZ | \
340 ((p)&PMSK) << 11*PSZ | \
341 ((p)&PMSK) << 12*PSZ | \
342 ((p)&PMSK) << 13*PSZ | \
343 ((p)&PMSK) << 14*PSZ | \
344 ((p)&PMSK) << 15*PSZ )
345 #define PFILL2(p, pf) { \
348 pf |= (pf << 2*PSZ); \
349 pf |= (pf << 4*PSZ); \
350 pf |= (pf << 8*PSZ); \
352 #endif /* PPW == 16 */
354 #define PFILL(p) ( ((p)&PMSK) | \
355 ((p)&PMSK) << PSZ | \
356 ((p)&PMSK) << 2*PSZ | \
357 ((p)&PMSK) << 3*PSZ | \
358 ((p)&PMSK) << 4*PSZ | \
359 ((p)&PMSK) << 5*PSZ | \
360 ((p)&PMSK) << 6*PSZ | \
361 ((p)&PMSK) << 7*PSZ )
362 #define PFILL2(p, pf) { \
365 pf |= (pf << 2*PSZ); \
366 pf |= (pf << 4*PSZ); \
370 #define PFILL(p) ( ((p)&PMSK) | \
371 ((p)&PMSK) << PSZ | \
372 ((p)&PMSK) << 2*PSZ | \
373 ((p)&PMSK) << 3*PSZ )
374 #define PFILL2(p, pf) { \
377 pf |= (pf << 2*PSZ); \
381 #define PFILL(p) ( ((p)&PMSK) | \
383 #define PFILL2(p, pf) { \
390 #define PFILL2(p,pf) (pf = (p))
394 * Reduced raster op - using precomputed values, perform the above
395 * in three instructions
398 #define DoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
400 #define DoMaskRRop(dst, and, xor, mask) \
401 (((dst) & ((and) | ~(mask))) ^ (xor & mask))
403 #if PSZ != 32 || PPW != 1
405 # if (PSZ == 24 && PPW == 1)
406 #define maskbits(x, w, startmask, endmask, nlw) {\
407 startmask = cfbstarttab[(x)&3]; \
408 endmask = cfbendtab[((x)+(w)) & 3]; \
409 nlw = ((((x)+(w))*3)>>2) - (((x)*3 +3)>>2); \
412 #define mask32bits(x, w, startmask, endmask) \
413 startmask = cfbstarttab[(x)&3]; \
414 endmask = cfbendtab[((x)+(w)) & 3];
416 #define maskpartialbits(x, w, mask) \
417 mask = cfbstartpartial[(x) & 3] & cfbendpartial[((x)+(w)) & 3];
419 #define maskbits24(x, w, startmask, endmask, nlw) \
420 startmask = cfbstarttab24[(x) & 3]; \
421 endmask = cfbendtab24[((x)+(w)) & 3]; \
423 nlw = (((w) - (4 - ((x) & 3))) >> 2); \
428 #define getbits24(psrc, dst, index) {\
430 switch(idx = ((index)&3)<<1){ \
432 dst = (*(psrc) &cfbmask[idx]); \
435 dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]); \
438 dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]) | \
439 BitRight(((*((psrc)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
443 #define putbits24(src, w, pdst, planemask, index) {\
444 register PixelGroup dstpixel; \
445 register unsigned int idx; \
446 switch(idx = ((index)&3)<<1){ \
448 dstpixel = (*(pdst) &cfbmask[idx]); \
451 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
454 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
455 BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
457 dstpixel &= ~(planemask); \
458 dstpixel |= (src & planemask); \
459 *(pdst) &= cfbrmask[idx]; \
462 *(pdst) |= (dstpixel & cfbmask[idx]); \
467 *(pdst) = ((*(pdst)) & cfbrmask[idx]) | \
468 (BitLeft(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
471 *(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
476 #define putbitsrop24(src, x, pdst, planemask, rop) \
478 register PixelGroup t1, dstpixel; \
479 register unsigned int idx; \
480 switch(idx = (x)<<1){ \
482 dstpixel = (*(pdst) &cfbmask[idx]); \
485 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
488 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
489 BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
491 DoRop(t1, rop, (src), dstpixel); \
492 dstpixel &= ~planemask; \
493 dstpixel |= (t1 & planemask); \
494 *(pdst) &= cfbrmask[idx]; \
497 *(pdst) |= (dstpixel & cfbmask[idx]); \
501 *((pdst)+1) = ((*((pdst)+1)) & cfbrmask[idx+1]) | \
502 (BitLeft(dstpixel, cfb24Shift[idx+1]) & (cfbmask[idx+1])); \
504 *(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
507 # else /* PSZ == 24 && PPW == 1 */
508 #define maskbits(x, w, startmask, endmask, nlw) \
509 startmask = cfbstarttab[(x)&PIM]; \
510 endmask = cfbendtab[((x)+(w)) & PIM]; \
512 nlw = (((w) - (PPW - ((x)&PIM))) >> PWSH); \
516 #define maskpartialbits(x, w, mask) \
517 mask = cfbstartpartial[(x) & PIM] & cfbendpartial[((x) + (w)) & PIM];
519 #define mask32bits(x, w, startmask, endmask) \
520 startmask = cfbstarttab[(x)&PIM]; \
521 endmask = cfbendtab[((x)+(w)) & PIM];
524 #define maskbits24(x, w, startmask, endmask, nlw) \
526 #define getbits24(psrc, dst, index) \
528 #define putbits24(src, w, pdst, planemask, index) \
530 #define putbitsrop24(src, x, pdst, planemask, rop) \
533 #endif /* PSZ == 24 && PPW == 1 */
535 #define getbits(psrc, x, w, dst) \
536 if ( ((x) + (w)) <= PPW) \
538 dst = SCRLEFT(*(psrc), (x)); \
544 dst = (SCRLEFT(*(psrc), (x)) & cfbendtab[m]) | \
545 (SCRRIGHT(*((psrc)+1), m) & cfbstarttab[m]); \
549 #define putbits(src, x, w, pdst, planemask) \
550 if ( ((x)+(w)) <= PPW) \
552 PixelGroup tmpmask; \
553 maskpartialbits((x), (w), tmpmask); \
554 tmpmask &= PFILL(planemask); \
555 *(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \
561 PixelGroup pm = PFILL(planemask); \
564 *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | \
565 (SCRRIGHT(src, x) & (cfbstarttab[x] & pm)); \
566 *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
567 (SCRLEFT(src, m) & (cfbendtab[n] & pm)); \
569 #if defined(__GNUC__) && defined(mc68020)
571 #define FASTGETBITS(psrc, x, w, dst) \
572 asm ("bfextu %3{%1:%2},%0" \
573 : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
575 #define getbits(psrc,x,w,dst) \
577 FASTGETBITS(psrc, (x) * PSZ, (w) * PSZ, dst); \
578 dst = SCRLEFT(dst,PPW-(w)); \
581 #define FASTPUTBITS(src, x, w, pdst) \
582 asm ("bfins %3,%0{%1:%2}" \
583 : "=o" (*(char *)(pdst)) \
584 : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
587 #define putbits(src, x, w, pdst, planemask) \
589 if (planemask != PMSK) { \
590 PixelGroup _m, _pm; \
591 FASTGETBITS(pdst, (x) * PSZ , (w) * PSZ, _m); \
592 PFILL2(planemask, _pm); \
594 _m |= (SCRRIGHT(src, PPW-(w)) & _pm); \
595 FASTPUTBITS(_m, (x) * PSZ, (w) * PSZ, pdst); \
597 FASTPUTBITS(SCRRIGHT(src, PPW-(w)), (x) * PSZ, (w) * PSZ, pdst); \
604 #define putbitsrop(src, x, w, pdst, planemask, rop) \
605 if ( ((x)+(w)) <= PPW) \
607 PixelGroup tmpmask; \
609 maskpartialbits((x), (w), tmpmask); \
610 PFILL2(planemask, t1); \
612 t1 = SCRRIGHT((src), (x)); \
613 DoRop(t2, rop, t1, *(pdst)); \
614 *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
622 PFILL2(planemask, pm); \
625 t1 = SCRRIGHT((src), (x)); \
626 DoRop(t2, rop, t1, *(pdst)); \
627 *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | (t2 & (cfbstarttab[x] & pm));\
628 t1 = SCRLEFT((src), m); \
629 DoRop(t2, rop, t1, *((pdst) + 1)); \
630 *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
631 (t2 & (cfbendtab[n] & pm)); \
634 #else /* PSZ == 32 && PPW == 1*/
637 * These macros can be optimized for 32-bit pixels since there is no
638 * need to worry about left/right edge masking. These macros were
639 * derived from the above using the following reductions:
641 * - x & PIW = 0 [since PIW = 0]
642 * - all masking tables are only indexed by 0 [ due to above ]
643 * - cfbstartab[0] and cfbendtab[0] = 0 [ no left/right edge masks]
644 * - cfbstartpartial[0] and cfbendpartial[0] = ~0 [no partial pixel mask]
646 * Macro reduction based upon constants cannot be performed automatically
647 * by the compiler since it does not know the contents of the masking
648 * arrays in cfbmskbits.c.
650 #define maskbits(x, w, startmask, endmask, nlw) \
651 startmask = endmask = 0; \
654 #define maskpartialbits(x, w, mask) \
657 #define mask32bits(x, w, startmask, endmask) \
658 startmask = endmask = 0;
661 * For 32-bit operations, getbits(), putbits(), and putbitsrop()
662 * will only be invoked with x = 0 and w = PPW (1). The getbits()
663 * macro is only called within left/right edge logic, which doesn't
664 * happen for 32-bit pixels.
666 #define getbits(psrc, x, w, dst) (dst) = *(psrc)
668 #define putbits(src, x, w, pdst, planemask) \
669 *(pdst) = (*(pdst) & ~planemask) | (src & planemask);
671 #define putbitsrop(src, x, w, pdst, planemask, rop) \
674 DoRop(t1, rop, (src), *(pdst)); \
675 *(pdst) = (*(pdst) & ~planemask) | (t1 & planemask); \
678 #endif /* PSZ != 32 */
681 * Use these macros only when you're using the MergeRop stuff
682 * in ../mfb/mergerop.h
685 /* useful only when not spanning destination longwords */
687 #define putbitsmropshort24(src,x,w,pdst,index) {\
688 PixelGroup _tmpmask; \
690 maskpartialbits ((x), (w), _tmpmask); \
691 _t1 = SCRRIGHT((src), (x)); \
692 DoMaskMergeRop24(_t1, pdst, _tmpmask, index); \
695 #define putbitsmropshort(src,x,w,pdst) {\
696 PixelGroup _tmpmask; \
698 maskpartialbits ((x), (w), _tmpmask); \
699 _t1 = SCRRIGHT((src), (x)); \
700 *pdst = DoMaskMergeRop(_t1, *pdst, _tmpmask); \
703 /* useful only when spanning destination longwords */
704 #define putbitsmroplong(src,x,w,pdst) { \
705 PixelGroup _startmask, _endmask; \
709 _startmask = cfbstarttab[x]; \
710 _endmask = cfbendtab[(w) - _m]; \
711 _t1 = SCRRIGHT((src), (x)); \
712 pdst[0] = DoMaskMergeRop(_t1,pdst[0],_startmask); \
713 _t1 = SCRLEFT ((src),_m); \
714 pdst[1] = DoMaskMergeRop(_t1,pdst[1],_endmask); \
717 #define putbitsmrop(src,x,w,pdst) \
718 if ((x) + (w) <= PPW) {\
719 putbitsmropshort(src,x,w,pdst); \
721 putbitsmroplong(src,x,w,pdst); \
724 #if GETLEFTBITS_ALIGNMENT == 1
725 #define getleftbits(psrc, w, dst) dst = *((unsigned int *) psrc)
726 #define getleftbits24(psrc, w, dst, idx){ \
727 regiseter int index; \
728 switch(index = ((idx)&3)<<1){ \
730 dst = (*((unsigned int *) psrc))&cfbmask[index]; \
734 dst = BitLeft(((*((unsigned int *) psrc))&cfbmask[index]), cfb24Shift[index]); \
735 dst |= BitRight(((*((unsigned int *) psrc)+1)&cfbmask[index]), cfb4Shift[index]); \
738 dst = BitLeft((*((unsigned int *) psrc)),cfb24Shift[index]); \
742 #endif /* GETLEFTBITS_ALIGNMENT == 1 */
744 #define getglyphbits(psrc, x, w, dst) \
746 dst = BitLeft((unsigned) *(psrc), (x)); \
747 if ( ((x) + (w)) > 32) \
748 dst |= (BitRight((unsigned) *((psrc)+1), 32-(x))); \
750 #if GETLEFTBITS_ALIGNMENT == 2
751 #define getleftbits(psrc, w, dst) \
753 if ( ((int)(psrc)) & 0x01 ) \
754 getglyphbits( ((unsigned int *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
756 dst = *((unsigned int *) psrc); \
758 #endif /* GETLEFTBITS_ALIGNMENT == 2 */
760 #if GETLEFTBITS_ALIGNMENT == 4
761 #define getleftbits(psrc, w, dst) \
764 off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
766 (unsigned int *)( ((char *)(psrc)) - off), \
767 (off_b), (w), (dst) \
770 #endif /* GETLEFTBITS_ALIGNMENT == 4 */
773 * getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix )
775 * Converts bits to pixels in a reasonable way. Takes w (1 <= w <= PPW)
776 * bits from *psrcstip, starting at bit x; call this a quartet of bits.
777 * Then, takes the pixels from *psrcpix corresponding to the one-bits (if
778 * ones is TRUE) or the zero-bits (if ones is FALSE) of the quartet
779 * and puts these pixels into destpix.
783 * getstipplepixels( &(0x08192A3B), 17, 4, 1, &(0x4C5D6E7F), dest )
785 * 0x08192A3B = 0000 1000 0001 1001 0010 1010 0011 1011
787 * This will take 4 bits starting at bit 17, so the quartet is 0x5 = 0101.
788 * It will take pixels from 0x4C5D6E7F corresponding to the one-bits in this
789 * quartet, so dest = 0x005D007F.
791 * XXX Works with both byte order.
792 * XXX This works for all values of x and w within a doubleword.
794 #if (BITMAP_BIT_ORDER == MSBFirst)
795 #define getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) \
799 if ((m = ((x) - ((PPW*PSZ)-PPW))) > 0) { \
800 q = (*(psrcstip)) << m; \
801 if ( (x)+(w) > (PPW*PSZ) ) \
802 q |= *((psrcstip)+1) >> ((PPW*PSZ)-m); \
805 q = (*(psrcstip)) >> -m; \
806 q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
807 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
809 /* I just copied this to get the linker satisfied on PowerPC,
810 * so this may not be correct at all.
812 #define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
815 q = *(psrcstip) >> (xt); \
816 q = ((ones) ? q : ~q) & 1; \
817 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
819 #else /* BITMAP_BIT_ORDER == LSB */
821 /* this must load 32 bits worth; for most machines, thats an int */
822 #define CfbFetchUnaligned(x) ldl_u(x)
824 #define getstipplepixels( psrcstip, xt, w, ones, psrcpix, destpix ) \
827 q = CfbFetchUnaligned(psrcstip) >> (xt); \
828 if ( ((xt)+(w)) > (PPW*PSZ) ) \
829 q |= (CfbFetchUnaligned((psrcstip)+1)) << ((PPW*PSZ)-(xt)); \
830 q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
831 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
835 #define getstipplepixels24(psrcstip,xt,w,ones,psrcpix,destpix,stipindex,srcindex,dstindex) \
839 register unsigned int sidx; \
840 register unsigned int didx; \
841 sidx = ((srcindex) & 3)<<1; \
842 didx = ((dstindex) & 3)<<1; \
843 q = *(psrcstip) >> (xt); \
844 /* if((srcindex)!=0)*/ \
845 /* src = (((*(psrcpix)) << cfb24Shift[sidx]) & (cfbmask[sidx])) |*/ \
846 /* (((*((psrcpix)+1)) << cfb24Shift[sidx+1]) & (cfbmask[sidx+1])); */\
848 src = (*(psrcpix))&0xFFFFFF; \
849 if ( ((xt)+(w)) > PGSZ ) \
850 q |= (*((psrcstip)+1)) << (PGSZ -(xt)); \
851 q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
852 src &= QuartetPixelMaskTable[q]; \
853 *(destpix) &= cfbrmask[didx]; \
856 *(destpix) |= (src &cfbmask[didx]); \
861 *(destpix) = ((*(destpix)) & (cfbrmask[didx]))| \
862 (BitLeft(src, cfb24Shift[didx]) & (cfbmask[didx])); \
865 *(destpix) |= (BitRight(src, cfb24Shift[didx]) & cfbmask[didx]); \
870 #define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
873 q = *(psrcstip) >> (xt); \
874 q = ((ones) ? q : ~q) & 1; \
875 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
878 #endif /* PSZ == 24 */
881 extern PixelGroup cfbstarttab
[];
882 extern PixelGroup cfbendtab
[];
883 extern PixelGroup cfbstartpartial
[];
884 extern PixelGroup cfbendpartial
[];
885 extern PixelGroup cfbrmask
[];
886 extern PixelGroup cfbmask
[];
887 extern PixelGroup QuartetBitsTable
[];
888 extern PixelGroup QuartetPixelMaskTable
[];
890 extern int cfb24Shift
[];