690 lines
21 KiB
C
690 lines
21 KiB
C
/* 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 */
|