Windows.Oberon.Printer.Mod 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. (* ETH Oberon, Copyright 2001 ETH Zuerich Institut fuer Computersysteme, ETH Zentrum, CH-8092 Zuerich.
  2. Refer to the "General ETH Oberon System Source License" contract available at: http://www.oberon.ethz.ch/ *)
  3. MODULE Printer IN Oberon; (** portable *) (* jm 26.10.95 *)
  4. (** Module Printer provide an interface for installable printers. *)
  5. IMPORT KernelLog IN A2, Modules, Pictures, Display, Fonts, Texts, Oberon;
  6. CONST
  7. Unit300 = 3048; (* 300 dpi resolution *)
  8. defaultPrinter = "WinPrinter.Install";
  9. TYPE
  10. Printer* = POINTER TO PrinterDesc;
  11. PrinterDesc* = RECORD
  12. res*: INTEGER; (** Result code for Open method. *)
  13. gen*: ARRAY 64 OF CHAR; (** Command used for installing the printer. *)
  14. Height*, Width*, Depth*: INTEGER; (** Page size (in printer pixels), and available colors (bit depth) **)
  15. FrameX*, FrameY*, FrameW*, FrameH*: INTEGER; (** Printable region of the page. *)
  16. Unit*: LONGINT; (** Printer resolution in 1/36000 mm per pixel. *)
  17. InitMetrics*: PROCEDURE (P: Printer);
  18. Open*: PROCEDURE (P: Printer; printer, options: ARRAY OF CHAR); (** Initialize printer & set result code. *)
  19. Close*: PROCEDURE (P: Printer); (** Stop printing & set result code. *)
  20. Page*: PROCEDURE (P: Printer; nofcopies: INTEGER); (** End of page reached. *)
  21. ReplConst*: PROCEDURE (P: Printer; x, y, w, h: INTEGER); (** Block fill. *)
  22. ReplPattern*: PROCEDURE (P: Printer; x, y, w, h: INTEGER; patno: INTEGER); (** Pattern fill. *)
  23. Line*: PROCEDURE (P: Printer; x0, y0, x1, y1: INTEGER); (** Line between (x0, y0) and (x1, y1). *)
  24. Circle*: PROCEDURE (P: Printer; x0, y0, r: INTEGER);
  25. Ellipse*: PROCEDURE (P: Printer; x0, y0, a, b: INTEGER);
  26. Spline*: PROCEDURE (P: Printer; x0, y0, n, open: INTEGER; VAR X, Y: ARRAY OF INTEGER);
  27. Picture*: PROCEDURE (P: Printer; pict: Pictures.Picture; sx, sy, sw, sh, dx, dy, dw, dh, mode: INTEGER);
  28. UseListFont*: PROCEDURE (P: Printer; name: ARRAY OF CHAR);
  29. String*: PROCEDURE (P: Printer; x, y: INTEGER; str: ARRAY OF CHAR; fnt: Fonts.Font);
  30. ContString*: PROCEDURE (P: Printer; str: ARRAY OF CHAR; fnt: Fonts.Font);
  31. UseColor*: PROCEDURE (P: Printer; red, green, blue: INTEGER);
  32. GetMetric*: PROCEDURE (P: Printer; fnt: Fonts.Font): Fonts.Font
  33. END;
  34. VAR
  35. Height*, Width*, Depth*: INTEGER; (** In printer pixels, and bit depth *)
  36. FrameX*, FrameY*, FrameW*, FrameH*: INTEGER; (** Printable area. *)
  37. Unit*: LONGINT; (** Printer resolution in 1/36000 mm per pixel. *)
  38. res*: INTEGER; (** result code. 0 = ok, 1 = no such printer, 2 = no link, 3 = printer not ready, 4 = no permission *)
  39. current*: Printer; (** Current active printer. *)
  40. PROCEDURE SplitName(VAR name, MName, PName: ARRAY OF CHAR);
  41. VAR i, j: LONGINT;
  42. BEGIN i := 0;
  43. WHILE name[i] # "." DO MName[i] := name[i]; INC(i) END;
  44. MName[i] := 0X; INC(i); j := 0;
  45. WHILE name[i] # 0X DO PName[j] := name[i]; INC(i); INC(j) END;
  46. PName[j] := 0X
  47. END SplitName;
  48. PROCEDURE LoadDefaultPrinter;
  49. VAR
  50. S: Texts.Scanner;
  51. s, defMod, defCmd: ARRAY 64 OF CHAR;
  52. Mod: Modules.Module; Cmd: Modules.Command;
  53. BEGIN
  54. current := NIL;
  55. Oberon.OpenScanner(S, "Printer.Default");
  56. IF S.class IN {Texts.Name, Texts.String} THEN
  57. COPY(S.s, s)
  58. ELSE
  59. COPY(defaultPrinter, s)
  60. END;
  61. SplitName(s, defMod, defCmd);
  62. Mod := Modules.ThisMod(defMod);
  63. IF Modules.res = 0 THEN
  64. Cmd := Modules.ThisCommand(Mod, defCmd);
  65. IF Modules.res = 0 THEN
  66. Cmd()
  67. END
  68. ELSE
  69. KernelLog.String("Printer.LoadDefaultPrinter "); KernelLog.String(s); KernelLog.String(" not found"); KernelLog.Ln();
  70. Mod := Modules.ThisMod("WinPrinter");
  71. IF Modules.res = 0 THEN
  72. Cmd := Modules.ThisCommand(Mod, "Install");
  73. IF Modules.res = 0 THEN
  74. Cmd()
  75. END
  76. END
  77. END
  78. END LoadDefaultPrinter;
  79. (** Install printer driver. P.InitMetrics is called to initialise the page metrics. *)
  80. PROCEDURE Install*(P: Printer);
  81. VAR M: Display.ControlMsg; N: Oberon.ControlMsg;
  82. BEGIN
  83. ASSERT(P # NIL, 100);
  84. P.InitMetrics(P);
  85. Width := P.Width; Height := P.Height; Depth := P.Depth;
  86. FrameX := P.FrameX; FrameY := P.FrameY; FrameW := P.FrameW; FrameH := P.FrameH;
  87. Unit := P.Unit; current := P;
  88. N.id := Oberon.neutralize; M.F := NIL; Display.Broadcast(N);
  89. M.id := Display.newprinter; M.F := NIL; Display.Broadcast(M);
  90. M.id := Display.suspend; M.F := NIL; Display.Broadcast(M);
  91. M.id := Display.restore; M.F := NIL; Display.Broadcast(M)
  92. END Install;
  93. (** Open specified printer. res code is set. *)
  94. PROCEDURE Open*(printer, options: ARRAY OF CHAR);
  95. VAR P: Printer;
  96. BEGIN
  97. IF current # NIL THEN
  98. P := current;
  99. P.Open(P, printer, options);
  100. res := P.res;
  101. Width := P.Width; Height := P.Height; Depth := P.Depth;
  102. FrameX := P.FrameX; FrameY := P.FrameY; FrameW := P.FrameW; FrameH := P.FrameH;
  103. Unit := P.Unit
  104. ELSE
  105. res := 1 (* no such printer *)
  106. END
  107. END Open;
  108. PROCEDURE Close*;
  109. VAR P: Printer;
  110. BEGIN
  111. P := current;
  112. P.Close(P);
  113. res := P.res;
  114. Width := P.Width; Height := P.Height; Depth := P.Depth;
  115. FrameX := P.FrameX; FrameY := P.FrameY; FrameW := P.FrameW; FrameH := P.FrameH;
  116. Unit := P.Unit
  117. END Close;
  118. PROCEDURE Page*(nofcopies: INTEGER);
  119. BEGIN
  120. current.Page(current, nofcopies)
  121. END Page;
  122. PROCEDURE ReplConst*(x, y, w, h: INTEGER);
  123. BEGIN
  124. current.ReplConst(current, x, y, w, h)
  125. END ReplConst;
  126. PROCEDURE ReplPattern*(x, y, w, h: INTEGER; patno: INTEGER);
  127. BEGIN
  128. current.ReplPattern(current, x, y, w, h, patno)
  129. END ReplPattern;
  130. PROCEDURE Line*(x0, y0, x1, y1: INTEGER);
  131. BEGIN
  132. current.Line(current, x0, y0, x1, y1)
  133. END Line;
  134. PROCEDURE Circle*(x0, y0, r: INTEGER);
  135. BEGIN
  136. current.Circle(current, x0, y0, r)
  137. END Circle;
  138. PROCEDURE Ellipse*(x0, y0, a, b: INTEGER);
  139. BEGIN
  140. current.Ellipse(current, x0, y0, a, b)
  141. END Ellipse;
  142. PROCEDURE Spline*(x0, y0, n, open: INTEGER; VAR X, Y: ARRAY OF INTEGER);
  143. BEGIN
  144. current.Spline(current, x0, y0, n, open, X, Y)
  145. END Spline;
  146. PROCEDURE Picture*(P: Pictures.Picture; sx, sy, sw, sh, dx, dy, dw, dh, mode: INTEGER);
  147. BEGIN
  148. current.Picture(current, P, sx, sy, sw, sh, dx, dy, dw, dh, mode)
  149. END Picture;
  150. PROCEDURE UseListFont*(name: ARRAY OF CHAR);
  151. BEGIN
  152. current.UseListFont(current, name)
  153. END UseListFont;
  154. PROCEDURE String*(x, y: INTEGER; str: ARRAY OF CHAR; fnt: Fonts.Font);
  155. BEGIN
  156. current.String(current, x, y, str, fnt)
  157. END String;
  158. PROCEDURE ContString*(str: ARRAY OF CHAR; fnt: Fonts.Font);
  159. BEGIN
  160. current.ContString(current, str, fnt)
  161. END ContString;
  162. PROCEDURE UseColor*(red, green, blue: INTEGER);
  163. BEGIN
  164. current.UseColor(current, red, green, blue)
  165. END UseColor;
  166. PROCEDURE GetMetric*(fnt: Fonts.Font): Fonts.Font;
  167. BEGIN
  168. IF current # NIL THEN
  169. RETURN current.GetMetric(current, fnt)
  170. ELSE RETURN NIL
  171. END;
  172. END GetMetric;
  173. BEGIN
  174. Height := 0; Width := 0;
  175. Unit := Unit300;
  176. LoadDefaultPrinter
  177. END Printer.
  178. (** Remarks:
  179. 1. Installing a printer involves calling Printer.Install with a filled-out printer (say P) descriptor. The installed printer is assigned to Printer.current. Immediately after installation, the InitMetrics method is called so that the printer can return its metrics in P.Width, P.Height, P.Depth, P.FrameX, P.FrameY, P.FrameW, P.FrameH, and P.Unit (see next remark also). These variables are copied to the global variables with the same names. Calling procedures of module Printer results in a call to a corresponding method of the currently active printer Printer.current.
  180. 2. The Open method may interpret the user and password for allowing access to a printer. A res code of 0 indicates that the printer has successfully been opened. The Open method must fill in the fields Height, Width, Depth, FrameX, FrameY, FrameW, FrameH, and Unit of the printer descriptor. All values except Unit and Depth are in printer pixels. Typical printers have 300 pixels per inch (commonly abbreviated dots-per-inch (dpi)). Unit specifies the width and height of a single pixel in units of 1/36000 mm. The printer origin 0, 0 is the left bottom corner of the page (and may not be printable). FrameX, FrameY, FrameW, FrameH indicate the printable area of the page. Depth (bits per pixel) has a typical value of 1 (black and white printer) or 24 (true-color printer). A printer must be closed for output to appear.
  181. 3. All coordinates are in printer pixels. Only the first characters of a font name (fname) up to the first period are relevant. Strings are positioned relative to their base-line. A module is free to print anywhere on the page regardless of the printer connected (there is no need to print from the top to the bottom of a page when a line printer is connected).
  182. 4. The printer patterns are defined as follows:
  183. 1 2 3 4 5 6 7 8
  184. 5. UseListFont has no meaning.
  185. 6. The String method keeps track of where the last character ends, allowing ContString to continue from that position.
  186. 7. UseColor takes intensity values in the range 0 <= x < 256 for each color component. Setting a color influences all further drawing operations. Setting the color to white allows you to delete already printer areas (a single page is normally cached in memory).
  187. 8. Method Spline draws a spline through the n points in arrays X, Y. (x0, y0) specifies a translation vector. Open set to 1 indicates an open spline should be drawn, otherwise a closed spline is assumed.
  188. 9. Implementation restriction: On Oberon for Windows nofcopies is ignored and defaults to 1.
  189. 10. Method Picture prints the area sx, sy, sw, sh of a picture onto the area dx, dy, dw, dh of the printer (scaling as needed).
  190. 11. The default printer that is installed at startup is specified in the System section of the registry under key DefaultPrinter. The value of the key must be the name of a command that installs a printer. Windows Oberon supports WinPrinter.Install and PSPrinter.Install. Oberon has to be rebooted before a change will take effect.
  191. System.Set Printer Default := "WinPrinter.Install"
  192. System.Get Printer *)