Skip to main content
Skip table of contents

BeginPage and EndPage procedures


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

BeginPage and EndPage are standard PostScript Level 2 page device hooks: see [RB3], section 4.11). However, when the Imposition page device key (a RIP extension) is true, BeginPage has the side effect of setting up a transformation for the page which it applies to, according to any changes made to the current transformation matrix while BeginPage is being executed. This mechanism is described in detail under The Imposition page device key.

eHVD does not handle BeginPage/EndPage hooks, especially those generating marks.

iHVD works fine with marks added in EndPage (for example, when using HqnImpose2).

Some points to note about BeginPage and EndPage:

  • Because there may be multiple calls to setpagedevice as a job starts up, BeginPage may be invoked several times before any EndPage for showpage is executed (though there are device deactivation calls of EndPage, the EndPage operand is 2 in these circumstances).
  • It is possible, but rare, for a job to execute setpagedevice in the middle. If this happens, device deactivation occurs (as described in [RB3]). If it is necessary to determine whether a particular invocation of EndPage is truly the end of a job or not, you can use the following Harlequin-specific code fragment. This checks whether the file from which the job has been executing is closed; it always has been if it is the restore within the server loop that is causing the device deactivation:

serverdict /stdin get status

The boolean on the operand stack is then false at the end of a job and true at other device deactivations.

  • It is easy to forget to return the boolean parameter of EndPage which indicates whether the page should be rendered or not, especially when you have defined EndPage for some reason that has nothing to do with that decision. Usually you do not want the page to be output at device deactivation. (If you are imposing pages, however, usually you want to flush partially filled media at this time.) This is why the default EndPage procedure is:

{ exch pop 2 ne }

(Recall from [RB3] that 2 is a special argument to Endpage indicating that device deactivation is happening.) Forgetting to return the boolean usually manifests itself as a typecheck error in setpagedevice. (The exact behavior depends on what the EndPage procedure actually does instead.)

  • It is wise to concatenate old and new versions of BeginPage and EndPage as described at the beginning of Hooks. However, you must take care doing this. In general, you need to know what the older BeginPage is doing, because the new one may interact with it in unpredictable ways. For example, consider an imposition in conjunction with an underlay; should the underlay extend across all the imposed pages, or should there be one on each imposed page? For EndPage, the older version needs copies of the operands, and you need to resolve conflicting results for the resultant boolean.
  • You cannot simply execute setscreen inside BeginPage to set up a different screen for each page. This is because a common job structure is like this:
TEXT
... setpagedevice
% implicit call to BeginPage here
save
  ... do some graphics ...
  showpage
  % implicit call to BeginPage here
restore
save
  ... do some more graphics ...
  showpage
  % implicit call to BeginPage here
restore

Sometimes a job wants to retain its graphics state across a showpage, so it does this:

TEXT
... setpagedevice
% implicit call to BeginPage here
... do some graphics ...
gsave
  showpage
  % implicit call to BeginPage here
grestore
... do some more graphics ...
gsave
  showpage
  % implicit call to BeginPage here
grestore

In either case, BeginPage is called where indicated and any call to setscreen inside it is then invalidated shortly afterwards by the restore or grestore restoring the previous screen. This is essentially the same problem for screens as the Imposition extensions solve for transformation matrices. This problem is solved using the OverrideSpotFunctionName system parameter, see Override screening system parameters.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.