RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Printer Drivers


Introduction

Printing from applications

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.

The structure of the printing system

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.

Overview

Rectangles

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.

Measurement systems

Millipoints

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

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.

Transform matrix

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.

Printing a document from an application

Overview of printing

This section describes how to print from an application.

Initiating printing under the Wimp

If your application is running under the Wimp, it must initiate printing using the Wimp message protocol described in the The Printer protocol.

Get information on the printer you're going to use

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:

  • the type of printer driver in use
  • the version number of that printer driver
  • the x and y resolution of the printer in use
  • the name of the printer in use
  • the halftone resolution of the printer (if any).

It also returns a features word giving a bit mask showing:

  • the printer driver's colour and shading capabilities
  • the printer driver's plotting capabilities, such as its ability to handle filled shapes, thick lines, overwriting and transformed sprites
  • the printer driver's support for optional features such as screen dumps, arbitrary transformations, insertion of illustrations, and font declaration and handling.

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:

  • PDriver_CheckFeatures (see PDriver_CheckFeatures) provides a quick way of checking if specific features are available by comparing a bit mask of features you desire to be present against the printer driver's own features word.
  • PDriver_PageSize returns the size of the paper in use and its printable area.
Open the printer: file for output

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.

Start a new print job

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.

Declare the fonts your document uses

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.

Specify the rectangles to be printed on a page

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).

Print the rectangles specified by the printer driver

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.

Similarities with the Window Manager

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.

Draw any other pages

For each page, you must repeat the procedure in the above two sections.

End the print job

To end the print job, you must call PDriverEndJob (see PDriver_EndJob).

Close the output file

Finally, you must close the output file you've been using (typically 'printer:').

Error handling whilst printing

If you get an error from any printing SWI or from any other call whilst printing pages, you must do one of the following:

  • Correct the cause of the error and continue
  • Immediately call PDriver_AbortJob to end the current job before any error message or other output occurs.

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 whilst printing

Multitasking (ie calling Wimp_Poll) whilst printing has an obvious advantage:

  • You can use other applications whilst printing takes place.

However, there are problems associated with it:

  • Multitasking is incompatible with the queueing mechanism used by the Printers application. If you call Wimp_Poll whilst printing, the Printers application will assume that you have finished; if there is another job in the queue it will continue with that, which will obviously cause an immediate error. Future versions of RISC OS may address this problem.
  • It is difficult to arrange your printing such that you call Wimp_Poll sufficiently often to confer a useful degree of multitasking on the rest of the system, since you cannot predict for all classes of printer the size and complexity of rectangles that you will be asked to print.

    To do so properly, you need to use a timer.

  • You must select the previous print job before polling the Wimp, and reselect your own job on return.

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.

Code skeleton

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:

Other calls for controlling a print job

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.

Trapping of output calls

Software vectors

When printing occurs, the printer driver intercepts software vectors through which pass calls that may output to the screen. These are:

  • ByteV
  • ColourV
  • DrawV
  • SpriteV
  • WrchV.

It treats the intercepted calls in different ways:

  1. It appropriately processes the call itself; typically this produces printed output, or alters the printer driver's own record of the graphic state for the current print job.
  2. It faults the call as one that is inappropriate to call in the context of a print job.
  3. It ignores the call as one that is irrelevant to the print job, and has no wider meaning to the rest of RISC OS.
  4. It passes the call on to RISC OS, as it is one that is relevant to other parts of the system.

A few calls are both processed by the printer driver and passed on to RISC OS.

Font manager SWIs

Furthermore, when printing starts the printer driver issues a service call which alters the font manager's SWI handling:

  • It processes certain SWIs itself, as normal.
  • It passes certain SWIs to the printer driver using an internal mechanism. The printer driver may then:
    1. process the call
    2. ignore the call.

      The font manager does not process such SWIs itself.

Guidelines on output calls to use

This section outlines which calls you should use for output to the printer drivers.

General advice

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.

Setting colours

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:

  • makes the printer driver output dependent on the current screen mode and palette
  • artificially limits the printer driver to the number of colours displayed on the screen, which can be particularly embarrassing if (say) a user were to try to print in colour whilst in a 2 colour mode.

We therefore recommend that you do not set colours with these other calls.

Graphic object output

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.

Painting fonts

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.

Sprite output

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.

Character output

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 output calls in detail

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.

ByteV

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

ColourV

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
ColourTrans_ReturnColourNumber
ColourTrans_ReturnColourNumberForMode with R1 = -1

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:

  • If the RGB combination is already known about, return the corresponding code value.
  • If the RGB combination is not already known about and some code values are still free, allocate one of the unused code values to the new RGB combination and return that code value.
  • If the RGB combination is not already known about and all code values have been allocated, return the code number whose RGB combination is as close as possible to the desired RGB combination.

The pre-allocation of evenly spaced RGB combinations will ensure that even the third case does not have really terrible results.

ColourTrans_ReturnOppColourNumber
ColourTrans_ReturnOppColourNumberForMode with R1 = -1

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.

ColourTrans_SelectTable with R2 = -1

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.

ColourTrans_SetFontColours

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.

ColourTrans_SetGCOL

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:

  • If gcol_action MOD 8 [NOT EQUAL] 0, subsequent plots and sprite plots will not do anything.
  • If gcol_action = 0, the RGB value in R0 is remembered by the printer driver and used for subsequent plots. Plotting is done by overwriting with the closest approximation to this RGB value that the printer can render. Subsequent sprite plotting will be done without using the sprite's mask.
  • If gcol_action = 8, subsequent plots will be treated the same as R4 = 0 above, except that sprite plots will be done using the sprite's mask, if any.
  • If gcol_action > 8, and gcol_action MOD 8 = 0, an unspecified solid colour will be used.

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.

ColourTrans_SetOppGCOL

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.

ColourTrans_SetTextColour
ColourTrans_SelectOppTextColour

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.

DrawV

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.

Floating point calls

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.

Treatment of Draw SWIs

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.

Draw_ProcessPath

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.

Draw_Fill

Printer drivers can deal with most common calls to this SWI. The restrictions are:

  • They cannot deal with fill styles that invoke the positive or negative winding number rules - ie those with bit 0 set.
  • They cannot deal with a fill style which asks for non-boundary exterior pixels to be plotted (ie bit 2 is set), except for the trivial case in which all of bits 2 - 5 are set (ie all pixels in the plane are to be plotted).
  • They cannot deal with the following values for bits 5 - 2:

      0010 - plot exterior boundary pixels only.
      0100 - plot interior boundary pixels only.
      1010 - plot exterior boundary and interior non-boundary pixels only.

  • An application should not rely on there being any difference between what is printed for the following three values of bits 5 - 2:

      1000 - plot interior non-boundary pixels only.
      1100 - plot all interior pixels.
      1110 - plot all interior pixels and exterior boundary pixels.

A printer driver will generally try its best to distinguish these, but it may not be possible.

Draw_Stroke

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:

  • Printer drivers cannot deal with a fill style with bits 3 - 2 equal to 01 - one that asks for pixels lying off the stroke to be plotted and those that lie on the stroke not to be.
  • Most printer drivers will not pay any attention to bit 31 of the fill style, which distinguishes plotting the stroke subpath by subpath from plotting it all at once.

If the specified thickness is non-zero, all the restrictions mentioned above for Draw_Fill also apply to this call. Further restrictions are:

  • Printer drivers cannot deal with bits 5 - 2 being 0110 - a call asking for just the boundary pixels of the resulting filled path to be plotted.
  • Most printer drivers will not pay any attention to bit 31 of the fill style, which distinguishes plotting the stroke subpath by subpath from plotting it all at once.

Font manager SWIs

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
Font_SetFontColours

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.

Font_Paint

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.

SpriteV

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.

Scale

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.

Colours

The colours used to plot sprite pixels are determined as follows:

  • If the call does not allow a pixel translation table, or if no translation table is supplied, the current screen palette is consulted to find out what RGB combination the sprite pixel's value corresponds to. The printer driver then does its best to produce that RGB combination.
  • If a translation table is supplied with the call, the printer driver assumes that the table contains code values allocated by ColourTrans_SelectTable with R2 = -1.
    It can therefore look up precisely which RGB combination is supposedto correspond to each sprite pixel value. Because of the variety of ways in which printer drivers can allocate these values, the translation table should alwyas have been set up in the current print job and using these calls.

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.

Treatment of SpriteOp reason codes

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
OS_SpriteOp 24

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.

WrchV

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.

Internal graphics state of printer driver

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:

  • VDU drivers are enabled.
  • VDU 5 state is set up.
  • All graphics cursor positions and the graphics origin have been set to (0,0) in the user's rectangle coordinate system.
  • A VDU 5 character size and spacing of 16 OS units by 32 OS units have been set in the user's rectangle coordinate system.
  • The graphics clipping region has been set to bound the actual area that is to be plotted, with a possible slight difference caused by rounding errors when converting the coordinates to OS units. However, an application cannot read what this area is; the printer drivers do not and cannot intercept OS_ReadVduVariables or OS_ReadModeVariable.
  • The area in which plotting will actually take place has been cleared to the background colour supplied in the corresponding PDriver_GiveRectangle call.
  • The cursor movement control bits (ie the ones that would be set by VDU 23,16,...) are set to &40 - so that cursor movement is normal, except that movements beyond the edge of the graphics window in VDU 5 mode do not generate special actions.
  • One OS unit has a nominal size on the paper of 1/180 inch, depending on the transformation supplied with this rectangle.
  • A pixel has a nominal size on the paper of 1/90 inch square (ie 2 OS units square); thus all PLOT line, PLOT point and PLOT outline calls produce lines that are approximately 1/90 inch wide.
  • No text coordinate system is defined.

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.

Rounding

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.

Treatment of character sequences

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)
VDU 18 and GCOLs

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:

  • As usual the background colour is affected if colour >= 128, and the foreground colour if colour < 128.
  • The gcol_action is treated in the same way as for ColourTrans_SetGCOL; see ColourTrans_SetGCOL.

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.

Miscellaneous SWIs

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:

OS_Word 10 used to read character and ECF definitions.
OS_Word 11 used to read palette definitions.
OS_ReadPalette used to read palette definitions.
OS_Byte 218 when used to read number of bytes in VDU queue.

Processor flags

Note that processor flags may have different values on exit from some calls when a printer driver is active to those that they would otherwise have.

Error handling changes

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.

Escape handling

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:

  • PDriver_SelectJob for a new job
  • PDriver_EndJob.

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:

  • PDriver_DrawPage
  • PDriver_GetRectangle
  • OS_WriteC and its derivatives - ie all SWIs that call WrchV
  • All ColourTrans SWIs - except ColourTrans_ColourNumberToGCOL, ColourTrans_GCOLToColourNumber, ColourTrans_InvalidateCache, ColourTrans_MiscOp, ColourTrans_SetOppTextColour and ColourTrans_SetTextColour.
  • Draw_Fill
  • Draw_Stroke
  • Font_SetFontColours
  • Font_SetPalette
  • Font_Paint
  • OS_SpriteOp with reason codes 28 (put sprite), 34 (put sprite at user coordinates), 48 (plot mask), 49 (plot mask at user coordinates), 50 (plot mask scaled) 52 (put sprite scaled), 53 (put sprite grey scaled), 55 (plot mask transformed), or 56 (put sprite transformed).
Persistent errors

Secondly, inside a number of calls, any error that occurs is converted into a 'persistent error'. The net effect of this is that:

  • The error number is left unchanged.
  • The error message has the string ' (print cancelled)' appended to it. If it is so long that this would cause it to exceed 255 characters, it is truncated to a suitable length and '... (print cancelled)' is appended to it.
  • Any subsequent call to any of the routines concerned will immediately return the same error.

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:

  • PDriver_EndJob
  • PDriver_GiveRectangle
  • PDriver_DrawPage
  • PDriver_GetRectangle

When the printer driver is intercepting plotting calls, the following SWIs also generate persistent errors:

  • OS_WriteC and its derivatives - ie all SWIs that call WrchV
  • All ColourTrans SWIs - except ColourTrans_ColourNumberToGCOL, ColourTrans_GCOLToColourNumber, ColourTrans_InvalidateCache, ColourTrans_MiscOp, ColourTrans_SetOppTextColour and ColourTrans_SetTextColour.
  • Draw_Fill
  • Draw_Stroke
  • Draw_ProcessPath with R7=1
  • Font_SetFontColours
  • Font_SetPalette
  • Font_Paint
  • OS_SpriteOp with reason codes 28 (put sprite), 34 (put sprite at user coordinates), 48 (plot mask), 49 (plot mask at user coordinates), 50 (plot mask scaled) 52 (put sprite scaled), 53 (put sprite grey scaled), 55 (plot mask transformed), or 56 (put sprite transformed)
PDriver_CancelJob

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.

Technical Details

The structure of the printing system

The Printers application

The Printers application is the user interface to the printing system. It is split into two parts.

The 'front end'

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 'back ends'

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

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

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

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

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 module's SWI handling

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 PDriver sharer module processes the SWIs PDriver_CurrentJob and PDriver_EnumerateJobs. These just require some inspection of its internal job management structures, and no interaction with the real drivers.
  • The PDriver sharer module needs the cooperation of the printer drivers to process the PDriver_SelectJob, PDriver_SelectIllustration, PDriver_AbortJob, PDriver_EndJob and PDriver_Reset job handling SWIs.

    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.

  • The PDriver sharer module does not process PDriver_CancelJob nor PDriver_CancelJobWithError. These simply set flags inside the real driver to stop future printer actions on the specified job from working - they do not affect the job management in the PDriver sharer module itself.
The printer drivers

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

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

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.

PDumperSupport

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.

Summary

The diagram below summarises the printing system in RISC OS 3 (version 3.10):


Structure of printing system in RISC OS 3 (version 3.10)

The RISC OS 2 printing system

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.)

Extending the printing 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.

Adding printer definition files

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.

Adding a printer dumper

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.

Adding a back end to the Printers application

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.

Adding a printer driver

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.

Adding a palette file and/or a new PDumperSupport module

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 driver numbers

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

Using PostScript fonts

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.

New-style applications

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:

  • Using an existing PostScript font directly
  • Augmenting an existing PostScript font by applying a different encoding and/or transformation matrix, and/or by adding extra characters such as composite accented characters.
  • Downloading an existing Type 1 PostScript version of the font on the fly.
  • Generating and downloading a Type 3 PostScript version of the font on the fly.

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.

Old-style applications

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.

Font names

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:

RISC OS name PostScript name
Churchill.Medium.Italic ZapfChancery-MediumItalic
Clare.Medium AvantGarde-Book
Clare.Medium.Oblique AvantGarde-BookOblique
Clare.Demi AvantGarde-Demi
Clare.Demi.Oblique AvantGarde-DemiOblique
Corpus.Medium Courier
Corpus.Medium.Oblique Courier-Oblique
Corpus.Bold Courier-Bold
Corpus.Bold.Oblique Courier-BoldOblique
Homerton.Medium Helvetica
Homerton.Medium.Oblique Helvetica-Oblique
Homerton.Bold Helvetica-Bold
Homerton.Bold.Oblique Helvetica-BoldOblique
NewHall.Medium NewCenturySchlbk-Roman
NewHall.Medium.Italic NewCenturySchlbk-Italic
NewHall.Bold NewCenturySchlbk-Bold
NewHall.Bold.Italic NewCenturySchlbk-BoldItalic
Pembroke.Medium Palatino-Roman
Pembroke.Medium.Italic Palatino-Italic
Pembroke.Bold Palatino-Bold
Pembroke.Bold.Italic Palatino-BoldItalic
Robinson.Light Bookman-Light
Robinson.Light.Italic Bookman-LightItalic
Robinson.Demi Bookman-Demi
Robinson.Demi.Italic Bookman-DemiItalic
Selwyn ZapfDingbats
Sidney Symbol
Trinity.Medium Times-Roman
Trinity.Medium.Italic Times-Italic
Trinity.Bold Times-Bold
Trinity.Bold.Italic Times-BoldItalic

You can use T1ToFont to convert AFM (Adobe Font Metrics) files into IntMetrics files, and hence ensure that the correct metrics are used.

Service Calls


Service_Print
(Service Call &41)

For internal use only

You must not use it in your own code.


Service_PDriverStarting
(Service Call &65)

PDriver sharer module started

On entry

R1 = &65 (reason code)

On exit

All registers preserved

Use

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).


Service_PDriverGetMessages
(Service Call &78)

Get common messages file

On entry

R1 = &78 (reason code)

On exit
Not claimed

R0 - R8 must be preserved

Call claimed

R1 = 0 (implies service claimed)
R3 = pointer to 20 byte block for open messages file

Use

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:

  • If the service call is claimed R3 will point to a 20 byte block. The first 16 bytes of this are a MessageTrans block referring to the file, and the remaining word is a usage count. The PDriver module should increment this usage count and use the MessageTrans block to access the file. When the module has finished using the file it should decrement the usage count, and if the count is <= 0 SHOULD THEN CALL MessageTrans_CloseFile followed by OS_Module 7 to free the 20 byte block.
  • If the service call is not claimed the PDriver module should instead allocate 20 bytes using OS_Module 6, and then use MessageTrans_OpenFile to open Resources:$.Resources.PDrivers.Messages, placing the MessageTrans block in the first 16 bytes of the claimed buffer, and setting the usage count in the last word to 1.

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.


Service_PDriverChanged
(Service Call &7F)

Currently selected printer driver has changed

On entry

R1 = &7F (reason code)
R2 = printer driver number of new driver (see Printer driver numbers)

On exit

All registers are preserved

Use

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.

SWI Calls


PDriver_Info
(SWI &80140)

Get information on the printer driver

On entry

--

On exit

R0 = version number and type:

bits 0 - 15 - printer driver's version number × 100
bits 16 - 31 - printer driver number (see Printer driver numbers)
R1 = x resolution of printer driven, in dots per inch
R2 = y resolution of printer driven, in dots per inch
R3 = features word: see below
R4 = pointer to printer name, null terminated, maximum 20 characters long
R5 = x halftone resolution in repeats/inch (same as R1 if no halftoning)
R6 = y halftone resolution in repeats/inch (same as R2 if no halftoning)
R7 = printer driver specific number identifying the configured printer (which is zero, unless it has been changed using PDriver_SetInfo)

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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:

Bit 0 Bit 1 Bit 2 Colours available
0 0 0 Arbitrary greys
0 0 1 A limited set of greys (probably only black and white)
0 1 0 Arbitrary greys
0 1 1 A limited set of greys (probably only black and white)
1 0 0 Arbitrary colours
1 0 1 A limited discrete set of colours, including all the eight primary colours
1 1 0 Arbitrary colours within a limited range (for example, it might be able to represent arbitrary greys, red, pinks and so on, but no blues or greens). This is not a very likely option
1 1 1 A finite set of colours - as for instance an XY plotter might have

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.

Related SWIs

PDriver_SetInfo, PDriver_CheckFeatures

Related vectors

None


PDriver_SetInfo
(SWI &80141)

Configure the printer driver

On entry

R1 = x resolution of printer driven, in dots per inch
R2 = y resolution of printer driven, in dots per inch
R3 = features word:

bit 0 set => colour, else monochrome
all other bits reserved (must be zero)
R4 = pointer to new printer name, null terminated, maximum 20 characters long
R5 = x halftone resolution in repeats/inch (same as R1 if no halftoning)
R6 = y halftone resolution in repeats/inch (same as R2 if no halftoning)
R7 = printer driver specific number identifying the configured printer

On exit

R1 - R7 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_Info

Related vectors

None


PDriver_CheckFeatures
(SWI &80142)

Check the features of a printer

On entry

R0 = mask of bits to check in features word
R1 = desired value of features word

On exit

R0, R1 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_Info

Related vectors

None


PDriver_PageSize
(SWI &80143)

Find how large the paper and print area is

On entry

--

On exit

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

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_SetPageSize

Related vectors

None


PDriver_SetPageSize
(SWI &80144)

Set how large the paper and print area is

On entry

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

On exit

R1 - R6 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_PageSize

Related vectors

None


PDriver_SelectJob
(SWI &80145)

Make a given print job the current one

On entry

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

On exit

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

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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:

  • A simple printer driver might ignore it.
  • The PostScript printer driver adds a line '%%Title:' followed by the given title string to the PostScript header it generates.
  • Printer drivers whose output is destined for an expensive central printer in a large organisation might use it when generating a cover sheet for the document.

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.

Related SWIs

PDriver_CurrentJob, PDriver_EndJob, PDriver_AbortJob, PDriver_Reset, PDriver_EnumerateJobs, PDriver_SelectIllustration

Related vectors

None


PDriver_CurrentJob
(SWI &80146)

Get the file handle of the current job

On entry

--

On exit

R0 = file handle for current job, or 0 if none

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_SelectJob, PDriver_EndJob, PDriver_AbortJob, PDriver_Reset, PDriver_EnumerateJobs, PDriver_SelectIllustration

Related vectors

None


PDriver_FontSWI
(SWI &80147)

This call is part of the internal interface between the font system and printer drivers. Applications must not call it.


PDriver_EndJob
(SWI &80148)

End a print job normally

On entry

R0 = file handle for print job to be ended

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_SelectJob, PDriver_CurrentJob, PDriver_AbortJob, PDriver_Reset, PDriver_CancelJob, PDriver_CancelJobWithError, PDriver_SelectIllustration

Related vectors

None


PDriver_AbortJob
(SWI &80149)

End a print job without any further output

On entry

R0 = file handle for print job to be aborted

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_SelectJob, PDriver_CurrentJob, PDriver_EndJob, PDriver_Reset, PDriver_CancelJob, PDriver_CancelJobWithError, PDriver_SelectIllustration

Related vectors

None


PDriver_Reset
(SWI &8014A)

Abort all print jobs

On entry

--

On exit

--

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_SelectJob, PDriver_CurrentJob,
PDriver_EndJob, PDriver_AbortJob, PDriver_SelectIllustration

Related vectors

None


PDriver_GiveRectangle
(SWI &8014B)

Specify a rectangle to be printed

On entry

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.

On exit

R0 - R4 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_DrawPage, PDriver_GetRectangle

Related vectors

None


PDriver_DrawPage
(SWI &8014C)

Called to draw the page after all rectangles specified

On entry

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

On exit

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 [NOT EQUAL] 0
R3 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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 [NOT EQUAL] 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.

Related SWIs

PDriver_GiveRectangle, PDriver_GetRectangle

Related vectors

None


PDriver_GetRectangle
(SWI &8014D)

Get the next print rectangle

On entry

R1 = pointer to 4 word block, to receive the rectangle to print (in OS units)

On exit

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 [NOT EQUAL] 0

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_GiveRectangle, PDriver_DrawPage

Related vectors

None


PDriver_CancelJob
(SWI &8014E)

Stops the print job associated with a file handle from printing

On entry

R0 = file handle for job to be cancelled

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_EndJob, PDriver_AbortJob, PDriver_CancelJobWithError

Related vectors

None


PDriver_ScreenDump
(SWI &8014F)

Output a screen dump to the printer

On entry

R0 = file handle of file to receive the dump

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

None

Related vectors

None


PDriver_EnumerateJobs
(SWI &80150)

List existing print jobs

On entry

R0 = zero to enumerate first print job, or handle returned from previous call

On exit

R0 = next print job handle, or zero if no more

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_CurrentJob

Related vectors

None


PDriver_SetPrinter
(SWI &80151)

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.


PDriver_CancelJobWithError
(SWI &80152)

Cancels a print job - future attempts to output to it generate an error

On entry

R0 = file handle for job to be cancelled
R1 = pointer to error block

On exit

R0, R1 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_EndJob, PDriver_AbortJob, PDriver_CancelJob

Related vectors

None


PDriver_SelectIllustration
(SWI &80153)

Makes the given print job the current one, and treats it as an illustration

On entry

R0 = file handle for print job to be selected, or 0 to deselect all jobs
R1 = pointer to title string for job, or 0

On exit

R0 = file handle for previously active print job, or 0 if none was active
R1 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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 print job started must contain exactly one page; if it doesn't, an error will be generated.
  • Depending on the printer driver involved, the output generated may differ. (For instance, the PostScript printer driver will generate Encapsulated PostScript output for a job started this way.)

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.

Related SWIs

PDriver_SelectJob, PDriver_CurrentJob, PDriver_EndJob, PDriver_AbortJob, PDriver_Reset, PDriver_CancelJob, PDriver_CancelJobWithError

Related vectors

None


PDriver_InsertIllustration
(SWI &80154)

Inserts a file containing an illustration into the current job's output

On entry

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

On exit

R0 - R7 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_SelectIllustration

Related vectors

None


PDriver_DeclareFont
(SWI &80155)

Declares the fonts that will be used in a document

On entry

R0 = handle of font to be declared, or zero
R1 = pointer to name of font to be declared, or zero
R2 = flags word:

bit 0 set => don't download font if not present within device
bit 1 set => when font is used kerning is applied all other bits reserved (must be zero)

On exit

R0 - R2 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

  • Setting bit 0 stops a non-resident font being downloaded, in which case it will be substituted with a resident font, usually Courier (although this is driver specific). An example of appropriate use of this facility would be to set up a draft print option, so the correct font is used unless it can only be obtained at the expense of a slow download.
  • Bit 1 is used to specify if kerning is applied to the font at any point in the job, so the PostScript printer driver knows whether or not it needs to download the font's kerning information.

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.

Related SWIs

None

Related vectors

None


PDriver_DeclareDriver
(SWI &80156)

Registers a printer driver with the PDriver sharer module

On entry

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

On exit

R0 - R2 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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:

On entry

R11 = reason code (SWI number - &80140)
R12 = pointer to private word
R14 = return address
Other register usage as documented for corresponding SWI

On exit

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.

Related SWIs

PDriver_RemoveDriver

Related vectors

None


PDriver_RemoveDriver
(SWI &80157)

Deregisters a printer driver with the PDriver sharer module

On entry

R0 = printer driver number (see Printer driver numbers)

On exit

R0 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_DeclareDriver

Related vectors

None


PDriver_SelectDriver
(SWI &80158)

Selects the specified driver

On entry

R0 = printer driver number (Printer driver numbers), or -1 to set no current active driver, or -2 to read current driver

On exit

R0 = previous driver number, or -1 if none

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_DeclareDriver, PDriver_RemoveDriver, PDriver_EnumerateDrivers

Related vectors

None


PDriver_EnumerateDrivers
(SWI &80159)

Enumerates all drivers within the system.

On entry

R0 = zero to enumerate first driver, or handle returned from previous call

On exit

R0 = handle to enumerate next driver, or zero if no more
R1 = printer driver number if R0 [NOT EQUAL] 0, or undefined if no more

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_SelectDriver

Related vectors

None


PDriver_MiscOp
(SWI &8015A)

Processes miscellaneous printer driver operations

On entry

R0 = reason code
Other registers are reason code dependent

On exit

Reason code dependent

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call processes miscellaneous printer driver operations. The action depends on the reason code passed in R0:

R0 Action Page
0 Adds a font name to a list of those known to the current printer PDriver_MiscOp 0
1 Removes font name(s) from a list of those known to the current printer PDriver_MiscOp 1
2 Enumerates the font name(s) in a list of those known to the current printer PDriver_MiscOp 2
&80000000 Registers a printer dumper with PDriverDP PDriver_MiscOp &80000000
&80000001 Deregisters a printer dumper with PDriverDP PDriver_MiscOp &80000001
&80000100 - &80000FFF An extension mechanism to provide direct control over a printer dumper PDriver_MiscOp &80000100 - &80000FFF

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.

Related SWIs

PDriver_MiscOpForDriver

Related vectors

None


PDriver_MiscOp 0
(SWI &8015A)

Adds a font name to a list of those known to the current printer

On entry

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:

bit 0 set => font is resident within device
bit 1 set => font to be downloaded at job start
bit 2 set => font has been downloaded
bits 3 - 31 reserved (must be zero)
R4 = flag word for font addition:
bit 0 set => overwrite existing entries
bits 1 - 31 reserved (must be zero)

On exit

R0 - R4 preserved

Use

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.


PDriver_MiscOp 1
(SWI &8015A)

Removes font name(s) from a list of those known to the current printer

On entry

R0 = 1 (reason code)
R1 = pointer to RISC OS font name (control-character terminated), or zero to delete all fonts

On exit

R0, R1 preserved

Use

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.


PDriver_MiscOp 2
(SWI &8015A)

Enumerates the font name(s) in a list of those known to the current printer

On entry

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:

all bits reserved (must be zero)

On exit

if R1 [NOT EQUAL] 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

Use

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).


PDriver_MiscOp &80000000
(SWI &8015A)

Registers a printer dumper with PDriverDP

On entry

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

On exit

R0 - R6 preserved

Use

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.


PDriver_MiscOp &80000001
(SWI &8015A)

Deregisters a printer dumper with PDriverDP

On entry

R0 = &80000001 (reason code)
R1 = number of printer dumper to deregister (see Printer dumper numbers and names)

On exit

R0, R1preserved

Use

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.


PDriver_MiscOp &80000100 - &80000FFF
(SWI &8015A)

An extension mechanism to provide direct control over a printer dumper

On entry

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

On exit

Reason code dependent

Use

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.


PDriver_MiscOpForDriver
(SWI &8015B)

Processes miscellaneous printer driver operations using a specified driver

On entry

R0 = reason code
R8 = number of printer driver to which to pass call
Other registers are reason code dependent

On exit

Reason code dependent

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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.

Related SWIs

PDriver_MiscOp

Related vectors

None


PDriver_SetDriver
(SWI &8015C)

Configures the current printer driver

PrinterDM version

Sets the current printer dumper, if PrinterDM is the current printer driver

On entry

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

On exit

R1 - R5 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

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 call is not available under RISC OS 2.

PDriverPS version

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.

Related SWIs

None

Related vectors

None

Example program

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

Notes

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%)

  • checks the printer driver's features bit and, if necessary, declares the fonts in the structure pointed to by fontptr%.

DEFPROCgetdocumentsize(box%)

  • fills the area pointed to by box% with the size of a document page in OS units.

DEFPROCfittwopages(l%, b%, r%, t%, box%, transform%, org1%, org2%)

  • given left, bottom, right and top bounds of a piece of paper, and a bounding box of a document page in OS units, sets up a transformation and two origins in the areas pointed to by tr%, org1% and org2% to print two of those pages on a piece of paper.

DEFPROCdrawpage(page%, box%)

  • draws the parts of document page number 'page%' that lie with the box held in the 4 word area pointed to by '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.

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015