maskRectangle: CommandBuffer.maskRectangle => {
TransferRectangle[[maskRectangle.sMin, maskRectangle.fMin, maskRectangle.sSize, maskRectangle.fSize]];
IF leftovers AND maskRectangle.sMin+maskRectangle.sSize>bandMaxS THEN AddLeftover[];
};
maskTrapezoid: CommandBuffer.maskTrapezoid => {
EdgeBlock: TYPE = RECORD [fPos, fIncr: Basics.LongNumber];
MakeEdge:
PROC[fMinLast, fMin, sSize:
CARDINAL]
RETURNS [edge: EdgeBlock] = {
edge.fPos.highbits ← fMin;
edge.fPos.lowbits ← 0;
edge.fIncr.highbits ← fMinLast - fMin;
edge.fIncr.lowbits ← 0;
IF sSize > 1 THEN edge.fIncr.li ← edge.fIncr.li/sSize;
};
fMinBox: CARDINAL←MIN[maskTrapezoid.fMin, maskTrapezoid.fMinLast];
fMaxBox: CARDINAL←MAX[maskTrapezoid.fMin+maskTrapezoid.fSize, maskTrapezoid.fMinLast+maskTrapezoid.fSizeLast];
fSizeBox: CARDINAL𡤏MaxBox-fMinBox;
trapMaxS: CARDINAL ← maskTrapezoid.sMin+maskTrapezoid.sSize;
s: CARDINAL ← maskTrapezoid.sMin;
sMinBand: CARDINAL ← MIN[band.sOrigin+band.sMin, maskTrapezoid.sMin+maskTrapezoid.sSize];
sMaxBand: CARDINAL ← MIN[bandMaxS, trapMaxS];
calculate initial edges:
minEdge: EdgeBlock ← MakeEdge[fMinLast: maskTrapezoid.fMinLast, fMin: maskTrapezoid.fMin, sSize: maskTrapezoid.sSize];
maxEdge: EdgeBlock ← MakeEdge[fMinLast: maskTrapezoid.fMinLast+maskTrapezoid.fSizeLast, fMin: maskTrapezoid.fMin+maskTrapezoid.fSize, sSize: maskTrapezoid.sSize];
TempColor[[sMin: maskTrapezoid.sMin, fMin: fMinBox, sSize: maskTrapezoid.sSize, fSize: fSizeBox]];
WHILE s < sMinBand
DO
minEdge.fPos.lc ← minEdge.fPos.lc + minEdge.fIncr.li;
maxEdge.fPos.lc ← maxEdge.fPos.lc + maxEdge.fIncr.li;
s ← s + 1;
ENDLOOP;
WHILE s < sMaxBand
DO
DoLine[sMin: s, fMin: minEdge.fPos.highbits, fSize: maxEdge.fPos.highbits-minEdge.fPos.highbits];
minEdge.fPos.lc ← minEdge.fPos.lc + minEdge.fIncr.li;
maxEdge.fPos.lc ← maxEdge.fPos.lc + maxEdge.fIncr.li;
s ← s + 1;
ENDLOOP;
TempColor[[sMin: maskTrapezoid.sMin, fMin: fMinBox, sSize: maskTrapezoid.sSize, fSize: fSizeBox]];
IF leftovers AND trapMaxS>bandMaxS THEN AddLeftover[];
};
maskRunGroup: CommandBuffer.maskRunGroup => {
s: CARDINAL ← maskRunGroup.sMin;
sMinBand: CARDINAL ← MIN[band.sOrigin+band.sMin, maskRunGroup.sMin+maskRunGroup.sSize];
sMaxBand: CARDINAL ← MIN[band.sOrigin+band.sMin+band.sSize, maskRunGroup.sMin+maskRunGroup.sSize];
run: LONG POINTER TO PDFileFormat.Run ← maskRunGroup.pointer;
TempColor[[maskRunGroup.sMin, maskRunGroup.fMin, maskRunGroup.sSize, maskRunGroup.fSize]];
WHILE s < sMinBand
DO
IF run.lastRun THEN s ← s + 1;
run ← run + SIZE[PDFileFormat.Run];
ENDLOOP;
WHILE s < sMaxBand
DO
IF run.fMin+run.fSize > maskRunGroup.fSize THEN ERROR;
DoLine[sMin: s, fMin: run.fMin+maskRunGroup.fOffset, fSize: run.fSize];
IF run.lastRun THEN s ← s + 1;
run ← run + SIZE[PDFileFormat.Run];
ENDLOOP;
TempColor[[maskRunGroup.sMin, maskRunGroup.fMin, maskRunGroup.sSize, maskRunGroup.fSize]];
IF leftovers
AND maskRunGroup.loadAddress>=0
AND maskRunGroup.sMin+maskRunGroup.sSize>bandMaxS
THEN {
maskRunGroup.sSize←maskRunGroup.sSize-(s-maskRunGroup.sMin);
maskRunGroup.sMin←s;
maskRunGroup.runCount ← -1; --unused, eventually eliminate from DEF
maskRunGroup.pointer←run;
AddLeftover[];
};
};
maskSamples: CommandBuffer.maskSamples => {
rectangle: PDInterpBitmap.Rectangle ← PDInterpBitmap.Window[maskSamples.samples];
TempColor[rectangle];
SELECT currentColorType
FROM
none => ERROR;
clear => PDInterpBitmap.Transfer[band, maskSamples.samples, [and, complement]];
opaqueTile, ink => PDInterpBitmap.Transfer[band, maskSamples.samples, [or, null]];
transparentTile => {
bounds: PDInterpBitmap.Rectangle ← PDInterpBitmap.Intersect[rectangle, PDInterpBitmap.Window[band]];
scratchWords: INT ← Basics.LongMult[bounds.sSize, (bounds.fSize+bitsPerWord-1)/bitsPerWord];
buffer: LONG POINTER ←PDInterpSysCalls.AllocateSpace[scratchWords];
destDesc:PDInterpBitmap.BitmapDesc←PDInterpBitmap.Reshape[pointer: buffer, words: scratchWords, bounds: bounds];
GetColorTile[];
PDInterpBitmap.TransferTile[dest: destDesc, tile: cachedColorTile];
PDInterpBitmap.Transfer[destDesc, maskSamples.samples, [and, null]];
PDInterpBitmap.Transfer[band, destDesc, [or, null]];
PDInterpSysCalls.FreeSpace[buffer];
};
ENDCASE => ERROR;
TempColor[rectangle];
IF leftovers AND maskSamples.loadAddress>=0 AND maskSamples.samples.sOrigin+maskSamples.samples.sMin+maskSamples.samples.sSize > bandMaxS THEN AddLeftover[];
};