ImagerColorTestMainImpl.mesa
Authored by Frank Crow
Last Edited by: Crow, May 21, 1984 8:16:19 am PDT
Last Edited by: Hiller, September 7, 1984 0:09:05 am PDT
Copyright (C) 1984 by Xerox Corporation. All rights reserved.
DIRECTORY       
Basics     USING [BITSHIFT],
ColorNames   USING [HSLToRope],
ConstantColors  USING [NameToColor, RGBToColor, ColorToName, HSLToColor],
Graphics    USING [Context],
Imager    USING [Context, Create, FONT, MakeFont, MaskRectangle,
         MaskVector, SetColor, Pair, SetXY,
         ShowCharacters, SetFont, SpecialOp],
ImagerColorAIS  USING [GetAISFile, Get3AISFiles, PutAISFile, PutFastAISFile],
ImagerBasic   USING [IntRectangle],
ImagerDisplay  USING [DisplayData],
ImagerDisplayExtras USING [RGBSequence],
ImagerPixelMaps  USING [PixelMap, BoundedWindow, DeviceRectangle],
ImagerPixelMapsExtras USING [FillTrap, DrawLine, DrawBltLine],
IO      USING [PutRope, PutF, STREAM, int],
QuickViewer   USING [DrawInViewer, BuildViewer],
Real     USING [FixI, FixC],
RealFns    USING [Power],
Rope     USING [ROPE],
ViewerIO    USING [CreateViewerStreams],
ImagerColorTestMain;
ImagerColorTestMainImpl: CEDAR PROGRAM
IMPORTS Basics, ColorNames, ConstantColors, Imager, ImagerColorAIS, ImagerPixelMaps, ImagerPixelMapsExtras, IO, QuickViewer, Real, RealFns, ViewerIO
EXPORTS ImagerColorTestMain
= BEGIN
displayContext: Imager.Context ← NIL;
contexts: ARRAY [0..10) OF Imager.Context ← ALL[NIL];
contextCount: NAT ← 0;
in, out: IO.STREAM;         -- I/O to log viewer
nullRectangle: ImagerBasic.IntRectangle ← [0, 0, 0, 0];
activeButton: ATOM;
GetDisplayContext: PUBLIC PROC RETURNS[ Imager.Context] ~ {
RETURN[ displayContext];
};
GetDisplayData: PUBLIC PROC RETURNS[ ImagerDisplay.DisplayData] ~ {
RETURN[ NARROW[displayContext.data, ImagerDisplay.DisplayData]];
};
NameColor: PUBLIC PROC [color: Rope.ROPE] ~ {
Imager.SetColor[displayContext, ConstantColors.NameToColor[color]];
};
RGBColor: PUBLIC PROC [r, g, b: REAL] ~ {
Imager.SetColor[displayContext, ConstantColors.RGBToColor[r, g, b]];
};
HSLToName: PUBLIC PROC [h, s, l: REAL] ~ {
name: Rope.ROPE;
name ← ConstantColors.ColorToName[ConstantColors.HSLToColor[h, s, l]];
IO.PutRope[out, name];
IO.PutF[out, "\n"];
};
HSLToLongName: PUBLIC PROC [h, s, l: REAL, levels: NAT] ~ {
name: Rope.ROPE;
name ← ColorNames.HSLToRope[h, s, l, levels];
IO.PutRope[out, name];
IO.PutF[out, "\n"];
};
LoadAndRotate8BitMap: PUBLIC PROC [duration: NAT] ~ {
start: REF NATNEW[NAT];
length: NAT ← 512;
entries: REF ImagerDisplayExtras.RGBSequence ← NEW[
               ImagerDisplayExtras.RGBSequence[length] ];
data: LIST OF REF ANYNIL;
start^ ← 1;
FOR i: NAT IN [0..40) DO              -- greyscale
entries[i + 216].r ← entries[i + 216].g ← entries[i + 216].b ← i*6;
entries[i + 471].r ← entries[i + 471].g ← entries[i + 471].b ← 255 - i*6;
ENDLOOP;
FOR i: NAT IN [0..216) DO          -- 6 x 6 x 6 color cube
entries[i].r ← 36 * (i/36 + 1);     entries[i + 255].r ← 255 - entries[i].r;
entries[i].g ← 36 * ((i/6) MOD 6 + 1); entries[i + 255].g ← 255 - entries[i].g;
entries[i].b ← 36 * (i MOD 6 + 1);   entries[i + 255].b ← 255 - entries[i].b;
ENDLOOP;
data ← CONS[start, data];
data ← CONS[entries, data];
[] ← Imager.SpecialOp[displayContext, $LoadColorMap, data];
FOR i: NAT IN [0..duration*60) DO
color: RECORD[ r, g, b: [0..256) ] ← [ entries[1].r, entries[1].g, entries[1].b ];
FOR j: NAT IN [2..length) DO entries[j-1] ← entries[j]; ENDLOOP;
entries[length-1] ← [ color.r, color.g, color.b ];
[] ← Imager.SpecialOp[displayContext, $LoadColorMap, data];
ENDLOOP;
};
LoadGrey8BitMap: PUBLIC PROC [] ~ {
start: REF NATNEW[NAT];
length: NAT ← 512;
entries: REF ImagerDisplayExtras.RGBSequence ← NEW[
               ImagerDisplayExtras.RGBSequence[length] ];
data: LIST OF REF ANYNIL;
start^ ← 0;
FOR i: NAT IN [0..256) DO          -- greyscale
j: NAT ← Real.FixC[RealFns.Power[i/256.0, .43] * 256.0];
entries[i].r ← j;    entries[i + 255].r ← 255 - entries[i].r;
entries[i].g ← j;   entries[i + 255].g ← 255 - entries[i].g;
entries[i].b ← j;   entries[i + 255].b ← 255 - entries[i].b;
ENDLOOP;
data ← CONS[start, data];
data ← CONS[entries, data];
[] ← Imager.SpecialOp[displayContext, $LoadColorMap, data];
};
FillRectangle: PUBLIC PROC [x, y, w, h: REAL] ~ {
Imager.MaskRectangle[displayContext, x, y, w, h];
};
FillTrap: PUBLIC PROC [top, bottom, leftTop, leftBot, rightTop, rightBot: INTEGER, color: NAT] ~ {
displayData: ImagerDisplay.DisplayData ← NARROW[displayContext.data,
               ImagerDisplay.DisplayData];
ImagerPixelMapsExtras.FillTrap[displayData[0],
         top, bottom, leftTop, leftBot, rightTop, rightBot, color];
};
DrawLine: PUBLIC PROC [pt1, pt2: Imager.Pair, width: REAL] ~ {
Imager.MaskVector[displayContext, pt1, pt2, width];
};
DrawGrid: PUBLIC PROC[boxWidth: NAT] ~ {
ax, ay, bx, by: INTEGER;
displayData: ImagerDisplay.DisplayData ← NARROW[displayContext.data,
               ImagerDisplay.DisplayData];
window: ImagerPixelMaps.DeviceRectangle;
window ← ImagerPixelMaps.BoundedWindow[displayData[0]];
FOR i: NAT IN [0..window.fSize/boxWidth] DO
ax ← window.sMin;    ay ← window.fMin + i*boxWidth;
bx ← window.sMin + window.sSize;  by ← window.fMin + i*boxWidth;
ImagerPixelMapsExtras.DrawLine[displayData[0], [ay, ax], [by, bx], 0];
ENDLOOP;
FOR i: NAT IN [0..window.sSize/boxWidth] DO
ax ← window.sMin + i*boxWidth;    ay ← window.fMin;
bx ← window.sMin + i*boxWidth;  by ← window.fMin + window.fSize;
ImagerPixelMapsExtras.DrawLine[displayData[0], [ay, ax], [by, bx], 0];
ENDLOOP;
};
LineTest: PUBLIC PROC[color: CARDINAL, length, times: NAT] ~ {
ax, ay, bx, by, xOffset, yOffset: INTEGER;
displayData: ImagerDisplay.DisplayData ← NARROW[displayContext.data,
               ImagerDisplay.DisplayData];
logBitsPerPixel: NAT ← displayData[0].refRep.lgBitsPerPixel;
mapLength: NAT ← Basics.BITSHIFT[1, Basics.BITSHIFT[1, logBitsPerPixel]];
xMax: NAT ← displayData[0].fSize; yMax: NAT ← displayData[0].sSize;
IF length > yMax THEN length ← yMax;
xOffset ← (xMax - length) / 2; yOffset ← (yMax - length) / 2;
FOR i: NAT IN [0..times) DO
FOR j: NAT IN [0..length] DO
ax ← j + xOffset;    ay ← length + yOffset;
bx ← length + xOffset;  by ← length - j + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawLine[displayData[0], [ax, ay], [bx, by], color];
ENDLOOP;
FOR j: NAT IN [0..length] DO
ax ← length + xOffset;  ay ← length - j + yOffset;
bx ← length - j + xOffset; by ← 0 + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawLine[displayData[0], [ax, ay], [bx, by], color];
ENDLOOP;
FOR j: NAT IN [0..length] DO
ax ← length - j + xOffset; ay ← 0 + yOffset;
bx ← 0 + xOffset;    by ← j + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawLine[displayData[0], [ax, ay], [bx, by], color];
ENDLOOP;
FOR j: NAT IN [0..length] DO
ax ← 0 + xOffset;    ay ← j + yOffset;
bx ← j + xOffset;    by ← length + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawLine[displayData[0], [ax, ay], [bx, by], color];
ENDLOOP;
ENDLOOP;
};
BltLineTest: PUBLIC PROC[color: CARDINAL, length, times: NAT] ~ {
ax, ay, bx, by, xOffset, yOffset: INTEGER;
displayData: ImagerDisplay.DisplayData ← NARROW[displayContext.data,
               ImagerDisplay.DisplayData];
logBitsPerPixel: NAT ← displayData[0].refRep.lgBitsPerPixel;
mapLength: NAT ← Basics.BITSHIFT[1, Basics.BITSHIFT[1, logBitsPerPixel]];
xMax: NAT ← displayData[0].fSize; yMax: NAT ← displayData[0].sSize;
IF length > yMax THEN length ← yMax;
xOffset ← (xMax - length) / 2; yOffset ← (yMax - length) / 2;
FOR i: NAT IN [0..times) DO
FOR j: NAT IN [0..length] DO
ax ← j + xOffset;    ay ← length + yOffset;
bx ← length + xOffset;  by ← length - j + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawBltLine[displayData[0], [ax, ay], [bx, by], color, [xor, null]];
ENDLOOP;
FOR j: NAT IN [0..length] DO
ax ← length + xOffset;  ay ← length - j + yOffset;
bx ← length - j + xOffset; by ← 0 + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawBltLine[displayData[0], [ax, ay], [bx, by], color, [xor, null]];
ENDLOOP;
FOR j: NAT IN [0..length] DO
ax ← length - j + xOffset; ay ← 0 + yOffset;
bx ← 0 + xOffset;    by ← j + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawBltLine[displayData[0], [ax, ay], [bx, by], color, [xor, null]];
ENDLOOP;
FOR j: NAT IN [0..length] DO
ax ← 0 + xOffset;    ay ← j + yOffset;
bx ← j + xOffset;    by ← length + yOffset;
color ← (color MOD mapLength) + 1;
ImagerPixelMapsExtras.DrawBltLine[displayData[0], [ax, ay], [bx, by], color, [xor, null]];
ENDLOOP;
ENDLOOP;
};
ShowRope: PUBLIC PROC[x, y: REAL, rope: Rope.ROPE, fontRope: Rope.ROPENIL, size: REAL ← .008] ~ {
font: Imager.FONT;
IF fontRope = NIL THEN fontRope ← "Xerox/Pressfonts/TimesRoman/MRR";
font ← Imager.MakeFont[fontRope, size];
Imager.SetFont[displayContext, font];
Imager.SetXY[displayContext, [x, y]];
Imager.ShowCharacters[displayContext, rope, ];
};
SetDevice: PUBLIC PROC[deviceType: ATOM, box: ImagerBasic.IntRectangle] ~{
IF box = nullRectangle THEN displayContext ← Imager.Create[deviceType]
ELSE {
refBox: REF ImagerBasic.IntRectangle ← NEW[ImagerBasic.IntRectangle];
refPinned: REF BOOLEANNEW[BOOLEANFALSE];  -- don't pin this pixelmap
creationList: LIST OF REF ANYLIST[refBox, refPinned];
refBox.x ← box.x; refBox.y ← box.y; refBox.w ← box.w; refBox.h ← box.h;
displayContext ← Imager.Create[deviceType, creationList];
};
contexts[contextCount] ← displayContext;
contextCount ← contextCount + 1;
NameColor["Black"];
FillRectangle[0.0, 0.0, .26, .2];    -- clear screen
};
RecoverContext: PUBLIC PROC[contextNumber: NAT] ~ {
displayContext ← contexts[contextNumber];
};
PinMap: PUBLIC PROC[] ~ {
[] ← Imager.SpecialOp[displayContext, $DisplayContext, NIL];
};
PinOverlay: PUBLIC PROC[] ~ {
[] ← Imager.SpecialOp[displayContext, $OverlayContext, NIL];
};
GetAISFile: PUBLIC PROC[fileName: Rope.ROPE, xOffSet, yOffSet: INTEGER ← 0] ~ {
ImagerColorAIS.GetAISFile[displayContext, fileName, xOffSet, yOffSet];
};
Get3AISFiles: PUBLIC PROC[redFile, greenFile, blueFile: Rope.ROPE,
         xOffSet, yOffSet: INTEGER ← 0] ~ {
ImagerColorAIS.Get3AISFiles[displayContext, redFile, greenFile, blueFile, xOffSet, yOffSet];
};
PutAISFile: PUBLIC PROC[fileName: Rope.ROPE] ~ {
ImagerColorAIS.PutAISFile[displayContext, fileName];
};
PutFastAISFile: PUBLIC PROC[fileName: Rope.ROPE] ~ {
ImagerColorAIS.PutFastAISFile[displayContext, fileName];
};
DrawX: PUBLIC PROC[x, y, size: REAL] ~ {
DoDrawX: PUBLIC PROC [dc: Graphics.Context] ~ {
DrawLine[[x, y], [x+size, y+size], size/10.0];
DrawLine[[x+size, y], [x, y+size], size/10.0];
};
QuickViewer.DrawInViewer[DoDrawX];  -- ask the viewer procs to call you back
};
MenuHit: PROCEDURE[command: ATOM, x, y: REAL] = { 
SELECT command FROM
$Button => activeButton ← NIL;
$MoveDCB => { activeButton ← $MoveDCB; IO.PutF[out, "Button received\n"]; };
$Boxes, $Circles, $Exes, $Octagons => drawMode ← command;
$LeftButton, $LeftHeld => { pointList ← CONS[ [x, y], pointList];
         SELECT drawMode FROM
         $Exes  => DrawX[pointList.first, size, black];
         $Boxes => DrawBox[pointList.first, size, black];
         $Circles => DrawCircle[pointList.first, size, black];
         $Octagons => DrawOct[pointList.first, size, black];
           ENDCASE;
        };
$MiddleButton => DrawX[[x, y], size, black];
$RightButton => DrawCircle[[x, y], size, black];
$MiddleHeld  => DrawX[[x, y], size, white];
$RightHeld  => IF activeButton = $MoveDCB THEN {
displayData: ImagerDisplay.DisplayData ← NARROW[contexts[0].data,
               ImagerDisplay.DisplayData];
displayData[0].sOrigin ← 50 + Real.FixI[-y];
displayData[0].fOrigin ← 100 + Real.FixI[x];
displayContext ← contexts[0];
PinMap[];
};
$LeftHeld  => IF activeButton = $MoveDCB THEN {
displayData: ImagerDisplay.DisplayData ← NARROW[contexts[1].data,
               ImagerDisplay.DisplayData];
displayData[0].sOrigin ← 50 + Real.FixI[-y];
displayData[0].fOrigin ← 100 + Real.FixI[x];
displayContext ← contexts[1];
PinOverlay[];
IO.PutF[out, "x = %g, y = %g\n",
        IO.int[displayData[0].fOrigin], IO.int[displayData[0].sOrigin]];
};
ENDCASE;
};
ReDraw:  PROCEDURE [dc: Graphics.Context] = { 
ImagerBridge.SetViewFromGraphicsContext[displayContext, dc];
Display Color Map (first 16)
Yellow   Cyan     Magenta  White
 Very Dark Grey Very Light Grey Grey   Purple
 Orange   Brown   Dark Grey  Light Grey
 Black    Red     Green   Blue
NameColor["Black"];
FillRectangle[0.025, 0.0, .05, .05];
NameColor["Red"];
FillRectangle[0.075, 0.0, .05, .05];
NameColor["Green"];
FillRectangle[0.125, 0.0, .05, .05];
NameColor["Blue"];
FillRectangle[0.175, 0.0, .05, .05];
NameColor["Orange"];
FillRectangle[0.025, 0.05, .05, .05];
NameColor["Brown"];
FillRectangle[0.075, 0.05, .05, .05];
NameColor["Dark Grey"];
FillRectangle[0.125, 0.05, .05, .05];
NameColor["Light Grey"];
FillRectangle[0.175, 0.05, .05, .05];
NameColor["Very Dark Grey"];
FillRectangle[0.025, 0.1, .05, .05];
NameColor["Very Light Grey"];
FillRectangle[0.075, 0.1, .05, .05];
NameColor["Grey"];
FillRectangle[0.125, 0.1, .05, .05];
NameColor["Purple"];
FillRectangle[0.175, 0.1, .05, .05];
NameColor["Yellow"];
FillRectangle[0.025, 0.15, .05, .05];
NameColor["Cyan"];
FillRectangle[0.075, 0.15, .05, .05];
NameColor["Magenta"];
FillRectangle[0.125, 0.15, .05, .05];
NameColor["White"];
FillRectangle[0.175, 0.15, .05, .05];
};
ShutDown: PROCEDURE [] = {
IO.PutF[out, "Imager Color Test over -- Bye\n"];        -- say goodbye
};
Init: PROCEDURE [] = {
QuickViewer.BuildViewer[LIST[$Button, $MoveDCB],
        ReDraw, ShutDown, MenuHit, "ImagerColorTest"];
[in, out] ← ViewerIO.CreateViewerStreams["ImagerColorTest.log"]; -- initialize i/o viewer
};
END.