105b261ecSmrg/*
205b261ecSmrg * Copyright © 1998 Keith Packard
305b261ecSmrg *
405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
605b261ecSmrg * the above copyright notice appear in all copies and that both that
705b261ecSmrg * copyright notice and this permission notice appear in supporting
805b261ecSmrg * documentation, and that the name of Keith Packard not be used in
905b261ecSmrg * advertising or publicity pertaining to distribution of the software without
1005b261ecSmrg * specific, written prior permission.  Keith Packard makes no
1105b261ecSmrg * representations about the suitability of this software for any purpose.  It
1205b261ecSmrg * is provided "as is" without express or implied warranty.
1305b261ecSmrg *
1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
2105b261ecSmrg */
2205b261ecSmrg
2305b261ecSmrg#ifndef _FBROP_H_
2405b261ecSmrg#define _FBROP_H_
2505b261ecSmrg
2605b261ecSmrgtypedef struct _mergeRopBits {
2735c4bbdfSmrg    FbBits ca1, cx1, ca2, cx2;
2805b261ecSmrg} FbMergeRopRec, *FbMergeRopPtr;
2905b261ecSmrg
3035c4bbdfSmrgextern _X_EXPORT const FbMergeRopRec FbMergeRopBits[16];
3105b261ecSmrg
3205b261ecSmrg#define FbDeclareMergeRop() FbBits   _ca1, _cx1, _ca2, _cx2;
3305b261ecSmrg#define FbDeclarePrebuiltMergeRop()	FbBits	_cca, _ccx;
3405b261ecSmrg
3505b261ecSmrg#define FbInitializeMergeRop(alu,pm) {\
3605b261ecSmrg    const FbMergeRopRec  *_bits; \
3705b261ecSmrg    _bits = &FbMergeRopBits[alu]; \
3805b261ecSmrg    _ca1 = _bits->ca1 &  pm; \
3905b261ecSmrg    _cx1 = _bits->cx1 | ~pm; \
4005b261ecSmrg    _ca2 = _bits->ca2 &  pm; \
4105b261ecSmrg    _cx2 = _bits->cx2 &  pm; \
4205b261ecSmrg}
4305b261ecSmrg
4405b261ecSmrg#define FbDestInvarientRop(alu,pm)  ((pm) == FB_ALLONES && \
4505b261ecSmrg				     (((alu) >> 1 & 5) == ((alu) & 5)))
4605b261ecSmrg
4705b261ecSmrg#define FbDestInvarientMergeRop()   (_ca1 == 0 && _cx1 == 0)
4805b261ecSmrg
4905b261ecSmrg/* AND has higher precedence than XOR */
5005b261ecSmrg
5105b261ecSmrg#define FbDoMergeRop(src, dst) \
5205b261ecSmrg    (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2))
5305b261ecSmrg
5405b261ecSmrg#define FbDoDestInvarientMergeRop(src)	(((src) & _ca2) ^ _cx2)
5505b261ecSmrg
5605b261ecSmrg#define FbDoMaskMergeRop(src, dst, mask) \
5705b261ecSmrg    (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask)))
5805b261ecSmrg
5905b261ecSmrg#define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \
6005b261ecSmrg    FbBits  __xor = ((src) & _ca2) ^ _cx2; \
6105b261ecSmrg    FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \
6205b261ecSmrg}
6305b261ecSmrg
6405b261ecSmrg#define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \
6505b261ecSmrg    FbBits  __xor = ((src) & _ca2) ^ _cx2; \
6605b261ecSmrg    FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \
6705b261ecSmrg}
6805b261ecSmrg
6905b261ecSmrg#define FbDoRRop(dst, and, xor)	(((dst) & (and)) ^ (xor))
7005b261ecSmrg
7105b261ecSmrg#define FbDoMaskRRop(dst, and, xor, mask) \
7205b261ecSmrg    (((dst) & ((and) | ~(mask))) ^ (xor & mask))
7305b261ecSmrg
7405b261ecSmrg/*
7505b261ecSmrg * Take a single bit (0 or 1) and generate a full mask
7605b261ecSmrg */
7705b261ecSmrg#define fbFillFromBit(b,t)	(~((t) ((b) & 1)-1))
7805b261ecSmrg
7905b261ecSmrg#define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \
8005b261ecSmrg			      (~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm))
8105b261ecSmrg
8205b261ecSmrg#define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \
8305b261ecSmrg			      (~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \
8405b261ecSmrg			     ~(pm))
8505b261ecSmrg
8605b261ecSmrg#define fbXor(rop,fg,pm)	fbXorT(rop,fg,pm,FbBits)
8705b261ecSmrg
8805b261ecSmrg#define fbAnd(rop,fg,pm)	fbAndT(rop,fg,pm,FbBits)
8905b261ecSmrg
9005b261ecSmrg#define fbXorStip(rop,fg,pm)    fbXorT(rop,fg,pm,FbStip)
9105b261ecSmrg
9205b261ecSmrg#define fbAndStip(rop,fg,pm)	fbAndT(rop,fg,pm,FbStip)
9305b261ecSmrg
9405b261ecSmrg/*
9535c4bbdfSmrg * Stippling operations;
9605b261ecSmrg */
9705b261ecSmrg
9805b261ecSmrg#define FbStippleRRop(dst, b, fa, fx, ba, bx) \
9905b261ecSmrg    (FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b)
10005b261ecSmrg
10105b261ecSmrg#define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \
10205b261ecSmrg    (FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b))
10335c4bbdfSmrg
10405b261ecSmrg#define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \
10505b261ecSmrg    FbBits  __xor = ((fx) & (b)) | ((bx) & ~(b)); \
10605b261ecSmrg    FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
10705b261ecSmrg}
10805b261ecSmrg
10905b261ecSmrg#define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \
11005b261ecSmrg    FbBits  __xor = ((fx) & (b)) | ((bx) & ~(b)); \
11105b261ecSmrg    FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
11205b261ecSmrg}
11305b261ecSmrg
11405b261ecSmrg#define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b)))
11535c4bbdfSmrg
11605b261ecSmrg/*
11705b261ecSmrg * Compute rop for using tile code for 1-bit dest stipples; modifies
11805b261ecSmrg * existing rop to flip depending on pixel values
11905b261ecSmrg */
12005b261ecSmrg#define FbStipple1RopPick(alu,b)    (((alu) >> (2 - (((b) & 1) << 1))) & 3)
12105b261ecSmrg
12205b261ecSmrg#define FbOpaqueStipple1Rop(alu,fg,bg)    (FbStipple1RopPick(alu,fg) | \
12305b261ecSmrg					   (FbStipple1RopPick(alu,bg) << 2))
12405b261ecSmrg
12505b261ecSmrg#define FbStipple1Rop(alu,fg)	    (FbStipple1RopPick(alu,fg) | 4)
12605b261ecSmrg
12705b261ecSmrg#endif
128