
- •Preface
- •DESIGN FEATURES
- •STRUCTURED PROGRAMMING TECHNIQUES
- •PROGRAMMING TASKS
- •WINDOW SYSTEMS, COMMUNICATIONS, AND DISPLAYS
- •DATA STRUCTURES AND ALGORITHMS
- •CONCLUDING THOUGHTS
- •PostScript is Not Like C
- •COMPARISON OF LANGUAGE MECHANISMS
- •EXPRESSING AN ALGORITHM AS A PROGRAM
- •THE UNIX SHELL AND OPERATING SYSTEM
- •INPUT, OUTPUT, AND THROUGHPUT
- •CONCLUDING THOUGHTS
- •Foundations
- •POSTSCRIPT LANGUAGE SYNTAX
- •SIMPLE PROGRAM STRUCTURE
- •Make Definitions First
- •Indentation Style
- •SETTING UP TEMPLATES
- •DECLARING AND USING VARIABLES
- •Arithmetic with Numeric Variables
- •Using the // Notation for Constants
- •ALLOCATING MEMORY
- •GETTING MEMORY BACK
- •OPENING AND CLOSING FILES
- •COMPARISONS AND EQUALITY OF OBJECTS
- •CONCLUDING THOUGHTS
- •Some Typical Programs
- •A TYPICAL PAGE DESCRIPTION PROGRAM
- •FONT PROGRAMS
- •PROGRAMS THAT READ DATA
- •QUERY PROGRAMS
- •ENCAPSULATED POSTSCRIPT PROGRAMS
- •PERSISTENTLY RESIDENT PROGRAMS
- •CONCLUDING THOUGHTS
- •Understanding the Stack
- •A QUICK OVERVIEW OF DATA TYPES
- •NAME LOOKUP
- •HOW OPERATORS USE THE STACK
- •GROUPING AND VISUAL CHUNKING
- •THINKING BACKWARD AND SIDEWAYS
- •COMPOSITE OBJECTS
- •THE OTHER STACKS
- •The Dictionary Stack
- •The Execution Stack
- •The Graphics State Stack
- •CONCLUDING THOUGHTS
- •Trusting the Stack
- •SAFETY OF DATA ON THE STACK
- •WHERE ARE THE DATA GOING?
- •REARRANGING THE STACK
- •Using the dup and index Operators
- •Using the roll Operator
- •CONDITIONALS AND LOOPS
- •RECURSION AND LOCAL VARIABLES
- •CONCLUDING THOUGHTS
- •Building Conditional Statements
- •SIMPLE CONDITIONALS
- •SETTING UP THE CONDITION
- •CONDITIONALS ARE NOT MAGIC
- •NESTED CONDITIONALS AND ELSE CLAUSES
- •COMPOUND CONDITIONALS
- •CONCLUDING THOUGHTS
- •Using Looping Constructs
- •LOOP BASICS
- •USING THE LOOP INDEX
- •LOOPS ARE PROCEDURE BODIES
- •LOOPS OF INSTRUCTIONS
- •EXITING LOOPS PREMATURELY
- •CONCLUDING THOUGHTS
- •Procedures
- •WHAT EXACTLY IS A PROCEDURE?
- •PARAMETER PASSING
- •CONSTRUCTING GOOD PROCEDURES
- •What to Name Your Procedure
- •A Useful Naming Convention
- •SELF-MODIFYING PROCEDURES
- •CONCLUDING THOUGHTS
- •Using Dictionaries
- •DICTIONARIES FOR NAME SCOPING
- •LOCAL DICTIONARIES
- •GLOBAL DICTIONARIES OF PROCEDURES
- •MAINTAINING THE DICTIONARY STACK
- •INTO AND OUT OF DICTIONARIES
- •LOOKING INTO DICTIONARIES
- •Using the forall Operator
- •Using the where and known Operators
- •REDEFINING OPERATORS
- •Changing the Behavior of Operators
- •Debugging with Redefined Names
- •Proper Nesting of Redefinitions
- •CONCLUDING THOUGHTS
- •Creating and Manipulating Data
- •CONSTRUCTING AN ARRAY
- •CONSTRUCTING A STRING
- •MANIPULATING DATA WITH PUT AND GET
- •CONCATENATING ARRAYS AND STRINGS
- •INPUT AND OUTPUT OF STRING DATA
- •ARRAYS VERSUS DICTIONARIES
- •ADVANCED TECHNIQUES
- •CONCLUDING THOUGHTS
- •Storing and Using Data
- •Data and the Operand Stack
- •Data and Algorithms for Underlining
- •CLASSICAL DATA STRUCTURES
- •Linked Lists
- •Using Arrays to Form Lists
- •Using Dictionaries to Form Lists
- •Queues, Trees, and Other Data Structures
- •CONCLUDING THOUGHTS
- •Program Data and Instructions
- •TURNING DATA INTO INSTRUCTIONS
- •TURNING INSTRUCTIONS INTO DATA
- •DATA CONVERSIONS
- •CONCLUDING THOUGHTS
- •File Objects
- •Streams and Files
- •PostScript File Operators
- •OPENING AND CLOSING FILES
- •READING AND WRITING FILES
- •Reading from a File
- •Writing to a File
- •Copying and Renaming Files
- •WRITING FORMATTED DATA TO FILES
- •Writing Out Various Data Types
- •Spaces, Tabs, Returns, and Special Characters
- •FILE STATUS INFORMATION
- •RANDOM VERSUS SEQUENTIAL ACCESS
- •CONCLUDING THOUGHTS
- •Appendix
- •Answers to Exercises

If you mix up the index and the value, you will very likely get an error, although not always, if the values are still within range. Remember that the PostScript operators themselves don’t know what you have in mind. They are flexible, and will allow you to do things that you may not have intended. It is very easy to lose track of what is on the operand stack, or to supply incorrect operands to some operator, leading to bugs in your program that are sometimes difficult to locate.
GROUPING AND VISUAL CHUNKING
One of the best ways to learn to read and write PostScript programs is to be able to “chunk” together sequences of instructions into a block that has a well-understood input and output. In many programming languages, you can usually read a single line of the source code and make sense of it. In fact, usually one line of the program represents a single statement in that language, which may be an assignment statement or a procedure call. But in the PostScript language, the statements can get fairly complex, and each operator and its arguments represents one phrase of the statement. The programs that are the most difficult to read are those that use one operator to manufacture the arguments for the next operator.
Let’s look quickly at two examples that illustrate the concept of one operator leaving behind results that become arguments for the subsequent operation. The first case (Example 5.2) shows a series of code samples of gradually increasing complexity, culminating in some that may look a little bit confusing at first glance. Take a moment to mentally execute the program to see what it does.
Example 5.2: Each Operator Uses the Operand Stack
%currentgray leaves result for setgray currentgray 1 exch sub setgray
%save leaves a value for restore (“3 exch” is just there to confuse you) save 3 exch restore
%search leaves three strings and a boolean
(ABCD) (B) search { = pop = flush }{ = flush } ifelse
56 |
Chapter 5: UNDERSTANDING THE STACK |

Example 5.3 is an extremely familiar program fragment that is actually somewhat tricky in its operation. The findfont operator returns a dictionary that is used by the scalefont operator, and if you ever mix up the order of these operators, you might never even know that this object was there, since it no sooner is produced than it is consumed again. The (Testing) exch part of this example demonstrates that there really is a font dictionary on the operand stack, and if you put something else on top of it and use exch to flip the two, scalefont will still have the right information on the stack to perform its task, but the string will now be on the bottom of the stack, ready to be used by show at the end of the example.
Example 5.3: The findfont Operator Returns a Dictionary
/Times-Roman findfont (Testing) exch 12 scalefont setfont show
The secret to “visual chunking” is to recognize an operator and its operands in the middle of a program segment. You might have noticed several candidates for visual chunking in the short program of Example 5.3. Even if you didn’t, with a little practice, you’ll learn to chunk program fragments together visually, greatly improving your ability to read PostScript code. There are really three kinds of things you can see:
1.A sequence of operators that, combined, yields a new object or group of objects on the operand stack.
2.A sequence of operators that may rearrange or duplicate some elements of the stack, but which do not inherently add anything new to the stack.
3.Operations that consume or otherwise remove things from the operand stack.
Visual chunking for the code of Example 5.3 is illustrated graphically in Figure 5.3.
After a while, you start to see bigger chunks all at once, which makes it much easier to follow the program.
Chapter 5: UNDERSTANDING THE STACK |
57 |