MODULE Printing; (* THIS IS TEXT COPY OF BlackBox 1.6-rc6 System/Mod/Printing.odc *) (* DO NOT EDIT *) IMPORT Kernel, Fonts, Ports, Dates, Printers, Views, Dialog, Strings; CONST maxNrOfSegments = 16; TYPE PageInfo* = RECORD first*, from*, to*: INTEGER; (** current IN **) (** first, from, to: OUT, preset to (0, 0, 9999) **) alternate*: BOOLEAN; title*: Views.Title END; Banner* = RECORD font*: Fonts.Font; gap*: INTEGER; (** OUT, prest to (0,0) **) left*, right*: ARRAY 128 OF CHAR (** OUT, preset to "", "" **) (** anywhere in header or footer: &p - replaced by current page number as arabic numeral &r - replaced by current page number as roman numeral &R - replaced by current page number as capital roman numeral &a - replaced by current page number as alphanumeric character &A - replaced by current page number as capital alphanumeric character &d - replaced by printing date &t - replaced by printing time &&- replaced by & character &; - specifies split point &f - filename without path/title **) END; Par* = POINTER TO LIMITED RECORD page*: PageInfo; header*, footer*: Banner; copies-: INTEGER END; Line = RECORD buf: ARRAY 256 OF CHAR; beg: ARRAY maxNrOfSegments OF BYTE; len: INTEGER END; Hook* = POINTER TO ABSTRACT RECORD (Kernel.Hook) END; VAR par*: Par; month: ARRAY 12 * 3 + 1 OF CHAR; printingHook: Hook; PROCEDURE (h: Hook) Print* (v: Views.View; par: Par), NEW, ABSTRACT; PROCEDURE (h: Hook) Current* (): INTEGER, NEW, ABSTRACT; PROCEDURE SetHook* (p: Hook); BEGIN printingHook := p END SetHook; PROCEDURE NewPar* (IN page: PageInfo; IN header, footer: Banner; copies: INTEGER): Par; VAR par: Par; BEGIN NEW(par); par.page := page; par.header := header; par.footer := footer; par.copies := copies; IF par.header.font = NIL THEN par.header.font := Fonts.dir.Default() END; IF par.footer.font = NIL THEN par.footer.font := Fonts.dir.Default() END; RETURN par END NewPar; PROCEDURE NewDefaultPar* (title: Views.Title): Par; VAR par: Par; BEGIN NEW(par); par.page.first := 1; par.page.from := 0; par.page.to := 9999; par.page.alternate := FALSE; par.copies := 1; par.header.gap := 0; par.header.left := ""; par.header.right := ""; par.header.font := Fonts.dir.Default(); par.footer.gap := 0; par.footer.left := ""; par.footer.right := ""; par.header.font := Fonts.dir.Default(); par.page.title := title; RETURN par END NewDefaultPar; PROCEDURE PrintView* (view: Views.View; p: Par); BEGIN ASSERT(view # NIL, 20); ASSERT(p # NIL, 21); ASSERT(par = NIL, 22); (* no recursive printing *) IF Printers.dir.Available() THEN ASSERT(p.page.first >= 0, 23); ASSERT(p.page.from >= 0, 24); ASSERT(p.page.to >= p.page.from, 25); ASSERT(printingHook # NIL, 100); printingHook.Print(view, p) ELSE Dialog.ShowMsg("#System:NoPrinterFound") END END PrintView; PROCEDURE GetDateAndTime (IN date: Dates.Date; IN time: Dates.Time; VAR d, t: ARRAY OF CHAR); VAR i, j, k: INTEGER; s: ARRAY 8 OF CHAR; BEGIN Strings.IntToStringForm (date.day, Strings.decimal, 0, "0", FALSE, d); j := date.month * 3; i := j - 3; k := 0; WHILE i < j DO s[k] := month[i]; INC(k); INC(i) END; s[k] := 0X; d := d + "-" + s; Strings.IntToStringForm (date.year, Strings.decimal, 0, "0", FALSE, s); d := d + "-" + s; Strings.IntToStringForm (time.hour, Strings.decimal, 0, "0", FALSE, t); Strings.IntToStringForm (time.minute, Strings.decimal, 2, "0", FALSE, s); t := t + ":" + s; END GetDateAndTime; PROCEDURE Expand (s: ARRAY OF CHAR; IN date: Dates.Date; IN time: Dates.Time; IN title: Views.Title; pno: INTEGER; printing: BOOLEAN; VAR line: Line); VAR i, l: INTEGER; ch: CHAR; j: BYTE; p, d, t, r, rl: ARRAY 32 OF CHAR; BEGIN IF printing THEN Strings.IntToStringForm (pno, Strings.decimal, 0, "0", FALSE, p); IF (0 < pno) & (pno < 4000) THEN Strings.IntToStringForm(pno, Strings.roman, 0, " ", FALSE, r) ELSE r := p END; ELSE p := "#"; r := "#" END; GetDateAndTime(date, time, d, t); i := 0; ch := s[i]; line.len := 0; j := 0; WHILE ch # 0X DO IF ch = "&" THEN INC(i); ch := s[i]; IF ch = "p" THEN l := 0; WHILE p[l] # 0X DO line.buf[j] := p[l]; INC(j); INC(l) END ELSIF ch = "r" THEN Strings.ToLower(r, rl); l := 0; WHILE rl[l] # 0X DO line.buf[j] := rl[l]; INC(j); INC(l) END ELSIF ch = "R" THEN l := 0; WHILE r[l] # 0X DO line.buf[j] := r[l]; INC(j); INC(l) END ELSIF (ch = "a") OR (ch = "A") THEN IF printing & (0 < pno) & (pno <= 26) THEN line.buf[j] := CHR(pno + ORD(ch) - 1); INC(j) ELSE l := 0; WHILE p[l] # 0X DO line.buf[j] := p[l]; INC(j); INC(l) END END ELSIF ch = "d" THEN l := 0; WHILE d[l] # 0X DO line.buf[j] := d[l]; INC(j); INC(l) END ELSIF ch = "t" THEN l := 0; WHILE t[l] # 0X DO line.buf[j] := t[l]; INC(j); INC(l) END ELSIF ch = "f" THEN l := 0; WHILE title[l] # 0X DO line.buf[j] := title[l]; INC(j); INC(l) END ELSIF ch = ";" THEN IF (line.len < maxNrOfSegments-1) THEN line.beg[line.len] := j; INC(line.len) ELSE line.buf[j] := " "; INC(j) END ELSIF ch = "&" THEN line.buf[j] := "&"; INC(j) END; IF ch # 0X THEN INC(i); ch := s[i] END ELSE line.buf[j] := ch; INC(j); INC(i); ch := s[i] END END; line.buf[j] := 0X; line.beg[line.len] := j; INC(line.len) END Expand; PROCEDURE PrintLine (f: Views.Frame; font: Fonts.Font; x0, x1, y: INTEGER; VAR line: Line); VAR sp, dx, x: INTEGER; i, j, k: INTEGER; buf: ARRAY 128 OF CHAR; BEGIN sp := (x1 - x0 - font.StringWidth(line.buf)); IF line.len = 1 THEN (* center *) f.DrawString(x0 + sp DIV 2, y, Ports.defaultColor, line.buf, font) ELSE IF sp > 0 THEN dx := sp DIV (line.len - 1) ELSE dx := 0 END; k := 0; j := 0; x := x0; WHILE k < line.len DO i := 0; WHILE j < line.beg[k] DO buf[i] := line.buf[j]; INC(i); INC(j) END; buf[i] := 0X; f.DrawString(x, y, Ports.defaultColor, buf, font); x := x + font.StringWidth(buf) + dx; INC(k) END END END PrintLine; PROCEDURE PrintBanner* (f: Views.Frame; IN p: PageInfo; IN b: Banner; IN date: Dates.Date; IN time: Dates.Time; x0, x1, y: INTEGER); VAR line: Line; printing: BOOLEAN; BEGIN printing := par # NIL; IF printing THEN ASSERT(printingHook # NIL, 100); IF p.alternate & ~ODD(p.first + printingHook.Current()) THEN Expand(b.left, date, time, p.title, p.first + printingHook.Current(), printing, line) ELSE Expand(b.right, date, time, p.title, p.first + printingHook.Current(), printing, line) END ELSE Expand(b.right, date, time, p.title, 0, printing, line) END; PrintLine(f, b.font, x0, x1, y, line) END PrintBanner; PROCEDURE Current*(): INTEGER; BEGIN ASSERT(par # NIL, 21); ASSERT(printingHook # NIL, 100); RETURN printingHook.Current() END Current; BEGIN month := "JanFebMarAprMayJunJulAugSepOctNovDec" END Printing.