ExtraAISImpl.Mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Spreitzer, August 8, 1984 10:06:55 pm PDT
Rick Beach, May 17, 1985 12:45:45 pm PDT
DIRECTORY
AIS, Basics, ExtraAIS;
ExtraAISImpl: CEDAR PROGRAM
IMPORTS AIS
EXPORTS ExtraAIS
= BEGIN OPEN ExtraAIS;
OpenWindow: PUBLIC PROC [f: AIS.FRef, firstScan: INTEGER ← 0, lastScan: INTEGERLAST[INTEGER], firstPixel: INTEGER ← 0, lastPixel: INTEGERLAST[INTEGER], emptyValue: CARDINAL ← 0]
RETURNS [v: VRef] = {
cfs, cls, cfp, clp: CARDINAL;
pixelsPerWord: CARDINAL = IF f.raster.bitsPerPixel=0 THEN Basics.bitsPerWord ELSE Basics.bitsPerWord/f.raster.bitsPerPixel;
w: AIS.WRef ← NIL;
IF lastScan < firstScan OR lastPixel < firstPixel THEN ERROR AIS.Error[badWindow];
cfs ← MAX[0, firstScan];
cls ← MIN[f.raster.scanCount-1, lastScan];
cfp ← MAX[0, firstPixel];
clp ← MIN[f.raster.scanLength-1, lastPixel];
IF cls >= cfs AND clp >= cfp THEN w ← AIS.OpenWindow[f, cfs, cls, cfp, clp];
v ← NEW [VRep ← [w: w, fref: f, firstScan: firstScan, lastScan: lastScan, firstPixel: firstPixel, lastPixel: lastPixel, cfs: cfs, cls: cls, cfp: cfp, clp: clp, wordsPerLine: (lastPixel - firstPixel + pixelsPerWord) / pixelsPerWord, pixelsPerWord: pixelsPerWord, emptyValue: emptyValue]];
};
Line1: TYPE = LONG POINTER TO RECORD [PACKED SEQUENCE COMPUTED NAT OF [0..1]];
Line2: TYPE = LONG POINTER TO RECORD [PACKED SEQUENCE COMPUTED NAT OF [0..3]];
Line4: TYPE = LONG POINTER TO RECORD [PACKED SEQUENCE COMPUTED NAT OF [0..15]];
Line8: TYPE = LONG POINTER TO RECORD [PACKED SEQUENCE COMPUTED NAT OF [0..255]];
Line16: TYPE = LONG POINTER TO RECORD [PACKED SEQUENCE COMPUTED NAT OF [0..65535]];
UnsafeReadLine: PUBLIC UNSAFE PROC [v: VRef, buffer: AIS.Buffer, line: INTEGERLAST[INTEGER]] = UNCHECKED {
scanPad, pixelPad, wordPad, pixelPadOff, pixelsPerLine, realPixelsPerLine: CARDINAL;
IF buffer.length < v.wordsPerLine THEN ERROR AIS.Error[bufferTooSmall];
line ← IF line = LAST[INTEGER] THEN v.nextScanLine ELSE line;
scanPad ← v.cfs - v.firstScan;
pixelPad ← v.cfp - v.firstPixel;
wordPad ← pixelPad/v.pixelsPerWord;
pixelPadOff ← pixelPad - wordPad*v.pixelsPerWord;
pixelsPerLine ← 1 + v.lastPixel - v.firstPixel;
realPixelsPerLine ← MAX[1 + v.clp - v.cfp, 0];
IF v.clp >= v.cfp AND line + v.firstScan IN [v.cfs .. v.cls] THEN {
IF buffer.length < wordPad THEN ERROR;
AIS.UnsafeReadLine[w: v.w, buffer: [length: buffer.length-wordPad, addr: buffer.addr+wordPad], line: line-scanPad];
IF pixelPadOff # 0 OR v.cfp # v.firstPixel OR v.clp # v.lastPixel THEN {
SELECT v.pixelsPerWord FROM
1 => {line: Line16 = LOOPHOLE[buffer.addr];
IF pixelPadOff # 0 THEN ERROR;
FOR i: INTEGER IN [v.firstPixel .. v.cfp) DO line[i - v.firstPixel] ← v.emptyValue ENDLOOP;
FOR i: INTEGER IN (v.clp .. v.lastPixel] DO line[i-v.firstPixel] ← v.emptyValue ENDLOOP;
};
2 => {line: Line8 = LOOPHOLE[buffer.addr];
IF pixelPadOff # 0 THEN {
FOR i: NAT DECREASING IN [v.cfp .. v.clp] DO
line[i-v.firstPixel] ← line[i-v.firstPixel-pixelPadOff]
ENDLOOP};
FOR i: INTEGER IN [v.firstPixel .. v.cfp) DO line[i - v.firstPixel] ← v.emptyValue ENDLOOP;
FOR i: INTEGER IN (v.clp .. v.lastPixel] DO line[i-v.firstPixel] ← v.emptyValue ENDLOOP;
};
4 => {line: Line4 = LOOPHOLE[buffer.addr];
IF pixelPadOff # 0 THEN {
FOR i: NAT DECREASING IN [v.cfp .. v.clp] DO
line[i-v.firstPixel] ← line[i-v.firstPixel-pixelPadOff]
ENDLOOP};
FOR i: INTEGER IN [v.firstPixel .. v.cfp) DO line[i - v.firstPixel] ← v.emptyValue ENDLOOP;
FOR i: INTEGER IN (v.clp .. v.lastPixel] DO line[i-v.firstPixel] ← v.emptyValue ENDLOOP;
};
8 => {line: Line2 = LOOPHOLE[buffer.addr];
IF pixelPadOff # 0 THEN {
FOR i: NAT DECREASING IN [v.cfp .. v.clp] DO
line[i-v.firstPixel] ← line[i-v.firstPixel-pixelPadOff]
ENDLOOP};
FOR i: INTEGER IN [v.firstPixel .. v.cfp) DO line[i - v.firstPixel] ← v.emptyValue ENDLOOP;
FOR i: INTEGER IN (v.clp .. v.lastPixel] DO line[i-v.firstPixel] ← v.emptyValue ENDLOOP;
};
16 => {line: Line1 = LOOPHOLE[buffer.addr];
IF pixelPadOff # 0 THEN {
FOR i: NAT DECREASING IN [v.cfp .. v.clp] DO
line[i-v.firstPixel] ← line[i-v.firstPixel-pixelPadOff]
ENDLOOP};
FOR i: INTEGER IN [v.firstPixel .. v.cfp) DO line[i - v.firstPixel] ← v.emptyValue ENDLOOP;
FOR i: INTEGER IN (v.clp .. v.lastPixel] DO line[i-v.firstPixel] ← v.emptyValue ENDLOOP;
};
ENDCASE => ERROR;
};
}
ELSE {
SELECT v.pixelsPerWord FROM
1 => {line: Line16 = LOOPHOLE[buffer.addr];
FOR i: NAT IN [0 .. pixelsPerLine) DO line[i] ← v.emptyValue ENDLOOP};
2 => {line: Line8 = LOOPHOLE[buffer.addr];
FOR i: NAT IN [0 .. pixelsPerLine) DO line[i] ← v.emptyValue ENDLOOP};
4 => {line: Line4 = LOOPHOLE[buffer.addr];
FOR i: NAT IN [0 .. pixelsPerLine) DO line[i] ← v.emptyValue ENDLOOP};
8 => {line: Line2 = LOOPHOLE[buffer.addr];
FOR i: NAT IN [0 .. pixelsPerLine) DO line[i] ← v.emptyValue ENDLOOP};
16 => {line: Line1 = LOOPHOLE[buffer.addr];
FOR i: NAT IN [0 .. pixelsPerLine) DO line[i] ← v.emptyValue ENDLOOP};
ENDCASE => ERROR;
};
v.nextScanLine ← MIN[line+1, v.lastScan];
};
CloseWindow: PUBLIC PROC [v: VRef] = {
w: AIS.WRef ← v.w;
v.w ← NIL;
v.fref ← NIL;
IF w # NIL THEN AIS.CloseWindow[w];
};
END.