IIMaskImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Michael Plass, August 20, 1986 10:59:32 am PDT
Doug Wyatt, May 19, 1985 5:23:50 pm PDT
DIRECTORY
Basics USING [BITSHIFT, bitsPerWord, LongMult],
IIDevice USING [CharMask, CharMaskRep, DeviceBox, Run, RunProc],
IIMask USING [],
IIPixelMap USING [BoundedWindow, Clear, Clip, Create, CreateFrameBuffer, DeviceRectangle, Fill, Intersect, PixelMap, PixelMapRep],
Process USING [CheckForAbort];
PixelMap: TYPE ~ IIPixelMap.PixelMap;
RunProc: TYPE ~ IIDevice.RunProc;
CharMask: TYPE ~ IIDevice.CharMask;
DeviceBox: TYPE ~ IIDevice.DeviceBox;
DeviceRectangle:
TYPE ~ IIPixelMap.DeviceRectangle;
bitsPerWord:
NAT ~ Basics.bitsPerWord;
RunsFromBitmap:
PUBLIC
PROC [bitmap: PixelMap, run: RunProc] ~
TRUSTED {
refRep: REF IIPixelMap.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: BOOLEAN ← FALSE;
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 IIDevice.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 IIDevice.CharMaskRep.runs => {
s: INTEGER ← s0;
sMax: INTEGER ~ clip.sMin+clip.sSize;
FOR i:
NAT
IN [0..runGroup.nRuns)
WHILE s < sMax
DO
r: IIDevice.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 IIDevice.CharMaskRep.raster =>
TRUSTED {
rast: CARDINAL ~ (raster.fSizeBB+(bitsPerWord-1))/bitsPerWord;
bitmap ← IIPixelMap.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 IIDevice.CharMaskRep.runs => {
w: DeviceRectangle ~ [x.sMinBB, x.fMinBB, x.sSizeBB, x.fSizeBB];
Run: RunProc ~ {bitmap.Fill[[sMin, fMin, 1, fSize], 1]};
bitmap ← IIPixelMap.Create[0, w];
bitmap.Clear;
RunsFromCharMask[charMask: charMask, run: Run, s: 0, f: 0, clip: w];
};
ENDCASE => ERROR;
};