ColorTrixBasicsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Plass and Bloomenthal, December 4, 1986 9:27:40 pm PST
DIRECTORY Basics, ColorTrixBasics, ColorDisplay, Draw2d, Imager, ImagerColorMap, ImagerOps, ImagerPixelMap, ImagerRaster, ImagerSample, ImagerSmooth, ImagerTerminal, InterminalBackdoor, PixelMapOps, Process, Rope, RuntimeError, Terminal, Vector2;
ColorTrixBasicsImpl: CEDAR MONITOR
IMPORTS ColorDisplay, Draw2d, Imager, ImagerColorMap, ImagerOps, ImagerPixelMap, ImagerRaster, ImagerSample, ImagerSmooth, ImagerTerminal, InterminalBackdoor, PixelMapOps, Process, RuntimeError, Terminal
EXPORTS ColorTrixBasics
~ BEGIN
DeviceRectangle:  TYPE ~ ImagerPixelMap.DeviceRectangle;
PixelMap:     TYPE ~ ImagerPixelMap.PixelMap;
PixelMapMisc:   TYPE ~ ColorTrixBasics.PixelMapMisc;
VtMode:     TYPE ~ ColorTrixBasics.VtMode;
PixelProc:     TYPE ~ ColorTrixBasics.PixelProc;
ValueProc:    TYPE ~ ColorTrixBasics.ValueProc;
RGBProc:     TYPE ~ ColorTrixBasics.RGBProc;
screenPixelsPerMeter: REAL ← 72/0.0254;
ColorDisplayNotReady: PUBLIC ERROR = CODE;
Support Procedures
OrderBox: PROC [x0, y0, x1, y1: INTEGER] RETURNS [INTEGER,INTEGER,INTEGER,INTEGER] ~ {
IF x0 > x1 THEN {t: INTEGER ← x0; x0 ← x1; x1 ← t};
IF y0 > y1 THEN {t: INTEGER ← y0; y0 ← y1; y1 ← t};
RETURN[x0, y0, x1, y1];
};
Miscellaneous Operations
InsureColorDisplayOn: PUBLIC PROC [bpp: NAT] ~ {
on, onLeft, gray: BOOL;
bppA, bppB: CARDINAL;
monitorType: Rope.ROPE;
[on, onLeft, gray, bppA, bppB, monitorType] ← ColorDisplay.GetColorDisplayStatus[];
IF NOT on OR bppA # bpp THEN {
IF bpp = 24 THEN {monitorType ← "640x480"; gray ← FALSE};
ColorDisplay.SetColorDisplayStatus[TRUE, onLeft, gray, bpp, bppB, monitorType];
};
};
8 Bit Pixel Map Operations
GetColorDisplayPm: PUBLIC PROC RETURNS [pm: PixelMap] ~ {
InsureColorDisplayOn[8];
pm ← ImagerOps.PixelMapFromFrameBuffer[
Terminal.GetColorFrameBufferA[InterminalBackdoor.terminal]];
};
ShowPm: PUBLIC PROC [pm: PixelMap] ~ {
ImagerPixelMap.Transfer[GetColorDisplayPm[], pm];
};
FillPm: PUBLIC PROC [pm: PixelMap, color: CARDINAL] ~ {
ImagerPixelMap.Fill[pm, [pm.sMin, pm.fMin, pm.sSize, pm.fSize], color];
};
PutPixel: PUBLIC PROC [pm: PixelMap, x, y: INTEGER, value: CARDINAL] ~ {
ImagerPixelMap.PutPixel[pm, y, x, value ! RuntimeError.BoundsFault => CONTINUE];
};
GetPixel: PUBLIC PROC [pm: PixelMap, x, y: INTEGER] RETURNS [value: CARDINAL] ~ {
RETURN[ImagerPixelMap.GetPixel[pm, y, x ! RuntimeError.BoundsFault => CONTINUE]];
};
PutBox: PUBLIC PROC [pm: PixelMap, x0, y0, x1, y1: INTEGER, value: CARDINAL] ~ {
[x0, y0, x1, y1] ← OrderBox[x0, y0, x1, y1];
ImagerPixelMap.Fill[pm, [y0, x0, y1-y0+1, x1-x0+1], value];
};
PutLine: PUBLIC PROC [pm: PixelMap, x0, y0, x1, y1: INTEGER, value: CARDINAL] ~ {
proc: PixelProc ~ {
ImagerPixelMap.PutPixel[pm, y, x, value ! RuntimeError.BoundsFault => CONTINUE];
};
Draw2d.DoWithLine[[x0, y0], [x1, y1], proc];
};
PutScanLine: PUBLIC PROC [
pm: PixelMap, y: INTEGER, proc: ValueProc, data: REF ANYNIL] ~ {
line: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pm.fSize];
FOR x: NAT IN [0..pm.fSize) DO
line.samples[x] ← proc[x, y, data];
ENDLOOP;
PixelMapOps.PutF[pm, y, 0, line, 0, 0, pm.fSize, null, null];
ImagerSample.ReleaseScratchBuffer[line];
};
PutFrame: PUBLIC PROC [pm: PixelMap, proc: ValueProc, data: REF ANYNIL] ~ {
line: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pm.fSize];
FOR y: NAT IN [0..pm.sSize) DO
Process.CheckForAbort[];
FOR x: NAT IN [0..pm.fSize) DO
line.samples[x] ← proc[x, y, data];
ENDLOOP;
PixelMapOps.PutF[pm, y, 0, line, 0, 0, pm.fSize, null, null];
ENDLOOP;
ImagerSample.ReleaseScratchBuffer[line];
};
24 Bit Pixel Map Operations
FillRGBPm: PUBLIC PROC [pmMisc: PixelMapMisc, r, g, b: CARDINAL] ~ {
IF pmMisc.bpp # 24 THEN RETURN;
FillPm[pmMisc.rg, 256*r+g];
FillPm[pmMisc.b, b];
};
PutRGBPixel: PUBLIC PROC [pmMisc: PixelMapMisc, x, y: INTEGER, r, g, b: CARDINAL] ~ {
IF pmMisc.bpp # 24 THEN RETURN;
ImagerPixelMap.PutPixel[pmMisc.rg, y, x, 256*r+g ! RuntimeError.BoundsFault => CONTINUE];
ImagerPixelMap.PutPixel[pmMisc.b, y, x, b ! RuntimeError.BoundsFault => CONTINUE];
};
GetRGBPixel: PUBLIC PROC [pmMisc: PixelMapMisc, x, y: INTEGER]
RETURNS [r, g, b: CARDINAL] ~ {
IF pmMisc.bpp = 24 THEN {
rg: CARDINAL;
rg ← ImagerPixelMap.GetPixel[pmMisc.rg, y, x ! RuntimeError.BoundsFault => CONTINUE];
r ← rg/256;
g ← rg MOD 256;
b ← ImagerPixelMap.GetPixel[pmMisc.b, y, x ! RuntimeError.BoundsFault => CONTINUE];
};
};
PutRGBBox: PUBLIC PROC [
pmMisc: PixelMapMisc, x0, x1, y0, y1: INTEGER, r, g, b: CARDINAL] ~ {
IF pmMisc.bpp # 24 THEN RETURN;
[x0, y0, x1, y1] ← OrderBox[x0, y0, x1, y1];
ImagerPixelMap.Fill[pmMisc.rg, [y0, x0, y1-y0+1, x1-x0+1], 256*r+g];
ImagerPixelMap.Fill[pmMisc.b, [y0, x0, y1-y0+1, x1-x0+1], b];
};
PutRGBLine: PUBLIC PROC [
pmMisc: PixelMapMisc, x0, x1, y0, y1: INTEGER, r, g, b: CARDINAL] ~ {
proc: PixelProc ~ {
ImagerPixelMap.PutPixel[
pmMisc.rg, y, x, 256*r+g ! RuntimeError.BoundsFault => CONTINUE];
ImagerPixelMap.PutPixel[pmMisc.b, y, x, b ! RuntimeError.BoundsFault => CONTINUE];
};
IF pmMisc.bpp = 24 THEN Draw2d.DoWithLine[[x0, y0], [x1, y1], proc];
};
PutRGBScanLine: PUBLIC PROC [
pmMisc: PixelMapMisc, y: INTEGER, proc: RGBProc, data: REF ANYNIL] ~ {
IF pmMisc.bpp = 24 THEN {
rgLine: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pmMisc.w];
bLine: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pmMisc.w];
FOR x: NAT IN [0..pmMisc.w) DO
r, g: CARDINAL;
[r, g, bLine.samples[x]] ← proc[x, y, data];
rgLine.samples[x] ← 256*r+g;
ENDLOOP;
PixelMapOps.PutF[pmMisc.rg, y, 0, rgLine, 0, 0, pmMisc.w, null, null];
PixelMapOps.PutF[pmMisc.b, y, 0, bLine, 0, 0, pmMisc.w, null, null];
ImagerSample.ReleaseScratchBuffer[rgLine];
ImagerSample.ReleaseScratchBuffer[bLine];
};
};
PutRGBFrame: PUBLIC PROC [
pmMisc: PixelMapMisc, proc: RGBProc, data: REF ANYNIL] ~ {
IF pmMisc.bpp = 24 THEN {
rgLine: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pmMisc.w];
bLine: ImagerSample.SampleBuffer ~ ImagerSample.ObtainScratchBuffer[1, pmMisc.w];
FOR y: NAT IN [0..pmMisc.h) DO
Process.CheckForAbort[];
FOR x: NAT IN [0..pmMisc.w) DO
r, g: CARDINAL;
[r, g, bLine.samples[x]] ← proc[x, y, data];
rgLine.samples[x] ← 256*r+g;
ENDLOOP;
PixelMapOps.PutF[pmMisc.rg, y, 0, rgLine, 0, 0, pmMisc.w, null, null];
PixelMapOps.PutF[pmMisc.b, y, 0, bLine, 0, 0, pmMisc.w, null, null];
ENDLOOP;
ImagerSample.ReleaseScratchBuffer[rgLine];
ImagerSample.ReleaseScratchBuffer[bLine];
};
};
PixelMapMisc Operations
GetColorDisplayPmMisc: PUBLIC PROC RETURNS [pmMisc: PixelMapMisc] ~ {
on: BOOL;
window: DeviceRectangle;
[on: on, bpp: pmMisc.bpp] ← ColorDisplay.GetColorDisplayStatus[];
IF NOT on THEN ColorDisplay.SetColorDisplayStatus[on: TRUE];
SELECT pmMisc.bpp FROM
8 => window ← ImagerPixelMap.Window[pmMisc.bw ← GetColorDisplayPm[]];
24 => {
pmMisc.rg ← ImagerOps.PixelMapFromFrameBuffer[
Terminal.GetColorFrameBufferA[InterminalBackdoor.terminal]];
pmMisc.b ← ImagerOps.PixelMapFromFrameBuffer[
Terminal.GetColorFrameBufferB[InterminalBackdoor.terminal]];
window ← ImagerPixelMap.Window[pmMisc.rg];
};
ENDCASE;
pmMisc.x ← window.fMin;
pmMisc.y ← window.sMin;
pmMisc.w ← window.fSize;
pmMisc.h ← window.sSize;
};
ShowPmMisc: PUBLIC PROC [pmMisc: PixelMapMisc] ~ {
SELECT pmMisc.bpp FROM
8 => ShowPm[pmMisc.bw];
24 => {
cd: PixelMapMisc;
InsureColorDisplayOn[24];
cd ← GetColorDisplayPmMisc[];
ImagerPixelMap.Transfer[cd.rg, pmMisc.rg];
ImagerPixelMap.Transfer[cd.b, pmMisc.b];
};
ENDCASE;
};
SetPmMiscWindow: PUBLIC PROC [pm: PixelMapMisc, x, y, w, h: NAT]
RETURNS [PixelMapMisc] ~ {
pm.x ← x;
pm.y ← y;
pm.w ← w;
pm.h ← h;
SELECT pm.bpp FROM
8 => pm.bw ← ImagerPixelMap.SetWindow[pm.bw, [y, x, h, w]];
24 => {
pm.rg ← ImagerPixelMap.SetWindow[pm.rg, [y, x, h, w]];
pm.b ← ImagerPixelMap.SetWindow[pm.b, [y, x, h, w]];
};
ENDCASE;
RETURN[pm];
};
FillPmMisc: PUBLIC PROC [pm: PixelMapMisc, r, g, b: CARDINAL ← 0] ~ {
SELECT pm.bpp FROM
8 => FillPm[pm.bw, r];
24 => FillRGBPm[pm, r, g, b];
ENDCASE;
};
WindowFromPmMisc: PUBLIC PROC [pm: PixelMapMisc] RETURNS [DeviceRectangle] ~ {
RETURN[[pm.y, pm.x, pm.h, pm.w]];
};
CreatePmMisc: PUBLIC PROC [bpp, x, y, w, h: NAT] RETURNS [pm: PixelMapMisc] ~ {
window: DeviceRectangle ~ [pm.y ← y, pm.x ← x, pm.h ← h, pm.w ← w];
SELECT pm.bpp ← bpp FROM
8 => pm.bw ← ImagerPixelMap.Create[3, window];
24 => {
pm.rg ← ImagerPixelMap.Create[4, window];
pm.b ← ImagerPixelMap.Create[3, window];
};
ENDCASE;
};
CopyPmMisc: PUBLIC PROC [src, dst: PixelMapMisc] ~ {
SELECT dst.bpp FROM
8 => ImagerPixelMap.Transfer[dst.bw, src.bw];
24 => {
ImagerPixelMap.Transfer[dst.rg, src.rg];
ImagerPixelMap.Transfer[dst.b, src.b];
};
ENDCASE;
};
CopyClippedPmMisc: PUBLIC PROC [src, dst: PixelMapMisc, xSrc, ySrc, w, h: NAT] ~ {
Inner: PROC [src, dst: PixelMap] ~ {
src ← ImagerPixelMap.Clip[src, [ySrc, xSrc, h, w]];
ImagerPixelMap.Transfer[dst, ImagerPixelMap.ShiftMap[src, dst.sMin-ySrc, dst.fMin-xSrc]];
};
SELECT src.bpp FROM
8 => Inner[src.bw, dst.bw];
24 => {
Inner[src.rg, dst.rg];
Inner[src.b, dst.b];
};
ENDCASE;
};
Imager Context Operations
InitCd: PUBLIC PROC [type: ColorTrixBasics.CdType, pixelUnits: BOOLTRUE, clear: BOOLFALSE, cmapInit: BOOLTRUE] RETURNS [Imager.Context] ~ {
cd: Imager.Context;
IF NOT ColorDisplay.GetColorDisplayStatus[].on THEN
ColorDisplay.SetColorDisplayStatus[on: TRUE];
cd ← SELECT type FROM
gray => InitGrayCd[InterminalBackdoor.terminal, pixelUnits, cmapInit],
smooth => InitSmoothCd[InterminalBackdoor.terminal, pixelUnits, cmapInit],
color => InitColorCd[InterminalBackdoor.terminal, pixelUnits, cmapInit],
ENDCASE => NIL;
IF clear AND cd # NIL THEN ClearCd[cd];
RETURN[cd];
};
InitGrayCd: PROC [vt: Terminal.Virtual ← InterminalBackdoor.terminal, pixelUnits: BOOLTRUE, cmapInit: BOOLTRUE] RETURNS [cd: Imager.Context] ~ {
[] ← SetVtMode[gray];
cd ← ImagerRaster.Create[              -- the color display
ImagerRaster.NewGrayDevice[vt],
TRUE, NIL, 0];
IF cmapInit THEN ImagerColorMap.SetStandardGrayMap[vt];    -- g corrected cmap
IF NOT pixelUnits THEN Imager.ScaleT[cd, screenPixelsPerMeter];
};
InitSmoothCd: PROC [vt: Terminal.Virtual ← InterminalBackdoor.terminal, pixelUnits: BOOLFALSE, cmapInit: BOOLTRUE] RETURNS [cd: Imager.Context] ~ {
cd ← ImagerSmooth.Create[
ImagerOps.PixelMapFromFrameBuffer[Terminal.GetColorFrameBufferA[vt]],
$Intensity,
ImagerSmooth.LikeScreen[vt.colorHeight],
IF pixelUnits THEN 1.0 ELSE screenPixelsPerMeter];
IF cmapInit THEN ImagerColorMap.SetStandardGrayMap[vt];    -- g corrected cmap
};
InitColorCd: PROC [vt: Terminal.Virtual ← InterminalBackdoor.terminal, pixelUnits: BOOLTRUE, cmapInit: BOOLTRUE] RETURNS [cd: Imager.Context] ~ {
[] ← SetVtMode[dither];
cd ← ImagerTerminal.ColorContext[vt, TRUE];
IF cmapInit THEN ImagerColorMap.SetStandardColorMap[vt];    -- dither colormap
IF NOT pixelUnits THEN Imager.ScaleT[cd, screenPixelsPerMeter];
};
ClearCd: PUBLIC PROC [cd: Imager.Context, color: Imager.ConstantColor ← Imager.black] ~ {
Imager.SetColor[cd, color];              -- clear buffer
Imager.MaskRectangle[cd, [0, 0, 1024, 768]];         -- visibilize
Terminal.TurnOnColorDisplay[InterminalBackdoor.terminal];
};
ClearVt: PUBLIC PROC [vt: Terminal.Virtual ← NIL, val: INTEGER ← 0] ~ {
pm: PixelMap;
IF vt = NIL THEN vt ← InterminalBackdoor.terminal;
pm ← ImagerOps.PixelMapFromFrameBuffer[Terminal.GetColorFrameBufferA[vt: vt]];
ImagerPixelMap.Fill[pm, ImagerPixelMap.Window[pm], val];
};
Miscellaneous
SetVtMode: PUBLIC PROC [vtMode: VtMode] RETURNS [Terminal.Virtual] ~ {
ENABLE UNWIND => NULL;
vt: Terminal.Virtual ← InterminalBackdoor.terminal;
IF NOT vt.hasColorDisplay THEN ERROR ColorDisplayNotReady;
IF vtMode = gray
THEN ColorDisplay.SetColorDisplayStatus[on: TRUE, gray: TRUE, bpp: 8]
ELSE ColorDisplay.SetColorDisplayStatus[on: TRUE];
RETURN[InterminalBackdoor.terminal];
};
END.
..