Search code examples
postscript

Where are PostScript procedure sets and resources stored?


PostScript contains Procedure Sets (ProcSets). A procedure set is a dictionary that contains named procedures and operators.

These procedure sets are organized in categories. Now where are these categories stored?

  1. Where are (regular) resources stored? (e.g. Font, CIDFont, CMap, ProcSet, ...)
  2. Where are the categories of ProcSet stored?

Do you need just two extra dictionaries in systemdict (localDict and a globalDict to store resources or where exactly are these stored?)

UPDATE 1: (after answer of KenS)

Ok, maybe the first question now should be. How are resources stored in an interpreter.

From what I understand is that there is maybe a structure like this:

Resources (Dictionary ??? is this local or global or ...?)
- Font (Dictionary)
- CIDFont (Dictionary)
--- CIDFontType (integer)
--- CIDFontName (name)
--- CIDSystemInfo (dictionary)
--- FontBBox (array)
--- FontMatrix (array)
--- FontType (integer)
--- ...
--- ...
- CMap (Dictionary)
- FontSet (Dictionary)
- Encoding (Array)
- Form (Dictionary)
- Pattern (Dictionary)
- ProcSet (Dictionary)
--- BitmapFontInit (Dictionary)
--- CIDInit (Dictionary)
--- ColorRendering (Dictionary)
--- FontSetInit (Dictionary)
--- Trapping (Dictionary)
- ColorSpace (Array)
- ...
- ...
- Category (Dictionary)
--- Generic (Dictionary)

Most of these are dictionaries that are stored in VM. Either in local VM or global VM.

Are these resources added also in userdict and globaldict, because:

  • If you store something in local VM it is most likely added to the userdict.
  • if you store something in global VM it is most likely added to the globaldict.

see PostScript Language Reference Manual 3 (page 66 chapter 3):

The dictionaries userdict and globaldict are intended to be the principal repositories for application-defined dictionaries and other objects. When a PostScript program creates a dictionary in local VM, it then typically associates that dictionary with a name in userdict. Similarly, when the program creates a dictionary in global VM, it typically associates the dictionary with a name in globaldict.

So the easiest would be creating 2 dictionaries: "MyLocalResources" and "MyGlobalResources" where the first is stored in userdict and the other in globaldict. These two dictionaries will contain the Categories (Font, CIDFont, ProcSet, etc...).

The findresource operator is a mechanism that you have to implement yourself that will look in one of these two dictionaries.

Is this correct?

FontDirectory and GlobalFontDirectory are these actually the implementation of the local and global "Font" Category resource?


Solution

  • OK firstly Procedure sets are not arranged in categories, they are a resource like any other. So you reference them by name and Category (where Category in this case is ProcSet).

    Stored Resources can be stored anywhere that is convenient for the implementation. Usually this is on disk, but it doesn't have to be; Ghostscript for example can store its standard Resources in a ROM file system.

    Once instantiated, whether by creating a definition from a PostScript program, or by locating and instantiating a named Resource, a Resource is stored in VM.

    I don't see that you need any extra entries in localdict or globaldict, since findresource can use any mechanism you like to locate resources (note that fonts behave a little differently and there are rules to follow there)

    To be honest, the ProcSet resource is more or less pointless, its only use is to allow PostScript program generators to avoid sending a ProcSet definition of their own to the interpreter every time they generate a new PostScript program.

    Obviously this only works in a tight workflow, where you have control over how the PostScript is generated. This is pretty rare. The overhead of sending the ProcSet each time, for most application ProcSets, is pretty small by comparison with the remainder of the program. I guess it seemed like a good idea at the time.

    [post question edit]

    Provided you follow the rules defined in the PLRM, its up to you how you define resources. Ghostscript, for example, does define two 'instances' dictionaries, one for global VM and one for local VM instances, and these are IIRC defined in localdict and globaldict. You can find out more about the way this is implemented by reading /ghostpdl/Resource/Init/gs_res.ps, you may find some of the comments helpful. Especially the notes about copying the Generic Resource Category implementation.

    Its entirely reasonable for FontDirectory and GlobalFontDirectory to be the implementation of instances of the Font Category, though there's no actual requirement for that, I don't think. Obviously in that case you have to have the Font Category findresource implementation look in those dictionaries first for existing instances. On the other hand, if you don't implement it that way, then you have to keep the FontDirectory and GlobalFontDirectory synchronised with the Font Category instance implementation which is probably awkward and wasteful.

    Fonts are, as you've noted a little different from most other resources, for historical reasons really, and backward compatibility with earlier PostScript versions.

    Don't forget the implicit Resource implementations.