home *** CD-ROM | disk | FTP | other *** search
/ Archive Magazine 1996 / ARCHIVE_96.iso / discs / mag_discs / volume_8 / issue_06 / risc_os / PDrivers < prev    next >
Text File  |  1988-12-12  |  74KB  |  1,652 lines

  1. This document is intended to tell application authors how to write their
  2. applications so as to make use of the standard RISC OS printer driver
  3. interface. It starts with a general explanation of how the printer drivers
  4. are supposed to be used. Then the SWI interface is described and an example
  5. BASIC procedure is given that shows an application might do its printing. The
  6. final section of the document specifies exactly what VDU sequences and other
  7. plotting operations the application may use while printing.
  8.  
  9.  
  10.  
  11. PRINTER DRIVER PHILOSOPHY
  12. =========================
  13.  
  14.  
  15. What the application user sees
  16. ------------------------------
  17.  
  18. RISC OS comes with two printer driver applications, !PSPrinter for PostScript
  19. printers and !DMPrinter for a range of dot matrix printers.
  20.  
  21. If I possess a PostScript printer and I wish to print, I should do the
  22. following:
  23.  
  24. Double-click on !PSPrinter. An icon will appear. Menu on this and check
  25. that the settings are right for where the printer is connected, e.g.
  26. net/parallel/serial etc. This setting will be retained in CMOS RAM, so it
  27. need only be done once.
  28.  
  29. If I wish to print Text files, drag them onto the printer icon. They will get
  30. printed.
  31.  
  32. If I wish to print from ArcDraw, click Print on the Print dialogue box after
  33. running !PSPrinter. The diagram will be printed. Or, drag the icon from the
  34. Save dialogue box onto the printer icon.
  35.  
  36. If I wish to print from ArcPaint, it's exactly the same.
  37.  
  38. If I with to print from any other editor program, it's exactly the same.
  39.  
  40. If I have a dot matrix printer, run !DMPrinter. Click on the printer icon to
  41. produce a dialogue box of the correct type of printer. Click on the
  42. printer-type field to cycle through the various dot matrix printers
  43. supported, until it reflects mine. If I can't find mine, seek help.
  44.  
  45. Drivers for other printers will appear, from Acorn and from others, in an
  46. analogous form. New printer drivers will work with all existing applications,
  47. subject to the limitations of any particular printing device.
  48.  
  49.  
  50. How and Why
  51. -----------
  52.  
  53. I use the term "editor" to mean any sort of interactive program that
  54. prepares, changes and processes data files. This includes word processors,
  55. DTP packages, spreadsheets, draw programs, etc. I use the term "Foo" to refer
  56. to any editor program, which operates on "Foo data files": so, substitute
  57. ArcDraw, ArcPaint, or whatever as you read. I use the term "Poo" to refer to
  58. any printer capable of generating graphics, e.g. FX80, Apple LaserWriter,
  59. etc.
  60.  
  61. In the general case, editors save data in files of their own format, with an
  62. appropriate file type. Only Foo understands Foo data files. Also, different
  63. printers are entirely different from each other, and a pain to drive. If each
  64. editor is to understand each printer, and there are X editors and Y printers
  65. in the world, then:
  66.  
  67.   (a) There is X*Y work to do
  68.   (b) If a new printer type comes along, all applications need updating.
  69.  
  70. Because of this, RISC OS separates printer drivers from editors so that they
  71. are separate programs. This means:
  72.  
  73.   (a) There is X+Y work to do
  74.   (b) If a new printer type comes along, once a printer driver has been
  75.       written for it, it will work with all applications.
  76.  
  77. This is clearly a better situation, and is one of the main reasons why
  78. applications working together is important.
  79.  
  80. How do we achieve this? The main step is to define an interface that all
  81. editors should use when talking to printers, a sort of "virtual printer
  82. interface". All editors then output to this virtual interface, knowing little
  83. of the characteristics of the physical printer itself.
  84.  
  85. The "virtual printer interface" chosen in RISC OS is to say that the printer
  86. supports a specified subset of the screen graphics primitives. This is
  87. because a WYSIWYG editor (where what you see on the screen is what you get on
  88. paper) will already contain code to render the data file using screen
  89. primitives; provided the application restricts itself to the specified
  90. subset, printing is unlikely to require very much extra code.
  91.  
  92. There are several reasons why not all the screen primitives are supported by
  93. the virtual printer interface. The main ones are:
  94.  
  95.   (a) Some screen primitives are screen hardware specific (e.g. flashing
  96.       colours, hardware palette changes, etc.).
  97.   (b) Some screen primitives are very hard or impossible to implement on
  98.       common types of printer (e.g. PostScript printers cannot handle
  99.       non-overwriting GCOL actions).
  100.   (c) Some screen primitives - e.g. flood fill - cannot be split across
  101.       multiple boxes and so do not work with the window system. The printer
  102.       drivers use a similar interface to the window system and have the same
  103.       problems with these calls as it does.
  104.  
  105. Each printer driver is implemented as a RISC OS relocatable module, which
  106. provides extra SWIs (system calls) concerned with starting, stopping and
  107. controlling a print job. The interface allows the printer driver to ask the
  108. application to render specific rectangles of the picture in any order, to
  109. give the printer driver maximum freedom in manipulating buffer space, etc.
  110.  
  111. The interface to printer drivers means that an editor is not able to supply
  112. an acceptable user interface for setting printer-specific options such as
  113. quality/draft mode. For this reason, a separate application exists for each
  114. possible printer driver, to allow any printer-specific options to be set.
  115.  
  116. The printing of plain text is such a basic facility that it is considered
  117. unacceptable to require the loading of ArcEdit. Furthermore, printers tend to
  118. provide a much simpler method for the printing of simple text than the
  119. facilities provided for arbitrary graphics. For this reason, every printer
  120. interface program provides simple facilities for the printing of plain text
  121. files.
  122.  
  123.  
  124.  
  125. THE SWI INTERFACE
  126. =================
  127.  
  128.  
  129. To send output to the printer, an application must engage in a dialogue with
  130. the printer driver. Parts of this dialogue is similar to the dialogue with
  131. the window manager when a window requires redrawing. The dialogue can be
  132. summarised as follows:
  133.  
  134. The application starts by opening a file to receive the printer driver's
  135. output. Typically this file is "printer:", but any file may be used. It
  136. passes this file's handle to SWI PDriver_SelectJob in order to start a print
  137. job.
  138.  
  139. To output a page, the application then uses SWI PDriver_GiveRectangle to give
  140. the printer driver a list of the rectangles it wants to appear on the page
  141. and where it wants them to appear.
  142.  
  143. When it has specified all the rectangles it wants printed, it uses SWI
  144. PDriver_DrawPage to ask the printer driver for the first rectangle to be
  145. printed. It then prints this rectangle and uses SWI PDriver_GetRectangle to
  146. get another rectangle to print, until there are no further rectangles to
  147. print. This is very similar to the way an application uses SWI
  148. Wimp_RedrawWindow and SWI Wimp_GetRectangle when redrawing its window.
  149.  
  150. When all the desired pages have been output in this manner, the application
  151. first uses SWI PDriver_EndJob to end the print job, then closes the output
  152. file.
  153.  
  154. The full set of printer driver SWIs is as follows:
  155.  
  156.  
  157. SWI PDriver_Info (&80140)
  158. -------------------------
  159.  
  160.   Entry: -
  161.  
  162.   Exit:  R0 (top 16 bits) identifies general type of printer driven.
  163.             Current assignments:
  164.               0 = PostScript printers.
  165.               1 = FX80 and similar dot matrix printers.
  166.          R0 (bottom 16 bits) = 100 * version number of printer driver.
  167.          R1 = X pixel resolution of printer driven (pixels/inch).
  168.          R2 = Y pixel resolution of printer driven (pixels/inch).
  169.          R3 = features word:
  170.               Bit 0 set => colour
  171.               If bit 0 set, bit 1 set => full colour range not available.
  172.               Bit 2 set => only a discrete set of colours supported.
  173.               Bit 8 set => cannot handle filled shapes well.
  174.               Bit 9 set => cannot handle thick lines well.
  175.               Bit 10 set => cannot handle overwriting well.
  176.               Bit 24 set => supports the PDriver_ScreenDump call.
  177.               Bit 25 set => supports arbitrary transformations (else only
  178.                             axis-preserving ones).
  179.          R4 -> adjectival description of printers supported (a maximum of 20
  180.               characters, excluding the zero-termination).
  181.          R5 = X halftone resolution (repeats/inch). If no halftoning is done,
  182.               this is equal to the value returned in R1.
  183.          R6 = Y halftone resolution (repeats/inch). If no halftoning is done,
  184.               this is equal to the value returned in R2.
  185.          R7 identifies a specific configured printer. Assignments of these
  186.               numbers are specific to each printer driver.
  187.  
  188. Some of these values can be changed by the configuration application
  189. associated with the printer driver (using SWI PDriver_SetInfo). If SWI
  190. PDriver_Info is called while a print job is selected, the values returned are
  191. those that were in effect when that print job was started (i.e. when it was
  192. first selected using PDriver_SelectJob). If SWI PDriver_Info is called when
  193. no print job is active, the values returned are those that would be used for
  194. a new print job.
  195.  
  196. The printer/driver features word returned in R3 describes the various ways
  197. in which the printers supported differ from a "standard" printer. Most
  198. applications need not look at this word, but sophisticated ones may want to
  199. in order to ensure that the printer can handle their output, or to adjust
  200. their output to the printer being used.
  201.  
  202. In more detail than above, the bits in R3 have the following meanings:
  203.  
  204. Bits 0-7 relate to the printer/driver's colour capabilities:
  205.  
  206. Bit 0 = 0:  It can only print grey colours. (I.e. it produces monochrome
  207.             output.)
  208. Bit 0 = 1:  It supports at least some non-grey colours.
  209.  
  210. Bit 1 is irrelevant if bit 0 = 0. Otherwise:
  211. Bit 1 = 0:  It supports the full colour range - i.e. it can manage each of
  212.             the eight primary colours (white, yellow, cyan, green, magenta,
  213.             red, blue, black).
  214. Bit 1 = 1:  It supports only a limited set of colours (this would typically
  215.             be set e.g. for an XY-plotter which only had black, red, blue and
  216.             green pens loaded).
  217.  
  218. Bit 2 = 0:  It supports a semi-continuous range of colours at the software
  219.             level (e.g. if bit 0 = 0 and bit 2 = 0, the application can
  220.             expect to be able to plot a reasonable approximation to any
  221.             grey).
  222. Bit 2 = 1:  It only supports a discrete set of colours at the software level
  223.             - for example, an XY-plotter would probably set this bit, not
  224.             having many pen colours, nor being able to mix its pen colours
  225.             sensibly by halftoning, dithering or any similar technique.
  226.  
  227. Bits 3-7 are reserved - current printer drivers will set them to zero.
  228.  
  229. Bits 8-15 relate to the printer/driver's plotting capabilities:
  230.  
  231. Bit 8 = 0:  It can handle filled shapes.
  232. Bit 8 = 1:  It cannot handle filled shapes other than by outlining them (e.g.
  233.             an unsophisticated XY-plotter driver would have this bit set).
  234.  
  235. Bit 9 = 0:  It can handle thick lines.
  236. Bit 9 = 1:  It cannot handle thick lines other than by plotting a thin line.
  237.             (Unsophisticated XY-plotter drivers might again come into this
  238.             category. It differs from the filled shape criterion in bit 8 in
  239.             that it can be solved, at least partially, if the plotter has a
  240.             range of pens of differing thicknesses available.)
  241.  
  242. Bit 10 = 0: It handles overwriting of one colour by another on the paper
  243.             properly (this is generally true of any printer/driver that
  244.             buffers its output, either in the printer or in the driver).
  245. Bit 10 = 1: It does not handle overwriting of one colour by another properly
  246.             - only overwriting of the background colour by another. (Again,
  247.             this is a standard property of XY-plotters.)
  248.  
  249. Bits 11-15 are reserved - current printer drivers will set them to zero.
  250.  
  251. Bits 16-23 are reserved - current printer drivers will set them to zero.
  252.  
  253. Bits 24-31 relate to optional features of the printer driver:
  254.  
  255. Bit 24 = 0: This printer driver does not support screen dumps.
  256. Bit 24 = 1: This printer driver does support screen dumps.
  257.  
  258. Bit 25 = 0: This printer driver does not support transformations (supplied
  259.             to PDriver_DrawPage) other than scalings, translations, rotations
  260.             by multiples of 90 degrees and combinations thereof.
  261. Bit 25 = 1: This printer driver supports arbitrary transformations supplied
  262.             to PDriver_DrawPage.
  263.  
  264. Bits 25-31 are reserved - current printer drivers will set them to zero.
  265.  
  266.  
  267. SWI PDriver_SetInfo (&80141)
  268. ----------------------------
  269.  
  270.   Entry: R1 = X pixel resolution of printer driven (pixels/inch).
  271.          R2 = Y pixel resolution of printer driven (pixels/inch).
  272.          R3 (bit 0) is zero to set monochrome, 1 to set colour. The other
  273.               bits of R3 are ignored.
  274.          R5 = X halftone resolution (repeats/inch). If no halftoning is to be
  275.               done, this should be equal to the value in R1.
  276.          R6 = Y halftone resolution (repeats/inch). If no halftoning is to be
  277.               done, this should be equal to the value in R2.
  278.          R7 identifies a specific configured printer.
  279.  
  280.   Exit:  -
  281.  
  282. The configuration application associated with a particular printer driver
  283. uses this SWI to change the information values associated with subsequent
  284. print jobs. In general, no other application should use this SWI.
  285.  
  286.  
  287. SWI PDriver_CheckFeatures (&80142)
  288. ----------------------------------
  289.  
  290.   Entry: R0 = features word mask.
  291.          R1 = features word value.
  292.  
  293.   Exit:  If the features word that PDriver_Info would return in R3 satisfies
  294.          ((features word) AND R0) = (R1 AND R0), return is normal with all
  295.          registers preserved. Otherwise a suitable error is generated, if
  296.          appropriate - e.g. no error will be generated if the printer driver
  297.          has the ability to support arbitrary rotations and your features
  298.          word value merely requests axis-preserving ones.
  299.  
  300. This call may be used by an application to check that the current printer
  301. driver has the features it requires, and to generate a suitable descriptive
  302. error if it doesn't.
  303.  
  304.  
  305. SWI PDriver_PageSize (&80143)
  306. -----------------------------
  307.  
  308.   Entry: -
  309.  
  310.   Exit:  R1 = X size of paper, including margins. (Units 1/72000 inch)
  311.          R2 = Y size of paper, including margins. (Units 1/72000 inch)
  312.          R3 = left edge of printable area of paper, relative to the left edge
  313.               of the paper. (Units 1/72000 inch)
  314.          R4 = bottom edge of printable area of paper, relative to the bottom
  315.               edge of the paper. (Units 1/72000 inch)
  316.          R5 = right edge of printable area of paper, relative to the left
  317.               edge of the paper. (Units 1/72000 inch)
  318.          R6 = top edge of printable area of paper, relative to the bottom
  319.               edge of the paper. (Units 1/72000 inch)
  320.  
  321. An application can use this call to find out how big the paper in use is and
  322. how large the printable area on the paper is. This information can then be
  323. used to decide how to place the data to be printed on the page.
  324.  
  325. These values can be changed by the configuration application associated with
  326. the printer driver (using SWI PDriver_SetPageSize). If SWI PDriver_PageSize
  327. is called while a print job is selected, the values returned are those that
  328. were in effect when that print job was started (i.e. when it was first
  329. selected using PDriver_SelectJob). If SWI PDriver_PageSize is called when no
  330. print job is active, the values returned are those that would be used for a
  331. new print job.
  332.  
  333.  
  334. SWI PDriver_SetPageSize (&80144)
  335. --------------------------------
  336.  
  337.   Entry: R1 = X size of paper, including margins. (Units 1/72000 inch)
  338.          R2 = Y size of paper, including margins. (Units 1/72000 inch)
  339.          R3 = left edge of printable area of paper, relative to the left edge
  340.               of the paper. (Units 1/72000 inch)
  341.          R4 = bottom edge of printable area of paper, relative to the bottom
  342.               edge of the paper. (Units 1/72000 inch)
  343.          R5 = right edge of printable area of paper, relative to the left
  344.               edge of the paper. (Units 1/72000 inch)
  345.          R6 = top edge of printable area of paper, relative to the bottom
  346.               edge of the paper. (Units 1/72000 inch)
  347.  
  348.   Exit:  -
  349.  
  350. The configuration application associated with a particular printer driver
  351. uses this SWI to change the page size values associated with subsequent print
  352. jobs. In general, no other application should use this SWI.
  353.  
  354.  
  355. SWI PDriver_SelectJob (&80145)
  356. ------------------------------
  357.  
  358.   Entry: R0 = file handle for print job to be selected, or zero to cease
  359.               having any print job selected.
  360.          R1 is zero or points to a title string for the job. This title
  361.               string is terminated by any character outside the range ASCII
  362.               32-126.
  363.  
  364.   Exit:  R0 = file handle for print job that was previously active, or zero
  365.               if no print job was active.
  366.  
  367. A print job is identified by a file handle, which must be that of a file that
  368. is open for output. The printer output for the job concerned is sent to this
  369. file.
  370.  
  371. Calling SWI PDriver_SelectJob with R0=0 will cause the current print job (if
  372. any) to be suspended, and the printer driver will cease intercepting plotting
  373. calls.
  374.  
  375. Calling SWI PDriver_SelectJob with R0 containing a file handle will cause the
  376. current print job (if any) to be suspended, and a print job with the given
  377. file handle to be selected. If a print job with this file handle already
  378. exists, it is resumed; otherwise a new print job is started. The printer
  379. driver will start to intercept plotting calls if it is not already doing so.
  380.  
  381. Note that this call never ends a print job - to do so, use one of SWI
  382. PDriver_EndJob and SWI PDriver_AbortJob.
  383.  
  384. The title string pointed to by R1 is treated by different printer drivers in
  385. different ways. It is only ever used if a new print job is being started, not
  386. when an old one is being resumed. Typical uses are:
  387.  
  388.   (a) A simple printer driver might ignore it.
  389.   (b) The PostScript printer driver adds a line "%%Title: " followed by the
  390.       given title string to the PostScript header it generates.
  391.   (c) Printer drivers whose output is destined for an expensive central
  392.       printer in a large organisation might use it when generating a cover
  393.       sheet for the document.
  394.  
  395. An application is always entitled not to supply a title (by setting R1=0),
  396. and a printer driver is entitled to ignore any title supplied.
  397.  
  398. Printer drivers may also use the following OS variables when creating cover
  399. sheets, etc.:
  400.  
  401.   PDriver$For     - indicates who the output is intended to go to.
  402.   PDriver$Address - indicates where to send the output.
  403.  
  404. These variables should not contain characters outside the range ASCII 32-126.
  405.  
  406. If an error occurs during PDriver_SelectJob, the previous job will still be
  407. selected afterwards (though it may have been de-selected and re-selected
  408. during the call). No new job will exist (one may have been created during
  409. the call, but the error will cause it to be destroyed again).
  410.  
  411.  
  412. SWI PDriver_CurrentJob (&80146)
  413. -------------------------------
  414.  
  415.   Entry: -
  416.  
  417.   Exit:  R0 = file handle for print job that is currently active, or zero if
  418.               no print job is active.
  419.  
  420.  
  421. SWI PDriver_FontSWI (&80147)
  422. ----------------------------
  423.  
  424. This SWI is part of the internal interface between the font system and
  425. printer drivers. Applications should not call it.
  426.  
  427.  
  428. SWI PDriver_EndJob (&80148)
  429. ---------------------------
  430.  
  431.   Entry: R0 = file handle for print job to be ended.
  432.  
  433.   Exit:  -
  434.  
  435. This SWI should be used to end a print job normally. This may result in
  436. further printer output - e.g. the PostScript printer driver will produce the
  437. standard trailer comments.
  438.  
  439. If the print job being ended is the currently active one, there will be no
  440. current print job after this call (so plotting calls will no longer be
  441. intercepted).
  442.  
  443. If the print job being ended is not currently active, it will be ended
  444. without altering which print job is currently active or whether plotting
  445. calls are being intercepted.
  446.  
  447.  
  448. SWI PDriver_AbortJob (&80149)
  449. -----------------------------
  450.  
  451.   Entry: R0 = file handle for print job to be aborted.
  452.  
  453.   Exit:  -
  454.  
  455. This SWI should be used to end a print job abnormally - it should generally
  456. be called after errors while printing. It will not try to produce any
  457. further printer output - this is important if an error occurs while sending
  458. output to the print job's output file.
  459.  
  460. If the print job being aborted is the currently active one, there will be no
  461. current print job after this call (so plotting calls will no longer be
  462. intercepted).
  463.  
  464. If the print job being aborted is not currently active, it will be aborted
  465. without altering which print job is currently active or whether plotting
  466. calls are being intercepted.
  467.  
  468. Application authors should note (a) that many error messages reported by the
  469. printer driver are buffered within a print job's workspace; (b) that aborting
  470. the print job with this call (or with PDriver_Reset) releases the print job's
  471. workspace back to the heap. So if (as is likely) the application wants to
  472. report the error after issuing SWI PDriver_AbortJob, it should take a copy of
  473. the error number and message first. (This is even more important if the
  474. application is going to close the output file before reporting the error, as
  475. filing systems are quite liable to claim some workspace from the heap
  476. temporarily while closing the file.)
  477.  
  478.  
  479. SWI PDriver_Reset (&8014A)
  480. --------------------------
  481.  
  482.   Entry: -
  483.  
  484.   Exit:  -
  485.  
  486. This SWI aborts all print jobs known to the printer driver, leaving the
  487. printer driver with no active or suspended print jobs and ensuring that
  488. plotting calls are not being intercepted.
  489.  
  490. Normal applications shouldn't use this SWI, but it can be useful as an
  491. emergency recovery measure when developing an application.
  492.  
  493. A call to this SWI is generated automatically if the machine is reset or the
  494. printer driver module is killed or RMTIDYed.
  495.  
  496.  
  497. SWI PDriver_GiveRectangle (&8014B)
  498. ----------------------------------
  499.  
  500.   Entry: R0 = rectangle identification word. This word is reported back to
  501.               the application when it is requested to plot all or part of
  502.               this rectangle.
  503.          R1 -> 4 word block, containing rectangle to be plotted. Units are OS
  504.               units.
  505.          R2 -> 4 word block, containing dimensionless transformation to be
  506.               applied to the specified rectangle before printing it. The
  507.               entries are given as fixed point numbers with 16 binary places,
  508.               so the transformation is:
  509.                 x' = (x * R2!0 + y * R2!8)/2^16
  510.                 y' = (x * R2!4 + y * R2!12)/2^16
  511.          R3 -> 2 word block, containing the position where the bottom left
  512.               corner of the rectangle is to be plotted on the printed page.
  513.               Units are 1/72000 inch.
  514.          R4 = background colour for this rectangle, in the form &BBGGRRXX.
  515.  
  516. Exit:  -
  517.  
  518. This SWI allows an application to specify a rectangle from its workspace to
  519. be printed, how it is to be transformed and where it is to appear on the
  520. printed page. An application should make one or more calls to SWI
  521. PDriver_GiveRectangle before a call to SWI PDriver_DrawPage and the
  522. subsequent calls to SWI PDriver_GetRectangle. (Multiple calls allow the
  523. application to print multiple rectangles from its workspace to one printed
  524. page - e.g. for "two up" printing).
  525.  
  526. The printer driver may subsequently ask the application to plot the specified
  527. rectangles or parts thereof in any order it chooses. An application should
  528. not make any assumptions about this order or whether the rectangles it
  529. specifies will be split. (A common reason why a printer driver might split a
  530. rectangle is that it prints the page in strips to avoid using excessively
  531. large page buffers.)
  532.  
  533. Assuming that a non-zero number of copies is requested and that none of the
  534. requested rectangles go outside the area available for printing, it is
  535. certain to ask the application to plot everything requested at least once. It
  536. may ask for some areas to be plotted more than once, even if only one copy is
  537. being printed, and it may ask for areas marginally outside the requested
  538. rectangles to be plotted (this can typically happen if the boundaries of the
  539. requested rectangles are not on exact device pixel boundaries).
  540.  
  541. If SWI PDriver_GiveRectangle is used to specify a set of rectangles that
  542. overlap on the output page, the rectangles will be printed in the order of
  543. the SWI PDriver_GiveRectangle calls. For appropriate printers (i.e. most
  544. printers, but not e.g. XY plotters), this means that rectangles supplied via
  545. later PDriver_GiveRectangle calls will overwrite rectangles supplied via
  546. earlier calls.
  547.  
  548.  
  549. SWI PDriver_DrawPage (&8014C)
  550. -----------------------------
  551.  
  552.   Entry: R0 = number of copies to print.
  553.          R1 -> 4 word block, to receive the rectangle to print.
  554.          R2 is zero or contains the page's sequence number within the
  555.               document being printed (i.e. 1-n for an n-page document).
  556.          R3 is zero or points to a string, terminated by a character in the
  557.               ASCII range 33-126 (note spaces are not allowed), which gives
  558.               the 'real' page number. (Examples: "23", "viii", "A-1")
  559.  
  560.   Exit:  R0 = number of copies still requiring printing. This is zero if and
  561.               only if no more plotting is required.
  562.          If R0 is non-zero, the area pointed to by R1 has been filled in with
  563.               the rectangle that needs to be plotted, and R2 contains the
  564.               rectangle identification word for the user-specified rectangle
  565.               that this is a part of.
  566.          If R0 is zero, the contents of R2 and the area pointed to by R1 are
  567.               undefined.
  568.  
  569. This SWI should be called after all rectangles to be plotted on the current
  570. page have been specified (using SWI PDriver_GiveRectangle). It returns the
  571. first rectangle that the printer driver wants plotted in the area pointed to
  572. by R1. If nothing requires plotting - i.e. if there is no such rectangle - it
  573. returns R0=0.
  574.  
  575. So the application should stop trying to plot the current page if R0=0, and
  576. continue otherwise. If R0<>0, the fact that R0 is the number of copies still
  577. to be printed is only intended to be used for information purposes (e.g.
  578. putting a "Printing page m of n" message on the screen); as long as it is
  579. non-zero, R0's value does not affect what the application should try to plot.
  580.  
  581. The information passed in R2 and R3 is not particularly important, though it
  582. helps to make output produced by the PostScript printer driver conform better
  583. to Adobe's structuring conventions. If non-zero values are supplied, they
  584. should be correct. Note that R2 is NOT the sequence number of the page in the
  585. print job, but in the document.
  586.  
  587. An example: if a document consists of 11 pages, numbered "" (the title page),
  588. "i"-"iii" and "1"-"7", and the application is requested to print the entire
  589. preface part, it should use R2 = 2, 3, 4 and R3 -> "i", "ii", "iii" for the
  590. three pages.
  591.  
  592. When plotting starts in a rectangle supplied by a printer driver, the printer
  593. driver behaves as though the VDU system is in the following state:
  594.  
  595.   * VDU drivers enabled.
  596.   * VDU 5 state has been set up.
  597.   * all graphics cursor positions and the graphics origin have been set to
  598.     (0,0).
  599.   * the current dot pattern for dotted lines plotted via VDU calls is
  600.     &AA,&AA,&AA,&AA,&AA,&AA,&AA,&AA, with a repeat length of 8.
  601.   * a VDU 5 character size and spacing of 16 OS units by 32 OS units.
  602.   * the graphics clipping region has been set to bound the actual area that
  603.     is to be plotted. (But note that an application cannot read what this
  604.     area is: the printer drivers do not - and cannot - intercept
  605.     OS_ReadVduVariables or OS_ReadModeVariable.)
  606.   * the area in which plotting will actually take place has been cleared to
  607.     the background colour supplied in the corresponding PDriver_GiveRectangle
  608.     call, as though a CLG had occurred.
  609.   * the cursor movement control bits (i.e. the ones that would be set by
  610.     VDU 23,16,...) are set to &40 - i.e. cursor movement is normal, except
  611.     that movements beyond the edge of the graphics window in VDU 5 mode do
  612.     not generate special actions.
  613.   * one OS unit on the paper is 1/180 inch.
  614.  
  615. This is designed to be as similar as possible to the state set up by the
  616. window manager when redrawing.
  617.  
  618.  
  619. SWI PDriver_GetRectangle (&8014D)
  620. ---------------------------------
  621.  
  622.   Entry: R1 -> 4 word block, to receive the rectangle to print.
  623.  
  624.   Exit:  R0 = number of copies still requiring printing. This is zero if and
  625.               only if no more plotting is required.
  626.          If R0 is non-zero, the area pointed to by R1 has been filled in with
  627.               the rectangle that needs to be plotted, and R2 contains the
  628.               rectangle identification word for the user-specified rectangle
  629.               that this is a part of.
  630.          If R0 is zero, the contents of R2 and the area pointed to by R1 are
  631.               undefined.
  632.  
  633. This SWI should be used after plotting a rectangle returned by a previous
  634. call to SWI PDriver_DrawPage or SWI PDriver_GetRectangle, to get the next
  635. rectangle the printer driver wants plotted. It returns precisely the same
  636. information as PDriver_DrawPage.
  637.  
  638.  
  639. SWI PDriver_CancelJob (&8014E)
  640. ------------------------------
  641.  
  642.   Entry: R0 = file handle for job to be cancelled.
  643.  
  644.   Exit:  -
  645.  
  646. This SWI causes subsequent attempts to output to the print job associated
  647. with the given file handle to do nothing other than generate the error "Print
  648. cancelled". An application is expected to respond to this error by aborting
  649. the print job.
  650.  
  651.  
  652. SWI PDriver_ScreenDump (&8014F)
  653. -------------------------------
  654.  
  655.   Entry: R0 = file handle of file to receive the dump.
  656.  
  657.   Exit:  -
  658.  
  659. If this SWI is supported (i.e. if bit 24 is set in the value SWI PDriver_Info
  660. returns in R3), this SWI causes the printer driver to output a screen dump to
  661. the file handle supplied in R0. The file concerned should be open for output.
  662.    If the SWI is not supported, an error is returned.
  663.  
  664.  
  665. SWI PDriver_EnumerateJobs (&80150)
  666. ----------------------------------
  667.  
  668.   Entry: R0 = 0 to get file handle of first print job, or file handle of a
  669.               print job to get the file handle of the next print job.
  670.   Exit:  R0 = file handle of print job requested, or 0 if there are no more
  671.               print jobs.
  672.  
  673. This allows the print jobs that exist to be enumerated. The order in which
  674. they appear is undefined.
  675.  
  676.  
  677. SWI PDriver_SetPrinter (&80151)
  678. -------------------------------
  679.  
  680.   Entry: Printer-driver specific.
  681.   Exit:  Printer-driver specific.
  682.  
  683. This allows the setting of options specific to a particular printer driver.
  684. See the individual printer driver documentation for details. In general,
  685. this SWI is used by the configuration application associated with the
  686. printer driver module and no other application should use it.
  687.  
  688.  
  689.  
  690. EXAMPLE BASIC PROCEDURE
  691. =======================
  692.  
  693.  
  694. An example BASIC procedure that does a standard "two up" printing job:
  695.  
  696.   DEFPROCprintout(firstpage%, lastpage%, title$, filename$)
  697.     :
  698.     REM Get SWI numbers used in this procedure.
  699.     LOCAL select%, abort%, pagesize%, giverect%, drawpage%, getrect%, end%
  700.     SYS "OS_SWINumberFromString",,"PDriver_SelectJob" TO select%
  701.     SYS "OS_SWINumberFromString",,"PDriver_AbortJob" TO abort%
  702.     SYS "OS_SWINumberFromString",,"PDriver_PageSize" TO pagesize%
  703.     SYS "OS_SWINumberFromString",,"PDriver_GiveRectangle" TO giverect%
  704.     SYS "OS_SWINumberFromString",,"PDriver_DrawPage" TO drawpage%
  705.     SYS "OS_SWINumberFromString",,"PDriver_GetRectangle" TO getrect%
  706.     SYS "OS_SWINumberFromString",,"PDriver_EndJob" TO end%
  707.     :
  708.     REM Open destination file and set up a local error handler that will
  709.     REM close it again on an error. Note that our local error handlers
  710.     REM take copies of error messages and numbers: this avoids the danger
  711.     REM that they will be lost when a print job is aborted or a subsequent
  712.     REM file operation occurs.
  713.     LOCAL H%, O%
  714.     H% = OPENOUT(filename$)
  715.     LOCAL e%, e$
  716.     LOCAL ERROR
  717.     ON ERROR LOCAL:RESTORE ERROR:PROCrderr:CLOSE#H%:PROCerr
  718.     :
  719.     REM Start up a print job associated with this file, remembering the
  720.     REM handle associated with the previous print job (if any), then set up a
  721.     REM a local error handler for it.
  722.     SYS select%,H%,title$ TO O%
  723.     LOCAL ERROR
  724.     ON ERROR LOCAL:RESTORE ERROR:PROCrderr:SYSabort%,H%:SYSselect%,O%:PROCerr
  725.     :
  726.     REM Now we decide how two pages are to fit on a piece of paper.
  727.     LOCAL left%, bottom%, right%, top%
  728.     PROCgetdocumentsize(box%)
  729.     SYS pagesize% TO ,,,left%,bottom%,right%,top%
  730.     PROCfittwopages(left%,bottom%,right%,top%,box%,matrix%,origin1%,origin2%)
  731.     :
  732.     REM Start the double page loop
  733.     LOCAL page%, copiesleft%, pagetoprint%, white%
  734.     white%=&FFFFFF00
  735.     FOR page%=firstpage% TO lastpage% STEP 2
  736.       :
  737.       REM Set up to print two pages, or possibly just one if an odd number of
  738.       REM pages are being printed and this is the last time around.
  739.       SYS giverect%, page%, box%, matrix%, origin1%, white%
  740.       IF page%<lastpage% THEN
  741.         SYS giverect%, page%+1, box%, matrix%, origin2%, white%
  742.       ENDIF
  743.       :
  744.       REM Start printing. As each printed page corresponds to two document
  745.       REM pages, we cannot easily assign any sensible page numbers to printed
  746.       REM pages. So we simply pass zeroes to PDriver_DrawPage.
  747.       SYS drawpage%,1,box2%,0,0 TO copiesleft%,,pagetoprint%
  748.       WHILE copiesleft%<>0
  749.         PROCprintpage(pagetoprint%, box2%)
  750.         SYS getrect%,,box% TO copiesleft%,,pagetoprint%
  751.       ENDWHILE
  752.       :
  753.     REM End of page loop
  754.     NEXT
  755.     :
  756.     REM All pages have now been printed. Terminate this print job.
  757.     SYS end%,H%
  758.     :
  759.     REM Go back to the first of our local error handlers.
  760.     RESTORE ERROR
  761.     :
  762.     REM And go back to whatever print job was active on entry to this
  763.     REM procedure (or to no print job in no print job was active).
  764.     SYS select%,O%
  765.     :
  766.     REM Go back to the caller's error handler.
  767.     RESTORE ERROR
  768.     :
  769.     REM Close the destination file.
  770.     CLOSE#H%
  771.   ENDPROC
  772.   :
  773.   REM Procedure to take a copy of the current error report
  774.   DEFPROCrderr
  775.     e%=ERR: e$=REPORT$
  776.   ENDPROC
  777.   :
  778.   REM Procedure to re-report the error last registered with PROCrderr, with
  779.   REM a backtrace error line attached to it.
  780.   DEFPROCerr
  781.     ERROR e%,e$+" (from line "+STR$(ERL)+")"
  782.   ENDPROC
  783.  
  784. This uses the following global areas of store:
  785.  
  786.   box%:     4 words
  787.   box2%:    4 words
  788.   matrix%:  4 words
  789.   origin1%: 2 words
  790.   origin2%: 2 words 
  791.  
  792. And the following external procedures:
  793.  
  794. DEFPROCgetdocumentsize(box%)
  795.   - fills the area pointed to by 'box%' with the size of a document page in
  796.     OS units.
  797.  
  798. DEFPROCfittwopages(l%, b%, r%, t%, box%, transform%, org1%, org2%)
  799.   - given left, bottom, right and top bounds of a piece of paper in units of
  800.     1/72000 inch, and a bounding box of a document page in OS units, sets up
  801.     a transformation and two origins in the areas pointed to by 'tr%','org1%'
  802.     and 'org2%' to print two of those pages on a piece of paper.
  803.  
  804. DEFPROCdrawpage(page%, box%)
  805.   - draw the parts of document page number 'page%' that lie with the box held
  806.     in the 4 word area pointed to by 'box%'.
  807.  
  808. If printing is likely to take a long time and the application does not want
  809. to hold other applications up while it prints, it should regularly use a
  810. sequence like the following during printing:
  811.  
  812.   SYS select%,O%
  813.   SYS "Wimp_Poll",mask%,area% TO reason%
  814.   <process reason% as appropriate>
  815.   SYS select%,H% TO O%
  816.  
  817.  
  818.  
  819. THE VIRTUAL PRINTER INTERFACE
  820. =============================
  821.  
  822.  
  823. When a print job is active, the printer driver intercepts the following
  824. vectors:
  825.  
  826.   (a) WrchV (= WriteCV): all character output is received and interpreted by
  827.       the printer driver. Many VDU sequences are converted into printer
  828.       output to do similar things on the printed page. Some VDU sequences
  829.       produce errors. A few are passed through to the real VDU drivers. Only
  830.       these last go through the usual output stream selection controlled by
  831.       OS_Byte 3.
  832.         See the section entitled 'VDU SEQUENCES' below for more details.
  833.  
  834.   (b) SpriteV: most sprite operations are passed on unchanged to the
  835.       SpriteExtend module and/or the operating system. Those that do sprite
  836.       plotting are intercepted and generate printer output to do similar
  837.       sprite plotting on the printed page.
  838.         Note that, because of the way vector interception is done, the
  839.       SpriteExtend module must be initialised before the printer driver.
  840.         See the section entitled 'SPRITE OPERATIONS' below for more details.
  841.  
  842.   (c) DrawV: Draw calls that would not normally plot to the screen are passed
  843.       on unchanged to the Draw module. Others are intercepted and, where
  844.       possible, used to generate printer output to do similar things on the
  845.       printed page. However, some of the intercepted calls cannot be so
  846.       treated and instead produce errors.
  847.         Note that, because of the way vector interception is done, the
  848.       Draw module must be initialised before the printer driver.
  849.         See the section entitled 'DRAW MODULE CALLS' below for more details.
  850.  
  851.   (d) ColourV: some ColourTrans calls are intercepted and processed by the
  852.       printer driver, others are left to be dealt with by the ColourTrans
  853.       module itself.
  854.         Note that, because of the way vector interception is done, the
  855.       ColourTrans module must be initialised before the printer driver.
  856.         See the section entitled 'COLOURTRANS MODULE CALLS' below for more
  857.       details.
  858.  
  859.   (e) ByteV: The OS_Byte calls dealing with dot-dash repeat lengths (OS_Byte
  860.       163,242,0-64) are intercepted and processed by the printer driver. The
  861.       same applies to OS_Byte 218 (read/write bytes in VDU queue).
  862.         See the section entitled 'MISCELLANEOUS CALLS' below for more
  863.       details.
  864.  
  865. In addition, the font manager and the printer driver interact to cause many
  866. of the font manager calls to be processed by the printer driver. See the
  867. section entitled 'FONT MANAGER CALLS' below for more details.
  868.  
  869.  
  870.  
  871. VDU SEQUENCES
  872. =============
  873.  
  874.  
  875. General rules
  876. -------------
  877.  
  878. Whenever a print job is active, the printer driver will intercept all
  879. characters sent through WrchV. It will then queue them in the same way as the
  880. VDU drivers do and process complete VDU sequences as they appear. Because the
  881. printer driver will not pick up any data currently in the VDU queue, and may
  882. send sequences of its own to the VDU drivers, a print job should not be
  883. selected with an incomplete sequence in the VDU queue.
  884.  
  885. Also, because the printer driver may send sequences of its own to the VDU
  886. drivers, the output stream specification set by OS_Byte 3 should be in its
  887. standard state (i.e. as though set by OS_Byte 3,0).
  888.  
  889. The printer driver will pass the following VDU sequences through to the
  890. normal VDU drivers, either because they control the screen hardware or
  891. because they affect global resources such as the character and ECF
  892. definitions:
  893.  
  894.   VDU 7                         - Produce bell sound
  895.   VDU 19,l,p,r,g,b              - Change hardware palette
  896.   VDU 20                        - Set default hardware palette
  897.   VDU 23,0,n,m|                 - "Program 6845 registers"
  898.   VDU 23,1,n|                   - Change cursor appearance
  899.   VDU 23,2-5,a,b,c,d,e,f,g,h    - Set ECF pattern
  900.   VDU 23,9-10,n|                - Set flash durations
  901.   VDU 23,11|                    - Set default ECF patterns
  902.   VDU 23,12-15,a,b,c,d,e,f,g,h  - Simple setting of ECF pattern
  903.   VDU 23,17,4,m|                - Set ECF type
  904.   VDU 23,17,6,x;y;|             - Set ECF origin
  905.   VDU 23,32-255,a,b,c,d,e,f,g,h - Define character
  906.  
  907. The printer driver will interpret or fault all other VDU sequences. If the
  908. printer driver currently wants a rectangle printed (i.e. if there has been a
  909. call to SWI PDriver_DrawPage or SWI PDriver_GetRectangle and the last such
  910. call returned R0 <> 0), these will result in it producing appropriate output
  911. or errors. Otherwise, the printer driver will keep track of some state
  912. information (e.g. what the current foreground and background colours are),
  913. but will not produce any printer output.
  914.  
  915. The printer driver will always behave as though it is in VDU 5 state. No text
  916. co-ordinate system is defined, and no scrolling is possible. For these
  917. reasons, the following VDU sequences are faulted:
  918.  
  919.    VDU 4                        - exit VDU 5 state
  920.    VDU 23,7,m,d,z|              - scroll display
  921.    VDU 23,8,t1,t2,x1,y1,x2,y2|  - clear text block
  922.  
  923. It is generally meaningless to try to send or echo characters directly to the
  924. printer while printing. Furthermore, attempts to do so are likely to disrupt
  925. the operation of printer drivers. For these reasons, the following VDU
  926. sequences are faulted:
  927.  
  928.    VDU 1,c                      - send character to printer
  929.    VDU 2                        - start echoing characters to printer
  930.  
  931. It is not possible to change the "mode" of a printed page, so the following
  932. VDU sequence is faulted:
  933.  
  934.    VDU 22,m                     - change display mode
  935.  
  936. A printer driver cannot be written to deal with undefined or reserved calls,
  937. so the following VDU sequences are faulted:
  938.  
  939.    VDU 23,18-24,...             - reserved for Acorn expansion
  940.    VDU 23,28-31,...             - reserved for use by applications
  941.    VDU 25,216-231,...           - reserved for Acorn expansion
  942.    VDU 25,240-255,...           - reserved for use by applications
  943.  
  944. The following VDU sequences are ignored, either because they normally do
  945. nothing (at least when stuck in VDU 5 mode and not echoing characters to the
  946. printer) or because they have no sensible interpretation when applied to
  947. printed output rather than a screen.
  948.  
  949.    VDU 0                        - do nothing
  950.    VDU 3                        - stop echoing characters to printer
  951.    VDU 5                        - enter VDU 5 state
  952.    VDU 14                       - start "paged" display
  953.    VDU 15                       - end "paged" display
  954.    VDU 17,c                     - define text colour
  955.    VDU 23,17,5|                 - exchange text foreground and background
  956.    VDU 27                       - do nothing
  957.    VDU 28,l,b,r,t               - define text window
  958.  
  959.  
  960. Colours
  961. -------
  962.  
  963. Colours are a rather complicated matter. It is strongly recommended that
  964. applications should use SWI ColourTrans_SetGCOL, SWI ColourTrans_SelectTable
  965. and SWI ColourTrans_SetFontColours to set colours, as these will allow the
  966. printer to produce as accurate an approximation as it can to the desired
  967. colour, independently of the screen palette. The GCOL sequence (VDU 18,k,c)
  968. should only be used if absolutely necessary, and the application writer
  969. should be aware of the fact that the printer driver has a simplified
  970. interpretation of the parameters, as follows:
  971.  
  972.   * The fact that the background colour is affected if c >= 128 and the
  973.     foreground colour if c < 128 is unchanged.
  974.   * If k MOD 8 <> 0, subsequent plots and sprite plots will not do anything.
  975.   * If k=0, subsequent plots will cause the colour c MOD 128 (possibly
  976.     modified by the current tint) is looked up in the screen palette (at the
  977.     time of plotting, not the time the VDU 18,k,c command was issued).
  978.     Plotting is done by overwriting with the closest approximation the
  979.     printer can produce to the RGB combination found. Subsequent sprite
  980.     plotting will be done without use of the sprite's mask.
  981.   * If k=8, subsequent plots will be treated the same as k=0 above, except
  982.     that sprite plots will be done using the sprite's mask (if any).
  983.   * If k > 8, an unspecified solid colour will be used.
  984.  
  985. The major problems with the use of VDU 18,k,c to set colours are (a) that
  986. it makes the printer driver output dependent on the current screen mode and
  987. palette; (b) that it artificially limits the printer driver to the number
  988. of colours displayed on the screen (which can be very limiting in a two
  989. colour mode!).
  990.  
  991. Other techniques that depend on GCOLs (e.g. SWI Font_SetFontColours,
  992. colour-changing sequences in strings passed to Font_Paint, plotting sprites
  993. without a translation table, etc.) have the same problems and are similarly
  994. not recommended.
  995.  
  996. No operations other than overwriting are permitted, mainly because they
  997. cannot be implemented on many common printers (e.g. PostScript printers).
  998.  
  999. Note that the printer driver maintains its own foreground and background
  1000. colour information. The screen foreground and background colours are not
  1001. affected by VDU 18,k,c sequences encountered while a print job is active.
  1002.  
  1003. Similarly, VDU 23,17,2-3,t| sequences encountered while a print job is active
  1004. do not affect the screen tints, just the printer driver's own tints. VDU
  1005. 23,17,0-1,t| sequences would only affect the colours of the text tints, so
  1006. the printer driver ignores them.
  1007.  
  1008.  
  1009. Other graphics state operations
  1010. -------------------------------
  1011.  
  1012. The VDU 6 and VDU 21 sequences have their normal effects of enabling and
  1013. disabling execution (but not parsing) of subsequent VDU sequences. As usual,
  1014. the printer driver keeps track of this independently of the VDU drivers.
  1015.  
  1016. The cursor movement VDU sequences (i.e. VDU 8-11, VDU 13, VDU 30 and VDU
  1017. 31,x,y) all update the current graphics position (without updating the
  1018. previous graphics positions used in e.g. triangle plotting), precisely as
  1019. they do in VDU 5 mode on the screen.
  1020.  
  1021. VDU 24,l;b;r;t; will set the printer driver's graphics clipping box. The
  1022. rectangle specified should lie completely within the box that was reported on
  1023. return from the last call to SWI PDriver_DrawPage or SWI
  1024. PDriver_GetRectangle. If this is not the case, it is not defined what will
  1025. happen, and different printer drivers may treat it in different ways. This is
  1026. analogous to the situation with the window manager: attempts to set a
  1027. graphics clipping box outside the rectangle currently being redrawn may be
  1028. ignored completely (if they go outside the screen) or may get obeyed (with
  1029. consequences that are almost certainly wrong!).
  1030.  
  1031. VDU 29,x;y; sets the printer driver's graphics origin.
  1032.  
  1033. VDU 26 will reset the printer driver's graphics clipping box to its maximum
  1034. size (this is essentially the box reported on return from the last call to
  1035. SWI PDriver_DrawPage or SWI PDriver_GetRectangle, but may be slightly
  1036. different due to rounding problems when converting from a box expressed in
  1037. printer pixels to one expressed in OS units). It also resets its versions of
  1038. the graphics origin, the current graphics position and all the previous
  1039. graphics positions to (0,0).
  1040.  
  1041. VDU 23,6,a,b,c,d,e,f,g,h will set the printer driver's current dot pattern
  1042. (for use with lines plotted via VDU 25,16-31,x;y; and VDU 25,48-63,x;y;). The
  1043. exact lengths of the dashes and gaps produced may differ between various
  1044. printer drivers, and also between the screen and printer drivers, so an
  1045. application should not rely on them. However, an application can reasonably
  1046. expect each set bit in the pattern to correspond to approximately 2 to 3 OS
  1047. units on the printed page.
  1048.  
  1049. VDU 23,16,x,y| changes the printer driver's version of the cursor control
  1050. flags, and thus how the cursor movement control sequences and BBC-style
  1051. character plotting affect the current graphics position. As usual, this is
  1052. completely independent of the corresponding flags in the VDU drivers.
  1053. However, printer drivers pay no attention to the setting of bit 6 (which
  1054. controls whether movements beyond the edge of the graphics window cause
  1055. carriage return/line feeds and other cursor movements to be generated
  1056. automatically) - they always behave as though it is set. Note that the
  1057. Wimp normally sets this bit, and that it is not sensible to have it clear
  1058. at any time during a Wimp redraw.
  1059.  
  1060. VDU 23,17,7,flags,x;y;| changes the printer driver's version of the size that
  1061. BBC-style characters are to be plotted and the spacing that is required
  1062. between them. Setting the VDU 4 character size cannot possibly affect the
  1063. printer driver's output and so will be ignored completely. As noted below
  1064. under 'Plotting operations', a "pixel" is regarded as the size of a screen
  1065. pixel for the screen mode that was in effect when the print job was started.
  1066.  
  1067.  
  1068. Plotting operations
  1069. -------------------
  1070.  
  1071. The printer driver regards a "pixel" as having size 2 OS units square (1/90
  1072. inch square). The main effect of this is that all PLOT line, PLOT point and
  1073. PLOT outline calls will produce lines that are approximately 2 OS units
  1074. wide.
  1075.  
  1076. However, when translating the character size and spacing information provided
  1077. by VDU 23,17,7,... (see above) from pixels to OS units, the screen pixel size
  1078. for the screen mode that was in effect when the print job was started is
  1079. used. This is done in the expectation that the application is basing its
  1080. requested sizes on that screen mode.
  1081.  
  1082. The following VDU sequences perform straightforward plotting operations;
  1083. printer drivers will produce the corresponding printed output:
  1084.  
  1085.    VDU 12                       - clear graphics window (in VDU 5 state)
  1086.    VDU 16                       - clear graphics window
  1087.    VDU 25,0-63,x;y;             - draw line; however, the lines are always
  1088.                                     plotted solid, so only VDU 25,0-15,...
  1089.                                     and VDU 25,32-47,... will look the same
  1090.                                     as in VDU output. Use Draw_Stroke to
  1091.                                     generate dashed lines that will come
  1092.                                     out well in printed output.
  1093.    VDU 25,64-71,x;y;            - draw point
  1094.    VDU 25,80-87,x;y;            - fill triangle
  1095.    VDU 25,96-103,x;y;           - fill axis-aligned rectangle
  1096.    VDU 25,112-119,x;y;          - fill parallelogram
  1097.    VDU 25,144-151,x;y;          - draw circle
  1098.    VDU 25,152-159,x;y;          - fill circle
  1099.    VDU 25,160-167,x;y;          - draw circular arc
  1100.    VDU 25,168-175,x;y;          - fill circular segment
  1101.    VDU 25,176-183,x;y;          - fill circular sector
  1102.    VDU 25,192-199,x;y;          - draw ellipse
  1103.    VDU 25,200-207,x;y;          - fill ellipse
  1104.    VDU 32-126                   - print characters in BBC-style font
  1105.    VDU 127                      - backspace & delete
  1106.    VDU 128-255                  - print characters in BBC-style font
  1107.  
  1108. One difference to note is that most printer drivers will either not do the
  1109. rounding to pixel centres normally done by the VDU drivers, or will round to
  1110. different pixel centres (probably the centres of their device pixels).
  1111.  
  1112. The following VDU sequences are faulted because they cannot be split up
  1113. easily across rectangles, and also because they depend on the current picture
  1114. contents and so cannot be implemented e.g. on PostScript printers:
  1115.  
  1116.    VDU 25,72-79,x;y;            - horizontal line fill (flood fill primitive)
  1117.    VDU 25,88-95,x;y;            - horizontal line fill (flood fill primitive)
  1118.    VDU 25,104-111,x;y;          - horizontal line fill (flood fill primitive)
  1119.    VDU 25,120-127,x;y;          - horizontal line fill (flood fill primitive)
  1120.    VDU 25,128-143,x;y;          - flood fills
  1121.    VDU 25,184-191,x;y;          - copy/move rectangle
  1122.  
  1123. Exception: VDU 25,184,x;y; and VDU 25,188,x;y; are now correctly interpreted
  1124. by printer drivers (as being equivalent to VDU 25,0,x;y; and VDU 25,4,x;y;
  1125. respectively).
  1126.  
  1127. The sprite plotting VDU sequences (VDU 23,27,m,n| and VDU 25,232-239,x;y;)
  1128. and the font manager VDU sequences (VDU 23,25,a,b,c,d,e,f,g,h,
  1129. VDU 23,26,a,b,c,d,e,f,g,h,text and VDU 25,208-215,x;y;text) cannot be handled
  1130. by the printer drivers and generate errors. Application authors should use
  1131. SWI OS_SpriteOp and the font manager SWIs instead.
  1132.  
  1133.  
  1134.  
  1135. SPRITE OPERATIONS
  1136. =================
  1137.  
  1138.  
  1139. Printer drivers intercept OS_SpriteOp via the SpriteV vector. Most calls are
  1140. simply passed through to the operating system or the SpriteExtend module. The
  1141. ones that normally plot to the screen are generally intercepted and used to
  1142. generate printer output by the printer driver.
  1143.  
  1144. The following reason codes normally involve reading or writing the screen
  1145. contents and are not straightforward sprite plotting operations. Because some
  1146. printer drivers redirect output to a sprite internally, it is unknown what
  1147. the "screen" is during these operations. They are therefore faulted.
  1148.  
  1149.    2 - screen save
  1150.    3 - screen load
  1151.   14 - get sprite from current point on screen
  1152.   16 - get sprite from specified point on screen
  1153.  
  1154. Reason codes that are passed through to the operating system or the
  1155. SpriteExtend module are:
  1156.  
  1157.    8 - read sprite area control block
  1158.    9 - initialise sprite area
  1159.   10 - load sprite file
  1160.   11 - merge sprite file
  1161.   12 - save sprite file
  1162.   13 - return name of numbered sprite
  1163.   15 - create sprite
  1164.   25 - delete sprite
  1165.   26 - rename sprite
  1166.   27 - copy sprite
  1167.   29 - create mask
  1168.   30 - remove mask
  1169.   31 - insert row
  1170.   32 - delete row
  1171.   33 - flip about X axis
  1172.   35 - append sprite
  1173.   36 - set pointer shape
  1174.   40 - read sprite size
  1175.   41 - read pixel colour
  1176.   42 - write pixel colour
  1177.   43 - read pixel mask
  1178.   44 - write pixel mask
  1179.   45 - insert column
  1180.   46 - delete column
  1181.   47 - flip about Y axis
  1182.   62 - read save area size
  1183.  
  1184. The following reason code is passed through to the operating system when it
  1185. is called for a user sprite (i.e. with &100 or &200 added to it), as this
  1186. call is simply asking the operating system for the address of the sprite
  1187. concerned. If the system version is called (i.e. without anything added to
  1188. it), it is asking for a sprite to be selected for use with the VDU sprite
  1189. plotting sequences. As these sequences are not handled by the printer
  1190. driver, this version of the call generates an error.
  1191.  
  1192.   24 - select sprite
  1193.  
  1194. The following reason codes plot a sprite or its mask, and are converted into
  1195. appropriate printer output:
  1196.  
  1197.   28 - plot sprite at current point on screen
  1198.   34 - plot sprite at specified point on screen
  1199.   48 - plot mask at current point on screen
  1200.   49 - plot mask at specified point on screen
  1201.   50 - plot mask at specified point on screen, scaled
  1202.   52 - plot sprite at specified point on screen, scaled
  1203.   53 - plot sprite at specified point on screen, grey scaled
  1204.  
  1205. The following reason code is mainly used by the VDU drivers to implement
  1206. sizes other than 8x8 and 8x16 for VDU 5 characters. It is not handled by the
  1207. printer drivers (which deal with scaled VDU 5 text by another mechanism) and
  1208. causes an error if encountered during a print job.
  1209.  
  1210.   51 - plot character, scaled
  1211.  
  1212. As usual for a printer driver, only some GCOL actions are understood. If the
  1213. GCOL action is not divisible by 8, nothing is plotted. If it is divisible by
  1214. 8, the "overwrite" action is used. If it is divisible by 16, the sprite is
  1215. plotted without using its mask; otherwise the mask is used.
  1216.  
  1217. The colours used to plot sprite pixels are determined as follows:
  1218.  
  1219.   * If the call does not allow a pixel translation table, or if no
  1220.     translation table is supplied, the current screen palette is consulted to
  1221.     find out what RGB combination the sprite pixel's value corresponds to.
  1222.     The printer driver then does its best to produce that RGB combination.
  1223.     Use of this option is not really recommended.
  1224.   * If a translation table is supplied with the call, the printer driver
  1225.     assumes that the table contains code values allocated by one of:
  1226.  
  1227.       SWI ColourTrans_SelectTable with R2 = -1
  1228.       SWI ColourTrans_ReturnColourNumber
  1229.       SWI ColourTrans_ReturnColourNumberForMode with R1 = -1
  1230.       SWI ColourTrans_ReturnOppColourNumber
  1231.       SWI ColourTrans_ReturnOppColourNumberForMode with R1 = -1
  1232.  
  1233.     It can therefore look up precisely which RGB combination is supposed to
  1234.     correspond to each sprite pixel value. Because of the variety of ways in
  1235.     which printer drivers can allocate these values, the translation table
  1236.     should always have been set up in the current print job and using these
  1237.     calls.
  1238.  
  1239. If a sprite is printed unscaled, its size on the printed output is the same
  1240. as its size would be if it were plotted to the screen in the screen mode that
  1241. was in effect at the time that the print job concerned was started. If it is
  1242. printed scaled, the scaling factors are applied to this size. This is one of
  1243. the few ways in which the printed output does depend on this screen mode (the
  1244. main other ones are in interpreting GCOL and TINT values, and in interpreting
  1245. VDU 5 character sizes). It is done this way in the expectation that the
  1246. application is scaling the sprite for what it believes is the current screen
  1247. mode.
  1248.  
  1249. Finally, the following two reason codes are intercepted to keep track of
  1250. whether plotting output is currently supposed to go to a sprite or to the
  1251. screen. If it is supposed to go to a sprite, it really will go to that sprite
  1252. - this allows applications to create sprites normally while printing. If it
  1253. is supposed to go to the screen, it will be processed by the printer driver.
  1254. (Note that printer drivers that redirect output to a sprite internally will
  1255. treat this case specially, regarding output as still being destined for the
  1256. screen!)
  1257.  
  1258.   60 - switch output to sprite
  1259.   61 - switch output to mask
  1260.  
  1261.  
  1262.  
  1263. DRAW MODULE CALLS
  1264. =================
  1265.  
  1266.  
  1267. Printer drivers intercept the DrawV vector and re-interpret those calls whose
  1268. purpose is to plot something on the screen, producing appropriate printer
  1269. output instead. There are a number of restrictions on the calls that can be
  1270. dealt with, mainly due to the limitations of PostScript. Most of the
  1271. operations that are disallowed are not particularly useful, fortunately.
  1272.  
  1273. Note that the Draw module calls normally use the graphics foreground colour
  1274. to plot with and the graphics origin. The printer driver uses its versions of
  1275. these values. In particular, this means that the fill colour is subject to
  1276. all the restrictions noted elsewhere in this document.
  1277.  
  1278. The floating point Draw module calls are not intercepted at present. If and
  1279. when the Draw module is upgraded to deal with them, printer drivers will be
  1280. similarly upgraded.
  1281.  
  1282.  
  1283. SWI Draw_Fill
  1284. -------------
  1285.  
  1286.   Printer drivers can deal with most common calls to this SWI. The
  1287. restrictions are:
  1288.  
  1289.   (a) They cannot deal with fill styles that invoke the positive or negative
  1290.       winding number rules - i.e. those with bit 0 set.
  1291.   (b) They cannot deal with a fill style which asks for non-boundary exterior
  1292.       pixels to be plotted (i.e. which have bit 2 set). Exception: they can
  1293.       deal with the trivial case in which all of bits 2-5 are set - i.e. if
  1294.       all pixels in the plane are to be plotted!
  1295.   (c) They cannot deal with the following values for bits 5-2:
  1296.         0010 - plot exterior boundary pixels only.
  1297.         0100 - plot interior boundary pixels only.
  1298.         1010 - plot exterior boundary and interior non-boundary pixels only.
  1299.   (d) An application should not rely on there being any difference between
  1300.       what is printed for the following three values of bits 5-2:
  1301.         1000 - plot interior non-boundary pixels only.
  1302.         1100 - plot all interior pixels.
  1303.         1110 - plot all interior pixels and exterior boundary pixels.
  1304.       (A printer driver will generally try its best to distinguish these, but
  1305.       it may not be possible.)
  1306.  
  1307.  
  1308. SWI Draw_Stroke
  1309. ---------------
  1310.  
  1311.   Again, most common calls to this SWI can be dealt with. The restrictions
  1312. on the parameters depend on whether the specified thickness is zero or not:
  1313.  
  1314. If the specified thickness is zero, the restrictions are:
  1315.  
  1316.   (a) Printer drivers cannot deal with a fill style with bits 3-2 equal to 01
  1317.       - i.e. one that asks for pixels lying on the stroke to be plotted and
  1318.       those that lie off the stroke not to be.
  1319.   (b) Most printer drivers will not pay any attention to bit 31 of the fill
  1320.       style - the one that distinguishes plotting the stroke subpath by
  1321.       subpath from plotting it all at once.
  1322.  
  1323. If the specified thickness is non-zero, the restrictions are:
  1324.  
  1325.   (a) All the restrictions mentioned under SWI Draw_Fill above.
  1326.   (b) They cannot deal with bits 5-2 being 0110 - i.e. asking for just the
  1327.       boundary pixels of the resulting filled path to be plotted.
  1328.   (c) Most printer drivers will not pay any attention to bit 31 of the fill
  1329.       style - the one that distinguishes plotting the stroke subpath by
  1330.       subpath from plotting it all at once.
  1331.  
  1332.  
  1333. SWI Draw_StrokePath, SWI Draw_FlattenPath and SWI Draw_TransformPath
  1334. --------------------------------------------------------------------
  1335.  
  1336. None of these do any plotting; they are all dealt with in the normal way by
  1337. the Draw module.
  1338.  
  1339.  
  1340. SWI Draw_ProcessPath
  1341. --------------------
  1342.  
  1343. This SWI is faulted if R7=1 (fill path normally) or R7=2 (fill path subpath
  1344. by subpath) on entry. Use the appropriate one of Draw_Fill or Draw_Stroke if
  1345. you want to produce printed output. If the operation you're trying to do is
  1346. too complicated for them, it almost certainly cannot be handled by e.g. the
  1347. PostScript printer driver.
  1348.  
  1349. All other values of R7 correspond to calls that don't do any plotting and are
  1350. dealt with in the normal way by the Draw module. If you're trying to do
  1351. something complicated and you've got enough workspace and RMA, a possible
  1352. useful trick is to use SWI Draw_ProcessPath with R7 pointing to an output
  1353. buffer, followed by SWI Draw_Fill on the result.
  1354.  
  1355.  
  1356.  
  1357. COLOURTRANS MODULE CALLS
  1358. ========================
  1359.  
  1360.  
  1361. The printer driver intercepts calls to the ColourTrans module, via the
  1362. ColourV vector. Most of them are passed straight on to the ColourTrans module
  1363. - the exceptions are:
  1364.  
  1365.  
  1366. SWI ColourTrans_SelectTable with R2 = -1
  1367. ----------------------------------------
  1368.  
  1369. Each RGB combination in the source palette (or implied by it in the case of
  1370. 256 colour modes) is converted into a colour number as though by SWI
  1371. ColourTrans_ReturnColourNumber (see below). The resulting values are placed
  1372. in the table.
  1373.  
  1374.  
  1375. SWI ColourTrans_SetGCOL
  1376. -----------------------
  1377.  
  1378. The printer driver's version of the foreground or background colour (as
  1379. appropriate) is set. The GCOL actions are interpreted precisely as for the
  1380. VDU 18,k,c call (see above). However, rather than looking up a GCOL in the
  1381. screen palette at plot time, the exact RGB combination specified in this call
  1382. is remembered and used (as accurately as the printer will render it) at plot
  1383. time.
  1384.  
  1385. After this has been done, the call is effectively converted into SWI
  1386. ColourTrans_ReturnGCOL and passed down to the ColourTrans module in order to
  1387. set the information returned correctly. Note that this implies that
  1388. subsequently using the GCOL returned in a VDU 18,k,c sequence will not
  1389. produce the same effect on the colour as this call: it will merely produce
  1390. the best approximation the printer can manage to the best approximation the
  1391. current screen palette can manage to the specified RGB combination. It is
  1392. therefore probably a bad idea to use the values returned.
  1393.  
  1394. This call therefore allows the application to make full use of a printer's
  1395. colour resolution without having to switch to another screen mode or mess
  1396. around with the screen's palette, and without worrying about the effects of a
  1397. change in the screen's palette. It is therefore the recommended way to set
  1398. the foreground and background colours.
  1399.  
  1400.  
  1401. SWI ColourTrans_ReturnColourNumber
  1402. ----------------------------------
  1403.  
  1404. This will return a code value (in the range 0-255) that identifies the
  1405. specified RGB combination as accurately as possible to the printer driver.
  1406. How this code value is determined may vary from printer driver to printer
  1407. driver, and indeed even from print job to print job for the same printer
  1408. driver. An application should therefore not make any assumptions about what
  1409. these code values mean.
  1410.  
  1411. (Most printer drivers implement this by pre-allocating some range of code
  1412. values to evenly spaced RGB combinations, then adopting the following
  1413. approach:
  1414.  
  1415.    (a) If the RGB combination is already known about, return the
  1416.        corresponding code value.
  1417.    (b) If the RGB combination is not already known about and some code values
  1418.        are still free, allocate one of the unused code values to the new RGB
  1419.        combination and return that code value.
  1420.    (c) If the RGB combination is not already known about and all code values
  1421.        have been allocated, return the code number whose RGB combination is
  1422.        as close as possible to the desired RGB combination.
  1423.  
  1424. The pre-allocation of evenly spaced RGB combinations will ensure that even
  1425. case (c) does not have really terrible results.)
  1426.  
  1427.  
  1428. SWI ColourTrans_ReturnColourNumberForMode with R1 = -1
  1429. ------------------------------------------------------
  1430.  
  1431. This is treated exactly the same as SWI ColourTrans_ReturnColourNumber above.
  1432.  
  1433.  
  1434. SWI ColourTrans_SetOppGCOL
  1435. --------------------------
  1436.  
  1437. This behaves like ColourTrans_SetGCOL above, except that the RGB combination
  1438. it remembers is the furthest possible RGB combination from the one actually
  1439. specified in R0, and it ends by being converted into a call to
  1440. ColourTrans_ReturnOppGCOL. Note that there is no guarantee that the GCOL
  1441. returned is anywhere near the RGB combination remembered!
  1442.  
  1443.  
  1444. SWI ColourTrans_ReturnOppColourNumber
  1445. -------------------------------------
  1446.  
  1447. This behaves exactly as though ColourTrans_ReturnColourNumber (see above) had
  1448. been called with R0 containing the furthest possible RGB combination from the
  1449. one actually specified.
  1450.  
  1451.  
  1452. SWI ColourTrans_ReturnOppColourNumberForMode with R1 = -1
  1453. ---------------------------------------------------------
  1454.  
  1455. This behaves exactly as though ColourTrans_ReturnColourNumberForMode (see
  1456. above) had been called with R1 = -1 and R0 containing the furthest possible
  1457. RGB combination from the one actually specified.
  1458.  
  1459.  
  1460. SWI ColourTrans_SetFontColours
  1461. ------------------------------
  1462.  
  1463. The printer driver's version of the font colours is set, to as accurate a
  1464. representation of the desired RGB combinations as the printer can manage.
  1465.  
  1466. After this has been done, the call is effectively converted into SWI
  1467. ColourTrans_ReturnFontColours and passed down to the ColourTrans module in
  1468. order to set the information returned correctly. Note that this implies that
  1469. subsequently using the values returned in a SWI Font_SetFontColours call will
  1470. not produce the same effect on the font colours as this call: it will merely
  1471. produce the best approximations the printer can manage to the best
  1472. approximations the current screen palette can manage to the specified RGB
  1473. combinations. It is therefore probably a bad idea to use the values returned.
  1474.  
  1475. This call therefore allows the application to make full use of a printer's
  1476. colour resolution without having to switch to another screen mode or mess
  1477. around with the screen's palette, and without worrying about the effects of a
  1478. change in the screen's palette. It is the recommended way to set the font
  1479. colours.
  1480.  
  1481.  
  1482.  
  1483. FONT MANAGER CALLS
  1484. ==================
  1485.  
  1486.  
  1487. The printer driver interacts with the font manager (via a service call and
  1488. SWI PDriver_FontSWI) in such a way that when it is active, calls to the
  1489. following SWIs are processed by the printer driver:
  1490.  
  1491.   SWI Font_Paint
  1492.   SWI Font_LoseFont
  1493.   SWI Font_SetFontColours
  1494.   SWI Font_SetPalette
  1495.  
  1496. This enables the printer driver to make SWI Font_Paint produce printer output
  1497. rather than affecting the screen.
  1498.  
  1499. The use of SWI Font_SetFontColours is not recommended, as it results in the
  1500. setting of colours that depend on the current screen palette. Instead, use
  1501. SWI ColourTrans_SetFontColours to set font colours to absolute RGB values.
  1502. Similarly, the use of colour-changing control sequences in strings passed to
  1503. SWI Font_Paint is not recommended.
  1504.  
  1505. In addition to the control sequences allowed by current font managers,
  1506. printer drivers will be able to handle the following control sequence if
  1507. the font manager they are working with can:
  1508.  
  1509.   19,background red,green,blue,foreground red,green,blue,maximum offset
  1510.  
  1511. This gives a way of changing colour in the middle of a string without
  1512. sacrificing colour resolution.
  1513.  
  1514. (How exactly it does this varies quite markedly between printer drivers: for
  1515. instance, most dot matrix printer drivers will probably use the font manager
  1516. to write into the sprite they are using to hold the current strip of printed
  1517. output, while the PostScript printer driver uses the PostScript prologue to
  1518. define a translation from font manager font names to printer fonts.)
  1519.  
  1520.  
  1521.  
  1522. MISCELLANEOUS CALLS
  1523. ===================
  1524.  
  1525.  
  1526. OS_Byte 163,242,0-64 are intercepted to set the printer driver version of the
  1527. dot pattern repeat length instead of the VDU drivers' version.
  1528.  
  1529. OS_Byte 218 is intercepted to act on the printer driver's VDU queue instead
  1530. of the VDU drivers' version.
  1531.  
  1532. It should be noted that most of the informational calls associated with the
  1533. VDU drivers (and OS_ReadVduVariables in particular) will produce undefined
  1534. results when a printer driver is active. These results are likely to differ
  1535. between printer drivers (in particular, they will vary according to whether
  1536. the printer driver plots to a sprite internally and if so, how large the
  1537. sprite concerned is).
  1538.  
  1539. The only informational calls that the application may rely upon are:
  1540.  
  1541.    OS_Word 10      - used to read character and ECF definitions.
  1542.    OS_Word 11      - used to read palette definitions.
  1543.    OS_ReadPalette  - used to read palette definitions.
  1544.    OS_Byte 218     - when used to read the number of bytes in the VDU queue.
  1545.  
  1546.  
  1547.  
  1548. ERROR HANDLING
  1549. ==============
  1550.  
  1551.  
  1552. There are a couple of somewhat unusual features about the printer drivers'
  1553. error handling that an application author should be aware of:
  1554.  
  1555. First, ESCAPE condition generation and side effects are turned on within
  1556. various calls to the printer driver and restored to their original state
  1557. afterwards. If the application has ESCAPE generation turned off, it is
  1558. guaranteed that any ESCAPE generated within the print job will be
  1559. acknowledged and turned into an 'Escape' error. If the application has
  1560. ESCAPE generation turned on, most ESCAPEs generated within the print job
  1561. will be acknowledged and turned into 'Escape' errors, but there is a small
  1562. window at the end of the call during which an ESCAPE will not be
  1563. acknowledged. If the application makes a subsequent call of one of the
  1564. relevant types to the printer driver, that subsequent call will catch the
  1565. ESCAPE. If no such subsequent call is made, the application will need to
  1566. trap the ESCAPE itself.
  1567.  
  1568. The SWIs during which ESCAPE generation is turned on are:
  1569.  
  1570.   PDriver_SelectJob for a new job
  1571.   PDriver_EndJob
  1572.   OS_WriteC
  1573.   All ColourTrans SWIs
  1574.   Draw_Fill
  1575.   Draw_Stroke
  1576.   Font_SetFontColours
  1577.   Font_SetPalette
  1578.   Font_Paint
  1579.   OS_SpriteOp with reason codes: PutSprite
  1580.                                  PutSpriteUserCoords
  1581.                                  PutSpriteScaled
  1582.                                  PutSpriteGreyScaled
  1583.                                  PlotMask
  1584.                                  PlotMaskUserCoords
  1585.                                  PlotMaskScaled
  1586.  
  1587. All but the first two only apply at times when the printer driver is
  1588. intercepting plotting calls - i.e. at times when all of the following
  1589. conditions hold:
  1590.   (a) There is an active print job.
  1591.   (b) Plotting output is directed either to the screen or to a sprite
  1592.       internal to the printer driver.
  1593.   (c) The Wimp is not reporting an error (as defined by the service call
  1594.       with reason WimpReportError).
  1595.  
  1596. Secondly, inside a number of calls, any error that occurs is converted into
  1597. a "persistent error". The net effect of this is that:
  1598.   (a) The error number is left unchanged.
  1599.   (b) The error message has the string " (print cancelled)" appended to it.
  1600.       If it is so long that this would cause it to exceed 255 characters, it
  1601.       is truncated to a suitable length and "... (print cancelled)" is
  1602.       appended to it.
  1603.   (c) Any subsequent call to any of the routines concerned will immediately
  1604.       return the same error.
  1605. The reason for this behaviour is to prevent errors the application is not
  1606. expecting from being ignored. (E.g. quite a lot of code assumes incorrectly
  1607. that OS_WriteC cannot produce an error. This ensures that an error during
  1608. OS_WriteC cannot reasonably get ignored forever.)
  1609.  
  1610. The SWIs during which persistent errors are created are:
  1611.  
  1612.   PDriver_EndJob
  1613.   PDriver_GiveRectangle
  1614.   PDriver_DrawPage
  1615.   PDriver_GetRectangle
  1616.   OS_WriteC
  1617.   All ColourTrans SWIs
  1618.   Draw_Fill
  1619.   Draw_Stroke
  1620.   Draw_ProcessPath with R7=1
  1621.   Font_SetFontColours
  1622.   Font_SetPalette
  1623.   Font_Paint
  1624.   OS_SpriteOp with reason codes: PutSprite
  1625.                                  PutSpriteUserCoords
  1626.                                  PutSpriteScaled
  1627.                                  PutSpriteGreyScaled
  1628.                                  PlotMask
  1629.                                  PlotMaskUserCoords
  1630.                                  PlotMaskScaled
  1631.                                  ScreenSave
  1632.                                  ScreenLoad
  1633.                                  GetSprite
  1634.                                  GetSpriteUserCoords
  1635.                                  PaintCharScaled
  1636.                                  SelectSprite (system version only)
  1637.                                  Reason codes unknown to the printer driver
  1638.  
  1639. All but the first four only apply at times that the printer driver is
  1640. intercepting plotting calls - see above for details of this.
  1641.  
  1642. SWI PDriver_CancelJob puts a print job into a similar state, with the error
  1643. message being simply "Print cancelled". However, this error is only returned
  1644. by subsequent calls from the list above - not by PDriver_CancelJob itself.
  1645.  
  1646. Note that an application must respond to any error during a print job that
  1647. could have come from one of the above sources by calling PDriver_AbortJob.
  1648. In particular, take care to respond to errors from PDriver_EndJob by calling
  1649. PDriver_AbortJob, not PDriver_EndJob - otherwise an infinite succession of
  1650. errors will occur or an unfinished print job will be left around.
  1651.  
  1652.