Created Date: 16 Mar, 2022 15:14
Last Modifed Date: 16 Mar, 2022 15:14

This page applies to Harlequin v13.1r0 and later; both Harlequin Core and Harlequin MultiRIP.

This is a simple example to add a set of registration marks and a grayscale around the sheet. For simplicity, the example omits the code to impose multiple pages on the sheet.


Adding registration marks and a grayscale

This PostScript language fragment needs to be run sometime in advance of the job. In the GUI version of the RIP this could be done in a page feature, or a custom separation feature, or tacked onto the front of a job by an input plugin (version 3.3 only). In the command-line version, it could be a config file, or concatenated with the job in a pipe. In the core-RIP version there are many possible ways of incorporating the job configuration, mostly using the %config% device. All versions can also use the concept of a montage (see Imposition) and set the configuration in the montage control job.

The use of SensePageDevice and BeginPage is explained further in Configuring the page device.

First, some procedures to actually draw the graphic elements follow. This is in the standard Level 2 PostScript language. It uses the sheet size and margin size to calculate where each element is placed, and therefore assumes that SepDict is on the dictionary stack.

            SepDict begin
                /regmark { % centered at 0,0 Margin 2 div dup scale
                .3 0 moveto 0 0 .3 0 360 arc
                0 .5 moveto 0 -1 rlineto .5 0 moveto -1 0 rlineto stroke
              } bind def
              /grayscale {
                % This uses the dictionary form of the image operator, with
                % 9 pixels scaled greatly to produce the gray ramp (the
                % multiple operand version of image implies DeviceGray
                % color space, but we want to draw in a spot color).
                10 dict begin
                  /ImageType 1 def
                  /Width 9 def /Height 1 def
                  /Decode [0 1] def
                  [Width 0 0 Height Width 2 div Height 2 div neg] def
                  /BitsPerComponent 8 def
                /DataSource <0020406080A0C0E0FF> def currentdict end image
              } bind def
              /position-and-draw-features {
                % four register marks near the corners gsave
                0.5 Margin div setlinewidth % 1/4 point hairlines gsave
                Width Margin 3 div sub Margin 2 mul translate regmark
                grestore gsave
                Width Margin 3 div sub
                Height Margin 2 mul sub translate regmark
                grestore gsave
                Margin 3 div Height Margin 2 mul sub translate regmark
                grestore gsave
                Margin 3 div Margin 2 mul translate regmark
                grestore grestore
                % center grayscale along the bottom margin gsave
                Width 2 div Margin 2 div translate
                Width 2 div Margin 2 mul sub Margin 3 div scale grayscale
            } bind def end % SepDict

Then set up comment parsing to capture bounding boxes (not illustrated here), determine the sheet sizes etc. and the page device SensePageDevice procedure to capture requested page sizes.

            userdict /SepDict 32 dict put
            SepDict begin % for temporary variables
              % Work out the separation sizes. Leave a border
              % of 50 points for crop marks etc.
              /Margin 50 def
              statusdict /mediasize get exec % width height
              % A media size of 0 means unrestricted, so use page size instead. dup 0 eq { pop currentpagedevice /PageSize get 1 get } if
              /Height exch def
              dup 0 eq { pop currentpagedevice /PageSize get 0 get } if
              /Width exch def
              % Default the page size. This just subtracts the margins, but an n-up
              % imposition would have a more complicated calculation here.
              /PageWidth Width Margin dup add sub def
              /PageHeight Height Margin dup add sub def
              << % setpagedevice dictionary starts here
                /SensePageDevice [
                  % Concatenate to previous if needed. currentpagedevice /SensePageDevice get /exec load
                  1 index null eq { pop pop } if
                  % Only allow our fixed page size, but catch what was requested
                  % in order to clip to this area later.
                    //SepDict begin
                      currentpagedevice /PageSize get aload pop
                      2 copy Height ne exch Width ne and {
                        /PageHeight exch def
                        /PageWidth exch def
                        /PageSize [Width Height]
                    } {pop pop} ifelse end
                  } bind /exec load
                ] cvx
            >> setpagedevice end % SepDict

Then comes a slightly different Install procedure, which adds a single background separation:

              /Install [
                currentpagedevice /Install get /exec load
                  1183615869 internaldict /addtoseparationcolornames get exec [ /Cyan /Magenta /Yellow /Black ]
                    /BackgroundDecoration <<
                      /Frame 4 -1 roll
                      /Background true
                    >> 1183615869 internaldict /addtoseparationorder get exec
                  } forall
                } bind /exec load
              ] cvx

The BeginPage procedure actually draws the background marks when it is called:

            /BeginPage {
                pop % the page count
                //SepDict begin
                  % draw the background save
                    true setoverprint
                    [ /Separation /BackgroundDecoration /DeviceGray {} ] setcolorspace
                    1 setcolor
                  position-and-draw-features restore
                  % position the real job (real n-up would be more complicated) Margin Margin translate
                0 0 PageWidth PageHeight rectclip end
              } bind
              /Imposition true % to allow the translation in BeginPage to behave
                              % correctly see  "Imposition"
            >> setpagedevice