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
>this?
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
taken.
But....
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 ?
>If
>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.
Ken
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TASK: Shoot yourself in the foot.
Hewlett-Packard
You can use this machine-gun to shoot yourself in the foot, but the firing pin is broken.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -