ColorTrixFileImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Plass and Bloomenthal, May 13, 1986 6:25:30 pm PDT
DIRECTORY AIS, ColorTrixBasics, ColorTrixFile, Commander, FS, Imager, ImagerBackdoor, ImagerColorMap, ImagerColorOperator, ImagerOps, ImagerPixelArray, ImagerPixelMap, ImagerTransformation, InterminalBackdoor, Interpress, IO, IPMaster, Process, ProcessProps, Rope, Terminal, Vector2;
ColorTrixFileImpl: CEDAR PROGRAM
IMPORTS AIS, ColorTrixBasics, FS, Imager, ImagerBackdoor, ImagerColorMap, ImagerColorOperator, ImagerOps, ImagerPixelArray, ImagerPixelMap, ImagerTransformation, InterminalBackdoor, Interpress, IO, IPMaster, Process, ProcessProps, Rope, Terminal
EXPORTS ColorTrixFile
~ {
ROPE: TYPE ~ Rope.ROPE;
Viewing Procedures:
Display: PUBLIC PROC [cd: Imager.Context, pa: ImagerPixelArray.PixelArray, op: ImagerColorOperator.ColorOperator] ~ {
r1: ImagerTransformation.Rectangle ← ViewRectangle[pa];
r2: ImagerTransformation.Rectangle ← ImagerBackdoor.GetBounds[cd];
inner: PROC ~ {
x: REAL ~ (r2.w-r1.w)/2;
y: REAL ~ (r2.h-r1.h)/2;
Imager.TranslateT[cd, [x, y]];
Imager.SetSampledColor[cd, pa, ViewPort[], op];
Imager.MaskRectangle[cd, ViewRectangle[pa]];       
};
Process.CheckForAbort[];
Imager.DoSave[cd, inner];
};
ViewRectangle: PROC [pa: ImagerPixelArray.PixelArray] RETURNS [rect: ImagerTransformation.Rectangle] ~ {
rect ← ImagerTransformation.TransformRectangle[pa.m, [0, 0, pa.sSize, pa.fSize]];
};
ViewPort: PROC RETURNS [ImagerTransformation.Transformation ← ImagerTransformation.Scale[1]] ~ {};
ViewIpFile: PUBLIC PROC [name: ROPE, cmapInit: BOOLTRUE]
RETURNS [BOOLTRUE] ~ {
cd: Imager.Context ~ ColorTrixBasics.InitCd[color, FALSE, FALSE, cmapInit];
master: Interpress.OpenMaster ~ OpenInterpress[name];
IF master = NIL THEN RETURN[FALSE];
FOR page: INT IN [1..master.pages] DO
Action: PROC ~ {Interpress.DoPage[master: master, page: page, context: cd]};
Process.CheckForAbort[];
ColorTrixBasics.ClearCd[cd, Imager.white];
Imager.SetColor[cd, Imager.black];
Imager.DoSaveAll[cd, Action];
ENDLOOP;
};
ViewDitherFile: PUBLIC PROC [name: ROPE, cd: Imager.Context ← NIL, cmapInit: BOOLTRUE]
RETURNS [ok: BOOLTRUE]
~ {
pa: ImagerPixelArray.PixelArray;
IF View8BitFile[name, cd, TRUE ! FS.Error, AIS.Error => CONTINUE] THEN RETURN;
pa ← ImagerPixelArray.FromAIS[name !
FS.Error, ImagerPixelArray.Error => {ok ← FALSE; CONTINUE}];
IF NOT ok THEN RETURN;
IF cd = NIL THEN cd ← ColorTrixBasics.InitCd[gray, TRUE, TRUE, cmapInit];
Display[cd, pa, ImagerColorOperator.GrayLinearColorModel[255, 0]];
};
ViewGrayFile: PUBLIC PROC [
name: ROPE, cd: Imager.Context ← NIL, cmapInit: BOOLTRUE]
RETURNS [ok: BOOLTRUE]
~ {
pa: ImagerPixelArray.PixelArray;
IF View8BitFile[name, cd, FALSE ! FS.Error, AIS.Error => CONTINUE] THEN RETURN;
pa ← ImagerPixelArray.FromAIS[name !
FS.Error, ImagerPixelArray.Error => {ok ← FALSE; CONTINUE}];
IF NOT ok THEN RETURN;
IF cd = NIL THEN cd ← ColorTrixBasics.InitCd[gray, TRUE, TRUE, cmapInit];
Display[cd, pa, ImagerColorOperator.GrayLinearColorModel[255, 0]];
};
View8BitFile: PROC [
name: ROPE, cd: Imager.Context ← NIL, dither: BOOLTRUE, cmapInit: BOOLTRUE]
RETURNS [ok: BOOLTRUE]
~ {
ais: AIS.FRef ← AIS.OpenFile[name];
raster: AIS.Raster ← AIS.ReadRaster[ais];
IF raster.bitsPerPixel # 8 THEN ok ← FALSE
ELSE {
vt: Terminal.Virtual ← IF cd = NIL
THEN ColorTrixBasics.SetVtMode[IF dither THEN dither ELSE gray]
ELSE InterminalBackdoor.terminal;
w: AIS.WRef ← AIS.OpenWindow[ais];
colorDisplay: ImagerPixelMap.PixelMap ←
ImagerOps.PixelMapFromFrameBuffer[Terminal.GetColorFrameBufferA[vt]];
lineMap: ImagerPixelMap.PixelMap ← ImagerPixelMap.Create[3,
[-raster.scanCount/2, -raster.scanLength/2, 1, raster.scanLength]];
lineBufferDesc: AIS.Buffer ← [lineMap.refRep.words, lineMap.refRep.pointer];
colorDisplay ← colorDisplay.ShiftMap[-colorDisplay.sSize/2, -colorDisplay.fSize/2];
IF cd = NIL THEN {
ColorTrixBasics.ClearVt[vt];
IF cmapInit AND dither   THEN ImagerColorMap.SetStandardColorMap[vt];
IF cmapInit AND NOT dither THEN ImagerColorMap.SetStandardGrayMap[vt];
Terminal.TurnOnColorDisplay[vt]
};
FOR i: INT IN [0..raster.scanCount) DO
TRUSTED {AIS.UnsafeReadLine[w, lineBufferDesc, i]};
colorDisplay.Transfer[lineMap];
lineMap.sOrigin ← lineMap.sOrigin + 1;
Process.CheckForAbort[];
ENDLOOP;
AIS.CloseWindow[w];
};
AIS.CloseFile[ais];
};
ViewColorFiles: PUBLIC PROC [r, g, b: ROPE, cmapInit: BOOLTRUE]
RETURNS [ok: BOOLTRUE] ~ {
pa: ImagerPixelArray.PixelArray;
pa ← ImagerPixelArray.Join3AIS[r, g, b !
FS.Error, ImagerPixelArray.Error => {ok ← FALSE; CONTINUE}];
IF ok THEN Display[ColorTrixBasics.InitCd[color, TRUE, TRUE, cmapInit], pa, ImagerColorOperator.RGBLinearColorModel[255]];
};
IpOpenFailed: ERROR = CODE;
LogError: Interpress.LogProc ~ {
WITH ProcessProps.GetProp[$CommanderHandle] SELECT FROM
cmd: Commander.Handle =>
IO.PutRope[cmd.err, Rope.Concat["\n Interpress error: ", explanation]];
ENDCASE => NULL;
IF class = masterError THEN ERROR IpOpenFailed;
};
OpenInterpress: PUBLIC PROC [name: ROPE]
RETURNS [master: Interpress.OpenMaster] ~ {
master ← Interpress.Open[name, LogError ! IpOpenFailed => {master ← NIL; CONTINUE}];
};
Parsing Procedures:
Parse: PUBLIC PROC [name: ROPE] RETURNS [type: ColorTrixFile.FileType ← bad, name1, name2, name3: ROPENIL] ~ {
ok: BOOL;
ext: ROPE ← GetSuffix[name];
Test: PROC [x: ROPE] RETURNS [BOOL] ~ { RETURN[ext.Equal[x, FALSE]]; };
IF (Test["ip"] OR Test["interpress"]) AND TestIpName[name] THEN RETURN[ip, name];
IF Test["ais"] AND FileExists[name] THEN RETURN [bw, name];
[ok, name1, name2, name3] ← GetColorNames[name]; IF ok THEN {type ← color; RETURN};
IF TestIpName[name.Cat["ip"]] THEN RETURN[ip, name.Cat["ip"],,];
IF TestIpName[name.Cat["interpress"]] THEN RETURN[ip, name.Cat["interpress"]];
};
GetSuffix: PUBLIC PROC [rope: ROPE] RETURNS [ROPE] ~ {
n, len: INT;
n ← len ← rope.Length[]-1;
WHILE n >= 0 AND rope.Fetch[n] # '. DO n ← n-1; ENDLOOP;
RETURN[IF n = len OR n = -1 THEN NIL ELSE rope.Substr[n+1, len]];
};
TestIpName: PROC [name: ROPE] RETURNS [ok: BOOLTRUE] ~ {
s: FS.STREAM;
IF NOT FileExists[name] THEN RETURN[FALSE];
s ← FS.StreamOpen[name ! FS.Error => { ok ← FALSE; CONTINUE}];
IF ok THEN ok ← IPMaster.GetHeader[s, "Interpress/" ! IPMaster.Error => CONTINUE] # NIL;
};
FileExists: PROC [name: ROPE] RETURNS [ok: BOOLTRUE] ~ {
[] ← FS.FileInfo[name ! FS.Error => {ok ← FALSE; CONTINUE}];
};
AisSuffix: PROC [base, suffix: ROPE] RETURNS [name: ROPE] ~ {
name ← IO.PutFR["%g-%g.ais", IO.rope[base], IO.rope[suffix]];
};
FileChoice: PROC [r: ROPE, a: ROPENIL, b: ROPENIL, c: ROPENIL]
RETURNS [result: ROPE] ~ {
IF FileExists[result ← AisSuffix[r, a]] THEN RETURN;
IF b = NIL THEN RETURN[NIL];
IF FileExists[result ← AisSuffix[r, b]] THEN RETURN;
IF c = NIL THEN RETURN[NIL];
IF NOT FileExists[result ← AisSuffix[r, c]] THEN RETURN[NIL];
};
GetColorNames: PROC [name: ROPE] RETURNS [ok: BOOL, red, grn, blu: ROPE] ~ {
red ← FileChoice[name, "red", "r"];
IF red = NIL THEN { ok ← FALSE; RETURN};
grn ← FileChoice[name, "grn", "green", "g"];
IF grn = NIL THEN { ok ← FALSE; RETURN};
blu ← FileChoice[name, "blu", "blue", "b"];
ok ← blu # NIL;
};
}.
..
Notes:
May wish to add functionality for standard (640 by 480) resolution, in particular, true color display of AIS files.
May wish to make allocation of Color Display only if NOT WindowManager.colorDisplayOn.