X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fmfb%2Fmaskbits.h;fp=Xserver%2Fprograms%2FXserver%2Fmfb%2Fmaskbits.h;h=cab946a4938db22e6f9d46c3fce996df745659ee;hb=b6e6afccf37f4ad0515ef2a698f714fdf1bf23b3;hp=0000000000000000000000000000000000000000;hpb=e3340a110a3b01756b8e67531395a33b40a17d37;p=rdpsrv diff --git a/Xserver/programs/Xserver/mfb/maskbits.h b/Xserver/programs/Xserver/mfb/maskbits.h new file mode 100644 index 0000000..cab946a --- /dev/null +++ b/Xserver/programs/Xserver/mfb/maskbits.h @@ -0,0 +1,719 @@ +/* Combined Purdue/PurduePlus patches, level 2.1, 1/24/89 */ +/*********************************************************** +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XConsortium: maskbits.h,v 1.33 94/04/17 20:28:13 dpw Exp $ */ +/* $XFree86: xc/programs/Xserver/mfb/maskbits.h,v 3.3 1996/12/09 11:56:33 dawes Exp $ */ +#include "X.h" +#include "Xmd.h" +#include "servermd.h" + + +/* the following notes use the following conventions: +SCREEN LEFT SCREEN RIGHT +in this file and maskbits.c, left and right refer to screen coordinates, +NOT bit numbering in registers. + +starttab[n] + bits[0,n-1] = 0 bits[n,PLST] = 1 +endtab[n] = + bits[0,n-1] = 1 bits[n,PLST] = 0 + +startpartial[], endpartial[] + these are used as accelerators for doing putbits and masking out +bits that are all contained between longword boudaries. the extra +256 bytes of data seems a small price to pay -- code is smaller, +and narrow things (e.g. window borders) go faster. + +the names may seem misleading; they are derived not from which end +of the word the bits are turned on, but at which end of a scanline +the table tends to be used. + +look at the tables and macros to understand boundary conditions. +(careful readers will note that starttab[n] = ~endtab[n] for n != 0) + +----------------------------------------------------------------------- +these two macros depend on the screen's bit ordering. +in both of them x is a screen position. they are used to +combine bits collected from multiple longwords into a +single destination longword, and to unpack a single +source longword into multiple destinations. + +SCRLEFT(dst, x) + takes dst[x, PPW] and moves them to dst[0, PPW-x] + the contents of the rest of dst are 0. + this is a right shift on LSBFirst (forward-thinking) + machines like the VAX, and left shift on MSBFirst + (backwards) machines like the 680x0 and pc/rt. + +SCRRIGHT(dst, x) + takes dst[0,x] and moves them to dst[PPW-x, PPW] + the contents of the rest of dst are 0. + this is a left shift on LSBFirst, right shift + on MSBFirst. + + +the remaining macros are cpu-independent; all bit order dependencies +are built into the tables and the two macros above. + +maskbits(x, w, startmask, endmask, nlw) + for a span of width w starting at position x, returns +a mask for ragged bits at start, mask for ragged bits at end, +and the number of whole longwords between the ends. + +maskpartialbits(x, w, mask) + works like maskbits(), except all the bits are in the + same longword (i.e. (x&PIM + w) <= PPW) + +maskPPWbits(x, w, startmask, endmask, nlw) + as maskbits, but does not calculate nlw. it is used by + mfbGlyphBlt to put down glyphs <= PPW bits wide. + +------------------------------------------------------------------- + +NOTE + any pointers passed to the following 4 macros are + guranteed to be PPW-bit aligned. + The only non-PPW-bit-aligned references ever made are + to font glyphs, and those are made with getleftbits() + and getshiftedleftbits (qq.v.) + + For 64-bit server, it is assumed that we will never have font padding + of more than 4 bytes. The code uses int's to access the fonts + intead of longs. + +getbits(psrc, x, w, dst) + starting at position x in psrc (x < PPW), collect w + bits and put them in the screen left portion of dst. + psrc is a longword pointer. this may span longword boundaries. + it special-cases fetching all w bits from one longword. + + +--------+--------+ +--------+ + | | m |n| | ==> | m |n| | + +--------+--------+ +--------+ + x x+w 0 w + psrc psrc+1 dst + m = PPW - x + n = w - m + + implementation: + get m bits, move to screen-left of dst, zeroing rest of dst; + get n bits from next word, move screen-right by m, zeroing + lower m bits of word. + OR the two things together. + +putbits(src, x, w, pdst) + starting at position x in pdst, put down the screen-leftmost + w bits of src. pdst is a longword pointer. this may + span longword boundaries. + it special-cases putting all w bits into the same longword. + + +--------+ +--------+--------+ + | m |n| | ==> | | m |n| | + +--------+ +--------+--------+ + 0 w x x+w + dst pdst pdst+1 + m = PPW - x + n = w - m + + implementation: + get m bits, shift screen-right by x, zero screen-leftmost x + bits; zero rightmost m bits of *pdst and OR in stuff + from before the semicolon. + shift src screen-left by m, zero bits n-PPW; + zero leftmost n bits of *(pdst+1) and OR in the + stuff from before the semicolon. + +putbitsrop(src, x, w, pdst, ROP) + like putbits but calls DoRop with the rasterop ROP (see mfb.h for + DoRop) + +putbitsrrop(src, x, w, pdst, ROP) + like putbits but calls DoRRop with the reduced rasterop ROP + (see mfb.h for DoRRop) + +----------------------------------------------------------------------- + The two macros below are used only for getting bits from glyphs +in fonts, and glyphs in fonts are gotten only with the following two +mcros. + You should tune these macros toyour font format and cpu +byte ordering. + +NOTE +getleftbits(psrc, w, dst) + get the leftmost w (w<=32) bits from *psrc and put them + in dst. this is used by the mfbGlyphBlt code for glyphs + <=PPW bits wide. + psrc is declared (unsigned char *) + + psrc is NOT guaranteed to be PPW-bit aligned. on many + machines this will cause problems, so there are several + versions of this macro. + + this macro is called ONLY for getting bits from font glyphs, + and depends on the server-natural font padding. + + for blazing text performance, you want this macro + to touch memory as infrequently as possible (e.g. + fetch longwords) and as efficiently as possible + (e.g. don't fetch misaligned longwords) + +getshiftedleftbits(psrc, offset, w, dst) + used by the font code; like getleftbits, but shifts the + bits SCRLEFT by offset. + this is implemented portably, calling getleftbits() + and SCRLEFT(). + psrc is declared (unsigned char *). +*/ + +/* to match CFB and allow algorithm sharing ... + * name mfb32 mfb64 explanation + * ---- ------ ----- ----------- + * PGSZ 32 64 pixel group size (in bits; same as PPW for mfb) + * PGSZB 4 8 pixel group size (in bytes) + * PPW 32 64 pixels per word (pixels per pixel group) + * PLST 31 63 index of last pixel in a word (should be PPW-1) + * PIM 0x1f 0x3f pixel index mask (index within a pixel group) + * PWSH 5 6 pixel-to-word shift (should be log2(PPW)) + * + * The MFB_ versions are here so that cfb can include maskbits.h to get + * the bitmap constants without conflicting with its own P* constants. + */ + +/* warning: PixelType definition duplicated in mfb.h */ +#ifndef PixelType +#define PixelType unsigned long +#endif /* PixelType */ + +#ifdef LONG64 +#define MFB_PGSZB 8 +#else +#define MFB_PGSZB 4 +#endif /* LONG64 */ +#define MFB_PPW (MFB_PGSZB<<3) /* assuming 8 bits per byte */ +#define MFB_PGSZ MFB_PPW +#define MFB_PLST (MFB_PPW-1) +#define MFB_PIM MFB_PLST + +/* set PWSH = log2(PPW) using brute force */ + +#if MFB_PPW == 32 +#define MFB_PWSH 5 +#else +#if MFB_PPW == 64 +#define MFB_PWSH 6 +#endif /* MFB_PPW == 64 */ +#endif /* MFB_PPW == 32 */ + +extern PixelType starttab[]; +extern PixelType endtab[]; +extern PixelType partmasks[MFB_PPW][MFB_PPW]; +extern PixelType rmask[]; +extern PixelType mask[]; + +#ifndef MFB_CONSTS_ONLY + +#define PGSZB MFB_PGSZB +#define PPW MFB_PPW +#define PGSZ MFB_PGSZ +#define PLST MFB_PLST +#define PIM MFB_PIM +#define PWSH MFB_PWSH + +#define BitLeft(b,s) SCRLEFT(b,s) +#define BitRight(b,s) SCRRIGHT(b,s) + +#if (BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER) +#define LONG2CHARS(x) ((unsigned long)(x)) +#else +/* + * the unsigned case below is for compilers like + * the Danbury C and i386cc + */ +#if PPW == 32 +#define LONG2CHARS( x ) ( ( ( ( x ) & (unsigned long)0x000000FF ) << 0x18 ) \ + | ( ( ( x ) & (unsigned long)0x0000FF00 ) << 0x08 ) \ + | ( ( ( x ) & (unsigned long)0x00FF0000 ) >> 0x08 ) \ + | ( ( ( x ) & (unsigned long)0xFF000000 ) >> 0x18 ) ) +#else /* PPW == 64 */ +#if defined( __alpha__) +#define LONG2CHARS( x ) \ + ( ( ( ( x ) & 0x000000FFUL) << 0x38 ) \ + | ( ( ( x ) & 0x0000FF00UL) << 0x28 ) \ + | ( ( ( x ) & 0x00FF0000UL) << 0x18 ) \ + | ( ( ( x ) & 0xFF000000UL) << 0x08 ) \ + | ( ( ( x ) & 0x000000FF00000000UL) >> 0x08 ) \ + | ( ( ( x ) & 0x0000FF0000000000UL) >> 0x18 ) \ + | ( ( ( x ) & 0x00FF000000000000UL) >> 0x28 ) \ + | ( ( ( x ) & 0xFF00000000000000UL) >> 0x38 ) ) +#else /* __alpha__ */ +#define LONG2CHARS( x ) ( ( ( ( x ) & 0x000000FF000000FFUL) << 0x18 ) \ + | ( ( ( x ) & 0x0000FF000000FF00UL) << 0x08 ) \ + | ( ( ( x ) & 0x00FF000000FF0000UL) >> 0x08 ) \ + | ( ( ( x ) & 0xFF000000FF000000UL) >> 0x18 ) ) +#endif /* __alpha__ */ +#endif /* PPW */ +#endif /* BITMAP_BIT_ORDER */ + +#ifdef STRICT_ANSI_SHIFT +#define SHL(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) << (y))) +#define SHR(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) >> (y))) +#else +#define SHL(x,y) LONG2CHARS(LONG2CHARS(x) << (y)) +#define SHR(x,y) LONG2CHARS(LONG2CHARS(x) >> (y)) +#endif + +#if (BITMAP_BIT_ORDER == MSBFirst) /* pc/rt, 680x0 */ +#define SCRLEFT(lw, n) SHL((PixelType)(lw),(n)) +#define SCRRIGHT(lw, n) SHR((PixelType)(lw),(n)) +#else /* vax, intel */ +#define SCRLEFT(lw, n) SHR((PixelType)(lw),(n)) +#define SCRRIGHT(lw, n) SHL((PixelType)(lw),(n)) +#endif + +#define DoRRop(alu, src, dst) \ +(((alu) == RROP_BLACK) ? ((dst) & ~(src)) : \ + ((alu) == RROP_WHITE) ? ((dst) | (src)) : \ + ((alu) == RROP_INVERT) ? ((dst) ^ (src)) : \ + (dst)) + +#if PPW == 32 +/* A generalized form of a x4 Duff's Device */ +#define Duff(counter, block) { \ + while (counter >= 4) {\ + { block; } \ + { block; } \ + { block; } \ + { block; } \ + counter -= 4; \ + } \ + switch (counter & 3) { \ + case 3: { block; } \ + case 2: { block; } \ + case 1: { block; } \ + case 0: \ + counter = 0; \ + } \ +} +#else /* PPW == 64 */ +/* A generalized form of a x8 Duff's Device */ +#define Duff(counter, block) { \ + while (counter >= 8) {\ + { block; } \ + { block; } \ + { block; } \ + { block; } \ + { block; } \ + { block; } \ + { block; } \ + { block; } \ + counter -= 8; \ + } \ + switch (counter & 7) { \ + case 7: { block; } \ + case 6: { block; } \ + case 5: { block; } \ + case 4: { block; } \ + case 3: { block; } \ + case 2: { block; } \ + case 1: { block; } \ + case 0: \ + counter = 0; \ + } \ +} +#endif /* PPW */ + + +#define maskbits(x, w, startmask, endmask, nlw) \ + startmask = starttab[(x) & PIM]; \ + endmask = endtab[((x)+(w)) & PIM]; \ + if (startmask) \ + nlw = (((w) - (PPW - ((x) & PIM))) >> PWSH); \ + else \ + nlw = (w) >> PWSH; + +#define maskpartialbits(x, w, mask) \ + mask = partmasks[(x) & PIM][(w) & PIM]; + +#define maskPPWbits(x, w, startmask, endmask) \ + startmask = starttab[(x) & PIM]; \ + endmask = endtab[((x)+(w)) & PIM]; + +#ifdef __GNUC__ /* XXX don't want for Alpha? */ +#ifdef vax +#define FASTGETBITS(psrc,x,w,dst) \ + __asm ("extzv %1,%2,%3,%0" \ + : "=g" (dst) \ + : "g" (x), "g" (w), "m" (*(char *)(psrc))) +#define getbits(psrc,x,w,dst) FASTGETBITS(psrc,x,w,dst) + +#define FASTPUTBITS(src, x, w, pdst) \ + __asm ("insv %3,%1,%2,%0" \ + : "=m" (*(char *)(pdst)) \ + : "g" (x), "g" (w), "g" (src)) +#define putbits(src, x, w, pdst) FASTPUTBITS(src, x, w, pdst) +#endif /* vax */ +#ifdef mc68020 +#define FASTGETBITS(psrc, x, w, dst) \ + __asm ("bfextu %3{%1:%2},%0" \ + : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc))) + +#define getbits(psrc,x,w,dst) \ +{ \ + FASTGETBITS(psrc, x, w, dst);\ + dst = SHL(dst,(32-(w))); \ +} + +#define FASTPUTBITS(src, x, w, pdst) \ + __asm ("bfins %3,%0{%1:%2}" \ + : "=o" (*(char *)(pdst)) \ + : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst))) + +#define putbits(src, x, w, pdst) FASTPUTBITS(SHR((src),32-(w)), x, w, pdst) + +#endif /* mc68020 */ +#endif /* __GNUC__ */ + +/* The following flag is used to override a bugfix for sun 3/60+CG4 machines, + */ + +/* We don't need to be careful about this unless we're dealing with sun3's + * We will default its usage for those who do not know anything, but will + * override its effect if the machine doesn't look like a sun3 + */ +#if !defined(mc68020) || !defined(sun) +#define NO_3_60_CG4 +#endif + +/* This is gross. We want to #define u_putbits as something which can be used + * in the case of the 3/60+CG4, but if we use /bin/cc or are on another + * machine type, we want nothing to do with u_putbits. What a hastle. Here + * I used slo_putbits as something which either u_putbits or putbits could be + * defined as. + * + * putbits gets it iff it is not already defined with FASTPUTBITS above. + * u_putbits gets it if we have FASTPUTBITS (putbits) from above and have not + * overridden the NO_3_60_CG4 flag. + */ + +#define slo_putbits(src, x, w, pdst) \ +{ \ + register int n = (x)+(w)-PPW; \ + \ + if (n <= 0) \ + { \ + register PixelType tmpmask; \ + maskpartialbits((x), (w), tmpmask); \ + *(pdst) = (*(pdst) & ~tmpmask) | \ + (SCRRIGHT(src, x) & tmpmask); \ + } \ + else \ + { \ + *(pdst) = (*(pdst) & endtab[x]) | (SCRRIGHT((src), x)); \ + (pdst)[1] = ((pdst)[1] & starttab[n]) | \ + (SCRLEFT(src, PPW-(x)) & endtab[n]); \ + } \ +} + +#if defined(putbits) && !defined(NO_3_60_CG4) +#define u_putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst) +#else +#define u_putbits(src, x, w, pdst) putbits(src, x, w, pdst) +#endif + +#if !defined(putbits) +#define putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst) +#endif + +/* Now if we have not gotten any really good bitfield macros, try some + * moderately fast macros. Alas, I don't know how to do asm instructions + * without gcc. + */ + +#ifndef getbits +#define getbits(psrc, x, w, dst) \ +{ \ + dst = SCRLEFT(*(psrc), (x)); \ + if ( ((x) + (w)) > PPW) \ + dst |= (SCRRIGHT(*((psrc)+1), PPW-(x))); \ +} +#endif + +/* We have to special-case putbitsrop because of 3/60+CG4 combos + */ + +#define u_putbitsrop(src, x, w, pdst, rop) \ +{\ + register PixelType t1, t2; \ + register int n = (x)+(w)-PPW; \ + \ + t1 = SCRRIGHT((src), (x)); \ + DoRop(t2, rop, t1, *(pdst)); \ + \ + if (n <= 0) \ + { \ + register PixelType tmpmask; \ + \ + maskpartialbits((x), (w), tmpmask); \ + *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \ + } \ + else \ + { \ + int m = PPW-(x); \ + *(pdst) = (*(pdst) & endtab[x]) | (t2 & starttab[x]); \ + t1 = SCRLEFT((src), m); \ + DoRop(t2, rop, t1, (pdst)[1]); \ + (pdst)[1] = ((pdst)[1] & starttab[n]) | (t2 & endtab[n]); \ + } \ +} + +/* If our getbits and putbits are FAST enough, + * do this brute force, it's faster + */ + +#if defined(FASTPUTBITS) && defined(FASTGETBITS) && defined(NO_3_60_CG4) +#if (BITMAP_BIT_ORDER == MSBFirst) +#define putbitsrop(src, x, w, pdst, rop) \ +{ \ + register PixelType _tmp, _tmp2; \ + FASTGETBITS(pdst, x, w, _tmp); \ + _tmp2 = SCRRIGHT(src, PPW-(w)); \ + DoRop(_tmp, rop, _tmp2, _tmp) \ + FASTPUTBITS(_tmp, x, w, pdst); \ +} +#define putbitsrrop(src, x, w, pdst, rop) \ +{ \ + register PixelType _tmp, _tmp2; \ + \ + FASTGETBITS(pdst, x, w, _tmp); \ + _tmp2 = SCRRIGHT(src, PPW-(w)); \ + _tmp= DoRRop(rop, _tmp2, _tmp); \ + FASTPUTBITS(_tmp, x, w, pdst); \ +} +#undef u_putbitsrop +#else +#define putbitsrop(src, x, w, pdst, rop) \ +{ \ + register PixelType _tmp; \ + FASTGETBITS(pdst, x, w, _tmp); \ + DoRop(_tmp, rop, src, _tmp) \ + FASTPUTBITS(_tmp, x, w, pdst); \ +} +#define putbitsrrop(src, x, w, pdst, rop) \ +{ \ + register PixelType _tmp; \ + \ + FASTGETBITS(pdst, x, w, _tmp); \ + _tmp= DoRRop(rop, src, _tmp); \ + FASTPUTBITS(_tmp, x, w, pdst); \ +} +#undef u_putbitsrop +#endif +#endif + +#ifndef putbitsrop +#define putbitsrop(src, x, w, pdst, rop) u_putbitsrop(src, x, w, pdst, rop) +#endif + +#ifndef putbitsrrop +#define putbitsrrop(src, x, w, pdst, rop) \ +{\ + register PixelType t1, t2; \ + register int n = (x)+(w)-PPW; \ + \ + t1 = SCRRIGHT((src), (x)); \ + t2 = DoRRop(rop, t1, *(pdst)); \ + \ + if (n <= 0) \ + { \ + register PixelType tmpmask; \ + \ + maskpartialbits((x), (w), tmpmask); \ + *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \ + } \ + else \ + { \ + int m = PPW-(x); \ + *(pdst) = (*(pdst) & endtab[x]) | (t2 & starttab[x]); \ + t1 = SCRLEFT((src), m); \ + t2 = DoRRop(rop, t1, (pdst)[1]); \ + (pdst)[1] = ((pdst)[1] & starttab[n]) | (t2 & endtab[n]); \ + } \ +} +#endif + +#if GETLEFTBITS_ALIGNMENT == 1 +#define getleftbits(psrc, w, dst) dst = *((CARD32 *) psrc) +#endif /* GETLEFTBITS_ALIGNMENT == 1 */ + +#if GETLEFTBITS_ALIGNMENT == 2 +#define getleftbits(psrc, w, dst) \ + { \ + if ( ((int)(psrc)) & 0x01 ) \ + getbits( ((CARD32 *)(((char *)(psrc))-1)), 8, (w), (dst) ); \ + else \ + getbits(psrc, 0, w, dst); \ + } +#endif /* GETLEFTBITS_ALIGNMENT == 2 */ + +#if GETLEFTBITS_ALIGNMENT == 4 +#define getleftbits(psrc, w, dst) \ + { \ + int off, off_b; \ + off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \ + getbits( \ + (CARD32 *)( ((char *)(psrc)) - off), \ + (off_b), (w), (dst) \ + ); \ + } +#endif /* GETLEFTBITS_ALIGNMENT == 4 */ + + +#define getshiftedleftbits(psrc, offset, w, dst) \ + getleftbits((psrc), (w), (dst)); \ + dst = SCRLEFT((dst), (offset)); + +/* FASTGETBITS and FASTPUTBITS are not necessarily correct implementations of + * getbits and putbits, but they work if used together. + * + * On a MSBFirst machine, a cpu bitfield extract instruction (like bfextu) + * could normally assign its result to a long word register in the screen + * right position. This saves canceling register shifts by not fighting the + * natural cpu byte order. + * + * Unfortunately, these fail on a 3/60+CG4 and cannot be used unmodified. Sigh. + */ +#if defined(FASTGETBITS) && defined(FASTPUTBITS) +#ifdef NO_3_60_CG4 +#define u_FASTPUT(aa, bb, cc, dd) FASTPUTBITS(aa, bb, cc, dd) +#else +#define u_FASTPUT(aa, bb, cc, dd) u_putbits(SCRLEFT(aa, PPW-(cc)), bb, cc, dd) +#endif + +#define getandputbits(psrc, srcbit, dstbit, width, pdst) \ +{ \ + register PixelType _tmpbits; \ + FASTGETBITS(psrc, srcbit, width, _tmpbits); \ + u_FASTPUT(_tmpbits, dstbit, width, pdst); \ +} + +#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \ +{ \ + register PixelType _tmpsrc, _tmpdst; \ + FASTGETBITS(pdst, dstbit, width, _tmpdst); \ + FASTGETBITS(psrc, srcbit, width, _tmpsrc); \ + DoRop(_tmpdst, rop, _tmpsrc, _tmpdst); \ + u_FASTPUT(_tmpdst, dstbit, width, pdst); \ +} + +#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \ +{ \ + register PixelType _tmpsrc, _tmpdst; \ + FASTGETBITS(pdst, dstbit, width, _tmpdst); \ + FASTGETBITS(psrc, srcbit, width, _tmpsrc); \ + _tmpdst = DoRRop(rop, _tmpsrc, _tmpdst); \ + u_FASTPUT(_tmpdst, dstbit, width, pdst); \ +} + +#define getandputbits0(psrc, srcbit, width, pdst) \ + getandputbits(psrc, srcbit, 0, width, pdst) + +#define getandputrop0(psrc, srcbit, width, pdst, rop) \ + getandputrop(psrc, srcbit, 0, width, pdst, rop) + +#define getandputrrop0(psrc, srcbit, width, pdst, rop) \ + getandputrrop(psrc, srcbit, 0, width, pdst, rop) + + +#else /* Slow poke */ + +/* pairs of getbits/putbits happen frequently. Some of the code can + * be shared or avoided in a few specific instances. It gets us a + * small advantage, so we do it. The getandput...0 macros are the only ones + * which speed things here. The others are here for compatibility w/the above + * FAST ones + */ + +#define getandputbits(psrc, srcbit, dstbit, width, pdst) \ +{ \ + register PixelType _tmpbits; \ + getbits(psrc, srcbit, width, _tmpbits); \ + putbits(_tmpbits, dstbit, width, pdst); \ +} + +#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \ +{ \ + register PixelType _tmpbits; \ + getbits(psrc, srcbit, width, _tmpbits) \ + putbitsrop(_tmpbits, dstbit, width, pdst, rop) \ +} + +#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \ +{ \ + register PixelType _tmpbits; \ + getbits(psrc, srcbit, width, _tmpbits) \ + putbitsrrop(_tmpbits, dstbit, width, pdst, rop) \ +} + + +#define getandputbits0(psrc, sbindex, width, pdst) \ +{ /* unroll the whole damn thing to see how it * behaves */ \ + register int _flag = PPW - (sbindex); \ + register PixelType _src; \ + \ + _src = SCRLEFT (*(psrc), (sbindex)); \ + if ((width) > _flag) \ + _src |= SCRRIGHT (*((psrc) + 1), _flag); \ + \ + *(pdst) = (*(pdst) & starttab[(width)]) | (_src & endtab[(width)]); \ +} + + +#define getandputrop0(psrc, sbindex, width, pdst, rop) \ +{ \ + register int _flag = PPW - (sbindex); \ + register PixelType _src; \ + \ + _src = SCRLEFT (*(psrc), (sbindex)); \ + if ((width) > _flag) \ + _src |= SCRRIGHT (*((psrc) + 1), _flag); \ + DoRop(_src, rop, _src, *(pdst)); \ + \ + *(pdst) = (*(pdst) & starttab[(width)]) | (_src & endtab[(width)]); \ +} + +#define getandputrrop0(psrc, sbindex, width, pdst, rop) \ +{ \ + int _flag = PPW - (sbindex); \ + register PixelType _src; \ + \ + _src = SCRLEFT (*(psrc), (sbindex)); \ + if ((width) > _flag) \ + _src |= SCRRIGHT (*((psrc) + 1), _flag); \ + _src = DoRRop(rop, _src, *(pdst)); \ + \ + *(pdst) = (*(pdst) & starttab[(width)]) | (_src & endtab[(width)]); \ +} + +#endif /* FASTGETBITS && FASTPUTBITS */ + +#endif /* MFB_CONSTS_ONLY */