PostScript


The PostScript is a page description language developed by Adobe . It is based on vector formulations of most of its elements. It also knows how to process dot matrix images .

This language between platforms makes it possible to obtain a single file containing all the elements describing the page (texts, images, fonts, colors, etc.).

PostScript has become almost a standard, most printers upscale laser may deal directly PostScript. On the other or the oldest, it was necessary to use an input filter to convert the PostScript language to the raster format comprehensible by the old printers.

The development of the PostScript is stopped by Adobe since 2007, so that the PDF can take over.

Other descendants of PostScript are:

  • Display PostScript and NeWS , both relating to windowing systems;
  • EPS (for Encapsulated PostScript ) , image format, based on PostScript.

The language

Postscript is a complete language, which allows the coding of any algorithm . Although it is quite possible to directly write such programs, they are generally manufactured by other programs, for example print drivers.

The Postscript is inseparable from the environment in which it will be executed. Given the fully dynamic nature of this language, it will in fact be interpreted .

The interpreter consists of a stack, and one or more dictionaries. The stack serves as temporary storage for the parameters of the functions and then for their results. The dictionaries allow the storage of the variables, as well as the code of the functions.

A PostScript program consists of a sequence of words separated by spaces, tabs (TAB), carriage return (CR), line feed (LF), or comments. The interpreter analyzes each word of the PostScript program sequentially by operating as a computer in reverse Polish notation , ie each word is evaluated and then the result (s) of this evaluation is placed at the top The stack, and so on.

Example, to perform the simple numerical calculation b 2 – 4 ac , this could be coded:b b mul 4 a mul c mul sub

PostScript supports the following five types of words:

Digital Constants
Integer ( 123) or real ( 3.14159), the evaluation adds the numeric value to the top of the stack;
Chain Constant
These are character arrays enclosed in parentheses, ex (Abc)represents the string “Abc”;
Reference to a name
/aRepresents the name “a”, which may be used to name a variable or a function; The reference is added to the top of the stack;
Name
This can be the name of a predefined or created procedure, a variable, a dictionary; The name is searched in the active dictionaries, then if it is a value, it is placed on the stack, and if it is a function, it is called (executed); The evaluation of a function could use the values ​​at the top of the stack and replace them with the possible results;
Manufacturer
Four constructors allow to create data structures of variable size, they are composed of the following paired characters, which delimit the beginning and the end of the structure:

  • [And ] any table;
  • <And > : hexadecimal byte arrays;
  • <<And >> : dictionaries;
  • {And } : executable code.
The first part of the manufacturer places a mark on the stack, then the elements of this structure are placed successively on the stack, finally the right part of the constructor recovers all the elements since the last mark in the stack and “manufactures” the corresponding structure and Puts it on the pile.

Dictionaries are tables with only two columns:

  • The first column may contain a value used as an index, or a reference to a name or other object, but the name or value is unique in that column for all rows in the table;
  • And the second, any value associated with that name or value.

With this property, a dictionary therefore works as an array with a column, but whose index can be of value or of any type, and is not restricted to a simple interval of integers.

The dictionary is managed as a hash table (thanks to a hash function predefined by the language itself) and it can be predefined at its creation the initial size as a function of the number of pairs name-value (However, PostScript can dynamically resize a dictionary based on the number of collisions on names, or its fill rate). PostScript dictionaries serve primarily (but not only) to define (dynamically) the scope of variables named and referenced elsewhere in the language.

Among the predefined operators, the most important is defthat it allows to add a name-value association in the current dictionary, which allows to define new variables with their value, or to modify their value, and to define or redefine functions . It can be seen that in Postscript, the executable code is a given, almost like the others, and can be created on the fly, modified.

Examples:

  • /pi 3.14159 def : Defines the variable of name pi, with the numerical value 3.14159;
  • /compteur compteur 1 add def : Add 1 to the variable named counter;
  • /incremente {1 add} def : Defines the increment function, which adds 1 to the parameter;
  • /compteur compteur incremente def : Finds the value associated with the variable named “counter” in the current dictionary and replaces that name with its value, then this value is incremented by the function defined above, and the result is stored (by the function “def” ) In the variable named “/ counter” in the current dictionary. In other words, the variable named “counter” in the scope of a dictionary (starting the search by the current dictionary) will be incremented.

In the last example above, there is no indication that the variable named “counter” will be the same variable from which the value was extracted. Indeed, “def” is used to store a name-value association only in the current dictionary, and none of the other dictionaries in the stack. Now, reading the counter variable (the second reference in the above code) can return the value of a variable found in another dictionary than the current dictionary (or generate an exception at runtime if none of the dictionaries in the In this case, a new variable will be added by “def” in the current dictionary, without modifying the original variable where it was found and which will therefore retain its value. However, as long as the current dictionary is active, the new variable will mask the old one. This device therefore makes it possible to manage local variables other than by a relative position in the stack.

PostScript can differentiate references to a variable (by its name given after one /) and those to its value. However, the reference is not resolved in any dictionary of scope until it is associated with a dictionary to find it. When a name is used without /initial, it is immediately searched when compiling the function in the active scope dictionaries (starting with the current dictionary when compiling and not the one that will be active when the function is executed) , Then the name of the variable is replaced at runtime in the stack by the value associated with that name in the dictionary where the name was found.

Also, to create a complete reference to a well-defined variable and not its value or another variable of the same name in another dictionary, you must specify not only the name of that variable, but also a reference to the dictionary that contains it and where It must be sought. If the dictionary is not referenced (for example by not prefixing by one /), the name resolution is dynamic and can therefore reference different variables depending on the execution context.

PostScript therefore defines two distinct contexts of using a reference to a variable:

  • In the context of compiling a function definition, the reference found in the current dictionary (at the time of compilation) is resolved immediately, but the value is not immediately dereferenced; Instead, the reference is stacked and will then be stored in the code at the time the function is actually defined;
  • Then when the code of the function is executed, any stacked variable reference executes by replacing it in with the value of the variable independently of the current dictionary.

This behavior for the dereference of a variable (read access) is therefore very different from that of storing a variable with defwhich is always done according to the current dictionary at the moment of execution.

Operators

all pop Eliminates the cell element
All 1 All 2 Exch All 2 All 1 Exchange the two elements
Number 1 Number 2 Add sum Returns number 1 plus number 2
Number 1 Number 2 Div quotient Returns number 1 divided number 2
Integer 1 Whole 2 Idiv quotient Returns integer 1 divided integer 2

Implementation

PostScript is licensed from Adobe. However, there is a free PostScript interpreter, Ghostscript .