Oberon/V2/Draw

MODULE Draw; (*NW 29.6.88 / 22.11.91*) IMPORT Files, Fonts, Viewers, Printer, Texts, Oberon, TextFrames, MenuViewers, Graphics, GraphicFrames; VAR W: Texts.Writer; (*Exported commands: 		Open, Delete, 		SetWidth, ChangeColor, ChangeWidth, ChangeFont, 		Store, Print 		Macro, OpenMacro, MakeMacro, LoadLibrary, StoreLibrary*) PROCEDURE Open*; VAR X, Y: INTEGER; beg, end, t: LONGINT; G: Graphics.Graph; V: Viewers.Viewer; text: Texts.Text; S: Texts.Scanner; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = "^") THEN Oberon.GetSelection(text, beg, end, t); IF t >= 0 THEN Texts.OpenScanner(S, text, beg); Texts.Scan(S) END END ; IF S.class = Texts.Name THEN NEW(G); Graphics.Open(G, S.s); Oberon.AllocateUserViewer(Oberon.Par.vwr.X, X, Y); V := MenuViewers.New( 				TextFrames.NewMenu(S.s, 					"System.Close System.Copy System.Grow Draw.Delete Draw.Store"), 				GraphicFrames.New(G, 0, 0, 0, TRUE), TextFrames.menuH, X, Y) 		END END Open; PROCEDURE Delete*; VAR F: GraphicFrames.Frame; BEGIN IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN F := Oberon.Par.vwr.dsc.next(GraphicFrames.Frame); GraphicFrames.Erase(F); Graphics.Delete(F.graph) END END Delete; PROCEDURE SetWidth*; VAR S: Texts.Scanner; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF (S.class = Texts.Int) & (S.i > 0) & (S.i < 7) THEN Graphics.width := SHORT(S.i) END END SetWidth; PROCEDURE ChangeColor*; VAR ch: CHAR; CM: Graphics.ColorMsg; S: Texts.Scanner; BEGIN IF Oberon.Par.frame(TextFrames.Frame).sel > 0 THEN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.frame(TextFrames.Frame).selbeg.pos); Texts.Read(S, ch); CM.col := S.col ELSE Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Int THEN CM.col := SHORT(S.i) ELSE CM.col := S.col END END ; GraphicFrames.Change(GraphicFrames.Selected, CM) END ChangeColor; PROCEDURE ChangeWidth*; VAR WM: Graphics.WidMsg; S: Texts.Scanner; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Int THEN WM.w := SHORT(S.i); GraphicFrames.Change(GraphicFrames.Selected, WM) END END ChangeWidth; PROCEDURE ChangeFont*; VAR FM: Graphics.FontMsg; S: Texts.Scanner; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Name THEN FM.fnt := Fonts.This(S.s); IF FM.fnt # NIL THEN GraphicFrames.Change(GraphicFrames.Selected, FM) END END END ChangeFont; PROCEDURE Backup (VAR name: ARRAY OF CHAR); VAR res, i: INTEGER; ch: CHAR; bak: ARRAY 32 OF CHAR; BEGIN i := 0; ch := name[0]; WHILE ch > 0X DO bak[i] := ch; INC(i); ch := name[i] END ; IF i < 28 THEN bak[i] := "."; bak[i+1] := "B"; bak[i+2] := "a"; bak[i+3] := "k"; bak[i+4] := 0X; Files.Rename(name, bak, res) END END Backup; PROCEDURE Store*; VAR par: Oberon.ParList; S: Texts.Scanner; Menu: TextFrames.Frame; G: GraphicFrames.Frame; v: Viewers.Viewer; BEGIN par := Oberon.Par; IF par.frame = par.vwr. dsc THEN Menu := par.vwr.dsc(TextFrames.Frame); G := Menu.next(GraphicFrames.Frame); Texts.OpenScanner(S, Menu.text, 0); Texts.Scan(S); IF S.class = Texts.Name THEN Texts.WriteString(W, S.s); Texts.WriteString(W, " storing"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Backup(S.s); Graphics.WriteFile(G.graph, S.s) 			END ELSE Texts.OpenScanner(S, par.text, par.pos); Texts.Scan(S); IF S.class = Texts.Name THEN v := Oberon.MarkedViewer; IF (v.dsc # NIL) & (v.dsc.next IS GraphicFrames.Frame) THEN G := v.dsc.next(GraphicFrames.Frame); Texts.WriteString(W, S.s); Texts.WriteString(W, " storing"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Backup(S.s); Graphics.WriteFile(G.graph, S.s) 				END END END END Store; PROCEDURE Print*; VAR nofcopies: INTEGER; S: Texts.Scanner; G: Graphics.Graph; V: Viewers.Viewer; PROCEDURE Copies; VAR ch: CHAR; BEGIN nofcopies := 1; IF S.nextCh = "/" THEN Texts.Read(S, ch); IF (ch >= "0") & (ch <= "9") THEN nofcopies := ORD(ch) - 30H END ; WHILE ch > " " DO Texts.Read(S, ch) END ; S.nextCh := ch 			END END Copies; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Name THEN Printer.Open(S.s, Oberon.User, Oberon.Password); IF Printer.res = 0 THEN Texts.Scan(S); WHILE S.class = Texts.Name DO 					Texts.WriteString(W, S.s); Copies; Graphics.Open(G, S.s); IF Graphics.res = 0 THEN Texts.WriteString(W, " printing"); Texts.WriteInt(W, nofcopies, 3); Texts.Append(Oberon.Log, W.buf); Graphics.Print(G, 0, Printer.PageHeight-128); Printer.Page(nofcopies) ELSE Texts.WriteString(W, " not found") END ; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Texts.Scan(S) END ; IF (S.class = Texts.Char) & (S.c = "*") THEN Copies; V := Oberon.MarkedViewer; IF (V.dsc # NIL) & (V.dsc.next IS GraphicFrames.Frame) THEN Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan(S); IF S.class = Texts.Name THEN Texts.WriteString(W, S.s); Texts.WriteString(W, " printing"); Texts.WriteInt(W, nofcopies, 3); Texts.Append(Oberon.Log, W.buf); Graphics.Print(V.dsc.next(GraphicFrames.Frame).graph, 0, Printer.PageHeight-128); Printer.Page(nofcopies) END END END ; Printer.Close ELSIF Printer.res = 1 THEN Texts.WriteString(W, " no printer") ELSIF Printer.res = 2 THEN Texts.WriteString(W, " no link") ELSIF Printer.res = 3 THEN Texts.WriteString(W, " bad response") ELSIF Printer.res = 4 THEN Texts.WriteString(W, " no permission") END END ; Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END Print; PROCEDURE Macro*; VAR S: Texts.Scanner; T: Texts.Text; time, beg, end: LONGINT; Lname: ARRAY 32 OF CHAR; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Name THEN COPY(S.s, Lname); Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = "^") THEN Oberon.GetSelection(T, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(S, T, beg); Texts.Scan(S) END END ; IF (S.class = Texts.Name) OR (S.class = Texts.String) THEN GraphicFrames.Macro(Lname, S.s) 			END END END Macro; PROCEDURE OpenMacro*; VAR F: GraphicFrames.Frame; sel: Graphics.Object; BEGIN F := GraphicFrames.Selected; IF F # NIL THEN sel := F.graph.sel; IF (sel # NIL) & (sel IS Graphics.Macro) THEN GraphicFrames.Deselect(F); Graphics.OpenMac(sel(Graphics.Macro).mac, F.graph, F.mark.x - F.x, F.mark.y - F.y); GraphicFrames.Draw(F) END END END OpenMacro; PROCEDURE MakeMacro*; VAR new: BOOLEAN; F: GraphicFrames.Frame; S: Texts.Scanner; Lname: ARRAY 32 OF CHAR; PROCEDURE MakeMac; VAR x0, y0, x1, y1, w, h: INTEGER; mh: Graphics.MacHead; L: Graphics.Library; BEGIN L := Graphics.ThisLib(Lname, FALSE); IF L = NIL THEN L := Graphics.NewLib(Lname) END ; x0 := F.mark.x; y0 := F.mark.y; x1 := F.mark.next.x; y1 := F.mark.next.y; 			w := ABS(x1-x0); h := ABS(y1-y0); IF x0 < x1 THEN x0 := x0 - F.x ELSE x0 := x1 - F.x END ; IF y0 < y1 THEN y0 := y0 - F.y ELSE y0 := y1 - F.y END ; mh := Graphics.MakeMac(F.graph, x0, y0, w, h, S.s); Graphics.InsertMac(mh, L, new) END MakeMac; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Name THEN COPY(S.s, Lname); Texts.Scan(S); IF (S.class = Texts.Name) OR (S.class = Texts.String) & (S.len <= 8) THEN F := GraphicFrames.Focus; IF (F # NIL) & (F.graph.sel # NIL) THEN MakeMac; Texts.WriteString(W, S.s); IF new THEN Texts.WriteString(W, " inserted in ") ELSE Texts.WriteString(W, " replaced in ") END ; Texts.WriteString(W, Lname); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END END END MakeMacro; PROCEDURE LoadLibrary*; VAR S: Texts.Scanner; L: Graphics.Library; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Name THEN L := Graphics.ThisLib(S.s, TRUE); Texts.WriteString(W, S.s); Texts.WriteString(W, " loaded"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END END LoadLibrary; PROCEDURE StoreLibrary*; VAR i: INTEGER; S: Texts.Scanner; L: Graphics.Library; Lname: ARRAY 32 OF CHAR; BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); IF S.class = Texts.Name THEN i := 0; WHILE S.s[i] >= "0" DO Lname[i] := S.s[i]; INC(i) END ; Lname[i] := 0X; L := Graphics.ThisLib(Lname, FALSE); IF L # NIL THEN Texts.WriteString(W, S.s); Texts.WriteString(W, " storing"); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Graphics.StoreLib(L, S.s) 			END END END StoreLibrary; BEGIN Texts.OpenWriter(W) END Draw.