ðÁSyntax10.Scn.Fntèÿÿÿ £Zà¥ParcElemsAlloc Æê€å ™€ä¯€Ï³Cðÿÿÿ £ZॠÆê€å ™Syntax10b.Scn.Fnt ôSyntax10i.Scn.Fnt– a j  9(ƒ V+B  8"Á9I›[Dðÿÿÿ £ZॠÆê€å ™ßV 7 "1€)+öObjektorientierte Programmierung SS92 Hilfsblatt 1 H. M„ssenb„ck Module Texts Texts.Elem = POINTER TO Texts.ElemDesc; Texts.ElemMsg = RECORD END; Texts.Handler = PROCEDURE (e: Texts.Elem; VAR msg: Texts.ElemMsg); Texts.ElemDesc = RECORD W, H: LONGINT; handle: Texts.Handler END; The bounding box of an element (W, H) is given in device independent coordinates ("units"). 1mm = 36000 units. The handler of an element has to deal with the messages described below. A handler uses a sequence of type tests to deal with the various message types. Texts.CopyMsg = RECORD (Texts.ElemMsg) e: Elem END; The receiver creates a fully initialized copy of itself and returns it in the message field e. The fields inherited from Texts.Elem should be copied by calling Texts.CopyElem(from, to). Texts.IdentifyMsg = RECORD (Texts.ElemMsg) mod, proc: ARRAY 32 OF CHAR END; When receiving an identify message, an element returns the module and procedure string identifying its allocation procedure. An allocation procedure creates a new instance of the corresponding element class, installs the element handler, and assigns it to the variable Texts.new. Texts.FileMsg = RECORD (Texts.ElemMsg) id: INTEGER; r: Files.Rider END; Depending on the message id (Texts.load, Texts.store) the receiver loads or stores its state using the rider r. The state of the base type Texts.ElemDesc (W, H) is automatically loaded and stored. Module WriteFrames WriteFrames.DisplayMsg = RECORD (Texts.ElemMsg) prepare: BOOLEAN; fnt: Fonts.Font; col: SHORTINT; X0, Y0: INTEGER END; WriteFrames sends display messages to an element to determine the space required by the element (prepare) and to draw the element within a frame (~prepare). The text attributes set for the receiving element are given by fnt and col. Fields X0 and Y0 are not used if prepare holds. If ~prepare, the receiver is asked to display itself (using module Display) at absolute screen coordinates (X0, Y0). WriteFrames.TrackMsg = RECORD (Texts.ElemMsg) X, Y: INTEGER; keys: SET; fnt: Fonts.Font; col: SHORTINT; X0, Y0: INTEGER END; The receiving element, based at screen coordinates (X0, Y0) is asked to handle a mouse click at screen coordinate (X, Y) with keys pressed. The text attributes set for the receiving element are given by fnt and col. To create a new element and insert it into some text, an insertion command should be supplied. The insertion command creates a new element, initializes W, H, handle, and other element fields, perhaps according to some command arguments. Then, it may call WriteFrames.CopyToFocus(elem) to insert a copy of the new element at the position of the caret. Module WritePrinter TYPE WritePrinter.PrintMsg = RECORD (Texts.ElemMsg) prepare: BOOLEAN; fnt: Fonts.Font; col: SHORTINT; X0, Y0: INTEGER END; Write sends print messages to an element to determine the space required by the element (prepare) and to print the element (~prepare). The text attributes set for the receiving element are given by fnt and col. Fields X0 and Y0 are not used if prepare holds. If ~prepare, the receiver is asked to print itself (using modules Printer and WritePrinter) at absolute screen coordinates (X0, Y0). Procedures to measure, display, and print strings PROCEDURE GetDisplayStringSize (VAR s: ARRAY OF CHAR; fnt: Fonts.Font; VAR W, H: LONGINT); VAR i, sx, dx, x, y, w, h: INTEGER; pat: Display.Pattern; BEGIN i := 0; sx := 0; WHILE s[i] # 0X DO Display.GetChar(fnt.raster, s[i], dx, x, y, w, h, pat); INC(sx, dx); INC(i) END; W := sx * LONG(WriteFrames.Unit); H := fnt.height * LONG(WriteFrames.Unit) END GetDisplayStringSize; WriteFrames.Unit defines the number of units per screen pixel. PROCEDURE DrawString (x0, y0: INTEGER; VAR s: ARRAY OF CHAR; fnt: Fonts.Font; col: SHORTINT); VAR i, dx, x, y, w, h: INTEGER; pat: Display.Pattern; BEGIN INC(y0, -fnt.minY); i := 0; WHILE s[i] # 0X DO Display.GetChar(fnt.raster, s[i], dx, x, y, w, h, pat); Display.CopyPattern(col, pat, x0+x, y0+y, Display.paint); INC(x0, dx); INC(i) END END DString; PROCEDURE GetPrinterStringSize (VAR s: ARRAY OF CHAR; fnt: Fonts.Font; VAR W, H: LONGINT); VAR fno: SHORTINT; i: INTEGER; sX, dX, X, Y: LONGINT; BEGIN fno := WritePrinter.FontNo(fnt); i := 0; sX := 0; WHILE s[i] # 0X DO WritePrinter.Get(fno, s[i], dX, X, Y, W, H); INC(sX, dX); INC(i) END; W := sX; H := fnt.height * LONG(WriteFrames.Unit) END GetPrinterStringSize; WritePrinter.Unit defines the number of units per printer pixel. PROCEDURE PrintString (x0, y0: INTEGER; VAR s: ARRAY OF CHAR; fnt: Fonts.Font; col: SHORTINT); BEGIN Printer.String(x0, y0 - SHORT(fnt.minY * LONG(WriteFrames.Unit) DIV WritePrinter.Unit), s, fnt.name) END PrintString; Procedure to Locate and Update an Element PROCEDURE Update (E: Elem); VAR T: Texts.Text; R: Texts.Reader; pos: LONGINT; BEGIN T := Texts.ElemBase(E); IF T # NIL THEN Texts.OpenReader(R, T, 0); REPEAT Texts.ReadElem(R) UNTIL R.elem = E; pos := Texts.Pos(R); Texts.ChangeLooks(T, pos-1, pos, {}, NIL, 0, 0) END END Update;