ImagerMaskImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Michael Plass, November 1, 1985 9:24:02 am PST
Doug Wyatt, May 19, 1985 5:23:50 pm PDT
DIRECTORY
Basics USING [BITSHIFT, bitsPerWord, LongMult],
ImagerDevice USING [CharMask, CharMaskRep, DeviceBox, Run, RunProc],
ImagerMask USING [],
ImagerPixelMap USING [BoundedWindow, Clear, Clip, Create, CreateFrameBuffer, DeviceRectangle, Fill, Intersect, PixelMap, PixelMapRep],
Process USING [CheckForAbort];
ImagerMaskImpl: CEDAR PROGRAM
IMPORTS Basics, ImagerPixelMap, Process
EXPORTS ImagerMask
~ BEGIN
PixelMap: TYPE ~ ImagerPixelMap.PixelMap;
RunProc: TYPE ~ ImagerDevice.RunProc;
CharMask: TYPE ~ ImagerDevice.CharMask;
DeviceBox: TYPE ~ ImagerDevice.DeviceBox;
DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle;
bitsPerWord: NAT ~ Basics.bitsPerWord;
RunsFromBitmap: PUBLIC PROC [bitmap: PixelMap, run: RunProc] ~ TRUSTED {
refRep: REF ImagerPixelMap.PixelMapRep ← bitmap.refRep;
bitmap ← bitmap.Clip[bitmap.BoundedWindow];
RunsFromBits[base: refRep.pointer, wordsPerLine: refRep.rast, sBits: bitmap.sMin, fBits: bitmap.fMin, sSize: bitmap.sSize, fSize: bitmap.fSize, sRuns: bitmap.sOrigin+bitmap.sMin, fRuns: bitmap.fOrigin+bitmap.fMin, run: run];
};
RunsFromBits: PUBLIC PROC [base: LONG POINTER, wordsPerLine: NAT, sBits, fBits, sSize, fSize: NAT, sRuns, fRuns: INTEGER, run: RunProc] ~ TRUSTED {
sDelta: INTEGER ~ INTEGER[sRuns-sBits];
fDelta: INTEGER ~ INTEGER[fRuns-fBits];
s: INTEGER ← sBits;
sMax: INTEGER ~ sBits + sSize;
linePtr: LONG POINTER TO CARDINAL ← base + Basics.LongMult[s, wordsPerLine];
fFirst: NAT ~ fBits;
fEnd: NAT ~ MIN[fBits+fSize, wordsPerLine*bitsPerWord];
fFirstWord: CARDINAL ← fFirst / bitsPerWord;
fFirstBit: CARDINAL ← fFirst MOD bitsPerWord;
IF fFirst >= fEnd THEN RETURN;
WHILE s < sMax DO
wordPtr: LONG POINTER TO CARDINAL ← linePtr+fFirstWord;
wordsWorth: CARDINAL ← Basics.BITSHIFT[wordPtr^, fFirstBit];
goodBitCount: INTEGER ← bitsPerWord-fFirstBit;
f: CARDINAL ← fFirst;
someRuns: BOOLEANFALSE;
WHILE f < fEnd DO
fStart: NAT;
WHILE f < fEnd DO
IF goodBitCount = bitsPerWord AND wordsWorth = 0 THEN f ← f + bitsPerWord
ELSE {
f ← f + goodBitCount;
WHILE goodBitCount > 0 AND wordsWorth <= LAST[NAT] DO
goodBitCount ← goodBitCount-1;
wordsWorth ← wordsWorth*2;
ENDLOOP;
f ← f - goodBitCount;
IF goodBitCount > 0 THEN EXIT;
goodBitCount ← bitsPerWord;
};
wordPtr ← wordPtr + 1;
IF f < fEnd THEN wordsWorth ← wordPtr^;
ENDLOOP;
fStart ← f;
WHILE f < fEnd DO
IF goodBitCount = bitsPerWord AND wordsWorth = LAST[CARDINAL] THEN f ← f + bitsPerWord
ELSE {
f ← f + goodBitCount;
WHILE goodBitCount > 0 AND wordsWorth > LAST[NAT] DO
goodBitCount ← goodBitCount-1;
wordsWorth ← wordsWorth*2;
ENDLOOP;
f ← f - goodBitCount;
IF goodBitCount > 0 THEN EXIT;
goodBitCount ← bitsPerWord;
};
wordPtr ← wordPtr + 1;
IF f < fEnd THEN wordsWorth ← wordPtr^;
ENDLOOP;
f ← MIN[f, fEnd];
IF f > fStart THEN run[s+sDelta, fStart+fDelta, f-fStart];
ENDLOOP;
s ← s + 1;
linePtr ← linePtr + wordsPerLine;
IF LOOPHOLE[s, CARDINAL] MOD 16 = 0 THEN Process.CheckForAbort[];
ENDLOOP;
};
RunsFromBox: PUBLIC PROC [box: DeviceBox, run: RunProc] ~ {
IF box.fmax > box.fmin THEN {
fsize: NAT ~ box.fmax-box.fmin;
FOR s: INTEGER IN [INTEGER[box.smin]..INTEGER[box.smax]) DO
run[s, box.fmin, fsize];
ENDLOOP;
};
};
RunsFromRectangle: PUBLIC PROC [rect: DeviceRectangle, run: RunProc] ~ {
IF rect.fSize > 0 THEN {
FOR s: INTEGER IN [rect.sMin..rect.sMin+rect.sSize) DO
run[s, rect.fMin, rect.fSize];
ENDLOOP;
};
};
RunsFromCharMask: PUBLIC PROC [charMask: CharMask, run: RunProc, s, f: INTEGER, clip: DeviceRectangle] ~ {
s0: INTEGER ~ INT[s]+charMask.sMinBB;
f0: INTEGER ~ INT[f]+charMask.fMinBB;
clip ← clip.Intersect[[s0, f0, charMask.sSizeBB, charMask.fSizeBB]];
WITH charMask SELECT FROM
raster: REF ImagerDevice.CharMaskRep.raster => TRUSTED {
IF clip.sSize > 0 THEN RunsFromBits[
base: @raster[0],
wordsPerLine: (raster.fSizeBB+(bitsPerWord-1))/bitsPerWord,
sBits: clip.sMin-s0,
fBits: clip.fMin-f0,
sSize: clip.sSize,
fSize: clip.sSize,
sRuns: s0,
fRuns: f0,
run: run
];
};
runGroup: REF ImagerDevice.CharMaskRep.runs => {
s: INTEGER ← s0;
sMax: INTEGER ~ clip.sMin+clip.sSize;
FOR i: NAT IN [0..runGroup.nRuns) WHILE s < sMax DO
r: ImagerDevice.Run ~ runGroup[i];
IF s >= clip.sMin THEN {
min: INTEGER ~ MAX[NAT[r.fMin]+f0, clip.fMin];
max: INTEGER ~ MIN[NAT[r.fMin+r.fSize]+f0, clip.fMin+clip.fSize];
IF max > min THEN run[s, min, max-min];
};
IF r.lastRun THEN s ← s + 1;
ENDLOOP;
};
ENDCASE => NULL;
};
BitmapFromCharMask: PUBLIC PROC [charMask: CharMask] RETURNS [bitmap: PixelMap] ~ {
WITH charMask SELECT FROM
raster: REF ImagerDevice.CharMaskRep.raster => TRUSTED {
rast: CARDINAL ~ (raster.fSizeBB+(bitsPerWord-1))/bitsPerWord;
bitmap ← ImagerPixelMap.CreateFrameBuffer[pointer: @raster[0], words: Basics.LongMult[rast, raster.sSizeBB], lgBitsPerPixel: 0, rast: rast, lines: raster.sSizeBB, ref: charMask];
bitmap.sOrigin ← raster.sMinBB;
bitmap.fOrigin ← raster.fMinBB;
bitmap.fSize ← raster.fSizeBB;
};
x: REF ImagerDevice.CharMaskRep.runs => {
w: DeviceRectangle ~ [x.sMinBB, x.fMinBB, x.sSizeBB, x.fSizeBB];
Run: RunProc ~ {bitmap.Fill[[sMin, fMin, 1, fSize], 1]};
bitmap ← ImagerPixelMap.Create[0, w];
bitmap.Clear;
RunsFromCharMask[charMask: charMask, run: Run, s: 0, f: 0, clip: w];
};
ENDCASE => ERROR;
};
END.