ColorTrixCommandsImplB.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, December 2, 1986 1:33:18 pm PST
DIRECTORY Args, Atom, Buttons, ChoiceButtons, CedarProcess, ClassIncreek, ColorDisplay, ColorTrixBasics, ColorTrixMap, ColorTrixPrivate, Commander, Containers, Convert, Draw2d, Imager, ImagerBackdoor, ImagerColor, ImagerPixelMap, IO, MessageWindow, Process, Real, Rope, Terminal, TerminalDefs, TextNode, TiogaAccess, TiogaImager, TypeScript, ViewerClasses, ViewerIO, ViewerOps, ViewerTools;
ColorTrixCommandsImplB: CEDAR PROGRAM
IMPORTS Args, Atom, Buttons, ChoiceButtons, CedarProcess, ClassIncreek, ColorDisplay, ColorTrixBasics, ColorTrixMap, Containers, Convert, Draw2d, Imager, ImagerBackdoor, ImagerColor, ImagerPixelMap, IO, MessageWindow, Process, Real, Rope, Terminal, TiogaAccess, TiogaImager, TypeScript, ViewerIO, ViewerOps, ViewerTools
EXPORTS ColorTrixPrivate
~ BEGIN
ROPE:    TYPE ~ Rope.ROPE;
STREAM:   TYPE ~ IO.STREAM;
Viewer:   TYPE ~ ViewerClasses.Viewer;
PixelMap:   TYPE ~ ColorTrixBasics.PixelMap;
PixelMapMisc: TYPE ~ ColorTrixBasics.PixelMapMisc;
Cmap:    TYPE ~ ColorTrixMap.Cmap;
Context:   TYPE ~ Imager.Context;
Color:    TYPE ~ Imager.Color;
CtDif
CtDif: PUBLIC Commander.CommandProc ~ {
Dif: PROC [pm: PixelMap] ~ {
src0: PixelMap ~ ImagerPixelMap.Clip[pm, [y0.int, x0.int, h.int, w.int]];
src1: PixelMap ~ ImagerPixelMap.Clip[pm, [y1.int, x1.int, h.int, w.int]];
dif: PixelMap ~ ImagerPixelMap.Clip[pm, [y2.int, x2.int, h.int, w.int]];
FOR y: INT IN [0..h.int) DO
FOR x: INT IN [0..w.int) DO
src0Value: INTEGER ~ ColorTrixBasics.GetPixel[src0, x+src0.fMin, y+src0.sMin];
src1Value: INTEGER ~ ColorTrixBasics.GetPixel[src1, x+src1.fMin, y+src1.sMin];
ColorTrixBasics.PutPixel[dif, x+dif.fMin, y+dif.sMin, ABS[src0Value-src1Value]];
ENDLOOP;
ENDLOOP;
};
ok: BOOL;
x0, y0, x1, y1, x2, y2, w, h: Args.Arg;
[ok, x0, y0, x1, y1, x2, y2, w, h] ← Args.ArgsGet[cmd, "%iiiiiiii"];
IF NOT ok
THEN RETURN[$Failure, "Bad argument(s)."]
ELSE {
pmMisc: PixelMapMisc ← ColorTrixBasics.GetColorDisplayPmMisc[];
SELECT pmMisc.bpp FROM
8 => Dif[pmMisc.bw];
24 => {
Dif[pmMisc.rg];
Dif[pmMisc.b];
};
ENDCASE;
};
};
CtText
CtTextData:  TYPE ~ REF CtTextDataRec;
CtTextDataRec: TYPE ~ RECORD [
viewer:     Viewer ← NIL,
context:     Context ← NIL,
bounds:     Imager.Rectangle,
x, y, c:     Viewer ← NIL,
printButton:    Viewer ← NIL
];
CtText: PUBLIC Commander.CommandProc ~ {
context: Context ~ ColorTrixBasics.InitCd[smooth, TRUE, FALSE, FALSE];
IF Args.NArgs[cmd] > 0
THEN {
x: Args.Arg ← Args.ArgInt[cmd, 0];
y: Args.Arg ← Args.ArgInt[cmd, 1];
text: Args.Arg ← Args.ArgRope[cmd, 2];
IF NOT x.ok OR NOT y.ok OR NOT text.ok THEN RETURN[$Failure, NIL];
Draw2d.Label[context, [x.int, y.int], text.rope];
}
ELSE {
data: CtTextData ← NEW[CtTextDataRec];
data.context ← context;
data.bounds ← ImagerBackdoor.GetBounds[data.context];
data.viewer ← Containers.Create[
info: [name: "CtText", openHeight: 33, iconic: TRUE, column: right, scrollable: FALSE],
paint: FALSE];
data.x ← ChoiceButtons.BuildTextPrompt[data.viewer, 0, 0, "x:", "0", , 30].textViewer;
data.y ← ChoiceButtons.BuildTextPrompt[data.viewer, 60, 0, "y:", "0", , 30].textViewer;
data.c ← ChoiceButtons.BuildTextPrompt[data.viewer, 120, 0, "color:", "Black", , 50].textViewer;
data.printButton ← Buttons.Create[
info: [parent: data.viewer, name: "Print", wx: 240, wy: 3],
proc: Print,
clientData: data,
paint: TRUE];
ViewerOps.OpenIcon[data.viewer];
};
};
Blink: PROC [rope: Rope.ROPE] ~ {
MessageWindow.Append[rope, TRUE];
MessageWindow.Blink[];
};
Print: Buttons.ButtonProc ~ {
badButton: ERROR;
GetValue: PROC [viewer: Viewer] RETURNS [NAT] ~ {
num: INT;
selection: Rope.ROPE ← ViewerTools.GetContents[viewer];
num ← Convert.IntFromRope[selection ! Convert.Error => ERROR badButton];
IF num < 0 THEN ERROR badButton;
RETURN[num];
};
data: CtTextData ~ NARROW[clientData];
x, y: NAT;
formattedNode: TiogaImager.FormattedNodes;
color: Color ← ImagerColor.ColorFromAtom[Atom.MakeAtom[ViewerTools.GetContents[data.c]]];
reader: TiogaAccess.Reader ~ TiogaAccess.FromSelection[];
location: TextNode.Location ~ [NARROW[TiogaAccess.GetNodeRefs[reader].current], 0];
IF location.node = NIL THEN GOTO BadText;
IF color = NIL THEN GOTO BadColor;
formattedNode ← TiogaImager.FormatNodes[location, [data.bounds.w, data.bounds.h], TRUE];
x GetValue[data.x ! badButton => GOTO BadButton];
y Real.RoundI[data.bounds.h]-GetValue[data.y ! badButton => GOTO BadButton];
Imager.SetColor[data.context, color];
TiogaImager.Render[formattedNode.box, data.context, [x, y]];
EXITS
BadButton => Blink["Bad coordinates(s)"];
BadText => Blink["Bad selection"];
BadColor => Blink["Bad color (see ImagerColor.mesa)"];
};
CtInfo
CtInfoData:  TYPE ~ REF CtInfoDataRec;
CtInfoDataRec: TYPE ~ RECORD [
viewer:     Viewer ← NIL,
colorDisplayChanged: BOOLFALSE,
out:      STREAMNIL,
pm:      PixelMapMisc,
cmap:      Cmap ← NIL,
x, y:      INTEGER ← 0
];
PixelInfo:   TYPE ~ RECORD [
pval:      CARDINAL,
red:      CARDINAL,
grn:      CARDINAL,
blu:      CARDINAL
];
SeColorDisplayInfo: PROC [info: CtInfoData] ~ {
info.pm ← ColorTrixBasics.GetColorDisplayPmMisc[];
info.cmap ← IF info.pm.bpp = 8 THEN ColorTrixMap.Read[] ELSE NIL;
};
CtInfo: PUBLIC Commander.CommandProc ~ {
nArgs: INTEGER ← Args.NArgs[cmd];
IF nArgs # 0 AND nArgs # 2
THEN RETURN[$Failure, Rope.Concat["Bad argument(s); usage: ", NIL]]
ELSE SELECT nArgs FROM
0 => {
info: CtInfoData ← NEW[CtInfoDataRec];
SeColorDisplayInfo[info];
info.viewer ← TypeScript.Create[info: [openHeight: 400, name: "CtInfo", data: info, scrollable: TRUE, column: right, iconic: TRUE]];
ViewerOps.OpenIcon[info.viewer];
info.out ← ViewerIO.CreateViewerStreams[NIL, info.viewer].out;
TRUSTED {Process.Detach[FORK Informer[info]]};
};
2 => {
x: Args.Arg ← Args.ArgInt[cmd, 0];
y: Args.Arg ← Args.ArgInt[cmd, 1];
pm: PixelMapMisc ← ColorTrixBasics.GetColorDisplayPmMisc[];
cmap: Cmap ← IF pm.bpp = 8 THEN ColorTrixMap.Read[] ELSE NIL;
IF NOT x.ok OR NOT y.ok THEN RETURN[$Failure, "Bad argument(s)."];
IF NOT CoordinatesOK[pm, x.int, y.int] THEN RETURN[
$Failure,
IO.PutFR["(x, y) must be ([0..%g), [0..%g))", IO.int[pm.w], IO.int[pm.h]]];
APixel[cmd.out, pm, cmap, x.int, y.int];
};
ENDCASE => NULL;
};
CDNotifyProc: ColorDisplay.CDNotifyProc ~ {
IF old # new THEN NARROW[clientData, CtInfoData].colorDisplayChanged ← TRUE;
};
Informer: PROC [info: CtInfoData] ~ TRUSTED {
report: BOOLFALSE;
key: TerminalDefs.KeyName;
action: ClassIncreek.ActionBody;
increek: ClassIncreek.Increek ← ClassIncreek.NewStdIncreek[];
viewPosition: ClassIncreek.ViewPosition ← ClassIncreek.GetPositionFrom[increek];
cdReg: ColorDisplay.CDRegistration ← ColorDisplay.RegisterCDNotifyProc[CDNotifyProc, info];
CedarProcess.SetPriority[background];
IO.PutRope[info.out, "\n"];
WHILE NOT info.viewer.destroyed DO
IF info.colorDisplayChanged THEN {
SeColorDisplayInfo[info];
info.colorDisplayChanged ← FALSE;
};
action ← ClassIncreek.GetAction[self: increek, acceptance: clicksAndMotion];
IF viewPosition.mousePosition.color THEN {
WITH ac: action SELECT FROM
keyDown => IF ac.value IN [Red..Yellow] THEN {key ← ac.value; report ← TRUE};
keyUp => IF ac.value IN [Red..Yellow] THEN {key ← ac.value; report ← FALSE};
ENDCASE;
IF report THEN {
WITH ac: action SELECT FROM
keyDown, deltaMouse => {
info.x ← viewPosition.mousePosition.mouseX;
info.y ← info.pm.h-viewPosition.mousePosition.mouseY;
};
ENDCASE;
IF key = Blue
THEN WITH ac: action SELECT FROM
keyDown => ManyPixels[info];
ENDCASE
ELSE WITH ac: action SELECT FROM
keyDown, deltaMouse => APixel[info.out, info.pm, info.cmap, info.x, info.y];
ENDCASE;
};
};
ENDLOOP;
ColorDisplay.UnregisterCDNotifyProc[cdReg];
};
APixel: PROC [out: STREAM, pm: PixelMapMisc, cmap: Cmap, x, y: INTEGER] ~ {
pix: PixelInfo ← GetPixelInfo[pm, cmap, x, y];
SELECT pm.bpp FROM
8 =>
IO.PutRope[out, Rope.Concat[
IO.PutFR["8 bit pixel at (%g, %g): %g ", IO.int[x], IO.int[y], IO.card[pix.pval]],
IO.PutFR["(r: %g, g: %g, b: %g)\n",
IO.int[cmap[0][pix.pval]], IO.int[cmap[1][pix.pval]], IO.int[cmap[2][pix.pval]]]]];
24 =>
IO.PutRope[out, IO.PutFR["24 bit pixel at (%g, %g), r: %g, g: %g, b: %g\n",
IO.int[x], IO.int[y], IO.card[pix.red], IO.card[pix.grn], IO.card[pix.blu]]];
ENDCASE => NULL;
};
ManyPixels: PROC [info: CtInfoData] ~ {
pixs: ARRAY [0..5) OF ARRAY [0..5) OF PixelInfo;
Bar: PROC ~ {
IF info.pm.bpp = 8
THEN IO.PutF[info.out, "——————————————————————————————————\n"]
ELSE IO.PutF[info.out, "——————————————————————\n"]
};
PrintLine: PROC [j: INTEGER, proc: PROC [i, j: INTEGER], report: BOOLFALSE] ~ {
IF proc # PrintX THEN IO.PutRope[info.out, "| "];
FOR i: NAT IN [0..5) DO proc[i, j]; ENDLOOP;
IF report THEN IO.PutF[info.out, " %g", IO.int[info.y-2+j]];
IO.PutRope[info.out, "\n"];
};
PrintX: PROC [i, j: INTEGER] ~ {
IF info.pm.bpp = 8
THEN IO.PutF[info.out, " %3g\t", IO.int[info.x-2+i]]
ELSE IO.PutF[info.out, " %3g\t", IO.int[info.x-2+i]];
};
PrintPval: PROC [i, j: INTEGER] ~ {
IO.PutF[info.out, " %-3g\t\t|", IO.card[pixs[i][j].pval]];
};
PrintRed: PROC [i, j: INTEGER] ~ {PrintCard["r", pixs[i][j].red]};
PrintGrn: PROC [i, j: INTEGER] ~ {PrintCard["g", pixs[i][j].grn]};
PrintBlu: PROC [i, j: INTEGER] ~ {PrintCard["b", pixs[i][j].blu]};
PrintCard: PROC [rope: ROPE, card: CARDINAL] ~ {
IF info.pm.bpp = 8
THEN IO.PutF[info.out, " %g: %3g\t|", IO.rope[rope], IO.card[card]]
ELSE IO.PutF[info.out, " %3g\t|", IO.card[card]];
};
FOR j: NAT IN [0..5) DO
y: INTEGER ← info.y-2+j;
FOR i: NAT IN [0..5) DO
pixs[i][j] ← GetPixelInfo[info.pm, info.cmap, info.x-2+i, y];
ENDLOOP;
ENDLOOP;
IO.PutF[
info.out, "\n%g bit pixels centered at (%g, %g):\n",
IO.int[info.pm.bpp], IO.int[info.x], IO.int[info.y]];
Process.Pause[Process.MsecToTicks[100]];
[] ← info.viewer.class.scroll[info.viewer, thumb, 100];
PrintLine[0, PrintX];
Bar[];
FOR line: NAT IN [0..5) DO
IF info.pm.bpp = 8 THEN PrintLine[line, PrintPval];
PrintLine[line, PrintRed];
PrintLine[line, PrintGrn, TRUE];
PrintLine[line, PrintBlu];
Bar[];
ENDLOOP
};
CoordinatesOK: PROC [pm: PixelMapMisc, x, y: INTEGER] RETURNS [BOOL] ~ {
RETURN[x IN [0..pm.w) AND y IN [0..pm.h)];
};
GetPixelInfo: PROC [pm: PixelMapMisc, cmap: Cmap, x, y: INTEGER] RETURNS [PixelInfo] ~ {
pix: PixelInfo;
GetInner: PROC ~ {
IF CoordinatesOK[pm, x, y] THEN SELECT pm.bpp FROM
8 => {
pix.pval ← ImagerPixelMap.GetPixel[pm.bw, y, x];
pix.red ← cmap[0][pix.pval];
pix.grn ← cmap[1][pix.pval];
pix.blu ← cmap[2][pix.pval];
};
24 =>
[pix.red, pix.grn, pix.blu] ← ColorTrixBasics.GetRGBPixel[pm, x, y];
ENDCASE => NULL;
};
Terminal.ModifyColorFrame[Terminal.Current[], GetInner, x, y, x+1, y+1];
RETURN[pix];
};
Start Code
ViewerOps.RegisterViewerClass[$Info, NEW[ViewerClasses.ViewerClassRec]];
END.