The RISC OS Printing System (part 8)

Colour separation

Many modern DTP and drawing applications have the facility to print colour separations for sending to printing bureaux, but it would be nice to be able to produce colour separations from our old faithful applications such as Draw etc. This means modifying the printing system so that only C, M, Y or K information is sent to the printer. Another use is to produce full colour documents usi g black and white printers (if you can get hold of colour cartridges/ribbons). Rather than every application having to include colour separation routines, surely it is neater for the printing sy tem to produce them?

Let me state from the start; this utility is not a full colour separation add-on to !Printers - that would require a complete re-write of !Printers. (RISCOS Ltd, could you please include it in t e next version?) My utility will only produce colour separations from applications which contain only 256 colour (or less) sprite images, no JPEGs or 32K and 16M colour sprites. This may seem quite a disadvantage, but as the example drawfile (on this month's disc?) shows, a 256-colour sprite with an optimum palette can produce a high quality image. All other colour graphic and font commands will roduce separations.

Possible solutions...

As I have said, one way would be to re-write the PDriverDP and PDriverPS modules. The PDriverDP module produces a bitmap output in sprite format so this could be altered. However, this  doesn't allow for PostScript printing (the very method printing bureaux use). Re-writing these modules would be quite a task! Another way is to intercept all the ColourTrans SWIs that the printing sy tem processes. These are:

SWI"ColourTrans_GenerateTable"(only processed if R2=-1)
SWI"ColourTrans_SelectTable" (only processed if R2=-1)
SWI"ColourTrans_SetFontColours"
SWI"ColourTrans_SetGCOL"
SWI"ColourTrans_SetOppGCOL"
SWI"ColourTrans_ReturnColourNumber"
SWI"ColourTrans_ReturnColourNumber-ForMode" (only processed if R1=-1)
SWI"ColourTrans_ReturnOppColour-Number"
SWI"ColourTrans_ReturnOppColour-NumberForMode" (only processed if R1=-1)

Apart from the first two, all of them use a standard palette entry word &BBGGRR00 (B=Blue, R=Red and G=Green) which could be easily altered before calling the main SWI routine. SWIs Generate and Select Table use a pointer to a set of BGR palette entries (see later).

Producing colour separations

Most colour printing is based on a four-colour model. The four colours used are Cyan (light blue), Magenta (purple), Yellow and Key (black). Some professional printing uses more than four layers, spl tting each of the above colours, e.g. Light Cyan, Cyan etc. For our purposes, we will just use the four standard layers. Taking a standard palette entry BBGGRR00, we must produce a new palette entry n the same format but only containing the required value for either C, M, Y or K components.

Example

Let's look at pure red 0000FF00. How much cyan is needed? Not easy, but there are two useful ColourTrans SWIs which will do the work for us:

SWI"ColourTrans_ConvertRGBToCMYK"

The input registers are:

R0 RED
R1 GREEN
R2 BLUE

and the output components returned are:

R0 CYAN
R1 MAGENTA
R2 YELLOW
R3 KEY (usually black)

Then to do the opposite

SWI"ColourTrans_ConvertCMYKToRGB"

Both of these SWIs use values that are 32 bits wide with a value 0 to 1, 16 bits above the fixed point and 16 bits below.

So, the pseudo-code for cyan separation is

Read BBGGRR00 palette value.
Mask out each colour component and change it to a value of range 0 to 1.
Place them into the required registers.
Call SWI"ColourTrans_ConvertRGB-ToCMYK".
Make M and Y values zero (only need C) and copy the C value into K then make C zero.
Call SWI"ColourTrans_ConvertCMYK-ToRGB".
Build up the palette entry from RGB registers.
For the other colour separations, just alter the fifth step as required.

I have included a short Basic routine, just for interest, with which the user can input a palette value and select a colour separation. The new value of the palette is then displayed. There is o e slight complication which occurs when the red, green and blue components are produced by SWI"ColourTrans_ConvertCMYKToRGB". They could have the value &010000 (1 in the fixed point format) when e require &00FF00. Just checking this and subtracting 1 from their values if required overcomes this overflow.

Problems

As in most programming, the solution turns out to be not so simple! The PDriverDP and PDriverPS modules don't simply claim vectors at the start of a printing routine and release them at the end ut claim and release each time the printing loop is repeated. So if we just claim the required vectors, then start to print, our routine won't be the first to be run. In fact, if the printer dri er intercepts the vector, our routine will never run! This was confirmed by claiming the colour vector and letting the colour separation occur when an application was redrawing its window on scr en This worked; the required separations were displayed in the window but, when printing, full colour was output!

Back to PDriverDP etc

This means the PDriverDP and PDriverPS modules would have to be modified! However, there is light at the end of the tunnel. Vectors are claimed by giving a re-directing address so, if we&nb p;remember the driver's re-directing address, replace this address so as to re-direct to our colour separation routine, then finally branch back to the original driver address, our routine will alway be run before the printer drivers. It is a simple matter to look where the vector claims and releases are situated in the two driver modules. The vector routine which needs to be modified is ColourV (ColourTrans SWIs). Finally, a * command is required to select the colour separations.

Different versions

There have been several different versions of the !Printers application. Version 1.24 was one of the early ones followed by 1.53 which many people still use. Then 1.54 was released with RISC&nbs ;OS 3.7 (it was just 1.53 in ROM). The next major re-write was 1.62 with RISC OS 4. Finally, there's 1.64, recently released, which works with RISC OS 3.1 through to the latest version of R SC OS 4. Although I've been told that certain applications don't give exactly the same printed results using version 1.64, perhaps a table of non-compatibility could be produced. However, the PD iverDP and PS modules have also been re-coded, so the vector claim positions for each of the above versions had to be noted. Once this was done, the colour separation add-on worked with all of t e above versions of !Printers. When newer versions are produced, extra positions will be needed, but these could be easily added.

How it works

The set of ColourTrans SWIs take care of most of the colour rendering, including font colours. We only need to modify the previously mentioned SWIs. The only SWIs that need extra explanatio are ColourTrans_SelectTable and ColourTrans_ GenerateTable. These two are equivalent and are processed by printers when register 2 is -1. For those who haven't dabbled in the intricacies of sprite p otting, these SWIs produce a colour translation table from a sprites palette or, if the sprite has no palette, the default palette for the sprite's mode, so that a sprite will be displayed correctly n any colour mode.

One feature, added under RISC OS 3.1, allows a user routine to modify each palette entry before it is used for the table generation. This is exactly what is required for colour separat on. Each time these SWIs are used in a printing loop, the colour separation routine modifies the call so that each palette entry is subject to the colour separation routine before it is used to produ e the translation table. Therefore, the sprite is displayed as if it had only the required separation colour in its palette. All the other ColourTrans SWIs work on a single palette entry, which is mo ified before calling the main SWI routine.

Special cases

1) ColourTrans_GenerateTable didn't work reliably with the PostScript driver when intercepted as described. So I have found the address in both drivers where it is called. A branch to the colour separation routine is placed there, branching back to the next command after the call in the drivers.

2) Colour separation on font printing works fine with the PDriverDP by the interception of ColourTrans_SetFontColours, but doesn't work with PDriverPS since it doesn't seem to need this cal !? So a separate module is used which sends all PostScript printing to a file. The file is then scanned for all font usage, and the colour commands are changed. The file is then sent to the nbsp;required destination (printer or original file output).

The front-end

I don't like permanently altering vital modules, so the following procedure is used for modifying the PDriverDP and PS printer modules. A Basic control program called !ColSep is used to sta t up !Printers. This means the required driver module(s) will be in memory (RMA). The program saves the module(s), assembles the patches required and then re-runs each module. Using this method, if anything goes wrong, the printer system hasn't been trashed. The control program now places an icon on the iconbar and becomes a standard WIMP program which is used to send user selected colour se aration commands to the modified driver modules.

A disadvantage to using this method is that !Printers forgets its selected printer so !Colsep searches through all the icons on the iconbar to find the selected printer icon, then sends a mouse click to this icon, hence re-selecting the correct printer. If !Printers is already running when !Colsep is run, !Colsep quits and re-runs !Printers.

User instructions

Now for the boring bit, but I do recommend you take note of the following. !Colsep requires RISC OS 3.1 onwards. It should work with all versions of !Printers from version 1.24 onwards It won't work with Turbo Printer drivers, but since these have colour separation already...

  1. Before running !ColSep, make sure your computer has 'seen' !Printers. (Place !Printers on the pinboard?)
  2. When !Colsep has started, you should see your usual printer icons together with the Colsep icon on the iconbar.
  3. Repeated clicking on the Colsep icon rotates through the various colour separations. Note all the already installed printers that use PDriverDP or PDriverPS will colour separate. These include al PostScript (make sure the colour is switched on in the configuration window) inkjet and dot matrix. Only have one PostScript printer installed. Install it before starting up !Printers v a !Colsep. Do not change its connection settings while using !Colsep.
  4. Quitting either !Printers or !Colsep will quit the whole printing and colour separation. This is done to stop any problems with the modified modules being modified twice etc!
  5. If you are going to use a monochrome printer to produce a full colour picture then the colours should be printed in the following order: yellow, cyan, magenta and finally key (black). The qu lity of the finished printout will be limited by how accurately your printer handles the paper. I have seen quite good results, many years ago!

The application has been tested with RISC OS 3.1 and 3.7 and using !Printers 1.24, 1.53, 1.54, 1.62 and 1.64. Well it's been quite a long discourse this month but hopefully, if not riveting, use ul for all you budding publishers! The simple example and full blown !Colsep can be found on this month's disc, together with a test draw page.


Source: Archive Magazine 13.11
Publication: Archive Magazine
Contributor: Brian Pickard