<<>> <> <> <> <> DIRECTORY Args, Buttons, ChoiceButtons, Convert, CtBasic, CtDispatch, CtMisc, CtViewer, Imager, ImagerColor, MessageWindow, Process, Rope, ViewerClasses, ViewerOps, ViewerTools; CtTextCommandImpl: CEDAR PROGRAM IMPORTS Args, Buttons, ChoiceButtons, Convert, CtBasic, CtDispatch, CtMisc, CtViewer, Imager, ImagerColor, MessageWindow, Process, Rope, ViewerOps, ViewerTools ~ BEGIN <> ButtonProc: TYPE ~ Buttons.ButtonProc; Color: TYPE ~ Imager.Color; Context: TYPE ~ Imager.Context; ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ ViewerClasses.Viewer; ViewerClassRec: TYPE ~ ViewerClasses.ViewerClassRec; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ image: Viewer ¬ NIL, parent: Viewer ¬ NIL, x, y, a, b, c: Viewer ¬ NIL, trackButton: Viewer ¬ NIL, styleButton: Viewer ¬ NIL, printButton: Viewer ¬ NIL, modeButton: Viewer ¬ NIL ]; ctTextUsage: ROPE ~ "Ct Text [-color []] [-font ] [-size ] If arguments given, print text starting at pixel location (x, y), with given color [1, 1, 1], font [helvetica-mrr] and size (pixel height) [14]. Fonts come from project/pcedar2.0/imagerfonts/xerox/pressfonts/. If no arguments, create a viewer to print selected text."; CtText: CtDispatch.CtProc ~ { err: ROPE; affect ¬ [[0, 0], [0, 0]]; IF Args.NArgs[cmd] > 0 THEN { ENABLE Args.Error => {error ¬ reason; GOTO Bad}; xA, yA, textA, rA, gA, bA, fontA, sizeA: Args.Arg; [xA, yA, textA, rA, gA, bA, fontA, sizeA] ¬ Args.ArgsGet[cmd, "%rrs-color%r[rr-font%s-size%r"]; { r: REAL ¬ IF rA.ok THEN rA.real ELSE 1.0; g: REAL ¬ IF gA.ok THEN gA.real ELSE r; b: REAL ¬ IF bA.ok THEN bA.real ELSE g; font: ROPE ¬ IF fontA.ok THEN fontA.rope ELSE NIL; size: REAL ¬ IF sizeA.ok THEN sizeA.real ELSE 14.; color: Color ¬ ImagerColor.ColorFromRGB[[r, g, b]]; context: Context ¬ CtBasic.ContextFromSampleMaps[maps]; CtMisc.PrintRope[textA.rope, [xA.real, yA.real], color, font, size, context ! Imager.Warning => {err ¬ Rope.Concat["no such font: ", font]; GOTO Bad}]; }; EXITS Bad => error ¬ err; } ELSE { v: Viewer ¬ ViewerOps.FindViewer["Ct Text"]; t: Data ¬ IF v = NIL THEN NEW[DataRep] ELSE NARROW[v.data]; IF v = NIL THEN TRUSTED {Process.Detach[FORK MakeViewer[t]]}; t.image ¬ viewer; t.parent ¬ v; CtViewer.RegisterMouse[viewer, MouseProc, t, lowerLeft]; }; }; MakeViewer: PROC [t: Data] ~ { TextButton: PROC [x, y, w: NAT, name, text: ROPE] RETURNS [v: Viewer] ~ { v ¬ ChoiceButtons.BuildTextPrompt[t.parent, x, y, name, text,, w, t].textViewer; }; ProcButton: PROC [x, y: INT, name: ROPE, proc: ButtonProc] RETURNS [Viewer] ~ { RETURN[Buttons.Create[ info: [parent: t.parent, name: name, wx: x, wy: y], proc: proc, clientData: t, paint: TRUE]]; }; ViewerOps.OpenIcon[t.parent ¬ ViewerOps.CreateViewer[ flavor: $CtText, info: [openHeight: 51, name: "Ct Text", data: t, column: right, iconic: TRUE]]]; t.x ¬ TextButton[0, 3, 30, "x:", "0"]; t.y ¬ TextButton[75, 3, 30, "y:", "0"]; t.a ¬ TextButton[150, 3, 30, "h/r:", "0"]; t.b ¬ TextButton[225, 3, 30, "s/g:", "0"]; t.c ¬ TextButton[300, 3, 30, "v/b:", "0"]; t.trackButton ¬ ProcButton[3, 18, "Track-Off", ToggleTrack]; t.styleButton ¬ ProcButton[70, 18, "PrintStyle ", ToggleStyle]; t.modeButton ¬ ProcButton[146, 18, "RGB", ToggleMode]; t.printButton ¬ ProcButton[180, 18, "PRINT", Print]; }; Destroy: ViewerClasses.DestroyProc ~ { CtViewer.UnregisterMouse[NARROW[self.data, Data].image, MouseProc]; }; MouseProc: CtViewer.MouseProc ~ { IF mouse.state # up AND mouse.button = left THEN { t: Data ¬ NARROW[clientData]; Buttons.ReLabel[t.x, Convert.RopeFromInt[mouse.pos.x]]; Buttons.ReLabel[t.y, Convert.RopeFromInt[mouse.pos.y]]; }; }; ToggleTrack: ButtonProc ~ { t: Data ~ NARROW[clientData]; IF Rope.Equal[parent.name, "Track-Off"] THEN { Buttons.ReLabel[parent, "Track-On"]; CtViewer.RegisterMouse[t.parent, MouseProc, clientData, lowerLeft]; } ELSE { Buttons.ReLabel[parent, "Track-Off"]; CtViewer.UnregisterMouse[t.parent, MouseProc]; }; }; ToggleMode: ButtonProc ~ { Buttons.ReLabel[parent, IF Rope.Equal[parent.name, "RGB"] THEN "HSV" ELSE "RGB"]; }; ToggleStyle: ButtonProc ~ { IF Rope.Equal[parent.name, "ScreenStyle"] THEN Buttons.ReLabel[parent, "PrintStyle "] ELSE Buttons.ReLabel[parent, "ScreenStyle"]; }; Blink: PROC [rope: ROPE] ~ { MessageWindow.Append[Rope.Concat["\t\t", rope], TRUE]; MessageWindow.Blink[]; }; Action: CtViewer.ViewerProc ~ { Arg: ERROR = CODE; { ENABLE Arg, Convert.Error => GOTO Bad; GetInt: PROC [v: Viewer] RETURNS [num: INT] ~ { IF (num ¬ Convert.IntFromRope[ViewerTools.GetContents[v]]) < 0 THEN ERROR Arg; }; GetReal: PROC [v: Viewer] RETURNS [num: REAL] ~ { IF (num ¬ Convert.RealFromRope[ViewerTools.GetContents[v]]) < 0 THEN ERROR Arg; }; error: ROPE; t: Data ¬ NARROW[clientData]; x: NAT ¬ GetInt[t.x]; y: NAT ¬ GetInt[t.y]; a: REAL ¬ GetReal[t.a]; b: REAL ¬ GetReal[t.b]; c: REAL ¬ GetReal[t.c]; color: Color ¬ IF Rope.Equal[t.modeButton.name, "HSV"] THEN ImagerColor.ColorFromHSV[a, b, c] ELSE ImagerColor.ColorFromRGB[[a, b, c]]; screenStyle: BOOL ~ Rope.Equal[t.styleButton.name, "ScreenStyle"]; context: Context ¬ CtBasic.ContextFromSampleMaps[maps]; IF (error ¬ CtMisc.PrintTiogaSelection[[x, y], color, context, screenStyle]) # NIL THEN Blink[error]; EXITS Bad => Blink["Bad coordinate(s)"]; }; }; Print: ButtonProc ~ { t: Data ¬ NARROW[clientData]; CtViewer.DoWithViewer[t.image, Action, t]; }; <> ViewerOps.RegisterViewerClass[$CtText, NEW[ViewerClassRec ¬ [destroy: Destroy]]]; CtDispatch.RegisterCtOp["Text and Painting:", NIL, NIL]; CtDispatch.RegisterCtOp["Text", CtText, ctTextUsage]; END. <<>>