[gs-devel] Re: beginpage and the vector device

Ken Sharp ken.sharp at artifex.com
Fri Nov 2 02:06:02 PDT 2007

Hi Ralph,

At 23:22 01/11/2007 -0700, Ralph Giles wrote:

>Sorry this is a bit long, but I wanted to check with you

I'm hoping Lenoardo will be in on this too, I haven't had any exposure to 
the area you're discussing here yet, so I'm going to be guessing a bit...

>As it turns out, the way gx_device_vector decides when to call
>beginpage is by testing vdev->in_page INSIDE AN ACCESSOR for
>the output stream. So, the subclass is expected to call
>gdev_vector_stream() whenever it wants to write EXCEPT from
>inside the beginpage method, where it must access the stream
>directly. The subclass is also expected to set in_page back to
>false after finishing a page if it wants its beginpage method
>called again. Essentially the same hack I was doing, but half
>a level up. And gdevpx.c does all this in implementing the
>pxl output device. Whacky.
>I think someone was just trying to save some code by blurring a
>boundary, which is unfortunately common in Ghostscript, and I'd
>like to fix it. Do you have any thoughts before I try and rework

Not many, it does sound like it was reuse of existing code, you may be 
right there. Rather than redesign something, it looks like a shortcut was 


I can see some reasoning behind this. If the file header needs to have some 
information which is culled from the job, and which can change several 
times before drawing begins, you want to defer writing the header until the 
actual start of the drawing operations (DSC comments spring to mind here) 
so that you can write the correct information.

To do this you either need to put the 'start of a page?' test somewhere 
nice and central, guaranteed to be called at every important point, or you 
need every operation which writes to the stream to do the test instead.

This doesn't impose a performance penalty, because the test needs to be 
done the same number of times, but it does increase the code size, and 
impose a coding burden. The developer really *must* be sure to add this 
test to every routine which writes to the output stream. Its clearly 
simpler and safer to have the code perform the test in one central location.

By having the test done whenever the output stream is written, there is no 
possible way to miss identifying the start of the page.

>  Is there a general page_begin event that I've missed?

Not that I know of, but as yet all my poking has been inside the pdfwrite 
code, I haven't so far had to look into how to get there...

As noted above, it may depend on just what you define as the 'beginning' of 
a page. It seems to me that the method here is in effect defining the 
beginning of the page as the first time data is written to the output 
stream. I think this definition is useful for high-level output, although 
probably irrelevant to low-level (raster) output.

So a particular definition of 'page begin' event may only be useful to a 
particular set of devices. While almost anything is probably good enough 
for low level devices, high level devices would probably have to implement 
their own methods for deferring output until enough information has been 
assembled, and do their own page checking.

Does the above make any sense ?

>not I guess we just have to make all the gdevvec.c routines check
>in_page themselves. More code, but less surprise.

Perhaps it would be better to improve the API documentation ?

I agree that this kind of surprise is not ideal, but perhaps this is a 
point where engineering takes over from science. Its theoretically better 
to design a system where this sort of hack isn't required, but from a 
practical point of view it may be better to live with it, but at least make 
sure its clearly labelled.

I'm afraid I have to go and load my laptop with stuff for next week's 
meetings now, and do some other maintenance tasks. Also I have an early 
start in the morning. If you'd like to discuss it further maybe we could 
talk about it face to face next week ? (and post a summary to gs-devel) 
Probably other people like Leonardo and Henry will have useful input too.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TASK: Shoot yourself in the foot.
You can use this machine-gun to shoot yourself in the foot, but the firing pin is broken. 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

More information about the gs-devel mailing list