ð“Syntax10.Scn.Fntöÿÿÿ hÀÔStampElemsAlloc8 Oct 98­Syntax10b.Scn.Fntÿÿÿÿ€8ÀÔFoldElemsNew ÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔPÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔ*ÿÿÿÿ€8ÀÔ§ÿÿÿÿ€8ÀÔøÿÿÿÿ€8ÀÔ%ÿÿÿÿ€8ÀÔwSyntax10i.Scn.FntTÿÿÿÿ€8ÀÔ&ÿÿÿÿ€8ÀÔzTÿÿÿÿ€8ÀÔDÿÿÿÿ€8ÀÔAF @ÿÿÿÿ€8ÀÔ )ÿÿÿÿ€8ÀÔÞZ)3 Zƒ §óÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔLÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔäÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔÿÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔ‚ÿÿÿÿ€8ÀÔPÿÿÿÿ€8ÀÔ¾ÿÿÿÿ€8ÀÔ MODULE PElems; (* MAH *) IMPORT Pictures, Texts, Fonts, Display, TextFrames, TextPrinter, Files, In, Oberon, Input; CONST pixel = LONG(TextFrames.Unit); ppixel = LONG(TextPrinter.Unit); TYPE Elem* = POINTER TO ElemDesc;  ElemDesc* = RECORD (Texts.ElemDesc) pic*: Pictures.Picture; width*, height*: INTEGER END;  Frame = POINTER TO FrameDesc;  FrameDesc = RECORD (Display.FrameDesc) p: Pictures.Picture; e: Elem END;  ModifyMsg* = RECORD (Display.FrameMsg)  check*: PROCEDURE (VAR m: Display.FrameMsg); e*: Elem END;  (* GetDsr should not be necessary if the error in TextPrinter is corrected *) PROCEDURE GetDsr (f: Display.Frame; pos: LONGINT; fnt: Fonts.Font; VAR dsr: INTEGER);  VAR p: TextFrames.Parc; beg: LONGINT; BEGIN IF f = NIL THEN IF fnt = NIL THEN dsr := 0 ELSE dsr := - fnt.minY END ELSE TextFrames.ParcBefore(f(TextFrames.Frame).text, pos, p, beg); dsr := SHORT(p.dsr DIV TextFrames.Unit) END END GetDsr;  PROCEDURE Width(e: Elem) : INTEGER;  BEGIN IF e.width > 0 THEN RETURN e.width ELSIF (e.height = 0) OR (e.pic.width = 1) THEN RETURN e.pic.width ELSE (* keep proportions *) RETURN SHORT((e.pic.width * LONG(e.height)) DIV e.pic.height) END END Width;  PROCEDURE Height(e: Elem) : INTEGER;  BEGIN IF e.height > 0 THEN RETURN e.height ELSIF (e.width = 0) OR (e.pic.height = 1) THEN RETURN e.pic.height ELSE (* keep proportions *) RETURN SHORT((e.pic.height * LONG(e.width)) DIV e.pic.width) END END Height;  PROCEDURE HandleFrame (f: Display.Frame; VAR m: Display.FrameMsg);  VAR t: Texts.Text; e: Elem; x, y, w, h: LONGINT; BEGIN WITH m: Pictures.UpdateMsg DO e := f(Frame).e; IF e.pic = m.p THEN IF m.new # NIL THEN e.pic := m.new END; t := Texts.ElemBase (e); w := Width(e); h := Height(e); IF (f.W = w) & (f.H = h) THEN x := f.X + (m.x*w) DIV e.pic.width; y := f.Y + (m.y*h) DIV e.pic.height; w := ((m.x+m.w)*w) DIV e.pic.width + f.X - x; h := ((m.y+m.h)*h) DIV e.pic.height + f.Y - y; e.pic.DrawStretched (m.x, m.y, m.w, m.h, SHORT(x), SHORT(y), SHORT(w), SHORT(h), Display.replace) ELSE TextFrames.NotifyDisplay (t, Texts.replace, Texts.ElemPos (e), Texts.ElemPos (e)+1) END END | m: ModifyMsg DO m.e := f(Frame).e; m.check(m) ELSE END END HandleFrame;  PROCEDURE Handler* (e: Texts.Elem; VAR m: Texts.ElemMsg);  CONST MM = 1; VAR e1: Elem; dsr: INTEGER; x, y, res: INTEGER; f: Frame; keysum, keys: SET; loc: TextFrames.Location; r, g, b, col: INTEGER; li: Pictures.LoadInfo; version: SHORTINT; BEGIN WITH e: Elem DO WITH m: TextFrames.DisplayMsg DO IF m.prepare THEN e.W := Width(e) * pixel; e.H := Height(e) * pixel ELSE NEW(f); f.X := m.X0; f.Y := m.Y0; f.W := Width(e); f.H := Height(e); f.e := e; f.handle := HandleFrame; f.p := e.pic; m.elemFrame := f; e.pic.DrawStretched (0, 0, e.pic.width, e.pic.height, m.X0, m.Y0, f.W, f.H, Display.replace) END | m: TextPrinter.PrintMsg DO GetDsr(NIL, m.pos, m.fnt, dsr); IF m.prepare THEN e.W := Width(e)*pixel; e.H := (Height(e)+dsr)*pixel ELSE x := m.X0; y := m.Y0 + SHORT(dsr*pixel DIV ppixel); e.pic.Print(x, y, SHORT(e.W DIV ppixel), SHORT((Height(e)*pixel) DIV ppixel), Display.replace) END | m: Texts.IdentifyMsg DO m.mod := "PElems"; m.proc := "Alloc" | m: Texts.FileMsg DO IF m.id = Texts.load THEN Files.Read(m.r, version); IF version = 0 THEN (* new version with size *) Files.ReadInt(m.r, e.width); Files.ReadInt(m.r, e.height) ELSE e.width := 0; e.height := 0; Files.Set(m.r, Files.Base(m.r), Files.Pos(m.r)-1) END; li := Pictures.Load(Files.Base(m.r), Files.Pos(m.r)); IF li # NIL THEN IF li.picture = NIL THEN NEW (li.picture); li.picture.Init (1, 1, 1) END; e.pic := li.picture; li.Do; li.Completed END; Files.Set(m.r, Files.Base(m.r), Files.Pos(m.r) + li.usedBytes) ELSIF m.id = Texts.store THEN version := 0; Files.Write(m.r, version); Files.WriteInt(m.r, e.width); Files.WriteInt(m.r, e.height); e.pic.Store (m.r) END | m: Texts.CopyMsg DO IF m.e = NIL THEN NEW (e1); m.e := e1 ELSE e1 := m.e(Elem) END; Texts.CopyElem(e, e1); e1.pic := e.pic; e1.width := e.width; e1.height := e.height (* | m: TextFrames.TrackMsg DO IF m.keys = {MM} THEN keysum := {MM}; REPEAT Input.Mouse(keys, x, y); keysum := keysum + keys; Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x, y) UNTIL keys = {}; TextFrames.LocatePos(m.frame(TextFrames.Frame), TextFrames.Pos(m.frame(TextFrames.Frame), x, y), loc); Out.Ln; Out.Char("("); Out.Int(x - loc.x, 0); Out.Char(","); Out.Int(y - loc.y, 0); Out.String("): "); e.pic.GetPixelRGB(x - loc.x, y - loc.y, r, g, b); IF e.pic.depth <= 8 THEN e.pic.GetPixelIdx(x - loc.x, y - loc.y, col); Out.String("palIdx = "); Out.Int(col, 0) END; Out.String(", R = "); Out.Int(r, 4); Out.String(", G = "); Out.Int(g, 4); Out.String(", B = "); Out.Int(b, 4) END *) ELSE END END END Handler;  PROCEDURE Alloc*;  VAR e: Elem; BEGIN NEW(e); e.handle := Handler; Texts.new := e END Alloc;  PROCEDURE Insert*;  VAR e: Elem; insert: TextFrames.InsertElemMsg; f: Files.File; r: Files.Rider; name: ARRAY 256 OF CHAR; res: INTEGER; li: Pictures.LoadInfo; BEGIN In.Open; In.Name (name); IF ~In.Done THEN In.Open; In.String(name) END; IF In.Done THEN NEW(e); e.handle := Handler; In.Int(e.width); IF In.Done THEN In.Int(e.height); IF ~In.Done THEN e.height := 0 END ELSE e.width := 0; e.height := 0 END; f := Files.Old (name); IF f # NIL THEN li := Pictures.Load (f, 0); IF li # NIL THEN IF li.picture = NIL THEN NEW (li.picture); li.picture.Init (1, 1, 1) END; e.pic := li.picture; insert.e := e; Oberon.FocusViewer.handle(Oberon.FocusViewer, insert); li.Do; li.Completed END END END END Insert;  PROCEDURE Resize*;  VAR t: Texts.Text; beg, end, time: LONGINT; r: Texts.Reader; p: Elem; w, h: INTEGER; BEGIN Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN Texts.OpenReader(r, t, beg); REPEAT Texts.ReadElem(r) UNTIL r.eot OR (Texts.Pos(r) > end) OR (r.elem IS Elem); IF ~r.eot & (Texts.Pos(r) <= end) THEN p := r.elem(Elem); end := Texts.Pos(r); beg := end - 1; In.Open; In.Int(w); IF ~In.Done THEN TextFrames.NotifyDisplay (t, Texts.replace, beg, end); In.Open; In.Int(w) END; IF In.Done THEN In.Int(h); IF ~In.Done THEN h := 0 END ELSE w := 0; h := 0 END; IF (w # p.width) OR (h # p.height) THEN p.width := w; p.height := h; TextFrames.NotifyDisplay (t, Texts.replace, beg, end) END END END; END Resize;  PROCEDURE Paste*;  VAR e: Elem; insert: TextFrames.InsertElemMsg; name: ARRAY 256 OF CHAR; res: INTEGER; BEGIN NEW(e); e.handle := Handler; NEW(e.pic); e.pic.Paste(res); IF res = 0 THEN insert.e := e; Oberon.FocusViewer.handle(Oberon.FocusViewer, insert) END END Paste;  PROCEDURE Copy*;  VAR t: Texts.Text; beg, end, time: LONGINT; r: Texts.Reader; e: Texts.Elem; p: Elem; res: INTEGER; BEGIN Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN Texts.OpenReader(r, t, beg); REPEAT Texts.ReadElem(r) UNTIL r.eot OR (Texts.Pos(r) > end) OR (r.elem IS Elem); IF ~r.eot & (Texts.Pos(r) <= end) THEN p := r.elem(Elem); p.pic.Copy(res) END END; END Copy;  END PElems. PElems.Insert Clipboard.Snapshot drag PElems.Paste (* PROCEDURE Insert*;  VAR e: Elem; insert: TextFrames.InsertElemMsg; f: Files.File; r: Files.Rider; name: ARRAY 256 OF CHAR; res: INTEGER; BEGIN In.Open; In.Name (name); IF ~In.Done THEN In.Open; In.String(name) END; IF In.Done THEN NEW(e); e.handle := Handler; f := Files.Old (name); IF f # NIL THEN Files.Set (r, f, 0); NEW (e.pic); e.pic.Load (r, res); insert.e := e; Oberon.FocusViewer.handle(Oberon.FocusViewer, insert) END END END Insert;  *) System.Free PElems* ~