www.riscos.com Technical Support: |
|
One of the major headaches on some operating systems is that all applications must write drivers for all the required types of printers. This duplicates a lot of work and makes each application correspondingly larger and more complex.
The solution to this problem that RISC OS has adopted is to supply a virtual printer interface, so that all printer devices can be used in the same way. Thus, your application can write to the printer, without being aware of the differences between (for example) a dot matrix printer, a PostScript printer, and a plotter.
To send output to the printer, an application must engage in a dialogue with the printer driver. This is similar in part to the dialogue used with the Wimp when a window needs redrawing.
To simplify printer driving further, output to the printer is done using a subset of the same calls that normally write to the screen. Calls to the VDU drivers and to the SpriteExtend, Draw, ColourTrans and Font modules are trapped by the printer driver. It interprets all these calls in the most appropriate way for the selected printer, using the printer's resolution and set of features to the best. Thus applications need not know about printer specific operation, but this does not result in lack of fine control of the printer.
Of course, not all calls have meaning to the printer driver - flashing colours for example. These generate an error or are ignored as appropriate.
Printer drivers are written to support a general class of printers, such as PostScript printers. Under RISC OS 3 you can have more than one printer driver installed at the same time, and it is easy to switch between them. Support for this is supplied by a sharer module, and also by the new Printer manager application, which also provides facilities that allows users to control the unique attributes of each type of printer.
The structure of the printing system need not concern application writers; you do not need to know which part of the printing system is handling your calls. Further details are given in the The structure of the printing system, should you be interested.
A key feature of all printer drivers is the rectangle. In normal use, it is a page. It is however possible to have many rectangles appear on the same physical sheet of paper. For example, an A3 sized plotter may be used to draw two A4 rectangles on it side by side; or it could be used to generate a pagination sheet for a DTP package, showing many rectangles on a sheet.
When reading this chapter, in most cases you can consider a rectangle and a page to be effectively equivalent, but bear in mind the above use of rectangles.
Many of the printer driver SWIs deal with an internal measurement system, using millipoints. This is 1/1000 of a point, or 1/72000 of an inch. This system is an abstraction from the physical characteristics of the printer. Printed text and graphics can be manipulated by its size, rather than in terms of numbers of print pixels, which will vary from printer to printer.
OS units are the coordinate system normally used by the VDU drivers. In this context, an OS unit is defined as 1/180 of an inch, so each OS unit is 2/5 of a point, or 400 millipoints.
It is in this coordinate system that all plotting commands are interpreted. When a rectangle is declared, it is given a size in OS units. This is treated like a graphics window, with output outside it being clipped, and so on.
Like the Draw module, the printer driver uses a transform matrix to convert OS units to the scale, rotation and translation required on paper. With a matrix with no scaling transformation, a line of 180 OS units (ie one inch) will appear as an approximation of an inch long line on all printers. Naturally, it depends on the resolution of the printer as to how close to this it gets. If the matrix scaled x and y up by two, then the line would be two inches long.
This section describes how to print from an application.
If your application is running under the Wimp, it must initiate printing using the Wimp message protocol described in the The Printer protocol.
Your application should not make any assumptions about the printer that it is going to use; RISC OS supports many types of printers, and your users could be using any of them. Similarly, you shouldn't make assumptions about the printer driver you'll be using.
Instead you should use the SWI PDriver_Info (see PDriver_Info) to find out any information you need to know about the printer and printer driver that you're using. You should do so each time you start printing, rather than when your application is loaded. This is because the user may change either the way in which they are using a printer or the printer that they are using during the time your application is printing. The information this call returns includes:
It also returns a features word giving a bit mask showing:
You may wish to - or indeed have to - change the behaviour of your application based on this information. Note that many colour limitations you might be worried about can be overcome by the printer drivers' own halftoning.
There are two other informational SWIs that you may find useful:
To start a print job, you should first open 'printer:' as an output file. This device independent name is used so that the Printer application can control the actual destination of printed output using the OS_Byte 5 call (for details of this call, see OS_Byte 5).
You may - if you wish - open any other valid pathname as a file to use as a printer output. The file created may subsequently be dumped to the printer. This technique could be used for background printing, for instance.
The next stage of printing is to start a new print job by passing the file handle of the output file you just opened (see above) to PDriver_SelectJob (see PDriver_SelectJob).
This call suspends the current print job, if there is one, and sets up a new job that uses the file handle that you passed for its output.
You should then declare any fonts that your document uses, assuming the printer driver you're using supports this feature. (You can find this out using PDriver_Info; see the section above entitled Get information on the printer you're going to use). Certain printer drivers need this information before printing begins; for example, the PostScript driver needs it to generate more efficient output, to perform font downloading, and to conform with structuring rules for PostScript documents.
To declare the fonts, you should call PDriver_DeclareFont (see PDriver_DeclareFont) for each distinct font that your document uses. The definition of what is a 'distinct font' is strict, and is given in the documentation of this SWI. Having declared each font, you must make one further call of this SWI, passing special values to indicate the end of the list of fonts. Even if your document does not use any fonts you should still make this 'end of list' call; the printer driver then knows that your application is aware of this call, and uses no fonts.
You're now ready to print a page. The first step is to specify as rectangles those area(s) of your document that you wish to have printed on the page.
You must call PDriver_GiveRectangle (see PDriver_GiveRectangle) for each rectangle, specifying the location and size of the rectangle within the document, an ID for the rectangle (allocated by you), a transformation to apply to it before printing, and its location and background colour on the printed page.
Typically you will just specify a single rectangle consisting of a whole page of your document. An example of the use of multiple rectangles would be for printing 'thumbnails' (ie printing multiple pages of your document on a single page).
To actually start printing you call PDriver_DrawPage (see PDriver_DrawPage). This returns the first rectangle for your application to plot. This may be all of a rectangle you specified for printing, or it may only be a strip of that rectangle. You should plot the rectangle using calls that normally output to the screen; the printer driver intercepts these calls, and converts them to printed output. For general information see the chapter entitled Trapping of output calls, and the Guidelines on output calls to use. For a more detailed description of how the printer drivers handle each output call, see the chapter entitled The output calls in detail.
Having plotted the first rectangle, you should find any other rectangles to plot by repeatedly calling PDriver_GetRectangle (see PDriver_GetRectangle), plotting each rectangle as it is returned. Eventually the call will return a special value indicating that there are no more rectangles to print.
You must not make any assumptions about the returned rectangles. The printer driver is free to request any rectangle from the area(s) that you specified be printed; it may do so in any order it pleases, as many times as it pleases. A dot matrix driver, for instance, may get the output a strip at a time to conserve workspace, and may make multiple passes over a strip (particularly if it uses a multi-coloured ribbon); whereas a PostScript driver can process an entire page in one go.
You may have noticed that this procedure is very similar to the process used by the Wimp to redraw windows: Wimp_RedrawWindow initiates the redraw, returning the first rectangle to draw, and Wimp_GetRectangle returns all subsequent windows to redraw. You should find that with care you can share a lot or all of the code to redraw windows and to print.
For each page, you must repeat the procedure in the above two sections.
To end the print job, you must call PDriverEndJob (see PDriver_EndJob).
Finally, you must close the output file you've been using (typically 'printer:').
If you get an error from any printing SWI or from any other call whilst printing pages, you must do one of the following:
Because the printer driver intercepts output calls this may itself cause an error; thus you may get an infinite loop where an error causes an error, which causes an error, which...
This implies that all calls inside the main print loop must be error-returning SWIs (ie have their 'X' bit set; see the chapter entitled An introduction to SWIs, and Generating and handling errors).
There are also changes made to error handling within printing to ensure that Escape conditions and errors are not ignored for an undue length of time; see the chapter entitled Error handling changes.
Multitasking (ie calling Wimp_Poll) whilst printing has an obvious advantage:
However, there are problems associated with it:
To do so properly, you need to use a timer.
In practice these problems are likely to outweigh any advantages conferred by multitasking. If you have any doubts as to whether or not you should multitask, we recommend that you don't.
This example code skeleton may help you to understand the above:
Use Printers message protocol if running under the Wimp PDriver_Info REM check what features are available (eg PDriver_DeclareFont) OPEN printer: PDriver_SelectJob IF driver supports PDriver_DeclareFont THEN WHILE fonts to be declared PDriver_DeclareFont font ENDWHILE PDriver_DeclareFont end of font list ENDIF FOR each page to print REPEAT PDriver_GiveRectangle UNTIL all rectangles declared REM typically only one rectangle given, specifying whole page PDriver_DrawPage WHILE more rectangles to print plot returned rectangle using supported output calls PDriver_GetRectangle ENDWHILE ENDFOR PDriver_EndJob CLOSE printer:
PDriver_CurrentJob will tell you the file handle for the currently active print job.
PDriver_EnumerateJobs allows you to scan through all the print jobs that the printer driver currently knows about.
PDriver_CancelJob will cancel a job. It is normally followed by the job being aborted. It is not intended to be used by the printing application, but by another task that allows cancellations of print jobs. It would use PDriver_EnumerateJobs to find out which jobs exist and then cancel what it wishes to. The application that owns the cancelled job would subsequently find that it had been cancelled and would then abort the job.
PDriver_Reset will abort all print jobs known to the printer drivers. Normally, you should never have to use this command. It may be useful during development of an application as an emergency recovery measure.
When printing occurs, the printer driver intercepts software vectors through which pass calls that may output to the screen. These are:
It treats the intercepted calls in different ways:
A few calls are both processed by the printer driver and passed on to RISC OS.
Furthermore, when printing starts the printer driver issues a service call which alters the font manager's SWI handling:
The font manager does not process such SWIs itself.
This section outlines which calls you should use for output to the printer drivers.
Only use overwriting; do not use logical operations such as AND, OR, EOR and NOT, as many types of printer (eg PostScript printers, plotters) cannot support them. Avoid using ECFs.
You should set colours for all printing using appropriate calls to the ColourTrans module, rather than by other calls (such as Font_SetFontColours). The ColourTrans calls are independent of the current screen mode and palette, and ensure that the colours rendered by the printer are the best approximations it is able to produce.
All other calls that set colours take the colour to be printed, choose the closest colour available from the current screen palette, and then ask the printer to render that colour. So the printer produces its best approximation to the screen palette's best approximation. Using these other calls:
We therefore recommend that you do not set colours with these other calls.
You should use calls to the Draw module to print object-oriented graphics such as rectangles. This is preferable to using VDU and PLOT sequences.
You should paint fonts using font manager SWIs rather than VDU sequences. Set colours using ColourTrans calls, or control (19) sequences within the string to be painted - as these in fact use ColourTrans. Do not set colours using font manager calls, or other (non-19) control sequences.
Use OS_SpriteOp calls to output sprites. You should set colours for the sprite using a translation table, set up using ColourTrans calls during the print job.
You should use the OS_Write... SWIs, OS_NewLine and OS_PrettyPrint for character output. Do not use OS_PrintChar.
You should avoid OS_Byte calls and VDU sequences wherever possible - in particular where an alternative method is available and recommended. For example, you should use font SWIs for font painting rather than the VDU sequences that do so.
The following sections contain tables giving more detail on how the printer driver treats calls passing through the software vectors it claims, and how it interacts with the font manager. Some of the tables are followed by extra information on the more complex calls; unless otherwise stated, you should not take this to mean that such calls are recommended over and above all other supported ones.
The printer drivers pass on the vast majority of calls made through ByteV; they are interpreted as usual by the ROM's OS_Byte routine. The printer drivers claim and process only the following calls:
Call processed | Meaning | Notes |
---|---|---|
OS_Byte 135 | Read character at text cursor and screen mode | Use only to read 'screen' mode; returned character may be invalid |
OS_Byte 163 | Read/write general graphics information | Use only to set dot-dash length (ie R1 = 242, R2 64) |
OS_Byte 218 | Read/write bytes in VDU queue | No restrictions |
The printer driver intercepts calls to the ColourTrans module, via the ColourV vector. Most of them are passed straight on to the ColourTrans module, but some are processed by the printer driver:
ColourTrans SWI | Meaning | Printer driver's treatment |
---|---|---|
Colour Number To GCOL | Translate a colour number to a GCOL | Passed on |
Convert CIE To RGB | Convert industry standard CIE colours to RISC OS RGB colours | Passed on |
Convert CMYK To RGB | Convert from the CMYK model to RISC OS RGB colours | Passed on |
Convert Device Colour | Convert a device colour to a standard colour | Passed on |
Convert Device Palette | Convert a device palette to standard colours | Passed on |
Convert HSV To RGB | Convert hue, saturation and value into corresponding RISC OS RGB colours | Passed on |
Convert RGB To CIE | Convert RISC OS RGB colours to industry standard CIE colours | Passed on |
Convert RGB To CMYK | Convert RISC OS RGB colours into the CMYK model | Passed on |
Convert RGB To HSV | Convert RISC OS RGB colours into corresponding hue, saturation and value | Passed on |
GCOL To Colour Number | Translate a GCOL to a colour number | Passed on |
Generate Table | Set up a translation table in a buffer | Processed if R2 = -1 (ie table is for current mode); passed on otherwise |
Invalidate Cache | Inform ColourTrans that the palette has been changed by some other means | Passed on |
Misc Op | For internal use only | Passed on |
Select GCOL Table | Set up a list of GCOLs in a buffer | Passed on |
Select Table | Set up a translation table in a buffer | Processed if R2 = -1 (ie ta is for current mode); passed on otherwise |
Set Calibration | Set the calibration table for the screen | Passed on |
Set Colour | Change the foreground or background colour to a GCOL number | Passed on |
Set Font Colours | Set the best range of anti-alias colours to match a pair of palette entries | Processed |
Set GCOL | Set the closest GCOL for a palette entry | Processed |
Set Opp GCOL | Set the furthest GCOL for a palette entry | Processed |
Set Opp Text Colour | Change the text foreground or background colour to a GCOL number | Passed on |
Set Text Colour | Change the text foreground or background colour to a GCOL number | Passed on |
Read Calibration | Read the calibration table for the screen | Passed on |
Read Palette | Read either the screen's palette, or a sprite's palette | Passed on |
Return Colour Number | Get the closest colour for a palette entry | Processed |
Return Colour Number For Mode | Get the closest colour for a palette entry | Processed if R1 = -1 (ie colour is for current mode); passed on otherwise |
Return Font Colours | Find the best range of anti-alias colours to match a pair of palette entries | Passed on |
Return GCOL | Get the closest GCOL for a palette entry | Passed on |
Return GCOL For Mode | Get the closest GCOL for a palette entry | Passed on |
Return Opp Colour Number | Get the furthest colour for a palette entry | Processed |
Return Opp Colour Number For Mode | Get the furthest colour for a palette entry | Processed if R1 = -1 (ie colour is for current mode); passed on otherwise |
Return Opp GCOL | Get the furthest GCOL for a palette entry | Passed on |
Return Opp GCOL For Mode | Get the furthest GCOL for a palette entry | Passed on |
Write Calibration To File | Save the current calibration to a file | Passed on |
Write Loadings To File | Write a * Command to a file that will set the ColourTrans error loadings | Passed on |
Write Palette | Write to either the screen's palette, or to a sprite's palette | Passed on |
Both these calls are treated in the same way by the printer drivers. They return a code value, in the range 0 - 255, that identifies the specified RGB combination as accurately as possible to the printer driver. How this code value is determined may vary from printer driver to printer driver, and indeed even from print job to print job for the same printer driver. An application should therefore not make any assumptions about what these code values mean.
Most printer drivers implement this by pre-allocating some range of code values to evenly spaced RGB combinations, then adopting the following approach:
The pre-allocation of evenly spaced RGB combinations will ensure that even the third case does not have really terrible results.
These calls behave exactly as though ColourTrans_ReturnColourNumber had been called with R0 containing the furthest possible RGB combination from the one actually specified.
This results in a subtle difference between the 'opposite' colours returned by the printer driver, and those normally returned by the ColourTrans module. The printer driver returns the colour closest to the RGB value most different to that given, whereas ColourTrans returns the colour furthest from the given RGB. This difference will only be obvious if your printer cannot print a very wide range of colours.
Each RGB combination in the source palette, or implied by it in the case of 256 colour modes, is converted into a colour number as though by ColourTrans_ReturnColourNumber (see above). The resulting values are placed in the table.
This call sets the printer driver's version of the font colours, to as accurate a representation of the desired RGB values as the printer can manage. Along with control (19) sequences within the string to be painted - which themselves use this call - it is the recommended way to set font colours.
As with other ColourTrans calls, the returned values are obtained by calling the ColourTrans module; in this case before the printer driver's own colours are actually set. Just as with the above calls, you should not subsequently use these values to set printing colours.
This call sets the printer driver's version of the foreground or background colour, as appropriate. It is the recommended way to do so.
The gcol_action passed in R4 is interpreted as follows:
This call never uses ECFs; the flag which sets whether or not to use ECFs (bit 8 of R3) is ignored.
After this has been done, the call is effectively converted into a call to ColourTrans_ReturnGCOL, and is passed down to the ColourTrans module in order to set the information returned. Note that the returned GCOL is therefore the closest GCOL available from the current screen palette, which may considerably differ from the passed RGB value. You should therefore not subsequently use the returned value to set colours for printing.
This behaves like ColourTrans_SetGCOL above, except that the RGB value the printer driver remembers is the furthest possible RGB value from the one actually specified in R0, and the returned values are given by converting this call into a call to ColourTrans_ReturnOppGCOL. Again, you should not subsequently use the returned value to set printing colours, as they are dependent on the current screen palette.
You should not use these calls to set text colours when printing, as the printer drivers ignore text colours. You should instead use the font manager to print coloured text; if necessary, you can use the outline System font introduced in RISC OS 3.
Printer drivers intercept Draw SWIs via the DrawV vector. Those calls that normally plot to the screen are intercepted and processed by the printer driver to generate printer output. There are a number of restrictions on these calls, mainly due to the limitations of PostScript. Fortunately most of the operations that are disallowed are not particularly useful.
All other calls to DrawV are passed on to the Draw module and treated in the same way as usual.
The floating point Draw module calls are not intercepted at present. If and when the Draw module is upgraded to deal with them, printer drivers will be similarly upgraded.
The table below summarises the printer driver's treatment of each integer Draw SWI. It is followed by more detailed notes of the restriction on each of the calls processed by the printer driver:
Draw SWI | Meaning | Printer driver's treatment |
---|---|---|
Fill | Process and output a path, filling the interior portion | Processed, but with restrictions; see below for notes |
Flatten Path | Convert an input path into a flattened output path | Passed on |
Process Path | Multi-purpose main Draw SWI | Faulted if R7 = 1 or 2; processed otherwise, but with restrictions; see below for notes |
Stroke | Process and output a path | Processed, but with restrictions; see below for notes |
Stroke Path | Process a path, writing output to a path | Passed on |
Transform Path | Convert an input path | Passed on |
Note: The rounding of coordinates is printer driver specific. Some drivers may not output paths that are less than one output device pixel wide. However, paths of width 0 (ie 'as thin as possible') should always result in output.
This call is faulted if R7 = 1 (fill path normally) or R7 = 2 (fill path subpath by subpath) on entry. Use the appropriate one of Draw_Fill or Draw_Stroke if you want to produce printed output. If the operation you're trying to do is too complicated for them, it almost certainly cannot be handled by some printer drivers, such as the PostScript one.
If you are using this call to calculate bounding boxes, using the R7 = &80000000+ address option, then the parameters such as the matrix, flatness and line thickness must exactly correspond with those in the intended call. If they differ, then rounding errors, flattening errors and the like may cause clipping.
All other values of R7 correspond to calls that don't do any plotting and are dealt with in the normal way by the Draw module. If you're trying to do something complicated and you've got enough workspace and RMA, a possible useful trick is to use Draw_ProcessPath with R7 pointing to an output buffer, followed by Draw_Fill on the result.
Printer drivers can deal with most common calls to this SWI. The restrictions are:
0010 - plot exterior boundary pixels only.
0100 - plot interior boundary pixels only.
1010 - plot exterior boundary and interior non-boundary pixels only.
A printer driver will generally try its best to distinguish these, but it may not be possible.
Again, most common calls to this SWI can be dealt with. The restrictions on the parameters depend on whether the specified thickness is zero or not.
If the specified thickness is zero, the restrictions are:
If the specified thickness is non-zero, all the restrictions mentioned above for Draw_Fill also apply to this call. Further restrictions are:
The printer driver interacts with the font manager via a service call and the SWI PDriver_FontSWI in such a way that when it is active, calls to some SWIs are passed to the printer driver, which may then process the SWI or ignore it. The table below shows how each SWI is handled. Note that some of the SWIs listed as being processed by the font manager may cause a Lose Font operation, which is passed to the printer driver:
Font SWI | Meaning | Processing |
---|---|---|
Cache Addr | Get the version number, font cache size and amount used | Processed by font manager as usual |
Caret | Define text cursor | Passed to printer driver, but ignored by it |
Char BBox | Get the bounding box of a character | Processed by font manager as usual |
Convert to OS | Convert internal coordinates to OS coordinates | Processed by font manager as usual |
Convert to Points | Convert OS coordinates to internal coordinates | Processed by font manager as usual |
Current Font | Get current font handle and colours | Processed by font manager as usual |
Current RGB | Read the settings of colours after calling Font_Paint | Processed by font manager as usual |
Decode Menu | Decode a selection made from a font menu | Processed by font manager as usual |
Find Caret | Find where the caret is in the string | Processed by font manager as usual |
Find Caret J | Find where the caret is in a justified string | Processed by font manager as usual |
Find Font | Get the handle for a font | Passed to printer driver and processed by it |
Future Font | Check font characteristics after Font_StringWidth | Processed by font manager as usual |
Future RGB | Read the settings of colours after calling various Font_... SWIs | Processed by font manager as usual |
List Fonts | Scan for fonts, returning their names one at a time; or build a menu of fonts | Processed by font manager as usual |
Lose Font | Finish use of a font | Passed to printer driver and processed by it |
Make Bitmap | Make a font bitmap file | Processed by font manager as usual |
Paint | Output a string | Passed to printer driver and processed by it |
Read Colour Table | Read the anti-alias colour table | Processed by font manager as usual |
Read Defn | Read details about a font | Processed by font manager as usual |
Read Encoding Filename | Return the filename of the encoding file used for a given font handle | Processed by font manager as usual |
Read Font Max | Read the FontMax values | Processed by font manager as usual |
Read Font Metrics | Reads the metrics information held in a font's IntMetrics file | Processed by font manager as usual |
Read Font Prefix | Find the directory prefix for a given font handle | Processed by font manager as usual |
Read Info | Get the font bounding box | Processed by font manager as usual |
Read Scale Factor | Read the internal to OS conversion factor | Processed by font manager as usual |
Read Thresholds | Read the list of threshold values for printing | Processed by font manager as usual |
Scan String | Return information on a string | Processed by font manager as usual |
Set Colour Table | For internal use by the ColourTrans module only | Passed to printer driver, but ignored by it |
Set Font | Select the font to be subsequently used | Passed to printer driver and processed by it |
Set Font Colours | Change the current colours and (optionally) the current font | Passed to printer driver and processed by it; however, you should use ColourTrans_ SetFontColours to set font colours |
Set Font Max | Set the FontMax values | Processed by font manager as usual |
Set Palette | Define the anti-alias palette | Passed to printer driver, but ignored by it |
Set Scale Factor | Set the internal to OS conversion factor | Processed by font manager as usual |
Set Thresholds | Define the list of threshold values for printing | Processed by font manager as usual |
String BBox | Get the bounding box of a string | Processed by font manager as usual |
String Width | Calculate how wide a string would be | Processed by font manager as usual |
Switch Output To Buffer | Switch output to a buffer, creating a Draw file structure | Processed by font manager as usual |
UnCache File | Delete uncached font information, or recache it | Processed by font manager as usual |
The use of Font_SetFontColours is not recommended, as it results in the setting of colours that depend on the current screen palette. Instead, set font colours to absolute RGB values using ColourTrans_SetFontColours or control (19) sequences within the string to be painted. Similarly, the use of colour-changing control sequences in strings passed to Font_Paint is not recommended.
How exactly this call operates varies quite markedly between printer drivers. For instance, most dot matrix printer drivers will probably use the font manager to write into the sprite they are using to hold the current strip of printed output, while the PostScript printer driver uses the PostScript prologue to define a translation from font manager font names to printer fonts.
Printer drivers intercept OS_SpriteOp via the SpriteV vector. Most calls are simply passed through to the operating system or the SpriteExtend module. The ones that normally plot to the screen are generally intercepted and processed by the printer driver to generate printer output.
If a sprite is printed unscaled, its size on the printed output is the same as its size would be if it were plotted to the screen using the screen mode in effect at the start of the print job. If it is printed scaled, the scaling factors are applied to this size. It is done this way in the expectation that the application is scaling the sprite for what it believes is the current screen mode.
The colours used to plot sprite pixels are determined as follows:
The latter method is strongly recommended over the former. As usual when printing, if you don't use ColourTrans calls, you will get unpredictable results that are dependent on the current screen palette.
The table below shows the printer driver's treatment of each SpriteOp reason code:
Reason code | Meaning | Printer driver's treatment |
---|---|---|
2 | Screen save | Faulted: unknown what 'screen' may be |
3 | Screen load | Faulted: unknown what 'screen' may be |
8 | Read area control block | Passed on |
9 | Initialise sprite area | Passed on |
10 | Load sprite file | Passed on |
11 | Merge sprite file | Passed on |
12 | Save sprite file | Passed on |
13 | Return name | Passed on |
14 | Get sprite | Faulted: unknown what 'screen' may be |
15 | Create sprite | Passed on |
16 | Get sprite from user coordinates | Faulted: unknown what 'screen' may be |
24 | Select sprite | Passed on for user sprite (ie when &100 or &200 added to reason code); faulted for system sprite (ie when reason code is 24); see note below |
25 | Delete sprite | Passed on |
26 | Rename sprite | Passed on |
27 | Copy sprite | Passed on |
28 | Put sprite | Processed |
29 | Create mask | Passed on |
30 | Remove mask | Passed on |
31 | Insert row | Passed on |
32 | Delete row | Passed on |
33 | Flip about x axis | Passed on |
34 | Put sprite at user coordinates | Processed |
35 | Append sprite | Passed on |
36 | Set pointer shape | Passed on |
37 | Create/remove palette | Passed on |
40 | Read sprite information | Passed on |
41 | Read pixel colour | Passed on |
42 | Write pixel colour | Passed on |
43 | Read pixel mask | Passed on |
44 | Write pixel mask | Passed on |
45 | Insert column | Passed on |
46 | Delete column | Passed on |
47 | Flip about y axis | Passed on |
48 | Plot sprite mask | Processed |
49 | Plot mask at user coordinates | Processed |
50 | Plot mask scaled | Processed |
51 | Paint character scaled | Faulted; you should instead pass the character to WrchV using OS_WriteC (or a derivative) |
52 | Put sprite scaled | Processed |
53 | Put sprite grey scaled | Processed, but normally treated as reason code 52, because grey-level anti-aliasing can be unpredictable and is hard to support |
54 | Remove lefthand wastage | Passed on |
55 | Plot mask transformed | Processed |
56 | Put sprite transformed | Processed |
57 | Insert/delete rows | Passed on |
58 | Insert/delete columns | Passed on |
60 | Switch output to sprite | Passed on; applications can still create sprites whilst printing |
61 | Switch output to mask | Passed on; applications can still create masks whilst printing |
62 | Read save area size | Passed on |
A call to SpriteV with reason code 24 is passed through to the operating system if it is for a user sprite (ie when &100 or &200 is added to the reason code), as the call is simply asking the operating system for the address of the sprite concerned. If the call is for a system sprite (ie nothing has been added to the reason code), it is faulted, because it is asking for a sprite to be selected for use with the VDU 25,232-239 sprite plotting sequences, which are themselves not supported by printer drivers.
The printer driver queues all characters sent through WrchV in the same way as the VDU drivers do, processing complete character sequences as they appear.
The printer driver will not pick up any data currently in the VDU queue, and may send sequences of its own to the VDU drivers. Consequently, you should not select a print job if there is an incomplete sequence in the VDU queue. Also, the output stream specification set by OS_Byte 3 should be in its standard state - as though set by OS_Byte 3,0. Finally, the printing application should not use any output calls whilst partway through sending a VDU sequence, as the two may clash.
When plotting starts in a rectangle supplied by a printer driver, the printer driver behaves as though the VDU system were in the following state:
This is designed to be as similar as possible to the state set up by the window manager when redrawing.
The printer driver maintains its own state, and calls that it processes alter this state rather than that of the screen. If WrchV is called but the printer driver does not currently want a rectangle printed, it will keep track of the state - for example, the current foreground and background colours - but will not produce any printer output.
Most printer drivers will either not do the rounding to pixel centres normally done by the VDU drivers, or will round to different pixel centres - probably the centres of their device pixels.
The table below shows the number of extra bytes needed to complete each character sequence, and whether the printer driver claims and processes the sequence, claims and faults it, claims and ignores it, or passes it on to the VDU drivers. It gives further information for most sequences, or a reference to a longer note following the table:
Character sequence | Extra bytes | Meaning | Printer driver's treatment |
---|---|---|---|
0 | 0 | Do nothing | Ignored |
1 | 1 | Send character to printer only | Faulted: would probably disrupt printing |
2 | 0 | Enable printer | Faulted: would probably disrupt printing |
3 | 0 | Disable printer | Ignored: would probably disrupt printing |
4 | 0 | Write text at text cursor | Faulted: text printing always uses graphics cursor |
5 | 0 | Write text at graphics cursor | Ignored: text printing always uses graphics cursor anyway |
6 | 0 | Enable processing of character sequences | Processed: reverses effect of character 21 |
7 | 0 | Generate bell sound | Passed on |
8 | 0 | Move cursor back one character | Processed: always moves graphics cursor |
9 | 0 | Move cursor on one character | Processed: always moves graphics cursor |
10 | 0 | Move cursor down one line | Processed: always moves graphics cursor |
11 | 0 | Move cursor up one line | Processed: always moves graphics cursor |
12 | 0 | Clear window | Processed: always clears graphics window |
13 | 0 | Move cursor to start of current line | Processed: always moves graphics cursor |
14 | 0 | Turn on page mode | Ignored: meaningless when printing |
15 | 0 | Turn off page mode | Ignored: meaningless when printing |
16 | 0 | Clear graphics window | Processed |
17 | 1 | Define text colour | Ignored: text colour is unused in graphics printing |
18 | 2 | Define graphics colour | Processed: see note below |
19 | 5 | Define logical colour | Passed on: affects screen hardware |
20 | 0 | Restore default logical colours | Passed on: affects screen hardware |
21 | 0 | Disable VDU drivers | Processed: printer driver parses but does not process subsequent character sequences, until it receives character 6 |
22 | 1 | Select screen mode | Faulted: cannot change the 'mode' of a printed page |
23,0 | 8 | Set the interlace or the cursor appearance | Passed on: affects screen hardware |
23,1 | 8 | Control the appearance of the cursor | Passed on: affects screen hardware |
23,2-5 | 8 | Define ECF pattern and colours | Passed on: affects global resources |
23,6 | 8 | Set dot-dash line style | Ignored: use Draw SWIs for dotted lines |
23,7 | 8 | Scroll text window or screen | Faulted: text printing always uses graphics window |
23,8 | 8 | Clear a block of the text window | Faulted: text printing always uses graphics window |
23,9 | 8 | Set flash time for first flashing colour | Passed on: affects screen hardware |
23,10 | 8 | Set flash time for second flashing colour | Passed on: affects screen hardware |
23,11 | 8 | Set default patterns | Passed on: affects global resources |
23,12-15 | 8 | Define ECF patterns and colours | Passed on: affects global resources |
23,16 | 8 | Control movement of cursor | Processed: bit 6 of the flags is ignored, and treated as if set |
23,17,0-1 | 7 | Set tint for text colours | Ignored: text printing always uses graphics colours |
23,17,2-3 | 7 | Set tint for graphics colours | Processed |
23,17,4 | 7 | Choose colour patterns used | Passed on: affects global resources |
23,17,5 | 7 | Exchange text foreground and background colours | Ignored: text printing always uses graphics colours |
23,17,6 | 7 | Set ECF origin | Passed on: affects global resources |
23,17,7 | 7 | Set character size/spacing | Processed: uses screen pixel size for the screen mode that was in effect when the print job was started |
23,18-24 | 8 | Reserved | Faulted: reserved, so meaning not known by printer driver |
23,25-26 | 8 | Obsolete font calls provided for compatibility | Faulted: obsolete |
23,27 | 8 | Obsolete sprite call provided for compatibility | Faulted: obsolete |
23,28-31 | 8 | Reserved | Faulted: reserved, so meaning not known by printer driver |
23,32-255 | 8 | Redefine printable characters | Passed on: affects global resource |
24 | 8 | Define graphics window | Processed: window must lie entirely within rectangle currently being printed, or unpredictable results will occur |
25,0-15 | 4 | Plot solid line | Processed |
25,16-31 | 4 | Plot dotted line | Processed: plots solid line (use Draw_Stroke to get dotted lines) |
25,32-47 | 4 | Plot solid line | Processed |
25,48-63 | 4 | Plot dotted line | Processed: plots solid line (use Draw_Stroke to get dotted lines) |
25,64-71 | 4 | Plot point | Processed |
25,72-79 | 4 | Horizontal line fill | Faulted: cannot be implemented on some printers |
25,80-87 | 4 | Triangle fill | Processed |
25,88-95 | 4 | Horizontal line fill | Faulted: cannot be implemented on some printers |
25,96-103 | 4 | Rectangle fill | Processed |
25,104-111 | 4 | Horizontal line fill | Faulted: cannot be implemented on some printers |
25,112-119 | 4 | Parallelogram fill | Processed |
25,120-127 | 4 | Horizontal line fill | Faulted: cannot be implemented on some printers |
25,128-143 | 4 | Flood fill | Faulted: cannot be implemented on some printers |
25,144-151 | 4 | Circle outline | Processed |
25,152-159 | 4 | Circle fill | Processed |
25,160-167 | 4 | Circular arc | Processed |
25,168-175 | 4 | Segment | Processed |
25,176-183 | 4 | Sector | Processed |
25,184 | 4 | Move relative | Processed: equivalent to 25,0 |
25,185-187 | 4 | Relative rectangle move/copy | Faulted: dependent on current picture contents |
25,188 | 4 | Move absolute | Processed: equivalent to 25,4 |
25,198-191 | 4 | Absolute rectangle move/copy | Faulted: dependent on current picture contents |
25,192-199 | 4 | Ellipse outline | Processed |
25,200-207 | 4 | Ellipse fill | Processed |
25,208-215 | 4 | Font plot | Faulted |
25,216-231 | 4 | Reserved | Faulted: reserved, so meaning not known by printer driver |
25,232-239 | 4 | Sprite plot | Faulted |
25,240-255 | 4 | Reserved | Faulted: reserved, so meaning not known by printer driver |
26 | 0 | Restore default windows | Processed: resets graphics window to maximum size (ie rectangle being printed) |
27 | 0 | Do nothing | Ignored |
28 | 4 | Define text window | Ignored: text printing always uses graphics window |
29 | 4 | Define graphics origin | Processed |
30 | 0 | Home cursor | Processed: always moves graphics cursor |
31 | 2 | Move cursor | Processed: always moves graphics cursor |
32-126 | 0 | Output printable character | Processed: outputs character in system font (use Font SWIs for font printing) |
127 | 0 | Delete | Processed |
128-255 | 0 | Output printable character | Processed: outputs character in system font (use Font SWIs for font printing) |
You should only use the GCOL sequence (VDU 18,gcol_action,colour) if absolutely necessary, and you should be aware of the fact that the printer driver has a simplified interpretation of the parameters, as follows:
We strongly recommend that applications should use ColourTrans calls to set colours, as these will allow the printer to produce as accurate an approximation as it can to the desired colour, independently of the screen palette.
It should be noted that most of the informational calls associated with the VDU drivers, and OS_ReadVduVariables in particular, will produce undefined results when a printer driver is active. These results are likely to differ between printer drivers. In particular, they will vary according to whether the printer driver plots to a sprite internally and if so, how large the sprite concerned is.
The only informational calls that the application may rely upon are:
This section describes a couple of somewhat unusual features of the printer drivers' error handling that an application author should be aware of. Before reading this, you should have read the Error handling whilst printing.
Firstly, Escape condition generation and side effects are turned on within various calls to the printer driver and restored to their original state afterwards. If the application has Escape generation turned off, it is guaranteed that any Escape generated within the print job will be acknowledged and turned into an 'Escape' error. If the application has Escape generation turned on, most Escapes generated within the print job will be acknowledged and turned into 'Escape' errors, but there is a small period at the end of the call during which an Escape will not be acknowledged. If the application makes a subsequent call of one of the relevant types to the printer driver, that subsequent call will catch the Escape. If no such subsequent call is made, the application will need to trap the Escape itself.
Escape generation is turned on permanently for these SWIs:
When the printer driver is intercepting plotting calls (ie there is an active print job, and plotting output is directed either to the screen or to a sprite internal to the printer driver, and the Wimp is not reporting an error - as defined by ServiceCall_WimpReportError) escape generation is also enabled for these calls:
Secondly, inside a number of calls, any error that occurs is converted into a 'persistent error'. The net effect of this is that:
The reason for this behaviour is to prevent errors that the application is not expecting from being ignored. For example, quite a lot of code assumes incorrectly that OS_WriteC cannot produce an error; generating a persistent error ensures that it cannot reasonably get ignored forever.
Persistent errors are created at all times for these SWIs:
When the printer driver is intercepting plotting calls, the following SWIs also generate persistent errors:
PDriver_CancelJob puts a print job into a similar state, with the error message being simply 'Print cancelled'. However, this error is only returned by subsequent calls from the list above, not by PDriver_CancelJob itself.
The Printers application is the user interface to the printing system. It is split into two parts.
The 'front end' of the Printers application contains those parts of the code that are device independent. This includes support for such things as the text printing queue, reading printer definition files.
The Printers application has several 'back ends', each of which contains code that is specific to a particular class of device. RISC OS 3 provides back ends for PostScript printers, LaserJet printers, and dot-matrix printers.
A back end implements such things as handling the printer configuration window for that class of printer, passing the information from that window to the printer drivers, and printing fancy text files. New back ends can be added to support new classes of printers, faxes, and so on.
Printer definition files are supplied with the other RISC OS applications in a directory named Printers. Inside this directory there is a Top_Left file used to calibrate the position of output on Epson and IBM compatible dot matrix printers, a subdirectory for each supported printer manufacturer (eg Epson, Star, Apple, etc), and a Read_Me file giving extra help.
Inside each of the subdirectories there are some printer definition files (eg FX-80) and a further Read_Me file. These Read_Me files give some technical detail on what is in each definition file, paying attention to tricky areas to guide you should you either want to modify the files, or want to choose the most appropriate starting point to provide support for a new printer. They also give some guidance on which files to try for 'compatible' printers.
You will find further help in the Printer definition files.
The PrintEdit application is used to edit dot matrix and LaserJet printer definition files. You can use this application to provide support for a new printer by editing the printer definition file of an already supported printer that has similar behaviour.
The FontPrint application is used to edit the list of supported fonts in the Printer application's configuration for the current PostScript printer. With it you can specify mappings between RISC OS font names and the printer's native font names, and the encodings that those fonts use. You can also specify whether a font is resident in the printer, or to be supplied by downloading it from RISC OS.
The PDriver module - also known as the PDriver sharer module - allows you to have multiple resident printer drivers, and hence easily use different devices such as a dot-matrix printer, a PostScript printer and a Fax card during the same session. The module is responsible for tracking which printer drivers are loaded, and which of these is the 'current' printer driver. It is also responsible for handling printer jobs, and tracking which printer driver owns which jobs.
When the PDriver sharer module starts up, it issues the service call Service_PDriverStarting (see Service_PDriverStarting (Service Call &65)). Any printer drivers resident at that time should declare themselves to the PDriver sharer module by calling PDriver_DeclareDriver (see PDriver_DeclareDriver).
The PDriver sharer module receives all printer driver SWIs. It processes some of these SWIs by itself, and some in conjunction with a printer driver, but passes on the majority to the current printer driver (set using PDriver_SelectDriver - see PDriver_SelectDriver).
Most of the SWIs that the PDriver sharer module processes in whole or in part by itself relate to job handling:
The code for the select SWIs is quite complex, as it has to deselect the current job on one driver, and then select the new job on a new driver. Any errors occurring in the selection process will lead to no job being selected on exit.
>Ending and Aborting are easily handled: they just clear the internal data for the specified job, and then pass through to the real driver. Resetting is similarly easy; it just requires that all drivers be reset.
Each printer driver handles a particular class of output device. They are mainly responsible for producing the device-dependent output necessary to print a page. They receive SWI calls via a handler registered with the PDriver sharer module when they declare themselves using PDriver_DeclareDriver; see PDriver_DeclareDriver for details of this mechanism.
RISC OS 3 provides printer drivers for PostScript printers (PDriverPS), and for bit image devices such as dot-matrix printers (PDriverDP).
PDriverDP differs from PDriverPS in that it is further subdivided, to cope with the wide range of available bit image devices.
The PDriverDP module itself handles the device-independent parts of printing, rendering print jobs into bit image strips. These strips are then passed to a PDumper module (or printer dumper).
Printer dumpers provide the actual device driving for a particular type of bit image printer, outputting the bit image in an appropriate manner. In RISC OS 3 (version 3.00) they are also responsible for performing colour matching, error diffusion and halftoning; the same code is duplicated in each printer dumper.
RISC OS 3 provides printer dumpers for LaserJets (PDumperLJ), ImageWriters (PDumperIW) and Integrex/Epson printers (PDumperDM). PDumperDM is effectively two printer dumpers in one; they are combined to save ROM space.
Note that there is not a one to one correspondence between printer dumpers and back ends for the Printers application. For example, the dot-matrix back end caters for both PDumperIW and PDumperDM.
For more information on printer dumpers, see the chapter entitled Printer Dumpers.
In RISC OS 3 (version 3.10) the colour matching, error diffusion and halftoning has been separated from the printer dumpers and is provided by an additional module called PDumperSupport. It reads in printer dumper palette files to do so; these are held in the Printers application.
The PDumperSupport module saves ROM space, and allows the code to be used as a resource by third party printer dumpers, as it provides a SWI interface. Alternatively, third parties may choose not to use this module, but instead to perform colour matching in their own printer dumpers. Another option is to replace the PDumperSupport module to modify the colour matching performed by the Acorn printer dumpers.
The diagram below summarises the printing system in RISC OS 3 (version 3.10):
The RISC OS 2 printing system was much simpler in structure, but at the expense of considerable duplication of code. Each printer driver had its own printing application. Only one such application could be loaded at once, hence there was no PDriver sharer module. Its job handling capabilities were supplied by each printer driver.
There were also no printer dumper modules, nor the PDumperSupport module. Each class of dot-matrix printer had its own printer driver. There was no support for ImageWriters.
If you were using a PostScript printer the structure was simply this:
Structure of printing system in RISC OS 2
(The other parts of the printing system - shown above in grey - could not have been loaded at the same time as the PostScript system.)
There are a variety of ways in which you can extend the printing system, replacing one or more of its parts. Acorn is prepared to supply source code for the current system to developers wishing to do this; we strongly recommend that you follow this route for maximum compatibility with the existing system.
You can add support for a new printer that closely matches an existing one by creating a new printer definition file (or more likely modifying an existing one) using the PrintEdit application. This may be for as trivial a reason as changing the name to match a particular printer or to make things more obvious to the user, or it may involve changing sequences to make things work better (or work at all) with a particular printer. Obviously you don't need source code to do this.
You need to add a new printer dumper if the existing ones don't understand the output format of the printer you wish to support, or if you want to optimise things for your printers (such as printing on 20 out of 24 pins, or providing new colour matching).
A new printer dumper is virtually guaranteed to need a new printer definition file. Sometimes the PrintEdit application will be capable of creating this (eg 20 out of 24 pins); sometimes you will need to create them by hand, to modify PrintEdit, or to write your own tool. You might also need to supply a new palette file for your dumper.
You will also need a new back end to the Printers application if your printer differs in major ways from those already supported: for example to add a direct drive laser printer, or a fax card. While these printers are still bit image - and thus can use a printer dumper - they need new text printing code, and (since they can't use the parallel port, for example) they need new printer connection management.
The LaserJet is a good example of this: it uses a printer dumper, yet it has its own back end since its text requirements differ from those of other dot-matrix printers.
To add a radically different type of printer you will need to write a new printer driver. For example, a pen plotter or turtle graphics printer might need a new driver.
You may wish to do this for an existing printer to modify the colour balance, whilst still using the Acorn drivers and printer dumpers.
Printer drivers are identified by numbers, which are used as parameters to many of the PDriver SWIs. Currently assigned printer driver numbers are:
Value | Meaning |
---|---|
0 | PostScript |
1 | Epson FX80 or compatible |
2 | HP LaserJet or compatible |
3 | Integrex ColourJet |
4 | FAX modem |
5 | Direct drive laser printer |
6 | Caspel graphics language |
7 | PDumper interface |
99 | Ace Computing Epson JX/Star LC10 driver or PaintJet driver |
The new PostScript printer drivers have enhanced support for utilising PostScript fonts resident in the printer, as well as the ability to download PostScript equivalents of RISC OS fonts.
As far as the application writer is concerned, the details of the process are transparent, but a brief summary is presented below.
When an application attempts to print a document containing fonts, it should declare them using PDriver_DeclareFont; see the chapter entitled Declare the fonts your document uses, and the documentation of the SWI on PDriver_DeclareFont.
When the printer driver is ready to output the PostScript prologue, it scans this list of fonts. Each name is passed to the MakePSFont module, which attempts to ensure that the font is available in the printer by one of the following methods:
The most efficient method possible is chosen - downloading is only done as a last resort, because the resulting fonts are very large.
To make this choice, the printer driver has to know which fonts are already available in the printer. This information is maintained by the printer driver system, and controlled by use of the FontPrint application. FontPrint lets the user specify the mapping between RISC OS font names and PostScript font names, such as Trinity.Medium maps to Times-Roman.
An old-style application does not make any calls to PDriver_DeclareFont, and hence the printer system cannot be certain about which fonts to provide. (The rules of PostScript prologue generation prevent us from simply sending the font the first time it is used in the print job - they must all be known in advance).
There are two mechanisms for coping with this situation. The simplest emulates the old printer driver and sends a prologue file that blindly provides a fixed set of fonts. This satisfies most old applications because they were written with this expectation. The advanced user can edit the prologue file by hand to adjust the list of fonts provided.
The second and more sophisticated method takes the intersection of the set of fonts known to the font manager and the set of fonts known by FontPrint to be resident in the printer. It passes each font in the resulting set to MakePSFont. Thus all of the fonts that can be provided by simple renaming of an existing PostScript font are sent, which is fairly comprehensive but still efficient.
The user chooses between these two mechanisms by the 'Verbose prologue' switch in the Printers configuration window.
A standard Adobe implementation of PostScript - such as that used on the Apple LaserWriter - has 35 fonts built in. Font names have been preallocated for RISC OS fonts that have the same metrics and general appearance as those fonts, and map onto them. This allows Acorn to produce a version of !PrinterPS that already knows the correct font name mappings. These names are:
You can use T1ToFont to convert AFM (Adobe Font Metrics) files into IntMetrics files, and hence ensure that the correct metrics are used.
You must not use it in your own code.
R1 = &65 (reason code)
All registers preserved
This service call is issued when the PDriver sharer module starts up. Any printer drivers resident at that time should declare themselves to the PDriver sharer module by calling PDriver_DeclareDriver (see PDriver_DeclareDriver).
R1 = &78 (reason code)
R0 - R8 must be preserved
R1 = 0 (implies service claimed)
R3 = pointer to 20 byte block for open messages file
This service call is issued by a PDriver module that is about to open the common message file for printer drivers, held in Resources:$.Resources.PDrivers.Messages. It is provided so that the module can find if another PDriver module has already opened the file, and if so get its MessageTrans block:
A PDriver module receiving this service call that is using the common messages file should set R3 to point to the MessageTrans block and claim the service call by setting R1 to zero.
R1 = &7F (reason code)
R2 = printer driver number of new driver (see Printer driver numbers)
All registers are preserved
This service call is issued when the PDriver sharer module has selected a new printer driver. R2 contains the printer driver number being selected; see Printer driver numbers for a list of these.
It is not issued if the currently selected printer driver is deselected, but no new one is selected.
This may be of use, for example, to a spooler module that needs to monitor which printer driver is currently selected.
--
R0 = version number and type:
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This calls tells an application what the capabilities of the attached printer are. This allows the application to change the way it outputs its data to suit the printer.
The values can be changed by the SWI PDriver_SetInfo, typically as a result of the user changing the printer configuration using the Printers application. If this call is made while a print job is selected, the values returned are those for that job (ie those in force when the job was first selected using PDriver_SelectJob). If this call is made when no print job is active, the values returned are those that would be used for a new print job.
The value returned in R0 is split in half. The bottom 16 bits of R0 have the version number of the printer driver × 100: eg Version 3.21 would be 321 (&0141). The top 16 bits contain the printer driver number of the currently selected driver; see Printer driver numbers for a list of these.
R3 returns a bitfield that describes the available features of the current printer. Most applications shouldn't need to look at this word, unless they wish to alter their output depending on the facilities available.
It is split into several fields:
Bits | Subject |
---|---|
0 - 7 | printer driver's colour capabilities |
8 - 15 | printer driver's plotting capabilities |
16 - 23 | reserved - must be set to zero |
24 - 31 | printer driver's optional features |
In more detail, each individual bit has the following meaning. For a complete description of the values bits 0 - 2 may have, see The table below shows the effect of bits 0 - 2 in more detail::
Bit(s) | Value | Meaning |
---|---|---|
0 | 0 | it can only print in monochrome. |
1 | it can print in colour. | |
1 | 0 | it supports the full colour range - ie it can manage each of the eight primary colours. Ignored if bit 0 = 0. |
1 | it supports only a limited set of colours. | |
2 | 0 | it supports a semi-continuous range of colours at the software level. Also, if bit 0 = 0 and bit 2 = 0, then an application can expect to plot in any level of grey. |
1 | it only supports a discrete set of colours at the software level; it does not support mixing, dithering, toning or any similar technique. | |
3 - 7 | reserved and set to zero. | |
8 | 0 | it can handle filled shapes. |
1 | it cannot handle filled shapes other than by outlining them; an unsophisticated XY plotter would have this bit set, for example. | |
9 | 0 | it can handle thick lines. |
1 | it cannot handle thick lines other than by plotting a thin line. (An unsophisticated XY plotter would also come into this category. The difference is that the problem can be solved, at least partially, if the plotter has a range of pens of differing thicknesses available.) | |
10 | 0 | it handles overwriting of one colour by another on the paper properly. This is generally true of any printer that buffers its output, either in the printer or the driver. |
1 | it does not handle overwriting of one colour by another properly, but only overwriting of the background colour by another. (This is a standard property of XY plotters.) | |
11 | 0 | it does not support transformed sprite plotting. |
1 | it supports transformed sprite plotting. | |
12 | 0 | it cannot handle new Font manager features. |
1 | it can handle new Font manager features such as transforms and encodings. | |
13 - 23 | reserved and set to zero. | |
24 | 0 | it does not support screen dumps. |
1 | it does support screen dumps. | |
25 | 0 | it does not support transformations supplied to PDriver_DrawPage other than scalings, translations, rotations by multiples of 90 degrees and combinations thereof. |
1 | it does support arbitrary transformations supplied to PDriver_DrawPage. | |
26 | 0 | it does not support the PDriver_InsertIllustration call |
1 | it does support the PDriver_InsertIllustration call | |
27 | 0 | it does not support the PDriver_MiscOp call. |
1 | it does support the PDriver_MiscOp call. | |
28 | 0 | it does not support the PDriver_SetDriver call. |
1 | it does support the PDriver_SetDriver call. | |
29 | 0 | it does not support the PDriver_DeclareFont call. |
1 | it does support the PDriver_DeclareFont call. |
The table below shows the effect of bits 0 - 2 in more detail:
The printer name pointed to by R4 is always null terminated, regardless of what the terminating character was when the name was passed to PDriver_SetInfo. If PDriver_SetInfo has not been called, then R4 will point to a zero length string on return from PDriver_Info.
A copy should be taken of the name at R4 if you intend to use this. With the introduction of multiple printer drivers this name can change.
The value in R7 - a printer driver specific number identifying the configured printer - is for internal use only.
R1 = x resolution of printer driven, in dots per inch
R2 = y resolution of printer driven, in dots per inch
R3 = features word:
R1 - R7 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call is used by the Printer application on the desktop to configure a printer driver so that it is set up for a specific printer within the general class of printers the driver supports. The printer name can also be modified; a copy is taken, and any future calls to PDriver_Info will return this modified string.
This call only affects print jobs started after it is called. Existing print jobs use whatever values were in effect when they were started.
Only bit 0 of the features word passed in R3 is used; all other bits are ignored.
The printer name in R4 is ignored by RISC OS 2.
The value in R7 - a printer driver specific number identifying the configured printer - is for internal use only.
This SWI must never be called by user applications.
R0 = mask of bits to check in features word
R1 = desired value of features word
R0, R1 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
If the features word that PDriver_Info would return in R3 satisfies (features_word AND R0) = (R1 AND R0), then it returns normally with all registers preserved. Otherwise a suitable error is generated if appropriate. For example, no error will be generated if the printer driver has the ability to support arbitrary rotations and your features word value merely requests axis preserving ones.
None
--
R1 = x size of paper (including margins), in millipoints
R2 = y size of paper (including margins), in millipoints
R3 = left edge of printable area of paper, in millipoints from paper's left edge
R4 = bottom edge of printable area of paper, in millipoints from paper's bottom edge
R5 = right edge of printable area of paper, in millipoints from paper's left edge
R6 = top edge of printable area of paper, in millipoints from paper's bottom edge
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call returns the size of the paper in use and its printable area. An application can use this information to decide how to place the data to be printed on the page.
The values can be changed by the SWI PDriver_SetPageSize, typically as a result of the user changing the printer configuration using the Printers application. If this call is made while a print job is selected, the values returned are those for that job (ie those in force when the job was first selected using PDriver_SelectJob). If this call is made when no print job is active, the values returned are those that would be used for a new print job.
All units are in millipoints, and R3 - R6 are relative to the bottom left corner of the page.
None
Set how large the paper and print area is
R1 = x size of paper (including margins), in millipoints
R2 = y size of paper (including margins), in millipoints
R3 = left edge of printable area of paper, in millipoints from paper's left edge
R4 = bottom edge of printable area of paper, in millipoints from paper's bottom edge
R5 = right edge of printable area of paper, in millipoints from paper's left edge
R6 = top edge of printable area of paper, in millipoints from paper's bottom edge
R1 - R6 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call is used by the Printers application to set - for a particular driver - the paper size and printable area associated with subsequent print jobs. It must never be called by user applications.
All units are in millipoints, and R3 - R6 are relative to the bottom left corner of the page.
R0 = file handle for print job to be selected, or zero to suspend current print job
R1 = pointer to a title string for the job, or zero if none
R0 = file handle for print job that was previously active, or zero if none
R1 preserved
Under RISC OS 3.1 and earlier, R7 is corrupted
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call makes a given print job the current one. The job is identified by the handle of the file used for output from the job (eg printer:), which must be open for output.
The current print job (if any) is suspended, and a print job with the given file handle is selected. If a print job with this file handle already exists, it is resumed; otherwise a new print job is started. The printer driver starts to intercept plotting calls if it is not already doing so.
A file handle of zero has special meaning; the current print job (if any) is suspended, and the printer driver ceases to intercept plotting calls.
Note that this call never ends a print job. To do so, use one of the SWIs PDriver_EndJob or PDriver_AbortJob.
The title string pointed to by R1 is treated by different printer drivers in different ways. It is terminated by any character outside the range ASCII 32 -126. It is only ever used if a new print job is being started, not when an old one is being resumed. Typical uses are:
An application is always entitled not to supply a title (by setting R1=0), and a printer driver is entitled to ignore any title supplied.
Printer drivers may also use the following OS variables when creating cover sheets, etc:
PDriver$For - indicates who the output is intended to go to
PDriver$Address - indicates where to send the output.
These variables must not contain characters outside the range ASCII 32 - 126.
If an error occurs during PDriver_SelectJob, the previous job will still be selected afterwards, though it may have been deselected and reselected during the call. No new job will exist. One may have been created during the call, but the error will cause it to be destroyed again.
PDriver_CurrentJob, PDriver_EndJob, PDriver_AbortJob, PDriver_Reset, PDriver_EnumerateJobs, PDriver_SelectIllustration
--
R0 = file handle for current job, or 0 if none
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call gets the file handle of the current job, returning it in R0. A value of zero is returned if no print job is active.
PDriver_SelectJob, PDriver_EndJob, PDriver_AbortJob, PDriver_Reset, PDriver_EnumerateJobs, PDriver_SelectIllustration
None
This call is part of the internal interface between the font system and printer drivers. Applications must not call it.
R0 = file handle for print job to be ended
R0 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call should be used to end a print job normally. This may result in further printer output - for example, the PostScript printer driver will produce the standard trailer comments.
If the print job being ended is the currently active one, there will be no current print job after this call, so plotting calls will no longer be intercepted.
If the print job being ended is not currently active, it will be ended without altering which print job is currently active or whether plotting calls are being intercepted.
PDriver_SelectJob, PDriver_CurrentJob, PDriver_AbortJob, PDriver_Reset, PDriver_CancelJob, PDriver_CancelJobWithError, PDriver_SelectIllustration
R0 = file handle for print job to be aborted
R0 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call should be used to end a print job abnormally. It should be called immediately you get an error while printing, before you try to display the error message. It will not try to produce any further printer output. This is important if an error occurs while sending output to the print job's output file.
If the print job being aborted is the currently active one, there will be no current print job after this call, so plotting calls will no longer be intercepted.
If the print job being aborted is not currently active, it will be aborted without altering which print job is currently active or whether plotting calls are being intercepted.
PDriver_SelectJob, PDriver_CurrentJob, PDriver_EndJob, PDriver_Reset, PDriver_CancelJob, PDriver_CancelJobWithError, PDriver_SelectIllustration
None
Abort all print jobs
--
--
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This SWI aborts all print jobs known to all printer drivers, leaving the printer drivers with no active or suspended print jobs and ensuring that plotting calls are not being intercepted.
Normal applications shouldn't use this SWI, but it can be useful as an emergency recovery measure when developing an application.
The state of the printer driver after this call is not necessarily the same as it is after initialisation. For example, the PostScript printer driver does not know of any fonts (see PDriver_MiscOp).
A call to this SWI is generated automatically if the machine is reset or the printer driver module is killed or RMTidy'd.
PDriver_SelectJob, PDriver_CurrentJob,
PDriver_EndJob, PDriver_AbortJob, PDriver_SelectIllustration
R0 = rectangle identification word (specified by application)
R1 = pointer to 4 word block, containing rectangle to be plotted (in OS units)
R2 = pointer to 4 word block, containing transformation table
R3 = pointer to 2 word block, containing the plot position (in millipoints)
R4 = background colour for this rectangle, in the form &BBGGRR00.
R0 - R4 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This SWI allows an application to specify a rectangle from its workspace to be printed, how it is to be transformed and where it is to appear on the printed page.
The word in R0 is reported back to the application when it is requested to plot all or part of this rectangle.
The 4 word block pointed to by R1 contains the following:
Word | Contents |
---|---|
0 | low x coordinate of rectangle to print, in OS units (inclusive) |
1 | low y coordinate of rectangle to print, in OS units (inclusive) |
2 | high x coordinate of rectangle to print, in OS units (exclusive) |
3 | high y coordinate of rectangle to print, in OS units (exclusive) |
The value passed in R2 is the dimensionless transformation to be applied to the specified rectangle before printing it. The entries are given as fixed point numbers with 16 binary places, so the transformation is:
x' = (x × R2!0 + y × R2!8)/216
y' = (x × R2!4 + y × R2!12)/216
(The rectangle and the transformation are very similar to Draw module rectangles and transformation matrices.)
The value passed in R3 is the position where the bottom left corner of the rectangle is to be plotted on the printed page in millipoints.
An application should make one or more calls to PDriver_GiveRectangle before a call to PDriver_DrawPage and the subsequent calls to PDriver_GetRectangle. Multiple calls allow the application to print multiple rectangles from its workspace to one printed page - for example, for 'two up' printing.
The printer driver may subsequently ask the application to plot the specified rectangles or parts thereof in any order it chooses. An application should not make any assumptions about this order or whether the rectangles it specifies will be split. A common reason why a printer driver might split a rectangle is that it prints the page in strips to avoid using excessively large page buffers.
Assuming that a non-zero number of copies is requested and that none of the requested rectangles go outside the area available for printing, it is certain to ask the application to plot everything requested at least once. It may ask for some areas to be plotted more than once, even if only one copy is being printed, and it may ask for areas marginally outside the requested rectangles to be plotted. This can typically happen if the boundaries of the requested rectangles are not on exact device pixel boundaries.
If PDriver_GiveRectangle is used to specify a set of rectangles that overlap on the output page, the rectangles will be printed in the order of the PDriver_GiveRectangle calls. For appropriate printers (ie most printers, but not XY plotters for example), this means that rectangles supplied via later PDriver_GiveRectangle calls will overwrite rectangles supplied via earlier calls.
The rectangle specified should be a few OS units larger than the 'real' rectangle, especially if important things lie close to its edge. This is because rounding errors are liable to appear when calculating bounding boxes, resulting in clipping of the image. Such errors tend to be very noticeable, even when the amounts involved are small. We recommend that you initially try a margin of 1 point (21/2 OS units), increasing this if results are not satisfactory.
However, you shouldn't make the rectangle a lot larger than the real rectangle. This will result in slowing the process down and use of unnecessarily large amounts of memory. Also, some subsequent users may scale the image according to this rectangle size (say to use some PostScript as an illustration in another document), resulting in it being too small.
R0 = number of copies to print
R1 = pointer to 4 word block, to receive the rectangle to print (in OS units)
R2 = page sequence number within the document, or 0
R3 = pointer to a page number string, or 0
R0 = non-zero if more rectangles to be printed, zero if finished
R1 preserved
R2 = identification word for rectangle containing rectangle to print - if R0 0
R3 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This SWI should be called after all rectangles to be plotted on the current page have been specified using PDriver_GiveRectangle. It returns the first rectangle (if any) that the printer driver wants plotted in the area.
R2 on entry is zero or contains the page's sequence number within the document being printed (ie. 1-n for an n-page document).
R3 on entry is zero or points to a string, terminated by a character in the ASCII range 33 - 126, which gives the text page number: for example '23', 'viii', 'A-1'. Note that spaces are not allowed in this string.
If R0 is non-zero on exit, the area pointed to by R1 has been filled in with the rectangle that needs to be plotted, and R2 contains the rectangle identification word for the user-specified rectangle that this is a part of. If R0 is zero, the contents of R2 and the area pointed to by R1 are undefined. The rectangle in R1 is in user coordinates before transformation.
Your application should stop trying to plot the current page if R0 = 0, and continue otherwise.
If R0 0, it in fact gives the number of copies still to be printed, but this is only intended to be used for information purposes - for example, putting a 'Printing page m of n' message on the screen. Note that on some printer drivers you cannot rely on this number changing incrementally, ie it may suddenly go from n to zero. As long as it is non-zero, R0's value does not affect what the application should try to plot.
The 4 word block pointed to by R1 contains the following on exit:
Word | Contents |
---|---|
0 | low x coordinate of rectangle to print, in OS units (inclusive) |
1 | low y coordinate of rectangle to print, in OS units (inclusive) |
2 | high x coordinate of rectangle to print, in OS units (exclusive) |
3 | high y coordinate of rectangle to print, in OS units (exclusive) |
The information passed in R2 and R3 is not particularly important, though it helps to make output produced by the PostScript printer driver conform better to Adobe's structuring conventions. If non-zero values are supplied, they should be correct. Note that R2 is not the sequence number of the page in the print job, but in the document. For example, if a document consists of 11 pages, numbered '' (the title page), 'i'-'iii' and '1'-'7', and the application is requested to print the entire preface part, it should use R2 = 2, 3, 4 and R3 'i', 'ii', 'iii' for the three pages.
None
Get the next print rectangle
R1 = pointer to 4 word block, to receive the rectangle to print (in OS units)
R0 = non-zero if more rectangles to be printed, zero if finished
R1 preserved
R2 = identification word for rectangle containing rectangle to print - if R0 0
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This SWI should be used after plotting a rectangle returned by a previous call to PDriver_DrawPage or PDriver_GetRectangle, to get the next rectangle the printer driver wants plotted. It returns precisely the same information as PDriver_DrawPage.
Stops the print job associated with a file handle from printing
R0 = file handle for job to be cancelled
R0 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This SWI causes subsequent attempts to output to the print job associated with the given file handle to do nothing other than generate the error 'Print cancelled'. An application is expected to respond to this error by aborting the print job, which must be done before giving any error message. See the chapter entitled Error handling changes.
PDriver_EndJob, PDriver_AbortJob, PDriver_CancelJobWithError
None
R0 = file handle of file to receive the dump
R0 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
If this SWI is supported (ie if bit 24 of R3 is set on exit from PDriver_Info), this call makes the printer driver output a screen dump to the file handle supplied in R0. The file concerned should already be open for output.
If the SWI is not supported, an error is returned.
Note that currently none of the Acorn printer drivers support this SWI.
None
None
R0 = zero to enumerate first print job, or handle returned from previous call
R0 = next print job handle, or zero if no more
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call enumerates all the existing print jobs within the system, returning their job handles. The order in which they appear is undefined. To enumerate the complete list you should set R0 to zero and repeatedly call this SWI until R0 is returned as zero.
None
This call is used to set options specific to a particular printer driver. It is a private interface between the RISC OS 2 printing applications and the corresponding printer drivers. You must not use it.
This SWI has now been superseded by the SWI PDriver_SetDriver.
Cancels a print job - future attempts to output to it generate an error
R0 = file handle for job to be cancelled
R1 = pointer to error block
R0, R1 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This SWI causes subsequent attempts to output to the print job associated with the given file handle to do nothing other than generate the specified error. An application is expected to respond to this error by aborting the print job, which must be done before giving any error message. See the chapter entitled Error handling changes.
This call is not available in RISC OS 2, unless version 2.00 or above of the printer driver module has been soft-loaded.
None
Makes the given print job the current one, and treats it as an illustration
R0 = file handle for print job to be selected, or 0 to deselect all jobs
R1 = pointer to title string for job, or 0
R0 = file handle for previously active print job, or 0 if none was active
R1 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call does exactly the same thing as PDriver_SelectJob, except when it used to start a new print job. In this case, the differences are:
The intention of this SWI is that it should be used instead of PDriver_SelectJob when an application is printing a single page that is potentially useful as an illustration in another document. For example, the Draw application uses this to print.
We recommend that the user should explicitly choose when a print job is to be saved to file for use as an illustration in another document. Only if the user has made that choice should you call this SWI; you should call PDriver_SelectJob for all other printing.
This call is not available in RISC OS 2, unless version 2.00 or above of the printer driver module has been soft-loaded.
PDriver_SelectJob, PDriver_CurrentJob, PDriver_EndJob, PDriver_AbortJob, PDriver_Reset, PDriver_CancelJob, PDriver_CancelJobWithError
Inserts a file containing an illustration into the current job's output
R0 = file handle for file containing illustration
R1 = pointer to Draw module path to be used as a clipping path, or 0 if no clipping is required
R2 = x coordinate of where the bottom left corner of the illustration is to go
R3 = y coordinate of where the bottom left corner of the illustration is to go
R4 = x coordinate of where the bottom right corner of the illustration is to go
R5 = y coordinate of where the bottom right corner of the illustration is to go
R6 = x coordinate of where the top left corner of the illustration is to go
R7 = y coordinate of where the top left corner of the illustration is to go
R0 - R7 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
If this SWI is supported (ie if bit 26 of R3 is set on exit from PDriver_Info), it inserts an external file containing an illustration, such as an Encapsulated PostScript file, into the current job's output. The format of such an illustration file depends on the printer driver concerned, and many printer drivers won't support any sort of illustration file inclusion at all.
All coordinates in the clipping path and in R2 - R7 are in 256ths of an OS unit, relative to the PDriver_GiveRectangle rectangle currently being processed.
This call is not available in RISC OS 2, unless version 2.00 or above of the printer driver module has been soft-loaded.
R0 = handle of font to be declared, or zero
R1 = pointer to name of font to be declared, or zero
R2 = flags word:
R0 - R2 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call declares the fonts that will be used in a document, either by name or by handle. Certain printer drivers need this information before printing begins; for example, the PostScript driver needs it to perform font downloading, and to conform with structuring rules for PostScript documents. You should declare fonts after you have called PDriver_SelectJob or PDriver_SelectIllustration to start the print job.
Before calling PDriver_DeclareFont you must check if the printer driver you are using supports it by calling PDriver_Info and examining bit 29 of R3 on return. If it is set you should declare each distinct font that your document uses by repeated calls of PDriver_DeclareFont. For the purposes of this call, a font is 'distinct' if it differs in its name, encoding or matrix fields (\F, \E or \M; for details of font name syntax see the chapter entitled The Font Manager). You must not declare other variations in the font such as size, colour, etc. You may declare the font by its handle (passed in R0), or by a pointer to its name (R0 = 0, R1 = pointer to name). Any font name you pass must be exactly the same as is passed to Font_FindFont (see Font_FindFont), including any encoding and matrix information.
After you have declared all the fonts, you must make one further call with both R0 and R1 set to zero to signify the end of the list. If your document does not use any fonts you should still make this 'end of list' call; the printer driver then knows that your application is aware of this call, and will generate more efficient output.
The flags word gives other information about the font.
Once you have declared the fonts your application may then go on to make any PDriver_DrawPage request (PDriver_DrawPage).
If this SWI is not called at all, the results are printer driver dependent. PDriverDP does not care in the least whether you call this SWI or not. On the other hand PDriverPS does care, and will perform default actions configured by the user, dependent on which fonts are already in the printer and which fonts need to be downloaded.
This call is not available under RISC OS 2.
None
R0 = pointer to reason code handler for driver
R1 = pointer to driver's private word (to be passed in R12 when calling driver)
R2 = printer driver number
R0 - R2 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call registers a printer driver with the PDriver sharer module. A driver should make this call when it is started, or when it receives Service_PDriverStarting. The driver can then be selected using PDriver_SelectDriver. Duplicate printer drivers are not allowed, and an error is generated if the driver is already registered.
You must register any new printer driver numbers with Acorn; see the chapter entitled Printer driver and printer dumper numbers.
The driver passes pointers to a reason code handler and to a private word (typically the driver's private workspace pointer). The driver's reason code handler provides entry points used by the sharer to implement PDriver_... SWIs. The sharer fully implements these SWIs itself:
PDriver_RemoveDriver
PDriver_SelectDriver
PDriver_EnumerateDrivers
For all other SWIs, the sharer subtracts the PDriver SWI chunk base (&80140) from the SWI number to derive a reason code, and then calls the appropriate driver's reason code handler with the following register usage:
R11 = reason code (SWI number - &80140)
R12 = pointer to private word
R14 = return address
Other register usage as documented for corresponding SWI
V clear - register usage as documented for corresponding SWI
V set - R0 = pointer to error block
The handler should implement the functionality of the SWI, as documented.
This call is not available under RISC OS 2.
R0 = printer driver number (see Printer driver numbers)
R0 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call deregisters a printer driver with the PDriver sharer module. This cancels all jobs associated with the driver. Doing so can get some applications confused - and possibly crash them, if they have pending jobs and believe the driver to still be present - so we strongly recommend that a driver checks that it has no pending jobs before calling this SWI.
This call is not available under RISC OS 2.
None
R0 = printer driver number (Printer driver numbers), or -1 to set no current active driver, or -2 to read current driver
R0 = previous driver number, or -1 if none
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call selects the specified driver, returning an error if the driver has not been registered. This call is not designed for use by applications' authors, and should only be used by the Printer application.
If you must use this call, your code should store the previous driver number (returned in R0), and attempt to reselect it when finished.
This call is not available under RISC OS 2.
PDriver_DeclareDriver, PDriver_RemoveDriver, PDriver_EnumerateDrivers
None
R0 = zero to enumerate first driver, or handle returned from previous call
R0 = handle to enumerate next driver, or zero if no more
R1 = printer driver number if R0 0, or undefined if no more
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call enumerates all the drivers within the system, returning their printer driver numbers (a list of which is on Printer driver numbers). To enumerate the complete list you should set R0 to zero and repeatedly call this SWI until R0 is returned as zero.
This call is not available under RISC OS 2.
None
R0 = reason code
Other registers are reason code dependent
Reason code dependent
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call processes miscellaneous printer driver operations. The action depends on the reason code passed in R0:
Reason codes with bit 31 clear are applicable to all drivers, whereas those with bit 31 set are driver specific.
This call is not available under RISC OS 2.
None
Adds a font name to a list of those known to the current printer
R0 = 0 (reason code)
R1 = pointer to RISC OS font name (control-character terminated)
R2 = pointer to printer's native font name (control-character terminated), or 0 if none
R3 = flag word for printer dependent code:
R0 - R4 preserved
This call adds a font name to a list of those known to the current printer. It is used by the Printers application, and need not be called by other applications.
If no job is selected, the font name gets added to a global list which describes the fonts known to the printer. If a job is selected, the font name instead gets added to a local list - associated with the job - which describes the fonts and their mappings within that job. Each record is stored as a separate block within the RMA. When PDriver_SelectJob is called to start a job, the local list is initialised by copying the blocks in the current global list.
The RISC OS font name pointed to by R1 should ideally contain the encoding vector used (ie \Ffont_name \Eencoding); you can also include matrix information for derived fonts. This name is case insensitive.
R2 contains a pointer to the printer's native font name to be associated with the RISC OS font name. This is case sensitive, and is used by the printer dependent code as required. You may pass a null name if necessary; for example direct drive laser printer drivers don't have native font names.
R3 is a flag word to be used by the printer dependent code; see specific printer documentation for further details.
R4 contains a flag word to associate with the addition of the record. Bit 0 controls what happens when you try to add a font name that has already been defined; if the bit is set, the old data gets overwritten, whereas if it is clear an error is generated.
Removes font name(s) from a list of those known to the current printer
R0 = 1 (reason code)
R1 = pointer to RISC OS font name (control-character terminated), or zero to delete all fonts
R0, R1 preserved
This call is used to remove font name(s) from a list of those known to the current printer. It is used by the Printers application, and need not be called by other applications.
R1 points to the font name to be removed, but if this pointer is zero, all font names get removed.
If no job is selected, the font name(s) get removed from the global list; if a job is selected, the font name(s) instead get removed from the local list. See PDriver_MiscOp 0 on PDriver_MiscOp 0 for more details of how these lists are used.
No error is generated if you attempt to remove all font names but none are registered, whereas an error will be generated if you attempt to remove a specific font name that is not present.
Current versions of this call ignore R1, and always remove all fonts.
Enumerates the font name(s) in a list of those known to the current printer
R0 = 2 (reason code)
R1 = pointer to return buffer, or zero to return required size of buffer
R2 = size of return buffer, or zero to return required size of buffer
R3 = zero to enumerate first font names, or handle returned from previous call, or (if R1 = R2 = 0) header size to add to returned buffer size
R4 = flags:
if R1 0 on entry then:
R1 = pointer to first free byte in buffer
R2 = number of free bytes in buffer
R3 = handle to enumerate next font names, or zero if no more
R4 preserved
else:
R1 preserved
R2 = required size of buffer to return data + header size passed in R3
R3, R4 preserved
This call enumerates the font name(s) in a list of those known to the current printer. It is used by the Printers application, and need not be called by other applications.
To enumerate the complete list you should set R3 to zero and repeatedly call this SWI until R3 is returned as zero
If no job is selected, the global list is enumerated; if a job is selected, the local list is instead enumerated. See PDriver_MiscOp 0 on PDriver_MiscOp 0 for more details of how these lists are used.
The font names are returned as a series of three word records in the return buffer:
Offset | Meaning |
---|---|
0 | pointer to RISC OS font name (control-character terminated) |
4 | pointer to native font name (control-character terminated) |
8 | flag word for printer dependent code (see PDriver_MiscOp 0) |
The font names are stored in blocks within the RMA. Ideally you should make a copy of these, as someone could later remove them by calling PDriver_MiscOp 1.
Before enumerating the fonts you can find the required size of the return buffer by calling this SWI with R1 and R2 set to zero, and R3 set to the size of any header for which you wish to pre-allocate room. The required buffer size is returned in R2 (ie sufficient to hold all enumerated fonts, and the given size of header).
R0 = &80000000 (reason code)
R1 = number of printer dumper to register (see Printer dumper numbers and names)
R2 = version of PDriverDP required by dumper × 100
R3 = pointer to dumper's private word (to be passed in R12 when calling dumper)
R4 = pointer to reason code handler for dumper
R5 = supported calls bit mask
R6 = supported strip types bit mask
R0 - R6 preserved
This call registers a printer dumper with PDriverDP. A dumper should make this call when it is started, or when it receives Service_PDumperStarting. We recommend you use the PDriver_MiscOpForDriver, as this ensures correct operation even if PDriverDP is not the currently selected driver. Duplicate printer dumpers are not allowed, and an error is generated if the dumper is already registered.
The dumper passes pointers to a reason code handler, and to a private word (typically the dumper's private workspace pointer). The dumper's reason code handler provides entry points used by PDriverDP to implement those parts of its functionality that are printer dependent, such as initialising a printer, or outputting a strip of an image.
The dumper also passes a bit mask in each of R5 and R6. If bit n of the mask is set, then it shows (respectively) that the printer dumper supports reason code n or that it can output strip type n. A dumper must support reason codes 0 - 7, and strip types 0 - 2; PDriverDP will assume that it does so. Bits corresponding to undefined reason codes or strip types must be zero.
For details of the current range of reason codes and strip types - and of the entry conditions for the handler - see the chapter entitled Reason code handler entry and exit conditions.
R0 = &80000001 (reason code)
R1 = number of printer dumper to deregister (see Printer dumper numbers and names)
R0, R1preserved
This call deregisters a printer dumper with PDriverDP. A dumper should make this call when it dies. This call may return an error, especially if the dumper is currently being used for a print job, in which case the dumper must refuse to die, returning the original error. We recommend you use the PDriver_MiscOpForDriver form (see PDriver_MiscOpForDriver), as this ensures correct operation even if PDriverDP is not the currently selected driver.
An extension mechanism to provide direct control over a printer dumper
R0 = &80000100 - &80000FFF (reason code)
R1 = number of printer dumper to process call (see Printer dumper numbers and names)
R2 - R7 are reason code dependent
Reason code dependent
These calls are an extension mechanism to provide direct control over a printer dumper. Registers R0 - R7 are passed straight through to the specified dumper using the MiscOp entry point; the processing of these registers is dumper-specific.
All current Acorn printer dumpers do not use this feature, and merely return control immediately the MiscOp entry point is called.
Processes miscellaneous printer driver operations using a specified driver
R0 = reason code
R8 = number of printer driver to which to pass call
Other registers are reason code dependent
Reason code dependent
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call processes miscellaneous printer driver operations using a specified driver. It is identical to PDriver_MiscOp, save that the call gets passed to the driver specified in R8. For details of the various reason codes see PDriver_MiscOp 0 onwards.
This call is not available under RISC OS 2.
Sets the current printer dumper, if PrinterDM is the current printer driver
R1 = printer dumper number (see Printer dumper numbers and names)
R2 = pointer to command to ensure printer dumper present
R3 = pointer to 256 byte data block giving dumper configuration data
R4 = pointer to 256 byte block giving PDriverDP and dumper configuration data
R5 = configuration word for dumper
R1 - R5 preserved
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call sets the current printer dumper to that specified by the number held in R1. It does so by calling the dumper's reason code handler with reason code 0. For a list of current printer dumper numbers, see Printer dumper numbers and names.
R2 points to a command line, used to load the printer dumper if it is not already loaded. The length of this command line should not exceed 256 bytes including the terminating character.
R3 and R4 are both pointers to 256 byte data blocks containing configuration data for the dumper. PDriverDP copies each block, adds some information to the block pointed to by R4 (see below), and then passes the dumper pointers to the copies. Consequently you may free the original buffers on exit.
R5 is a configuration word, the meaning of which is dumper-specific.
The information that PDriverDP adds to the copy of the block pointed to by R4 consists of 12 unsigned bytes at the start of the block (which overwrite the existing contents):
Offset | Meaning |
---|---|
0 | height in dots of a strip (pin height × no. of vertical interlace passes: |
ie PrintEdit's DumpDepth) | |
1 | number of vertical interlace passes - 1(ie PrintEdit's x interlace) |
2 | number of horizontal interlace passes - 1(ie PrintEdit's y interlace) |
3 | number of passes over line - 1: for multiple pass printing, eg colour |
4 | strip type (see Strip types) |
5 | output depth (bits per pixel): can only be 1 (monochrome) or 8 (grey or colour) |
6 | number of passes per strip, 0 1 pass: useful for colour separation |
7 | number of current pass |
8 - 11 | PDriverDP's copy of dumper's private word |
and 4 signed words that are appended to the block:
Offset | Meaning |
---|---|
256 | configuration word for dumper (as passed in R5) |
260 | pointer to active printer dumper |
264 | printer dumper number (as passed in R1) |
268 | left margin in pixels (calculated from the Printers application's paper sizes) |
For details of the information the Printers application places in the buffers and configuration word when it makes this call, see the documentation of PDumperReason_SetDriver on PDumperReason_SetDriver (reason code 0).
This SWI is used as part of the private interface between the Printers application and PDriverPS. You must not use it from your own applications; it is only of relevance to anyone wishing to replace the current PostScript printer drivers. See the chapter entitled Extending the printing system.
This call is not available under RISC OS 2.
None
This is an example BASIC procedure that does a standard 'two up' printing job:
DEFPROCprintout(firstpage%, lastpage%, title$, filename$, fontptr%) REM Open destination file and set up a local error handler that REM will close it again on an error. LOCAL H%, O% H% = OPENOUT(filename$) LOCAL ERROR ON ERROR LOCAL:RESTORE ERROR:CLOSE#H%:PROCpasserror REM Start up a print job associated with this file, remembering the REM handle associated with the previous print job (if any), then REM set up a local error handler for it. SYS "PDriver_SelectJob",H%,title$ TO O% LOCAL ERROR ON ERROR LOCAL:RESTORE ERROR:SYS"PDriver_AbortJob",H%:SYS"PDriver_SelectJob",O%:PROCpasserror PROCdeclarefonts(fontptr%) : REM Now we decide how two pages are to fit on a piece of paper. LOCAL left%, bottom%, right%, top% REM see below for an explanation of PROCgetdocumentsize PROCgetdocumentsize(box%) SYS "PDriver_PageSize" TO ,,,left%,bottom%,right%,top% REM see below for an explanation of PROCfittwopages PROCfittwopages(left%,bottom%,right%,top%,box%,matrix%,origin1%,origin2%) : REM Start the double page loop LOCAL page%, copiesleft%, pagetoprint%, white% white%=&FFFFFF00 : FOR page%=firstpage% TO lastpage% STEP 2 : REM Set up to print two pages, or possibly just one last time around. SYS "PDriver_GiveRectangle", page%, box%, matrix%, origin1%, white% IF page%<lastpage% THEN SYS "PDriver_GiveRectangle", page%+1, box%, matrix%, origin2%, white% ENDIF : REM Start printing. As each printed page corresponds to two document pages, REM we cannot easily assign any sensible page numbers to printed pages. REM So we simply pass zeroes to PDriver_DrawPage. SYS "PDriver_DrawPage",1,box2%,0,0 TO copiesleft%,,pagetoprint% WHILE copiesleft%<>0 REM see below for an explanation of PROCdrawpage PROCdrawpage(pagetoprint%, box2%) SYS "PDriver_GetRectangle",,box% TO copiesleft%,,pagetoprint% ENDWHILE : REM End of page loop NEXT REM All pages have now been printed. Terminate this print job. SYS "PDriver_EndJob",H% : REM Go back to the first of our local error handlers. RESTORE ERROR : REM And go back to whatever print job was active on entry to this procedure REM (or to no print job if no print job was active). SYS "PDriver_SelectJob",O% : REM Go back to the caller's error handler. RESTORE ERROR REM Close the destination file. CLOSE#H% ENDPROC : DEFPROCpasserror SYS "BASICTrans_Message",42,ERL,REPORT$ TO ;flags% IF (flags% AND 1)<>0 THEN REPORT:IF ERL<>0 THEN PRINT" at line "ERL ELSE PRINT ENDIF ENDPROC
This uses the following global areas of memory:
box% - 4 words
box2% - 4 words
matrix% - 4 words
origin1% - 2 words
origin2% - 2 words
And the following external procedures:
DEFPROCdeclarefonts(fontptr%)
DEFPROCgetdocumentsize(box%)
DEFPROCfittwopages(l%, b%, r%, t%, box%, transform%, org1%, org2%)
DEFPROCdrawpage(page%, box%)
If printing is likely to take a long time and the application does not want to hold other applications up while it prints, you may like to use multitasking. To do so, you should regularly use a sequence like the following during printing:
SYS "PDriver_SelectJob",O% SYS "Wimp_Poll",mask%,area% TO reason% ... process reason% as appropriate ... SYS "PDriver_SelectJob",H% TO O%
However, you should first see the chapter entitled Multitasking whilst printing, which explains the issues involved in multitasking printing.