diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /xorg-server/mfb/maskbits.h | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'xorg-server/mfb/maskbits.h')
-rw-r--r-- | xorg-server/mfb/maskbits.h | 689 |
1 files changed, 689 insertions, 0 deletions
diff --git a/xorg-server/mfb/maskbits.h b/xorg-server/mfb/maskbits.h new file mode 100644 index 000000000..36a611fe7 --- /dev/null +++ b/xorg-server/mfb/maskbits.h @@ -0,0 +1,689 @@ +/* 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. + +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <X11/X.h> +#include <X11/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. + * + * Keith Packard (keithp@suse.com): + * Note mfb64 is no longer supported; it requires DIX support + * for realigning images which costs too much + */ + +/* warning: PixelType definition duplicated in mfb.h */ +#ifndef PixelType +#define PixelType CARD32 +#endif /* PixelType */ +#ifndef MfbBits +#define MfbBits CARD32 +#endif + +#define MFB_PGSZB 4 +#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 +#endif /* MFB_PPW == 32 */ + +/* XXX don't use these five */ +extern PixelType starttab[]; +extern PixelType endtab[]; +extern PixelType partmasks[MFB_PPW][MFB_PPW]; +extern PixelType rmask[]; +extern PixelType mask[]; +/* XXX use these five */ +extern PixelType mfbGetstarttab(int); +extern PixelType mfbGetendtab(int); +extern PixelType mfbGetpartmasks(int, int); +extern PixelType mfbGetrmask(int); +extern PixelType mfbGetmask(int); + +#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 1 +#define LONG2CHARSSAMEORDER(x) ((MfbBits)(x)) +#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \ + | ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \ + | ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \ + | ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) ) +#endif /* XFree86Server */ + +#if (BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER) +#define LONG2CHARS(x) ((MfbBits)(x)) +#else +/* + * the unsigned case below is for compilers like + * the Danbury C and i386cc + */ +#define LONG2CHARS( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \ + | ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \ + | ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \ + | ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) ) +#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)) + +/* 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; \ + } \ +} + +#define maskbits(x, w, startmask, endmask, nlw) \ + startmask = mfbGetstarttab((x) & PIM); \ + endmask = mfbGetendtab(((x)+(w)) & PIM); \ + if (startmask) \ + nlw = (((w) - (PPW - ((x) & PIM))) >> PWSH); \ + else \ + nlw = (w) >> PWSH; + +#define maskpartialbits(x, w, mask) \ + mask = mfbGetpartmasks((x) & PIM, (w) & PIM); + +#define maskPPWbits(x, w, startmask, endmask) \ + startmask = mfbGetstarttab((x) & PIM); \ + endmask = mfbGetendtab(((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 \ + { \ + register int d = PPW-(x); \ + *(pdst) = (*(pdst) & mfbGetendtab(x)) | (SCRRIGHT((src), x)); \ + (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | \ + (SCRLEFT(src, d) & mfbGetendtab(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) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \ + t1 = SCRLEFT((src), m); \ + DoRop(t2, rop, t1, (pdst)[1]); \ + (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(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) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \ + t1 = SCRLEFT((src), m); \ + t2 = DoRRop(rop, t1, (pdst)[1]); \ + (pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(n)); \ + } \ +} +#endif + +#if GETLEFTBITS_ALIGNMENT == 1 +#define getleftbits(psrc, w, dst) dst = *((CARD32 *)(pointer) 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 32-bit 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) & mfbGetstarttab((width))) | (_src & mfbGetendtab((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) & mfbGetstarttab((width))) | (_src & mfbGetendtab((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) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \ +} + +#endif /* FASTGETBITS && FASTPUTBITS */ + +#endif /* MFB_CONSTS_ONLY */ |