DIRECTORY Args, Atom, Buttons, ChoiceButtons, CedarProcess, ClassIncreek, ColorDisplay, ColorTrixBasics, ColorTrixMap, Commander, Containers, Convert, Draw2d, Imager, ImagerBackdoor, ImagerColor, ImagerPixelMap, IO, MessageWindow, Process, Real, Rope, Terminal, TerminalDefs, TextNode, TiogaAccess, TiogaImager, TypeScript, ViewerClasses, ViewerIO, ViewerOps, ViewerTools; ColorTrixCommands2Impl: CEDAR PROGRAM IMPORTS Args, Atom, Buttons, ChoiceButtons, CedarProcess, ClassIncreek, ColorDisplay, ColorTrixBasics, ColorTrixMap, Commander, Containers, Convert, Draw2d, Imager, ImagerBackdoor, ImagerColor, ImagerPixelMap, IO, MessageWindow, Process, Real, Rope, Terminal, TiogaAccess, TiogaImager, TypeScript, ViewerIO, ViewerOps, ViewerTools ~ 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: 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; }; }; 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: 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, ctTextUsage]; 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)"]; }; CtInfoData: TYPE ~ REF CtInfoDataRec; CtInfoDataRec: TYPE ~ RECORD [ viewer: Viewer _ NIL, colorDisplayChanged: BOOL _ FALSE, out: STREAM _ NIL, 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: Commander.CommandProc ~ { nArgs: INTEGER _ Args.NArgs[cmd]; IF nArgs # 0 AND nArgs # 2 THEN RETURN[$Failure, Rope.Concat["Bad argument(s); usage: ", ctInfoUsage]] 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: BOOL _ FALSE; 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: BOOL _ FALSE] ~ { 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]; }; ctTextUsage: ROPE ~ "\nCtText [x, y: INT, text: ROPE] If arguments given, print text starting at pixel loaction (x, y). Otherwise, create a viewer to print any selected text."; ctInfoUsage: ROPE ~ "\nctInfo [x, y: INT]: Print the pixel value at (x, y)."; ctDifUsage: ROPE ~ "\nctDif Display |dif| between windows."; ViewerOps.RegisterViewerClass[$Info, NEW[ViewerClasses.ViewerClassRec]]; Commander.Register["///Commands/CtText", CtText, ctTextUsage]; Commander.Register["///Commands/CtInfo", CtInfo, ctInfoUsage]; Commander.Register["///Commands/CtDif", CtDif, ctDifUsage]; END. ฎColorTrixCommands2Impl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Bloomenthal, November 30, 1986 12:17:24 pm PST CtDif CtText CtInfo Start Code ส ?˜šœ™Jšœ ฯmœ1™Jšžœžœ˜.J˜—˜J˜"J˜"Jšœ;˜;Jš œ žœ žœžœžœ˜=J˜Jš žœžœžœžœžœžœ˜Bšžœžœ žœžœ˜3Jšœ ˜ Jšžœ,žœ žœ ˜K—Jšœ(˜(J˜—Jšžœžœ˜—J˜—J˜—šข œ˜+Jšžœ žœžœ/žœ˜LJ˜J˜—šขœžœžœ˜-Jšœžœžœ˜Jšœ˜J˜ Jšœ=˜=J˜PJ˜[J˜Jšœ%˜%Jšžœ˜J˜šžœžœž˜"šžœžœ˜"Jšœ˜Jšœžœ˜!J˜—J˜Lšžœ"žœ˜*šžœ žœž˜Jš œ žœ žœžœžœ˜MJš œ žœ žœžœžœ˜LJšžœ˜—šžœžœ˜šžœ žœž˜šœ˜Jšœ+˜+Jšœ5˜5J˜—Jšžœ˜—šžœ ˜ šžœžœ žœž˜ Jšœ˜Jšž˜—šžœžœ žœž˜ JšœL˜LJšžœ˜—J˜—J˜——Jšžœ˜J˜—J˜+J˜J˜—šขœžœžœ&žœ˜KJšœ.˜.šžœž˜šœ˜šžœ˜Jšžœ&žœ žœ žœ˜Sšžœ!˜#Jšžœžœžœ˜S———˜šžœžœ9˜KLš žœ žœ žœžœžœ˜M——Jšžœžœ˜—J˜J˜—šก œžœ˜'Jš œžœžœžœžœ ˜0šขœžœ˜ šžœ˜Jšžœžœ7˜>Jšžœžœ+˜2J˜——šข œžœžœžœžœ žœžœ˜RJšžœžœžœ˜1Jš žœžœžœžœ žœ˜,Jšžœžœžœžœ˜=Jšžœ˜J˜—šขœžœžœ˜ šžœ˜Jšžœžœžœ˜7Jšžœžœžœ˜5—J˜—šข œžœžœ˜#Jšžœžœ˜:Jšœ˜—Jšขœžœžœ%˜BJšขœžœžœ&˜CJšขœžœžœ%˜Bšข œžœžœžœ˜0šžœ˜Jšžœžœ žœ žœ ˜DJšžœžœžœ ˜1—J˜—J˜šžœžœžœž˜Jšœžœ˜šžœžœžœž˜Jšœ=˜=Jšžœ˜—Jšžœ˜—J˜šžœ˜Jšœ4˜4Jšžœžœžœ˜5—J˜(Jšœ7˜7J˜Jšœ˜J˜šžœžœžœž˜Jšžœžœ˜3Jšœ˜Jšœžœ˜ Jšœ˜Jšœ˜Jšž˜—J˜J˜—š ข œžœžœžœžœ˜HJšžœžœ žœžœ ˜*Jšœ˜J˜—šข œžœ&žœžœ˜XJ˜šขœžœ˜šžœžœžœž˜2šœ˜Jšœ0˜0Jšœ˜Jšœ˜Jšœ˜J˜—˜L˜D—Jšžœžœ˜—J˜—J•StartOfExpansiont[vt: Terminal.Virtual, action: PROC, xmin: NAT _ 0, ymin: NAT _ 0, xmax: NAT _ 32767, ymax: NAT _ 32767]šœH˜HJšžœ˜ J˜——š  ™ šœ žœ˜Jšœ ฯsœฃœฃœ~˜žJ˜—Jšœ žœฃœ%˜MJ˜Jšœ žœD˜TJ˜šœ%žœ ˜HJ˜—Jšœ>˜>Jšœ>˜>Jšœ;˜;J˜—Jšž˜—…—+09