Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Reid G.C.Thinking in PostScript.1990.pdf
Скачиваний:
17
Добавлен:
23.08.2013
Размер:
846.44 Кб
Скачать

/Times-Bold 24 selectfont 1.0 -5 underlineON

(Hamlet, Act II) 200 650 TEXT underlineOFF

/Times-Roman 12 selectfont

(This should be the first line from Hamlet.) 72 600 TEXT (And this, of course, the second.) 72 570 TEXT

The resulting program has a nice balance of data use, passing some of it from the host word processor, storing some of it, and reducing the complexity of the program itself in the way it relies on the data. Notice that the only change to the way we wanted to set the program up was to add two operands to the underlineON procedure call. The rest of it stayed the same.

CLASSICAL DATA STRUCTURES

There are some classic data structures in the field of computer science that you might want to construct in your PostScript program. For instance, you might want to make use of doubly-linked lists, queues, stacks, trees, and so forth. (Stacks are generally free in PostScript because of the inherent stack-based model, but sometimes you need to create your own.)

Linked Lists

Linked lists can be very useful data structures. A linked list is basically a sequential list of chunks of data that you can traverse either forward or backward (if it is doubly-linked). The main advantage to linked lists in traditional programming languages is that you can allocate memory as you need it, and it doesn’t have to be contiguous. In each data block, you store a pointer to the next block, wherever it may be. In PostScript, the need for these lists diminishes greatly, since you don’t need to worry about the way memory is allocated in order to access data. PostScript language arrays are arrays of other PostScript objects, each of which is self-contained (and very likely occupies some memory that is not adjacent to the next element in the array). But, readjusting the terminology very slightly, lists are still extremely useful, even if you don’t have to spend much time worrying about the links between the elements.

Chapter 12: STORING AND USING DATA

151

Let’s assume that you have a single block of data representing text from a drawing program. You want to store the x, y location of the text on the page, the font in which the text is to appear, the text itself, and the color. In the C language, you might come up with something like the code in Example 12.7.

Example 12.7: List Elements as C Structures

struct textchunk {

 

float X,Y;

/* X,Y location on screen */

char font [ 128 ];

/* font name */

float ptsize;

/* point size of font */

float R,G,B;

/* color */

char *text

/* the text itself */

struct textchunk *next;

/* link for list */

} *head, *tail;

 

What might be the best way to implement a composite data structure like a struct in PostScript? You have only a few choices.

You could use an array that contains all of the pieces of data.

You might use dictionaries, creating one for each chunk of data.

You might simply accumulate piles of data on the operand stack, keeping track of what was where.

Since the operand stack is likely to be unwieldy for a structured approach such as this, let’s consider arrays and dictionaries, to see which one seems better.

Using Arrays to Form Lists

Let’s look at an array that contains everything that the C struct does, but which does not have the links to the next item in the list (see Example 12.8).

152

Chapter 12: STORING AND USING DATA

Example 12.8: List Elements as PostScript Array Objects

[

72.0 100.0 /Times-Italic 24.0 1.0 0.0 0.0

(Julius Caesar)

]

Notice that the names have disappeared, since arrays contain just the data. But how would you create a link to the next chunk of data? Since a PostScript array object is already a pointer to a composite data structure, we could use it directly, including an array object within the array that represents the next item in the list. It looks as though the arrays are nested when you look at them syntactically, but in effect one array simply contains a pointer to another. An array might even contain a circular reference by including a copy of itself as one of its elements, but we will try to avoid that in our examples. Notice that the original array (the one containing the name Julius Caesar) has been reproduced, but is written a little more compactly to save some space on the page (Example 12.9).

Example 12.9: Forming a List of Array Objects

[

72.0 650.0 /Times-BoldItalic 24.0 1 0 0 (Julius Caesar)

[

72.0 600 /Times-Italic 18.0 1 0 0 (William Shakespeare)

[]

]

]

The actual structure of these arrays looks more like Figure 12.1 when it is represented internally in the PostScript interpreter.

Chapter 12: STORING AND USING DATA

153

Figure 12.1: Structure of the PostScript Linked List

72.0 650.0 /Times-BoldItalic 24.0 1 0 0 (Julius Caesar) [ ]

72 600 /Times-Italic 18 1 0 0 (William Shakespeare) [ ]

This method is very compact and efficient, but it does present one difficulty: the elements of the structure cannot be referred to by name, but only by their position within the array (although you could write procedures to help you with this). Arrays could be troublesome to maintain effectively and to debug, but are much more space-efficient than dictionaries.

Using Dictionaries to Form Lists

Let’s try the same idea using a dictionary to store the elements of the structure (see Example 12.10).

Example 12.10: List Element as a PostScript Dictionary

/head 9 dict def /tail head def head begin

/X 72 def /Y 470 def

/font /Times-Roman def /ptsize 16 def

% red, green, and blue stored as R,G,B: /R 1 def

/G 0 def /B 0 def

/text (Act One) def

/next null def% points to nothing

end

154

Chapter 12: STORING AND USING DATA