create new tag
view all tags

Resolution Independent Clist

The what now?

The current clist is device-dependent; most particularly, it is resolution dependent, but also bakes in other things like colorspace etc. As such we can't interpret the page once, and then rerender it multiple times unless we just want exact carbon copies of it.

This has been identified as something that we'd like Ghostscript to be able to do?

We should probably refer to this as the "High level clist" or "Device independent clist", as that better captures what we need from it.


Well, the simplest example is panning and zooming within viewers.

The Display device currently has a mode where it can rerender different regions of a page repeatedly. For this, it uses a clist. It is limited to not being able to change the zoom, however. For that, we'd need resolution independence.

Also, previews - some printers might want to display a 'preview' of a page on a screen before printing it. This would require colorspace independence.

While it can be accomplished with the current clist, rendering a large page using 'tiles' is sometimes of value.

[Any other examples gratefully received.]

Discussion on this subject

A lot of the ideas on this page spring from a discussion on #artifex. Logs can be found here: https://ghostscript.com/privateirclogs/2020/09/07.html starting at 13:52:02. I've attempted to distill the ideas expressed here. Any mistakes are my own, etc.

How to implement this?

My initial thought was that there were several ways to go about coding this:

  1. Implement a new displaylist device.
  2. Work in the same way as the current clist.
  3. Reimplement something akin to the clist using subclassing.

1 Implement a new displaylist device

This is akin to the way MuPDF works; there we create the device, run to it, and we are left with a display list object. We can then run that display list object back to a different device to get the output we actually want.

So this wouldn't be the exact "1 shot" device that gs has always offered before, but a new style of working. (RJ: The current clist is not really "1-shot" since it has a clist writing phase, then the clist is rendered -- IMHO having a default mode that externally looks the same as now is fine)

2 Work in the same way as the current clist

The existing clist works by being baked into every device that uses it. Every device that can work using a clist is derived from a clist_mutatable_device 'class' (i.e. every clist device has the clist nature hidden away inside it from the start). (RJ: The kloodge of having the device 'mutate' from page mode to clist mode would be a good thing to get rid of).

This could either be done by modifying the existing clist code to have both 'device dependent' and 'device independent' modes, or by writing a new device from scratch to operate in the same kind of way.

3 Reimplement something akin to the clist using subclassing

Subclassing is relatively new, and wasn't around during the development of the clist, hence might present a neater way of working than the clists technique of replacing the innards of the chicken wholesale with a different one and hoping that the chicken doesn't notice.

But all of these ideas fall down...

But where all these fall down, is that the 'device interface' is not really the 'graphics library interface'. While in MuPDF the 'graphics library interface' and the 'device interface' are the same thing by design, in Ghostscript they are very different beasts. While the 'graphics library interface' is device independent, the 'device interface' is, by its very nature not. So we can't actually implement a device-independent anything as a device.

And in falling down leads us to a better solution.

If you visualise the structure of the complete system as being broadly "interpreter graphics library device" (as is made much plainer in gpdl), what we are really asking for is the ability to record the 'output' from an interpreter, and then to play it back later on. This would be exactly equivalent to MuPDFs display list.

To implement this within Ghostscript, we really need 2 things.

Firstly, that all interpreters should call into Ghostscript using the graphics library interface, and not 'short-circuit' it by calling the device interface.

Secondly, we need to vectorise the graphics library interface so it can be serialised and then played back.

The second stage should be a simple matter of programming. The first stage, however, has potential to be trickier for at least 2 reasons. a) Some interpreters call "device specific operations" - this will need rethinking, and b) the graphics library can call back into the interpreter to handle various things (the first example that springs to mind is color/colorspace setting within PS, but I think there are others, including fonts etc [RJ: also Images, and some Functions implemented as PS procedures]).

Such callbacks have potential to limit exactly how truly 'device independent' the mechanism can be, but, nonetheless, this feels like the best way forward I can see.

-- Robin Watts - 2021-01-01


Edit | Attach | Watch | Print version | History: r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r2 - 2021-01-07 - RayJohnston
This site is powered by the TWiki collaboration platform Powered by PerlCopyright 2014 Artifex Software Inc