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 6.2.6). 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
setpagedeviceas a job starts up,BeginPagemay be invoked several times before anyEndPageforshowpageis executed (though there are device deactivation calls ofEndPage, theEndPageoperand is2in these circumstances). - It is possible, but rare, for a job to execute
setpagedevicein the middle. If this happens, device deactivation occurs (as described in [RB3]). If it is necessary to determine whether a particular invocation ofEndPageis 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 therestorewithin 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
EndPagewhich indicates whether the page should be rendered or not, especially when you have definedEndPagefor 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 defaultEndPageprocedure 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
BeginPageandEndPageas described in Augmenting Procedure Hooks. However, you must take care doing this. In general, you need to know what the olderBeginPageis 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? ForEndPage, the older version needs copies of the operands, and you need to resolve conflicting results for the resultant boolean. - You cannot simply execute
setscreeninsideBeginPageto set up a different screen for each page. This is because a common job structure is like this:
... 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:
... 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.