1
/* Combined Purdue/PurduePlus patches, level 2.1, 1/24/89 */
2
/***********************************************************
3
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
7
Permission to use, copy, modify, and distribute this software and its
8
documentation for any purpose and without fee is hereby granted,
9
provided that the above copyright notice appear in all copies and that
10
both that copyright notice and this permission notice appear in
11
supporting documentation, and that the name of Digital not be
12
used in advertising or publicity pertaining to distribution of the
13
software without specific, written prior permission.
15
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23
******************************************************************/
25
#ifdef HAVE_DIX_CONFIG_H
26
#include <dix-config.h>
34
/* the following notes use the following conventions:
35
SCREEN LEFT SCREEN RIGHT
36
in this file and maskbits.c, left and right refer to screen coordinates,
37
NOT bit numbering in registers.
40
bits[0,n-1] = 0 bits[n,PLST] = 1
42
bits[0,n-1] = 1 bits[n,PLST] = 0
44
startpartial[], endpartial[]
45
these are used as accelerators for doing putbits and masking out
46
bits that are all contained between longword boudaries. the extra
47
256 bytes of data seems a small price to pay -- code is smaller,
48
and narrow things (e.g. window borders) go faster.
50
the names may seem misleading; they are derived not from which end
51
of the word the bits are turned on, but at which end of a scanline
52
the table tends to be used.
54
look at the tables and macros to understand boundary conditions.
55
(careful readers will note that starttab[n] = ~endtab[n] for n != 0)
57
-----------------------------------------------------------------------
58
these two macros depend on the screen's bit ordering.
59
in both of them x is a screen position. they are used to
60
combine bits collected from multiple longwords into a
61
single destination longword, and to unpack a single
62
source longword into multiple destinations.
65
takes dst[x, PPW] and moves them to dst[0, PPW-x]
66
the contents of the rest of dst are 0.
67
this is a right shift on LSBFirst (forward-thinking)
68
machines like the VAX, and left shift on MSBFirst
69
(backwards) machines like the 680x0 and pc/rt.
72
takes dst[0,x] and moves them to dst[PPW-x, PPW]
73
the contents of the rest of dst are 0.
74
this is a left shift on LSBFirst, right shift
78
the remaining macros are cpu-independent; all bit order dependencies
79
are built into the tables and the two macros above.
81
maskbits(x, w, startmask, endmask, nlw)
82
for a span of width w starting at position x, returns
83
a mask for ragged bits at start, mask for ragged bits at end,
84
and the number of whole longwords between the ends.
86
maskpartialbits(x, w, mask)
87
works like maskbits(), except all the bits are in the
88
same longword (i.e. (x&PIM + w) <= PPW)
90
maskPPWbits(x, w, startmask, endmask, nlw)
91
as maskbits, but does not calculate nlw. it is used by
92
mfbGlyphBlt to put down glyphs <= PPW bits wide.
94
-------------------------------------------------------------------
97
any pointers passed to the following 4 macros are
98
guranteed to be PPW-bit aligned.
99
The only non-PPW-bit-aligned references ever made are
100
to font glyphs, and those are made with getleftbits()
101
and getshiftedleftbits (qq.v.)
103
For 64-bit server, it is assumed that we will never have font padding
104
of more than 4 bytes. The code uses int's to access the fonts
107
getbits(psrc, x, w, dst)
108
starting at position x in psrc (x < PPW), collect w
109
bits and put them in the screen left portion of dst.
110
psrc is a longword pointer. this may span longword boundaries.
111
it special-cases fetching all w bits from one longword.
113
+--------+--------+ +--------+
114
| | m |n| | ==> | m |n| |
115
+--------+--------+ +--------+
122
get m bits, move to screen-left of dst, zeroing rest of dst;
123
get n bits from next word, move screen-right by m, zeroing
124
lower m bits of word.
125
OR the two things together.
127
putbits(src, x, w, pdst)
128
starting at position x in pdst, put down the screen-leftmost
129
w bits of src. pdst is a longword pointer. this may
130
span longword boundaries.
131
it special-cases putting all w bits into the same longword.
133
+--------+ +--------+--------+
134
| m |n| | ==> | | m |n| |
135
+--------+ +--------+--------+
142
get m bits, shift screen-right by x, zero screen-leftmost x
143
bits; zero rightmost m bits of *pdst and OR in stuff
144
from before the semicolon.
145
shift src screen-left by m, zero bits n-PPW;
146
zero leftmost n bits of *(pdst+1) and OR in the
147
stuff from before the semicolon.
149
putbitsrop(src, x, w, pdst, ROP)
150
like putbits but calls DoRop with the rasterop ROP (see mfb.h for
153
putbitsrrop(src, x, w, pdst, ROP)
154
like putbits but calls DoRRop with the reduced rasterop ROP
155
(see mfb.h for DoRRop)
157
-----------------------------------------------------------------------
158
The two macros below are used only for getting bits from glyphs
159
in fonts, and glyphs in fonts are gotten only with the following two
161
You should tune these macros toyour font format and cpu
165
getleftbits(psrc, w, dst)
166
get the leftmost w (w<=32) bits from *psrc and put them
167
in dst. this is used by the mfbGlyphBlt code for glyphs
169
psrc is declared (unsigned char *)
171
psrc is NOT guaranteed to be PPW-bit aligned. on many
172
machines this will cause problems, so there are several
173
versions of this macro.
175
this macro is called ONLY for getting bits from font glyphs,
176
and depends on the server-natural font padding.
178
for blazing text performance, you want this macro
179
to touch memory as infrequently as possible (e.g.
180
fetch longwords) and as efficiently as possible
181
(e.g. don't fetch misaligned longwords)
183
getshiftedleftbits(psrc, offset, w, dst)
184
used by the font code; like getleftbits, but shifts the
185
bits SCRLEFT by offset.
186
this is implemented portably, calling getleftbits()
188
psrc is declared (unsigned char *).
191
/* to match CFB and allow algorithm sharing ...
192
* name mfb32 mfb64 explanation
193
* ---- ------ ----- -----------
194
* PGSZ 32 64 pixel group size (in bits; same as PPW for mfb)
195
* PGSZB 4 8 pixel group size (in bytes)
196
* PPW 32 64 pixels per word (pixels per pixel group)
197
* PLST 31 63 index of last pixel in a word (should be PPW-1)
198
* PIM 0x1f 0x3f pixel index mask (index within a pixel group)
199
* PWSH 5 6 pixel-to-word shift (should be log2(PPW))
201
* The MFB_ versions are here so that cfb can include maskbits.h to get
202
* the bitmap constants without conflicting with its own P* constants.
204
* Keith Packard (keithp@suse.com):
205
* Note mfb64 is no longer supported; it requires DIX support
206
* for realigning images which costs too much
209
/* warning: PixelType definition duplicated in mfb.h */
211
#define PixelType CARD32
212
#endif /* PixelType */
214
#define MfbBits CARD32
218
#define MFB_PPW (MFB_PGSZB<<3) /* assuming 8 bits per byte */
219
#define MFB_PGSZ MFB_PPW
220
#define MFB_PLST (MFB_PPW-1)
221
#define MFB_PIM MFB_PLST
223
/* set PWSH = log2(PPW) using brute force */
227
#endif /* MFB_PPW == 32 */
229
/* XXX don't use these five */
230
extern PixelType starttab[];
231
extern PixelType endtab[];
232
extern PixelType partmasks[MFB_PPW][MFB_PPW];
233
extern PixelType rmask[];
234
extern PixelType mask[];
235
/* XXX use these five */
236
extern PixelType mfbGetstarttab(int);
237
extern PixelType mfbGetendtab(int);
238
extern PixelType mfbGetpartmasks(int, int);
239
extern PixelType mfbGetrmask(int);
240
extern PixelType mfbGetmask(int);
242
#ifndef MFB_CONSTS_ONLY
244
#define PGSZB MFB_PGSZB
246
#define PGSZ MFB_PGSZ
247
#define PLST MFB_PLST
249
#define PWSH MFB_PWSH
251
#define BitLeft(b,s) SCRLEFT(b,s)
252
#define BitRight(b,s) SCRRIGHT(b,s)
255
#define LONG2CHARSSAMEORDER(x) ((MfbBits)(x))
256
#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \
257
| ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \
258
| ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \
259
| ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) )
260
#endif /* XFree86Server */
262
#if (BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER)
263
#define LONG2CHARS(x) ((MfbBits)(x))
266
* the unsigned case below is for compilers like
267
* the Danbury C and i386cc
269
#define LONG2CHARS( x ) ( ( ( ( x ) & (MfbBits)0x000000FF ) << 0x18 ) \
270
| ( ( ( x ) & (MfbBits)0x0000FF00 ) << 0x08 ) \
271
| ( ( ( x ) & (MfbBits)0x00FF0000 ) >> 0x08 ) \
272
| ( ( ( x ) & (MfbBits)0xFF000000 ) >> 0x18 ) )
273
#endif /* BITMAP_BIT_ORDER */
275
#ifdef STRICT_ANSI_SHIFT
276
#define SHL(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) << (y)))
277
#define SHR(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) >> (y)))
279
#define SHL(x,y) LONG2CHARS(LONG2CHARS(x) << (y))
280
#define SHR(x,y) LONG2CHARS(LONG2CHARS(x) >> (y))
283
#if (BITMAP_BIT_ORDER == MSBFirst) /* pc/rt, 680x0 */
284
#define SCRLEFT(lw, n) SHL((PixelType)(lw),(n))
285
#define SCRRIGHT(lw, n) SHR((PixelType)(lw),(n))
286
#else /* vax, intel */
287
#define SCRLEFT(lw, n) SHR((PixelType)(lw),(n))
288
#define SCRRIGHT(lw, n) SHL((PixelType)(lw),(n))
291
#define DoRRop(alu, src, dst) \
292
(((alu) == RROP_BLACK) ? ((dst) & ~(src)) : \
293
((alu) == RROP_WHITE) ? ((dst) | (src)) : \
294
((alu) == RROP_INVERT) ? ((dst) ^ (src)) : \
297
/* A generalized form of a x4 Duff's Device */
298
#define Duff(counter, block) { \
299
while (counter >= 4) {\
306
switch (counter & 3) { \
315
#define maskbits(x, w, startmask, endmask, nlw) \
316
startmask = mfbGetstarttab((x) & PIM); \
317
endmask = mfbGetendtab(((x)+(w)) & PIM); \
319
nlw = (((w) - (PPW - ((x) & PIM))) >> PWSH); \
323
#define maskpartialbits(x, w, mask) \
324
mask = mfbGetpartmasks((x) & PIM, (w) & PIM);
326
#define maskPPWbits(x, w, startmask, endmask) \
327
startmask = mfbGetstarttab((x) & PIM); \
328
endmask = mfbGetendtab(((x)+(w)) & PIM);
330
#ifdef __GNUC__ /* XXX don't want for Alpha? */
332
#define FASTGETBITS(psrc,x,w,dst) \
333
__asm ("extzv %1,%2,%3,%0" \
335
: "g" (x), "g" (w), "m" (*(char *)(psrc)))
336
#define getbits(psrc,x,w,dst) FASTGETBITS(psrc,x,w,dst)
338
#define FASTPUTBITS(src, x, w, pdst) \
339
__asm ("insv %3,%1,%2,%0" \
340
: "=m" (*(char *)(pdst)) \
341
: "g" (x), "g" (w), "g" (src))
342
#define putbits(src, x, w, pdst) FASTPUTBITS(src, x, w, pdst)
345
#define FASTGETBITS(psrc, x, w, dst) \
346
__asm ("bfextu %3{%1:%2},%0" \
347
: "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
349
#define getbits(psrc,x,w,dst) \
351
FASTGETBITS(psrc, x, w, dst);\
352
dst = SHL(dst,(32-(w))); \
355
#define FASTPUTBITS(src, x, w, pdst) \
356
__asm ("bfins %3,%0{%1:%2}" \
357
: "=o" (*(char *)(pdst)) \
358
: "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
360
#define putbits(src, x, w, pdst) FASTPUTBITS(SHR((src),32-(w)), x, w, pdst)
363
#endif /* __GNUC__ */
365
/* The following flag is used to override a bugfix for sun 3/60+CG4 machines,
368
/* We don't need to be careful about this unless we're dealing with sun3's
369
* We will default its usage for those who do not know anything, but will
370
* override its effect if the machine doesn't look like a sun3
372
#if !defined(mc68020) || !defined(sun)
376
/* This is gross. We want to #define u_putbits as something which can be used
377
* in the case of the 3/60+CG4, but if we use /bin/cc or are on another
378
* machine type, we want nothing to do with u_putbits. What a hastle. Here
379
* I used slo_putbits as something which either u_putbits or putbits could be
382
* putbits gets it iff it is not already defined with FASTPUTBITS above.
383
* u_putbits gets it if we have FASTPUTBITS (putbits) from above and have not
384
* overridden the NO_3_60_CG4 flag.
387
#define slo_putbits(src, x, w, pdst) \
389
register int n = (x)+(w)-PPW; \
393
register PixelType tmpmask; \
394
maskpartialbits((x), (w), tmpmask); \
395
*(pdst) = (*(pdst) & ~tmpmask) | \
396
(SCRRIGHT(src, x) & tmpmask); \
400
register int d = PPW-(x); \
401
*(pdst) = (*(pdst) & mfbGetendtab(x)) | (SCRRIGHT((src), x)); \
402
(pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | \
403
(SCRLEFT(src, d) & mfbGetendtab(n)); \
407
#if defined(putbits) && !defined(NO_3_60_CG4)
408
#define u_putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
410
#define u_putbits(src, x, w, pdst) putbits(src, x, w, pdst)
413
#if !defined(putbits)
414
#define putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
417
/* Now if we have not gotten any really good bitfield macros, try some
418
* moderately fast macros. Alas, I don't know how to do asm instructions
423
#define getbits(psrc, x, w, dst) \
425
dst = SCRLEFT(*(psrc), (x)); \
426
if ( ((x) + (w)) > PPW) \
427
dst |= (SCRRIGHT(*((psrc)+1), PPW-(x))); \
431
/* We have to special-case putbitsrop because of 3/60+CG4 combos
434
#define u_putbitsrop(src, x, w, pdst, rop) \
436
register PixelType t1, t2; \
437
register int n = (x)+(w)-PPW; \
439
t1 = SCRRIGHT((src), (x)); \
440
DoRop(t2, rop, t1, *(pdst)); \
444
register PixelType tmpmask; \
446
maskpartialbits((x), (w), tmpmask); \
447
*(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
452
*(pdst) = (*(pdst) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \
453
t1 = SCRLEFT((src), m); \
454
DoRop(t2, rop, t1, (pdst)[1]); \
455
(pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(n)); \
459
/* If our getbits and putbits are FAST enough,
460
* do this brute force, it's faster
463
#if defined(FASTPUTBITS) && defined(FASTGETBITS) && defined(NO_3_60_CG4)
464
#if (BITMAP_BIT_ORDER == MSBFirst)
465
#define putbitsrop(src, x, w, pdst, rop) \
467
register PixelType _tmp, _tmp2; \
468
FASTGETBITS(pdst, x, w, _tmp); \
469
_tmp2 = SCRRIGHT(src, PPW-(w)); \
470
DoRop(_tmp, rop, _tmp2, _tmp) \
471
FASTPUTBITS(_tmp, x, w, pdst); \
473
#define putbitsrrop(src, x, w, pdst, rop) \
475
register PixelType _tmp, _tmp2; \
477
FASTGETBITS(pdst, x, w, _tmp); \
478
_tmp2 = SCRRIGHT(src, PPW-(w)); \
479
_tmp= DoRRop(rop, _tmp2, _tmp); \
480
FASTPUTBITS(_tmp, x, w, pdst); \
484
#define putbitsrop(src, x, w, pdst, rop) \
486
register PixelType _tmp; \
487
FASTGETBITS(pdst, x, w, _tmp); \
488
DoRop(_tmp, rop, src, _tmp) \
489
FASTPUTBITS(_tmp, x, w, pdst); \
491
#define putbitsrrop(src, x, w, pdst, rop) \
493
register PixelType _tmp; \
495
FASTGETBITS(pdst, x, w, _tmp); \
496
_tmp= DoRRop(rop, src, _tmp); \
497
FASTPUTBITS(_tmp, x, w, pdst); \
504
#define putbitsrop(src, x, w, pdst, rop) u_putbitsrop(src, x, w, pdst, rop)
508
#define putbitsrrop(src, x, w, pdst, rop) \
510
register PixelType t1, t2; \
511
register int n = (x)+(w)-PPW; \
513
t1 = SCRRIGHT((src), (x)); \
514
t2 = DoRRop(rop, t1, *(pdst)); \
518
register PixelType tmpmask; \
520
maskpartialbits((x), (w), tmpmask); \
521
*(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
526
*(pdst) = (*(pdst) & mfbGetendtab(x)) | (t2 & mfbGetstarttab(x)); \
527
t1 = SCRLEFT((src), m); \
528
t2 = DoRRop(rop, t1, (pdst)[1]); \
529
(pdst)[1] = ((pdst)[1] & mfbGetstarttab(n)) | (t2 & mfbGetendtab(n)); \
534
#if GETLEFTBITS_ALIGNMENT == 1
535
#define getleftbits(psrc, w, dst) dst = *((CARD32 *)(pointer) psrc)
536
#endif /* GETLEFTBITS_ALIGNMENT == 1 */
538
#if GETLEFTBITS_ALIGNMENT == 2
539
#define getleftbits(psrc, w, dst) \
541
if ( ((int)(psrc)) & 0x01 ) \
542
getbits( ((CARD32 *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
544
getbits(psrc, 0, w, dst); \
546
#endif /* GETLEFTBITS_ALIGNMENT == 2 */
548
#if GETLEFTBITS_ALIGNMENT == 4
549
#define getleftbits(psrc, w, dst) \
552
off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
554
(CARD32 *)( ((char *)(psrc)) - off), \
555
(off_b), (w), (dst) \
558
#endif /* GETLEFTBITS_ALIGNMENT == 4 */
561
#define getshiftedleftbits(psrc, offset, w, dst) \
562
getleftbits((psrc), (w), (dst)); \
563
dst = SCRLEFT((dst), (offset));
565
/* FASTGETBITS and FASTPUTBITS are not necessarily correct implementations of
566
* getbits and putbits, but they work if used together.
568
* On a MSBFirst machine, a cpu bitfield extract instruction (like bfextu)
569
* could normally assign its result to a 32-bit word register in the screen
570
* right position. This saves canceling register shifts by not fighting the
571
* natural cpu byte order.
573
* Unfortunately, these fail on a 3/60+CG4 and cannot be used unmodified. Sigh.
575
#if defined(FASTGETBITS) && defined(FASTPUTBITS)
577
#define u_FASTPUT(aa, bb, cc, dd) FASTPUTBITS(aa, bb, cc, dd)
579
#define u_FASTPUT(aa, bb, cc, dd) u_putbits(SCRLEFT(aa, PPW-(cc)), bb, cc, dd)
582
#define getandputbits(psrc, srcbit, dstbit, width, pdst) \
584
register PixelType _tmpbits; \
585
FASTGETBITS(psrc, srcbit, width, _tmpbits); \
586
u_FASTPUT(_tmpbits, dstbit, width, pdst); \
589
#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
591
register PixelType _tmpsrc, _tmpdst; \
592
FASTGETBITS(pdst, dstbit, width, _tmpdst); \
593
FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
594
DoRop(_tmpdst, rop, _tmpsrc, _tmpdst); \
595
u_FASTPUT(_tmpdst, dstbit, width, pdst); \
598
#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
600
register PixelType _tmpsrc, _tmpdst; \
601
FASTGETBITS(pdst, dstbit, width, _tmpdst); \
602
FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
603
_tmpdst = DoRRop(rop, _tmpsrc, _tmpdst); \
604
u_FASTPUT(_tmpdst, dstbit, width, pdst); \
607
#define getandputbits0(psrc, srcbit, width, pdst) \
608
getandputbits(psrc, srcbit, 0, width, pdst)
610
#define getandputrop0(psrc, srcbit, width, pdst, rop) \
611
getandputrop(psrc, srcbit, 0, width, pdst, rop)
613
#define getandputrrop0(psrc, srcbit, width, pdst, rop) \
614
getandputrrop(psrc, srcbit, 0, width, pdst, rop)
617
#else /* Slow poke */
619
/* pairs of getbits/putbits happen frequently. Some of the code can
620
* be shared or avoided in a few specific instances. It gets us a
621
* small advantage, so we do it. The getandput...0 macros are the only ones
622
* which speed things here. The others are here for compatibility w/the above
626
#define getandputbits(psrc, srcbit, dstbit, width, pdst) \
628
register PixelType _tmpbits; \
629
getbits(psrc, srcbit, width, _tmpbits); \
630
putbits(_tmpbits, dstbit, width, pdst); \
633
#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
635
register PixelType _tmpbits; \
636
getbits(psrc, srcbit, width, _tmpbits) \
637
putbitsrop(_tmpbits, dstbit, width, pdst, rop) \
640
#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
642
register PixelType _tmpbits; \
643
getbits(psrc, srcbit, width, _tmpbits) \
644
putbitsrrop(_tmpbits, dstbit, width, pdst, rop) \
648
#define getandputbits0(psrc, sbindex, width, pdst) \
649
{ /* unroll the whole damn thing to see how it * behaves */ \
650
register int _flag = PPW - (sbindex); \
651
register PixelType _src; \
653
_src = SCRLEFT (*(psrc), (sbindex)); \
654
if ((width) > _flag) \
655
_src |= SCRRIGHT (*((psrc) + 1), _flag); \
657
*(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
661
#define getandputrop0(psrc, sbindex, width, pdst, rop) \
663
register int _flag = PPW - (sbindex); \
664
register PixelType _src; \
666
_src = SCRLEFT (*(psrc), (sbindex)); \
667
if ((width) > _flag) \
668
_src |= SCRRIGHT (*((psrc) + 1), _flag); \
669
DoRop(_src, rop, _src, *(pdst)); \
671
*(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
674
#define getandputrrop0(psrc, sbindex, width, pdst, rop) \
676
int _flag = PPW - (sbindex); \
677
register PixelType _src; \
679
_src = SCRLEFT (*(psrc), (sbindex)); \
680
if ((width) > _flag) \
681
_src |= SCRRIGHT (*((psrc) + 1), _flag); \
682
_src = DoRRop(rop, _src, *(pdst)); \
684
*(pdst) = (*(pdst) & mfbGetstarttab((width))) | (_src & mfbGetendtab((width))); \
687
#endif /* FASTGETBITS && FASTPUTBITS */
689
#endif /* MFB_CONSTS_ONLY */