ColorTrixBasicsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Plass and Bloomenthal, December 4, 1986 9:27:40 pm PST
ColorTrixBasicsImpl:
CEDAR
MONITOR
IMPORTS ColorDisplay, Draw2d, Imager, ImagerColorMap, ImagerOps, ImagerPixelMap, ImagerRaster, ImagerSample, ImagerSmooth, ImagerTerminal, InterminalBackdoor, PixelMapOps, Process, RuntimeError, Terminal
EXPORTS ColorTrixBasics
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;
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 ANY ← NIL] ~ {
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
ANY ←
NIL] ~ {
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 ANY ← NIL] ~ {
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 ANY ← NIL] ~ {
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:
BOOL ←
TRUE, clear:
BOOL ←
FALSE, cmapInit:
BOOL ←
TRUE]
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:
BOOL ←
TRUE, cmapInit:
BOOL ←
TRUE]
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:
BOOL ←
FALSE, cmapInit:
BOOL ←
TRUE]
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:
BOOL ←
TRUE, cmapInit:
BOOL ←
TRUE]
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];
};