I'm a bit confused with the graphics state and devices.
PLRM page 679:
If valid for the current page device, these requested values are merged by setpagedevice into the current page device dictionary. The interpretation of these parameters is described in Section 6.2, “Page Device Parameters.”
If I read this I understand that the graphics state maintains a Current Page Device Dictionary. It seems to also hold a "current page device"
I assume the dictionary is the one you can modify and the current page device is a readonly "object" with defaults from the device?
By reading the manual you know that there is more than one device:
but the graphicsstate seems to only care about pagedevices. Is this correct? Where are the cachedevice and nulldevice stored when set?
If I try IdePS then I see ghostscript only has a currentpagedevice in state dict. When executing "nulldevice" the currentpagedevice is still there.
What about this "current page device" (not the dictionary) is this also stored in the graphicstate?
The current page device is the one that makes marks on the media, in Ghostscript the -sDEVICE
parameter is the initial page device.
However there can be many other devices, the most obvious being the nulldevice
, which is simply a bit bucket. If you execute nulldevice
then that will replace the current page device in the graphics state with the null device. Obviously you normally do this inside a gsave
/grestore
pair, so that you can grestore
back to the original device!
Similarly, while rendering a glyph to the cache, its normal to push the cache device and make it the current page device. Again this is done in an implicit save/restore so that you can go back to the normal page device. This is so that you can get the bitmap representing the glyph rendered, in order to cache it.
These are called page devices to distinguish them from other devices, such as I/O devices.
Each page device has a page device dictionary (it may be empty) which contains keys and values. You can retrieve the current settings of the device, as a dictionary, by executing currentpagedevice
. You can modify the behaviour of the device by creating a dictionary with key/value pairs, and sending the request to the device using setpagedevice
. Note that the device may ignore the request, and if it does not, it will reset the current page.
So I would expect :
currentpagedevice {exch == ==} forall
nulldevice
currentpagedevice {exch == ==} forall
to give different results.
NOTE The page device dictionary is not maintained as part of the graphics state, it is maintained by the device.
What is in the graphics state is the device itself, and that's generally an opaque object of some kind that you can't do anything with.
I'm not sure what you mean by : "If I try IdePS then I see ghostscript only has a currentpagedevice in state dict. When executing "nulldevice" the currentpagedevice is still there."
currentpagdevice
is an operator which returns the page device dictionary belonging to the current page device. So you can't have "a currentpagedevice in state dict". currentpagedevice
is always there, because its an operator.
If I run the code above, I see that the original page device has a dictionary with many entries, but that the null device has an empty page device dictionary.
[edit]
Well, its true that its a dictionary in Ghostscript, but that's (at least partly) because of the weird way Ghostscript implements setpagedevice. FWIW Distiller also implements it as a dictionary, but I know at least one interpreter which does not, it creates a new dictionary from the entries maintained in a C structure, and returns that when currentpagedevice is executed. I was under the impression this was a PostScript question, not a specific Ghostscript question.... :-)
If you implement it as a dictionary, then you have to make sure that the dictionary maintained by the device is synchronised with the dictionary in the graphics state, or whatever other means you use to return the dictionary from currentpagedevice. Of course, these can be the same dictionary, which means its not a problem.
I'm not sure how your program there is working, the graphics state is an opaque object, it can't be interrogating it. My guess is that the program is maintaining its own record of the 'state'. That record is nothing to do with the internal state of the interpreter. I can tell you for a fact that what you see listed under 'state' is not even close to the contents of the graphics state maintained internally by Ghostscript.
I'd suggest that the IdePS program is (behind the scenes) simply executing a currentpagedevice and reading the dictionary contents. Notice that on the left the dictionary has contents, on the right its empty.
I don't think the 'state' refers to any particular implementation in the interpreter, its just the program tracking stuff itself.