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 X Consortium
12 not be used in advertising or publicity pertaining to
13 distribution of the software without specific prior
14 written permission. Sun and X Consortium 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 /* $XConsortium: cfbmskbits.h,v 4.25 94/04/17 20:28:55 dpw Exp $ */
31 /* $XFree86: xc/programs/Xserver/cfb/cfbmskbits.h,v 3.3.2.1 1997/05/27 06:28:09 dawes Exp $ */
32 /* Optimizations for PSZ == 32 added by Kyle Marvin (marvin@vitec.com) */
38 #define NO_COMPILER_H_EXTRAS
43 * ==========================================================================
44 * Converted from mfb to support memory-mapped color framebuffer by smarks@sun,
47 * The way I did the conversion was to consider each longword as an
48 * array of four bytes instead of an array of 32 one-bit pixels. So
49 * getbits() and putbits() retain much the same calling sequence, but
50 * they move bytes around instead of bits. Of course, this entails the
51 * removal of all of the one-bit-pixel dependencies from the other
52 * files, but the major bit-hacking stuff should be covered here.
54 * I've created some new macros that make it easier to understand what's
55 * going on in the pixel calculations, and that make it easier to change the
60 * PSZ pixel size (in bits)
61 * PGSZ pixel group size (in bits)
62 * PGSZB pixel group size (in bytes)
63 * PGSZBMSK mask with lowest PGSZB bits set to 1
64 * PPW pixels per word (pixels per pixel group)
65 * PPWMSK mask with lowest PPW bits set to 1
66 * PLST index of last pixel in a word (should be PPW-1)
67 * PIM pixel index mask (index within a pixel group)
68 * PWSH pixel-to-word shift (should be log2(PPW))
69 * PMSK mask with lowest PSZ bits set to 1
72 * Here are some sample values. In the notation cfbA,B: A is PSZ, and
73 * B is PGSZB. All the other values are derived from these
74 * two. This table does not show all combinations!
76 * name cfb8,4 cfb24,4 cfb32,4 cfb8,8 cfb24,8 cfb32,8
77 * ---- ------ ------- ------ ------ ------ -------
79 * PGSZ 32 32 32 64 64 64
81 * PGSZBMSK 0xF 0xF? 0xF 0xFF 0xFF 0xFF
83 * PPWMSK 0xF 0x1 0x1 0xFF 0x3? 0x3
85 * PIM 0x3 0x0 0x0 0x7 0x1? 0x1
87 * PMSK 0xFF 0xFFFFFF 0xFFFFFFFF 0xFF 0xFFFFFF 0xFFFFFFFF
90 * I have also added a new macro, PFILL, that takes one pixel and
91 * replicates it throughout a word. This macro definition is dependent
92 * upon pixel and word size; it doesn't use macros like PPW and so
93 * forth. Examples: for monochrome, PFILL(1) => 0xffffffff, PFILL(0) =>
94 * 0x00000000. For 8-bit color, PFILL(0x5d) => 0x5d5d5d5d. This macro
95 * is used primarily for replicating a plane mask into a word.
97 * Color framebuffers operations also support the notion of a plane
98 * mask. This mask determines which planes of the framebuffer can be
99 * altered; the others are left unchanged. I have added another
100 * parameter to the putbits and putbitsrop macros that is the plane
102 * ==========================================================================
106 * PSZ needs to be defined before we get here. Usually it comes from a
107 * -DPSZ=foo on the compilation command line.
115 * PixelGroup is the data type used to operate on groups of pixels.
116 * We typedef it here to unsigned long with the assumption that you
117 * want to manipulate as many pixels at a time as you can. If unsigned
118 * long is not appropriate for your server, define it to something else
119 * before including this file. In this case you will also have to define
120 * PGSZB to the size in bytes of PixelGroup.
123 typedef unsigned long PixelGroup;
129 #endif /* PixelGroup */
131 #define PGSZ (PGSZB << 3)
132 #define PPW (PGSZ/PSZ)
135 #define PMSK (((PixelGroup)1 << PSZ) - 1)
136 #define PPWMSK (((PixelGroup)1 << PPW) - 1) /* instead of BITMSK */
137 #define PGSZBMSK (((PixelGroup)1 << PGSZB) - 1)
139 /* set PWSH = log2(PPW) using brute force */
155 #endif /* PPW == 16 */
156 #endif /* PPW == 8 */
157 #endif /* PPW == 4 */
158 #endif /* PPW == 2 */
159 #endif /* PPW == 1 */
161 /* Defining PIXEL_ADDR means that individual pixels are addressable by this
162 * machine (as type PixelType). A possible CFB architecture which supported
163 * 8-bits-per-pixel on a non byte-addressable machine would not have this
166 * Defining FOUR_BIT_CODE means that cfb knows how to stipple on this machine;
167 * eventually, stippling code for 16 and 32 bit devices should be written
168 * which would allow them to also use FOUR_BIT_CODE. There isn't that
169 * much to do in those cases, but it would make them quite a bit faster.
174 typedef CARD8 PixelType;
175 #define FOUR_BIT_CODE
180 typedef CARD16 PixelType;
185 #define PMSK 0xFFFFFF
189 typedef CARD32 PixelType;
194 #define PMSK 0xFFFFFFFF
196 typedef CARD32 PixelType;
200 /* the following notes use the following conventions:
201 SCREEN LEFT SCREEN RIGHT
202 in this file and maskbits.c, left and right refer to screen coordinates,
203 NOT bit numbering in registers.
206 pixels[0,n-1] = 0's pixels[n,PPW-1] = 1's
208 pixels[0,n-1] = 1's pixels[n,PPW-1] = 0's
210 cfbstartpartial[], cfbendpartial[]
211 these are used as accelerators for doing putbits and masking out
212 bits that are all contained between longword boudaries. the extra
213 256 bytes of data seems a small price to pay -- code is smaller,
214 and narrow things (e.g. window borders) go faster.
216 the names may seem misleading; they are derived not from which end
217 of the word the bits are turned on, but at which end of a scanline
218 the table tends to be used.
220 look at the tables and macros to understand boundary conditions.
221 (careful readers will note that starttab[n] = ~endtab[n] for n != 0)
223 -----------------------------------------------------------------------
224 these two macros depend on the screen's bit ordering.
225 in both of them x is a screen position. they are used to
226 combine bits collected from multiple longwords into a
227 single destination longword, and to unpack a single
228 source longword into multiple destinations.
231 takes dst[x, PPW] and moves them to dst[0, PPW-x]
232 the contents of the rest of dst are 0 ONLY IF
234 is cast as an unsigned.
235 this is a right shift on the VAX, left shift on
239 takes dst[0,x] and moves them to dst[PPW-x, PPW]
240 the contents of the rest of dst are 0 ONLY IF
242 this is a left shift on the VAX, right shift on
246 the remaining macros are cpu-independent; all bit order dependencies
247 are built into the tables and the two macros above.
249 maskbits(x, w, startmask, endmask, nlw)
250 for a span of width w starting at position x, returns
251 a mask for ragged pixels at start, mask for ragged pixels at end,
252 and the number of whole longwords between the ends.
254 maskpartialbits(x, w, mask)
255 works like maskbits(), except all the pixels are in the
256 same longword (i.e. (x&0xPIM + w) <= PPW)
258 mask32bits(x, w, startmask, endmask, nlw)
259 as maskbits, but does not calculate nlw. it is used by
260 cfbGlyphBlt to put down glyphs <= PPW bits wide.
262 getbits(psrc, x, w, dst)
263 starting at position x in psrc (x < PPW), collect w
264 pixels and put them in the screen left portion of dst.
265 psrc is a longword pointer. this may span longword boundaries.
266 it special-cases fetching all w bits from one longword.
268 +--------+--------+ +--------+
269 | | m |n| | ==> | m |n| |
270 +--------+--------+ +--------+
277 get m pixels, move to screen-left of dst, zeroing rest of dst;
278 get n pixels from next word, move screen-right by m, zeroing
279 lower m pixels of word.
280 OR the two things together.
282 putbits(src, x, w, pdst, planemask)
283 starting at position x in pdst, put down the screen-leftmost
284 w bits of src. pdst is a longword pointer. this may
285 span longword boundaries.
286 it special-cases putting all w bits into the same longword.
288 +--------+ +--------+--------+
289 | m |n| | ==> | | m |n| |
290 +--------+ +--------+--------+
297 get m pixels, shift screen-right by x, zero screen-leftmost x
298 pixels; zero rightmost m bits of *pdst and OR in stuff
299 from before the semicolon.
300 shift src screen-left by m, zero bits n-32;
301 zero leftmost n pixels of *(pdst+1) and OR in the
302 stuff from before the semicolon.
304 putbitsrop(src, x, w, pdst, planemask, ROP)
305 like putbits but calls DoRop with the rasterop ROP (see cfb.h for
308 getleftbits(psrc, w, dst)
309 get the leftmost w (w<=PPW) bits from *psrc and put them
310 in dst. this is used by the cfbGlyphBlt code for glyphs
314 #if (BITMAP_BIT_ORDER == MSBFirst)
315 #define BitRight(lw,n) ((lw) >> (n))
316 #define BitLeft(lw,n) ((lw) << (n))
317 #else /* (BITMAP_BIT_ORDER == LSBFirst) */
318 #define BitRight(lw,n) ((lw) << (n))
319 #define BitLeft(lw,n) ((lw) >> (n))
320 #endif /* (BITMAP_BIT_ORDER == MSBFirst) */
322 #define SCRLEFT(lw, n) BitLeft (lw, (n) * PSZ)
323 #define SCRRIGHT(lw, n) BitRight(lw, (n) * PSZ)
326 * Note that the shift direction is independent of the byte ordering of the
327 * machine. The following is portable code.
330 #define PFILL(p) ( ((p)&PMSK) | \
331 ((p)&PMSK) << PSZ | \
332 ((p)&PMSK) << 2*PSZ | \
333 ((p)&PMSK) << 3*PSZ | \
334 ((p)&PMSK) << 4*PSZ | \
335 ((p)&PMSK) << 5*PSZ | \
336 ((p)&PMSK) << 6*PSZ | \
337 ((p)&PMSK) << 7*PSZ | \
338 ((p)&PMSK) << 8*PSZ | \
339 ((p)&PMSK) << 9*PSZ | \
340 ((p)&PMSK) << 10*PSZ | \
341 ((p)&PMSK) << 11*PSZ | \
342 ((p)&PMSK) << 12*PSZ | \
343 ((p)&PMSK) << 13*PSZ | \
344 ((p)&PMSK) << 14*PSZ | \
345 ((p)&PMSK) << 15*PSZ )
346 #define PFILL2(p, pf) { \
349 pf |= (pf << 2*PSZ); \
350 pf |= (pf << 4*PSZ); \
351 pf |= (pf << 8*PSZ); \
353 #endif /* PPW == 16 */
355 #define PFILL(p) ( ((p)&PMSK) | \
356 ((p)&PMSK) << PSZ | \
357 ((p)&PMSK) << 2*PSZ | \
358 ((p)&PMSK) << 3*PSZ | \
359 ((p)&PMSK) << 4*PSZ | \
360 ((p)&PMSK) << 5*PSZ | \
361 ((p)&PMSK) << 6*PSZ | \
362 ((p)&PMSK) << 7*PSZ )
363 #define PFILL2(p, pf) { \
366 pf |= (pf << 2*PSZ); \
367 pf |= (pf << 4*PSZ); \
371 #define PFILL(p) ( ((p)&PMSK) | \
372 ((p)&PMSK) << PSZ | \
373 ((p)&PMSK) << 2*PSZ | \
374 ((p)&PMSK) << 3*PSZ )
375 #define PFILL2(p, pf) { \
378 pf |= (pf << 2*PSZ); \
382 #define PFILL(p) ( ((p)&PMSK) | \
384 #define PFILL2(p, pf) { \
391 #define PFILL2(p,pf) (pf = (p))
395 * Reduced raster op - using precomputed values, perform the above
396 * in three instructions
399 #define DoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
401 #define DoMaskRRop(dst, and, xor, mask) \
402 (((dst) & ((and) | ~(mask))) ^ (xor & mask))
404 #if PSZ != 32 || PPW != 1
406 # if (PSZ == 24 && PPW == 1)
407 #define maskbits(x, w, startmask, endmask, nlw) {\
408 startmask = cfbstarttab[(x)&3]; \
409 endmask = cfbendtab[((x)+(w)) & 3]; \
410 nlw = ((((x)+(w))*3)>>2) - (((x)*3 +3)>>2); \
413 #define mask32bits(x, w, startmask, endmask) \
414 startmask = cfbstarttab[(x)&3]; \
415 endmask = cfbendtab[((x)+(w)) & 3];
417 #define maskpartialbits(x, w, mask) \
418 mask = cfbstartpartial[(x) & 3] & cfbendpartial[((x)+(w)) & 3];
420 #define maskbits24(x, w, startmask, endmask, nlw) \
421 startmask = cfbstarttab24[(x) & 3]; \
422 endmask = cfbendtab24[((x)+(w)) & 3]; \
424 nlw = (((w) - (4 - ((x) & 3))) >> 2); \
429 #define getbits24(psrc, dst, index) {\
431 switch(idx = ((index)&3)<<1){ \
433 dst = (*(psrc) &cfbmask[idx]); \
436 dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]); \
439 dst = BitLeft((*(psrc) &cfbmask[idx]), cfb24Shift[idx]) | \
440 BitRight(((*((psrc)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
444 #define putbits24(src, x, w, pdst, planemask, index) {\
445 register PixelGroup dstpixel; \
446 register unsigned int idx; \
447 switch(idx = ((index)&3)<<1){ \
449 dstpixel = (*(pdst) &cfbmask[idx]); \
452 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
455 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
456 BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
458 dstpixel &= ~(planemask); \
459 dstpixel |= (src & planemask); \
460 *(pdst) &= cfbrmask[idx]; \
463 *(pdst) |= (dstpixel & cfbmask[idx]); \
468 *(pdst) = ((*(pdst)) & cfbrmask[idx]) | \
469 (BitLeft(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
472 *(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
477 #define putbitsrop24(src, x, pdst, planemask, rop) \
479 register PixelGroup t1, dstpixel; \
480 register unsigned int idx; \
481 switch(idx = (x)<<1){ \
483 dstpixel = (*(pdst) &cfbmask[idx]); \
486 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx]); \
489 dstpixel = BitLeft((*(pdst) &cfbmask[idx]), cfb24Shift[idx])| \
490 BitRight(((*((pdst)+1)) &cfbmask[idx+1]), cfb24Shift[idx+1]); \
492 DoRop(t1, rop, (src), dstpixel); \
493 dstpixel &= ~planemask; \
494 dstpixel |= (t1 & planemask); \
495 *(pdst) &= cfbrmask[idx]; \
498 *(pdst) |= (dstpixel & cfbmask[idx]); \
502 *((pdst)+1) = ((*((pdst)+1)) & cfbrmask[idx+1]) | \
503 (BitLeft(dstpixel, cfb24Shift[idx+1]) & (cfbmask[idx+1])); \
505 *(pdst) |= (BitRight(dstpixel, cfb24Shift[idx]) & cfbmask[idx]); \
508 # else /* PSZ == 24 && PPW == 1 */
509 #define maskbits(x, w, startmask, endmask, nlw) \
510 startmask = cfbstarttab[(x)&PIM]; \
511 endmask = cfbendtab[((x)+(w)) & PIM]; \
513 nlw = (((w) - (PPW - ((x)&PIM))) >> PWSH); \
517 #define maskpartialbits(x, w, mask) \
518 mask = cfbstartpartial[(x) & PIM] & cfbendpartial[((x) + (w)) & PIM];
520 #define mask32bits(x, w, startmask, endmask) \
521 startmask = cfbstarttab[(x)&PIM]; \
522 endmask = cfbendtab[((x)+(w)) & PIM];
525 #define maskbits24(x, w, startmask, endmask, nlw) \
527 #define getbits24(psrc, dst, index) \
529 #define putbits24(src, x, w, pdst, planemask, index) \
531 #define putbitsrop24(src, x, pdst, planemask, rop) \
534 #endif /* PSZ == 24 && PPW == 1 */
536 #define getbits(psrc, x, w, dst) \
537 if ( ((x) + (w)) <= PPW) \
539 dst = SCRLEFT(*(psrc), (x)); \
545 dst = (SCRLEFT(*(psrc), (x)) & cfbendtab[m]) | \
546 (SCRRIGHT(*((psrc)+1), m) & cfbstarttab[m]); \
550 #define putbits(src, x, w, pdst, planemask) \
551 if ( ((x)+(w)) <= PPW) \
553 PixelGroup tmpmask; \
554 maskpartialbits((x), (w), tmpmask); \
555 tmpmask &= PFILL(planemask); \
556 *(pdst) = (*(pdst) & ~tmpmask) | (SCRRIGHT(src, x) & tmpmask); \
562 PixelGroup pm = PFILL(planemask); \
565 *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | \
566 (SCRRIGHT(src, x) & (cfbstarttab[x] & pm)); \
567 *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
568 (SCRLEFT(src, m) & (cfbendtab[n] & pm)); \
570 #if defined(__GNUC__) && defined(mc68020)
572 #define FASTGETBITS(psrc, x, w, dst) \
573 asm ("bfextu %3{%1:%2},%0" \
574 : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
576 #define getbits(psrc,x,w,dst) \
578 FASTGETBITS(psrc, (x) * PSZ, (w) * PSZ, dst); \
579 dst = SCRLEFT(dst,PPW-(w)); \
582 #define FASTPUTBITS(src, x, w, pdst) \
583 asm ("bfins %3,%0{%1:%2}" \
584 : "=o" (*(char *)(pdst)) \
585 : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
588 #define putbits(src, x, w, pdst, planemask) \
590 if (planemask != PMSK) { \
591 PixelGroup _m, _pm; \
592 FASTGETBITS(pdst, (x) * PSZ , (w) * PSZ, _m); \
593 PFILL2(planemask, _pm); \
595 _m |= (SCRRIGHT(src, PPW-(w)) & _pm); \
596 FASTPUTBITS(_m, (x) * PSZ, (w) * PSZ, pdst); \
598 FASTPUTBITS(SCRRIGHT(src, PPW-(w)), (x) * PSZ, (w) * PSZ, pdst); \
605 #define putbitsrop(src, x, w, pdst, planemask, rop) \
606 if ( ((x)+(w)) <= PPW) \
608 PixelGroup tmpmask; \
610 maskpartialbits((x), (w), tmpmask); \
611 PFILL2(planemask, t1); \
613 t1 = SCRRIGHT((src), (x)); \
614 DoRop(t2, rop, t1, *(pdst)); \
615 *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
623 PFILL2(planemask, pm); \
626 t1 = SCRRIGHT((src), (x)); \
627 DoRop(t2, rop, t1, *(pdst)); \
628 *(pdst) = (*(pdst) & (cfbendtab[x] | ~pm)) | (t2 & (cfbstarttab[x] & pm));\
629 t1 = SCRLEFT((src), m); \
630 DoRop(t2, rop, t1, *((pdst) + 1)); \
631 *((pdst)+1) = (*((pdst)+1) & (cfbstarttab[n] | ~pm)) | \
632 (t2 & (cfbendtab[n] & pm)); \
635 #else /* PSZ == 32 && PPW == 1*/
638 * These macros can be optimized for 32-bit pixels since there is no
639 * need to worry about left/right edge masking. These macros were
640 * derived from the above using the following reductions:
642 * - x & PIW = 0 [since PIW = 0]
643 * - all masking tables are only indexed by 0 [ due to above ]
644 * - cfbstartab[0] and cfbendtab[0] = 0 [ no left/right edge masks]
645 * - cfbstartpartial[0] and cfbendpartial[0] = ~0 [no partial pixel mask]
647 * Macro reduction based upon constants cannot be performed automatically
648 * by the compiler since it does not know the contents of the masking
649 * arrays in cfbmskbits.c.
651 #define maskbits(x, w, startmask, endmask, nlw) \
652 startmask = endmask = 0; \
655 #define maskpartialbits(x, w, mask) \
658 #define mask32bits(x, w, startmask, endmask) \
659 startmask = endmask = 0;
662 * For 32-bit operations, getbits(), putbits(), and putbitsrop()
663 * will only be invoked with x = 0 and w = PPW (1). The getbits()
664 * macro is only called within left/right edge logic, which doesn't
665 * happen for 32-bit pixels.
667 #define getbits(psrc, x, w, dst) (dst) = *(psrc)
669 #define putbits(src, x, w, pdst, planemask) \
670 *(pdst) = (*(pdst) & ~planemask) | (src & planemask);
672 #define putbitsrop(src, x, w, pdst, planemask, rop) \
675 DoRop(t1, rop, (src), *(pdst)); \
676 *(pdst) = (*(pdst) & ~planemask) | (t1 & planemask); \
679 #endif /* PSZ != 32 */
682 * Use these macros only when you're using the MergeRop stuff
683 * in ../mfb/mergerop.h
686 /* useful only when not spanning destination longwords */
688 #define putbitsmropshort24(src,x,w,pdst,index) {\
689 PixelGroup _tmpmask; \
691 maskpartialbits ((x), (w), _tmpmask); \
692 _t1 = SCRRIGHT((src), (x)); \
693 DoMaskMergeRop24(_t1, pdst, _tmpmask, index); \
696 #define putbitsmropshort(src,x,w,pdst) {\
697 PixelGroup _tmpmask; \
699 maskpartialbits ((x), (w), _tmpmask); \
700 _t1 = SCRRIGHT((src), (x)); \
701 *pdst = DoMaskMergeRop(_t1, *pdst, _tmpmask); \
704 /* useful only when spanning destination longwords */
705 #define putbitsmroplong(src,x,w,pdst) { \
706 PixelGroup _startmask, _endmask; \
710 _startmask = cfbstarttab[x]; \
711 _endmask = cfbendtab[(w) - _m]; \
712 _t1 = SCRRIGHT((src), (x)); \
713 pdst[0] = DoMaskMergeRop(_t1,pdst[0],_startmask); \
714 _t1 = SCRLEFT ((src),_m); \
715 pdst[1] = DoMaskMergeRop(_t1,pdst[1],_endmask); \
718 #define putbitsmrop(src,x,w,pdst) \
719 if ((x) + (w) <= PPW) {\
720 putbitsmropshort(src,x,w,pdst); \
722 putbitsmroplong(src,x,w,pdst); \
725 #if GETLEFTBITS_ALIGNMENT == 1
726 #define getleftbits(psrc, w, dst) dst = *((unsigned int *) psrc)
727 #define getleftbits24(psrc, w, dst, idx){ \
728 regiseter int index; \
729 switch(index = ((idx)&3)<<1){ \
731 dst = (*((unsigned int *) psrc))&cfbmask[index]; \
735 dst = BitLeft(((*((unsigned int *) psrc))&cfbmask[index]), cfb24Shift[index]); \
736 dst |= BitRight(((*((unsigned int *) psrc)+1)&cfbmask[index]), cfb4Shift[index]); \
739 dst = BitLeft((*((unsigned int *) psrc)),cfb24Shift[index]); \
743 #endif /* GETLEFTBITS_ALIGNMENT == 1 */
745 #define getglyphbits(psrc, x, w, dst) \
747 dst = BitLeft((unsigned) *(psrc), (x)); \
748 if ( ((x) + (w)) > 32) \
749 dst |= (BitRight((unsigned) *((psrc)+1), 32-(x))); \
751 #if GETLEFTBITS_ALIGNMENT == 2
752 #define getleftbits(psrc, w, dst) \
754 if ( ((int)(psrc)) & 0x01 ) \
755 getglyphbits( ((unsigned int *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
757 dst = *((unsigned int *) psrc); \
759 #endif /* GETLEFTBITS_ALIGNMENT == 2 */
761 #if GETLEFTBITS_ALIGNMENT == 4
762 #define getleftbits(psrc, w, dst) \
765 off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
767 (unsigned int *)( ((char *)(psrc)) - off), \
768 (off_b), (w), (dst) \
771 #endif /* GETLEFTBITS_ALIGNMENT == 4 */
774 * getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix )
776 * Converts bits to pixels in a reasonable way. Takes w (1 <= w <= PPW)
777 * bits from *psrcstip, starting at bit x; call this a quartet of bits.
778 * Then, takes the pixels from *psrcpix corresponding to the one-bits (if
779 * ones is TRUE) or the zero-bits (if ones is FALSE) of the quartet
780 * and puts these pixels into destpix.
784 * getstipplepixels( &(0x08192A3B), 17, 4, 1, &(0x4C5D6E7F), dest )
786 * 0x08192A3B = 0000 1000 0001 1001 0010 1010 0011 1011
788 * This will take 4 bits starting at bit 17, so the quartet is 0x5 = 0101.
789 * It will take pixels from 0x4C5D6E7F corresponding to the one-bits in this
790 * quartet, so dest = 0x005D007F.
792 * XXX Works with both byte order.
793 * XXX This works for all values of x and w within a doubleword.
795 #if (BITMAP_BIT_ORDER == MSBFirst)
796 #define getstipplepixels( psrcstip, x, w, ones, psrcpix, destpix ) \
800 if ((m = ((x) - ((PPW*PSZ)-PPW))) > 0) { \
801 q = (*(psrcstip)) << m; \
802 if ( (x)+(w) > (PPW*PSZ) ) \
803 q |= *((psrcstip)+1) >> ((PPW*PSZ)-m); \
806 q = (*(psrcstip)) >> -m; \
807 q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
808 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
810 #else /* BITMAP_BIT_ORDER == LSB */
812 /*================================================================
813 BEGIN ORL VNC modification
814 Only use ldq_u on XFREE86 platforms */
817 #define getstipplepixels( psrcstip, xt, w, ones, psrcpix, destpix ) \
820 q = ldq_u(psrcstip) >> (xt); \
821 if ( ((xt)+(w)) > (PPW*PSZ) ) \
822 q |= (ldq_u((psrcstip)+1)) << ((PPW*PSZ)-(xt)); \
823 q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
824 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
827 #define getstipplepixels( psrcstip, xt, w, ones, psrcpix, destpix ) \
830 q = *(psrcstip) >> (xt); \
831 if ( ((xt)+(w)) > (PPW*PSZ) ) \
832 q |= (*((psrcstip)+1)) << ((PPW*PSZ)-(xt)); \
833 q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
834 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
838 /* END ORL VNC modification
839 ================================================================*/
843 #define getstipplepixels24( psrcstip,xt,w,ones,psrcpix,destpix,stipindex,srcindex,dstindex) \
845 PixelGroup q, srcpix, srcstip; \
847 register unsigned int sidx; \
848 register unsigned int didx; \
849 register unsigned int stipidx; \
850 sidx = ((srcindex) & 3)<<1; \
851 didx = ((dstindex) & 3)<<1; \
852 q = *(psrcstip) >> (xt); \
853 /* if((srcindex)!=0)*/ \
854 /* src = (((*(psrcpix)) << cfb24Shift[sidx]) & (cfbmask[sidx])) |*/ \
855 /* (((*((psrcpix)+1)) << cfb24Shift[sidx+1]) & (cfbmask[sidx+1])); */\
857 src = (*(psrcpix))&0xFFFFFF; \
858 if ( ((xt)+(w)) > PGSZ ) \
859 q |= (*((psrcstip)+1)) << (PGSZ -(xt)); \
860 q = QuartetBitsTable[(w)] & ((ones) ? q : ~q); \
861 src &= QuartetPixelMaskTable[q]; \
862 *(destpix) &= cfbrmask[didx]; \
865 *(destpix) |= (src &cfbmask[didx]); \
870 *(destpix) = ((*(destpix)) & (cfbrmask[didx]))| \
871 (BitLeft(src, cfb24Shift[didx]) & (cfbmask[didx])); \
874 *(destpix) |= (BitRight(src, cfb24Shift[didx]) & cfbmask[didx]); \
879 #define getstipplepixels24(psrcstip,xt,ones,psrcpix,destpix,stipindex) \
881 PixelGroup q, srcpix, srcstip; \
883 register unsigned int stipidx; \
884 q = *(psrcstip) >> (xt); \
885 q = ((ones) ? q : ~q) & 1; \
886 *(destpix) = (*(psrcpix)) & QuartetPixelMaskTable[q]; \
889 #endif /* PSZ == 24 */
892 extern PixelGroup cfbstarttab[];
893 extern PixelGroup cfbendtab[];
894 extern PixelGroup cfbstartpartial[];
895 extern PixelGroup cfbendpartial[];
896 extern PixelGroup cfbrmask[];
897 extern PixelGroup cfbmask[];
898 extern PixelGroup QuartetBitsTable[];
899 extern PixelGroup QuartetPixelMaskTable[];
901 extern int cfb24Shift[];