(v13) 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 [RB2], 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 (v13) The Imposition page device key.
eHVD does not handle StartPage/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 anyEndPage
forshowpage
is executed (though there are device deactivation calls ofEndPage
, theEndPage
operand is2
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 [RB2]). If it is necessary to determine whether a particular invocation ofEndPage
is truly the end of a job or not, you can use the following RIP-specific code fragment. This checks whether the file from which the job has been executing is closed; it always has been if it is therestore
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 definedEndPage
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 defaultEndPage
procedure is:
{ exch pop 2 ne }
(Recall from [RB2] 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
andEndPage
as described at the beginning of (v13) Hooks. However, you must take care doing this. In general, you need to know what the olderBeginPage
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? ForEndPage
, the older version needs copies of the operands, and you need to resolve conflicting results for the resultant boolean. - You cannot simply execute
setscreen
insideBeginPage
to 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. It is impossible to solve the problem using the OverrideSpotFunction
and/or OverrideScreenAngle
system parameters, because these only take effect at an explicit setscreen
, setcolorscreen,
or sethalftone
, not at the implicit setscreen
or whatever that is caused by a grestore
when the screen has changed.
Currently, there are only two ways to change screens explicitly on each page:
- By a combination of
setscreen
inBeginPage
and redefinition ofgrestore
,setgstate
andrestore
. - By changing separation names (see (v13) Parameter reference summary). Changing the system parameter
/Separation
has the side effect of invalidating all screens in all graphics states, causing them to be regenerated automatically onrestore
orgrestore
. The following code executed insideBeginPage
has the desired effect where this behavior is supported:
... setscreen
save % so we explicitly recover memory consumed by
% the dictionary, and especially currentsystemparams
<<
/Separation currentsystemparams /Separation get
/OverrideAngle 22.5
/Password 0
>> setsystemparams restore