DIRECTORY BitBlt, Environment, Inline, ImagerPixelMaps, Process, RTMicrocode, RTTypesBasic, SafeStorage, Space; ImagerPixelMapsImpl: CEDAR MONITOR IMPORTS BitBlt, ImagerPixelMaps, Inline, Process, RTMicrocode, RTTypesBasic, SafeStorage, Space EXPORTS ImagerPixelMaps ~ BEGIN PixelMap: TYPE ~ ImagerPixelMaps.PixelMap; Tile: TYPE ~ ImagerPixelMaps.Tile; PixelMapRep: TYPE ~ ImagerPixelMaps.PixelMapRep; DeviceRectangle: TYPE ~ ImagerPixelMaps.DeviceRectangle; Function: TYPE ~ ImagerPixelMaps.Function; bitsPerWord: NAT ~ Environment.bitsPerWord; lgBitsPerWord: NAT ~ Environment.logBitsPerWord; wordsPerPage: NAT ~ Environment.wordsPerPage; BITAND: PROC [a, b: CARDINAL] RETURNS[CARDINAL] ~ INLINE {RETURN[Inline.BITAND[a, b]]}; Shift: PROC [a: CARDINAL, b: INTEGER] RETURNS [CARDINAL] ~ INLINE {RETURN[Inline.BITSHIFT[a, b]]}; Intersect: PUBLIC PROC [a, b: DeviceRectangle] RETURNS [DeviceRectangle] ~ { sMin: INTEGER _ MAX[a.sMin, b.sMin]; fMin: INTEGER _ MAX[a.fMin, b.fMin]; sMax: INTEGER _ MIN[INT[a.sMin]+a.sSize, INT[b.sMin]+b.sSize]; fMax: INTEGER _ MIN[INT[a.fMin]+a.fSize, INT[b.fMin]+b.fSize]; IF sMax <= sMin OR fMax <= fMin THEN RETURN [[0, 0, 0, 0]] ELSE RETURN [[sMin, fMin, sMax-sMin, fMax-fMin]] }; Create: PUBLIC PROC [lgBitsPerPixel: [0..4], bounds: DeviceRectangle] RETURNS [pixelMap: PixelMap] ~ { bitsPerPixel: CARDINAL ~ Shift[1, lgBitsPerPixel]; bitsPerLine: NAT ~ Inline.LongMult[bounds.fSize, bitsPerPixel]; wordsPerLine: CARDINAL ~ (bitsPerLine+(bitsPerWord-1)) / bitsPerWord; words: LONG CARDINAL ~ Inline.LongMult[wordsPerLine, bounds.sSize]; pixelMap.refRep _ NewRefRep[words]; pixelMap.refRep.lgBitsPerPixel _ lgBitsPerPixel; pixelMap.refRep.rast _ wordsPerLine; pixelMap.refRep.lines _ bounds.sSize; pixelMap.sMin _ pixelMap.fMin _ 0; [pixelMap.sOrigin, pixelMap.fOrigin, pixelMap.sSize, pixelMap.fSize] _ bounds; }; CreateFrameBuffer: PUBLIC UNSAFE PROC [pointer: LONG POINTER, words: LONG CARDINAL, lgBitsPerPixel: [0..4], rast: CARDINAL, lines: CARDINAL, ref: REF _ NIL] RETURNS [pixelMap: PixelMap] ~ { bitsPerLine: NAT ~ Inline.LongMult[rast, bitsPerWord]; fSize: NAT ~ Shift[bitsPerLine, -lgBitsPerPixel]; wastedWords: NAT _ INT[words]-INT[rast]*INT[lines]; pixelMap.refRep _ NEW[PixelMapRep _ [ref, pointer, words, lgBitsPerPixel, rast, lines]]; pixelMap.sOrigin _ pixelMap.fOrigin _ pixelMap.sMin _ pixelMap.fMin _ 0; pixelMap.sSize _ lines; pixelMap.fSize _ fSize; }; Clear: PUBLIC PROC [pixelMap: PixelMap] ~ TRUSTED { pointer: LONG POINTER _ pixelMap.refRep.pointer; words: LONG CARDINAL _ pixelMap.refRep.words; WHILE words > 32768 DO pointer _ RTMicrocode.LONGZERO[pointer, 32768]; words _ words - 32768; ENDLOOP; pointer _ RTMicrocode.LONGZERO[pointer, words]; }; Reshape: PUBLIC PROC [refRep: REF PixelMapRep, lgBitsPerPixel: [0..4], bounds: DeviceRectangle] RETURNS [pixelMap: PixelMap] ~ { bitsPerPixel: CARDINAL ~ Shift[1, lgBitsPerPixel]; bitsPerLine: NAT ~ Inline.LongMult[bounds.fSize, bitsPerPixel]; wordsPerLine: CARDINAL ~ (bitsPerLine+(bitsPerWord-1)) / bitsPerWord; words: LONG CARDINAL ~ Inline.LongMult[wordsPerLine, bounds.sSize]; IF refRep = NIL THEN refRep _ NewRefRep[words] ELSE IF words > refRep.words THEN { refRep.pointer _ NIL; refRep.ref _ NIL; IF refRep.words > 1000 THEN SafeStorage.ReclaimCollectibleObjects[]; refRep _ NewRefRep[words]; }; refRep.lgBitsPerPixel _ lgBitsPerPixel; refRep.rast _ wordsPerLine; refRep.lines _ bounds.sSize; pixelMap _ [bounds.sMin, bounds.fMin, 0, 0, bounds.sSize, bounds.fSize, refRep]; }; ShiftMap: PUBLIC PROC [p: PixelMap, s, f: INTEGER] RETURNS [PixelMap] ~ { RETURN [[p.sOrigin + s, p.fOrigin + f, p.sMin, p.fMin, p.sSize, p.fSize, p.refRep]] }; ShiftWindow: PUBLIC PROC [p: PixelMap, s, f: INTEGER] RETURNS [PixelMap] ~ { RETURN [[p.sOrigin, p.fOrigin, p.sMin + s, p.fMin + f, p.sSize, p.fSize, p.refRep]] }; Clip: PUBLIC PROC [p: PixelMap, bounds: DeviceRectangle] RETURNS [PixelMap] ~ { bounds _ Intersect[Window[p], bounds]; RETURN [[p.sOrigin, p.fOrigin, bounds.sMin-p.sOrigin, bounds.fMin-p.fOrigin, bounds.sSize, bounds.fSize, p.refRep]] }; SetWindow: PUBLIC PROC [p: PixelMap, bounds: DeviceRectangle] RETURNS [PixelMap] ~ { RETURN [[p.sOrigin, p.fOrigin, bounds.sMin-p.sOrigin, bounds.fMin-p.fOrigin, bounds.sSize, bounds.fSize, p.refRep]] }; Window: PUBLIC PROC [p: PixelMap] RETURNS [DeviceRectangle] ~ { RETURN [[p.sOrigin + p.sMin, p.fOrigin + p.fMin, p.sSize, p.fSize]] }; BufferBounds: PUBLIC PROC [p: PixelMap] RETURNS [DeviceRectangle] ~ { RETURN [[p.sOrigin, p.fOrigin, p.refRep.lines, Shift[p.refRep.rast, lgBitsPerWord-p.refRep.lgBitsPerPixel]]] }; GetPixel: PUBLIC PROC [source: PixelMap, s, f: INTEGER] RETURNS [CARDINAL] ~ { bounds: DeviceRectangle _ Intersect[BufferBounds[source], Window[source]]; sCheck: NAT _ bounds.sSize-1-NAT[s-bounds.sMin]; fCheck: NAT _ bounds.fSize-1-NAT[f-bounds.fMin]; SELECT source.refRep.lgBitsPerPixel FROM 0 => RETURN [source.GetBit[s, f]]; 1 => RETURN [source.Get2Bits[s, f]]; 2 => RETURN [source.Get4Bits[s, f]]; 3 => RETURN [source.Get8Bits[s, f]]; 4 => RETURN [source.Get16Bits[s, f]]; ENDCASE => ERROR; }; Equal: PUBLIC PROC [a, b: PixelMap] RETURNS [BOOLEAN] ~ { window: DeviceRectangle _ Intersect[Window[a], BufferBounds[a]]; IF window # Intersect[Window[b], BufferBounds[b]] THEN RETURN [FALSE]; IF a.refRep = b.refRep THEN RETURN [TRUE]; IF a.refRep.lgBitsPerPixel # b.refRep.lgBitsPerPixel THEN RETURN [FALSE]; SELECT a.refRep.lgBitsPerPixel FROM 0 => TRUSTED { aPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..2) _ a.refRep.pointer + Inline.LongMult[(window.sMin - a.sOrigin), a.refRep.rast]; bPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..2) _ b.refRep.pointer + Inline.LongMult[(window.sMin - b.sOrigin), b.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF aPtr^[f-a.fOrigin] # bPtr^[f-b.fOrigin] THEN RETURN [FALSE]; ENDLOOP; aPtr _ aPtr+a.refRep.rast; bPtr _ bPtr+b.refRep.rast; ENDLOOP; }; 1 => TRUSTED { aPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..4) _ a.refRep.pointer + Inline.LongMult[(window.sMin - a.sOrigin), a.refRep.rast]; bPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..4) _ b.refRep.pointer + Inline.LongMult[(window.sMin - b.sOrigin), b.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF aPtr^[f-a.fOrigin] # bPtr^[f-b.fOrigin] THEN RETURN [FALSE]; ENDLOOP; aPtr _ aPtr+a.refRep.rast; bPtr _ bPtr+b.refRep.rast; ENDLOOP; }; 2 => TRUSTED { aPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..16) _ a.refRep.pointer + Inline.LongMult[(window.sMin - a.sOrigin), a.refRep.rast]; bPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..16) _ b.refRep.pointer + Inline.LongMult[(window.sMin - b.sOrigin), b.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF aPtr^[f-a.fOrigin] # bPtr^[f-b.fOrigin] THEN RETURN [FALSE]; ENDLOOP; aPtr _ aPtr+a.refRep.rast; bPtr _ bPtr+b.refRep.rast; ENDLOOP; }; 3 => TRUSTED { aPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..256) _ a.refRep.pointer + Inline.LongMult[(window.sMin - a.sOrigin), a.refRep.rast]; bPtr: LONG POINTER TO PACKED ARRAY [0..0) OF [0..256) _ b.refRep.pointer + Inline.LongMult[(window.sMin - b.sOrigin), b.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF aPtr^[f-a.fOrigin] # bPtr^[f-b.fOrigin] THEN RETURN [FALSE]; ENDLOOP; aPtr _ aPtr+a.refRep.rast; bPtr _ bPtr+b.refRep.rast; ENDLOOP; }; 4 => TRUSTED { aPtr: LONG POINTER TO PACKED ARRAY [0..0) OF CARDINAL _ a.refRep.pointer + Inline.LongMult[(window.sMin - a.sOrigin), a.refRep.rast]; bPtr: LONG POINTER TO PACKED ARRAY [0..0) OF CARDINAL _ b.refRep.pointer + Inline.LongMult[(window.sMin - b.sOrigin), b.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF aPtr^[f-a.fOrigin] # bPtr^[f-b.fOrigin] THEN RETURN [FALSE]; ENDLOOP; aPtr _ aPtr+a.refRep.rast; bPtr _ bPtr+b.refRep.rast; ENDLOOP; }; ENDCASE => ERROR; RETURN [TRUE]; }; IsAll: PUBLIC PROC [pixelMap: PixelMap, value: CARDINAL _ 0] RETURNS [BOOLEAN] ~ { window: DeviceRectangle _ Intersect[Window[pixelMap], BufferBounds[pixelMap]]; SELECT pixelMap.refRep.lgBitsPerPixel FROM 0 => TRUSTED { p: LONG POINTER TO PACKED ARRAY [0..0) OF [0..2) _ pixelMap.refRep.pointer + Inline.LongMult[(window.sMin - pixelMap.sOrigin), pixelMap.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF p^[f-pixelMap.fOrigin] # value THEN RETURN [FALSE]; ENDLOOP; p _ p+pixelMap.refRep.rast; ENDLOOP; }; 1 => TRUSTED { p: LONG POINTER TO PACKED ARRAY [0..0) OF [0..4) _ pixelMap.refRep.pointer + Inline.LongMult[(window.sMin - pixelMap.sOrigin), pixelMap.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF p^[f-pixelMap.fOrigin] # value THEN RETURN [FALSE]; ENDLOOP; p _ p+pixelMap.refRep.rast; ENDLOOP; }; 2 => TRUSTED { p: LONG POINTER TO PACKED ARRAY [0..0) OF [0..16) _ pixelMap.refRep.pointer + Inline.LongMult[(window.sMin - pixelMap.sOrigin), pixelMap.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF p^[f-pixelMap.fOrigin] # value THEN RETURN [FALSE]; ENDLOOP; p _ p+pixelMap.refRep.rast; ENDLOOP; }; 3 => TRUSTED { p: LONG POINTER TO PACKED ARRAY [0..0) OF [0..256) _ pixelMap.refRep.pointer + Inline.LongMult[(window.sMin - pixelMap.sOrigin), pixelMap.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF p^[f-pixelMap.fOrigin] # value THEN RETURN [FALSE]; ENDLOOP; p _ p+pixelMap.refRep.rast; ENDLOOP; }; 4 => TRUSTED { p: LONG POINTER TO PACKED ARRAY [0..0) OF CARDINAL _ pixelMap.refRep.pointer + Inline.LongMult[(window.sMin - pixelMap.sOrigin), pixelMap.refRep.rast]; FOR s: INTEGER IN [window.sMin..window.sMin+window.sSize) DO FOR f: INTEGER IN [window.fMin..window.fMin+window.fSize) DO IF p^[f-pixelMap.fOrigin] # value THEN RETURN [FALSE]; ENDLOOP; p _ p+pixelMap.refRep.rast; ENDLOOP; }; ENDCASE => ERROR; RETURN [TRUE]; }; Trim: PUBLIC PROC [pixelMap: PixelMap, backround: CARDINAL _ 0] RETURNS [PixelMap] ~ { temp: PixelMap _ pixelMap; WHILE pixelMap.sSize > 0 DO temp.sSize _ 1; temp.sMin _ pixelMap.sMin+pixelMap.sSize-1; IF IsAll[temp, backround] THEN {pixelMap.sSize _ pixelMap.sSize - 1} ELSE EXIT; ENDLOOP; WHILE pixelMap.sSize > 0 DO temp.sSize _ 1; temp.sMin _ pixelMap.sMin; IF IsAll[temp, backround] THEN {pixelMap.sSize _ pixelMap.sSize - 1; pixelMap.sMin _ pixelMap.sMin + 1} ELSE EXIT; ENDLOOP; IF pixelMap.sSize = 0 THEN pixelMap.fSize _ 0; temp _ pixelMap; WHILE pixelMap.fSize > 0 DO temp.fSize _ 1; temp.fMin _ pixelMap.fMin+pixelMap.fSize-1; IF IsAll[temp, backround] THEN {pixelMap.fSize _ pixelMap.fSize - 1} ELSE EXIT; ENDLOOP; WHILE pixelMap.fSize > 0 DO temp.fSize _ 1; temp.fMin _ pixelMap.fMin; IF IsAll[temp, backround] THEN {pixelMap.fSize _ pixelMap.fSize - 1; pixelMap.fMin _ pixelMap.fMin + 1} ELSE EXIT; ENDLOOP; IF pixelMap.fSize = 0 THEN pixelMap.sSize _ 0; RETURN [pixelMap] }; replicator: ARRAY [0..4] OF CARDINAL ~ [0FFFFH, 05555H, 01111H, 00101H, 00001H]; Fill: PUBLIC PROC [dest: PixelMap, area: DeviceRectangle, value: CARDINAL, function: Function] ~ TRUSTED { lgBitsPerPixel: INTEGER ~ dest.refRep.lgBitsPerPixel; rast: CARDINAL ~ dest.refRep.rast; sMin: INTEGER ~ MAX[dest.sMin, 0, area.sMin-dest.sOrigin]; sMax: INTEGER ~ MIN[dest.sMin+dest.sSize, dest.refRep.lines, area.sMin+area.sSize-dest.sOrigin]; fMin: INTEGER ~ MAX[dest.fMin, 0, area.fMin-dest.fOrigin]; fMax: INTEGER ~ MIN[dest.fMin+dest.fSize, Shift[rast, lgBitsPerWord-lgBitsPerPixel], area.fMin+area.fSize-dest.fOrigin]; replicatedPixel: CARDINAL _ Inline.BITAND[value, Shift[1, Shift[1, lgBitsPerPixel]]-1] * replicator[lgBitsPerPixel]; bbTableSpace: BitBlt.BBTableSpace; bb: BitBlt.BBptr _ BitBlt.AlignedBBTable[@bbTableSpace]; IF sMinfMinDest AND (fMinDest+fSize)>fMinSource AND (sStartSource+sSize)>sStartDest AND (sStartDest+sSize)>sStartSource THEN { bb.flags.disjoint _ FALSE; -- the rectangles overlap IF sStartDest=sStartSource THEN bb.flags.disjointItems _ FALSE; -- so do the items IF sStartDest>sStartSource OR (sStartDest=sStartSource AND fMinDest>fMinSource) THEN { -- reverse direction bb.flags.direction _ backward; bb.srcDesc.srcBpl _ bb.dstBpl _ -bb.dstBpl; sStartSource _ sStartSource + (sSize-1); sStartDest _ sStartDest + (sSize-1); }; }; }; bb.dst _ [word: dest.refRep.pointer + Inline.LongMult[sStartDest, dest.refRep.rast] + fMinDest/bitsPerWord, bit: fMinDest MOD bitsPerWord]; bb.src _ [word: source.refRep.pointer + Inline.LongMult[sStartSource, source.refRep.rast] + fMinSource/bitsPerWord, bit: fMinSource MOD bitsPerWord]; BitBlt.BITBLT[bb]; }; }; IsPowerOfTwo: PROC [c: CARDINAL] RETURNS [BOOLEAN] ~ INLINE { RETURN [BITAND[c, c-1] = 0] }; largeBitSize: INT _ 5000; CreateTile: PUBLIC PROC [pixelMap: PixelMap, phase: INTEGER _ 0, fSizeHint: NAT _ 100, scratch: REF PixelMapRep _ NIL] RETURNS [tile: Tile] ~ { lgBitsPerPixel: NAT _ pixelMap.refRep.lgBitsPerPixel; bitWidth: CARDINAL _ Shift[pixelMap.fSize, lgBitsPerPixel]; IF bitWidth <= 16 AND IsPowerOfTwo[bitWidth] AND pixelMap.sSize < 16 AND phase = 0 THEN { small: PixelMap _ Reshape[scratch, lgBitsPerPixel, [pixelMap.sOrigin+pixelMap.sMin, pixelMap.fOrigin+pixelMap.fMin, pixelMap.sSize, Shift[16, -lgBitsPerPixel]]]; FOR fShift: NAT _ 0, fShift+pixelMap.fSize UNTIL fShift>=small.fSize DO Transfer[small, ShiftMap[pixelMap, 0, fShift], [null, null]]; ENDLOOP; tile _ [small.sOrigin, small.fOrigin, small.sSize, small.fSize, 0, small.refRep]; } ELSE { fSize: NAT _ (fSizeHint+pixelMap.fSize-1)/pixelMap.fSize*pixelMap.fSize; bitsPerLine: NAT _ Shift[fSize, lgBitsPerPixel]; sSize: NAT _ MAX[(((largeBitSize+bitsPerLine-1)/bitsPerLine)/pixelMap.sSize)*pixelMap.sSize, pixelMap.sSize]; large: PixelMap _ Reshape[scratch, lgBitsPerPixel, [pixelMap.sOrigin+pixelMap.sMin, pixelMap.fOrigin+pixelMap.fMin, sSize, fSize]]; finalPhase: CARDINAL; WHILE phase<0 DO phase _ phase + pixelMap.fSize ENDLOOP; phase _ phase MOD pixelMap.fSize; finalPhase _ (phase * (sSize/pixelMap.sSize)) MOD pixelMap.fSize; large.sSize _ pixelMap.sSize; large.fSize _ pixelMap.fSize; Transfer[large, pixelMap, [null, null]]; WHILE large.fSize pixelMap.fSize DO phase _ phase - pixelMap.fSize ENDLOOP; ENDLOOP; tile _ [large.sOrigin, large.fOrigin, sSize, fSize, finalPhase, large.refRep]; }; }; TileFromStipple: PUBLIC PROC [stipple: CARDINAL, scratch: REF PixelMapRep _ NIL] RETURNS [tile: Tile] ~ TRUSTED { small: PixelMap _ Reshape[scratch, 0, [0, 0, 4, 16]]; p: LONG POINTER TO CARDINAL _ small.refRep.pointer+4*SIZE[CARDINAL]; IF small.refRep.words < 4*SIZE[CARDINAL] THEN ERROR; THROUGH [0..4) DO p _ p - SIZE[CARDINAL]; p^ _ 1111H * (stipple MOD 16); stipple _ stipple/16; ENDLOOP; tile _ [small.sOrigin, small.fOrigin, small.sSize, small.fSize, 0, small.refRep]; }; TransferTile: PUBLIC PROC [dest: PixelMap, tile: Tile, function: Function _ [null, null]] ~ TRUSTED { lgBitsPerPixel: NAT ~ tile.refRep.lgBitsPerPixel; bitWidth: CARDINAL ~ Shift[tile.fSize, lgBitsPerPixel]; IF dest.refRep.lgBitsPerPixel # lgBitsPerPixel THEN ERROR; IF bitWidth = bitsPerWord AND tile.refRep.rast = 1 AND tile.sSize <= 16 AND tile.phase = 0 THEN { startLine: NAT _ MAX[dest.sMin, 0]; endLine: INTEGER _ MIN[dest.sMin+dest.sSize, dest.refRep.lines]; startPixel: NAT _ MAX[dest.fMin, 0]; endPixel: INTEGER _ MIN[dest.fMin+dest.fSize, Shift[dest.refRep.rast, lgBitsPerWord-lgBitsPerPixel]]; IF endLine>startLine AND endPixel>startPixel THEN { startBit: NAT _ Shift[startPixel, lgBitsPerPixel]; bbTableSpace: BitBlt.BBTableSpace; bb: BitBlt.BBptr ~ BitBlt.AlignedBBTable[@bbTableSpace]; sOffset: INTEGER _ (dest.sOrigin+dest.sMin-tile.sOrigin) MOD tile.sSize; fOffset: INTEGER _ (dest.fOrigin+dest.fMin-tile.fOrigin) MOD tile.fSize; WHILE sOffset < 0 DO sOffset _ sOffset + tile.sSize ENDLOOP; WHILE fOffset < 0 DO fOffset _ fOffset + tile.fSize ENDLOOP; bb^ _ [ dst: [word: dest.refRep.pointer + Inline.LongMult[startLine, dest.refRep.rast] + startBit/bitsPerWord, bit: startBit MOD bitsPerWord], dstBpl: dest.refRep.rast*bitsPerWord, src: [word: tile.refRep.pointer+sOffset, bit: Shift[fOffset, lgBitsPerPixel]], srcDesc: [gray[[yOffset: sOffset, widthMinusOne: 0, heightMinusOne: tile.sSize-1]]], height: endLine-startLine, width: Shift[endPixel-startPixel, lgBitsPerPixel], flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: TRUE, srcFunc: function.srcFunc, dstFunc: function.dstFunc] ]; BitBlt.BITBLT[bb]; }; } ELSE { sMin: INT _ dest.sOrigin+dest.sMin; fMin: INT _ dest.fOrigin+dest.fMin; source: PixelMap; sOrigin: INT _ tile.sOrigin; fOrigin: INT _ tile.fOrigin; WHILE sOrigin < sMin DO sOrigin _ sOrigin + tile.sSize; fOrigin _ fOrigin + tile.phase; ENDLOOP; WHILE sOrigin > sMin DO sOrigin _ sOrigin - tile.sSize; fOrigin _ fOrigin - tile.phase; ENDLOOP; WHILE fOrigin < fMin DO fOrigin _ fOrigin + tile.fSize ENDLOOP; WHILE fOrigin > fMin DO fOrigin _ fOrigin - tile.fSize ENDLOOP; source _ [sOrigin, fOrigin, 0, 0, tile.sSize, tile.fSize, tile.refRep]; WHILE source.sOrigin < sMin+dest.sSize DO source.fOrigin _ fOrigin; WHILE source.fOrigin < fMin+dest.fSize DO Transfer[dest, source, function]; source.fOrigin _ source.fOrigin + source.fSize; ENDLOOP; source.sOrigin _ source.sOrigin + source.sSize; fOrigin _ fOrigin + tile.phase; WHILE fOrigin > fMin DO fOrigin _ fOrigin - source.fSize ENDLOOP; ENDLOOP; }; }; WordSeqRep: TYPE ~ RECORD [SEQUENCE length: NAT OF WORD]; SpaceRef: TYPE ~ REF SpaceRep; SpaceRep: TYPE ~ RECORD [space: Space.Handle _ Space.nullHandle, link: SpaceRef]; spaceList: SpaceRef _ NIL; NewRefRep: ENTRY PROC [words: LONG CARDINAL] RETURNS [refRep: REF PixelMapRep] ~ { ENABLE UNWIND => NULL; refRep _ NEW[PixelMapRep]; IF words < 16000 THEN { wordSeq: REF WordSeqRep _ NEW[WordSeqRep[words]]; refRep.ref _ wordSeq; TRUSTED {refRep.pointer _ @wordSeq[0]}; refRep.words _ words; } ELSE TRUSTED { spaceRef: SpaceRef _ NEW[SpaceRep]; pages: LONG CARDINAL _ (words + (wordsPerPage-1))/wordsPerPage; words _ pages*wordsPerPage; spaceRef.space _ Space.Create[size: pages, parent: Space.virtualMemory]; Space.Map[spaceRef.space]; refRep.ref _ spaceRef; refRep.pointer _ Space.LongPointer[spaceRef.space]; refRep.words _ words; spaceRef.link _ spaceList; spaceList _ spaceRef; }; }; finalizationQueue: RTTypesBasic.FinalizationQueue _ RTTypesBasic.NewFQ[20]; InitializeFinalization: ENTRY PROC ~ TRUSTED { ENABLE UNWIND => NULL; RTTypesBasic.EstablishFinalization[CODE[SpaceRep], 1, finalizationQueue]; Process.Detach[FORK FinalizerProcess[finalizationQueue]]; finalizationEstablished _ TRUE; }; ReInitializeFinalization: ENTRY PROC ~ TRUSTED { ENABLE UNWIND => NULL; RTTypesBasic.ReEstablishFinalization[CODE[SpaceRep], 1, finalizationQueue]; Process.Detach[FORK FinalizerProcess[finalizationQueue]]; finalizationEstablished _ TRUE; }; FinalizerProcess: PROC [finalizationQueue: RTTypesBasic.FinalizationQueue] ~ { DO ENABLE ABORTED => LOOP; spaceRef: SpaceRef _ NARROW[RTTypesBasic.FQNext[finalizationQueue]]; Finalize[spaceRef]; ENDLOOP; }; Finalize: ENTRY PROC [spaceRef: SpaceRef] ~ TRUSTED { ENABLE UNWIND => NULL; prev: SpaceRef _ NIL; IF spaceList = NIL THEN RETURN; FOR p: SpaceRef _ spaceList, p.link UNTIL p = spaceRef DO IF p = NIL THEN RETURN; prev _ p ENDLOOP; IF prev = NIL THEN spaceList _ spaceRef.link ELSE prev.link _ spaceRef.link; Space.Delete[spaceRef.space]; spaceRef.link _ NIL; }; finalizationEstablished: BOOLEAN _ FALSE; InitializeFinalization[! RTTypesBasic.CantEstablishFinalization => CONTINUE]; IF NOT finalizationEstablished THEN {ReInitializeFinalization[]}; END. ΊImagerPixelMapsImpl.mesa Michael Plass, September 6, 1983 3:26 pm -- Some inlines for basic bit-hacking operations. Will raise a bounds fault if too many bits per line. Bounds check if `words' is too small or much too big. Will raise a bounds fault if too many bits per line. The following bounding box is calculated in terms of the destination buffer. Space Managment In case this object was allocated under a different instantiation. ΚΙ˜Jšœ™J™(JšΟk œf˜ošœœ˜"JšœX˜_Jšœ˜Jšœ˜—Jšœ œ˜*Jšœœ˜"Jšœ œ˜0Jšœœ#˜8Jšœ œ˜*Jšœ œ˜+Jšœœ˜0Jšœœ˜-šœ1™1š Πknœœœœœ˜/Jšœœœœ ˜'—š Οnœœœœœœ˜8Jšœœœœ ˜)——šŸ œœœœ˜LJšœœœ˜$Jšœœœ˜$Jš œœœœœ˜>Jš œœœœœ˜>Jšœœœœ˜:Jšœœ%˜0Jšœ˜—šŸœœœ3œ˜fJšœœ˜2šœ œ/˜?J™4—Jšœœ/˜EJšœœœ/˜CJšœ#˜#Jšœ0˜0Jšœ$˜$Jšœ%˜%Jšœ"˜"JšœO˜OJšœ˜—šŸœœœœ œœ  œ œ œœœœ˜½Jšœ œ&˜6Jšœœ'˜1š œ œœœœ˜3Jšœ5™5—JšœœC˜XJšœH˜HJšœ˜Jšœ˜Jšœ˜—šŸœœœœ˜3Jšœ œœ˜0Jšœœœ˜-šœ˜Jšœœ˜/Jšœ˜Jšœ˜—Jšœœ˜/Jšœ˜—š Ÿœœœ œ?œ˜€Jšœœ˜2šœ œ/˜?J™4—Jšœœ/˜EJšœœœ/˜CJšœ œœ˜.šœœœ˜#Jšœœ˜Jšœ œ˜Jšœœ)˜DJšœ˜Jšœ˜—Jšœ'˜'Jšœ˜Jšœ˜JšœP˜PJšœ˜—š Ÿœœœœœ˜IJšœM˜SJšœ˜—š Ÿ œœœœœ˜LJšœM˜SJšœ˜—šŸœœœ(œ˜OJšœ'˜'Jšœm˜sJšœ˜—šŸ œœœ(œ˜TJšœm˜sJšœ˜—šŸœœœœ˜?Jšœ=˜CJšœ˜—šŸ œœœœ˜EJšœf˜lJšœ˜—š Ÿœœœœœœ˜NJšœJ˜JJšœœœ˜0Jšœœœ˜0šœ˜(Jšœœ˜"Jšœœ˜$Jšœœ˜$Jšœœ˜$Jšœœ˜%Jšœœ˜—Jšœ˜—š Ÿœœœœœ˜9J˜@Jšœ0œœœ˜FJšœœœœ˜*Jšœ3œœœ˜Išœ˜#šœœ˜Jš œœœœœœœW˜ƒJš œœœœœœœW˜ƒšœœœ)˜<šœœœ)˜˜HJšœ œ ˜0Jšœœœ]˜mJšœƒ˜ƒJšœ œ˜Jšœ œ œ˜8Jšœœ˜!Jšœ.œ˜AJšœ˜Jšœ˜Jšœ(˜(šœ˜Jšœ œ˜Jšœœ˜&Jšœ=˜=Jšœ˜—šœ˜Jšœ œ˜Jšœœ˜&JšœA˜AšœH˜HJšœ!˜!Jšœ)˜)J˜—Jšœ˜Jšœœ œ˜GJšœ˜—JšœN˜NJšœ˜—Jšœ˜—šŸœœœ œ œœœœ˜qJšœ5˜5Jš œœœœœœœ˜DJš œœœœœ˜4šœ˜Jšœœœ˜Jšœœ˜Jšœ˜Jšœ˜—JšœQ˜QJšœ˜—šŸ œœœCœ˜eJšœœ˜1Jšœ œ%˜7Jšœ-œœ˜:š œœœœœ˜aJšœ œœ˜#Jšœ œœ*˜@Jšœ œœ˜$Jšœ œœN˜ešœœœ˜3Jšœ œ%˜2J˜"Jšœ8˜8Jšœ œ)œ ˜HJšœ œ)œ ˜HJšœ œ œ˜