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: 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 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. °ImagerMaskImpl.mesa Copyright c 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 Κο˜code™Kšœ Οmœ1™Kšœ²˜²Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šœžœ#˜)Kšœ@˜@Kšœ8˜8Kšœ%˜%Kšœ ˜ KšœD˜DKšœ˜—Kšžœžœ˜—Kšœ˜—K˜—Kšžœ˜—…—2Ρ