DIRECTORY Basics, RasterBasics, RasterOp; RasterOpForwardImpl: PROGRAM IMPORTS Basics EXPORTS RasterOp ~ BEGIN OPEN Basics; bpw: CARDINAL ~ BITS[WORD]; BitOff: TYPE = [0..bpw); BitCount: TYPE = [0..bpw]; DstFunc: TYPE ~ RasterBasics.DstFunc; SrcFunc: TYPE ~ RasterBasics.SrcFunc; BitAddress: TYPE ~ RasterBasics.BitAddress; RawWords: TYPE ~ Basics.RawWords; RawWordsPtr: TYPE ~ LONG POINTER TO RawWords; WordPtr: TYPE = LONG POINTER TO WORD; WordsForBits: PROC [bits: CARDINAL] RETURNS [CARDINAL] ~ INLINE { RETURN [CARDINAL[bits+(bpw-1)]/bpw] }; WordFloorUnitsForBits: PROC [bits: CARDINAL] RETURNS [CARDINAL] ~ INLINE { RETURN [(CARDINAL[bits]/bpw)*CARDINAL[UNITS[WORD]]] }; CombineUnderMask: PROC [mask, onesSrc, zerosSrc: WORD] RETURNS [WORD] ~ INLINE { RETURN [BITXOR[BITAND[BITXOR[onesSrc, zerosSrc], mask], zerosSrc]] }; rightJustifiedOnes: ARRAY BitCount OF WORD ~ InitRightJustifiedOnes[]; InitRightJustifiedOnes: PROC RETURNS [a: ARRAY BitCount OF WORD] ~ { m: WORD ¬ 0; FOR n: CARDINAL IN BitCount DO a[n] ¬ m; m ¬ m+m+1; ENDLOOP; }; RightJustifiedZeros: PROC [n: BitCount] RETURNS [WORD] ~ INLINE { RETURN [BITNOT[rightJustifiedOnes[n]]] }; FOR f: NAT IN [0..8) DO unroll: INT ~ 4; SrcFunc: PROC [s: ROPE] ~ {IF f MOD 2 = 1 THEN {BITNOT[%s]} ELSE {%s}}; F: PROC[d, s: ROPE] ~ { SELECT f FROM 0 => {%s}; 1 => {BITNOT[%s]}; 2 => {BITAND[%d, %s]}; 3 => {BITAND[%d, BITNOT[%s]]}; 4 => {BITOR[%d, %s]}; 5 => {BITOR[%d, BITNOT[%s]]}; 6 => {BITXOR[%d, %s]}; 7 => {BITXOR[%d, BITNOT[%s]]}; ENDCASE => ERROR; };  Forward&f: PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ~ { MF: PROC [d, s, mask: WORD] RETURNS [WORD] ~ INLINE { RETURN [ IF f/2 = 2 THEN { BITOR[d, BITAND[mask, ?SrcFunc[s]]] } ELSE { BITXOR[BITAND[BITXOR[?F[d, s], d], mask], d] }; ] }; DoUniformLines: PROC [count: CARDINAL, dstPtr: WordPtr, dstBit: BitOff, srcPtr: WordPtr, srcBit: BitOff] ~ { dRast: CARD ~ WordFloorUnitsForBits[dstBpl]; sRast: CARD ~ WordFloorUnitsForBits[srcBpl]; ndw: CARDINAL ~ WordsForBits[dstBit + fSize]; lMask: WORD ~ rightJustifiedOnes[bpw-dstBit]; rMask: WORD ~ RightJustifiedZeros[ (LOOPHOLE[bpw-dstBit-fSize, CARDINAL]) MOD bpw]; lSA: BitOff ~ (LOOPHOLE[srcBit-dstBit, CARDINAL]) MOD bpw; -- left shift amount w: WORD ¬ 0; -- source word, aligned with destination dstLine: RawWordsPtr ¬ NIL; -- destination line word address srcLine: RawWordsPtr ¬ NIL; -- source line word address FOR alignment: NAT IN [0..1] DO  Inner&alignment: PROC = INLINE { IF alignment # 0 THEN { hi: WORD; -- left unshifted source word lo: WORD ¬ 0; -- right unshifted source word rSA: BitOff = bpw - lSA; nsw: CARDINAL = WordsForBits[srcBit + fSize]; fetchLastWord: BOOL = IF srcBit >= dstBit THEN (nsw>ndw) ELSE (nsw>=ndw); FetchNext: PROC ~ INLINE { hi ¬ lo; lo ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { hi ¬ lo; lo ¬ srcLine[wordOffset]; w ¬ BITLSHIFT[hi, lSA]+BITRSHIFT[lo, rSA] }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ BITLSHIFT[lo, lSA]; IF fetch THEN w ¬ w + BITRSHIFT[srcLine[wordOffset], rSA]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; IF srcBit >= dstBit THEN FetchNext[]; }; } ELSE { fetchLastWord: BOOL ~ TRUE; FetchNext: PROC ~ INLINE { w ¬ srcLine[0]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchNextOff: PROC [wordOffset: CARDINAL] ~ INLINE { w ¬ srcLine[wordOffset]; }; FetchLast: PROC [wordOffset: CARDINAL, fetch: BOOL] ~ INLINE { w ¬ srcLine[wordOffset]; }; BBLineSetup: PROC ~ INLINE { dstLine ¬ LOOPHOLE[dstPtr]; srcLine ¬ LOOPHOLE[srcPtr]; }; }; SELECT ndw FROM 1 => { bothMask: WORD ~ BITAND[lMask, rMask]; IF fetchLastWord THEN DO BBLineSetup[]; FetchLast[0, TRUE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP ELSE DO BBLineSetup[]; FetchLast[0, FALSE]; dstLine[0] ¬ MF[dstLine[0], w, bothMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP }; FOR u: INT IN [2..unroll] DO um: INT = u-1;  &u => { DO BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; FOR j: INT IN [1..um) DO  FetchNextOff[&j]; dstLine[&j] ¬ ?F[dstLine[&j], w]; ENDLOOP; FetchLast[&um, fetchLastWord]; dstLine[&um] ¬ MF[dstLine[&um], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; ENDLOOP; ENDCASE => { checkUnroll: [2..256] = &unroll; DO nw: CARDINAL ¬ LOOPHOLE[ndw-2, CARDINAL]; BBLineSetup[]; FetchNextOff[0]; dstLine[0] ¬ MF[dstLine[0], w, lMask]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; WHILE nw >= 4 DO FetchNextOff[0]; dstLine[0] ¬ ?F[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ ?F[dstLine[1], w]; FetchNextOff[2]; dstLine[2] ¬ ?F[dstLine[2], w]; FetchNextOff[3]; dstLine[3] ¬ ?F[dstLine[3], w]; dstLine ¬ dstLine+SIZE[WORD]*4; srcLine ¬ srcLine+SIZE[WORD]*4; nw ¬ nw - 4; ENDLOOP; IF nw >= 2 THEN { FetchNextOff[0]; dstLine[0] ¬ ?F[dstLine[0], w]; FetchNextOff[1]; dstLine[1] ¬ ?F[dstLine[1], w]; dstLine ¬ dstLine+SIZE[WORD]*2; srcLine ¬ srcLine+SIZE[WORD]*2; nw ¬ nw - 2; }; IF nw = 1 THEN { FetchNextOff[0]; dstLine[0] ¬ ?F[dstLine[0], w]; dstLine ¬ dstLine+SIZE[WORD]; srcLine ¬ srcLine+SIZE[WORD]; }; FetchLast[0, fetchLastWord]; dstLine[0] ¬ MF[dstLine[0], w, rMask]; IF count <= 1 THEN EXIT; count ¬ count - 1; dstPtr ¬ dstPtr + dRast; srcPtr ¬ srcPtr + sRast; ENDLOOP; }; }; ENDLOOP; IF lSA = 0 THEN { Inner0[] } ELSE { Inner1[] }; }; IF BITOR[sSize, fSize] # 0 THEN { IF dstBpl MOD bpw = 0 AND srcBpl MOD bpw = 0 THEN { DoUniformLines[sSize, dst.word, dst.bit, src.word, src.bit]; } ELSE { DO DoUniformLines[1, dst.word, dst.bit, src.word, src.bit]; IF (sSize ¬ sSize - 1) = 0 THEN EXIT; dst.word ¬ dst.word + WordFloorUnitsForBits[(dst.bit+dstBpl)]; dst.bit ¬ CARDINAL[(dst.bit+dstBpl)] MOD bpw; src.word ¬ src.word + WordFloorUnitsForBits[(src.bit+srcBpl)]; src.bit ¬ CARDINAL[(src.bit+srcBpl)] MOD bpw; ENDLOOP; }; }; }; ENDLOOP; forwardOp: PUBLIC ARRAY DstFunc OF ARRAY SrcFunc OF PROC [dst: BitAddress, src: BitAddress, dstBpl, srcBpl, sSize, fSize: CARDINAL] ¬ [[Forward0, Forward1], [Forward2, Forward3], [Forward4, Forward5], [Forward6, Forward7]]; END. : RasterOpForwardImpl.meta Copyright Σ 1988, 1989, 1990, 1991 by Xerox Corporation. All rights reserved. Michael Plass, October 1, 1991 4:37 pm PDT Russ Atkinson (RRA) March 1, 1990 4:03:19 pm PST Willie-s, June 13, 1991 4:28 pm PDT Procs number of destination words per (this) line mask for the leftmost dest word (ones where bits are to go) mask for the rightmost dest word amount to shift source words right to line them up true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the next word at the given offset, no pointer change -- fetches the final source bits on a line, avoiding a spurious fetch -- Aligned case is simpler true if last source word needs to be fetched fetches the next aligned source bits, and bumps source pointer fetches the word at the given offset, no pointer change -- fetches the final source bits on a line, avoiding a spurious fetch Special encoding of one destination word case for speed One trailing word -- don't need to do whole setup for each line -- need setup for every line Κ Λ–(cedarcode) style•NewlineDelimiter ™code™Kšœ ΟeœC™NKšœ*™*K™0K™#K˜KšΟk œ ˜)K˜—šΠlnœž˜Kšžœ˜Kšžœ ˜Kšœžœžœ˜K˜šœžœžœžœ˜Kšœžœ ˜Kšœ žœ ˜K˜—Kšœ žœ˜%Kšœ žœ˜%Kšœ žœ˜+Kšœ žœ˜!Kš œ žœžœžœžœ ˜-Kš œ žœžœžœžœžœ˜%—head™š Οn œžœžœžœžœžœ˜AKšžœžœ˜#Kšœ˜K˜—š  œžœžœžœžœžœ˜JKš žœžœ žœžœžœ˜3Kšœ˜K˜—š  œžœžœžœžœžœ˜PKšžœžœžœžœ&˜BKšœ˜K˜—Kšœžœ žœžœ˜Fš  œžœžœžœ žœžœ˜DKšœžœ˜ šžœžœžœ ž˜Kšœ ˜ K˜ Kšžœ˜—Kšœ˜K˜—š  œžœžœžœžœ˜AKšžœžœ˜&Kšœ˜K˜—šΠtzΠkzΟz’£’£’˜Kš‘’‘£‘˜KšΠnz£’£’£’£’£’£žœ£’£œ£˜Kš€£’£’£˜š’£’˜ Kš£œ£˜ Kš£žœ£˜Kš£žœ£˜Kš£žœžœ£˜ Kš£žœ£˜Kš£žœžœ£˜Kš£žœ£˜Kš£žœžœ£˜ Kš’£’£˜—Kš£‘˜—š  œžœBžœ˜^š žœžœžœžœžœžœ˜5šžœ˜š‘’£‘˜ š’£‘˜Kšžœžœ˜#Kš‘£˜—š’£‘˜Kšžœžœžœ˜,Kš‘˜——Kšœ˜—Kšœ˜—š œžœžœG˜lKšœžœ!˜,Kšœžœ!˜,šœžœ ˜-Kšœ+™+—šœžœ"˜-Kšœ;™;—š œžœžœžœžœ˜SKšœ ™ —KšœžœžœžœΟc˜PKšœžœ₯(˜5Kšœžœ₯ ˜Kšœ˜Kšœ˜Kšœžœžœ˜Kšœž œ ž œ ˜)Kšœ˜—š  œžœžœžœ˜4K™Idefault™EKšœž œ ˜Kšžœžœ ž œ˜:Kšœ˜—š  œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšžœžœ ˜%Kšœ˜—Kš‘£˜—š’£‘˜Kšœ™šœžœžœ˜Kšœ,™,—š  œžœžœ˜K™>Kšœ˜Kšœžœžœ˜Kšœ˜—š  œžœžœžœ˜4K™7Kšœ˜Kšœ˜—š   œžœžœ žœžœ˜>M™EKšœ˜Kšœ˜—š  œžœžœ˜Kšœ žœ ˜Kšœ žœ ˜Kšœ˜—Kš‘£‘˜——šžœž˜˜K™7Kšœ žœžœ˜&šžœ˜šž˜šž˜Kšœ˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜Kšœ˜K˜K˜Kšž˜——šž˜šž˜Kšœ˜Kšœ žœ˜Kšœ žœ˜)Kšžœ žœžœ˜Kšœ˜K˜K˜Kšž˜———K˜—š ‘’£’£’£ ’£‘’‘ ˜.˜šž˜Kšœ˜Kšœ˜Kšœ žœ˜&š ‘’£’£’£ ’£‘˜Kšœ˜Kšœ!˜!Kš‘’£‘˜ —Kšœ˜Kšœžœ˜*Kšžœ žœžœ˜Kšœ˜K˜K˜Kšžœ˜—K˜—Kš‘’£‘˜ —šžœ˜ K˜ šž˜Kšœžœžœžœ˜)Kšœ˜Kšœ˜Kšœ žœ˜&Kšœžœžœ˜Kšœžœžœ˜šžœ ž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœ ˜ Kšžœ˜—šžœ žœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœ ˜ Kšœ˜—šžœžœ˜K™Kšœ˜Kšœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœ˜—Kšœ˜Kšœ žœ˜&Kšžœ žœžœ˜Kšœ˜K˜K˜Kšžœ˜—Kšœ˜——Kšœ˜—Kš‘’£˜ —Kšžœ žœžœ˜/Kšœ˜—šžœžœžœ˜!šžœžœ žœžœ˜,šžœ˜Kš₯-™-Kšœ<˜˜>Kšœ žœžœ˜-Kšœ>˜>Kšœ žœžœ˜-Kšžœ˜—Kšœ˜——Kšœ˜—Kšœ˜—Kš‘’£‘˜ K˜—š œ ž œ žœžœ žœžœBžœ]˜ίK˜——Kšžœ˜K˜K˜—…—π(υ