PostScript Language Reference Manual

Transcript

1 See also cross-references: abcdefghijklmnopqrltuvw PLRM 2nd Edition July 27, 1992 ® PostScript Language Reference Manual SECOND EDITION Adobe Systems Incorporated Addison-Wesley Publishing Company, Inc. Reading, Massachusetts • Menlo Park, California • New York Don Mills, Ontario • Wokingham, England • Amsterdam Bonn • Sydney • Singapore • Tokyo • Madrid • San Juan

2 PLRM 2nd Edition July 27, 1992 Library of Congress Cataloging-in-Publication Data PostScript language reference manual / Adobe Systems. — 2nd ed. p. cm. Includes index. ISBN 0-201-18127-4 1. PostScript (Computer program language) I. Adobe Systems. QA76.73.P67P67 1990 005.13’3—dc20 90-43535 Copyright © 1985, 1986, 1987, 1988, 1990 Adobe Systems Incorporated. All Rights Reser ved. Patents Pending. No part of this publication may be repro- duced, stored in a retrieval system, or transmitted, in any form or by any means, wise, without the prior electronic, mechanical, photocopying, recording, or other written permission of Adobe Systems Incorporated and Addison-W esley Publish- ing Company, Inc. Printed in the United States of America. Published simultaneously in Canada. , is subject The information in this book is furnished for informational use only to change without notice, and should not be construed as a commitment by Adobe Systems Incorporated. Adobe Systems Incorporated assumes no responsi- bility or liability for any errors or inaccuracies that may appear in this book. The software described in this book is furnished under license and may only be used or copied in accordance with the terms of such license.  is a registered trademark of Adobe Systems Incorporated. The name PostScript All instances of the name PostScript in the text are references to the PostScript language as defined by Adobe Systems Incorporated unless other wise stated. The name PostScript also is used as a product trademark for Adobe Systems’ imple- mentation of the PostScript language interpreter. Any references to a “PostScript printer ,” a “PostScript file,” or a “PostScript driver” refer to printers, files, and driver programs (respectively) which are writ- ten in or support the PostScript language. The sentences in this book that use ce that “PostScript language” as an adjective phrase are so constructed to reinfor the name refers to the standard language definition as set forth by Adobe Systems Incorporated. PostScript, the PostScript logo, Display PostScript, Adobe, the Adobe logo, Adobe Illustrator , TranScript, Carta, and Sonata are trademarks of Adobe Systems Incor- porated registered in the U.S. Adobe Garamond and Lithos are trademarks of alk are trademarks and Mac- Adobe Systems Incorporated. QuickDraw and LocalT intosh and LaserW riter are registered trademarks of Apple Computer , Inc. FrameMaker is a registered trademark of Frame T echnology Corporation. ITC Stone is a registered trademark of International T ypeface Corporation. IBM is a registered trademark of International Business Machines Corporation. Helvetica, Times, and Palatino are trademarks of Linotype AG and/or its subsidiaries. Microsoft and MS-DOS are registered trademarks and W indows is a trademark of Microsoft Corporation. T imes New Roman is a registered trademark of The Monotype Corporation plc. NeXT is a trademark of NeXT , Inc. Sun-3 is a trade- mark of Sun Microsystems, Inc. UNIX is a registered trademark of A T&T Information Systems. X W indow System is a trademark of the Massachusetts Institute of T echnology . Other brand or product names are the trademarks or reg- istered trademarks of their respective holders. ABCDEFGHIJ-MW-90 First printing, December 1990

3 PLRM 2nd Edition January 27, 1994 Contents Preface vii Chapter 1: Introduction 1 1.1 About This Manual 3 1.2 Evolution of the PostScript Language 5 1.3 PostScript Level 2 Overview 7 1.4 Copyrights and Trademarks 9 Chapter 2: Basic Ideas 11 2.1 Raster Output Devices 11 2.2 Scan Conversion 12 2.3 Page-Description Languages 13 2.4 Using the PostScript Language 16 23 Chapter 3: Language 3.1 Interpreter 24 Syntax 25 3.2 3.3 Data Types and Objects 33 3.4 Stacks 43 3.5 Execution 45 3.6 Overview of Basic Operators 50 3.7 Memory Management 55 3.8 File Input and Output 71 3.9 Named Resources 85 3.10 Errors 99 3.11 Early Name Binding 101 3.12 Binary Encoding Details 105 Filtered Files Details 122 3.13 i

4 PLRM 2nd Edition January 27, 1994 143 Chapter 4: Graphics Imaging Model 144 4.1 4.2 Graphics State 146 4.3 Coordinate Systems and Transformations 150 4.4 Path Construction 157 4.5 Painting 160 4.6 User Paths 164 4.7 Forms 172 4.8 Color Spaces 176 4.9 Patterns 200 4.10 Images 210 4.11 Device Setup 226 Chapter 5: Fonts 257 5.1 Organization and Use of Fonts 257 5.2 Font Dictionaries 264 5.3 Character Encoding 269 5.4 Font Metric Information 271 Font Cache 274 5.5 5.6 Modifications to Existing Fonts 275 5.7 Type 3 Fonts 278 5.8 Unique ID Generation 283 5.9 Composite Fonts 285 Chapter 6: Rendering 293 6.1 CIE-Based Color to Device Color 294 6.2 Conversions Among Device Color Spaces 303 6.3 Transfer Functions 307 6.4 Halftones 309 6.5 Scan Conversion Details 320 Chapter 7: Display PostScript 325 7.1 Multiple Execution Contexts 326 7.2 Encoded User Names 332 7.3 Graphics and Window Systems 334 7.4 Bitmap Fonts 339 Chapter 8: Operators 343 8.1 Operator Summary 346 Operator Details 360 8.2 ii Contents

5 PLRM 2nd Edition January 27, 1994 555 Appendix A: Changes to Language and Implementation Language Extensions 555 A.1 A.2 Language Changes Affecting Existing Operators 560 A.3 Implementation and Documentation Changes 562 Appendix B: Implementation Limits 565 B.1 Typical Limits 566 B.2 Virtual Memory Use 569 Appendix C: Interpreter Parameters 571 C.1 Defined User and System Parameters 572 C.2 General Properties of User and System Parameters 574 C.3 Parameter Details 576 C.4 Device Parameters 579 Appendix D: Compatibility Strategies 581 D.1 The Level Approach 581 When To Provide Compatibility 582 D.2 D.3 Compatibility Techniques 585 D.4 Installing Emulations 588 Appendix E: Standard Character Sets and Encoding Vectors 591 E.1 Times Family 592 E.2 Helvetica Family 593 E.3 Courier Family 594 E.4 Symbol 595 E.5 Standard Roman Character Set 596 E.6 StandardEncoding Encoding Vector 598 E.7 ISOLatin1Encoding Encoding Vector 599 E.8 Expert Character Set 600 E.9 Expert Encoding Vector 602 E.10 ExpertSubset Encoding Vector 603 E.11 Symbol Character Set 604 E.12 Symbol Encoding Vector 606 607 Appendix F: System Name Encodings Contents iii

6 PLRM 2nd Edition January 27, 1994 611 Appendix G: Document Structuring Conventions—Version 3.0 G.1 Using the Document Structuring Conventions 613 G.2 Document Manager Services 614 G.3 DSC Conformance 620 G.4 Document Structure Rules 624 G.5 General Conventions 639 G.6 Requirement Conventions 658 G.7 Color Separation Conventions 685 G.8 Query Conventions 688 G.9 Open Structuring Conventions 696 G.10 Special Structuring Conventions 698 Changes Since Earlier Versions 699 G.11 G.12 DSC Version 3.0 Summary 706 Appendix H: Encapsulated PostScript File Format—Version 3.0 709 H.1 Introduction 709 H.2 Guidelines for Creating EPS Files 712 H.3 Guidelines for Importing EPS Files 718 H.4 File Types and Naming 727 H.5 Device-Specific Screen Preview 728 H.6 Device-Independent Screen Preview 730 H.7 EPS Example 733 H.8 Changes Since Version 2.0 735 Appendix I: Guidelines for Specific Operators 737 Bibliography 745 Index 747 iv Contents

7 PLRM 2nd Edition January 27, 1994 Preface Preface It has been only five years since the first PostScript Language Reference Manual was published and the first products based on the PostScript language were introduced. In 1985, we had no reason to anticipate the far-reaching effects that the PostScript language would have on the printing and publishing industry. At that time, there were no effective page-description standards, popular typefaces were used only with spe- cific typesetting equipment, producing high-quality visual materials was restricted to specialists, and the cost of producing most corporate communication pieces was prohibitive. In its brief history, the PostScript language and the many corporations and individuals working with PostScript products have changed all that. Today all major computer, printer, and imagesetter vendors sup- port the PostScript language as a standard. The major type libraries are becoming available in PostScript-compatible formats. The cost of pro- ducing high-quality, printed material has dropped substantially. As a result, the PostScript language is becoming a part of the basic fabric of the printing, publishing, and computing industries. We at Adobe not only take great pride in this success, but more impor- tantly, we feel a significant responsibility to those who have placed their trust in us and in this technology. We are committed to enhancing the PostScript language standard so that we can continue to earn that trust. In developing this language, we have tried to remember that PostScript is only one advancement in the rich 500-year history of printing and typography. We are constantly sensitive to the fact that we are working with a delicate combination of art, tradition, and technology. Not only must the technological effectiveness of the PostScript language be improved, but our aspiration to provide the highest-quality printed results must be preserved and enhanced in each implementation of a PostScript product. v

8 PLRM 2nd Edition Preface January 27, 1994 Any standard, if it is to continue to serve the community in the face of technological change, must grow and adapt; the PostScript language is no exception. We hope that you, the users, will find that this second incorporates many of edition of the PostScript Language Reference Manual the ideas you have given us. We have tried to use good taste, sound judgment, and some restraint in extending an already effective and use- ful standard. None of the success of the PostScript language would be possible with- out the efforts of the many individuals and corporations that have sup- ported PostScript. Successful standards are never the result of one individual or group. We take this opportunity to thank all of the organi- zations and individuals who have lent their support in the past, and hope we can continue working together to enjoy the benefits of an effective standard for communicating visual information. John Warnock & Chuck Geschke December 1990 vi Preface

9 PLRM 2nd Edition January 21, 1994 Introduction Example 1.0 Example 2.0 Example 3.0 Example 4.0 Example 1.0 Example 5.0 Table 1.0 Example 6.0 1 CHAPTER Figure 1.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Introduction ® language is a simple interpretive programming lan- The PostScript guage with powerful graphics capabilities. Its primary application is to describe the appearance of text, graphical shapes, and sampled images on printed or displayed pages. A program in this language can commu- nicate a description of a document from a composition system to a printing system or control the appearance of text and graphics on a dis- play. The description is high level and device independent. The page description and interactive graphics capabilities of the Post- Script language include the following features, which can be used in any combination: • Arbitrary shapes made of straight lines, arcs, rectangles, and cubic curves. Such shapes may self-intersect and have disconnected sec- tions and holes. • Painting operators that permit a shape to be outlined with lines of any thickness, filled with any color, or used as a clipping path to crop any other graphic. Colors can be specified in a variety of ways: gray-level, RGB, CMYK, and CIE based. Certain other features are also modelled as special kinds of colors: repeating patterns, color mapping, and separations. • Text fully integrated with graphics. In the PostScript language’s graphics model, text characters in both standard and user-defined fonts are treated as graphical shapes that may be operated on by any of the normal graphics operators. • Sampled images derived from natural sources (such as scanned pho- tographs) or generated synthetically. The PostScript language can describe images sampled at any resolution and according to a variety of color models. It provides a number of ways to reproduce images on an output device. 1

10 PLRM 2nd Edition January 21, 1994 Introduction • A general coordinate system that supports all combinations of linear transformations, including translation, scaling, rotation, reflection, and skewing. These transformations apply uniformly to all elements of a page, including text, graphical shapes, and sampled images. A PostScript language page description can be rendered on a printer, display, or other output device by presenting it to a PostScript inter- preter controlling that device. As the interpreter executes commands to paint characters, graphical shapes, and sampled images, it converts the high-level PostScript language description into the low-level raster data format for that particular device. Normally, application programs such as document composition systems, illustrators, and computer-aided design systems generate Post- Script language page descriptions automatically. Programmers generally write PostScript language programs only when creating new applica- tions. However, in special situations a programmer can write PostScript language programs to take advantage of capabilities of the PostScript language that are not accessible through an application program. The extensive graphical capabilities of the PostScript language are embedded in the framework of a general-purpose programming lan- guage. The language includes a conventional set of data types, such as numbers, arrays, and strings; control primitives, such as conditionals, loops, and procedures; and some unusual features, such as dictionaries. These features enable application programmers to define higher-level operations that closely match the needs of the application and then to generate commands that invoke those higher-level operations. Such a description is more compact and easier to generate than one written entirely in terms of a fixed set of basic operations. PostScript language programs can be created, transmitted, and inter- preted in the form of ASCII source text as defined in this manual. The entire language can be described in terms of printable characters and white space. This representation is convenient for programmers to cre- ate, manipulate, and understand. It also facilitates storage and transmis- sion of files among diverse computers and operating systems, enhancing machine independence. There are also binary encoded forms of the language for use in suitably controlled environments—for example, when the program is assured of a fully transparent communications path such as in the Display Post- ® Script system. Adobe recommends strict adherence to the ASCII repre- sentation of PostScript language programs for document interchange or archival storage. 2 Chapter 1: Introduction

11 PLRM 2nd Edition January 21, 1994 Introduction 1.1 About This Manual This is the programmer’s reference manual for the PostScript language. It is the definitive documentation for the syntax and semantics of the language, the imaging model, and the effects of the graphical operators. Here is what the manual contains: Chapter 2, “Basic Ideas,” is an informal presentation of some basic ideas underlying the more formal descriptions and definitions in the manual. These include the properties and capabilities of raster output devices, requirements for a language that effectively uses those capabilities, and some pragmatic information about the environments in which the PostScript interpreter operates and the kinds of PostScript language pro- grams it typically executes. Chapter 3, “Language,” introduces the fundamentals of the PostScript language: its syntax, semantics, data types, execution model, and inter- actions with application programs. This chapter concentrates on the conventional programming aspects of the language, ignoring its graph- ical capabilities and use as a page-description language. Chapter 4, “Graphics,” introduces the PostScript language imaging model at a device-independent level. It describes how to define and manipulate graphical entities—lines, curves, filled areas, sampled images, and higher-level structures such as patterns and forms. It includes complete information on the color models that the PostScript language supports. Finally, it describes how a page description commu- nicates its document processing requirements to the output device. Chapter 5, “Fonts,” describes how the PostScript language deals with text. Characters are defined as graphical shapes, whose behavior con- forms to the graphical model presented in Chapter 4. Because of the importance of text in most applications, the PostScript language pro- vides special capabilities for organizing sets of characters as fonts and for painting characters efficiently. Chapter 6, “Rendering,” details the device-dependent aspects of render- ing PostScript language page descriptions on printers and displays. These include color rendering, transfer functions, halftoning, and scan conversion, each of which is device dependent in some way. Chapter 7, “Display PostScript,” explains the concepts and PostScript language operators specific to interactive display applications. 1.1 About This Manual 3

12 PLRM 2nd Edition January 21, 1994 Introduction Chapter 8, “Operators,” describes all PostScript language operators and procedures. The chapter begins by categorizing operators into func- tional groups. Then the operators appear in alphabetical order, with complete descriptions of their operands, results, side effects, and possi- ble errors. The manual concludes with several appendices containing useful infor- mation that is not a formal part of the PostScript language. Appendix A, “Changes to Language and Implementation,” lists the changes that have been made to the PostScript language since the first edition of this manual. Appendix B, “Implementation Limits,” describes typical limits imposed by implementations of the PostScript interpreter—for example, maxi- mum integer value and maximum stack depth. Appendix C, “Interpreter Parameters,” specifies various parameters to control the operation and behavior of the PostScript interpreter. Most of these parameters have to do with allocation of memory and other resources for specific purposes. Appendix D, “Compatibility Strategies,” helps PostScript language pro- grammers take advantage of PostScript Level 2 features while maintain- ing compatibility with the installed base of Level 1 interpreter products. Appendix E, “Standard Character Sets and Encoding Vectors,” describes the organization of most common fonts that are built into interpreters or are available as separate software products. Appendix F, “System Name Encodings,” assigns numeric codes to stan- dard names, for use in binary-encoded PostScript language programs. Appendix G, “Document Structuring Conventions—Version 3.0,” describes a convention for structuring PostScript language page descrip- tions to facilitate their handling and processing by other programs. Appendix H, “Encapsulated PostScript File Format—Version 3.0,” describes a format that enables applications to treat each others’ output as included illustrations. Appendix I, “Guidelines for Specific Operators,” provides guidelines for PostScript language operators whose use can cause unintended side effects, make a document device dependent, or inhibit post-processing of a document by other programs. 4 Chapter 1: Introduction

13 PLRM 2nd Edition Introduction January 21, 1994 ” is a list of sour “ Bibliography ces for many of the concepts in the Post- Script language. Since this is a reference manual and not a tutorial, it provides relatively . As few guidelines on how to use the PostScript language effectively with any programming language, certain techniques yield the best solu- tions to particular programming problems; there are issues of style that in fl uence the performance, quality , and consistency of the results. These matters are the main topics of two companion books. introduces the PostScript • PostScript Language T utorial and Cookbook language at a basic level. It includes a large number of techniques and recipes for obtaining results from the mundane to the exotic. This book emphasizes examples, not ef ficient programming strate- gies, to illustrate in a clear way many of the capabilities of the Post- Script language. • PostScript Language Pr ogram Design is for programmers interested in ficient design of PostScript language programs the effective and ef and printer drivers. It includes many programming examples that are recommended for direct use in applications. Adobe T An additional book, , speci fies the internal ype 1 Font Format ype 1 font program. That speci fication is logically organization of a T part of the PostScript language, but it is published separately because it is highly specialized and is of interest to a different user community . A great deal of additional technical documentation is available through the Adobe Systems Developers ’ Association. Registered software devel- opers receive regular mailings of technical papers, telephone support, and discounts on PostScript hardware and software products. For infor- mation about the Developers ’ Association, please write to this address: Adobe Developer Technologies Adobe Systems Incorporated 345 Park Avenue San Jose, CA 95110 USA 1.2 Evolution of the PostScript Language Since its introduction in 1985, the PostScript language has been consid- erably extended for greater programming power , ef ficiency , and fl exibil- ypically , these language extensions have been designed to adapt ity . T 1.2 Evolution of the PostScript Language 5

14 PLRM 2nd Edition January 21, 1994 Introduction the PostScript language to new imaging technologies or system envi- ronments. While these extensions have introduced significant new functionality and flexibility to the language, the basic imaging model remains unchanged. The principal extensions are: • Color . The color extensions provide a cyan-magenta-yellow-black (CMYK) color model for specifying colors and a operator colorimage for painting color sampled images. They also include additional ren- dering controls for color output devices. • Composite fonts . The composite font extensions enhance the basic font facility to support character sets that are very large or have com- plex requirements for encoding or character positioning. . The Display PostScript system enables workstation • Display PostScript applications to use the PostScript language and imaging model for managing the appearance of the display. Some of the extensions are specialized to interactive display applications, such as concurrent execution and support for windowing systems. Other extensions are more general and are intended to improve performance or program- ming convenience. In addition to the language extensions above, there have been other minor additions to the language, such as file system extensions to sup- port products that include disks or cartridges. See Appendix A for com- plete details. This manual documents the entire PostScript language, which consists of three distinct groups of operators: Level 1, Level 2, and Display Post- Script operators. Level 1 operators are the ones documented in the first edition of the PostScript Language Reference Manual . Level 2 operators include all operators from the language extensions described above and new operators introduced into the language for PostScript Level 2. Dis- play PostScript operators are those operators present only in Display PostScript systems. Chapter 8 clearly identifies Level 2 and Display Post- Script operators with the following icons: LEVEL 2 Level 2 operator DPS Display PostScript operator 6 Chapter 1: Introduction

15 PLRM 2nd Edition January 21, 1994 Introduction While the Postscript language is a well-defined standard, not all Post- Script interpreters include all language features. Products that contain PostScript software from Adobe Systems can be categorized as follows: • Level 1 implementations include all Level 1 operators. Some Level 1 implementations include one or more language extensions. For example, PostScript color printers support Level 1 operators plus the color extensions. • Level 2 implementations include Level 1 and Level 2 operators. all • Display PostScript systems include the Display PostScript operators and can be based on either Level 1 or Level 2 implementations. Dis- play PostScript systems based on Level 1 include the Display Post- Script and color extensions mentioned above and sometimes other extensions as well. Display PostScript systems based on Level 2 include all Level 2 operators. Appendix D describes strategies for writing PostScript language pro- grams that can run compatibly on interpreters based on either Level 1 or Level 2 implementations of the language. 1.3 PostScript Level 2 Overview In addition to unifying all previous language extensions, PostScript Level 2 introduces a number of new language features. This section summarizes both new language features and ones from previous lan- guage extensions, which are now part of PostScript Level 2. • Dictionaries . Many Level 2 operators expect a dictionary operand that contains key-value pairs specifying parameters to the operator. Lan- guage features controlled in this way include halftones, images, forms, patterns, and device setup. This organization allows for optional parameters and future extensibility. For convenience in using such operators, the PostScript language syntax includes new tokens, << and >> , to construct a dictionary containing the brack- eted key-value pairs. • Memory management . It is now possible to remove individual entries from dictionaries and to remove font definitions in an order unre- lated to the order in which they were created. Virtual memory (VM) is reclaimed automatically for composite objects that are no longer accessible. In general, memory is more efficiently shared among dif- ferent uses and arbitrary memory restrictions have been eliminated. 1.3 PostScript Level 2 Overview 7

16 PLRM 2nd Edition Introduction January 21, 1994 Resources . A resource is a collection of named objects that either • reside in VM or can be located and brought into VM on demand. There are separate categories of resources with independent name spaces—for example, fonts and forms are distinct resource categories. The language includes convenient facilities for locating and manag- ing resources. • Filters . A filter transforms data as it is being read from or written to a file. The language supports filters for ASCII encoding of binary data, compression and decompression, and embedded subfiles. Properly used, these filters reduce the storage and transmission costs of page descriptions, especially ones containing sampled images. • Binary encoding . In addition to the standard ASCII encoding, the lan- guage syntax includes two binary-encoded representations. These binary encodings improve efficiency of generation, representation, and interpretation. However, they are less portable than the ASCII encoding and are suitable for use only in controlled environments. . A user path is a self-contained procedure that consists User paths • entirely of path construction operators and their coordinate oper- ands. User path operators perform path construction and painting as a single operation; this is both convenient and efficient. There is a user path cache to optimize interpretation of user paths that are invoked repeatedly. There are also some convenience operators for painting rectangles. • Forms . A form is a self-contained description of any arbitrary graph- ics, text, and sampled images that are to be painted multiple times— on each of several pages or several times at different locations on a single page. There is a form cache to optimize repeated uses of the same form. • . Colors can be specified according to a variety of color Color spaces systems, including gray-scale, RGB, CMYK, and CIE based. Patterns, color mapping, and separations are also modelled as color spaces. The color space is now an explicit parameter of the graphics state. CIE-based color spaces • . The language supports several device-indepen- dent color spaces based on the CIE 1931 (XYZ)-space, a system for specifying color values in a way that is related to human visual per- ception. A given CIE-based color specification can be expected to produce consistent results on different color output devices, inde- pendent of variations in marking technology, ink colorants, or screen phosphors. 8 Chapter 1: Introduction

17 PLRM 2nd Edition January 21, 1994 Introduction Patterns . It is possible to paint with patterns as well as with solid col- • ors. When the current color is a pattern, painting operators apply “paint” that is produced by replicating (or tiling) a small graphical figure, called a pattern cell, at fixed intervals in x and to cover the y areas being painted. The appearance of a pattern cell is defined by an arbitrary PostScript language procedure, which can include graphics, text, and sampled images. There is a pattern cache to optimize repeated uses of the same pattern. Images • . There are several enhancements to the facilities for painting sampled images: use of any color space, 12-bit component values, direct use of files as data sources, and additional decoding and ren- dering options. • . There are several other new opera- Other text and graphics operators tors optimized for performance. Graphics state objects allow fast switching among arbitrary graphics states. Automatic stroke adjust- ment efficiently compensates for rasterization effects to produce strokes of uniform thickness when rendering thin lines at low resolu- provide a natural way for applications to show tions. New variants of deal with individual character positioning and enable simultaneous selectfont operator pair kerning, track kerning, and justification. The optimizes switching among fonts. • Device setup . The setpagedevice operator provides a device-indepen- dent framework for specifying the requirements of a page descrip- tion and for controlling both standard features, such as the number of copies, and optional features of a device, such as duplex printing. • Interpreter parameters . Administrative operations, such as system con- figuration and changing input-output device parameters, are now organized in a more systematic way. Allocation of memory and other resources for specific purposes is under software control. For exam- ple, there are parameters controlling the maximum amount of mem- ory to be used for VM, font cache, form cache, pattern cache, and halftone screens. 1.4 Copyrights and Trademarks The general idea of utilizing a page-description language is in the public domain. Anyone is free to devise his own set of unique commands that constitute a page-description language. However, Adobe Systems Incor- porated owns the copyright in the list of operators and the written spec- ification for Adobe’s PostScript language. Thus, these elements of the 1.4 Copyrights and Trademarks 9

18 PLRM 2nd Edition January 21, 1994 Introduction PostScript language may not be copied without Adobe’s permission. Additionally, Adobe owns the trademark “PostScript,” which is used to identify both the PostScript language and Adobe’s PostScript software. Adobe will enforce its copyright and trademark rights. Adobe’s inten- tions are to: • Maintain the integrity of the PostScript language standard. This enables the public to distinguish between the PostScript language and other page-description languages. • Maintain the integrity of “PostScript” as a trademark. This enables the public to distinguish between Adobe’s PostScript interpreter and other interpreters that can execute PostScript language programs. However, Adobe desires to promote use of the PostScript language for information interchange among diverse products and applications. Accordingly, Adobe gives permission to anyone to: • Write programs in the PostScript language. • Write drivers to generate output consisting of PostScript language commands. • Write software to interpret programs written in the PostScript lan- guage. • Copy Adobe’s copyrighted list of commands to the extent necessary to use the PostScript language for the above purposes. The only condition of such permission is that anyone who uses the copyrighted list of commands in this way must include an appropriate copyright notice. This limited right to use the copyrighted list of commands does not include a right to copy the PostScript Language Reference Manual , other copyrighted publications from Adobe, or the software in Adobe’s Post- Script interpreter, in whole or in part. The trademark “PostScript” may not be used to identify any product not originating from or licensed by Adobe. 10 Chapter 1: Introduction

19 PLRM 2nd Edition January 21, 1994 Basic Ideas Example 1.0 Example 2.0 Example 3.0 Example 4.0 Example 2.0 Example 5.0 Table 2.0 Example 6.0 2 CHAPTER Figure 2.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Basic Ideas To obtain a complete understanding of the PostScript language, one must consider it from several points of view: • As a general-purpose programming language with powerful built-in graphics primitives. • As a page-description language that includes programming features. • As an interactive system for controlling raster output devices (dis- plays and printers). • As an interchange format. This chapter contains some basic ideas that are essential to understand- ing the problems the PostScript language is designed to solve and the environments in which it is designed to operate. Terminology intro- duced here appears throughout the manual. 2.1 Raster Output Devices Much of the power of the PostScript language derives from its ability to This class encom- raster output devices. deal with the general class of passes such technology as laser, dot-matrix, and ink-jet printers, digital phototypesetters, and raster scan displays. The defining property of a raster output device is that a printed or dis- pixels played image consists of a rectangular array of dots, called (pic- ture elements), that can be addressed individually. On a typical black and white output device, each pixel can be made either black or white. On certain devices, each pixel can be set to an intermediate shade of 11

20 PLRM 2nd Edition January 21, 1994 Basic Ideas gray or to some color. By individually setting the colors of many pixels, one can generate printed or displayed output that includes text, arbi- trary graphical shapes, and reproductions of sampled images. of a raster output device is a measure of the number of The resolution pixels per unit of distance along the two linear dimensions. Resolution is typically—but not necessarily—the same horizontally and vertically. Manufacturers’ decisions on device technology and price/performance trade-offs create characteristic ranges of resolution: • Displays in computer terminals have relatively low resolution, typi- cally 50 to 110 pixels per inch. • Dot-matrix printers generally range from 100 to 250 pixels per inch. • Laser scanning coupled to xerographic printing technology is capa- ble of medium resolution output of 300 to 600 pixels per inch. • Photographic technology permits high resolutions of 1,000 pixels per inch or more. Higher resolution yields better quality and fidelity of the resulting out- put, but is achieved at greater cost. 2.2 Scan Conversion An abstract graphical entity (for example, a line, a circle, a text charac- ter, or a sampled image) is rendered on a raster output device by a pro- cess known as scan conversion . Given a PostScript language description of the graphical entity, this process determines which pixels to adjust and what values to assign those pixels to achieve the most faithful ren- dition possible at the device resolution. The pixels on the page can be represented by a two-dimensional array of pixel values in computer memory. For an output device whose pixels can be only black or white, a single bit suffices to represent each pixel. For a device whose pixels can reproduce gray shades or colors, multiple bits per pixel are required. Note Although the ultimate representation of a printed or displayed page is logically a complete array of pixels, its actual representation in computer memory need not consist of one memory cell per pixel. Some implementations 12 Chapter 2: Basic Ideas

21 PLRM 2nd Edition January 21, 1994 Basic Ideas use other representations, such as display lists. The PostScript language’s imaging model has been carefully designed so as not to depend on any particular representation of raster memory. For each graphical entity that is to appear on the page, the scan con- verter sets the values of the corresponding pixels. When the interpreta- tion of the page description is complete, the pixel values in memory represent the appearance of the page. At this point, a raster output pro- cess can make this representation visible on a printed page or a display. Scan converting a graphical shape, such as a rectangle or a circle, involves determining which device pixels lie “inside” the shape and set- ting their values appropriately (for example, by setting them to black). Because the edges of a shape do not always fall precisely on the bound- aries between pixels, some policy is required for deciding which pixels along the edges are considered to be “inside.” Scan converting a text character is conceptually the same as scan converting an arbitrary graphical shape; however, characters are much more sensitive to legibil- ity requirements, and must meet more rigid objective and subjective measures of quality. Rendering gray-scale images on a device whose pixels can be only black halftoning . The array or white is accomplished by a technique known as of pixels is divided into small clusters according to some pattern (called the halftone screen ). Within each cluster, some pixels are set to black and some to white in proportion to the level of gray desired at that point in the image. When viewed from a sufficient distance, the individual dots become unnoticeable and the result is a shade of gray. This enables a black-and-white raster output device to reproduce shades of gray and to approximate natural images, such as photographs. Some color devices use a similar technique. 2.3 Page-Description Languages Theoretically, an application program could describe any page as a full- page pixel array. But this would be unsatisfactory because the descrip- tion would be bulky, the pixel array would be device dependent, and memory requirements would be beyond the capacity of many personal computers. A page-description language should produce files that are relatively compact for storage and transmission, and independent of any one out- put device. 2.3 Page-Description Languages 13

22 PLRM 2nd Edition Basic Ideas January 21, 1994 2.3.1 Levels of Description In today’s computer printing industry, raster output devices with differ- ent properties are proliferating, as are the applications that generate output for those devices. Meanwhile, expectations are also rising; type- writer emulation (text-only output in a single typeface) is no longer adequate. Users want to create, display, and print documents that com- bine sophisticated typography and graphics. A high-level, device-independent page-description language that can take advantage of the capabilities of different output devices answers the need for high-quality output on many different printers and dis- plays. Ideally, such a language should be able to describe the appear- ance of pages containing text and graphics in terms of high-level, abstract graphical entities rather than in terms of device pixels. Such a description is economical and device independent . Producing printed output from an application program then becomes a two-stage process: 1. The application generates a device-independent description of the desired output in the page-description language. 2. A program controlling a specific raster output device interprets the description and renders it on that device. The two stages may be executed in different places and at different times; the page-description language serves as an interchange standard for transmission and storage of printable or displayable documents. 2.3.2 Static versus Dynamic Formats Today’s page-description languages may be considered on the basis of or their intrinsic capabilities and on whether they are static dynamic . Intrinsic capabilities include the built-in operations of the language, such as the ability to deal with various sorts of text and graphics. Also, the degree to which the built-in operations interact harmoniously is important. A page-description language that treats text, graphical shapes, and sampled images consistently facilitates applications that must combine elements of all three on a single page. •A static format provides some fixed set of operations (sometimes called “control codes”) and a syntax for specifying the operations and their arguments. Static formats have been in existence since computers first used printers; classic examples are format control 14 Chapter 2: Basic Ideas

23 PLRM 2nd Edition January 21, 1994 Basic Ideas codes for line printers and “format effector” codes in standard char- acter sets. Historically, static formats have been designed to capture the capabilities of a specific class of printing device and have evolved to include new features as needed. allows much more flexibility than a static format. •A dynamic format The operator set may be extensible and the exact meaning of an operator may not be known until it is actually encountered. A page described in a dynamic format is a program to be executed rather than data to be consumed. Dynamic page-description languages con- tain elements of programming languages, such as procedures, vari- ables, and control constructs. A print or display format that is primarily static but that purports to cover a lot of graphic and text capabilities tends to have many special- purpose operators. A dynamic format that allows primitive operations to be combined according to the needs of the application will always be superior to a static format that tries to anticipate all possible needs. The PostScript language design is dynamic. The language includes a set of primitive graphic operators that can be combined to describe the appearance of any printed or displayed page. It has variables and allows arbitrary computations while interpreting the page description. It has a rich set of programming language control structures for combining its elements. For very complicated page layouts, there may be times when a page description must depend on information about the specific output device in use. This information may be known only when the page description is executed, not when it is composed. It is essential for a page description to be able to read information from its execution envi- ronment and to perform arbitrary computations based on that informa- tion while generating the desired output. These considerations have led to the design of the PostScript language, a dynamic format whose page descriptions are programs to be executed by an interpreter. PostScript language programs can be simplified to a form that resembles a static format—in other words, an uninterrupted sequence of basic commands to image text or graphics. Page descrip- tions generated by applications with simple needs will often have this simple nature. However, when the need arises, the power is there for the knowledgeable application designer to exploit. 2.3 Page-Description Languages 15

24 PLRM 2nd Edition January 21, 1994 Basic Ideas 2.4 Using the PostScript Language It is important to understand the PostScript interpreter and how it interacts with applications using it. A page description is a self-contained PostScript language description of a document, which is generated at one time for execution at some arbi- trarily later time. To facilitate document interchange, a page description should conform to the structuring conventions discussed below. An interactive session is a two-way interaction between an application program and a PostScript interpreter. There is no notion that the infor- mation being communicated represents a document to be preserved for later execution. A session has no obvious overall structure; the structur- ing conventions do not apply. 2.4.1 The Interpreter controls the actions of the output device interpreter The PostScript according to the instructions provided in the PostScript program gener- ated by an application. The interpreter executes the page description and produces output on a printer, display, or other raster device. The PostScript interpreter and the output device are bundled together and treated essentially as a black box by the application; the interpreter has little or no direct inter- action with the application’s end user. There are three ways the PostScript interpreter and the application interact (Figure 2.1 on page 17 illustrates these scenarios): • In the traditional PostScript printer model, the application creates a page description. The page description can be sent to the PostScript interpreter immediately or stored for transmission at some other time. The interpreter consumes a sequence of page descriptions as “print jobs” and produces the requested output. The output device is typically a printer, but it can be a preview window on a workstation’s display. The PostScript interpreter is often implemented on a dedi- cated processor that has direct control over the raster output device. • In the display model, an application interacts with the PostScript interpreter controlling a display or windowing system. The interac- session tion consists of a instead of a one-way transmission of a page description. In response to user actions, the application issues com- 16 Chapter 2: Basic Ideas

25 PLRM 2nd Edition Basic Ideas January 21, 1994 mands to the PostScript interpreter and sometimes reads informa- tion back from it. This form of interaction is supported by the Display PostScript system, described in Chapter 7. • In the interactive programming language model, a programmer interacts with the PostScript interpreter directly, issuing PostScript language commands for immediate execution. Many PostScript interpreters (for both printers and displays) have a rudimentary interactive executive to support this mode of use; see section 2.4.4, “Using the Interpreter Interactively.” Figure 2.1 How the PostScript interpreter and an application interact 1) Traditional PostScript printer model page PostScript Printer or Application interpreter preview device description 2) Display PostScript model Interactive PostScript Application interpreter display session 3) Interactive programming language model PostScript Any Human device interpreter programmer session Even when a PostScript interpreter is being used non-interactively to execute page descriptions prepared previously, there may be some dynamic interactions between the print manager or spooler and the PostScript interpreter. For example, the sender may ask the PostScript interpreter if certain fonts referenced by a document are available. This is accomplished by sending the interpreter a short program to read and return the information. The PostScript interpreter makes no distinction between a page description and a program that makes environmental queries or performs other arbitrary computations. To ensure consistent and reliable behavior in a variety of system environments, queries should conform to the conventions described in Appendix G. 17 2.4 Using the PostScript Language

26 PLRM 2nd Edition January 21, 1994 Basic Ideas 2.4.2 Program Structure A well-structured PostScript language page description generally con- sists of two parts: a prolog followed by a script. There is nothing in the PostScript language that formally distinguishes the prolog from the script or imposes any overall document structure. Such structuring is merely a convention, but one that is quite useful and is recommended for most applications. prolog is a set of application-specific procedure definitions that • The an application may use in the execution of its script. It is included as the first part of every PostScript language file generated by the appli- cation. It contains definitions that match the output functions of the application with the capabilities supported by the PostScript lan- guage. is generated automatically by the application program to • The script describe the specific elements of the pages being produced. It con- sists of references to PostScript operators and to procedure defini- tions in the prolog, together with operands and data. The script, unlike the prolog, is usually very stylized, repetitive, and simple. Dividing a PostScript language program into a prolog and a script reduces the size of each page description and minimizes data communi- cation and disk storage. An example may help explain the purpose of a separate prolog and script. One of the most common tasks in a Post- Script language program is placing text at a particular location on the current page. This is really two operations: “moving” the current point to a specific location and “showing” the text. A program is likely to do this often, so it’s useful for the prolog to define a procedure that com- bines the operations: /ms {moveto show} bind def Later, the script can call the “ms” procedure instead of restating the individual operations: (some text) 100 200 ms The script portion of a printable document ordinarily consists of a sequence of separate pages. The description of an individual page should stand by itself, depending only on the definitions in the prolog and not on anything in previous pages of the script. The language includes facilities (described in section 3.7, “Memory Management”) that may be used to guarantee page independence. 18 Chapter 2: Basic Ideas

27 PLRM 2nd Edition January 21, 1994 Basic Ideas Adobe has established conventions to make document structure explicit. These document structuring conventions appear in Appendix G. Document structure is expressed as PostScript language comments; the interpreter pays no attention to them. However, there are good rea- sons to adhere to the conventions: • Utility programs can operate on structured documents in various ways: change the order of pages, extract subsets of pages, embed individual pages within other pages, and so on. • Print managers and spoolers can obtain useful information from a properly structured document to determine how the document should be handled. • The structuring conventions serve as a good basis for organizing printing from an application. An application has its own model of the appearance of printable output that it generates. Some parts of this model are fixed for an entire docu- ment or for all documents; the application should incorporate their descriptions into the prolog. Other parts vary from one page to another; the application should produce the necessary descriptions of these as they appear. At page boundaries, the application should gener- ate commands to restore the standard environment defined by the pro- log and then explicitly re-establish non-standard portions of the environment for the next page. This technique ensures that each page is independent of any other. 2.4.3 Translating From Other Print Formats Many existing applications generate printable documents in some other print file format or in some intermediate representation. It is pos- sible to print such documents by translating them into PostScript lan- ® guage page descriptions. For example, Adobe’s TranScript software package translates documents from a number of widely-used represen- ® tations in the UNIX environment into the PostScript language. Implementing a translator is often the least expensive way to interface an existing application to a PostScript printer. Unfortunately, while such translation is usually straightforward, a translator may not be able to generate page descriptions that make the best use of the descriptive capabilities of the PostScript language. This is because the print file being translated often describes the desired results at a level that is too low; any higher-level information maintained by the original applica- tion has been lost and is not available to the translator. 2.4 Using the PostScript Language 19

28 PLRM 2nd Edition January 21, 1994 Basic Ideas While direct PostScript language output from applications is most desir- able, translation from another print format may be the only choice available for some applications. A translator should do the best it can to produce output that conforms to the document structuring conven- tions (see Appendix G). This ensures that such output is compatible with the tools for manipulating PostScript page descriptions. Once again, these guidelines for program structure are not part of the PostScript language and are not enforced by the PostScript interpreter. In some cases, a program may require an organization that is incompat- ible with the structuring conventions; this is most likely to be true of programs composed directly by a programmer. However, for page descriptions generated automatically by applications, adherence to the structuring conventions is strongly recommended. 2.4.4 Using the Interpreter Interactively Normally, the interpreter executes PostScript language programs gener- ated by application programs; a user does not interact with the Post- Script interpreter directly. However, many PostScript interpreters provide an interactive executive that enables a user to control the inter- preter directly. That is, from a terminal or terminal emulator connected directly to the PostScript interpreter, you can issue commands for immediate execution and control the operation of the interpreter in limited ways. This is useful for experimentation and debugging. To use the interpreter this way, you must first connect your terminal directly to the standard input and output channels of the PostScript interpreter, so characters that you type are sent directly to the inter- preter and characters that the interpreter sends appear on your termi- nal’s screen. How to accomplish this depends on the product. A typical method is to connect an ordinary character terminal (or personal com- puter running terminal emulation software) to a PostScript printer via the printer’s serial connector. Then, invoke the interactive executive by typing: executive (all lower case) followed by the return or line-feed key. The interpreter responds with a herald, such as: 20 Chapter 2: Basic Ideas

29 PLRM 2nd Edition Basic Ideas January 21, 1994 PostScript(r) Version 2001.3 Copyright (c) 1984-1990 Adobe Systems Incorporated. All Rights Reserved. PS> PS> prompt is an indication that the PostScript interpreter is wait- The ing for you to issue a command. Each time you type a complete PostScript language statement followed by return or line-feed, the interpreter executes that statement, then sends another prompt. If the statement causes the interpreter to PS> send back any output (produced by execution of the print or = opera- tors, for example), that output appears before the PS> prompt. If the statement causes an error to occur, an error message appears before the prompt; control remains in the interactive executive whereas errors PS> normally cause a job to terminate. The interactive executive provides a few simple amenities. While you are typing, the interpreter ordinarily “echoes” the typed characters—it sends them back to your terminal so you can see them. You can use the control characters in Table 2.1 to make corrections while entering a statement. Table 2.1 Control characters for the interactive executive Character Function Backspace (BS) Backs up and erases one character. Delete (DEL) Same as backspace. Control-U Erases the current line. Control-R Redisplays the current line. Control-C Aborts the entire statement and starts over. Control-C can also abort a statement that is executing and force the executive to revert to a PS> prompt. The interactive executive remains in operation until you invoke the operator or enter a channel-dependent end-of-file indication (for quit example, Control-D for a serial connection). 2.4 Using the PostScript Language 21

30 PLRM 2nd Edition January 21, 1994 Basic Ideas There are several important things you should understand about the interactive executive: • It is intended solely for direct interaction with the user; an applica- tion that is generating PostScript language programs should never invoke executive . In general, a program behaves differently when sent through the interactive executive than when executed directly by the PostScript interpreter. For example, the executive produces extraneous output such as echoes of the input characters and PS> prompts. Furthermore, a program that explicitly reads data embed- ded in the program file malfunctions if invoked via the executive, since the executive itself is interpreting the file. • The user amenities are intentionally minimal. The executive is not a full-scale programming environment; it lacks a text editor and other tools required for program development and it does not keep a record of your interactive session. The executive is useful mainly for experimenting and debugging. is not necessarily available in all PostScript interpreters. Its • executive behavior may vary among different products. 22 Chapter 2: Basic Ideas

31 PLRM 2nd Edition January 21, 1994 Language Example 1.0 lck Example 2.0 Example 3.0 Example 4.0 Example 3.0 Example 5.0 Table 3.0 Example 6.0 3 CHAPTER Figure 3.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Language Syntax, data types, and execution semantics are essential aspects of any PostScript language program. Later chapters document the graphics and font capabilities that specialize PostScript language software to the task of controlling the appearance of a printed page or controlling an inter- active session on the screen. This chapter is concerned with explaining the PostScript language as a language. programming As with all programming languages, the PostScript language builds on elements and ideas from several of the great programming languages. The syntax most closely resembles that of the programming language notation in which operators are pre- FORTH. It incorporates a postfix ceded by their operands. The number of special characters is small and there are no reserved words. Although the number of built-in operators is large, the names that represent Note operators are not reserved by the language. A PostScript language program may change the meanings of operator names. The data model includes elements, such as numbers, strings, and arrays, that are found in many modern programming languages. It also includes the ability to treat programs as data and to monitor and con- trol many aspects of the language’s execution state; these notions are derived from programming languages such as LISP. PostScript is a relatively simple language. It derives its power from the ability to combine these features in unlimited ways without arbitrary restrictions. Though you may seldom fully exploit this power, you can design sophisticated graphical applications that would otherwise be dif- ficult or impossible. Because this is a reference manual and not a tutorial, this chapter describes each aspect of the language systematically and thoroughly before moving on to the next. It begins with a brief overview of the 23

32 PLRM 2nd Edition January 21, 1994 Language PostScript interpreter. The following sections detail the syntax, data types, execution semantics, memory organization, and general-purpose operators of the PostScript language—excluding those that deal with graphics and fonts. The final sections cover file input and output, named resources, errors, how the interpreter evaluates name objects, and details on binary encodings and filtered files. 3.1 Interpreter The PostScript interpreter executes the PostScript language according to the rules in this chapter. These rules determine the order in which oper- ations are carried out and how the pieces of a PostScript language pro- gram fit together to produce the desired results. objects . Some The interpreter manipulates entities called PostScript objects are data, such as numbers, booleans, strings, and arrays. Other objects are elements of programs to be executed, such as names, opera- tors, and procedures. However, there is not a distinction between data and programs; any PostScript object may be treated as data or be exe- cuted as part of a program. The interpreter operates by executing a sequence of objects. The effect of executing a particular object depends on that object’s , attributes type , value . For example, executing a number object causes the inter- and preter to push a copy of that object on the operand stack (to be described shortly). Executing a name object causes the interpreter to look up the name in a dictionary, fetch, and execute the associated value. Executing an operator object causes the interpreter to perform a built-in action, such as adding two numbers or painting characters in raster memory. The objects to be executed by the interpreter come from two principal sources: • A character stream may be scanned according to the syntax rules of the PostScript language, producing a sequence of new objects. As each object is scanned, it is immediately executed. The character stream may come from an external source, such as a file or a commu- nication channel, or it may come from a string object previously stored in the PostScript interpreter’s memory. • Objects previously stored in an array in memory may be executed in . procedure sequence. Such an array is known as a 24 Chapter 3: Language

33 PLRM 2nd Edition January 21, 1994 Language The interpreter can switch back and forth between executing a proce- dure and scanning a character stream. For example, if the interpreter encounters a name in a character stream, it executes that name by look- ing it up in a dictionary and retrieving the associated value. If that value is a procedure object, the interpreter suspends scanning the char- acter stream and begins executing the objects in the procedure. When it reaches the end of the procedure, it resumes scanning the character execution stack for stream where it left off. The interpreter maintains an remembering all of its suspended execution contexts. 3.2 Syntax As the interpreter scans the text of a PostScript language program, it cre- ates various types of PostScript objects, such as numbers, strings, and syntactic representation of procedures. This section discusses only the such objects. Their internal representation and behavior are covered in section 3.3, “Data Types and Objects.” There are three encodings for the PostScript language: ASCII , binary token . The ASCII encoding is preferred for binary object sequence , and expository purposes (such as this manual), for archiving documents, and for transmission via communications facilities because it is easy to read and does not rely on any special characters that might be reserved for communications use. The two binary encodings are usable in con- trolled environments to improve efficiency of representation or execu- tion; they are intended exclusively for machine generation. There is detailed information on the binary encodings in section 3.12, “Binary Encoding Details,” at the end of this chapter. 3.2.1 Scanner The PostScript language differs from most other programming lan- guages in that it does not have any syntactic entity for a “program,” nor is it necessary for an entire “program” to exist in one place at one time. PostScript has no notion of “reading in” a program before executing it. Instead, the PostScript interpreter consumes a program by reading and executing one syntactic entity at a time. From the interpreter’s point of view, the program has no permanent existence. Execution of the pro- gram may have side effects in the interpreter’s memory or elsewhere. These side effects may include the creation of procedure objects in memory that are intended to be invoked later in the program; their exe- . deferred cution is 3.2 Syntax 25

34 PLRM 2nd Edition Language January 21, 1994 It is not correct to think the PostScript interpreter “executes” the char- acter stream directly. Rather, a scanner groups characters into tokens according to the PostScript language syntax rules. It then assembles one object —in other words, a data or more tokens to create a PostScript value in the interpreter’s memory. Finally, the interpreter executes the object. For example, when the scanner encounters a group of consecutive dig- its surrounded by spaces or other separators, it assembles the digits into a token and then converts the token into a number object represented internally as a binary integer. The interpreter then executes this number object; in this case, it pushes a copy of the number object on the oper- and stack. 3.2.2 ASCII Encoding The standard character set for ASCII-encoded PostScript language pro- grams is the printable subset of the ASCII character set, plus the charac- ters space , tab , and newline (return or line-feed). ASCII is the American Standard Code for Information Interchange, a widely used convention for encoding characters as binary numbers. ASCII encoding does not prohibit the use of characters outside this set, but such use is not rec- ommended because it impairs portability and may make transmission and storage of PostScript language programs more difficult. Note Control characters are often usurped by communications functions. Control codes are device dependent—not part of the PostScript language. For example, the serial communications protocol supported by many products uses the Control-D character as an end-of-file indication. In such cases, Control-D is a communications function and should not be part of a PostScript language program. Table 3.1 Characters treated as white space Octal Hex Decimal Name 000 00 0 Null (nul) 09 011 9 Tab (tab) 012 10 Line-feed (LF) 0A 014 0C 12 Form-feed (FF) 015 0D 13 Carriage-return (CR) Space (SP) 32 040 20 26 Chapter 3: Language

35 PLRM 2nd Edition Language January 21, 1994 White-space characters separate other syntactic constructs such as names and numbers from each other. The interpreter treats any number of consecutive white space characters as if there were just one. All white-space characters are equivalent, except in comments and strings. The characters carriage-return (CR) and line-feed (LF) are also called newline characters. A CR followed immediately by an LF are treated together as one newline. are special. They delimit syn- The characters ( , ) % < , > , [ , ] , { , } , / , and , tactic entities such as strings, procedure bodies, name literals, and com- ments. Any of these characters terminates the entity preceding it and is not included in the entity. All characters besides the white-space characters and delimiters are referred to as regular characters. These include non-printing characters that are outside the recommended PostScript ASCII character set. Comments Any occurrence of the character % outside a string introduces a com- ment . The comment consists of all characters between the % and the next newline or form-feed, including regular, delimiter, space, and tab characters. The scanner ignores comments, treating each one as if it were a single white-space character. That is, a comment separates the token preced- ing it from the one following. Thus, the ASCII-encoded program frag- ment abc% comment {/%) blah blah blah 123 is treated by the scanner as just two tokens: abc and 123 . Numbers Numbers in the PostScript language include signed integers, such as 123 –98 43445 0 +17 reals, such as –.002 34.5 –3.62 123.6e10 1E–5 –1. 0.0 3.2 Syntax 27

36 PLRM 2nd Edition Language January 21, 1994 and radix numbers, such as 8#1777 16#FFFE 2#1000 An integer consists of an optional sign followed by one or more decimal digits. The number is interpreted as a signed decimal integer and is con- verted to an integer object. If it exceeds the implementation’s limit for integers, it is converted to a real object (see Appendix B). A real consists of an optional sign and one or more decimal digits, with an embedded period (decimal point), a trailing exponent, or both. The E or e followed by an optional sign and exponent, if present, consists of one or more decimal digits. For example, the following numbers are legal reals: 1E6 1.0E6 1.0E–6 The number is interpreted as a real and is converted to a real (floating point) object. If it exceeds the implementation limit for reals, a limitcheck error occurs. A radix number takes the form base#number , where base is a decimal integer in the range 2 through 36. The number is then interpreted in this base; it must consist of digits ranging from 0 to base – 1. Digits a through greater than 9 are represented by the letters A through Z (or z ). The number is treated as an unsigned integer and is converted to an integer object. This notation is intended for specifying integers in a non-decimal radix, such as binary, octal, or hexadecimal. If the number exceeds the implementations limit for integers, a limitcheck error occurs. Strings There are three conventions for quoting a literal string object: • As literal text enclosed in ( and ) . > • As hexadecimal encoded data enclosed in < and . ). and ~> ( Level 2 only <~ • As ASCII base-85 encoded data enclosed in A literal text string consists of an arbitrary number of characters enclosed in ( and ) . Any characters may appear in the string other than , which must be treated specially. Balanced pairs of parenthe- ( , ) , and \ ses in the string require no special treatment. 28 Chapter 3: Language

37 PLRM 2nd Edition Language January 21, 1994 The following lines show several valid strings: (This is a string) (Strings may contain newlines and such.) (Strings may contain special characters *–&}^% and balanced parentheses ( ) (and so on).) (The following is an "empty" string.) ( ) (It has 0 (zero) length.) Within a text string, the \ (backslash) character is treated as an “escape” for various purposes, such as including unbalanced parentheses, non- printing characters, and the \ character itself. The character immedi- ately following the determines its precise interpretation. \ \n line-feed (LF or newline) \r carriage return (CR) \t horizontal tab \b backspace \f form-feed \\ backslash \( left parenthesis \) right parenthesis \ ddd character code ddd (octal) If the character following the \ is not in the preceding list, the scanner ignores the \. If the \ is followed immediately by a newline (CR, LF, or CR LF pair), the scanner ignores both the initial \ and the newline. But if a newline appears without a preceding , the result is equivalent to \ \n . For more information about end-of-line conventions, see section 3.8, “File Input and Output.” The \ newline combination breaks a string into multiple lines but with- out including the newline characters as part of the string, as in the fol- lowing examples: (These\ two strings\ are the same.) (These two strings are the same.) (This string has a newline at the end of it. ) (So does this one.\n) 3.2 Syntax 29

38 PLRM 2nd Edition Language January 21, 1994 \ form may be used to include any 8-bit character constant in a The ddd string. One, two, or three octal digits may be specified with high-order overflow ignored. This notation is preferred for specifying a character outside the recommended ASCII character set for the PostScript lan- guage, since the notation itself stays within the standard set and thereby avoids possible difficulties in transmitting or storing the text of the program. There are two other conventions for representing arbitrary data as ASCII text: the hexadecimal (base 16) encoding and the ASCII base-85 encoding. A hexadecimal string consists of a sequence of hex characters (the digits 0 through 9 and the letters A ) enclosed within F or a through f through . Each pair of hex digits defines one character of the string. If the > < and final digit of a given string is missing—in other words, if there is an odd number of digits—the final digit is assumed to be zero. White-space characters are ignored. For example, <901fa3> is a three-character string containing the characters whose hex codes are 90, 1f, and a3. But <901fa> is a three-character string containing the characters whose hex codes are 90, 1f, and a0. Hexadecimal strings are useful for including arbitrary binary data as literal text. An ASCII base-85 encoded string ( Level 2 only ) consists of a sequence of printable ASCII characters enclosed in <~ and ~>. This represents arbi- trary binary data using an encoding technique that produces a 4:5 expansion as opposed to the 1:2 expansion for hexadecimal. If a hexa- decimal or ASCII base-85 string is malformed, a occurs. The syntaxerror ASCII base-85 encoding algorithm is described under ASCII85Encode in section 3.13, “Filtered Files Details.” Names Any token that consists entirely of regular characters and cannot be interpreted as a number is treated as a name object (more precisely, an name). All characters except delimiters and white space can executable appear in names, including characters ordinarily considered to be punc- tuation. 30 Chapter 3: Language

39 PLRM 2nd Edition January 21, 1994 Language The following are examples of valid names: abc Offset $$ 23A 13-456 a.b $MyDict @pattern Use care when choosing names that begin with digits. For example, is a valid name, 23E1 while 23#1 is a radix 23A is a real number, and number token that represents an integer. / (slash— not backslash) introduces a literal A name. The slash is not part of the name itself, but is a prefix indicating that the following name is a / literal. There can be no white space between the and the name. The // (two slashes) introduce an immediately evaluated name characters . The important properties and uses of names, and the distinction between executable and literal names are described in section 3.3, “Data Types and Objects”; immediately evaluated names are discussed in section 3.11.2, “Immediately Evaluated Names.” Arrays and are self-delimiting tokens that specify the con- The characters [ ] struction of an array. The program fragment [ 123 /abc (xyz) ] results in the construction of an array object containing the integer 123 , the literal name object abc xyz object . Each , and the string object token within [ ] is executed in turn. [ and ] are special syntax for names that, when executed, invoke Post- Script language operators that collect objects and construct an array containing them. Thus, the example [ 123 /abc (xyz) ] really contains the five tokens described below: • The name object [ . • The integer object 123 . • The literal name object abc . • The string object xyz . ] . • The name object 3.2 Syntax 31

40 PLRM 2nd Edition January 21, 1994 Language When the example is executed, a sixth object (the array) results from executing the ] name objects. [ and Procedures , otherwise The special characters delimit an executable array and { } procedure . The syntax is superficially similar to that for the known as a [ and ] ; however, the semantics are entirely array construction operators scanning different and arise as a result of exe- the procedure rather than it. cuting Scanning the program fragment {add 2 div} produces a single procedure object that contains the name object add , 2 the integer object div . When the scanner , and the name object encounters the initial { , it continues scanning and creating objects, but the interpreter does not execute them. When the scanner encounters into a { the matching } , it puts all of the objects created since the initial new executable array (procedure) object. The interpreter does not execute a procedure immediately, but treats it as data; it pushes the procedure on the operand stack. Only when the procedure is explicitly invoked (by means yet to be described) will it be executed. Execution of the procedure—and of all objects within the procedure, including any embedded procedures—has been deferred . The matter of immediate versus deferred execution is discussed in section 3.5, “Execution.” The procedure object created by { and } is either an array or a packed array, according to the current setting of a mode switch. The distinction between these types of arrays is discussed in section 3.3, “Data Types and Objects.” Dictionaries >> The special character sequences << and ( Level 2 only ) are self-delimit- ing tokens that denote the construction of a dictionary, much the same as [ and ] denote the construction of an array. They are intended to be used as follows: >> value << key ... key value value key 2 1 2 1 n n 32 Chapter 3: Language

41 PLRM 2nd Edition Language January 21, 1994 This creates a dictionary containing the bracketed key-value pairs, and pushes the dictionary on the operand stack. Dictionaries are introduced in section 3.3, “Data Types and Objects.” << and >> are merely special names for operators that, when executed, [ and cause a dictionary to be constructed. This is like the array con- ] structor operators, but unlike the { and } delimiters for procedure literals. tokens are self-delimiting, so they need not be sur- The << and >> rounded by white space or other delimiters. Do not confuse these < and > , which delimit a hexadecimal string literal, or <~ tokens with and ~> , which delimit an ASCII base-85 string literal. The << and >> tokens are objects in their own right (specifically, name objects); the are merely punctuation for the enclosed literal string < ... > and <~ ... ~> objects. 3.3 Data Types and Objects All data accessible to PostScript language programs, including proce- dures that are part of the programs themselves, exist in the form of . Objects are produced, manipulated, and consumed by the Post- objects Script operators. They are also created by the scanner and executed by the interpreter. type, some attributes, and a value . Objects contain their Each object has a own dynamic types; that is, an object’s type is a property of the object itself, not of where it is stored or what it is called. Table 3.2 lists all the object types supported by the PostScript language. Extensions to the language may introduce additional object types. The distinction between simple and composite objects is explained below. Table 3.2 Types of objects Simple objects Composite objects boolean array fontID Display PostScript ) condition ( integer dictionary mark file name gstate ( Level 2 ) null lock ( Display PostScript ) operator packedarray ( Level 2 ) real string save 3.3 Data Types and Objects 33

42 PLRM 2nd Edition Language January 21, 1994 Simple and Composite Objects 3.3.1 Objects of most types are simple, atomic entities. An atomic object is always constant—a is always 2 . There is no visible substructure in the 2 object; the type, attributes, and value are irrevocably bound together and cannot be changed. . However, objects of certain types indicated in Table 3.2 are composite Their values have internal substructure that is visible and can some- times be modified selectively. The details of the substructures are pre- sented later in the descriptions of these individual types. An important distinction between simple and composite objects is the behavior of operations that copy objects. Copy refers to any operation that transfers the contents of an object from one place to another in the memory of the PostScript interpreter. “Fetching” and “storing” objects are copying operations. It is possible to derive a new object by copying an existing one, perhaps with modifications. When a simple object is copied, all of its parts (type, attributes, and value) are copied together. When a composite object is copied, the share the value is not copied; instead, the original and copy objects same value. Consequently, any changes made to the substructure of one object’s value also appear as part of the other object’s value. The sharing of composite objects’ values in the PostScript language cor- responds to the use of pointers in system-programming languages such as C and Pascal. Indeed, the PostScript interpreter uses pointers to implement shared values: a composite object contains a pointer to its value. However, the PostScript language does not have any explicit notion of a pointer. It is better to think in terms of the copying and sharing notions presented here. The values of simple objects are contained in the objects themselves. The values of composite objects reside in a special region of memory . Section 3.7, “Memory Management,” called virtual memory or VM describes the behavior of VM. 3.3.2 Attributes of Objects . In addition to type and value, each object has one or more attributes These attributes affect the behavior of the object when it is executed or when certain operations are performed on it. They do not affect its 34 Chapter 3: Language

43 PLRM 2nd Edition January 21, 1994 Language behavior when it is treated strictly as data; so, for example, two integers with the same value are considered “equal” even if their attributes differ. Literal and Executable literal or executable Every object is either . This distinction comes into play when the interpreter attempts to execute the object. • If the object is literal , the interpreter treats it strictly as data and pushes it on the operand stack for use as an operand of some subse- quent operator. • If the object is , the interpreter executes it. executable What it means to execute an object depends on the object’s type. This is described in section 3.5, “Execution.” For some types of objects, such as integers, execution consists of pushing the object on the operand stack; the distinction between literal and executable integers is meaningless. But for other types, such as names, operators, and arrays, execution consists of performing a different action. • Executing an executable name causes it to be looked up in the current dictionary context and the associated value to be executed. executable operator • Executing an causes some built-in action to be performed. executable array (otherwise known as a procedure) • Executing an causes the elements of the array to be executed in turn. As described in section 3.2, “Syntax,” some tokens produce literal objects and some produce executable ones. • Integer, real, and string constants are always literal objects. • Names are literal if they are preceded by / and executable if they are not. and • The [ ] operators, when executed, produce a literal array object with the enclosed objects as elements. Likewise, << and >> ( Level 2 only ) produce a literal dictionary object. enclose an executable array or procedure. } • { and 3.3 Data Types and Objects 35

44 PLRM 2nd Edition Language January 21, 1994 As mentioned above, it doesn’t matter whether an object is literal or Note executable when it is accessed as data, only when it is executed. However, referring to an executable object by name often causes that object to be executed automatically; see section 3.5.5, “Execution of Specific Types.” To avoid unintended behavior, it’s best to use the executable attribute only for objects that are meant to be executed, such as procedures. Access The other attribute of an object is its access . Only composite objects have access attributes, which restrict the set of operations that can be performed on the value of an object. There are four values of access. In increasing order of restriction, they are: 1. Unlimited . Normally, objects have unlimited access: all operations defined for that object are allowed. However, packed array objects always have read-only (or even more restricted) access. . An object with read-only access may not have its value Read-only 2. written, but may still be read or executed. 3. . An object with execute-only access may not have its Execute-only value either read or written, but may still be executed by the Post- Script interpreter. None . An object with no access may not be operated on in any way 4. by a PostScript language program. Such objects are not of any direct use to PostScript language programs, but serve internal purposes that are not documented in this manual. The literal/executable distinction and the access attribute are entirely independent, although there are combinations that are not of any prac- tical use (for example, a literal array that is execute-only). With one exception, attributes are properties of an object itself and not of its value . Two composite objects can share the same value but have different literal/executable or access attributes. The exception is the dic- tionary type: A dictionary’s access attribute is a property of the value, so multiple dictionary objects sharing the value have the same access attribute. 36 Chapter 3: Language

45 PLRM 2nd Edition Language January 21, 1994 3.3.3 Integer and Real The PostScript language provides two types of numeric objects: integer and real . Integer objects represent mathematical integers within a cer- tain interval centered at zero. Real objects approximate mathematical real numbers within a much larger interval but with limited precision. They are implemented as floating-point numbers. Most PostScript arithmetic and mathematical operators can be applied to numbers of both types. The interpreter performs automatic type con- version when necessary. Some operators expect only integers or a sub- range of the integers as operands. There are operators to convert from one data type to another explicitly. Throughout this manual, number means an object whose type is either integer or real. The range and precision of numbers is limited by the internal represen- tations used in the machine on which the PostScript interpreter is run- ning. Appendix B gives these limits for typical implementations of the PostScript interpreter. Note The machine representation of integers is accessible to a PostScript language program through the bitwise operators. However, the representation of integers may depend on the CPU architecture of the implementation. The machine representation of reals is not accessible to PostScript language programs. Boolean 3.3.4 The PostScript language provides boolean objects with values true and false for use in conditional and logical expressions. Booleans are the results of the relational (comparison) and logical operators. Various other operators also return them as status information. Booleans ifelse if and . The mainly are used as operands for the control operators names and false are associated with the two values of this type. true 3.3.5 Array An array is a one-dimensional collection of objects accessed by a numeric index. Unlike arrays in many other computer languages, Post- Script language arrays may be heterogeneous; that is, an array’s ele- ments may be any combination of numbers, strings, dictionaries, other procedure arrays, or any other objects. A is an array that may be executed by the PostScript interpreter. 3.3 Data Types and Objects 37

46 PLRM 2nd Edition January 21, 1994 Language All arrays are indexed from zero, so an array of n elements has indices from 0 through n − 1. All accesses to arrays are bounds-checked, and a rangecheck reference with an out-of-bounds index results in a error. The PostScript language directly supports only one-dimensional arrays. Arrays of higher dimension may be constructed by using arrays as ele- ments of arrays, nested to any arbitrary depth. As discussed earlier, an array is a composite object. When an array object is copied, the value is not copied. Instead, the old and new objects share the same value. Additionally, there is an operator ) that creates a new array object whose value is a subinterval ( getinterval of an existing array; the old and new objects share the array elements in that subinterval. Packed Array 3.3.6 A packed array is a more compact representation of an ordinary array, intended primarily for use as a procedure. A packed array object is dis- tinct from an ordinary array object, but in most respects it behaves the same as an ordinary array. Its principal distinguishing feature is that it occupies much less space in memory (see section B.2, “Virtual Memory Use”). Throughout this manual, any mention of a procedure may refer to either an executable array or an executable packed array. The two types of arrays are not distinguishable when they are executed, only when they are treated as data. See the introduction to the array operators in section 3.6, “Overview of Basic Operators.” 3.3.7 String A string is similar to an array, but its elements must be integers in the range 0 to 255. The string elements are not integer objects, but are stored in a more compact format. However, the operators that access string elements accept or return ordinary integer objects with values in the range 0 to 255. String objects are conventionally used to hold text, one character per string element. However, the PostScript language does not have a dis- tinct “character” syntax or data type and does not require that the inte- ger elements of a string encode any particular character set. String objects may also be used to hold arbitrary binary data. 38 Chapter 3: Language

47 PLRM 2nd Edition Language January 21, 1994 To enhance program portability, strings appearing literally as part of a PostScript language program should be limited to characters from the printable ASCII character set, with other characters inserted by means of the \ddd escape convention (see section 3.2, “Syntax”). ASCII text strings are fully portable; ASCII base-85 text strings are fully portable among Level 2 implementations. Like an array, a string is a composite object. Copying a string object or creating a subinterval (substring) results in sharing the string’s value. Name 3.3.8 A name is an atomic symbol uniquely defined by a sequence of charac- ters. Names serve the same purpose as “identifiers” in other program- ming languages: as tags for variables, procedures, and so on. However, PostScript language names are not just language artifacts, but are first- class data objects, similar to “atoms” in LISP. A name object is ordinarily created when the scanner encounters a PostScript token consisting entirely of regular characters, perhaps pre- , as described in section 3.2, “Syntax.” However, a name may ceded by / also be created by explicit conversion from a string; so there is no restriction on the set of characters that can be included in names. simple object not made up of other objects. Unlike a string, a name is a Although a name is defined by a sequence of characters, those charac- ters are not “elements” of the name. A name object, although logically simple, does have an invisible “value” that occupies space in VM. A name is unique . Any two name objects defined by the same sequence of characters are identical copies of each other. Name equality is based on an exact match between the corresponding characters defining each name. This includes the case of letters, so the names A are differ- and a ent. Literal and executable objects can be equal, however. The interpreter can inexpensively determine whether two existing name objects are equal or unequal without comparing the characters that define the names. This makes names useful as keys in dictionaries. Names do not have values, unlike variable or procedure names in other with values programming languages. However, names can be associated in dictionaries. 3.3 Data Types and Objects 39

48 PLRM 2nd Edition Language January 21, 1994 Dictionary 3.3.9 A is an associative table whose elements are pairs of PostScript dictionary objects. The first element of a pair is the key and the second element is . The PostScript language includes operators that insert a key- the value value pair into a dictionary, look up a key and fetch the associated value, and perform various other operations. Keys are normally name objects; the PostScript language syntax and the interpreter are optimized for this most common case. However, a key null may be any PostScript language object except (defined later). If you attempt to use a string as a key, the PostScript interpreter will first con- vert the string to a name object; thus, strings and names are interchange- . able when used as keys in dictionaries A dictionary has the capacity to hold a certain maximum number of key-value pairs; the capacity is specified when the dictionary is created. Level 1 and Level 2 implementations of the PostScript language differ in their behavior when a program attempts to insert an entry into a dic- tionary that is full. In Level 1, a dictfull error occurs. In Level 2, the interpreter enlarges the dictionary automatically. Dictionaries ordinarily associate the names and values of a program’s components, such as variables and procedures. This corresponds to the conventional use of identifiers in other programming languages. But there are many other uses for dictionaries. For example, a PostScript language font program contains a dictionary that associates the names of characters with the procedures for drawing those characters’ shapes (see Chapter 5). There are three primary methods for accessing dictionaries: • Operators exist to access a specific dictionary supplied as an operand. current dictionary and a set of operators to access it implic- • There is a itly. • The interpreter automatically looks up executable names it encoun- ters in the program being executed. The interpreter maintains a dictionary stack defining the current dynamic name space. Dictionaries may be pushed on and popped off the dictionary stack at will. The topmost dictionary on the stack is the . current dictionary 40 Chapter 3: Language

49 PLRM 2nd Edition Language January 21, 1994 When the interpreter looks up a key implicitly—for example, when it executes a name object—it searches for the key in the dictionaries on the dictionary stack. It searches first in the topmost dictionary, then in successively lower dictionaries on the dictionary stack, until it either finds the key or exhausts the dictionary stack. In Level 1 implementations of the PostScript language, there are two built-in dictionaries permanently on the dictionary stack; they are systemdict and userdict . In Level 2 implementations, there are called . three dictionaries: systemdict , globaldict , and userdict systemdict is a read-only dictionary that associates the names of all • the PostScript operators (those defined in this manual) with their values (the built-in actions that implement them). • . This is globaldict ( Level 2 ) is a writable dictionary in global VM explained in section 3.7.2, “Local and Global VM.” • is a writable dictionary in local VM . It is the default modifi- userdict able naming environment normally used by PostScript language pro- grams. userdict is the topmost of the permanent dictionaries on the dictionary stack. The def operator puts definitions there unless the program has pushed some other dictionary on the dictionary stack. Applications can and should create their own dictionaries rather than put things in userdict . A dictionary is a composite object. Copying a dictionary object does not copy the dictionary’s contents. Instead, the contents are shared. 3.3.10 Operator An operator object represents one of the PostScript language’s built-in actions. When the object is executed, its built-in action is invoked. Most of this manual is devoted to describing the semantics of the vari- ous operators. Operators have names. Most operators are associated with names in systemdict : The names are the keys and the values are the operators. When the interpreter executes one of these names, it looks up the name in the context of the dictionary stack. Unless the name has been defined in some dictionary higher on the dictionary stack, the inter- , fetches the associated value preter finds its definition in systemdict (the operator object itself), and executes it. 3.3 Data Types and Objects 41

50 PLRM 2nd Edition Language January 21, 1994 systemdict All standard operators are defined in . However, an applica- known in tion that tests if an operator is defined should not do a systemdict where to check all dictionaries on the diction- ; it should use ary stack. This enables proper handling of operator emulations (see Appendix D). Note There are some special internal PostScript operators whose names begin with @ . These operators are not officially part of the PostScript language and are not defined in systemdict . They may appear as the “offending command” in error messages. There is nothing special about an operator name, such as add , that dis- tinguishes it as an operator. Rather, the name add is associated in systemdict with the operator for performing addition, and execution of is not a add the operator causes the addition to occur. Thus the name “reserved word,” as it might be in other programming languages. Its meaning can be changed by a PostScript language program. add Throughout this manual, the notation means “the operator object add in systemdict ” or, occasionally, in some associated with the name other dictionary. 3.3.11 File A file is a readable or writable stream of characters transferred between the PostScript interpreter and its environment. The characters in a file may be stored permanently—in a disk file, for instance—or may be gen- erated dynamically and transferred via a communication channel. A file object represents a file. There are operators to open a file and create a file object for it. Other operators access an open file to read, write, and process characters in various ways—as strings, as PostScript language tokens, as binary data represented in hexadecimal, and so on. Standard input and output files are always available to a PostScript lan- guage program. The standard input file is the usual source of programs to be interpreted; the standard output file is the usual destination of such things as error and status messages. Although a file object does not have components visible at the Post- Script language level, it is composite in the sense that all copies of a file object share the same value, namely the underlying file. If a file opera- tor has a side effect on the underlying file, such as closing it or chang- ing the current position in the stream, all file objects sharing the file are affected. 42 Chapter 3: Language

51 PLRM 2nd Edition Language January 21, 1994 The properties of files and the operations on them are described in more detail in section 3.8, “File Input and Output.” 3.3.12 Mark mark is a special object used to denote a position on the operand A stack. This use is described in the presentation of stack and array opera- tors in section 3.6, “Overview of Basic Operators.” There is only one value of type mark, created by invoking the operator mark , [ , or << . Mark objects are not legal operands for most operators. Mark objects are legal operands for ] , >> , counttomark , cleartomark , and a few generic operators such as pop and type . Null 3.3.13 The PostScript interpreter uses objects to fill empty or uninitialized null positions in composite objects when they are created. There is only one value of type null; the name null is associated with a null object in systemdict . Null objects are not legal operands for most operators. 3.3.14 Save Save objects represent snapshots of the state of the PostScript interpret- er’s memory. They are created and manipulated by the save and restore operators, introduced in section 3.7.3, “Save and Restore.” 3.3.15 Other Object Types FontIDs are special objects used in the construction of fonts; see section 5.2, “Font Dictionaries.” A gstate object represents an entire graphics state ; see section 4.2, “Graphics State.” Gstate objects are a Level 2 feature. Locks and conditions are special objects used to synchronize multiple execution contexts in a Display PostScript system; see section 7.1, “Mul- tiple Execution Contexts.” 3.4 Stacks The PostScript interpreter manages four stacks representing the execu- tion state of a PostScript language program. Three of them—the oper- and, dictionary, and execution stacks—are described here; the fourth— 3.4 Stacks 43

52 PLRM 2nd Edition Language January 21, 1994 the graphics state stack—is presented in Chapter 4. Stacks are “last-in- first-out” (LIFO) data structures. In this manual, “the stack” with no qualifier means the operand stack. • The operand stack holds arbitrary PostScript objects that are the oper- ands and results of PostScript operators being executed. When an operator requires one or more operands, it obtains them by popping them off the top of the operand stack. When an operator returns one or more results, it does so by pushing them on the operand stack. The interpreter pushes objects on the operand stack when it encoun- ters them as literal data in a program being executed. • The holds only dictionary objects. The current set of dictionary stack dictionaries on the dictionary stack defines the environment for all implicit name searches, such as those that occur when the inter- preter encounters an executable name. The role of the dictionary stack is introduced in section 3.3, “Data Types and Objects,” and is further explained in section 3.5, “Execution.” • The execution stack holds executable objects (mainly procedures and files) that are in stages of execution. At any point in the execution of of a PostScript language program, this stack represents the call stack the program. Whenever the interpreter suspends execution of an object to execute some other object, it pushes the new object on the execution stack. When the interpreter finishes executing an object, it pops that object off the execution stack and resumes executing the suspended object beneath it. The three stacks are independent and there are different ways to access each of them: • The operand stack is directly under control of the PostScript lan- guage program being executed. Objects may be pushed and popped arbitrarily by various operators. • The dictionary stack is also under control of the PostScript language program being executed. But it can hold only dictionaries, and the bottom three dictionaries (two dictionaries in Level 1 implementa- tions) on this stack— systemdict , globaldict , and userdict —cannot be popped off. The operators begin , end , and cleardictstack are the only operators that can alter the dictionary stack. • The execution stack is under the control of the interpreter. It can be read but not modified by a PostScript language program. 44 Chapter 3: Language

53 PLRM 2nd Edition Language January 21, 1994 When an object is pushed on a stack, the object is copied onto the stack from wherever it was obtained; however, in the case of a composite object (array, string, or dictionary), the object’s value is not copied on the stack, but rather is shared with the original object. Similarly, when a composite object is popped off a stack and put somewhere, only the object itself is moved, not its value. See section 3.3, “Data Types and Objects,” for more details. The maximum capacity of stacks may be limited. See Appendices B and C. 3.5 Execution Execution semantics are different for each of the various object types. Also, execution can be either immediate , occurring as soon as the object is created by the scanner, or deferred to some later time. 3.5.1 Immediate Execution Several PostScript language program fragments will help clarify the con- cept of execution. Example 3.1, “ illustrates immediate execution of a few operators and operands to perform some simple arithmetic. Example 3.1 40 60 add 2 div 40 and pushes The interpreter first encounters the literal integer object it on the operand stack. Then it pushes the integer object 60 on the operand stack. Now it encounters the executable name object add , which it looks up in the environment of the current dictionary stack. Unless add has been redefined elsewhere, the interpreter finds it associated with an operator object, which it executes. This invokes a built-in function that pops the two integer objects off the operand stack, adds them together, and pushes the result (a new integer object whose value is 100) back on the operand stack. The rest of the program fragment is similarly executed. The interpreter pushes the integer 2 on the operand stack, then it executes the name div . The div operator pops two operands off the stack (the integers whose values are 2 and 100), divides the second-to-top one by the top one (100 divided by 2, in this case), and pushes the integer result 50 on the stack. 3.5 Execution 45

54 PLRM 2nd Edition Language January 21, 1994 The source of the objects being executed by the PostScript interpreter does not matter. They may have been contained within an array or scanned in from a character stream. Executing a sequence of objects produces the same result regardless of where the objects come from. 3.5.2 Operand Order 40 In Example 3.1, “, 60 is the second operand of the is the first and add operator. That is, objects are referred to according to the order in which they are pushed on the operand stack. This is the reverse of the order in which they are popped off by the operator. Similarly, the result add pushed by the add operator is the first operand of the div operator, and the 2 is its second operand. The same terminology applies to the results of an operator. If an opera- tor pushes more than one object on the operand stack, the first object pushed is the first result. This order corresponds to the usual left-to- right order of appearance of operands in a PostScript language program. 3.5.3 Deferred Execution average that The first line of Example 3.2, “ defines a procedure named computes the average of two numbers. The second line applies that pro- 40 and 60 , producing the same result as Example cedure to the integers 3.1. Example 3.2 /average {add 2 div} def 40 60 average The interpreter first encounters the literal name average . Recall from section 3.2, “Syntax,” that / introduces a literal name. The interpreter pushes this object on the operand stack, as it would any object having the literal attribute. Next the interpreter encounters the executable array . Recall {add 2 div} (an executable array, or packed array and } enclose a procedure { that object) that is produced by the scanner. This procedure contains three elements: the executable name add , the literal integer 2 , and the exe- . The interpreter has not encountered these elements cutable name div yet. 46 Chapter 3: Language

55 PLRM 2nd Edition Language January 21, 1994 Here is what the interpreter does: 1. Upon encountering this procedure object, the interpreter pushes it on the operand stack, even though the object has the executable attribute. This is explained soon. 2. The interpreter then encounters the executable name def . Looking def up this name in the current dictionary stack, it finds to be associ- ated in systemdict with an operator object, which it invokes. 3. The def operator pops two objects off the operand stack (the proce- dure {add 2 div} and the name average ). It enters this pair into the current dictionary (most likely ), creating a new association userdict having the name average as its key and the procedure {add 2 div} as its value. 4. The interpreter pushes the integer objects 40 and 60 on the operand average . stack, then encounters the executable name 5. It looks up average in the current dictionary stack, finds it to be asso- {add 2 div} executes that procedure. In ciated with the procedure , and this case, execution of the array object consists of executing the ele- add ments of the array in sequence, namely the objects 2 , and div . , This has the same effect as executing those objects directly. It pro- duces the same result: the integer object 50 . Why did the interpreter treat the procedure as data in the first line of the example but execute it in the second, despite the procedure having the executable attribute in both cases? There is a special rule that deter- mines this behavior: An executable array or packed array encountered directly by the interpreter is treated as data (pushed onto the operand stack). But an executable array or packed array encountered indirectly — as a result of executing some other object, such as a name or an opera- tor—is invoked as a procedure. This rule reflects how procedures are ordinarily used. Procedures appearing directly (either as part of a program being read from a file or as part of some larger procedure in memory) are usually part of a defini- tion or of a construct, such as a conditional, that operates on the proce- dure explicitly. But procedures obtained indirectly—for example, as a result of looking up a name—are usually intended to be executed. A PostScript language program can override these semantics when necessary. 3.5 Execution 47

56 PLRM 2nd Edition January 21, 1994 Language Control Constructs 3.5.4 In the PostScript language, control constructs such as conditionals and iterations are specified by means of operators that take procedures as operands. Example 3.3, “ computes the maximum of the values associ- ated with the names a and , as in the steps that follow. b Example 3.3 a b gt {a} {b} ifelse a and 1. The interpreter encounters the executable names in turn and b looks them up. Assume both names are associated with numbers. Executing the numbers causes them to be pushed onto the operand stack. gt (greater than) operator removes two operands from the stack 2. The and compares them. If the first operand is greater than the second, it true . Otherwise, it pushes false . pushes the boolean value {a} , 3. The interpreter now encounters the procedure objects {b} and which it pushes onto the operand stack. ifelse operator takes three operands: a boolean and two proce- 4. The dures. If the boolean’s value is true , ifelse causes the first procedure to be executed. Otherwise, it causes the second procedure to be exe- cuted. All three operands are removed from the operand stack before the selected procedure is executed. In this example, each procedure consists of a single element that is an a executable name (either or ). The interpreter looks up this name and, b since it is associated with a number, pushes that number on the oper- and stack. So the result of executing the entire program fragment is to push on the operand stack the maximum of the values associated with b a and . 3.5.5 Execution of Specific Types treated as data—pushed on An object with the literal attribute is always the operand stack by the interpreter—regardless of its type. Even opera- tor objects are treated this way if they have the literal attribute. 48 Chapter 3: Language

57 PLRM 2nd Edition January 21, 1994 Language For many objects, executing them has the same effect as treating them as data. This is true of integer, real, boolean, dictionary, mark, save, gstate, and fontID objects. So the distinction between literal and exe- cutable objects of these types is meaningless. The following descrip- tions apply only to objects having the executable attribute. •An executable array or executable packed array (procedure) object is pushed on the operand stack if it is encountered directly by the indirectly as a result of executing some interpreter. If it is invoked other object (a name or an operator), it is called instead. The inter- preter calls a procedure by pushing it on the execution stack and then executing the array elements in turn. When the interpreter reaches the end of the procedure, it pops the procedure object off the execution stack. (Actually, it pops the procedure object when there is one element remaining and then pushes that element. This is to per- mit unlimited depth of “tail recursion” without overflowing the exe- cution stack.) object is pushed onto the execution stack. The executable string •An interpreter then uses the string as a source of characters to be con- verted to tokens and interpreted according to the PostScript lan- guage syntax rules. This continues until the interpreter reaches the end of the string, when it pops the string object from the execution stack. •An executable file object is treated much the same as a string: The interpreter pushes it on the execution stack. It reads the characters of the file and interprets them as PostScript tokens until it encounters end-of-file. Then it closes the file and pops the file object from the execution stack. See section 3.8, “File Input and Output.” executable name •An object is looked up in the environment of the current dictionary stack and its associated value is executed. The interpreter looks first in the top dictionary on the dictionary stack and then in other dictionaries successively lower on the stack. If it finds the name as a key in some dictionary, it executes the associated value. To do that, it examines the value’s type and executable attribute, and performs the appropriate action described in this sec- tion. Note that if the value is a procedure, the interpreter executes it. If the interpreter fails to find the name in any dictionary on the dic- tionary stack, an undefined error occurs. object causes the interpreter to perform one of •An executable operator the built-in operations described in this manual. 3.5 Execution 49

58 PLRM 2nd Edition Language January 21, 1994 •An executable null object causes the interpreter to perform no action (in particular, it does not push the object on the operand stack). 3.6 Overview of Basic Operators This is an overview of the general-purpose PostScript language opera- tors, excluding all operators that deal with graphics and fonts, which are described in later chapters. The organization of this section roughly parallels that of the operator summary at the beginning of Chapter 8. The information here is insufficient for actual programming; it is intended only to acquaint you with the available facilities. For com- plete information about any particular operator, you should refer to the operator’s detailed description in Chapter 8. 3.6.1 Stack Operators The operand stack is the PostScript interpreter’s mechanism for passing arguments to operators and for gathering results from operators. It was introduced in section 3.4, “Stacks.” There are various operators that rearrange or manipulate the objects on the operand stack. Such rearrangement is often required when the results of some operators are to be used as arguments to other operators that require their operands in a different order. These operators manip- ulate only the objects themselves; they do not copy the values of com- posite objects. dup duplicates an object. • exchanges the top two elements of the stack. • exch • pop removes the top element from the stack. • copy duplicates portions of the operand stack. • roll treats a portion of the stack as a circular queue. • index accesses the stack as if it were an indexable array. • mark marks a position on the stack. • clear clears the stack. count counts the number of elements in the stack. • 50 Chapter 3: Language

59 PLRM 2nd Edition January 21, 1994 Language counttomark counts the elements above the highest mark. This is • used primarily for array construction (described later), but has other applications as well. 3.6.2 Arithmetic and Mathematical Operators The PostScript language includes a conventional complement of arith- metic and mathematical operators. In general, these operators accept either integer or real number objects as operands. They produce either integer or real numbers as results, depending on the types of the oper- ands and the magnitude of the results. If the result of an operation is mathematically meaningless or cannot be represented as a real, an undefinedresult error occurs. add , sub , mul , • , idiv , and mod are arithmetic operators of two div arguments. , abs neg , ceiling , • , round , and truncate are arithmetic operators floor of one argument. atan sqrt • are mathematical and trigono- , exp , ln , log , sin , cos , and metric functions. rand , srand , and rrand access a pseudo-random number generator. • 3.6.3 Array, Packed Array, Dictionary, and String Operators A number of operators are polymorphic —they may be applied to oper- ands of several different types and their precise functions depend on the types of the operands. In particular, there are various operators that perform similar operations on the values of several types of composite objects—arrays, packed arrays, dictionaries, and strings. • takes a composite object and an index (or key, in the case of a get dictionary) and returns a single element of the object. put stores a single element in a composite object. ( put does not • apply to packed array objects because they are read-only.) • copy copies the value of a composite object to another composite object of the same type, replacing the second object’s former value. This is different from merely copying the object. See the discussion of simple versus composite objects in section 3.3, “Data Types and Objects.” 3.6 Overview of Basic Operators 51

60 PLRM 2nd Edition Language January 21, 1994 length • returns the number of elements in a composite object. • forall accesses all of the elements of a composite object in sequence, calling a procedure for each one. • creates a new object that shares a subinterval of an array, getinterval packed array, or string. This does not apply to dictionary objects. • putinterval overwrites a subinterval of one array or string with the does not apply to dictionary or contents of another. putinterval packed array objects. In addition to the polymorphic operators, there are operators that apply to only one of the array, packed array, dictionary, and string types. For each type, there is an operator ( array , packedarray , dict , string ) that creates a new object of that type and a specified length. These four operators explicitly create new composite object values, con- suming virtual memory (VM) resources (see section 3.7.1, “Virtual Memory”). Most other operators read and write the values of composite objects, but do not create new ones. Operators that return composite results usually require an operand that is the composite object into which the result values are to be stored. The operators are organized this way to give programmers maximum control over consumption of VM. Array, packed array, and string objects have a fixed length that is speci- fied when the objects are created. In Level 1, dictionary objects also have this property. In Level 2, a dictionary’s capacity can grow beyond its initial allocation. The following operators apply only to arrays and (sometimes) packed arrays: • aload and astore transfer all the elements of an array to or from the operand stack in a single operation. aload may also be applied to a packed array. • The array construction operators combine to produce a new [ and ] array object whose elements are the objects appearing between the [ operator, which is a brackets in a PostScript language program. The synonym for mark , pushes a mark object on the operand stack. Exe- cution of the program fragment between the [ and the ] causes zero ] or more objects to be pushed on the operand stack. Finally, the operator counts the number of objects above the mark on the stack, 52 Chapter 3: Language

61 PLRM 2nd Edition January 21, 1994 Language creates an array of that length, stores the elements from the stack in the array, removes the mark from the stack, and pushes the array on the stack. and ( both Level 2 ) control a mode setting • currentpacking setpacking that determines the type of procedure objects the scanner generates when it encounters a sequence of tokens enclosed in } . If the { and true , the scanner produces packed arrays; if the array packing mode is false , it produces ordinary arrays. The default value is mode is . false • Packed array objects are always read-only, so the , putinterval , put astore and operations are not allowed on them. Accessing arbitrary elements of a packed array object can be quite slow; however, access- ing the elements sequentially, as the PostScript interpreter and the operator do, is efficient. forall The following operators apply only to dictionaries: begin and end push new dictionaries on the dictionary stack and • pop them off. store • associate keys with values in dictionaries on the dic- def and tionary stack; where search for keys there. and load countdictstack , cleardictstack , and dictstack operate on the diction- • ary stack. • known queries whether a key is present in a specific dictionary. • maxlength obtains a dictionary’s maximum capacity. • undef ( Level 2 ) removes individual keys from a dictionary. • and >> ( Level 2 ) construct a dictionary consisting of the bracketed << objects interpreted as key-value pairs. The following operators apply only to strings: • search and anchorsearch perform textual string searching and matching. token • scans the characters of a string according to the PostScript lan- guage syntax rules, without executing the resulting objects. 3.6 Overview of Basic Operators 53

62 PLRM 2nd Edition January 21, 1994 Language There are many additional operators that use array, dictionary, or string operands for special purposes—for instance, as transformation matrices, font dictionaries, or text to be shown. 3.6.4 Relational, Boolean, and Bitwise Operators The relational operators compare two operands and produce a boolean result indicating if the relation holds. Any two objects may be com- and ne pared for equality ( equal and not equal ); numbers and eq — gt , ge , le , and lt strings may be compared by the inequality operators ( — greater than greater than or equal to , less than or equal to , and less than ). , , and The boolean and bitwise operators ( , xor , true , false , and not ) or compute logical combinations of boolean operands or bitwise combina- tions of integer operands. The bitwise shift operator applies bitshift only to integers. Control Operators 3.6.5 The control operators modify the interpreter’s usual sequential execu- tion of objects. Most of them take a procedure operand that they exe- cute conditionally or repeatedly. • if and ifelse execute a procedure conditionally depending on the value of a boolean operand. ( ifelse is introduced in section 3.5, “Exe- cution.”) • exec executes an arbitrary object unconditionally. repeat • for , , and , loop forall execute a procedure repeatedly. Several specialized graphics and font operators, such as and pathforall kshow , behave similarly. • exit transfers control out of the scope of any of these looping opera- tors. • countexecstack and execstack are used to read the execution stack. A PostScript language program may terminate prematurely by execut- ing the stop operator. This occurs most commonly as a result of an . stop error; the default error handlers (in errordict ) all execute 54 Chapter 3: Language

63 PLRM 2nd Edition January 21, 1994 Language stopped operator establishes an execution environment that The . That is, executes a procedure encapsulates the effect of a stopped stop . If the interpreter executes given as an operand, just the same as exec during that procedure, it terminates the procedure and resumes stop execution at the object immediately after the stopped operator. Type, Attribute, and Conversion Operators 3.6.6 These operators deal with the details of PostScript types, attributes, and values, introduced in section 3.3, “Data Types and Objects.” type integertype , • returns the type of any operand as a name object ( realtype , and so on). • , rcheck , and wcheck query the literal/executable and access xcheck attributes of an object. and change the literal/executable attribute of an object. • cvlit cvx • executeonly , and noaccess reduce an object’s access , readonly attribute. Access can only be reduced, never increased. cvi and cvr convert between integer and real types, and interpret a • numeric string as an integer or real number. • cvn converts a string to a name object defined by the characters of the string. • cvs and cvrs convert objects of several types to a printable string rep- resentation. 3.7 Memory Management A PostScript language program executes in an environment with these major components: stacks, virtual memory, standard input and output files, and the graphics state. • The operand stack is working storage for objects that are the operands and results of operators. The dictionary stack contains dictionary con- objects that define the current name space. The execution stack tains objects that are in partial stages of execution by the PostScript interpreter. See section 3.4, “Stacks.” 3.7 Memory Management 55

64 PLRM 2nd Edition January 21, 1994 Language • The virtual memory (VM) is a storage pool for the values of all com- posite objects. The adjective “virtual” emphasizes the behavior of this memory visible at the PostScript language level, not its imple- mentation in computer storage. is the normal source of program text to be exe- • The standard input file cuted by the PostScript interpreter. The is the nor- standard output file mal destination of output from the print operator and of error messages. Other files can exist as well. See section 3.8, “File Input and Output.” • The graphics state is a collection of parameters that control the pro- duction of text and graphics on a raster output device. See section 4.2, “Graphics State.” This section describes the behavior of VM and its interactions with other components of the PostScript execution environment. It describes facilities for controlling the environment as a whole. The PostScript interpreter can execute a sequence of self-contained Post- Script programs as independent “jobs”; similarly, each job can have internal structure whose components are independent of each other. 3.7.1 Virtual Memory As described in section 3.3, “Data Types and Objects,” there are two classes of objects: simple and composite. A simple object’s value is con- tained in the object itself. A composite object’s value is stored sepa- rately; the object contains a reference to it. The virtual memory (VM) is the storage in which the values of composite objects reside. For example, the program fragment 234 (Here is a string) pushes two objects, an integer and a string, on the operand stack. The integer, which is a simple object, contains the value 234 as part of the object itself. The string, which is a composite object, contains a refer- ence to the value (Here is a string) , which is a text string that resides in VM. The elements of the text string are characters (actually, integers in the range 0 to 255) that can be individually selected or replaced. Here is another example: {234 (Here is a string)} 56 Chapter 3: Language

65 PLRM 2nd Edition Language January 21, 1994 This pushes a single object, a two-element executable array, on the operand stack. The array is a composite object whose value resides in VM. The value in turn consists of two objects, an integer and a string. Those objects are elements of the array, which can be individually selected or replaced. Several composite objects can share the same value. For example, in {234 (Here is a string)} dup the dup operator pushes a second copy of the array object on the oper- and stack. The two objects share the same value—that is, the same stor- age in VM. So, replacing an element of one array will affect the other. Other types of composite objects, including strings and dictionaries, behave similarly. Creating a new composite object consumes VM storage for its value. This occurs in two principal ways: • The scanner allocates storage for each composite literal object that it , (...) , <...> , <~...~> encounters. Composite literals are delimited by The first three produce strings; the fourth produces an exe- {...}. and cutable array. There also are binary encodings for composite objects. • Some operators explicitly create new composite objects and allocate storage for them. The array , packedarray , dict , string , and gstate operators create new array, packed array, dictionary, string, and gstate objects, respectively. Also, the bracketing constructs [...] and create new array and dictionary objects, respectively. The <<...>> brackets are just special names for operators; the closing bracket operators allocate the storage. For the most part, consumption and management of VM storage are under the control of the PostScript language program. Aside from the operators mentioned above and a few others that are clearly docu- mented, most operators do not create new composite objects or allocate storage in VM. Some operators place their results in existing objects (convert to string) operator supplied by the caller. For example, the cvs overwrites the value of a supplied string operand and returns a string object that shares a substring of the supplied string’s storage. 3.7 Memory Management 57

66 PLRM 2nd Edition January 21, 1994 Language Local and Global VM 3.7.2 There are two divisions of VM containing the values of composite and . Only composite objects occupy VM. An “object objects: global local occupies VM”; the loca- in VM” means a “composite object whose value tion of the object (for example, on a stack or stored as an element of some other object) is immaterial. Note Global VM exists only in Level 2 and Display PostScript implementations of the PostScript language. In Level 1 implementations, all of VM is local. Local VM is a storage pool that obeys a stack-like discipline. Allocations in local VM and modifications to existing objects in local VM are sub- save restore , named after the operators that ject to a feature called and save and invoke it. bracket a section of a PostScript language restore program whose local VM activity is to be encapsulated. restore deallo- cates new objects and undoes modifications to existing objects that were made since the matching are described in restore save . save and section 3.7.3, “Save and Restore.” Global VM is a storage pool for objects that don’t obey a fixed disci- pline. Objects in global VM can come into existence and disappear in an arbitrary order during execution of a program. Modifications to save existing objects in global VM are not affected by occurrences of restore within the program. However, an entire job’s VM activity and can be encapsulated, enabling separate jobs to be executed indepen- dently. This is described in section 3.7.7, “Job Execution Environment.” In a hierarchically structured program, such as a page description, local VM is used to hold information whose lifetime conforms to the struc- ture; that is, it persists to the end of a structural division, such as a sin- gle page. Global VM may be used to hold information whose lifetime is independent of the structure, such as definitions of fonts and other resources that are loaded dynamically during execution of a program. Control over allocation of objects in local versus global VM is provided by the setglobal operator (a Level 2 feature). This operator establishes a VM allocation mode , a boolean value that determines where subsequent allocations are to occur ( false means local, true means global). It affects objects created implicitly by the scanner and objects created explicitly by operators. The default VM allocation mode is local; a program can switch to global VM allocation mode when it needs to. 58 Chapter 3: Language

67 PLRM 2nd Edition Language January 21, 1994 The following example illustrates creation of objects in local and global VM: /lstr (string1) def /ldict 10 dict def true setglobal /gstr (string2) def /gdict 5 dict def false setglobal In the first line, when the scanner encounters (string1) , it allocates the operator allocates string object in local VM. In the second line, the dict a new dictionary in local VM. The third line switches to global VM allo- cation mode. The fourth and fifth lines allocate a string object and a dictionary object in global VM. The sixth line switches back to local VM allocation mode. The program associates the four newly created objects ldict lstr , , with the names gstr , and gdict in the current dictionary, pre- . sumably userdict It is illegal for an object in global VM to contain a reference to an object in local VM. An attempt to store a local object as an element of a global object will result in an error. The reason for this restriction invalidaccess is that subsequent execution of the restore operator might deallocate the local object, leaving the global object with a reference to a non-exis- tent object. This restriction applies only to storing a composite object in local VM as an element of a composite object in global VM. All other combinations are allowed. The following example illustrates this, using the objects that were created in the preceding example: ldict /a lstr put % Legal—a local object into a local dict gdict /b gstr put % Legal—a global object into a global dict % Legal—a global object into a local dict ldict /c gstr put gdict /d lstr put % Illegal ( invalidaccess error)—a local object into a global dict gdict /e 7 put % Legal—a simple object into any dict There are no restrictions on storing simple objects, such as integers and names, as elements of either local or global composite objects. The gcheck operator inquires whether an object can be stored as an element of a global composite object. It returns true for a simple object or for a for a composite object in local VM. false composite object in global VM, 3.7 Memory Management 59

68 PLRM 2nd Edition Language January 21, 1994 Save and Restore 3.7.3 save operator takes a snapshot of the state of local VM; it returns a The save object that represents the snapshot. The restore operator causes local VM to revert to a snapshot generated by a preceding . Specifi- save cally: • restore discards all objects in local VM that were created since the corresponding save , and reclaims the memory they occupied. • restore resets the values of all composite objects in local VM, except strings, to their state at the time of the . save • restore performs an implicit grestoreall , which resets the graphics state to its value at the time of the save (see section 4.2, “Graphics State.”) • restore closes files that were opened since the corresponding save , so long as those files were opened while local VM allocation mode was in effect (see section 3.8, “File Input and Output”). restore are limited to the ones described above. The effects of • does not affect the contents of the operand, dictionary, and restore execution stacks. If a stack contains a reference to a composite object in local VM that would be discarded by the restore , the restore is not allowed. An invalidrestore error occurs. • It does not affect any objects that reside in global VM, except as described in section 3.7.7, “Job Execution Environment.” • It does not undo side effects outside VM, such as writing data to files or rendering graphics on the raster output device. (However, the implicit grestoreall may deactivate the current device, thereby eras- ing the current page. See section 4.11, “Device Setup,” for details.) and save restore can be nested to a limited depth (see Appendix B for implementation limits). A PostScript language program can use save and restore to encapsulate the execution of an embedded program that also uses save and restore . save and restore are intended for use in structured programs, such as page descriptions. The conventions for structuring programs are intro- duced in section 2.4.2, “Program Structure,” and detailed in Appendix serve the following functions: restore G. In such programs, save and 60 Chapter 3: Language

69 PLRM 2nd Edition Language January 21, 1994 • A document consists of a prolog and a script. The prolog contains definitions that are used throughout the document. The script con- save at the sists of a sequence of independent pages. Each page has a restore beginning and a at the end, immediately before the showpage operator. Each page begins execution with the initial con- ditions established in local VM by the prolog. There are no unwanted legacies from previous pages. • A page sometimes contains additional substructure, such as embed- ded illustrations, whose execution needs to be encapsulated. The encapsulated program can make wholesale changes to the contents of local VM to serve its own purposes. By bracketing the program with save and restore , the enclosing program can isolate the effects of the embedded program. • As a PostScript language program executes, new composite objects accumulate in local VM. These include objects created by the scan- ner, such as literal string tokens, and objects allocated explicitly by operators. The restore operator reclaims all local VM storage allo- peri- restore cated since the corresponding save ; executing save and odically ensures that unreclaimed objects will not exhaust available VM resources. In Level 1 implementations, and restore are the save way to reclaim VM storage. Even in Level 2, explicit reclamation only save and restore is much more efficient than automatic reclama- by tion, described in section 3.7.4, “Garbage Collection.” • The PostScript interpreter uses save and restore to encapsulate the execution of individual jobs, as described in section 3.7.7, “Job Exe- cution Environment.” 3.7.4 Garbage Collection In addition to the save and restore operators for explicit VM reclama- tion, Level 2 implementations and Display PostScript systems include a facility for automatic reclamation, popularly known as a garbage collec- tor . The garbage collector reclaims the memory occupied by composite objects that are no longer accessible to the PostScript language pro- gram. For example, after the following program is executed, /a (string 1) def /a (string 2) def (Here is some text) show 3.7 Memory Management 61

70 PLRM 2nd Edition Language January 21, 1994 the string object (string 1) is no longer accessible, since the dictionary entry that referred to it has been replaced by a different object, (string 2) . Similarly, the string (Here is some text) is no longer accessible, since the show operator consumes its operand, but does not store it anywhere. The inaccessible strings are candidates for garbage collec- tion. Garbage collection normally takes place without explicit action by the PostScript language program. It has no effects that are visible to the pro- gram. However, the presence of a garbage collector strongly influences the style of programming that is permissible. If no garbage collector is present, a program that consumes VM endlessly and never executes save and restore will eventually exhaust available memory and cause a VMerror . Creating and destroying composite objects in VM have a cost. The most common case is that of literal objects—particularly strings, user paths, and binary object sequences—that are immediately consumed by oper- ators such as show and ufill , and never used again. The garbage collec- tor is engineered to deal with this case inexpensively, so application programs should not hesitate to take advantage of it. However, the cost of garbage collection is greater for objects that have longer lifetimes or are allocated explicitly. Programs that frequently require temporary objects are encouraged to create them once and reuse them instead of before creating new ones—for example, allocate a string object an image data acquisition procedure, rather than within it (see section 4.10.7, “Using Images”). save and restore operators still have Even with garbage collection, the restore resets all accessible objects in their standard behavior. That is, local VM to their state at the time of the matching save . It reclaims all composite objects created in local VM since the save , and does so very cheaply. On the other hand, garbage collection is the only way to reclaim storage in global VM, since and restore normally do not save affect global VM. With garbage collection comes the ability to explicitly discard compos- ite objects that are no longer needed. This can be done in an order unrelated to the time of creation of those objects, as opposed to the stack-like order imposed by save and restore . This is particularly desir- able for very large objects, such as font definitions. If the only reference to a particular composite object is an element of some array or dictionary, replacing that element with something else ) renders the object inaccessible. Alternatively, the undef (say, using put 62 Chapter 3: Language

71 PLRM 2nd Edition Language January 21, 1994 operator removes a dictionary entry entirely; that is, it removes both the key and the value of a key-value pair, as opposed to replacing the value with some other value. In either case, the removed object becomes a candidate for garbage collection. Regardless of the means used to remove a reference to a composite object, if the object containing the reference is in local VM, the action can be undone by a subsequent restore . This is true even for undef . Consider the following example: /a (string 1) def save currentdict /a undef restore undef removes the key a and its value from the current Execution of (string 1) to become inaccessi- dictionary, seemingly causing the object ble. However, assuming that the current dictionary is userdict , or some other dictionary in local VM, restore reinstates the deleted entry, since . The value is still acces- it existed at the time of the corresponding save sible and cannot be garbage collected. As a practical matter, this means that the technique of discarding objects explicitly (in expectation of their being garbage collected) is use- and restore have no save ful mainly for objects in global VM, where effect, and for objects in local VM that were created at the current level save nesting. of Standard and User-Defined Dictionaries 3.7.5 A job begins execution with three standard dictionaries on the diction- , and systemdict , globaldict userdict ary stack: , with userdict on top. • is a global dictionary that is permanently read-only. It systemdict contains mainly operators. • globaldict is a global dictionary that is writable ( Level 2 ). • userdict is a local dictionary that is writable. There are other standard dictionaries that are the values of permanent systemdict named entries in . Some of these are in local VM, some in global VM, as shown in Table 3.3 and Table 3.4. A PostScript language 3.7 Memory Management 63

72 PLRM 2nd Edition Language January 21, 1994 program can also create new dictionaries in either local or global VM, then push them on the dictionary stack or store them as entries in or globaldict . userdict Standard local dictionaries Table 3.3 Definition Dictionary userdict Standard writable local dictionary. Initially, it is the top dictionary on the dictionary stack, making it the current dictionary. errordict Error dictionary. See section 3.10, “Errors.” $error Dictionary accessed by the built-in error-handling pro- cedures to store stack snapshots and other information. See section 3.10, “Errors.” statusdict Dictionary for product-specific operators and other defi- nitions. See Chapter 8. FontDirectory Dictionary for font definitions. It is normally read-only, but is updated by definefont and consulted by findfont. See section 3.9, “Named Resources,” and section 5.2, “Font Dictionaries.” Table 3.4 Standard global dictionaries Dictionary Definition systemdict Read-only system dictionary containing all operators and other definitions that are standard parts of the Post- Script language. It is the bottom dictionary on the dic- tionary stack. globaldict ( Level 2 ) Standard writable global dictionary. It is on the dictionary stack between systemdict and userdict . GlobalFontDirectory ( Level 2 ) Dictionary for font definitions in global VM. It is normally read-only, but is updated by definefont and consulted by . See section 3.9, “Named findfont Resources,” and section 5.2, “Font Dictionaries.” The dictionaries userdict and globaldict are intended to be the principal repositories for application-defined dictionaries and other objects. When a PostScript language program creates a dictionary in local VM, it then typically associates that dictionary with a name in userdict . Simi- larly, when the program creates a dictionary in global VM, it typically globaldict . Note that the latter associates the dictionary with a name in 64 Chapter 3: Language

73 PLRM 2nd Edition Language January 21, 1994 step requires explicit action on the part of the program. Entering global VM allocation does not globaldict alter the dictionary stack (say, to put on top). The principal intended use of global VM is to hold font definitions and other resources that are loaded dynamically during execution of a Post- operator loads fonts into global Script language program. The findfont VM automatically when necessary. However, any program can take advantage of global VM when its properties are useful. The following guidelines are suggested: • Objects that are created during the prolog can be in either local or global VM; in either case, they will exist throughout the job, since they are defined outside the save and restore that enclose individual pages of the script. A dictionary in local VM reverts to the initial state defined by the prolog at the end of each page. This is usually the desirable behavior. A dictionary in global VM accumulates changes indefinitely and never reverts to an earlier state. This is use- ful when there is a need to communicate information from one page to another (strongly discouraged in a page description). • When using a writable dictionary in global VM, you must be careful about what objects you store in it. Attempting to store a local com- posite object in a global dictionary will cause an invalidaccess error. So, it is advisable to segregate local and global data and to use global VM only for those objects that must persist through executions of restore save and . • In general, the prologs for most existing PostScript language pro- grams do not work correctly if they are simply loaded into global VM. The same is true of some user-defined (Type 3) fonts. These pro- grams must be altered to define global and local information sepa- rately. Typically, global VM should be used to hold procedure definitions and constant data; local VM should be used to hold tem- porary data needed during execution of the procedures. There is no advantage to putting prologs in global VM except to share them among multiple contexts in a Display PostScript system (see below). • Creating gstate (graphics state) objects in global VM is particularly risky. This is because the graphics state almost always contains one or more local objects, which cannot be stored in a global gstate (see operator in Chapter 8). currentgstate 3.7 Memory Management 65

74 PLRM 2nd Edition January 21, 1994 Language In a Display PostScript system, which supports multiple execution con- texts operating simultaneously, global VM serves an additional purpose. Two or more contexts can share the same global VM, enabling them to communicate with each other dynamically. This is described in section 7.1, “Multiple Execution Contexts.” 3.7.6 User Objects Some applications require a convenient and efficient way to refer to PostScript language objects previously constructed in VM. The conven- tional way to accomplish this is to store such objects as named entries in dictionaries and later to refer to them by name. In a PostScript lan- guage program written by a programmer, this approach is natural and straightforward. When the program is generated mechanically by another program, however, it is more convenient to number the objects with small integers and later to refer to them by the numbers. This sim- plifies the bookkeeping the application program must do. The PostScript language provides built-in support for a single space of user objects . There are three operators, numbered objects, called defineuserobject undefineuserobject , and execuserobject , which , manipulate an array named UserObjects . These operators don’t intro- duce any fundamental capability. They merely provide convenient and efficient notation for accessing the elements of a special array. Note User objects exist only in Level 2 and Display PostScript implementations. The user object facility is entirely separate from the encoded user name feature of the binary encoding of the PostScript language. The latter is a Display PostScript extension that is described in Chapter 7. Example 3.4 illustrates the intended use of user objects: Example 3.4 17 {ucache 132 402 316 554 setbbox ... } cvlit defineuserobject 17 execuserobject ufill The first line of the example constructs an interesting object that is to be used repeatedly (in this case, a user path; see section 4.6, “User Paths”) and associates the user object index 17 with this object. 66 Chapter 3: Language

75 PLRM 2nd Edition Language January 21, 1994 The second line pushes the user object onto the operand stack, from which takes it. execuserobject executes the user object associated ufill with index 17. However, because the object in this example is not exe- cutable, the result of the execution is to push the object onto the oper- and stack. Note The pswrap translator, an adjunct to the Display PostScript system, enables an application program to refer to user objects conveniently (see Chapter 7). defineuserobject manages the UserObjects array automatically; there is no reason for a PostScript language program to refer to UserObjects explicitly. The array is allocated in local VM and defined in userdict . This means that the effect of defineuserobject is subject to save and restore . The values of user objects given to defineuserobject can be in either local or global VM. Job Execution Environment 3.7.7 As indicated in section 2.4, “Using the PostScript Language,” the con- ventional model of a PostScript interpreter is a “print server”—a single- threaded process that consumes and executes a sequence of “print jobs,” each of which is a complete, independent PostScript language program. This model is also appropriate for certain other environments, such as a document previewer built on top of a Display PostScript sys- tem. This model does not apply when an application uses the Display Post- Script system to manage the display screen interactively. That is described in Chapter 7. The following material applies only to a Post- Script interpreter that is being operated as a job server. The notion of a “print job” is not formally a part of the PostScript lan- guage, because it involves not only the PostScript interpreter but also some description of the environment in which the interpreter operates. Still, it is useful to describe a general model that is accurate for most job PostScript printers, though perhaps lacking in some details. Informa- tion about communication protocols, job control, system management, and so on, does not appear here, but in documentation for specific products. A job begins execution in an initial environment that consists of an empty operand stack, a dictionary stack containing the three standard systemdict dictionaries ( ), many other , globaldict ( Level 2 ), and userdict objects accessible via those dictionaries, and miscellaneous interpreter parameters. 3.7 Memory Management 67

76 PLRM 2nd Edition January 21, 1994 Language During execution, the job may alter its environment. Ordinarily, when a job finishes, the environment reverts to its initial state to prepare for the next job. That is, the job is encapsulated . The server accomplishes restore this encapsulation by executing save and and by explicitly resetting stacks and parameters between jobs. With suitable authorization, a job can make persistent alterations to objects in VM. That is, the job is not encapsulated. Instead, its alter- ations appear as part of the initial state of the next and all subsequent jobs. This is accomplished by means of the startjob and exitserver facil- ities described below. Server Operation A job server is presented a sequence of files via one or more communi- cation channels. For each file, the server performs the following sequence of steps: 1. Establish standard input and output file objects for the channel from which the file is to be obtained. 2. Execute save . This is the outermost save , which unlike a normal save obtains a snapshot of the initial state of objects in both local and global VM. 3. Establish default initial state for the interpreter: empty operand stack, local VM allocation mode, default user space for the raster out- put device, and so on. 4. Execute the standard input file until it reaches end-of-file or an error occurs. If an error occurs, report it and flush input to end-of-file. restore 5. Execute , causing objects in VM (both local and global) to revert to the state saved in step 2. 6. Close the standard input and output files, transmitting an end-of-file indication over the communication channel. Ordinarily, the server executes all six steps once for each file that it receives. Each file is treated as a separate job, and each job is encapsu- lated. 68 Chapter 3: Language

77 PLRM 2nd Edition January 21, 1994 Language Altering Initial VM A program can circumvent job encapsulation and alter the initial VM , a Level 2 fea- for subsequent jobs. To do so, it can use either startjob , a feature available in all implementations that exitserver ture, or include a job server. This capability is controlled by a password. The sys- tem administrator can choose not to make the capability available to ordinary users. Applications and drivers must be prepared to deal with the possibility that altering the initial VM is not allowed. startjob Note exitserver should be invoked only by a print manager, spooler, or and system administration program. They should never be used by an application program composing a page description. Appendix I gives more guidelines for using startjob and exitserver . startjob is invoked as follows: true startjob password where is a password—a string or integer; see section C.3.1, password “Passwords.” If this is successful, startjob causes the server to execute steps 5, 3, and 4 in the above sequence. In other words, it logically ends the current job, undoing all modifications it has made so far, and starts a new job. However, it does not precede the new job with a save , so its execution is not encapsulated. Furthermore, it does not disturb the standard input and output files; the interpreter resumes consuming the remainder of the same input file. Having started an unencapsulated job, the PostScript language program can alter the VM in arbitrary ways. Those alterations are persistent. If the job simply runs to completion, ending step 4 in the above sequence, the server skips step 5 (since there is no saved VM snapshot to restore), continues with step 6, and processes the next job normally starting at step 1. Alternatively, a program can explicitly terminate its alterations to initial VM: false password startjob This has the effect of executing steps 2, 3, and 4, logically starting yet another job that is encapsulated in the normal way, but still continuing to read from the same file. 3.7 Memory Management 69

78 PLRM 2nd Edition Language January 21, 1994 startjob If executes successfully, it always starts a new job in the sense described above. It clears all the stacks and then pushes the result true on the operand stack. But if startjob is unsuccessful, it has no effect false other than to push on the operand stack. In the latter case, the effect is as if the program text before and after the occurrence of startjob were a single combined job. A typical sequence is: true password startjob pop ...application prolog here... false startjob pop password ...application script here... This installs the application prolog in initial VM if it is allowed to do so. However, the script executes successfully, regardless of whether the attempt to alter initial VM was successful. The program can determine the outcome by testing the result returned by startjob . Although the above sequence is typical, there is no restriction on the sequence of encapsulated and unencapsulated jobs. If the password is correct and the boolean operand to startjob is true , the job that follows it is unencapsulated; if false , the job is encapsulated. But if the password startjob does not start a new job; the current job simply is incorrect, continues. also fails to start a new job if, at the time it is executed, the cur- startjob rent save nesting is more than one level deep. In other words, startjob works only when the current save level is equal to the level at which the current job started. This permits a file that executes startjob to be encapsulated as part of another job simply by bracketing it with save and restore . save Note If an unencapsulated job uses and affect restore , the save and restore global as well as local VM, since they are at the outermost level. Also, if save the job ends with one or more save s pending, a restore to the outermost saved VM is performed automatically. exitserver exitserver is an unofficial Level 1 feature that is retained in Level 2 has never been implementations for compatibility. Although exitserver a formal part of the PostScript language, it exists in nearly every Adobe 70 Chapter 3: Language

79 PLRM 2nd Edition Language January 21, 1994 PostScript product. Some applications have come to depend on it. The startjob feature, described above, is more flexible and is preferred for new Level 2 applications. The canonical method of invoking exitserver is: serverdict begin exitserver password This has the same effect as: true password startjob not {/exitserver errordict /invalidaccess get exec} if In other words, if successful, exitserver initiates an unencapsulated job that can alter initial VM; if unsuccessful, it generates an invalidaccess error. Like startjob , a successful exitserver clears the stacks—it removes serverdict from the dictionary stack. The program that follows (termi- nated by end-of-file) is executed as an unencapsulated job. In many implementations, successful execution of exitserver sends the message %%[exitserver: permanent state may be changed]%% to the . It is sup- startjob standard output file. This message is not generated by pressed if is true in the $error dictionary. See section 3.10.2, binary “Error Handling.” Note Aside from exitserver, the other contents of serverdict are not specified as part of the language. In Level 2, the effect of executing exitserver more than once in the same file is the same as that of executing the equivalent startjob sequence multiple times. In Level 1, the effect of executing the exitserver operator multiple times is undefined and unpredictable. 3.8 File Input and Output A file is a finite sequence of characters bounded by an end-of-file indica- tion. These characters may be stored permanently in some place (for instance, a disk file) or they may be generated on the fly and transmit- ted over some communication channel. Files are the means by which the PostScript interpreter receives executable programs and exchanges data with the external environment. There are two kinds of files: input and output . An input file is a source from which a PostScript language program can read a sequence of char- acters. An output file is a destination to which a PostScript language program can write characters. Some files in permanent storage media can be read and written. 3.8 File Input and Output 71

80 PLRM 2nd Edition Language January 21, 1994 3.8.1 Basic File Operators A PostScript file object represents a file. The file operators take a file object as an operand to read or write characters. Ignoring for a moment how a file object comes into existence, the file operators include: • read reads the next character from an input file. appends a character to an output file. • write • , readline , and writestring transfer the contents of strings readstring to and from files. • readhexstring and writehexstring read and write binary data repre- sented in the file by hexadecimal notation. scans characters from an input file according to the PostScript • token language syntax rules. • , applied to an input file, causes the PostScript interpreter to exe- exec cute a PostScript language program from that file. The operators that write to a file do not necessarily deliver the charac- ters to their destination immediately. They may leave some characters flush and in buffers for reasons of implementation or efficiency. The operators deliver these buffered characters immediately. These flushfile operators are useful in certain situations, such as during two-way inter- actions with another computer or with a human user, when such data must be transmitted immediately. Standard Input and Output Files All PostScript interpreters provide standard input and standard output files, which usually represent a real-time communication channel to and from another computer or user terminal. The standard input and output files always exist; it is not necessary for a program to create or close them. The PostScript interpreter reads and interprets the standard input file as PostScript language program text. It sends error and status messages to the standard output file. Also, a PostScript language program may exe- cute the print operator to send arbitrary data to the standard output file file. Note that print is a operator; it has nothing to do with placing text on a page or causing pages to emerge from a printer. 72 Chapter 3: Language

81 PLRM 2nd Edition January 21, 1994 Language It seldom is necessary for a PostScript language program to deal explic- itly with file objects for the standard files, because the PostScript inter- operator preter reads the standard input file by default and the print references the standard output file implicitly. Additionally, the file cur- rently being read by the PostScript interpreter is available via the currentfile operator. This file need not be the standard input file. How- operator to the ever, when necessary, a program may apply the file or %stdout to obtain file objects for the stan- identifying strings %stdin dard input and output files. End-of-Line Conventions The PostScript language scanner and the operator recognize all readline three external forms of end-of-line (EOL)—LF alone, CR alone, and the CR LF pair—and treat them uniformly. The PostScript interpreter does not translate data read by other means or written by any means. End-of-line sequences are recognized and treated specially in the fol- lowing situations: • Any of the three forms of EOL appearing in a literal string are con- newline verted to a single (LF character) in the resulting string object. 〈 CR 〉 (any text some more text) 〉 LF 〈 (any text some more text) 〈 CR 〉〈 LF 〉 (any text some more text) These three examples produce identical string objects, each of which has a single newline (LF) separating “text” and “some.” • Any of the three forms of EOL appearing immediately after \ in a string are treated as a line continuation; both the \ and the EOL are discarded. 〉 〈 CR (any text\ some more text) 〈 LF 〉 (any text\ some more text) 〈 〉 LF CR 〉〈 (any text\ some more text) (any textsome more text) These four examples produce identical string objects. • Any of the three forms of EOL appearing outside a string are treated as a single white-space character. Since the language treats multiple white-space characters as a single white-space character, the treat- 3.8 File Input and Output 73

82 PLRM 2nd Edition January 21, 1994 Language ment of EOL is interesting only when a PostScript language token is followed by data to be read explicitly by one of the file operators. CR 〉 〈 currentfile read x LF 〉 〈 x currentfile read 〈 CR 〉〈 〉 LF currentfile read x The above three examples produce identical results: the operator reads the character from the current input file and leaves its char- x 120 acter code (the integer ) on the stack. • The readline operator treats any of the three forms of EOL as the ter- mination condition. do not undergo EOL translation. readstring • Data read by read and The PostScript interpreter reads whatever characters were received from the channel. However, the channel itself may perform some EOL translation, as discussed below. • Data written by and writestring do not undergo EOL transla- write tion. Whatever characters the PostScript interpreter provides are sent to the channel. However, the channel itself may perform some EOL translation, as discussed below. Communication Channel Behavior Communications functions often usurp control characters. Control codes are device dependent and not part of the PostScript language. For example, the serial communication protocol supported by many prod- ucts uses the Control-D character as an end-of-file indication. In this case, Control-D is a communications function and not logically part of a PostScript language program. This specifically applies to the serial channel; other channels, such as LocalTalk™ and Ethernet, have differ- ent conventions for end-of-file and other control functions. In all cases, communication channel behavior is independent of the actions of the Post- Script interpreter. There are two levels of PostScript EOL translation: one in the PostScript interpreter and one in the serial communication channel. The previous description applies only to the EOL conventions at the level of the Post- Script interpreter. The purpose of the seemingly redundant communica- tion level EOL translation is to maintain compatibility with diverse host operating system and communications environments. 74 Chapter 3: Language

83 PLRM 2nd Edition Language January 21, 1994 As discussed in section 3.2, “Syntax,” the ASCII encoding of the lan- guage is designed for maximum portability. It avoids using control characters that might be pre-empted by operating systems or communi- cation channels. However, there are situations in which transmission of arbitrary binary data is desirable. For example, sampled images are rep- resented by large quantities of binary data. The PostScript language has an alternative binary encoding that is advantageous in certain situa- tions. There are two main ways to deal with PostScript language pro- grams that contain binary information: • Communicate with the interpreter via binary channels exclusively. Some channels, such as LocalTalk and Ethernet, are binary by nature. They do not pre-empt any character codes, but instead communicate control information separately from the data. Other channels, such as serial channels, may support a binary communication protocol that allows control characters to be quoted. This approach presup- poses a well-controlled environment. PostScript language programs produced in that environment may not be portable to other envi- ronments. • Take advantage of filters for encoding binary data as ASCII text. Filters are a Level 2 feature, described in section 3.8.4, “Filters.” Programs represented in this way do not include any control codes and are therefore portable to any Level 2 interpreter in any environment. Named Files 3.8.2 The PostScript language provides access to named files in secondary storage. The file access capabilities are part of the integration of the lan- guage with an underlying operating system; there are variations from one such integration to another. Not all the file system capabilities of the underlying operating system are necessarily made available at the PostScript language level. The PostScript language provides a standard set of operators for access- ing named files. These operators are supported in all Level 2 implemen- tations and also in certain Level 1 implementations that have access to file systems. The operators are , deletefile , renamefile , filenameforall setfileposition , and fileposition . Although the language defines a stan- dard framework for dealing with files, the detailed semantics of the file system operators, particularly file-naming conventions, are operating system dependent. 3.8 File Input and Output 75

84 PLRM 2nd Edition Language January 21, 1994 Files are in one or more “secondary storage devices,” hereafter referred to simply as devices . (These are not to be confused with the “current device,” which is a raster output device identified in the graphics state.) The PostScript language defines a uniform convention for naming devices, but it says nothing about how files in a given device are named. Different devices have different properties, and not all devices support all operations. device A complete file name is in the form % device % file , where identifies the secondary storage device and is the name of the file within the file device. When a complete file name is presented to a file system opera- tor, the device portion selects the device; the file portion is in turn pre- sented to the implementation of that device, which is operating system and environment dependent. When a file name is presented without a % device % prefix, a search rule determines which device is selected. The available storage devices are consulted in order; the requested operation is attempted on each device until the operation succeeds. The number of available devices, their names, and the order in which they are searched is environment depen- dent. Not all devices necessarily participate in such searches; some devices can be accessed only by explicitly naming them. In an interpreter that runs on top of an operating system (OS), such as the Display PostScript system in a workstation, there is a device that represents the complete file system provided by the OS. If so, by con- vention that device’s name is os ; thus, complete file names are in the form %os% file , where file conforms to underlying file system conven- tions. This device always participates in searches, as described above; a program can access ordinary files without specifying the %os% prefix. There may be more than one device that behaves in this way; the names of such devices are product dependent. The os device may impose some restrictions on the set of files that can be Note accessed. Restrictions are necessary when the PostScript interpreter executes with a user identity different from that of the user running the application program. In an interpreter that controls a dedicated product, such as a typical printer product, there can be one or more devices that represent file sys- tems on disks and cartridges. Files on these devices have names such as . Once again, these %disk0% file , %disk1% file , and %cartridge0% file devices participate in searches when the device name is not specified. 76 Chapter 3: Language

85 PLRM 2nd Edition January 21, 1994 Language filenameforall file , renamefile , status , and deletefile , For the operators , filename is a string object that identifies a file. The name of the file can a be in one of three forms. % device % file identifies a named file on a specific device • , as described above. file % ) identifies a named file on an unspecified • (first character not device, which is selected by an environment-specific search rule, as described above. % device • % device % identifies an unnamed file on the device. Cer- or tain devices, such as cartridges, support a single unnamed file as opposed to a collection of named files. Other devices represent com- munication channels rather than permanent storage media. There , and %lineedit are also special files named %stdin , %stdout , %statementedit , described below. The , renamefile , and deletefile operators do not apply to file names of this form. filenameforall filenameforall operator. See “Wildcard” file names are handled by the in Chapter 8 for more information on wildcards. filenameforall Creating and Closing a File Object File objects are created by the operator. This operator takes two file strings: the first identifies the file and the second specifies access. file returns a new file object associated with that file. An access is a string object that specifies how a file is to be accessed. File access conventions are operating system specific. The following access specifications are typical of the UNIX operating system and are sup- ported by many others. The access string always begins with , w , or r , a possibly followed by + ; any additional characters supply operating sys- tem specific information. Table 3.5 lists access strings and their mean- ings. Table 3.5 Access strings Access string Meaning r Open for reading only. Error if file doesn’t already exist. w Open for writing only. Create file if it doesn’t already exist. Truncate and overwrite it if it does exist. a Open for writing only. Create file if it doesn’t already exist. Append to it if it does. 3.8 File Input and Output 77

86 PLRM 2nd Edition Language January 21, 1994 Open for reading and writing. Error if file doesn’t already exist. r+ Open for reading and writing. Create file if it doesn’t already w+ exist. Truncate and overwrite it if it does. Open for reading and writing. Create file if it doesn’t already a+ exist. Append to it if it does. Like other composite objects, such as strings and arrays, file objects have access attributes. The access attribute of a file object is based on the access string used to create it. Attempting to access a file object in a way that would violate its access causes an invalidaccess error. Certain files—in particular, named files on disk—are positionable , mean- ing that one can access the data in the file in an arbitrary order rather setfileposition operator than only sequentially from the beginning. The adjusts a file object so it refers to a specified position in the underlying file; subsequent reads or writes access the file at that new position. One can open a positionable file for reading and writing by specifying + in the access string, as shown in Table 3.5. To ensure predictable results, it is necessary to execute setfileposition when switching between reading and writing. close the file to At the end of reading or writing a file, a program should break the association between the PostScript file object and the actual file. The file operators close a file automatically if end-of-file is encoun- tered during reading (see below). The closefile operator closes a file explicitly. restore closes a file if the file object was created since the cor- responding save while in local VM allocation mode. Garbage collection closes a file if the object is no longer accessible. All operators that access files treat end-of-file and exception conditions the same. During reading, if an end-of-file indication is encountered before the requested item can be read, the file is closed and the opera- tion returns an explicit end-of-file result. This also occurs if the file has already been closed when the operator is executed. All other exceptions during reading and any exceptions during writing result in execution of . ioerror , invalidfileaccess , or invalidaccess the errors 3.8.3 Special Files The file operator can also return special files that are identified by the filename string. These special files are: %stdin , the standard input file. • 78 Chapter 3: Language

87 PLRM 2nd Edition January 21, 1994 Language %stdout , • the standard output file. , the standard error file. This is for reporting low-level errors. %stderr • In many configurations, it is the same as the standard output file. • %statementedit , the statement editor filter file, described below. %lineedit , • the line editor filter file, described below. For example, the statements (%stdin) (r) file (%stdout) (w) file push copies of the standard input and output file objects on the oper- and stack. These are duplicates of existing file objects, not new objects. interactive executive, invoked by Some PostScript interpreters support an ; this is described in section 2.4.4, “Using the Interpreter Inter- executive actively.” executive obtains commands from the user by means of a operator to the file file special file named %statementedit . Applying the name string causes the following: %statementedit • The file operator begins reading characters from the standard input file and storing them in a temporary buffer. While doing so, it echoes the characters to the standard output file. It also interprets certain control characters as editing functions for making corrections, as described in section 2.4.4, “Using the Interpreter Interactively.” • When a complete statement has been entered, the file operator re- turns. A statement consists of one or more lines terminated by new- line that together form one or more complete PostScript language tokens, with no opening brackets ( ) left unmatched. { , ( , < , or <~ • The returned file object represents a temporary file containing the statement that was entered. Reading from that file obtains the char- acters of the statement in turn; end-of-file is reported when the end of the statement is reached. Normally, this file is used as an operand , causing the statement to be executed as a PostScript lan- to exec guage program. 3.8 File Input and Output 79

88 PLRM 2nd Edition January 21, 1994 Language %lineedit special file is similar to . However, the file The %statementedit operator returns after a single line has been entered, regardless of whether it constitutes a complete statement. If the standard input file reaches end-of-file before any characters have been entered, the file operator issues an undefinedfilename error. file for the It is important to understand that the file object returned by and %statementedit special files is not the same as the stan- %lineedit dard input file. It represents a temporary file containing a single buff- ered statement. When the end of that statement is reached, the file is closed and the file object is no longer of any use. Successive executions of for %statementedit and %lineedit return different file objects. file and special files are not available in Post- The %statementedit %lineedit Script interpreters that do not support an interactive executive. Post- Script language programs that are page descriptions should never refer to these files. 3.8.4 Filters A filter is a special kind of file object that can be layered on top of some other file to transform data being read from or written to that file. When a PostScript language program reads characters from an input filter, the filter reads characters from its underlying file and transforms the data in some way, depending on the filter. Similarly, when a pro- gram writes characters to an output filter, the filter transforms the data and writes the results to its underlying file. Filters are a Level 2 feature. There are two main classes of filters: •An encoding filter is an output file that takes the data written to it, converts them to some encoded representation depending on the filter, and writes the encoded data to the underlying file. For exam- ple, the ASCIIHexEncode filter transforms binary data to an ASCII hexadecimal encoded representation, which it writes to its underly- ing file. All encoding filters have “Encode” as part of their names. •A decoding filter is an input file that reads encoded data from its underlying file and decodes them. The program reading from the filter receives the decoded data. For example, the ASCIIHexDecode filter reads ASCII hexadecimal encoded data from its underlying file and transforms them to binary. All decoding filters have “Decode” as part of their names. 80 Chapter 3: Language

89 PLRM 2nd Edition Language January 21, 1994 Decoding filters are most likely to be used in page descriptions. An application program generating a page description can encode certain information (for example, data for sampled images) to compress it or to convert it to a portable ASCII representation. Then, within the page description itself, it invokes the corresponding decoding filter to con- vert the information back to its original form. Encoding filters are unlikely to be used in most page descriptions. How- ever, a PostScript language program can use them to encode data to be sent back to the application or written to a disk file. In the interest of symmetry, the PostScript language supports both encoding and decod- ing filters for all of its standard data transformation algorithms. Creating Filters operator, which is a Level 2 feature. Filter files are created by the filter The operator expects the following operands in the order given: filter 1. A data source or data target . This is ordinarily a file object that represents the underlying file the filter is to read or write. However, it can also be a string or a procedure. This is described in section 3.13, “Filtered Files Details.” 2. Filter parameters . Some filters require additional parameters to con- trol how they operate. This information must be given as one or more operands following the data source or target. Most filters require no additional parameters. 3. ASCIIHexDecode , that . This is a name object, such as Filter name specifies the data transformation the filter is to perform. It also deter- mines how many parameters there are and how they are to be inter- preted. filter operator returns a new file object that represents the filtered The file. For an encoding filter, this is an output file, and for a decoding filter, an input file. The direction of the underlying file—that is, its read/write attribute—must match that of the filter. Filtered files can be used just the same as other files; they are valid as operands to file opera- tors such as read , write , readstring , and writestring . Input filters are also valid as data sources for operators such as exec or image . Since a filter is itself a file, it can be used as the underlying file for yet that passes the another filter. One can cascade filters to form a pipeline data stream through two or more encoding or decoding transforma- tions in sequence. Example 3.5, “ illustrates the construction of an 3.8 File Input and Output 81

90 PLRM 2nd Edition Language January 21, 1994 input pipeline for decoding sampled image data that is embedded in the program. The application has encoded the image data twice: once RunLengthEncode method to compress the data and then using the ASCII85Encode using the method to represent the binary compressed data as ASCII text. Example 3.5 256 256 8 [256 0 0 –256 0 256] % Other operands of image operator currentfile /ASCII85Decode filter /RunLengthDecode filter image ...Encoded image data... ~> % ASCII85 end-of-data marker The currentfile operator returns the file object from which the Post- Script interpreter is currently executing. The first execution of filter cre- ates an ASCII85Decode filter whose underlying file is the one returned . It pushes the filter file object on the stack. The second currentfile by execution of creates a RunLengthDecode filter whose underlying filter file is the first filter file; it pushes the new filter file object on the stack. Finally, the image operator uses the second filter file as its data source. As image reads from its data source, the data are drawn from the under- lying file and transformed by the two filters in sequence. Standard Filters The PostScript language supports a standard set of filters. These filters fall into three main categories. Each category includes encoding and decoding filters. ASCII encoding filters enable arbitrary 8-bit binary data to be repre- • sented in the printable subset of the ASCII character set. This improves the portability of the resulting data, since it avoids the problem of interference by operating systems or communication channels that pre-empt use of control characters, represent text as 7- bit bytes, or impose line-length restrictions. • Compression and decompression filters enable data to be represented in a compressed form. This is particularly valuable for large sampled images. Compressing the image data reduces storage requirements and transmission time. There are several compression filters, each of which is best suited for particular kinds of image data. Note that the 82 Chapter 3: Language

91 PLRM 2nd Edition Language January 21, 1994 compressed data is in 8-bit binary form. For maximum portability of the encoded data, these filters should be used with ASCII encoding filters, as illustrated in Example 3.5, “. Subfile filters pass data through without modification. These filters • permit the creation of file objects that access arbitrary user-defined data sources or data targets. Input filters also can read data from an underlying file up to a specified end-of-data marker. Table 3.6 summarizes the available filters. A program can determine the complete list of filters that the PostScript interpreter supports by apply- ing the resourceforall operator to the Filter category; see section 3.9, “Named Resources.” Standard filters Table 3.6 Filter name Parameters Semantics ASCIIHexEncode (none) Encodes binary data in an ASCII hexadecimal representation. Each binary data byte is converted to two hexadecimal digits, resulting in an expansion factor of 1:2 in the size of the encoded data. ASCIIHexDecode (none) Decodes ASCII hexadecimal encoded data, producing the original binary data. Encodes binary data in an ASCII base-85 representation. This encoding uses (none) ASCII85Encode nearly all of the printable ASCII character set. The resulting expansion factor is 4:5, making this encoding much more efficient than hexadecimal. (none) ASCII85Decode Decodes ASCII base-85 encoded data, producing the original binary data. LZWEncode (none) Compresses text or binary data using the LZW (Lempel-Ziv-Welch) adaptive compression method. This is a good general-purpose encoding that is especially well-suited for English language and PostScript language text. (none) Decompresses LZW encoded data, producing the original text or binary data. LZWDecode RunLengthEncode recordsize Compresses binary data using a simple byte-oriented run-length encoding algo- rithm. This encoding is best suited to monochrome image data, or any data that contain frequent long runs of a single byte value. (none) Decompresses run-length encoded data, producing the original binary data. RunLengthDecode CCITTFaxEncode dictionary Compresses binary data using a bit-oriented encoding algorithm (the CCITT fac- simile standard). This encoding is specialized to monochrome image data at 1 bit per pixel. CCITTFaxDecode dictionary Decompresses facsimile encoded data, producing the original binary data. DCTEncode dictionary Compresses continuous-tone (gray-scale or color) sampled image data using a DCT (discrete cosine transform) technique based on the proposed JPEG stan- dard. This encoding is specialized to image data. It is “lossy,” meaning that the encoding algorithm can lose some information. 3.8 File Input and Output 83

92 PLRM 2nd Edition January 21, 1994 Language dictionary Decompresses DCT encoded data, producing image sample data that approxi- DCTDecode mate the original data. (none) Passes all data through, without any modification. This permits an arbitrary data NullEncode target (procedure or string) to be treated as an output file. SubFileDecode count, string Passes all data through, without any modification. This permits an arbitrary data source (procedure or string) to be treated as an input file. Optionally, this filter detects an end-of-data marker in the source data stream, treating the preceding data as a subfile. Section 3.13, “Filtered Files Details,” has complete information about individual filters, including specifications of the encoding algorithms for some of them. The section also describes the semantics of data sources and data targets in more detail. 3.8.5 Additional File Operators There are other miscellaneous file operators: status and • return status information about a file. bytesavailable • currentfile returns the file object from which the interpreter is cur- rently reading. file is a convenience operator that combines the functions of • run and . exec Several built-in procedures print the values of objects on the operand stack, sending a readable representation of those values to the standard output file: = pops one object from the operand stack and writes a text represen- • tation of its value to the standard output file, followed by a newline. == but produces results closer to full PostScript lan- is similar to =, • guage syntax and expands the values of arrays. • stack prints the entire contents of the operand stack with =, but leaves the stack unchanged. . • pstack performs a similar operation to stack , but uses == Input/output and storage devices can be manipulated individually by Level 2 operators. In particular: 84 Chapter 3: Language

93 PLRM 2nd Edition January 21, 1994 Language setdevparams currentdevparams access device-dependent • and parameters (see Appendix C). resourceforall , applied to the IODevice category, enumerates all • available devices (see section 3.9, “Named Resources”). 3.9 Named Resources The PostScript language has various features involving the use of open- ended collections of objects to control what the features do. For exam- ple, the font machinery uses font dictionaries that describe the appear- ance of characters. The number of possible font dictionaries is unlimited. For Level 2 implementations this same idea applies to forms, patterns, color rendering dictionaries, and many other categories of objects. It is often convenient to associate these objects with names in some central registry. This is particularly true for fonts, which are assigned Palatino-BoldItalic or standard names, such as Times-Roman , when they are created. Other categories of objects also can benefit from a central naming convention. If all available objects in a particular category (for example, all possible fonts) were permanently resident in VM, they could simply be stored in some dictionary. Accessing a named object would be a matter of per- forming get from the dictionary; checking if a named object is available known would be accomplished by performing a on the dictionary. There are many more fonts and objects of other categories than can possibly reside in VM at any given time. These objects originate from a source external to the PostScript interpreter. They are introduced into VM in two ways: 1. The application or spooler embeds the objects’ definitions directly in the job stream. 2. During execution, the PostScript language program requests the objects by name. The interpreter loads them into VM automatically from an external source, such as a disk file, a ROM cartridge, or a net- work file server. The notion of “named resources” supports the second method. A resource is a collection of named objects that either reside in VM or can be located and brought into VM on demand. There are separate catego- 3.9 Named Resources 85

94 PLRM 2nd Edition Language January 21, 1994 ries of resources with independent name spaces. For example, fonts and forms are distinct resource categories. Within each category, there is a collection of named resource instances. Some instances are objects that reside in VM, while others exist in some external form that can be brought into VM on demand. Each category can have its own policy for locating instances that are not in VM and for managing the instances that are in VM. Resource Operators 3.9.1 There are five operators that apply to resources: findresource , . resourcestatus , resourceforall , defineresource , and undefineresource These operators and the general concept of named resources are Level 2 findfont features. A more limited facility applicable only to fonts—the and definefont operators—is available in Level 1. The findresource operator is the key feature of the resource facility. Given a resource category name and an instance name, findresource returns an object. If the requested resource instance does not already gets it from an external source exist as an object in VM, findresource and loads it into VM. A PostScript language program can access named resources without knowing if they are already in VM or how they are obtained from external storage. resourcestatus , which returns infor- Other important features include mation about a resource instance, and resourceforall , which enumer- ates all available resource instances in a particular category. These operators apply to all resource instances, whether or not they reside in VM; the operators do not cause the resource instances to be brought into VM. resourceforall should be used with care and only when abso- lutely necessary, since the set of available resource instances is poten- tially extremely large. A program can explicitly define a named resource instance in VM. That is, it can create an object in VM, then execute defineresource to associ- ate the object with a name in a particular resource category. This resource instance will be visible in subsequent executions of , resourcestatus , and resourceforall . A program can also findresource execute undefineresource to reverse the effect of a prior defineresource . The findresource operator automatically executes defineresource and to manage the VM for resource instances that it undefineresource obtains from external storage. 86 Chapter 3: Language

95 PLRM 2nd Edition January 21, 1994 Language Resource instances can be defined in either local or global VM. The life- time of the definition depends on the VM allocation mode in effect at the time the definition is made (see section 3.7.2, “Local and Global VM”). Normally, both local and global resource instances are visible and available to a program. However, when the current VM allocation mode is global, only global instances are visible; this ensures correct behavior of resource instances that are defined in terms of other resource instances. defineresource to define a resource instance When a program executes explicitly, it has complete control over whether to use local or global VM. However, when execution of findresource causes a resource instance to be brought into VM automatically, the decision whether to use local or global VM is independent of the VM allocation mode at the time findresource is executed. Usually, resource instances are loaded into global VM; this enables them to be managed independently of the activity of the executing program. However, certain restore save and resource instances do not function correctly when they reside in global VM; they are loaded into local VM instead. The language does not specify a standard method for installing resources in external storage. Installation typically consists of writing a named file in a file system. However, details of how resource names are mapped to file names and how the files are managed are environment dependent. In some environments, resources may be installed using facilities entirely separate from the PostScript interpreter. Resource instances are identified by keys that ordinarily are name or string objects; the resource operators treat names and strings equiva- lently. Use of other types of keys is permitted but not recommended. The defineresource operator can define a resource instance with a key that is not a name or string; the other resource operators can access the instance using that key. However, such a key can never match any resource instance in external storage. 3.9.2 Resource Categories Resource categories are identified by name. The standard resource cate- gories are in the following tables. Within a given category, every resource instance that resides in VM is of a particular type and has a particular intended interpretation or use. 3.9 Named Resources 87

96 PLRM 2nd Edition Language January 21, 1994 Regular resources Table 3.7 Object type Interpretation Category name dictionary Font dictionary Font array Encoding vector Encoding Form dictionary Form definition Pattern dictionary Pattern definition (prototype) ProcSet Procedure set dictionary ColorSpace array Parameterized color space Halftone dictionary Halftone dictionary ColorRendering dictionary Color rendering dictionary Table 3.8 Resources whose instances are implicit Category name Object type Interpretation Filter algorithm name Filter ColorSpaceFamily Color space family name Emulator name Language interpreter IODevice string Input/output or storage device ColorRenderingType integer Color rendering dictionary type FMapType integer Composite font mapping algorithm FontType integer Font dictionary type FormType integer Form dictionary type HalftoneType Halftone dictionary type integer ImageType integer Image dictionary type PatternType integer Pattern dictionary type Table 3.9 Resources used in defining new resource categories Category name Object type Interpretation Category dictionary Resource category (recursive) Prototype for new categories any Generic 88 Chapter 3: Language

97 PLRM 2nd Edition January 21, 1994 Language are those whose instances are ordinary useful objects, Regular resources such as font or halftone dictionaries. For example, a program typically as an operand of some other uses the result returned by findresource or sethalftone . scalefont operator, such as Implicit resource s are those whose instances are not objects, but which represent some built-in capability of the PostScript interpreter. For example, the instances of the Filter category are filter names, such as and CCITTFaxDecode ASCII85Decode , that are passed directly to the filter findresource operator returns operator. For such resources, the resourceforall resourcestatus are only its name operand. However, and useful for inquiring about the availability of capabilities, such as spe- cific filter algorithms. The and Generic resources are used in defining new categories Category of resources. This is described in section 3.9.3, “Creating Resource Cate- gories.” , resourceforall The resource operators— findresource , resourcestatus , defineresource —have standard behavior that is undefineresource , and uniform across all resource categories. This behavior is specified in the operator descriptions in Chapter 8. For some categories, the operators have additional semantics that are category specific. The following sec- tions describe the semantics of each resource category. Font resource category are font names, such as Instance names of the Font Times-Roman . The instances are prototype font dictionaries. Those instances are suitable for use as operands to scalefont or makefont , pro- ducing a transformed font dictionary that can be used to paint charac- ters on the page. There are several special-purpose operators that apply only to fonts, but are otherwise equivalent to the resource operators: • is equivalent to /Font findresource findfont • definefont is equivalent to /Font defineresource • undefinefont is equivalent to /Font undefineresource The definefont and undefinefont operators have additional font-spe- cific semantics, which are described under those operators. Those when undefineresource semantics also apply to defineresource and 3.9 Named Resources 89

98 PLRM 2nd Edition Language January 21, 1994 Font definefont findfont and applied to the are available in category. Level 1 implementations, even though the general facility for named resources exists only in Level 2. The font operators also maintain dictionaries of font names and instances that are defined in VM. Those dictionaries are FontDirectory (only fonts in global VM). (all fonts in VM) and GlobalFontDirectory They are provided solely for compatibility with existing applications, which use them to enumerate the defined fonts; they are obsolete. The preferred method of enumerating all available fonts is: (*) proc scratch /Font resourceforall where proc is a procedure and scratch is a string used repeatedly to hold font names. This method works for all available fonts, whether or not to deter- they are in VM. Normally, it’s preferable to use resourcestatus mine the availability of specific resources rather than enumerate all resources and check whether those of interest are in the list. Encoding Encoding resource category are array objects, suitable Instances of the Encoding entry of font dictionaries (see section 5.3, for use as the “Character Encoding”). An encoding array usually contains 256 names, permitting it to be indexed by any 8-bit character code. An encoding array for use with composite fonts contains integers instead of names, and can be of any length. There are two standard encodings that are permanently defined in VM and available by name in systemdict . If any other encodings exist, they are available only through findresource . There are three special-purpose operators that apply only to encodings, but are otherwise equivalent to the resource operators: • StandardEncoding is equivalent to /StandardEncoding /Encoding findresource • ISOLatin1Encoding is equivalent to /ISOLatin1Encoding /Encoding findresource /Encoding findresource is equivalent to • findencoding 90 Chapter 3: Language

99 PLRM 2nd Edition January 21, 1994 Language Form Instances of the Form resource category are form dictionaries, described in section 4.7, “Forms.” A form dictionary is suitable as the operand to to render the form on the page. There are no standard execform instances of this resource category. Pattern Instances of the Pattern resource category are prototype pattern dic- tionaries, described in section 4.9, “Patterns.” A prototype pattern dic- makepattern tionary is suitable as the operand to , producing a transformed pattern dictionary describing a tiling that is locked to device space. This pattern can then be used in painting operations by establishing a Pattern setpattern opera- color space or by invoking the tor. There are no standard instances of this resource category. ProcSet procedure sets resource category are Instances of the ProcSet or procsets. A procset is a dictionary containing named procedures. Application prologs can be organized as one or more procsets that are available from a library instead of being included in-line in every document that uses them. The ProcSet resource category is a way to organize such a library. There are no standard instances of this resource category. ColorSpace ColorSpace resource category are array objects that rep- Instances of the resent fully parameterized color spaces. The first element of a color space array is a color space family name; the remaining elements are parameters to the color space. See section 4.8, “Color Spaces.” There are no standard instances of this resource category. ColorSpaceFamily The ColorSpace resource category is distinct from the Note category, described below. Halftone Instances of the Halftone resource category are halftone dictionaries, sethalftone suitable as operands to the operator (see section 6.4, “Half- tones”). There are no standard instances of this resource category. 3.9 Named Resources 91

100 PLRM 2nd Edition January 21, 1994 Language ColorRendering Instances of the ColorRendering resource category are color rendering operator (see setcolorrendering dictionaries, suitable as operands to the section 6.1, “CIE-Based Color to Device Color”). There are no standard instances of this resource category. Implicit Resources operator returns the For all implicit resources, the findresource and resourcestatus instance’s key if the instance is defined. The resourceforall operators have their normal behavior, although the and status values returned by resourcestatus are meaningless. The size defineresource operator is ordinarily not allowed, but the ability to define new instances of implicit resources may exist in some implemen- tations. The mechanisms are implementation dependent. Filter category are filter names, such as The instances of the and ASCII85Decode , which are used as an operand RunLengthEncode of the filter operator to determine its behavior. Filters are described in section 3.8.4, “Filters.” category are color space family ColorSpaceFamily The instances of the names, which appear as the first element of a color space array object. DeviceRGB, are determined by their family Some color spaces, such as name; others, such as CIEBasedABC , require additional parameters to describe them. Color spaces are described in section 4.8, “Color Spaces.” The instances of the Emulator category are names of emulators for lan- guages other than PostScript that may be built into a particular implementation. Those emulators are not a standard part of the Post- Script language, but one or more of them may be present in some prod- ucts. The instances of the IODevice category are names of input/output and storage devices, expressed as strings of the form % . See section device % 3.8.2, “Named Files,” and section C.4, “Device Parameters.” , The instances of the ColorRenderingType , FMapType , FontType categories are FormType , HalftoneType , ImageType , and PatternType integers that are the acceptable values for the correspondingly named entries in various classes of special dictionaries. For example, the 92 Chapter 3: Language

101 PLRM 2nd Edition Language January 21, 1994 category always includes the integers 0, 1, and 3 as keys. If an FontType FontType values, the FontType category interpreter supports additional will also include those values as instances. Creating Resource Categories 3.9.3 The language support for named resources is quite general. Most of it is independent of the semantics of specific resource categories. It’s occa- sionally useful to create new resource categories, each containing an independent collection of named instances. This is accomplished through a level of recursion in the resource machinery itself. The resource category named Category contains all of the resource cate- gories as instances. The instance names are resource category names, Font, Form , and Halftone . The instance values are dictionary such as objects, each containing information about how the resource category is implemented. A new resource category is created by defining a new instance of the Category category. Example 3.6 creates a Widget category. Example 3.6 true setglobal catdict /Category defineresource pop /Widget false setglobal catdict is a dictionary describing the implementation of In this example, the Widget category. Once defined, one can manipulate instances of the Widget category like other categories: /Frob1 w /Widget defineresource % Returns w /Frob1 /Widget findresource % Returns w /Frob1 /Widget resourcestatus % Returns true status size (*) /Widget resourceforall % Pushes (Frob1) on stack, proc scratch % then calls proc In this example, w is an instance of the Widget category whose type is whatever is appropriate for widgets. /Frob1 is the name of that instance. It is possible to redefine existing resource categories this way. Make sure the new definition correctly implements any special semantics of the category. 3.9 Named Resources 93

102 PLRM 2nd Edition January 21, 1994 Language Category Implementation Dictionary The behavior of all the resource operators, such as defineresource , is determined by entries in the resource category’s implementation dic- tionary. This was supplied as an operand to defineresource when the category was created. In the example /Frob1 /Widget defineresource w the defineresource operator: 1. Obtains catdict , the implementation dictionary for the Widget cate- gory. 2. Executes on the implementation dictionary. begin 3. Executes the DefineResource entry in the dictionary, which is ordi- narily a procedure, but might be an operator. When the procedure DefineResource entry is called, the operand corresponding to the stack contains the operands that were passed to defineresource , except the category name ( Widget in this example) has been removed. DefineResource is expected to consume the remaining operands, perform whatever action is appropriate for this resource category, and return the appropriate result. operator. If an error occurred during step 3, it also 4. Executes the end restores the operand and dictionary stacks to their initial state. The other resource operators— , findresource , undefineresource resourcestatus , and resourceforall —behave the same way, with the exception that resourceforall does not restore the stacks upon error. Aside from the steps described above, all of the behavior of the resource operators is implemented by the corresponding procedures in the dic- tionary. A category implementation dictionary contains the following entries: Table 3.10 Entries in a category implementation dictionary Key Type Semantics ( DefineResource procedure Required ) Implements defineresource behavior. UndefineResource ( Required ) Implements undefineresource behavior. procedure behavior. procedure ( Required ) Implements findresource FindResource behavior. resourcestatus ResourceStatus procedure ( Required ) Implements 94 Chapter 3: Language

103 PLRM 2nd Edition January 21, 1994 Language ResourceForAll procedure ( Required ) Implements resourceforall behavior. when the category is Category name ( Required ) The category name. Inserted by defineresource defined. name ( Optional ) The expected type of instances of this category. If this entry is present, InstanceType defineresource checks that the instance’s type, as returned by the type operator, matches it. ResourceFileName procedure ( Optional ) Translates a resource instance name to a file name (see below). The dictionary may also contain other information useful to the proce- dures in the dictionary. Since the dictionary is on the dictionary stack at the time those procedures are called, the procedures can access the information conveniently. A single dictionary provides the implementation for both local and glo- bal instances of a category. The implementation must maintain the local and global instances separately and must respect the VM alloca- tion mode in effect at the time each resource operator is executed. The category implementation dictionary must be in global VM; the that installs it in the Category category must be exe- defineresource cuted while in global VM allocation mode. Generic Category The preceding section describes a way to define a new resource cate- gory, but it does not provide guidance about how the individual proce- dures in the category’s dictionary should be implemented. In principle, every resource category has complete freedom over how to organize and manage resource instances, both in VM and in external storage. Since different implementations have different conventions for orga- nizing resource instances, especially in external storage, a program that seeks to create a new resource category might need implementation- dependent information. To overcome this problem, it is useful to have a generic resource implementation that can be copied and used to define new resource categories. The Category category contains an instance named Generic, whose value is a dictionary containing a generic resource implementation. The following example of defining the Widget resource category is simi- lar to Example 3.6 on page 93. However, Example 3.7 generates the cat- egory implementation dictionary by copying the one belonging to the Generic category. This avoids the need to know anything about how resource categories actually work. 3.9 Named Resources 95

104 PLRM 2nd Edition Language January 21, 1994 Example 3.7 true setglobal /Generic /Category findresource dup length 1 add dict copy dup /InstanceType /dicttype put /Widget exch /Category defineresource pop false setglobal The Generic resource category’s implementation dictionary does not have an InstanceType entry; instances need not be of any particular type. In the above example, the third line makes a copy of the diction- ary with space for one additional entry. The fourth line inserts an InstanceType entry with value dicttype . As a result, defineresource requires that instances of the Widget category be dictionaries. 3.9.4 Resources as Files The PostScript language does not specify how external resources are installed, how they are loaded, or what correspondence, if any, exists between resource names and file names. In general, all knowledge of such things is in the category implementation dictionary and in envi- ronment-dependent installation software. Typically, resource instances are installed as named files, which can also file and run . be accessed by ordinary PostScript file operators such as There is a straightforward mapping from resource names to file names, though the details of this mapping vary because of restrictions on file name syntax imposed by the underlying file system. In some implementations, including many dedicated printers, the only access to the file system is through the PostScript interpreter. In such environments, it is important for PostScript language programs to be able to access the underlying resource files directly to install or remove them. Only resource installation or other system management software should do this. Page descriptions should never attempt to access resources as files; they should use only resource operators, such as findresource . The implementation dictionary for a category can contain an optional , which is a procedure that translates from a entry, ResourceFileName resource name to a file name. If the procedure exists, a program can call it as follows: 96 Chapter 3: Language

105 PLRM 2nd Edition Language January 21, 1994 1. Push the category implementation dictionary on the dictionary stack. The ResourceFileName procedure requires this to obtain cate- gory-specific information, such as Category . 2. Push the instance name and a scratch string on the operand stack. The scratch string must be long enough to accept the complete file name for the resource. . 3. Execute ResourceFileName 4. Pop the dictionary stack. builds a complete file name in the scratch string and ResourceFileName returns the substring that was used on the operand stack. This string operand of file operators, such as filename file can then be used as the , deletefile , status , and so on. For example, the following program frag- font: ment obtains the file name for the Times-Roman /Font /Category findresource begin /Times-Roman ResourceFileName scratch end If this is successful, it leaves a string on the operand stack, such as %font%Times-Roman or %os%C:\FONT\TIMESRMN.PS , that can be used as the name of the font file. This file name uniquely identifies the file containing the resource definition for the specified category and instance names. It also conforms to all restrictions imposed by the underlying file system. There may be a limit on the length of a resource file name, which in turn imposes a length limit on the instance name. The inherent limit on resource instance names is the same as that on name objects in gen- eral (see Appendix B). By convention, font names are restricted to fewer than 40 characters. This convention is recommended for other resource categories as well. Note that the resource file name may be longer or shorter than the resource instance name, depending on details of the , it is pru- name-mapping algorithm. When calling ResourceFileName dent to provide a scratch string at least 100 characters long. A resource file contains a PostScript language program that can be exe- cuted to load the resource instance into VM. The last action the pro- gram should do is execute defineresource or an equivalent operator, , to associate the resource instance with a category such as definefont and a name. In other words, each resource file must be self-identifying 3.9 Named Resources 97

106 PLRM 2nd Edition Language January 21, 1994 and self-defining. The resource file must be well-behaved: it must leave the stacks in their original state and it must not execute any operators (graphics operators, for instance) not directly related to creating the resource instance. For most resource categories, the implementation of findresource exe- cutes true setglobal prior to executing the resource file. As a result, the resource instance is loaded into global VM and defineresource defines the resource instance globally. Unfortunately, certain resource instances behave incorrectly if they reside in global VM. Some means are required to force such resources to be loaded into local VM instead. Two meth- ods are currently used. for the findresource category makes the Font • The implementation of decision based on the FontType of the font being loaded. If the prior to executing FontType is 1, findresource executes true setglobal the font file; otherwise, it leaves the VM allocation mode unchanged. This is based on the assumption that Type 1 fonts always behave correctly in global VM but the behavior of Type 3 fonts is unpredictable. • For other resource categories, the implementation of findresource always executes true setglobal . This is based on the assumption that resource instances normally behave correctly in global VM. If a par- ticular instance is known not to work in global VM, the resource file should begin with an explicit false setglobal . See the explanation of the %%VMlocation convention in section G.6, “Requirement Con- ventions.” A resource file can contain header comments, as specified in Appendix G. If there is a header comment of the form int int %%VMusage: then the resourcestatus operator returns the larger of the two integers as its size result. If the %%VMusage comment is not present, resourcestatus may not be able to determine the VM consumption for the resource instance; it will return a size of –1. The definition of an entire resource category—that is, an instance of the category—can come from a resource file in the normal way. If Category any resource operator is presented with an unknown category name, it 98 Chapter 3: Language

107 PLRM 2nd Edition Language January 21, 1994 automatically executes category /Category findresource in an attempt to cause the resource category to become defined. Only if undefined that fails will the resource operator generate an error to report that the resource category is unknown. 3.10 Errors Various sorts of errors can occur during execution of a PostScript lan- guage program. Some errors are detected by the interpreter, such as overflow of one of the PostScript interpreter’s stacks. Others are detected during execution of the built-in operators, such as occurrence of the wrong type of operand. Errors are handled in a uniform fashion that is under the control of the PostScript language program. Each error is associated with a name, such as stackoverflow or typecheck . Each error name appears as a key in a special dictionary called errordict and is associated with a value that is the handler for that error. The complete set of error names appears in section 8.1, “Operator Summary.” Error Initiation 3.10.1 When an error occurs, the interpreter 1. Restores the operand stack to the state it was when it began execut- ing the current object. 2. Pushes that object onto the operand stack. errordict and executes the associated 3. Looks up the error’s name in error handler for that error. value, which is the This is everything the interpreter itself does in response to an error. The error handler in errordict is responsible for all other actions. A Post- Script language program can modify error behavior by defining its own error-handling procedures and associating them with the names in errordict . The interrupt and timeout errors, which are initiated by events external to the PostScript interpreter, are treated specially. The interpreter errordict , sandwiched merely executes interrupt or timeout from 3.10 Errors 99

108 PLRM 2nd Edition January 21, 1994 Language between execution of two objects being interpreted in normal sequence. It does not push the object being executed, nor does it alter the operand stack in any other way. In other words, it omits steps 1 and 2 above. Error Handling 3.10.2 errordict present in the initial state of VM provides standard han- The dlers for all errors. However, errordict is a writable dictionary; a pro- errordict is in gram can replace individual error handlers selectively. save and restore ; see section 3.7, “Memory local VM, so changes obey Management.” The default error handler procedures all operate in a standard way. They record information about the error in a special dictionary named $error stop . They do , set the VM allocation mode to local, and execute not print anything. Execution of stop exits the innermost enclosing context established by stopped stopped , inter- . Assuming the user program has not invoked pretation continues in the job server, which invoked the user program with stopped . In a Display PostScript execution context that is not under the control of a job server, interpretation continues in the con- resyncstart start text’s outer-level procedure. or As part of error recovery, the job server executes the name handleerror from errordict . The default handleerror procedure accesses the error information in the $error dictionary and reports the error in an instal- lation-dependent fashion. In some environments, handleerror simply writes a text message to the standard output file. In other environ- ments, it invokes more elaborate error-reporting mechanisms. In a Dis- play PostScript system, handleerror normally transmits a binary object sequence back to the application (see section 3.12.6, “Structured Out- put”). After an error occurs, $error contains the key-value entries as shown in Table 3.11. Entries in the $error dictionary Table 3.11 Key Type Value . boolean Set to true to indicate that an error has occurred. handleerror sets it to false newerror name The name of the error that was invoked. errorname 100 Chapter 3: Language

109 PLRM 2nd Edition Language January 21, 1994 any command The operator or other object being executed by the interpreter at the time the error occurred. array If the error was a configurationerror caused by errorinfo or setdevparams , setpagedevice this array contains the key and value of the request that could not be satisfied. ostack array A snapshot of the entire operand stack immediately before the error, stored as if by the astore operator. estack A snapshot of the execution stack, stored as if by the execstack operator. array dstack array A snapshot of the dictionary stack, stored as if by the dictstack operator. recordstacks boolean ( Level 2 ) Controls whether the standard error handlers record the ostack , estack , false in a Display PostScript and dstack snapshots. Default value: true in a printer, system. boolean ( Level 2 ) Controls the format of error reports produced by the standard binary handleerror procedure. false produces a text message; true produces a binary object sequence. Default value: false in a printer, true in a Display PostScript sys- tem. A program that wishes to modify the behavior of error handling can do so in one of two ways. First, it can change the way errors are reported handleerror simply by redefining in errordict . For example, a revised error handler might report more information about the context of the error, or it might produce a printed page containing the error informa- tion instead of reporting it to the standard output file. Second, a program can change the way errors are invoked by redefining the individual error names in errordict . There is no restriction on what an error-handling procedure can do. For example, in an interactive environment, an error handler might invoke a debugging facility that would enable the user to examine or alter the execution environment and perhaps resume execution. 3.11 Early Name Binding Normally, when the PostScript language scanner encounters an execut- able name in the program being scanned, it simply produces an execut- able name object; it does not look up the value of the name. It looks up the name only when the name object is executed by the interpreter. The lookup occurs in the dictionaries on the dictionary stack at the time of execution . 3.11 Early Name Binding 101

110 PLRM 2nd Edition Language January 21, 1994 A name object contained in a procedure is looked up each time the pro- cedure is executed. For example, given the definition /average {add 2 div} def add and div are looked up, yielding operators to be executed, the names average procedure is invoked. every time the This so-called late binding of names is an important feature of the Post- Script language. However, there are situations in which early binding is advantageous. There are two facilities for looking up the values of bind operator and the immediately evalu- names before execution: the ated name . 3.11.1 bind Operator bind performs early name binding on entire procedures. bind looks up all the executable names in a procedure. For each name whose value is operator (not an array, procedure, or other type), it replaces the name an with the operator object. This lookup occurs in the dictionaries on the bind is executed. The effect of bind applies dictionary stack at the time not only to the procedure, but to all subsidiary procedures (executable arrays) nested to arbitrary depth. When the interpreter executes this procedure, it encounters the operator objects , not the names of operators. For example, if the average proce- dure has been defined this way: /average {add 2 div} bind def then during execution of and average , the interpreter executes the add div add and div . operators directly, without looking up the names There are two main benefits of using bind : • A procedure that has been bound will execute the sequence of opera- tors that were intended when the procedure was defined, even if one or more of the operator names have been redefined in the meantime. • A bound procedure executes somewhat faster than one that has not been bound, since the interpreter need not look up the operator names each time, but can execute the operators directly. 102 Chapter 3: Language

111 PLRM 2nd Edition January 21, 1994 Language The first benefit is mainly of interest in procedures that are part of the PostScript implementation, such as = . Those procedures findfont and are expected to behave correctly and uniformly, regardless of how a user program has altered its name environment. The second benefit is of interest in most PostScript language programs, particularly in the prologs of page descriptions. It is worthwhile to to any procedure that will be executed more than a few apply bind times. bind replaces only those names It is important to understand that operators at the time whose values are is executed. Names whose bind values are of other types, particularly procedures, are not disturbed. If an operator name has been redefined in some dictionary above systemdict before execution of bind , occurrences on the dictionary stack of that name in the procedure will not be replaced. Certain standard language features, such as findfont , are implemented as Note built-in procedures instead of as operators. Also, certain names, such as true , , are associated directly with literal values in . false , and null systemdict Occurrences of such names in a procedure are not altered by . bind 3.11.2 Immediately Evaluated Names Level 2 implementations and many Level 1 implementations (see Appendix A) include a syntax feature called the immediately evaluated name . When the PostScript language scanner encounters a token of the // name (a name preceded by two slashes with no intervening form spaces), it immediately looks up the name and substitutes the corre- sponding value for the name. This lookup occurs in the dictionaries on the dictionary stack at the time the scanner encounters the token. If it can’t find the name, an undefined error occurs. The substitution occurs immediately , even inside an executable array delimited by and } , where execution is deferred. Note that this process { is a substitution and not an execution ; that is, the name’s value is not exe- cuted, but rather is substituted for the name itself, just as if the load operator were applied to the name. The most common use of immediately evaluated names is to perform early binding of objects (other than operators) in procedure definitions. operator, described in section 3.11.1, “bind Operator,” per- The bind forms early binding of operators; to bind objects of other types, explicit use of immediately evaluated names is required. 3.11 Early Name Binding 103

112 PLRM 2nd Edition Language January 21, 1994 Example 3.8, “ illustrates using an immediately evaluated name to bind a reference to a dictionary. Example 3.8 /mydict << ... >> def /proc { //mydict begin ... end } bind def proc In the definition of is an immediately evaluated name. At , //mydict the moment the scanner encounters the name, it substitutes the name’s current value, which is the dictionary defined earlier in the example. The first element of the proc executable array is a dictionary object, not a name object. When proc is executed, it will access that dictionary, has been redefined or the definition has even if in the meantime mydict been removed. Another use of immediately evaluated names is to refer directly to per- manent objects: standard dictionaries, such as , and constant systemdict true , false , and null . On the other literal objects, such as the values of hand, it does not make sense to treat the names of variables as immedi- ately evaluated names. Doing so would cause a procedure to be irrevo- cably bound to particular values of those variables. A word of caution is in order. Indiscriminate use of immediately evalu- ated names may change the semantics of a program. As discussed in section 3.5, “Execution,” the behavior of a procedure differs depending on whether the interpreter encounters it directly or as the result of exe- cuting some other object (a name or operator). Execution of the pro- gram fragments {... b ...} {... //b ...} will have different effects if the value of the name b is a procedure. So, it is inadvisable to treat the names of operators as immediately evalu- ated names. A program that does so will malfunction in an environ- ment in which some operators have been redefined as procedures. This bind is why applies only to names whose values are operators, not pro- cedures or other types. 104 Chapter 3: Language

113 PLRM 2nd Edition Language January 21, 1994 3.12 Binary Encoding Details In Level 2 and the Display PostScript system, the scanner recognizes two encoded forms of the PostScript language in addition to ASCII. These are binary token encoding and binary object sequence encoding. All three encoding formats can be mixed in any program. The binary encodings are intended for machine generation. Display PostScript system applications are further encouraged to make use of facilities, available from vendors of Client Library and pswrap the systems that support the Display PostScript system. The binary token encoding represents elements of the PostScript lan- guage as individual syntactic entities. This encoding emphasizes com- pactness over efficiency of generation or interpretation. Still, the binary token encoding is usually more efficient than using ASCII. Most ele- ments of the language, such as integers, reals, and operator names, are represented by fewer characters in the binary encoding than in the ASCII encoding. Binary encoding is most suitable for environments in which communication bandwidth or storage space is the scarce resource. The binary object sequence encoding represents a sequence of one or more PostScript objects as a single syntactic entity. This encoding is not compact, but it can be generated and interpreted very efficiently. In this encoding, most elements of the language are in a natural machine rep- resentation or something very close to one. Also, this encoding is ori- ented toward sending fully or partially precompiled sequences of objects, as opposed to sequences generated “on the fly.” This organiza- tion matches that of the , which is the principal interface Client Library between Display PostScript applications and the PostScript interpreter. Binary object sequence encoding is most suitable for environments in which execution costs dominate communication costs. Use of the binary encodings requires that the communication channel between the application and the PostScript interpreter be fully transpar- ent. That is, the channel must be able to carry an arbitrary sequence of arbitrary 8-bit character codes, with no characters reserved for commu- nication functions, no “line” or “record” length restrictions, and so on. If the communication channel is not transparent, an application must use the ASCII encoding. Alternatively, it can make use of the filters that encode binary data as ASCII text. See section 3.13, “Filtered Files Details.” 3.12 Binary Encoding Details 105

114 PLRM 2nd Edition January 21, 1994 Language The various language encodings apply only to characters the PostScript language scanner consumes. Applying exec to an executable file or string object invokes the scanner, as does the token operator. File opera- , however, read the incoming sequence tors such as read and readstring of characters as data, not as encoded PostScript language programs. The first character of each token determines what encoding is to be used for that token. If the character code is in the range 128 to 159 inclusive (that is, one of the first 32 codes with the high-order bit set), one of the binary encodings is used. For binary encodings, the character code is treated as a token type : it determines which encoding is used and sometimes also specifies the type and representation of the token. Note The codes 128 to 159 are control characters in most standard character sets, such as ISO and JIS; they do not have glyphs assigned to them and are unlikely to be used to construct names in PostScript language programs. setobjectformat Interpretation of binary encodings can be disabled. See the operator. Following the token type character, subsequent characters are inter- preted according to the same encoding until the end of the token is reached, regardless of character codes. A character code outside the range 128 to 159 can appear within a multiple-byte binary encoding. A character code in the range 128 to 159 can appear within an ASCII string literal or a comment. However, a binary token type character ter- minates a preceding ASCII name or number token. byte is synonymous with charac- In the following descriptions, the term ter but emphasizes that the information represents binary data instead of ASCII text. 3.12.1 Binary Tokens Binary tokens are variable-length binary encodings of certain types of PostScript objects. A binary token represents an object that can also be represented in the ASCII encoding, but it can usually represent the object with fewer characters. The binary token encoding is usually the most compact representation of a program. Semantically, a binary token is equivalent to some corresponding ASCII token. When the scanner encounters the binary encoding for the inte- ger 123, it produces the same result as when it encounters an ASCII 3 . That is, it produces an token consisting of the characters 1 , 2 , and 106 Chapter 3: Language

115 PLRM 2nd Edition Language January 21, 1994 integer object whose value is 123; the object is the same and occupies the same amount of space if stored in VM whether it came from a binary or an ASCII token. Unlike the ASCII and binary object sequence encodings, the binary token encoding is incomplete; not everything in the language can be expressed as a binary token. For example, it doesn’t make sense to have { and } , because their ASCII encodings are binary token encodings of already compact. It also doesn’t make sense to have binary encodings for the names of operators that are rarely used, because their contribu- tion to the overall length of a PostScript language program is negligible. The incompleteness of the binary token encoding is not a problem, because ASCII and binary tokens can be mixed. The binary token encoding is summarized in Table 3.12. A binary token begins with a token type byte. A majority of the token types (132 to 149) are used for binary tokens; the remainder are used for binary object sequences or are unassigned. The token type determines how many additional bytes constitute the token and how the token is inter- preted. Table 3.12 Binary token interpretation Additional Token type(s) Interpretation bytes 128–131 — Binary object sequence (see section 3.12.2, “Binary Object Sequences”). 132 4 32-bit integer, high-order byte first. 133 4 32-bit integer, low-order byte first. 134 2 16-bit integer, high-order byte first. 135 2 16-bit integer, low-order byte first. ; n 136 1 8-bit integer, treating the byte after the token type as a signed number − 128 ≤ n ≤ 127. 137 3 or 5 16- or 32-bit, fixed-point number. The number representation ( size , byte order , and scale ) is encoded in the byte immediately following the token type; the remaining two or four bytes constitute the number itself. The representation parameter is treated as an unsigned integer r in the range 0 to 255: 0 r ≤ 31 ≤ 32-bit fixed point number, high-order byte first. The scale parame- ter (number of bits of fraction) is equal to . r 32 ≤ r ≤ 47 16-bit fixed point number, high-order byte first; scale = r – 32. r ≥ 128 Same as r – 128, except all numbers are given low-order byte first. 32-bit IEEE standard real, high-order byte first. 4 138 3.12 Binary Encoding Details 107

116 PLRM 2nd Edition January 21, 1994 Language 4 32-bit IEEE standard real, low-order byte first. 139 32-bit native real. 140 4 1 Boolean. The byte following the token type gives the value 0 for false , 1 for true . 141 n String of length 142 . The parameter n is in the byte following the token type; 1 + n 0 ≤ n ≤ 255. The n characters of the string follow the parameter. 2 + n Long string of length n . The 16-bit parameter n is contained in the two bytes fol- 143 lowing the token type, represented high-order byte first; 0 ≤ ≤ 65535. The n n bytes of the string follow the parameter. 144 n Long string of length n . The 16-bit parameter n is contained in the two bytes fol- 2 + lowing the token type, represented low-order byte first; 0 n ≤ 65535. The n ≤ bytes of the string follow the parameter. 145 Literal name from the system name table indexed by index . The index 1 parameter is contained in the byte following the token type; 0 ≤ index ≤ 255. . The 146 index 1 Executable name from the system name table indexed by index parameter is contained in the byte following the token type; 0 ≤ ≤ 255. index . 1 Display PostScript only 147 index ( ) Literal name from the user name table indexed by The index parameter is contained in the byte following the token type; 0 ≤ index ≤ 255. 148 ( Display PostScript only ) Executable name from the user name table indexed by 1 index . The index parameter is contained in the byte following the token type; 0 ≤ index ≤ 255. 149 Homogeneous number array, which consists of a four-byte header, including the 3 + data token type, followed by a variable length array of numbers whose size and repre- sentation are specified in the header. The header is described in detail below. — syntaxerror . 150–159 Unassigned. Occurrence of a token with these types will cause a The encodings for integers, reals, and booleans are straightforward. They are explained in section 3.12.4, “Number Representations.” The other token types require additional discussion. A fixed point number is a binary number having integer and fractional parts. The position of the binary point is specified by a separate scale value. In a fixed point number of bits, the high-order bit is the sign, n the next n – scale – 1 bits are the integer part, and the low-order scale bits are the fractional part. For example, if the number is 16 bits wide and scale is 5, it is interpreted as a sign, a 10-bit integer part, and a 5-bit fractional part. A negative number is represented in two’s complement form. There are both 16- and 32-bit fixed point numbers, enabling an applica- tion to make a trade-off between compactness and precision. Regardless 108 Chapter 3: Language

117 PLRM 2nd Edition Language January 21, 1994 of the token’s length, the object produced by the scanner for a fixed point number is an integer if is zero; otherwise it is a real. A 32-bit scale fixed point number takes more bytes to represent than a 32-bit real. It is useful only if the application already represents numbers that way. Using this representation makes somewhat more sense in homoge- neous number arrays, described below. A string token specifies the string’s length as a one- or two-byte, unsigned integer. The specified number of characters of the string fol- low immediately. All characters are treated literally. There is no special treatment of \ (backslash) or other characters. The name encodings specify a or a user name index system name index that selects a name object from the system or user name table (see Appendix F) and uses it as either a literal or an executable name. This mechanism is described in section 3.12.3, “Encoded System Names.” A homogeneous number array is a single binary token that represents a lit- eral array object whose elements are all numbers. Figure 3.1 on page 110 illustrates the organization of the homogeneous number array. The token consists of a four-byte header, including the token type, followed by an arbitrarily long sequence of numbers. All of the numbers are rep- resented in the same way, which is specified in the header. The header consists of the token type byte (149, denoting a homogeneous number array), a byte that describes the number representation, and two bytes that specify the array length (number of elements). The number repre- in the range 0 to 255 and is r sentation is treated as an unsigned integer interpreted as shown in Table 3.13. Table 3.13 Number representation in the header for a homogeneous number array Interpretation Representation 0 r ≤ 31 ≤ 32-bit fixed point number, high-order byte first. The scale parameter (number of bits of fraction) is equal to r . 32 ≤ r ≤ 47 16-bit fixed point number, high-order byte first. scale r – 32. = 48 32-bit IEEE standard real, high-order byte first. 49 32-bit native real. 128 ≤ r ≤ 177 Same as r – 128, except all numbers are given low-order byte first. This interpretation is similar to that of the representation parameter r in individual fixed point number tokens. 3.12 Binary Encoding Details 109

118 PLRM 2nd Edition Language January 21, 1994 Figure 3.1 Homogeneous number array 8 Header bits token type 149 Header (4 bytes) representation array length (elements) length (bytes) Array of numbers (2 or 4 bytes each; all the same size) Number Representation Number Representation High byte first Low byte first sign LSB 2-byte integer/fixed sign LSB sign LSB 4-byte integer/fixed sign LSB sign exponent LSB of fraction IEEE LSB of exponent real exponent fraction sign exponent Note: first byte is at top in all diagrams is given by the last two bytes of the header, treated as The array’s length an unsigned 16-bit number. The byte order in this field is specified by the number representation. r < 128 indicates high-order byte first; r 128 indicates low-order byte first. ≥ Following the header are 2 × length or 4 × length bytes, depending on representation, that encode successive numbers of the array. When the homogeneous number array is consumed by the PostScript language scanner, the scanner produces a The ele- literal array object. is 0, r ments of this array are all integers if the representation parameter of zero. 32, 128, or 160, specifying fixed point numbers with a scale Otherwise, they are all reals. Once scanned, such an array is indistin- guishable from an array produced by other means and occupies the same amount of space. Chapter 3: Language 110

119 PLRM 2nd Edition January 21, 1994 Language Although the homogeneous number array representation is useful in its own right, it is particularly useful with operators that take an encoded number string as an operand. This is described in section 3.12.5, “Encoded Number Strings.” 3.12.2 Binary Object Sequences A binary object sequence is a single token that describes an executable array of objects, each of which may be a simple object, a string, or another array nested to arbitrary depth. The entire sequence can be constructed, transmitted, and scanned as a single, self-contained, syn- tactic entity. Semantically, a binary object sequence is an ordinary executable array, as if the objects in the sequence were surrounded by { and , but with } one important difference: Its execution is immediate instead of deferred. That is, when the PostScript interpreter encounters a binary object sequence in a file being executed directly, the interpreter per- exec forms an implicit instead of pushing the array on the operand stack, as it ordinarily would do. This special treatment does not apply when a binary object sequence appears in a context where execution is already deferred—for example, nested in ASCII-encoded { and } or con- sumed by the token operator. Because a binary object sequence is syntactically a single token, the scanner processes it completely before the interpreter executes it. The VM allocation mode in effect at the time the binary object sequence is scanned determines whether the entire array and all of its composite objects are allocated in local or global VM. The encoding emphasizes ease of construction and interpretation over compactness. Each object is represented by eight successive bytes. In the case of simple objects, these eight bytes describe the entire object— type, attributes, and value. In the case of composite objects, the eight bytes include a reference to some other part of the binary object sequence where the value of the object resides. The entire structure is easy to describe using the data type definition facilities of implementa- tion languages, such as C and Pascal. Figure 3.2 on page 112 shows the organization of the binary object sequence. 3.12 Binary Encoding Details 111

120 PLRM 2nd Edition January 21, 1994 Language Figure 3.2 Binary object sequence 8 Extended Header Normal Header bits (8 bytes) (4 bytes) Header token type token type (4 or 8 bytes) top level array 0 length (objects) top level array overall length length (objects) (bytes) Top-level array of objects (8 bytes each) overall length (bytes) Object (8 bytes) Subsidiary length 0 = literal arrays of objects type (bytes) 1 = executable (8 bytes each) 0 length value String values (variable length) Note: first byte is at top in all diagrams A binary object sequence consists of four parts, in the following order: • Header — four or eight bytes of information about the binary object sequence as a whole. • Top-level array—a sequence of objects, eight bytes each, which con- stitute the value of the main array object. • Subsidiary arrays — more eight-byte objects, which constitute the val- ues of nested array objects. • String values — an unstructured sequence of bytes, which constitute the values of string objects and the text of name objects. Chapter 3: Language 112

121 PLRM 2nd Edition Language January 21, 1994 The first byte of the header is the token type, mentioned earlier. Four token types denote a binary object sequence and select a number repre- sentation for all integers and reals embedded within it (see section 3.12.4, “Number Representations”). They are: high-order byte first, IEEE standard real format 128 129 low-order byte first, IEEE standard real format 130 high-order byte first, native real format 131 low-order byte first, native real format There are two forms of header, normal and extended , as shown in Figure 3.2. The normal header can describe a binary object sequence that has no more than 255 top-level objects and 65,535 bytes overall. The extended header is required for sequences that exceed these limits. Following the header is an uninterrupted sequence of eight-byte objects that constitute the top-level array and subsidiary arrays. The length of this sequence is not explicit. It continues until the earliest string value referenced from an object in the sequence, or until the end of the entire token. The first byte of each object in the sequence gives the object’s literal/ executable attribute in the high-order bit and its type in the low-order 7 bits. The attribute values are: 0 literal 1 executable The meaning of the object type field is given in Table 3.14. Table 3.14 Object types; length and value fields interpretation Length field Value field Object Type 0 Unused Unused null 1 integer Unused Signed, 32-bit integer 2 real Selects representation Real or fixed point number 3 name (See below) Offset or index boolean 4 0 for Unused false , 1 for true 5 Number of elements Offset of first element string 6 immediately (See below) Offset or index evaluated name 9 array Number of elements Offset of first element Unused Unused 10 mark 3.12 Binary Encoding Details 113

122 PLRM 2nd Edition Language January 21, 1994 The second byte of an object is unused; its value must be zero. The third and fourth bytes constitute the ; the fifth through eighth bytes length value . The bytes interpretation of the length constitute the value and fields depends on the object’s type and are given in Table 3.14. Once again, the byte order within these fields is according to the number rep- resentation for the binary object sequence overall. Number representations are explained in section 3.12.4, “Number Rep- resentations.” For a real, if length is zero, value is a floating point num- ber. If is non-zero, value is a fixed point number, using length as its length scale factor (see section 3.12.1, “Binary Tokens”). For types string and array , the length field specifies the number of ele- ments (characters in a string or objects in an array). It is treated as an value field specifies the offset, in bytes, of unsigned 16-bit integer. The the start of the object’s value relative to the first byte of the first object in the top-level array. An array offset must refer somewhere within the top-level or subsidiary arrays; it must be a multiple of 8. A string offset must refer somewhere within the string values. The strings have no alignment requirement and need not be null-terminated or otherwise delimited. If the length of a string or array object is zero, its value is dis- regarded. name type, the length field is treated as a signed, 16-bit integer For the that selects one of three interpretations of the value field: n > 0 Value is an offset to the text of the name, just as with a string. n is the name’s length, which must be within the implemen- tation limit for names. n = 0 Value is a user name index . This is a Display PostScript feature, not a standard part of Level 2 implementations. n − 1 Value is a system name index (see 3.12.3, “Encoded System = Names”). An immediately evaluated name object corresponds to the // name syntax of the ASCII encoding. See section 3.11.2, “Immediately Evaluated Names.” Aside from the type code, its representation is the same as a name. However, with an immediately evaluated name object, the scan- ner immediately looks up the name in the environment of the current dictionary stack and substitutes the corresponding value for that name. error occurs. undefined If the name is not found, an 114 Chapter 3: Language

123 PLRM 2nd Edition January 21, 1994 Language For the composite objects, there are no enforced restrictions against multiple references to the same value or to recursive or self-referential arrays. However, such structures cannot be expressed directly in the ASCII or binary token encodings of the language; their use violates the interchangeability of the encodings. The recommended structure of a binary object sequence is for each composite object to refer to a distinct value. There is one exception: References from multiple name objects to the same string value are encouraged, because name objects are unique by definition. The scanner generates a when it encounters a binary object syntaxerror sequence that is malformed in any way. Possible causes include: • An object type that is undefined. • An “unused” field that is not zero. • Lengths and offsets that, combined, would refer outside the bounds of the binary object sequence. • An array offset that is not a multiple of 8 or that refers beyond the earliest string offset. syntaxerror When a occurs, the PostScript interpreter pushes onto the operand stack the object that caused the error. For an error detected by the scanner, however, there is not such an object, because the error occurs before the scanner has finished creating one. Instead, the scan- ner fabricates a string object consisting of the characters encountered so far in the current token. If a binary token or binary object sequence was being scanned, the string object produced is a description of the token rather than the literal characters, which would be gibberish if printed as part of an error message. An example of such as error string is: (bin obj seq, type=128, elements=23, size=234, array out of bounds) 3.12.3 Encoded System Names Both the binary token and binary object sequence encodings provide optional means for representing certain names as small integers instead of as full text strings. Such an integer is referred to as a system name user name index index or a . Careful use of encoded names can save sub- stantial space and improve execution performance. 3.12 Binary Encoding Details 115

124 PLRM 2nd Edition January 21, 1994 Language Encoded system names are a Level 2 feature; they are described below. Encoded user names are supported only in the Display PostScript sys- tem; they are documented in Chapter 7. A name index is a reference to an element of a name table already known to the PostScript interpreter. When the scanner encounters a name token that specifies a name index, rather than a text name, it immediately substitutes the corresponding element of the table. This substitution occurs at scan time, not at execution time. The result of the substitution is an ordinary PostScript name object. The system name table contains standard operator names, single-letter names, and miscellaneous other useful names. The contents of this table are documented in Appendix F. They are also available as a machine-readable file for use by drivers, translators, and other programs that deal with binary encodings; contact the Adobe Systems Develop- ers’ Association. If there is no name associated with a specified system name index, the scanner generates an undefined error. The offending command is n system is the decimal representation of the index. n , where An encoded binary name specifies, as part of the encoding, whether the name is to be literal or executable. A given element of the system name table can be treated as either literal or executable when referenced from a binary token or object sequence. In the binary object sequence encod- ing, one can also specify an immediately evaluated name object analo- gous to //name . When such an object specifies a name index, there are two substitutions: the first obtains a name object from the table, the sec- ond looks up that name object in the current dictionary stack. A program can depend on a given system name index representing a particular name object. Applications that generate binary encoded Post- Script language programs are encouraged to take advantage of system name index encodings, because they save both space and time. Note The binary token encoding can reference only the first 256 elements of the system name table. Therefore, this table is organized such that the most commonly used names are in the first 256 elements. The binary object sequence encoding does not have this limitation. 116 Chapter 3: Language

125 PLRM 2nd Edition January 21, 1994 Language 3.12.4 Number Representations Binary tokens and binary object sequences use various representations for numbers. Some numbers are the values of number objects (integers and reals). Others provide structural information, such as lengths and offsets within binary object sequences. Different machine architectures use different representations for num- bers. The two most common variations are the byte order within multi- ple-byte integers and the format of real (floating point) numbers. Rather than specify a single convention for representing numbers, the language provides a choice of representations. The application program chooses whichever convention is most appropriate for the machine on which it is running. The PostScript language scanner accepts numbers conforming to any of the conventions, translating to its own internal representation when necessary. This translation is needed only when the application and the PostScript interpreter are running on machines with different architectures. The number representation to be used is specified as part of the token type—the initial character of the binary token or binary object sequence. There are two independent choices, one for byte order and one for real format. The byte order choices are: • High-order byte first in a multiple-byte integer or fixed point num- ber. The high-order byte comes first, followed by successively lower- order bytes. • Low-order byte first in a multiple-byte integer or fixed point number. The low-order byte comes first, followed by successively higher-order bytes. The real format choices are: • IEEE standard — a real number is represented in IEEE 32-bit, floating point format (see the bibliography). The order of the bytes is the same as the integer byte order. For example, if the high-order byte of an integer comes first, then the byte containing the sign and first 7 exponent bits of an IEEE standard real comes first. 3.12 Binary Encoding Details 117

126 PLRM 2nd Edition January 21, 1994 Language • Native — a real number is represented in the native format for the machine on which the PostScript interpreter is running. This may be a standard format or something completely different. The choice of byte order is not relevant. The application program is responsible for finding out what the correct format is. In general, this is useful only in environments where the application and the PostScript inter- preter are running on the same machine or on machines with com- patible architectures. PostScript language programs that use this real- number representation are not portable. Because each binary token and binary object sequence specifies its own number representation, binary encoded programs with different num- ber representations can be mixed. This is a convenience for applications that obtain portions of PostScript language programs from different sources. system parameters indicate the native RealFormat The ByteOrder and byte order and real number representation of the machine on which the PostScript interpreter is running (see Appendix C). A Display Post- Script application can query RealFormat to determine whether the interpreter’s native real number format is the same as the application’s. If so, translation to and from IEEE format can be avoided. 3.12.5 Encoded Number Strings Several operators require as operands an indefinitely long sequence of numbers to be used as coordinate values, either absolute or relative. The operators include those dealing with user paths, rectangles, and explic- itly positioned text. In the most common use of these operators, all of the numbers are provided as literal values by the applications rather than being computed by the PostScript language program. In order to facilitate this common use and to streamline generation and interpretation of numeric operand sequences, these operators permit their operands to be presented in either of two ways: • As an array object whose elements are numbers to be used succes- sively. encoded number string . • As a string object to be interpreted as an 118 Chapter 3: Language

127 PLRM 2nd Edition Language January 21, 1994 An encoded number string is a string that contains a single homogeneous number array according to the binary token encoding. That is, the first four bytes are treated as a header. The remaining bytes are treated as a sequence of numbers encoded as described in the header. (See Figure 3.1 on page 110.) An encoded number string is a compact representation of a number sequence both in its external form and in VM . Syntactically, it is simply a string object. It remains in that form after being scanned and placed in VM. It is interpreted as a sequence of numbers only when it is used as an operand of an operator that is expecting a number array. Further- more, even then it is neither processed by the scanner nor expanded into an array object; instead, the numbers are consumed directly by the operator. This arrangement is compact and efficient, particularly for large number sequences. Example 3.9, “ shows equivalent ways of invoking , which is one rectfill of the Level 2 operators that expect number sequences as operands. Example 3.9 [100 200 40 50] rectfill <95200004 0064 00c8 0028 0032> rectfill The first line constructs an ordinary PostScript array object containing the numbers and passes it to rectfill . This is the most general form, because the [ and ] could enclose an arbitrary computation that pro- duces the numbers and pushes them on the stack. On the second line, a string object appears in the program. When notices that it has been given a string object, it interprets the rectfill value of the string, expecting to find the binary token encoding of a homogeneous number array. Example 3.9 does not use encoded number strings to best advantage. In this example, it is an ASCII-encoded hexadecimal string enclosed in < and > . In a real application, one would use a more efficient encoding, such as a binary string token or an ASCII base-85 string literal. An ordi- nary ASCII string enclosed in ( and ) is unsuitable because of the need to quote special characters. The operators that use encoded number strings include rectfill , , rectstroke , rectclip , rectviewclip xshow , yshow , and xyshow . An encoded user path can represent its numeric operands as an encoded number string. The relevant operators are ufill , ueofill , ustroke , . inustroke uappend , inufill , inueofill , and 3.12 Binary Encoding Details 119

128 PLRM 2nd Edition Language January 21, 1994 3.12.6 Structured Output In some environments, a PostScript language program can transmit information back to the application program that generated it. This is particularly true in the Display PostScript system, where the application program and the PostScript interpreter communicate interactively via the Client Library (see Chapter 7). This information includes the values of objects produced by queries, error messages, and unstructured text generated by print . A PostScript language program writes all of this data to its standard out- put file. The Client Library or application requires a way to distinguish among these different kinds of information received from the Post- Script interpreter. To serve this need, the language includes operators to write output in a structured output format . This format is basically the same as the binary object sequence representation for input, described in section 3.12.2, “Binary Object Sequences.” A program that writes structured output should take care when using . Because the start of unstructured output operators, such as print and = a binary object sequence is indicated by a character whose code is in the range 128 to 159 inclusive, unstructured output should consist only of character codes outside that range. Otherwise, confusion will ensue in the Client Library or the application. Of course, this is only a conven- tion. By prior arrangement, a program can send arbitrary unstructured data to the application. The operator printobject writes an object as a binary object sequence to writeobject , writes to any the standard output file. A similar operator, file. The binary object sequence contains a top-level array consisting of one element that is the object being written (see section 3.12.2, “Binary Object Sequences”). That object, however, can be composite, so the binary object sequence may include subsidiary arrays and strings. In the binary object sequences produced by printobject and writeobject , the number representation is controlled by the setobjectformat operator. The binary object sequence has a token type that identifies the representation used. Accompanying the top-level object in the object sequence is a one-byte . tag , which is specified as an operand of printobject and writeobject This tag is carried in the second byte of the object, which is otherwise unused (see Figure 3.2 on page 112). Only the top-level object receives a 120 Chapter 3: Language

129 PLRM 2nd Edition Language January 21, 1994 tag; the second byte of subsidiary objects is zero. Despite its physical position, the tag is logically associated with the object sequence as a whole. The purpose of the tag is to enable the PostScript language program to specify the intended disposition of the object sequence. A few tag val- ues are reserved for reporting errors (see below). The remaining tag val- ues may be used arbitrarily. For example, the Display PostScript Client Library uses tags when it issues queries to the PostScript interpreter. A query consists of a PostScript language program that includes one or more instances of printobject to send responses back to the Client Library. A different tag is specified for each so the Client printobject Library can distinguish among the responses as they arrive. Tag values 0 through 249 are available for general use. Tag values 250 through 255 are reserved for identifying object sequences that have spe- cial significance. Of these, only tag value 250 is presently defined; it is used to report errors. Errors are initiated as described in section 3.10, “Errors.” Normally, when an error occurs, control automatically passes from the PostScript language program to a built-in procedure that catches errors. That pro- cedure invokes handleerror . Subsequent behavior depends on the defi- . The following description applies to the standard handleerror nition of definition of . handleerror If the value of binary in the $error dictionary is true and binary encoding is enabled, handleerror writes a binary object sequence with a binary tag value of 250. But if is false or binary encoding is disabled, handleerror writes a human-readable text message whose format is product-dependent. The binary object sequence that reports an error contains a four-ele- ment array as its top-level object. The array elements, ordered as they appear, are: • The name Error , which indicates an ordinary error detected by the PostScript interpreter. A different name could indicate another class of errors, in which case the meanings of the other array elements might be different. . typecheck • The name that identifies the specific error—for example, 3.12 Binary Encoding Details 121

130 PLRM 2nd Edition January 21, 1994 Language • The object that was being executed when the error occurred. If the object that raised the error is not printable, some suitable substitute is provided—for example, an operator name in place of an operator object. • An error-handler flag—a boolean object whose value is true if the program expects to resynchronize with the client, and false other- wise. The normal value is , but certain Display PostScript appli- false cations set it to true (see the section on handling errors in The Display PostScript Reference Manual , available from the Adobe Systems Devel- opers’ Association). 3.13 Filtered Files Details Level 2 implementations of the PostScript language support a special , which reads or writes an underlying file and filter kind of file called a transforms the data in some way. Filters are introduced in 3.8.4, “Fil- ters.” This section describes the semantics of filters in more detail. It includes information about: • Use of files, procedures, and strings as data sources and targets. • End-of-data conventions. • Details of individual filters. • Specifications of encoding algorithms for some filters. 3.13.1 Data Sources and Targets As stated in section 3.8.4, “Filters,” there are two kinds of filters, decod- filters and ing encoding filters. A decoding filter is an input file that reads from an underlying and produces transformed data as it is data source read. An encoding filter is an output file that takes the data written to it and writes transformed data to an underlying data target . Data sources and data targets may be files, procedures, or strings. Files A file is the most common data source or target for a filter. A file used as a data source must be an input file; one used as a data target must be an error occurs. invalidaccess output file. Otherwise, an 122 Chapter 3: Language

131 PLRM 2nd Edition January 21, 1994 Language If a file is a data source for a decoding filter, the filter reads from it as necessary to satisfy demands on the filter, until either the filter reaches its end-of-data (EOD) condition or the data source reaches end-of-file. If a file is a data target for an encoding filter, the filter writes to it as neces- sary to dispose of data that have been written to the filter and trans- formed. Closing a filter file does not close the underlying file. A program typi- cally creates a decoding filter to process data embedded in the program file itself—the one designated by currentfile . When the filter reaches EOD, execution of the underlying file resumes. Similarly, a program can embed the output of an encoding filter in the middle of an arbitrary data stream being written to the underlying output file. Once a program has begun reading from or writing to a filter, it should not attempt to access the underlying file in any way until the filter has been closed. Doing so could interfere with the operation of the filter and leave the underlying file in an unpredictable state. However, it is filter but before the safe to access the underlying file after execution of first read or write of the filter file. The procedure for establishing a filter pipeline in Example 3.5 on page 82 depends on this. Procedures The data source or target can be a procedure. When the filter file is read or written, it calls the procedure to obtain input data to be decoded or to dispose of output data that have been encoded. This enables the data to be supplied or consumed by an arbitrary program. If a procedure is a data source, the filter calls it whenever it needs to obtain input data. The procedure must return (on the operand stack) a readable string containing any number of bytes of data. The filter pops this string from the stack and uses its contents as input to the filter. This process repeats until the filter encounters end-of-data (EOD). Any left- over data in the final string are discarded. The procedure can return a string of length zero to indicate that no more data are available. If a procedure is a data target, the filter calls it whenever it needs to dis- pose of output data. Before calling the procedure, it pushes two oper- ands on the stack: a string and a boolean flag. It expects the procedure to consume those operands and to return a string. The filter calls the procedure in the following three situations: 3.13 Filtered Files Details 123

132 PLRM 2nd Edition Language January 21, 1994 • Upon the first write to the filter after the filter operator creates it, the filter calls the data target procedure with an empty string and the boolean true . The procedure must return a writable string of non- zero length, into which the filter may write filtered data. • Whenever the filter needs to dispose of accumulated output data, it calls the procedure again, passing it a string containing the data and the boolean true . This string is either the same string that was returned from the previous call or a substring of that string. The pro- cedure must now do whatever is appropriate with the data, then return another string or the same string into which the filter can write additional filtered data. • When the filter file is closed, it calls the procedure a final time, pass- ing it a string or substring containing the remaining output data, if . The procedure must now do whatever is any, and the boolean false appropriate with the data and perform any required end-of-data actions, then return a string. Any string (for example, one of length zero) is acceptable. The filter does not use this string, but merely pops it off the stack. It is normal for the data source or target procedure to return the same string each time. The string is allocated once at the beginning and serves simply as a buffer that is used repeatedly. Each time a data source procedure is called, it fills the string with one buffer’s worth of data and returns it. Similarly, each time a data target procedure is called, it first disposes of any buffered data passed to it, then returns the original string for reuse. Between successive calls to the data source or target procedure, a pro- gram should not do anything that would alter the contents of the string returned by that procedure. The filter reads or writes the string at unpredictable times, so altering it could disrupt the operation of the filter. If the string returned by the procedure is reclaimed by a restore before the filter becomes closed, the results are unpredictable. Typically, ioerror an occurs. One use of procedures as data sources or targets is to run filters “back- ward.” Filters are organized such that decoding filters are input files and encoding filters are output files. Normally, a PostScript language pro- gram obtains encoded data from some external source, decodes them, and uses the decoded data; or it generates some data, encodes them, and sends them to some external destination. The organization of fil- 124 Chapter 3: Language

133 PLRM 2nd Edition January 21, 1994 Language ters supports this model. However, if a program must provide the input to a decoding filter or consume the output of an encoding filter, it can do so by using procedures as data sources or targets. Strings If a string is a data source, the filter simply uses its contents as data to be decoded. If the filter encounters EOD, it ignores the remainder of the string. Otherwise, it continues until it has exhausted the string data. If a string is a data target, the filter writes encoded data into it. This con- tinues until the filter is closed. The contents of the string are not dependable until that time. If the filter exhausts the capacity of the ioerror occurs. There is no way to determine how much data string, an the filter has written into the string. If a program needs to know, it should use a procedure as the data target. 3.13.2 End-of-Data and End-of-File A filter can reach a state in which it cannot continue filtering data. This (EOD) condition. Most decoding (input) filters end-of-data is called the can detect an EOD marker encoded in the data that they are reading. The nature of this marker depends on the filter. Most encoding (output) filters append an EOD marker to the data that they are writing. This generally occurs automatically when the filter file is closed. In a few instances, the EOD condition is based on predetermined information, such as a byte count or a scan line count, instead of on an explicit marker in the encoded data. A file object, including a filter, can be closed at an arbitrary time, and a readable file can run out of data. This is called the end-of-file (EOF) condition. When a decoding filter detects EOD and all the decoded data have been read, the filter reaches the EOF condition. The underlying data source or target for a filter can itself reach EOF. This usually results in the filter reaching EOF, perhaps after some delay. For efficient operation, filters must be buffered. The PostScript inter- preter automatically provides buffering as part of the filter file object. Due to the effects of buffering, the filter reads from its data source or writes to its data target at irregular times, not at times when the filter file itself is read or written. Also, many filtering algorithms require an unpredictable amount of state to be held within the filter object. 3.13 Filtered Files Details 125

134 PLRM 2nd Edition January 21, 1994 Language Decoding Filters Before encountering EOD, a decoding filter reads an unpredictable amount of data from its data source. However, when it encounters EOD, it stops reading from its data source. If the data source is a file, encoded data that are properly terminated by EOD can be followed by additional unencoded data, which a program can then read directly from that file. When a filter reaches EOD and all the decoded data have been read from it, the filter file reaches EOF and is closed automatically. Auto- all file objects, matic closing of input files at EOF is a standard feature of not just of filters. Unlike other file objects, a filter reaches EOF and is last closed immediately after the data character is read from it instead of at the following attempt to read a character. A filter also reaches EOF if its data source runs out of data by reaching EOF. to a decoding filter causes data to be drawn from the Applying flushfile data source until the filter reaches EOD or the source runs out of data, whichever occurs first. This can be used to flush the remainder of the encoded data from the underlying file when reading of filtered data must be terminated prematurely. After flushfile , the underlying file is positioned so the next read from that file will begin immediately fol- lowing the EOD of the encoded data. If a program closes a decoding filter prematurely before it reaches EOD and without explicitly flushing it, the data source will be in an indeterminate state. Because of buffer- ing, there is no dependable way to predict how much data will have been consumed from the data source. Encoding Filters As stated earlier, writing to an encoding (output) filter causes it to write encoded data to its data target. However, due to the effects of buffering, the writes to the data target occur at unpredictable times. The only way to ensure that all encoded data have been written is to close the filter. Most encoding filters can accept an indefinite amount of data to be encoded. The amount usually is not specified in advance. Closing the filter causes an EOD marker to be written to the data target at the end of the encoded data. The nature of the EOD marker depends on the filter being used; it is sometimes under the control of parameters specified when the filter is created. 126 Chapter 3: Language

135 PLRM 2nd Edition January 21, 1994 Language The standard filter DCTEncode requires the amount of data to be speci- fied in advance. This information is supplied when the filter is created. When that amount of data has been encoded, the filter reaches the EOD condition automatically. Attempting to write additional data to the filter causes an ioerror , possibly after some delay. Some data targets can become unable to accept further data. For instance, if the data target is a string, that string may become full. If the data target is a file, that file may become closed. Attempting to write to a filter whose data target cannot accept data causes an ioerror . Applying flushfile to an encoding filter file causes the filter to flush buff- ered data to its data target to the extent possible. If the data target is a flushfile will propagate file, flushfile is also invoked for it. The effect of all the way down a filter pipeline. However, due to the nature of filter algorithms, it is not possible to guarantee that all data stored as part of a filter’s internal state will be flushed. On the other hand, applying closefile to an encoding filter flushes both the buffered data and the filter’s internal state. This causes all encoded data to be written to the data target, followed by an EOD marker, if appropriate. When closing a pipeline consisting of two or more encoding filters, one must close each component filter file in sequence, starting with the one that was created last (in other words, the one farthest upstream). This ensures that all buffered data and all appropriate EOD markers are writ- ten in the proper order. 3.13.3 Details of Individual Filters As stated in 3.8.4, “Filters,” the PostScript language supports three cate- gories of standard filters: ASCII encoding filters, compression and decompression filters, and subfile filters. The following sections docu- ment the individual filters. Some of the encoded formats these filters support are the same as or similar to those supported by applications or utility programs on many computer systems. It should be straightforward to make those programs compatible with the filters. Also, C language implementations of some filters are available from the Adobe Systems Developers’ Association. 3.13 Filtered Files Details 127

136 PLRM 2nd Edition January 21, 1994 Language ASCIIHexDecode Filter The syntax for using the ASCIIHexDecode filter is: /ASCIIHexDecode filter source This filter decodes data encoded as ASCII hexadecimal and produces binary data. For each pair of ASCII hexadecimal digits ( 0–9 A–F or and a–f ), it produces one byte of binary data. All white-space characters— space, tab, carriage return, line-feed, form-feed, and null—are ignored. > The character indicates EOD. Any other characters will cause an . ioerror If the filter encounters EOD when it has read an odd number of hexa- decimal digits, it will behave as if it had read an additional zero digit. ASCIIHexEncode Filter The syntax for using the filter is: ASCIIHexEncode target /ASCIIHexEncode filter This filter encodes binary data as ASCII hexadecimal. For each byte of and or binary data, it produces two ASCII hexadecimal digits ( 0–9 A–F ). It inserts a newline (line-feed) character in the encoded output at a–f least once every 80 characters, thereby limiting the lengths of lines. When the filter is closed, it writes a > character as an ASCIIHexEncode EOD marker. ASCII85Decode Filter The syntax for using the ASCII85Decode filter is: source /ASCII85Decode filter This filter decodes data encoded in the ASCII base-85 encoding and pro- duces binary data. See the description of the filter for a ASCII85Encode definition of the ASCII base-85 encoding. The ASCII base-85 encoded data format uses the characters ! through u and the character z . All white-space characters—space, tab, carriage- return, line-feed, form-feed, and null—are ignored. If the filter encoun- and the > ters the character ~ in its input, the next character must be 128 Chapter 3: Language

137 PLRM 2nd Edition Language January 21, 1994 filter will reach EOD. Any other characters will cause the filter to issue ioerror . Also, any character sequences that represent impossible an combinations in the ASCII base-85 encoding will cause an ioerror . ASCII85Encode Filter ASCII85Encode The syntax for using the filter is: target /ASCII85Encode filter This filter encodes binary data in the ASCII base-85 encoding. Gener- ally, for every 4 bytes of binary data it produces 5 ASCII printing charac- through ters in the range . It inserts a newline (line-feed) character in ! u the encoded output at least once every 80 characters, thereby limiting the lengths of lines. filter is closed, it writes the two-character When the ASCII85Encode sequence ~> as an EOD marker. Binary data bytes are encoded in 4-tuples (groups of 4). Each 4-tuple is used to produce a 5-tuple of ASCII characters. If the binary 4-tuple is ( b 1 c b ), then the relation b c ) and the encoded 5-tuple is ( b c c c 4 3 2 2 4 5 1 3 between them is: 3 1 2 b =  256 +++ 256 b () × × 256 () b () × b 3 4 2 1 4 3 2 1 c () × () 85 c () × × 85 ++++ 85 c () × c 85 c 3 1 2 5 4 In other words, four bytes of binary data are interpreted as a base-256 number and then converted into a base-85 number. The five “digits” of this number, ( c c c c c ), are then converted into ASCII characters by 1 4 5 3 2 adding 33, which is the ASCII code for ! , to each. ASCII characters in to u represents the value 0 and ! u are used, where ! represents the range the value 84. As a special case, if all five digits are zero, they are repre- z instead of by !!!!! . sented by a single character filter is closed when the number of characters If the ASCII85Encode written to it is not a multiple of 4, it uses the characters of the last, par- tial 4-tuple to produce a last, partial 5-tuple of output. Given n (1, 2, or 3) bytes of binary data, it first appends 4 – n zero bytes to make a com- plete 4-tuple. Then, it encodes the 4-tuple in the usual way, but without z + 1 bytes of the n special case. Finally, it writes the first applying the 3.13 Filtered Files Details 129

138 PLRM 2nd Edition Language January 21, 1994 ~> EOD resulting 5-tuple. Those bytes are followed immediately by the marker. This information is sufficient to correctly encode the number of final bytes and the values of those bytes. The following conditions constitute encoding violations: 32 • The value represented by a 5-tuple is greater than 2 –1. •A z character occurs in the middle of a 5-tuple. • A final partial 5-tuple contains only one character. These conditions never occur in the output produced by the ASCII85Encode filter. Their occurrence in the input to the ASCII85Decode filter causes an ioerror . The ASCII base-85 encoding is similar to one used by the public domain atob , which are widely available on workstations. utilities btoa and However, it is not exactly the same; in particular, it omits the begin- data and end-data marker lines, and it uses a different convention for marking end-of-data. LZWDecode Filter The syntax for using the LZWDecode filter is: source /LZWDecode filter The LZWDecode filter decodes data that are encoded in a Lempel-Ziv- Welch compressed format. See the description of the filter LZWEncode for details of the format. A code of 257 indicates EOD. LZWEncode Filter The syntax for using the LZWEncode filter is: target /LZWEncode filter The LZWEncode filter encodes ASCII or binary data according to the basic LZW (Lempel-Ziv-Welch) data compression method, which is a variable-length, adaptive compression method. The output produced filter is always binary, even if the input is ASCII text. LZWEncode by the 130 Chapter 3: Language

139 PLRM 2nd Edition January 21, 1994 Language LZW compression can discover and exploit many patterns in its input data, whether that input is text or image data. It is especially well-suited to English language and PostScript language text. The encoded data consist of a sequence of codes that can be from 9 to 12 bits long. Each code denotes a single character of input data (0 to 255), a clear-table marker (256), an EOD marker (257), or a table entry representing a multi-character sequence that has been encoun- tered previously in the input (258 and greater). Initially, the code length is 9 bits and the table contains only entries for the 258 fixed codes. As encoding proceeds, entries are appended to the table associating new codes with longer and longer input character sequences. The encoding and decoding filters maintain identical copies of this table. Whenever both encoder and decoder independently (but synchro- nously) realize that the current code length is no longer sufficient to represent the number of entries in the table, they increase the number of bits per code by one. The first output code that is 10 bits long is the one following the creation of table entry 511, and so on for 11 (1023) and 12 (2047) bits. Codes are never longer than 12 bits, so entry 4095 is the last entry of the LZW table. The encoder executes the following sequence of steps to generate each output code. 1. Accumulate a sequence of one or more input characters matching some sequence already present in the table. For maximum compres- sion, the encoder should find the longest such sequence. 2. Output the code corresponding to that sequence. 3. Create a new table entry for the first unused code. Its value is the sequence found in step 1 followed by the next input character. For example, suppose the input begins with the following sequence of ASCII character codes: 45 45 45 45 45 65 45 45 45 66 ... Starting with an empty table, the encoder proceeds as shown in Table 3.15. 3.13 Filtered Files Details 131

140 PLRM 2nd Edition Language January 21, 1994 Typical LZW encoding sequence Table 3.15 Output Code added Sequence represented Input sequence to table by new code code – 256 (clear-table) 45 45 258 45 45 45 45 259 45 45 45 258 45 45 258 260 45 45 65 65 65 261 65 45 45 45 45 66 262 45 45 45 259 Codes are packed into a continuous bit stream, high-order bit first. This stream is then divided into 8-bit bytes, high-order bit first. Thus, codes can straddle byte boundaries arbitrarily. After the EOD marker (code value of 257), any leftover bits in the final byte are set to 0. In the above example, all the output codes are nine bits long; they would pack into bytes like this (represented in hexadecimal): 80 0B 60 50 22 0C 0 ... To adapt to changing input sequences, the encoder may at any point issue a clear-table code, which causes both encoder and decoder to restart with initial tables and 9-bit codes. By convention, the encoder begins by issuing a clear-table code. It must issue a clear-table code when the table becomes full; it may do so sooner. LZW has been adopted as one of the standard compression methods in the tag image file format (TIFF) 5.0 standard. The PostScript language LZWEncode filters use the same coding as is used by and LZWDecode other popular implementations of LZW; this coding differs slightly from the one described in the TIFF 5.0 specification. Variants of LZW are used in the UNIX compress and personal computer ARC utilities. The LZW compression method is said to be the subject of United States patent number 4,558,302 and corresponding foreign patents owned by the Unisys Corporation. Adobe Systems has licensed this patent for use in its products. Independent software vendors (ISVs) may be required to license this patent to develop software using the LZW method to com- press PostScript language programs or data for use with Adobe products. Unisys has agreed that ISVs may obtain such a license for a modest one- 132 Chapter 3: Language

141 PLRM 2nd Edition January 21, 1994 Language time fee. Further information can be obtained from: Welch Licensing Department, Law Department, M/SC2SW1, Unisys Corporation, Blue Bell, Pennsylvania, 19424. RunLengthDecode Filter RunLengthDecode filter is: The syntax for using the /RunLengthDecode filter source This filter decodes data in run-length encoded format. The encoded data consist of pairs of run-length bytes and data. See the description of RunLengthEncode filter for details of the format. A run length of the 128 indicates EOD. RunLengthEncode Filter RunLengthEncode The syntax for using the filter is: target recordsize /RunLengthEncode filter RunLengthEncode The filter encodes data in a simple byte-oriented, run-length encoded format. The compressed data format is a sequence of runs, where each run consists of a length byte followed by 1 to 128 length bytes of data. If the byte is in the range 0 to 127, the following length + 1 bytes (1 to 128 bytes) are to be copied literally upon decom- length is in the range 129 to 255, the following single byte is pression. If − length times (2 to 128 times) upon decompres- to be replicated 257 sion. When the RunLengthEncode filter is closed, it writes a final byte, with value 128 as an EOD marker. recordsize is a positive integer specifying the number of bytes in a “record” of source data. The filter will not create a RunLengthEncode run that contains data from more than one source record. If recordsize is zero, the filter does not treat its source data as records. The notion of a “record” is irrelevant in the context of the PostScript interpreter (in par- ticular, the image operator does not require its data to be divided into recordsize records). A non-zero is useful only if the encoded data is to be sent to some application program that requires it. 3.13 Filtered Files Details 133

142 PLRM 2nd Edition January 21, 1994 Language ® ® This encoding is very similar to that used by the Apple Macintosh PackBits routine and by TIFF Data Compression scheme #32773. Out- RunLengthDecode filter put from PackBits is acceptable as input to the if an EOD marker (byte value 128) is appended to it. Output from the RunLengthEncode filter is acceptable to UnPackBits if the recordsize parameter is equal to the length of one scan line for the image being encoded. CCITTFaxDecode Filter CCITTFaxDecode filter is: The syntax for using the source dictionary /CCITTFaxDecode filter This filter decodes image data that have been encoded according to the CCITT facsimile standard. See CCITTFaxEncode for a description of the filter parameters. CCITTFaxDecode If the filter encounters improperly encoded source data, it will issue an . It will not perform any error correction or ioerror resynchronization. CCITTFaxEncode Filter The syntax for using the CCITTFaxEncode filter is: target dictionary /CCITTFaxEncode filter This filter encodes image data according to the CCITT facsimile ( fax ) standard. This encoding is defined by an international standards orga- nization named CCITT, the International Coordinating Committee for Tele- phony and Telegraphy . The encoding is designed to achieve efficient compression of monochrome (1 bit per pixel) image data at relatively low resolutions. The encoding algorithm is not described in this man- ual but in the CCITT standard (see the bibliography). Note PostScript language support for the CCITT standard is limited to encoding and decoding of image data. It does not include initial connection and handshaking protocols that would be required to communicate with a fax machine. The purpose of these filters is to enable efficient interchange of bi- level sampled images between an application program and a PostScript interpreter. 134 Chapter 3: Language

143 PLRM 2nd Edition Language January 21, 1994 CCITTFaxDecode CCITTFaxEncode filters support two The and encoding schemes, Group 3 and Group 4, and various optional features of the CCITT standard. Parameters for these filters are provided in the form of a dictionary object whose entries define the parameters. Table 3.16 describes the contents of this dictionary. All of its entries are optional and have default values. Entries in CCITTFaxEncode and CCITTFaxDecode dictionaries Table 3.16 Key Type Semantics Uncompressed boolean ( Optional ) If true , the CCITTFaxEncode filter is permitted to use uncompressed encoding when advantageous. If false , it never uses uncompressed encoding. The filter always accepts uncompressed encoding. Default value: CCITTFaxDecode false . Uncompressed encoding is an optional part of the CCITT fax encoding standard. Its use can prevent significant data expansion when encoding certain image data, but many fax machine manufacturers and software vendors do not support it. K integer ( Optional ) Selects the encoding scheme to be used. A negative value indicates pure two-dimensional (Group 4) encoding. Zero indicates pure one-dimensional encoding (Group 3, 1-D). A positive value indicates mixed one- and two-dimen- sional encoding (Group 3, 2-D), in which a line encoded one-dimensionally can be followed by at most K – 1 lines encoded two-dimensionally. Default value: 0. The CCITTFaxEncode filter uses the value of K to determine how to encode the data. The CCITTFaxDecode filter distinguishes among negative, zero, and posi- to determine how to interpret the encoded data. However, it K tive values of does not distinguish between different positive K values. boolean ( Optional EndOfLine true , the CCITTFaxEncode filter prefixes an end-of-line bit pattern to ) If each line of encoded data. The CCITTFaxDecode filter always accepts end-of-line bit patterns, but requires them to be present only if EndOfLine is true . Default value: false . , the EncodedByteAlign boolean ( Optional ) If true CCITTFaxEncode filter inserts extra zero bits before each encoded line so that the line begins on a byte boundary; the CCITTFaxDecode filter skips over encoded bits to begin decoding each line at a byte boundary. If false , the filters neither generate nor expect extra bits in the encoded representa- tion. Default value: false . Columns integer ( Optional ) Specifies the width of the image in pixels. If Columns is not a multiple of 8, the filters adjust the width of the unencoded image to the next multiple of image operator, which requires that each line 8. This is for consistency with the of source data start on a byte boundary. Default value: 1728. Rows only. Specifies the height of the image in ( Optional ) Affects CCITTFaxDecode integer scan lines. If this parameter is zero or absent, the image’s height is not predeter- mined. The encoded data must be terminated by an end-of-block bit pattern or by the end of the filter’s data source. Default value: 0. 3.13 Filtered Files Details 135

144 PLRM 2nd Edition Language January 21, 1994 boolean filter appends an end-of-block pattern to Optional ) If true , the CCITTFaxEncode EndOfBlock ( the encoded data; the filter expects the encoded data to be ter- CCITTFaxDecode minated by end-of-block, overriding the Rows parameter. If false , CCITTFaxEn- code does not append an end-of-block pattern. CCITTFaxDecode stops when it has decoded lines or when its data source is exhausted, whichever happens Rows first. The end-of-block pattern is the CCITT end-of-facsimile-block (EOFB) or return-to-control (RTC) appropriate for the K parameter. Default value: true . BlackIs1 boolean ( Optional ) If true , causes 1 bits to be interpreted as black pixels and 0 bits as white pixels, the reverse of the normal PostScript language convention for image data. Default value: false . DamagedRowsBeforeError DamagedRowsBeforeError is positive integer ( Optional ) Affects CCITTFaxDecode only. If EndOfLine is , and K is non-negative, then up to DamagedRowsBeforeError true IOError is generated. Tolerating a rows of data will be tolerated before an damaged row means locating its end in the encoded data by searching for an EndOfLine pattern, then substituting decoded data from the previous row if the previous row was not damaged, or a white scan line if the previous row was also damaged. Default value: 0. The CCITT fax standard specifies a bi-level picture encoding in terms of black and white pixels. It does not define a representation for the unen- coded image data in terms of 0 and 1 bits in memory. However, the PostScript language (specifically, the image operator) does impose a convention: Normally, 0 means black and 1 means white. Therefore, the CCITTFaxEncode filter normally encodes 0 bits as black pixels and 1 bits as white pixels. Similarly, the CCITTFaxDecode filter normally pro- duces 0 bits for black pixels and 1 bits for white pixels. The BlackIs1 parameter can be used to reverse this convention if necessary. The fax encoding method is bit-oriented, not byte-oriented. This means that, in principle, encoded or decoded data might not end at a byte boundary. The and CCITTFaxDecode filters deal with CCITTFaxEncode this problem in the following ways: • Unencoded data are treated as complete scan lines, with unused bits inserted at the end of each scan line to fill out the last byte. This is image operator uses. compatible with the convention the • Encoded data are ordinarily treated as a continuous, unbroken bit stream. However, the EncodedByteAlign parameter can be used to cause each encoded scan line to be filled to a byte boundary. This is not prescribed by the CCITT standard, and fax machines never do this. But some software packages find it convenient to encode data this way. • When a filter reaches EOD, it always skips to the next byte boundary following the encoded data. 136 Chapter 3: Language

145 PLRM 2nd Edition Language January 21, 1994 DCTDecode Filter The syntax for using the DCTDecode filter is: /DCTDecode filter source dictionary This filter decodes gray-scale or color image data in JPEG baseline encoded format (see the DCTEncode filter). Usually, no parameters are required—that is, the dictionary operand can be an empty dictionary. This is because all information required for decoding an image is usu- ally contained in the JPEG signalling parameters, which accompany the encoded data in the compressed data stream. The only parameter that is likely to be needed is ColorTransform (see Table 3.17 on page 138). The decoded data are a stream of image samples, each of which consists of 1, 2, 3, or 4 color components, interleaved on a per-sample basis. Each component value occupies one 8-bit byte. The dimensions of the image and the number of components per sample depend on parameters that were specified when the image was encoded. Given suitable parameters, the image operator can consume data directly from DCTDecode filter. a Note An image consisting of 2 components per sample is not directly useful as a image operator, because the PostScript language does not define source for the any color spaces that have 2 color components (only 1, 3, and 4). Also, an image whose components are sent as separate scans instead of interleaved is image requires that components from separate sources be not useful, because read in parallel. DCTEncode Filter The proper syntax for using the DCTEncode filter is: target dictionary /DCTEncode filter This filter encodes gray-scale or color image data in JPEG baseline for- mat. JPEG is the ISO/CCITT Joint Photographic Experts Group , an organi- zation responsible for developing an international standard for compression of color image data. The DCTEncode filter conforms to the JPEG-proposed standard at the time of publication of this manual (see the bibliography). DCT refers to the primary technique (discrete cosine transform) used in the encoding and decoding algorithms. The algo- rithm can achieve very impressive compression of color images. For example, at a compression ratio of 10 to 1, there is little or no percepti- ble degradation in quality. 3.13 Filtered Files Details 137

146 PLRM 2nd Edition January 21, 1994 Language The compression algorithm is “lossy,” meaning the data produced by the Note DCTDecode filter are not exactly the same as the data originally encoded by filter. These filters are designed specifically for compression of DCTEncode the sampled continuous-tone images, not for general data compression. Input to the DCTEncode filter is a stream of image samples, each of which consists of 1, 2, 3, or 4 color components, interleaved on a per- sample basis. Each component value occupies one 8-bit byte. The dimensions of the image and the number of components per sample filter must be specified in a dictionary provided as an operand to the operator. This dictionary can also contain other optional parameters that control the operation of the encoding algorithm. Table 3.17 describes the contents of this dictionary. To specify the optional parameters properly requires understanding details of the encoding algorithm. That algorithm is not described here, but in the JPEG-proposed standard. The DCTDecode DCTEncode and filters do not support certain features of the standard that are irrelevant to images following PostScript language conventions. Additionally, Adobe has made certain choices regarding reserved marker codes and other optional features of the standard. Contact the Adobe Systems Developers’ Association for futher information. Entries in a DCTEncode dictionary Table 3.17 Type Semantics Key Columns integer ( Required ) Width of the image—in other words, samples per scan line. ) Height of the image—in other words, the number of scan lines. Required Rows integer ( Colors ( Required ) Number of color components in the image. It must be 1, 2, 3, or 4. integer HSamples array ( Optional ) Array of Colors integers specifying horizontal sampling factors. The i th element of the array specifies the sampling factor for the i th color compo- nent. The allowed sampling factors are 1, 2, 3, and 4. Default value: an array containing 1 for all components, meaning that all components are to be sam- pled at the same rate. When the sampling factors are not all the same, DCTEncode sub-samples the image for those components whose sampling factors are less than the largest HSamples is [4 3 2 1] for a four-color image, then for every one. For example, if 4 horizontal samples of the first component, DCTEncode sends only 3 samples of the second component, 2 of the third, and 1 of the fourth. However, DCTDecode inverts this sampling process so that DCTDecode produces the same amount of data as was presented to DCTEncode . In other words, this parameter affects only the encoded representation, not the unencoded or decoded repre- sentation. The filters deal correctly with the situation in which the width or height of the image is not a multiple of the corresponding sampling factor. 138 Chapter 3: Language

147 PLRM 2nd Edition Language January 21, 1994 array Optional ) Array of Colors integers specifying vertical sampling factors. Interpre- VSamples ( HSamples . tation and default value are the same as for The JPEG-proposed standard imposes a restriction on the values in the HSamples and VSamples arrays, taken together. For each color component, multiply its HSamples value by its VSamples value, then add all of the products together. The result must not exceed 10. QuantTables array ( Optional ) Array of Colors quantization tables. The i th entry in QuantTables is the table to be used, after scaling by , for quantization of the i th compo- QFactor nent. As many as four unique quantization tables can be specified, but several elements of the QuantTables array can refer to the same table. Each table must be either an array or a string. If it is an array, the elements must be numbers; if it is a string, the elements are interpreted as integers in the range 0 to 255. In either case, each table must contain 64 numbers organized according to the zigzag pattern defined by the JPEG-proposed standard. After scaling by QFactor , every element is rounded to the nearest integer in the range 1 to 255. Default value: quantization tables chosen by Adobe. . This enables QuantTables QFactor number ( Optional ) Scale factor applied to the elements of straightforward adjustment of the tradeoff between image compression and image quality without respecifying the quantization tables. must be QFactor positive. A value less than 1 improves image quality but decreases compression. A value greater than 1 increases compression but degrades image quality. Default value: 1.0. array ( Optional ) Array of 2 HuffTables × Colors encoding tables. The pair of tables at indices 2 × i and 2 × i +1 in HuffTables are used to construct Huffman tables for coding of the i th color component. The first table in each pair is used for the DC coeffi- cients, the second for the AC coefficients. At most two DC tables and two AC tables can be specified, but several elements of the HuffTables array can refer to the same tables. Default value: chosen by Adobe. Each table must be either an array or a string. If it is an array, the elements must be numbers; if it is a string, the elements are interpreted as integers in the range 0 to 255. The first 16 values specify the number of codes of each length from 1 to 16 bits. The remaining values are the symbols corresponding to each code; they are given in order of increasing code length. This information is sufficient to construct a Huffman coding table according to an algorithm given in the JPEG proposed standard. A QFactor value other than 1.0 may alter this computation. ColorTransform integer ( Optional ) Specifies a transformation to be performed on the sample values: 0 No transformation. 1If Colors is 3, transform RGB values to YUV before encoding and from YUV to RGB after decoding. If Colors is 4, transform CMYK values to YUVK before encoding and from YUVK to CMYK after decoding. This option is is 1 or 2. Colors ignored if 3.13 Filtered Files Details 139

148 PLRM 2nd Edition Language January 21, 1994 DCTEncode If performed, these transformations occur entirely within the and DCTDecode filters. The RGB and YUV used here have nothing to do with the color spaces defined as part of the PostScript language’s imaging model. The pur- pose of converting from RGB to YUV is to separate luminance and chrominance information (see below). ColorTransform is 1 if Colors is 3 and 0 otherwise. In other The default value of words, conversion between RGB and YUV is performed for all 3-component images unless explicitly disabled by setting ColorTransform to 0. Additionally, the filter inserts an Adobe-defined marker code in the encoded data DCTEncode indicating the ColorTransform value used. If present, this marker code overrides the ColorTransform value given to DCTDecode . Thus, it’s necessary to specify ColorTransform only when decoding data that does not contain the Adobe- defined marker code. HuffTables are chosen without The default values for QuantTables and reference to the image color space and without specifying any particu- lar trade-off between image quality and compression. Although they will work, they will not produce optimal results for most applications. For superior compression, applications should provide custom QuantTables and HuffTables arrays rather then relying on the default values. Better compression is often possible for color spaces that treat lumi- nance and chrominance separately than for those that do not. The RGB to YUV conversion provided by the filters is one attempt to separate luminance and chrominance. Other color spaces, such as the CIE 1976 (L*a*b*)-space, may also achieve this objective. The chrominance com- ponents can then be compressed more than the luminance by using coarser sampling or quantization, with no degradation in quality. DCTEncode filter requires that a spe- Unlike other encoding filters, the cific amount of data be written to it: × Rows samples of Colors Columns bytes each. The filter reaches EOD at that point. It cannot accept further data, so attempting to write to it will cause an ioerror . The program must now close the filter file to cause the buffered data and EOD marker to be flushed to the data target. SubFileDecode Filter The syntax for using the SubFileDecode filter is: /SubFileDecode filter source EODcount EODstring This filter does not perform data transformation, but it can detect an EOD condition. Its output is always identical to its input, up to the 140 Chapter 3: Language

149 PLRM 2nd Edition Language January 21, 1994 sub- point where EOD occurs. The data preceding the EOD are called a of the underlying data source. file The SubFileDecode filter can be used in a variety of ways: • A subfile can contain data that should be read or executed condition- ally, depending on information that is not known until execution. If a program decides to ignore the information in a subfile, it can easily skip to the end of the subfile by invoking flushfile on the filter file. • Subfiles can help recover from errors that occur in encapsulated pro- grams. If the encapsulated program is treated as a subfile, the enclos- ing program can regain control if an error occurs, flush to the end of the subfile, and resume execution from the underlying data source. The application, not the PostScript interpreter, must provide such error handling; it is not the default error handling provided by the PostScript interpreter. • The SubFileDecode filter enables an arbitrary data source (procedure or string) to be treated as an input file. This use of subfiles does not require detection of an EOD marker. The SubFileDecode filter requires two parameters, EODcount and EOD- string , which specify the condition under which the filter is to recognize EOD. The filter will allow data to pass through the filter until it has ; then it will EODstring encountered exactly EODcount instances of the reach EOD. must be a non-negative integer. If EODcount is greater than EODcount zero, all input data up to and including that many occurrences of the EODstring will be passed through the filter and made available for read- ing. If EODcount is zero, the first occurrence of the EODstring will be consumed by the filter, but it will not be passed through the filter. EODstring is ordinarily a string of non-zero length. It is compared with successive subsequences of the data read from the data source. This comparison is based on equality of 8-bit character codes so matching is case-sensitive. Each occurrence of in the data is counted EODstring will not be recognized. EODstring once. Overlapping instances of the ” will be recognized only once in the For example, an EODstring of “ eee input “ XeeeeX ”. The EODstring may also be of length zero, in which case the bytes of arbitrary data. SubFileDecode filter will simply pass EODcount This is dependable only for binary data, when suitable precautions have 3.13 Filtered Files Details 141

150 PLRM 2nd Edition January 21, 1994 Language been taken to protect the data from any modification by communica- tion channels or operating systems. Ordinary ASCII text is subject to modifications such as translation between different end-of-line conven- tions, which can change the byte count in unpredictable ways. A recommended value for EODstring is a document structuring com- ment, such as %%EndBinary . EODstring s containing newline ( \n ) char- recommended. Translating the data between different not acters are end-of-line conventions could subvert the string comparisons. If EODcount is zero and EODstring is of zero length, detection of EOD markers is disabled; the filter will not reach EOD. This is useful prima- rily when using procedures or strings as data sources. It is illegal for EODcount to be negative. NullEncode Filter The syntax for using the NullEncode filter is: target /NullEncode filter This is an encoding filter that does not perform data transformation, and its output is always identical to its input. The purpose of this filter is to allow an arbitrary data target (procedure or string) to be treated as an output file. 142 Chapter 3: Language

151 PLRM 2nd Edition January 26, 1994 Graphics Example 1.0 3z Example 2.0 Example 3.0 Example 4.0 Example 4.0 Example 5.0 Table 4.0 Example 6.0 4 CHAPTER Figure 4.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Graphics The PostScript language graphics operators describe the appearance of pages that are to be reproduced on a raster output device. The facilities described here are intended for both display and printer applications. The graphics operators form six major groups: • . This group contains operators that manipu- Graphics state operators late the data structure called the graphics state , which is the global framework in which the other graphics operators execute. • Coordinate system and matrix operators . The graphics state includes the current transformation matrix (CTM) that maps coordinates speci- fied by the PostScript language program into output device coordi- nates. The operators in this group manipulate the CTM to achieve any combination of translation, scaling, rotation, reflection, and skewing of user coordinates onto device coordinates. • Path construction operators . The graphics state includes the current path that defines shapes and line trajectories. The operators in this group begin a new path, add line segments and curves to the current path, and close the current path. All of these operators implicitly ref- erence the CTM parameter in the graphics state. Painting operators . These operators paint graphical elements, such as • lines, filled areas, and sampled images into the raster memory of the output device. The painting operators are controlled by the current path, current color, and many other parameters in the graphics state. • . These operators select and paint charac- Character and font operators ters from fonts, or descriptions of typefaces. Because the PostScript language treats characters as general graphical shapes, many of the font operators should be grouped with the path construction or 143

152 PLRM 2nd Edition January 26, 1994 Graphics painting operators. However, the data structures and mechanisms for dealing with character and font descriptions are sufficiently special- ized that Chapter 5 focuses on them. • Device setup and output operators . Device setup operators establish the association between raster memory and a physical output device, such as a printer or a display. Once a page has been completely described, executing an output operator transmits the page to the device. This chapter presents general information about device-independent graphics in the PostScript language: how a program describes the abstract appearance of a page. Rendering—the device dependent part of graphics—is covered in Chapter 6. 4.1 Imaging Model The PostScript language’s imaging model is a simple and unified view of two-dimensional graphics borrowed from the graphic arts. A PostScript language program builds an image by placing “paint” on a “page” in selected areas. • The painted figures may be in the form of letter shapes, general filled shapes, lines, or digitally sampled representations of photographs. • The paint may be in color or in black, white, or any shade of gray. • The paint may take the form of a repeating pattern ( Level 2 ). • Any of these elements may be clipped to appear within other shapes as they are placed onto the page. • Once a page has been built up to the desired form, it may be trans- mitted to an output device. The PostScript interpreter maintains an implicit that accu- current page mulates the marks made by the painting operators . When a program begins, the current page is completely white. As each painting operator executes, it places marks on the current page. Each new mark com- pletely obscures any marks it may overlay. This method is known as a : No matter what color a mark has—white, black, gray, or painting model color—it is put onto the current page as if it were applied with opaque 144 Chapter 4: Graphics

153 PLRM 2nd Edition January 26, 1994 Graphics paint. Once the page has been completely composed, invoking the showpage operator renders the accumulated marks on the output media and then clears the current page to white again. The imaging model applies to raster display devices and printers. How- ever, there usually is not a separate operation for transmitting the page to a display device; instead, marks placed on the current page appear on the display immediately. There are some extensions to the imaging model to serve the special needs of interactive display applications. Those extensions are supported by the Display PostScript system and are documented in Chapter 7. The principal painting operators, among many others, are as follows: fill • paints an area. • paints lines. stroke image paints a sampled image. • show paints character shapes. • The painting operators require various parameters, some explicit and others implicit. Chief among the implicit parameters is the current path . A path consists of a sequence of con- show used by fill , stroke , and nected and disconnected points, lines, and curves that together describe shapes and their positions. It is built up through the sequential application of the path construction operators , each of which modifies the current path in some way, usually by appending one new element. arc Path construction operators include newpath , lineto , curveto , , and closepath . None of the path construction operators places marks on the current page; the painting operators do that. Path construction opera- tors create the shapes that the painting operators paint. Some opera- tors, such as ufill and ustroke , combine path construction and painting in a single operation for efficiency. Implicit parameters to the painting operators include the current color, current line thickness, current font (typeface-size combination), and many others. There are operators that examine and set each implicit parameter in the graphics state. The values used for implicit parameters are those in effect at the time an operator is invoked. 4.1 Imaging Model 145

154 PLRM 2nd Edition Graphics January 26, 1994 PostScript language programs contain many instances of the following typical sequence of steps: 1. Build a path using path-construction operators. 2. Set any implicit parameters if their values need to change. 3. Perform a painting operation. There is one additional implicit element in the PostScript imaging model that modifies this description: The current clipping path outlines the area of the current page on which paint may be placed. Initially, this clipping path outlines the entire imageable area of the current page. By using the operator, a PostScript language program can clip shrink the current clipping path to any shape desired. It is possible for a painting operator to attempt to place marks outside the current clip- ping path. Marks falling within the clipping area will affect the current page; marks falling outside will not. 4.2 Graphics State The PostScript interpreter maintains a data structure called the graphics state that holds current graphics control parameters. These parameters define the global framework in which the graphics operators execute. parame- current font For example, the show operator implicitly uses the ter as set in the graphics state, and the operator implicitly uses the fill current color parameter. The graphics state is not itself an object. However, it contains many objects, nearly all of which can be read and altered by special graphics state operators. For example, the operator setfont changes the current font parameter in the graphics state, and currentfont reads that param- eter from the graphics state. There are two mechanisms for saving and later restoring the entire graphics state. One is a graphics state stack . The gsave operator pushes a copy of the entire graphics state onto the graphics state stack. The grestore operator restores the entire graphics state to its former value by popping it from the graphics state stack. The second mechanism uses gstate objects in VM that contain saved cop- ies of the graphics state. This is a Level 2 feature. The gstate operator operator copies the entire currentgstate creates a new gstate object. The 146 Chapter 4: Graphics

155 PLRM 2nd Edition Graphics January 26, 1994 setgstate graphics state into a gstate object given as an operand. The operator replaces the entire graphics state by the value of the supplied gstate object. The graphics state stack, with its LIFO (last in, first out) organization, serves the needs of PostScript programs that are page descriptions. A well-structured document typically contains many graphical elements that are essentially independent of each other and sometimes nested to operators can be used to encap- multiple levels. The gsave and grestore sulate these elements so they can make local changes to the graphics state without disturbing the graphics state of the surrounding environ- ment. In some interactive applications, however, a program must switch its attention among multiple, more-or-less independent imaging contexts in an unpredictable order. This is most conveniently done by creating a separate gstate object for each one and using setgstate to switch among them as needed. parameter, including such things Saving a graphics state captures every as the current path and current clipping path. For example, if a non- empty current path exists at the time that gstate , or , gsave currentgstate is executed, that path will be reinstated by the corre- grestore or setgstate . Unless this effect is specifically desired, sponding it’s best to save a graphics state only when the current path is empty and the current clipping path is in its default state to minimize storage demands. Most graphics state parameters are ordinary PostScript language objects. The operators that set them simply store them, unchanged, for later use by other graphics operators. However, certain parameters have special properties or behavior: • The current path, clipping path, and device parameters are internal objects that are not directly accessible to a PostScript language program. • Most parameters must be of the correct type or have values that fall into a certain range. • Parameters that are numbers, such as color, line width, and miter limit, are forced into legal range, if necessary, and stored as reals. If they are later read out, they are always reals, regardless of how they not were originally specified. However, they are adjusted to reflect capabilities of the raster output device, such as resolution or number 4.2 Graphics State 147

156 PLRM 2nd Edition January 26, 1994 Graphics of distinguishable colors. Such adjustments are performed by graph- ics rendering operators, but the adjusted values are not stored back in the graphics state. • Certain parameters are composite objects, such as arrays or diction- aries. In general, graphics operators consult the values of those objects at unpredictable times, so altering them can have unpredict- able results. A PostScript language program should treat the values of graphics state parameters as if they were read-only. Table 4.1 lists the set of graphics state parameters that are device inde- pendent and are appropriate to specify in page descriptions. Table 4.2 . dependent lists the set of graphics state parameters that are device Device-dependent parameters control details of the rendering (scan- conversion) process. A page description that is intended to be device independent should not alter these parameters. Table 4.1 Device-independent parameters of the graphics state Type Parameter Definition CTM array Current transformation matrix, which maps positions from user coordinates to device coordinates. This matrix is modified by each application of the coordinate system operators. Initial value: a matrix that transforms default user coordinates to device coordinates. color (various) The color to use during painting operations. This is interpreted according to any of several different color spaces. For most color spaces, a color value consists of one to four numbers. Initial value: black. color space ) Determines how color values are to be interpreted. Initial value: Level 2 array ( DeviceGray . position 2 numbers Location of the current point in user space: the coordinates of the last element of the current path. Initial value: undefined. path (internal) The current path as built up by the path construction operators. The current clip path is an implicit argument to operators, such as fill , stroke , and . Initial value: empty. (internal) A path defining the current boundary against which all output is cropped. Initial clipping path value: the boundary of the entire imageable portion of the output page. font dictionary The set of graphic shapes (characters) that define the current typeface. Initial value: an invalid font dictionary. line width number The thickness (in user coordinate units) of lines to be drawn by the stroke operator. Initial value: 1. A code that specifies the shape of the endpoints of any open path that is stroked. line cap integer Initial value: 0 for a square butt end. 148 Chapter 4: Graphics

157 PLRM 2nd Edition Graphics January 26, 1994 integer line join A code that specifies the shape of joints between connected segments of a stroked line. Initial value: 0 for mitered joins. number The maximum length of mitered line joins for the stroke operator. This limits miter limit the length of “spikes” produced when line segments join at sharp angles. Initial value: 10 for a miter cutoff below 11 degrees. dash pattern (several) A description of the dash pattern to be used when lines are painted by the stroke operator. Initial value: a normal solid line. ) Specifies whether to compensate for resolution effects that may be stroke adjust boolean ( Level 2 noticeable when line thickness is a small number of device pixels. Initial value: false for printers, true for displays). installation dependent (typically Table 4.2 Device-dependent parameters of the graphics state Parameter Type Definition color rendering dictionary ( Level 2 ) Describes how to transform CIE-based color specifications to device color values. Initial value: installation dependent. ) When generating color separations, specifies whether painting on one overprint boolean ( Level 2 separation causes the corresponding areas of other separations to be erased ( true ). Initial value: false . ) or left unchanged ( false proc ( Level 2 ) Calculates the amount of black to use when converting RGB colors to black generation CMYK. Initial value: installation dependent. undercolor removal proc ( Level 2 ) Calculates the reduction in the amount of cyan, magenta, and yellow components to compensate for the amount of black added by black generation. Initial value: installation dependent. proc Transfer function that adjusts device gray or color component values to correct transfer for non-linear response in a particular device. Support for four transfer functions is a Level 2 feature. Initial value: installation dependent. halftone (various) Halftone screen for gray and color rendering, specified either as frequency, angle, and spot function or as a halftone dictionary. Support for four halftone screens is a Level 2 feature. Initial value: installation dependent. halftone phase 2 integers ( Display PostScript ) A shift in the alignment of halftone and pattern cells in device space to compensate for window system operations that involve scrolling. Initial values: 0, 0. flatness number The accuracy (or smoothness) with which curves are to be rendered on the output device. This number gives the maximum error tolerance, measured in output device pixels. Smaller numbers give smoother curves at the expense of more computation and memory use. Initial value: 1.0. (internal) device An internal data structure representing the current output device. Initial value: installation dependent. 4.2 Graphics State 149

158 PLRM 2nd Edition Graphics January 26, 1994 4.3 Coordinate Systems and Transformations Paths and shapes are defined in terms of pairs of points on the Carte- sian plane specified as coordinates . A coordinate pair is a pair of real numbers x and y that locate a point within a Cartesian (two-axis) coor- . The PostScript lan- dinate system superimposed on the current page guage defines a default coordinate system that PostScript language programs can use to locate any point on the current page. 4.3.1 User Space and Device Space Coordinates specified in a PostScript language program refer to loca- tions within a coordinate system that always bears the same relation- ship to the current page regardless of the output device on which printing or displaying will be done. This coordinate system is called user . space Output devices vary greatly in the built-in coordinate systems they use to address pixels within their imageable areas. A particular device’s coordinate system is a . A device space origin can be any- device space where on the output page. This is because the paper moves through dif- ferent printers and typesetters in different directions. On displays, the origin can vary depending on the window system. Different devices have different resolutions. Some devices even have resolutions that are different in the x and y directions. The operands of the path operators are user space coordinates. The PostScript interpreter automatically transforms user space coordinates into device space. For the most part, this transformation is hidden from the PostScript language program. A program must consider device space only rarely for certain special effects. This independence of user space from device space is key to the device independent nature of PostScript language page descriptions. One can define a coordinate system with respect to the current page by stating: • The location of the origin. axes. • The orientation of the x and y • The lengths of the units along each axis. 150 Chapter 4: Graphics

159 PLRM 2nd Edition Graphics January 26, 1994 Initially, the user space origin is located at the lower-left corner of the output page or display window, with the positive x axis extending hori- zontally to the right and the positive y axis extending vertically upward, as in standard mathematical practice. The length of a unit axes is 1/72 of an inch. This coordinate system is along both the x and y the . In default user space, all points within the current default user space page have positive x and y coordinate values. Note The default unit size (1/72 of an inch) is approximately the same as a “point,” a unit used widely in the printing industry. It is not exactly the same as a point, however; there is no universal definition of a point. The default user space origin coincides with the lower-left corner of the physical page. Portions of the physical page may not be imageable on certain output devices. For example, many laser printers cannot place marks at the extreme edges of their physical page areas. It may not be possible to place marks at or near the default user space origin. The physical correspondence of page corner to default origin ensures that marks within the imageable portion of the output page will be consis- tently positioned with respect to the edges of the page. Coordinates in user space may be specified as either integers or reals. Therefore, the unit size in default user space does not constrain locations to any arbitrary grid . The resolution of coordinates in user space is not related in any way to the resolution of pixels in device space. The default user space provides a consistent, dependable starting place for PostScript language programs regardless of the output device used. If necessary, the PostScript language program may then modify user space to be more suitable to its needs by applying coordinate transformation , such as operators translate . , rotate , and scale What may appear to be absolute coordinates in a PostScript language program are not absolute with respect to the current page, because they are described in a coordinate system that may slide around and shrink or expand. Coordinate system transformation not only enhances device independence, but is a useful tool in its own right. For example, a page description originally composed to occupy an entire page may be incor- porated without change into another page description as just one ele- ment of the page by shrinking the coordinate system in which it is drawn. Conceptually, user space is an infinite plane. Only a small portion of this plane corresponds to the imageable area of the output device: a rec- tangular area above and to the right of the origin in default user space. 4.3 Coordinate Systems and Transformations 151

160 PLRM 2nd Edition Graphics January 26, 1994 The actual size and position of the area is device and media dependent. An application can request a particular page size or other media proper- setpagedevice , described in section 4.11, ties using the Level 2 operator “Device Setup.” 4.3.2 Transformations A transformation matrix specifies how to transform the coordinate pairs of one coordinate space into another coordinate space. The graphics (CTM) that describes the state includes the current transformation matrix transformation from user space to device space. The elements of a matrix specify the coefficients of a pair of linear equa- tions in x and y that generate a transformed x and y . However, in graph- ical applications, matrices are not often thought of in this abstract mathematical way. Instead, a matrix is considered to capture some sequence of geometric manipulations: translation, rotation, scaling, reflection, and so on. Most of the PostScript language matrix operators are organized according to this latter model. the modify The most commonly used matrix operators are those that current transformation matrix in the graphics state. These operators do not create a new transformation matrix from nothing; instead, they change the existing transformation matrix in some specific way. Opera- tors that modify user space include the following: • translate moves the user space origin to a new position with respect to the current page while leaving the orientation of the axes and the unit lengths unchanged. • rotate turns the user space axes about the current user space origin by some angle, leaving the origin location and unit lengths unchanged. • scale modifies the unit lengths independently along the current x and y axes, leaving the origin location and the orientation of the axes unchanged. applies an arbitrary linear transformation to the user coordi- • concat nate system. Such modifications have a variety of uses: 152 Chapter 4: Graphics

161 PLRM 2nd Edition January 26, 1994 Graphics • Changing the user coordinate system conventions for an entire page . For example, in some applications it might be convenient to express user coordinates in centimeters rather than in 72nds of an inch, or it might be convenient to have the origin in the center of the page rather than in the lower left corner. • Defining each graphical element of a page in its own coordinate system , independent of any other element. The program can then position, orient, and scale each element to the desired location on the page by temporarily modifying the user coordinate system. This permits decoupling the description of an element from the description of its placement on the page. Example 4.1 may aid in understanding the second type of modification. Comments explain what each operator does. Example 4.1 /box {newpath % Define a procedure to construct a unit square 0 0 moveto % path in the current user coordinate system, % with its lower-left corner at the origin. 0 1 lineto 1 1 lineto 1 0 lineto closepath } def gsave % Save the current graphics state and create a % new one that we shall then modify. % Modify the current transformation matrix so 72 72 scale % everything subsequently drawn will be 72 times % larger; that is, each unit will represent an inch % instead of 1/72nd of an inch. box fill % Draw a unit square with its lower-left corner at % the origin and fill it with black. Because the unit % size is now one inch, this box is one inch on a side. 2 2 translate % Change the transformation matrix again so % the origin is at 2", 2" (displaced two inches % in from the left and bottom edges of the page). box fill % Draw the box again. This box has its lower- % left corner two inches up from and two inches % to the right of the lower-left corner of the page. grestore % Restore the saved graphics state. % Now we are back to default user space. 4.3 Coordinate Systems and Transformations 153

162 PLRM 2nd Edition January 26, 1994 Graphics Two squares produced by Example 4.1 Figure 4.1 0,0 inches Figure 4.1 is a reduction of the entire page containing the two squares x and y positions painted by Example 4.1, along with scales indicating in inches. This shows how coordinates, such as the ones given to the and lineto graphics operators, are transformed by the current moveto transformation matrix. By combining translation, scaling, and rotation, one may use very simple prototype graphics procedures—such as box in the example—to generate an infinite variety of instances. 4.3.3 Matrix Representation and Manipulation The descriptions of the coordinate system and matrix operators in Chapter 8 are easier to understand with some knowledge of the repre- sentation and manipulation of matrices. What follows is a brief intro- duction to this topic. It is not essential that you understand the details of matrix arithmetic on first reading, only that you obtain a clear geo- metrical model of the effects of the various transformations. A two-dimensional transformation is described mathematically by a × 3 matrix: 3 ab 0 cd 0 1 t t x y 154 Chapter 4: Graphics

163 PLRM 2nd Edition January 26, 1994 Graphics In the PostScript language, this matrix is represented as a six-element array object [ a b c d t t ] x y omitting the matrix elements in the third column, which always have constant values. This matrix transforms a coordinate pair ( x , y ) into another coordinate x’, y’ ) according to the linear equations: pair ( x ' ax cy t = ++ x ' y bx dy t ++ = y The common transformations are easily described in this matrix nota- t t tion. Translation by a specified displacement ( , ) is described by the y x matrix: 100 010 t 1 t y x in the y s dimension is in the x dimension and s Scaling by the factor y x accomplished by the matrix: 00 s x 0 s 0 y 001 θ Rotation counterclockwise about the origin by an angle is described by the matrix: sin 0 θ cos θ cos 0 θ sin −θ 001 155 4.3 Coordinate Systems and Transformations

164 PLRM 2nd Edition January 26, 1994 Graphics Figure 4.2 Effects of coordinate transformations θ s y t y t s x x Rotation Scaling Translation A PostScript language program can describe any desired transformation as a sequence of these operations performed in some order. An impor- a tant property of the matrix notation is that a program can concatenate of all sequence of operations to form a single matrix that embodies those operations in combination. That is, transforming any coordinate by the single concatenated matrix produces the same result as trans- forming it by all the original matrices in sequence. Any linear transfor- mation from user space to device space can be described by a single transformation matrix, the CTM. Note Concatenation is performed by matrix multiplication. The order in which transformations are concatenated is important (technically, matrix operations are associative, but not commutative). The requirement that matrices conform 3 matrices. Otherwise, × during multiplication is what leads to the use of 3 × 3 matrices would suffice to describe transformations. 2 , and The operators translate , scale rotate each concatenate the CTM with a matrix describing the desired transformation, thus producing a new matrix that describes the combination of the original and addi- tional transformations. This matrix is then established as the new CTM: new CTM = transformation original CTM × It is sometimes necessary to perform the of a transformation— inverse that is, to find the user space coordinate that corresponds to a specific device space coordinate. PostScript language programs explicitly do this only occasionally, but it occurs commonly in the implementation. Chapter 4: Graphics 156

165 PLRM 2nd Edition Graphics January 26, 1994 Not all transformations are invertible in the way just described. For d , b , example, if a matrix contains , and a elements that are all zero, all c user coordinates map to the same device coordinate and there is no unique inverse transformation. This condition produces the error undefinedresult . Non-invertible transformations aren’t very useful and generally arise from unintentional operations, such as scaling by zero. 4.4 Path Construction path defines shapes, trajectories, and In the PostScript language, a regions of all sorts. Programs use paths to draw lines, specify boundaries of filled areas, and define templates for clipping other graphics. A path is composed of straight and curved line segments. These seg- ments may connect to one another or they may be disconnected. The topology of a path is unrestricted: It may be concave or convex; it may contain multiple closed subpaths , representing several areas; and it may intersect itself in arbitrary ways. Paths are represented by data structures internal to the interpreter. Although a path is not directly accessible as an object, a PostScript lan- guage program directly controls its construction and use. A path is con- structed by sequential application of one or more path construction operators . At any time, the path may be read out, or more commonly, be used to control the application of one of the painting operators described in section 4.5, “Painting.” The current path is part of the graphics state. The path construction operators modify the current path, usually by appending to it, and the painting operators implicitly refer to the current path. The gsave and grestore operators respectively save and restore the current path, as they do all components of the graphics state. The order of the segments that define a path is significant. A pair of line only if they are defined consecutively, segments is said to “connect” with the second segment starting where the first one ends. Non-consec- utive segments that meet or intersect fortuitously are not considered to connect. A subpath of a path is a sequence of connected segments. A path is made up of one or more disconnected subpaths. There is an operator, closepath , that explicitly connects the end of a subpath back to its start- ing point; such a subpath is said to be closed . A subpath that has not . open been closed explicitly is 4.4 Path Construction 157

166 PLRM 2nd Edition January 26, 1994 Graphics newpath operator. This A program may begin a path by executing the initializes the current path to be empty. Some of the painting operators end of their execution. The program builds also initialize the path at the up the path by executing one or more of the operators that add seg- ments to the current path. A program may execute them in any must come first. sequence, but a moveto All the points used to describe the path are coordinates in user space. Each coordinate is transformed by the CTM into device space at the time the program enters the point into the current path. Changing the CTM does not cause existing points to move in device space. The trailing endpoint of the segment most recently entered is referred current point to as the . If the current path is empty, the current point is undefined. Most operators that add a segment to the current path start at the current point. If the current point is undefined, they execute the error . nocurrentpoint Following is a list of the most common path operators. There are several other path construction operators. Complete details are presented in Chapter 8. • establishes a new current point without adding a segment to moveto the path. This begins a new subpath of the current path. • lineto adds a straight line segment to the path, connecting the previ- ous current point to the new one. add an arc of a circle to the current path. arcto • arc , arcn , arct , and • adds a section of a Bézier cubic curve to the current path. curveto • rmoveto , rlineto , and rcurveto perform the moveto , lineto , and curveto operations, but specify new points as displacements in user space relative to the current point. closepath adds a straight line segment connecting the current point • to the starting point of the current subpath (usually the point most recently specified by moveto ), thereby closing the current subpath. The graphics state also contains a clipping path that defines the regions of the page that may be affected by the painting operators. Marks fall- ing inside the area defined by the closed subpaths of this path will be applied to the page; marks falling outside will not. (Precisely what is 158 Chapter 4: Graphics

167 PLRM 2nd Edition Graphics January 26, 1994 considered to be “inside” a path is discussed in section 4.5, “Painting.”) The clip operator computes a new clipping path from the intersection of the current path with the existing clipping path. Note Remember that the path construction operators do not place any marks on the page. Only the painting operators do that. The usual procedure for painting a graphic element on the page is to define that element as a path and then invoke one of the painting operators. This is repeated for each element on the page. A path that is to be used more than once in a page description can be defined by a PostScript language procedure that invokes the operators for constructing the path. Each instance of the path may then be con- structed and painted on the page by a three-step sequence: 1. Modify the CTM, if necessary, by invoking coordinate transforma- tion operators to properly locate, orient, and scale the path to the desired place on the page. 2. Call the procedure to construct the path. 3. Execute a painting operator to mark the path on the page in the desired manner. In the common situation that the path description is constant, you may invoke the user path operators (described in section 4.6, “User Paths”) to combine steps 2 and 3. User paths are a Level 2 feature. gsave You may encapsulate the entire sequence by surrounding it with and grestore . A simple illustration of this use appears in the “box” example of section 4.3, “Coordinate Systems and Transformations.” A path is unrestricted in its topology. However, because the entire set of points defining a path must exist as data simultaneously, there is a limit to the number of segments a path may have. Because several paths may also exist simultaneously (current path, clipping path, and paths saved by gsave and currentgstate ), this limit applies to the total amount of storage occupied by all paths. If a path exhausts available storage, a limitcheck error occurs. The value of the limit is implementation depen- dent; see Appendix B. 4.4 Path Construction 159

168 PLRM 2nd Edition Graphics January 26, 1994 As a practical matter, the limits on path storage are sufficiently large that they do not impose an unreasonable restriction. It is important, however, that separate elements of a page be constructed as separate paths with each one painted . An attempt to describe and then discarded an entire page as a single path is likely to exceed the path storage limit. 4.5 Painting The painting operators mark graphical shapes on the current page. The principal, general-purpose painting operators are stroke and fill , described in this section. More specialized operators include , image described in section 4.10, “Images,” and the character and font opera- tors, described in Chapter 5. The operators and graphics state parameters described here control the abstract appearance of graphical shapes; they are device independent. Additional facilities to control graphics rendering in raster memory are described in Chapter 6. Those facilities are device dependent. 4.5.1 Stroking stroke operator draws a line of some thickness along the current The path. For each straight or curved segment in the path, draws a stroke line that is centered on the segment with sides parallel to the segment. The settings of graphics state parameters control the results of the stroke operator. These parameters include CTM, color, line width, line cap, line join, miter limit, dash, and stroke adjustment (a Level 2 fea- ture). Graphics state parameters are summarized in section 4.2, “Graph- ics State.” Details on each of the operators appear in Chapter 8. stroke treats each subpath of a path separately. • Wherever two consecutive segments are connected, the joint between them is treated with the current line join , which may be mitered, rounded, or beveled (see the description of the setlinejoin operator). • If the subpath is open, the unconnected ends are treated with the current line cap , which may be butt, rounded, or square (see setlinecap ). 160 Chapter 4: Graphics

169 PLRM 2nd Edition Graphics January 26, 1994 • Points at which unconnected segments happen to meet or intersect receive no special treatment. In particular, “closing” a subpath with lineto rather than with closepath may result in a messy an explicit corner, because line caps rather than a line join are applied in that case. A stroke can be made either with a solid line or with a user-specified dash pattern (see setdash ). The color of the line is determined by the current color or pattern in the graphics state (see setgray , setrgbcolor , setpattern sethsbcolor setcmykcolor , setcolor , and , ; the last three are Level 2 operators). A program can request that coordinates and line widths be adjusted automatically to produce strokes of uniform thickness despite rasteriza- tion effects. This is a Level 2 feature, controlled by the stroke adjust- ; section 6.5.2, “Automatic Stroke setstrokeadjust ment parameter (see Adjustment,” gives details of the effects produced). Filling 4.5.2 The fill operator uses the current color or pattern to paint the entire region enclosed by the current path. If the path consists of several dis- fill paints the insides of all subpaths, considered connected subpaths, together. Any subpaths of the path that are open are implicitly closed before being filled. For a simple path, it is intuitively clear what region lies “inside.” How- ever, for a more complex path—for example, a path that intersects itself or has one subpath that encloses another—the interpretation of “inside” is not so obvious. The path machinery uses one of two rules for determining which points lie inside a path. The determines whether a given point is non-zero winding number rule inside a path by conceptually drawing a ray from that point to infinity in any direction and then examining the places where a segment of the path crosses the ray. Here’s how it works: Starting with a count of zero, add one each time a path segment crosses the ray from left to right and subtract one each time a path segment crosses the ray from right to left. After counting all the crossings, if the result is zero then the point is outside the path. Otherwise it is inside . The rule does not specify what to do if a path segment coincides with or is Note tangent to the ray. Since any ray will do, one may simply choose a different ray that does not encounter such problem intersections. 4.5 Painting 161

170 PLRM 2nd Edition January 26, 1994 Graphics With the non-zero winding number rule, a simple convex path yields inside and outside as you would expect. Now consider a five-pointed star, drawn with five connected straight line segments intersecting each other. The entire area enclosed by the star, including the pentagon in the center, is considered inside by the non-zero winding number rule. For a path composed of two concentric circles, if they are both drawn in the same direction , the areas enclosed by both circles are inside, accord- ing to the rule. If they are drawn in opposite directions, only the “doughnut” shape between the two circles is inside, according to the rule; the “doughnut hole” is outside. Figure 4.3 shows the effects of applying this rule. Non-zero winding number rule Figure 4.3 An alternative to the non-zero winding number rule is the even-odd rule . This rule determines the “insideness” of a point by drawing a ray from that point in any direction and counting the number of path segments that the ray crosses. If this number is odd, the point is inside; if even, the point is outside. Figure 4.4 shows the effects of applying this rule. Even-odd rule Figure 4.4 162 Chapter 4: Graphics

171 PLRM 2nd Edition Graphics January 26, 1994 The even-odd rule yields the same results as the non-zero winding number rule for paths with simple shapes, but yields different results for more complex shapes. For the five-pointed star drawn with five intersecting lines, the even-odd rule considers the triangular points to be inside, but the pentagon in the center to be outside. For the two con- centric circles, only the “doughnut” shape between the two circles is inside, according to the even-odd rule, regardless of whether the circles are drawn in the same or opposite directions. The non-zero winding number rule is more versatile than the even-odd rule and is the standard rule the fill operator uses. The even-odd rule is occasionally useful for special effects or for compatibility with other eofill graphics systems. The operator invokes this rule. The operator uses the same rule as the fill operator to determine the clip inside of the current clipping path. The eoclip operator uses the same rule as eofill . 4.5.3 Insideness Testing It is sometimes useful for a program to test whether a point lies inside a path or a path intersects another path, without actually painting any- thing. The Level 2 “insideness” operators can be used for this purpose. They are useful mainly for interactive applications using the Display PostScript system, where they can assist in hit detection (see section 7.3.2, “Hit Detection”). However, they have other uses as well. There are several insideness testing operators that vary according to how the paths to be tested are specified. All of the operators return a single boolean result. What it means for a given point to be “inside” a path is that painting the path (by fill or stroke ) would cause the device pixel lying under the point to be painted. These tests disregard the cur- rent clipping path. infill tests the current path in the graphics state. There are two forms • infill . One returns true of if the device pixel corresponding to a spe- cific point in user space would be painted by fill with the current path. The second tests whether any pixels in some would be aperture painted by fill . The aperture is specified by a user path given as a sepa- rate operand. See section 4.6, “User Paths.” • instroke is similar to infill , but it tests pixels that would be painted by with the current path, using the current stroke-related stroke parameters in the graphics state (line width, dash pattern, and so on). 4.5 Painting 163

172 PLRM 2nd Edition Graphics January 26, 1994 and inufill inustroke are similar to • and instroke , but they test a infill path given as a separate user path operand instead of testing the cur- rent path in the graphics state. • ineofill and inueofill are similar to infill and inufill , but their “inside- ness” test is based on the even-odd rule instead of the non-zero winding number rule. See section 4.5.2, “Filling.” 4.6 User Paths A user path is a procedure that consists entirely of path construction operators and their coordinate operands expressed as literal numbers. In other words, it is a completely self-contained description of a path in user space. Several operators combine the execution of a user path description with painting the resulting path, using it for filling or strok- ing. User paths are a Level 2 feature. Example 4.2 illustrates the construction and use of a user path. It defines a path and paints its interior with the current color. Example 4.2 { ucache % This is optional 100 200 400 500 setbbox % This is required 150 200 moveto 250 200 400 390 400 460 curveto 400 480 350 500 250 500 curveto 100 400 lineto closepath } ufill The tokens enclosed in { and } constitute a user path definition. ucache must appear first if it is used. The setbbox operator, with its four numeric operands (integers or reals), must appear after the optional ucache . The remainder of the user path consists of path construction operators and their operands in any sensible order. The path is assumed to begin empty, so the first operator after the must be an abso- setbbox lute positioning operator ( , arc , or arcn ). moveto ufill is a combined path construction and painting operator. It inter- prets the user path as if it were an ordinary PostScript language proce- dure being executed with systemdict as the current dictionary; it then performs a fill . Moreover, it automatically performs a newpath prior to interpreting the user path and it encloses the entire operation with grestore . The overall effect of the preceding example is to gsave and 164 Chapter 4: Graphics

173 PLRM 2nd Edition Graphics January 26, 1994 define a path and to paint its interior with the current color. It leaves no side effects in the graphics state or anywhere else, except in raster memory. The user path painting operators can be fully described in terms of other path construction and painting operators. The combined opera- tors offer several advantages in efficiency and convenience: • They closely match the needs of many application programs. • A user path consists of path construction operators and numeric operands, not arbitrary computations. The user path is self-con- tained; its semantics are guaranteed not to depend on an unpredict- able execution environment. Also, the information provided by setbbox assures that the coordinates of the path will be within pre- dictable bounds. As a result, interpretation of a user path may be much more efficient than execution of an arbitrary PostScript lan- guage procedure. • Most of the user path painting operators have no effect on the graphics state. The absence of side effects is a significant reason for the efficiency of the operations. There is no need to build up an explicit current path only to discard it after one use. Although the behavior of the operators can be described as if the path were built up, painted, and discarded in the usual way, the actual implementa- tion of the operators is optimized to avoid unnecessary work. • Because a user path is represented as a procedure object and is self- contained, the PostScript interpreter can save its output in a cache. This eliminates redundant interpretation of a path that is used repeatedly. 4.6.1 User Path Construction A user path is an array or packed array object consisting of a sequence of the following operators and their operands: ucache ll ll setbbox ur ur y x x y moveto xy dx dy rmoveto x y lineto dx dy rlineto x x curveto y y x y 2 2 3 1 3 1 rcurveto dy dx dx dy dy dx 2 1 2 1 3 3 4.6 User Paths 165

174 PLRM 2nd Edition Graphics January 26, 1994 x y r ang ang arc 1 2 x y r ang ang arcn 1 2 arct x r y y x 2 1 1 2 closepath The permitted operators are all the standard PostScript operators that append to the current path, with the exception of and charpath , arcto which are not allowed. There are two special user path construction . operators, ucache and setbbox Note arcto is not allowed because it would push results onto the operand stack. arct is the same as arcto , except for this effect. charpath is not allowed because the resulting user path would not be self-contained, but would depend on the current font. The permitted operands are literal numbers: integers and reals. The cor- rect number of operands must be supplied to each operator. The user path must be structured as follows (any deviation from these rules will result in a typecheck error when the user path is interpreted): 1. The optional ucache places the user path in a special cache. It speeds ucache is up execution for paths that a program uses frequently. If present, it must come first. See section 4.6.3, “User Path Cache.” 2. Next must be a setbbox , which establishes a bounding box in user space enclosing the entire path. 3. The remainder of the user path must be path construction operators and their operands. All coordinates must fall within the bounds . If they don’t, a setbbox rangecheck specified by error will occur when the user path is interpreted. The path construction operators in a user path may appear either as executable name objects, such as moveto , or as operator objects, such as the value of moveto in systemdict . An application program construct- ing a user path specifies name objects. However, the program might happen to apply bind to the user path or to a procedure containing it, causing the names to be replaced by the operator objects. No advantage is gained by binding a user path. The user path painting operators interpret a user path as if systemdict ). The path were the current dictionary (see the definition of uappend construction operators contained in the user path are guaranteed to have their standard meanings. 166 Chapter 4: Graphics

175 PLRM 2nd Edition January 26, 1994 Graphics Note It is illegal for a user path to contain names other than the standard path construction operator names. Aliases are prohibited to ensure that the user path definition is self-contained and its meaning entirely independent of its execution environment. 4.6.2 Encoded User Paths An encoded user path is a very compact representation of a user path. It is an array consisting of two string objects, or an array and a string. The strings effectively encode the operands and operators of an equivalent user path procedure, using a compact binary encoding. The encoded user path representation is accepted and understood by the user path painting operators, such as ufill . Those operators interpret the data structure and perform the encoded operations. It does not make sense to think of “executing” the encoded user path directly. Note Operator encoding is specialized to user path definitions; it has nothing to do with the alternative external encodings of the PostScript language, which are described in section 3.12, “Binary Encoding Details.” The elements of an encoded user path are: •A data string or data array containing numeric operands. operator string •An containing encoded operators. This two-part organization is for the convenience of application pro- grams that generate encoded user paths. In particular, operands always fall on natural addressing boundaries. All the characters in both strings are interpreted as binary numbers, not as ASCII character codes. If the first element is a string, it is interpreted as an encoded number string, whose representation is described in section 3.12.5, “Encoded Number Strings.” If it is an array, its elements are simply used in sequence. All elements must be numbers. The operator string is interpreted as a sequence of encoded path con- struction operators, one operation code (opcode) per character. Table 4.3 shows the allowed opcode values. 4.6 User Paths 167

176 PLRM 2nd Edition Graphics January 26, 1994 Opcodes for encoded user paths Table 4.3 Opcode Operator Operator Opcode 0 setbbox 6 rcurveto 1 moveto 7 arc 2 8 arcn rmoveto 3 lineto 9 arct 4 rlineto 10 closepath 5 curveto 11 ucache 255 repetition count: repeat ≤ 32 < n next code n 32 times. − Associated with each opcode in the operator string are zero or more operands in the data string or data array. The order of the operands is lineto the same as in an ordinary user path. For example, execution of a x operand and a (opcode 3) consumes an operand from the data y sequence. Note If the encoded user path does not conform to the rules described above, a typecheck error will occur when the path is interpreted. Possible errors include invalid opcodes in the operator string or premature end of the data sequence. Example 4.3 shows an encoded version of the user path from Example 4.2 on page 164. It specifies its operand list as an ordinary data array encoded in ASCII. Example 4.4 shows the same user path with the oper- ands given as an encoded number string. Example 4.3 { {100 200 400 500 150 200 250 200 400 390 400 460 400 480 350 500 250 500 100 400 } <0B 00 01 22 05 03 0A> } ufill Example 4.4 { <95200014 0064 00C8 0190 01F4 0096 00C8 168 Chapter 4: Graphics

177 PLRM 2nd Edition Graphics January 26, 1994 00FA 00C8 0190 0186 0190 01CC 0190 01E0 015E 01F4 00FA 01F4 0064 0190> <0B 00 01 22 05 03 0A> } ufill The second example illustrates how encoded user paths are likely to be used. Although it does not appear to be more compact than the first example in its ASCII representation, it occupies less space in VM and executes considerably faster. The example shows the operand as a hexa- decimal literal string for clarity of exposition. An ASCII base-85 string literal or a binary string token would be more compact. 4.6.3 User Path Cache Some applications define paths that must be redisplayed frequently or that are repeated many times. To optimize interpretation of such paths, the PostScript language provides a facility called the user path cache . This cache, analogous to the font cache, retains the results from having interpreted the user path definitions. When the PostScript interpreter encounters a user path that is already in the cache, it substitutes the cached results instead of reinterpreting the path definition. There is a non-trivial cost associated with placing a user path in the cache: Extra computation is required and existing paths may be dis- placed from the cache. Because most user paths are used once and immediately thrown away, it does not make sense to place every user path in the cache. Instead, the application program must explicitly identify the user paths that are to be cached. It does so by including the ucache operator as the first element of the user path definition before setbbox sequence, as shown in Example 4.5. the Example 4.5 /Circle1 {ucache –1–1 1 1 setbbox 0 0 1 0 360 arc} cvlit def Circle1 ufill The operator notifies the PostScript interpreter that the enclos- ucache ing user path should be placed in the cache if it is not already there, or obtained from the cache if it is. This cache management is not per- formed directly by ucache ; instead, it is performed by the painting operator applied to the user path ( ufill in this example). This is because the results retained in the cache differ according to what painting oper- ation is performed. User path painting operators produce the same effects on the current page whether or not the cache is accessed. 4.6 User Paths 169

178 PLRM 2nd Edition Graphics January 26, 1994 Note Invoking ucache outside a user path has no effect. Caching is based on the value of a user path object. That is, two user paths are considered the same for caching purposes if all elements of one are equal to the corresponding elements of the other, even if the objects themselves are not equal . A user path placed in the cache need not be explicitly retained in VM. An equivalent user path appearing literally later in the program can take advantage of the cached information. Of course, if it is known that a given user path will be used many times, defining it explicitly in VM avoids creating it multiple times. User path caching, like font caching, is effective across translations of the user coordinate system, but not across other transformations, such as scaling or rotation. In other words, multiple instances of a given user path painted at different places on the page take advantage of the user path cache when the CTM has been altered only by translate . If the CTM has been altered by scale or rotate , the instances will be treated as if they were described by different user paths. Two other features of Example 4.5 are important to note: • The user path object is explicitly saved for later use (as the value of in this example). This is done in anticipation of painting the Circle1 same path multiple times. • The operator is applied to the user path object to remove its exe- cvlit cutable attribute. This ensures that the subsequent reference to Circle1 pushes the object on the operand stack rather than inappro- priately executing it as a procedure. It is unnecessary to do this if the user path is to be consumed immediately by a user path painting operator, not saved for later use. Note It is necessary to build the user path as an executable array with { and } rather than as a literal array with and [ ] so that the user path construction operators are not executed while building the array. Executable arrays have deferred execution. 4.6.4 User Path Operators There are three categories of user path operators: • User path painting operators, combining interpretation of a user , fill or stroke )—for example, ufill path with a painting operation ( ustroke . ueofill , 170 Chapter 4: Graphics

179 PLRM 2nd Edition Graphics January 26, 1994 • Some of the insideness testing operators. See section 4.5.3, “Inside- ness Testing.” • Miscellaneous operators that involve user paths—for example, uappend , upath , ustrokepath. operand of any of those operators is one of the following: The userpath • an array, which need not be executable, whose Ordinary user path: length is at least 5. • Encoded user path: an array of two elements. The first element is either an array whose elements are all numbers or a string that can be interpreted as an encoded number string. See section 3.12.5, “Encoded Number Strings.” The second element is a string that encodes a sequence of operators, as described in Table 4.3 on page 168. In either case, the value of the object must conform to the rules for con- structing user paths, as detailed in preceding sections. That is, the oper- ands and operators must appear in the correct sequence. If the user path is malformed, a error occurs. typecheck Several of the operators take an optional matrix as their top-most oper- and. This is a six-element array of numbers that describe a transforma- tion matrix. A matrix is distinguished from a user path, which is also an array, by the number and types of its elements. There is no user path clipping operator. Because the whole purpose of the clipping operation is to alter the current clipping path, there is no way to avoid building the path. The best way to clip with a user path is newpath userpath uappend clip newpath This operation can still take advantage of information in the user path cache under favorable conditions. Note uappend operator and the user path painting operators perform a The temporary adjustment to the current transformation matrix as part of their execution. This adjustment consists of rounding the t and t components of y x the CTM to the nearest integer values. This ensures that scan conversion of the user path produces uniform results when it is placed at different positions on the page through translation. This is especially important if the user path is cached. This adjustment is not ordinarily visible to a PostScript language program and is not mentioned in the descriptions of the individual operators. 4.6 User Paths 171

180 PLRM 2nd Edition January 26, 1994 Graphics Rectangles 4.6.5 Rectangles are used very frequently, so it is useful to have a few opera- tors to paint rectangles directly. This is a convenience to application programs. Also, knowing that the figure will be a rectangle results in significantly optimized execution. The rectangle operators are similar to the user path operators in that they combine path construction with painting. However, their operands are in a considerably simpler form. A rectangle is defined in the user coordinate system, just as if it were constructed as an ordinary path. The Level 2 rectangle operators rectfill , , and rectclip accept three different forms of operands: rectstroke • Four numbers: , y , width , and height , which describe a single rectan- x gle. The rectangle’s sides are parallel to the user space axes. It has cor- ners located at coordinates ( x, y ), ( x + width, y ), ( x + width, y + height ), can be negative. height and (x, y + height ). Note that width and • An arbitrarily long sequence of numbers represented as an array. • An arbitrarily long sequence of numbers represented as an encoded number string, described in section 3.12.5, “Encoded Number Strings.” The sequence in the latter two operand forms must contain a multiple of four numbers. Each group of four consecutive numbers is interpreted x , y , width , and height values defining a single rectangle. The as the effect produced is equivalent to specifying all the rectangles as separate subpaths of a single combined path that is then operated on by a single fill , stroke , or clip operator. The PostScript interpreter draws all rectangles in a counterclockwise direction in user space, regardless of the signs of the width and height operands. This ensures that when multiple rectangles overlap, all of their interiors are treated as “inside” the path according to the non-zero winding number rule. 4.7 Forms is a self-contained description of any arbitrary graphics, text, or A form sampled images that are to be painted multiple times—on each of sev- eral pages or several times at different locations on a single page. The 172 Chapter 4: Graphics

181 PLRM 2nd Edition January 26, 1994 Graphics appearance of a form is described by a PostScript language procedure that executes graphical operators. Language support for forms is a Level 2 feature. What distinguishes a form from an ordinary procedure is that it is self- contained and behaves according to certain rules. By defining a form, a program declares that each execution of the form will produce the same output. The output depends only on the graphics state at the time the form is executed. The form’s definition does not refer to variable infor- mation in dictionaries or elsewhere in VM, and its execution has no side effects in VM. These rules permit the PostScript interpreter to save the graphical out- put of the form in a cache. Later, when the same form is used again, the interpreter substitutes the saved output instead of re-executing the form’s definition. This can significantly improve performance when the form is used many times. There are various uses for forms: • As suggested by its name, a form can serve as the template for an entire page. For example, a program that prints filled-in tax forms can first paint the fixed template as a form, then paint the variable information on top of it. • A form can also be any graphic element that is to be used repeatedly. For example, in output from computer-aided design systems, it is common for certain standard components to appear many times. A company’s logo can be treated as a form. 4.7.1 Using Forms Two steps are required to use forms: 1. Describe the appearance of the form . This is done by creating a diction- form dictionary ary, called a , that contains information about the PaintProc , a Post- form. A crucial element of the dictionary is the Script language procedure that can be executed to paint the form. 2. Invoke the form . This is accomplished simply by executing the execform operator with the form dictionary as the operand. Before doing so, a program should set appropriate parameters in the graph- ics state; in particular, it should alter the CTM to control the posi- tion, size, and orientation of the form in user space. 4.7 Forms 173

182 PLRM 2nd Edition Graphics January 26, 1994 Table 4.4 lists the entries in a form dictionary. Table 4.4 Entries in a form dictionary Key Type Semantics FormType integer ( Required ) Must be 1. XUID array ( Optional ) An extended unique ID that uniquely identifies the form; see section 5.8.2, “Extended Unique ID Numbers.” Presence of an XUID in a form dictionary enables the PostScript interpreter to save cached output from the form for later use, even when the form dictionary is loaded into VM multiple times (by differ- values must be assigned XUID ent jobs, for instance). To ensure correct behavior, from a central registry. This is particularly appropriate for forms treated as named resources. Forms that are created dynamically by an application program not contain XUID entries. should BBox array ( Required ) Array of four numbers in the form coordinate system giving lower-left of the form’s bounding box. This x , lower-left y , upper-right x , and upper-right y bounding box is used to clip the output of the form and to determine its size for caching. Matrix matrix ) A transformation matrix that maps from the form’s coordinate space ( Required PaintProc into user space. This matrix is concatenated with the CTM before the is called. procedure ( Required ) A PostScript language procedure for painting the form (see below). PaintProc any Added by execform . This entry contains data used by the implementation to Implementation support form caching. The type and value of this entry are implementation dependent. The form dictionary can contain other constant information that is required by the PaintProc . The form is defined in its own coordinate system, the form coordinate system Matrix with the CTM each , which is defined by concatenating time execform is executed. The BBox parameter is interpreted in the form coordinate system; the PaintProc is executed in that coordinate system. The execform operator first checks if the form dictionary has previously been used as an operand to execform . If not, it verifies that the diction- ary contains the required elements and it makes the dictionary read- or only. It then paints the form, either by invoking the form’s PaintProc by substituting cached output produced by a previous execution of the same form. 174 Chapter 4: Graphics

183 PLRM 2nd Edition Graphics January 26, 1994 execform needs to execute the form definition, it: Whenever 1. Executes . gsave 2. Concatenates the Matrix entry with the CTM. 3. Clips according to the BBox entry. 4. Executes newpath . 5. Pushes the form dictionary on the operand stack. 6. Executes the form’s PaintProc . 7. Executes grestore . is expected to consume its dictionary operand and to use PaintProc The the information at hand to paint the form. It must obey certain guide- lines to avoid disrupting the environment in which it is invoked. • It should not execute any of the operators that are unsuitable for use in encapsulated PostScript files; these are listed in Appendix I. • It should not execute showpage , copypage , or any device setup operator. • Except for removing its dictionary operand, it should leave the stacks unchanged. • It should have no side effects beyond painting the form. It should not alter objects in VM or anywhere else. Due to the effects of cach- ing, the is called at unpredictable times and in unpredict- PaintProc able environments. It should depend only on information in the form dictionary and should produce the same effect every time it is called. Form caching is most effective when the graphics state does not change between successive executions of execform with a given form. Changes to the translation components of the CTM usually do not influence caching behavior. Other changes may require the interpreter to re- . PaintProc execute the 4.7 Forms 175

184 PLRM 2nd Edition Graphics January 26, 1994 4.8 Color Spaces The PostScript language includes powerful facilities for describing the colors of graphical objects to be marked on the current page. The color facilities are divided into two parts: • Color specification . A PostScript language program can specify abstract colors in a device-independent way. Colors can be described in any . Some color spaces are of a variety of color systems or color spaces related to device color representation (gray scale, RGB, and CMYK); others are related to human visual perception (CIE based). Certain special features are also modelled as color spaces: patterns, separa- tions, and color mapping. • Color rendering . The PostScript interpreter reproduces colors on the raster output device by a multi-step process that includes color con- versions, gamma correction, halftoning, and scan conversion. Cer- tain aspects of this process are under PostScript language control. However, unlike the facilities for color specification, the color ren- dering facilities are device dependent and ordinarily should not be accessed from a page description. This section introduces the color specification facilities and describes how they work. It covers everything that most PostScript language pro- grams need to specify colors. Chapter 6 describes the facilities to con- trol color rendering; a program should use those facilities only to configure new output devices or to achieve special device-dependent effects. Figure 4.5 and Figure 4.6 on pages 178 and 179 illustrate the organiza- tion of the major language features for dealing with color. They show the division between color specification (device independent) and color rendering (device dependent). Figure 4.5 Figure 4.6 4.8.1 Types of Color Spaces As described in section 4.5, “Painting,” marks placed on the page by operators such as fill and stroke have a color that is determined by the current color parameter of the graphics state. A color value consists of one or more color components , which are usually numbers. For example, a gray value can be specified by a single number, ranging from 0 (black) to 1 (white). A full color value can be specified in any of several ways. A common method uses three numbers to specify red, green, and blue components. 176 Chapter 4: Graphics

185 PLRM 2nd Edition Graphics January 26, 1994 current color In Level 2, color values are interpreted according to the space , which is another parameter of the graphics state. A PostScript language program first selects a color space by executing the setcolorspace operator. It then selects color values in that color space by executing the setcolor operator. Also, there are convenience opera- — tors— setgray , setrgbcolor , sethsbcolor , setcmykcolor , and setpattern that select both a color space and a color value in a single step. In Level 1, this distinction between color spaces and color values is not explicit, and the set of color spaces is limited. Colors can be specified , only by setgray is also setrgbcolor , and sethsbcolor ( setcmykcolor available in some implementations). However, in the color spaces that are supported, the semantics of the color values are consistent between Level 1 and Level 2. image and colorimage operators, introduced in section 4.10, The “Images,” enable sampled images to be painted on the current page. Each sample of an image is a color value consisting of one or more com- ponents that are to be interpreted in some color space. Since the color values come from the image itself, the current color in the graphics state is not used. Regardless of whether color values originate from the graphics state or from a sampled image, all later stages of color processing treat them the same way. The following sections describe the semantics of color values that are specified as operands to the setcolor operator, but the same semantics apply to color values originating as image samples. There are three categories of color spaces: collectively refer to several methods for directly Device color spaces • specifying colors or gray levels that the output device is to produce. These methods include RGB (red-green-blue), HSB (hue-saturation- brightness), and CMYK (cyan-magenta-yellow-black). CIE (the • Commission Internationale de l’Éclairage ) has created an inter- national standard for color specification. Colors can be specified in the CIE-based color spaces in a way that is independent of the char- acteristics of any particular output device. add special semantics to an underlying color • Special color spaces space. They include facilities for patterns, color mapping, and sepa- rations. 4.8 Color Spaces 177

186 PLRM 2nd Edition Graphics January 26, 1994 Figure 4.5 Color specification Sources of Color spaces Color values color values A,B,C CIEBasedABC CIE Conversion setcolor X,Y,Z based to internal image color X, Y, Z A spaces values CIEBasedA setcolor image R,G,B R,G,B DeviceRGB setcolor setrgbcolor image colorimage H,S,B HSB to RGB conversion Device sethsbcolor color C,M,Y,K C,M,Y,K spaces DeviceCMYK setcolor setcmykcolor image colorimage Gray Gray DeviceGray setcolor setgray image Alternative Another color color space transform Tint Separation setcolor image Another Special Index Table Indexed color space color lookup setcolor spaces image Another color space Pattern setcolor Pattern dictionary Chapter 4: Graphics 178

187 PLRM 2nd Edition January 26, 1994 Graphics Figure 4.6 Color rendering Device color R,G,B Color values C,M,Y,K Rendering (depending on Dictionary contents of rendering Gray X,Y,Z dictionary) setcolorrendering To appropriate device color space R,G,B R,G,B device Conversion between Device C,M,Y,K Color C,M,Y,K Spaces Transfer device Halftones Functions (per (per component) component) Gray monochrome device setundercolorremoval setblackgeneration Tint monochrome device separation sethalftone sethalftone settransfer setscreen setcolorscreen setcolortransfer 4.8 Color Spaces 179

188 PLRM 2nd Edition Graphics January 26, 1994 spec- Regardless of which method a PostScript language program uses to a color (device, CIE-based, or special color space), rendering that color ify on a particular device is under separate control. Rendering is described in Chapter 6. The following operators control color space and color value selection: • setcolorspace sets the color space parameter in the graphics state. Its operand is an array object. The first element of the array is a name object that identifies the color space; the remaining elements, if any, are parameters that further describe the color space as a whole. The standard color space names are: DeviceGray Pattern CIEBasedABC DeviceRGB CIEBasedA Indexed DeviceCMYK Separation The number and types of the parameters vary according to the color space name. For color spaces that do not require parameters, the operand to setcolorspace can be the color space name instead of an array. currentcolorspace returns the current color space parameter (always as an array). setcolor sets the current color parameter in the graphics state to a • value that is interpreted according to the current color space. setcolor requires one or more operands, depending on the color space; each operand specifies one component of the color value. currentcolor returns the current color parameter. setgray , setrgbcolor , • , setcmykcolor , and setpattern set sethsbcolor the color space implicitly and the current color value as specified by the operands. , currentrgbcolor , currenthsbcolor , and currentgray currentcmykcolor return the current color according to an implicit color space. They perform conversions in certain limited cases if the current color space differs from the implicit one. The setcolorspace and setcolor operators sometimes install composite objects, such as arrays or dictionaries, as parameters in the graphics state. To ensure predictable behavior, a PostScript language program should thereafter treat all such objects as if they were read-only. 180 Chapter 4: Graphics

189 PLRM 2nd Edition Graphics January 26, 1994 In certain circumstances, it is illegal to execute operators that specify colors or other color-related parameters in the graphics state. This restriction occurs when defining graphical figures whose colors are to be specified separately each time they are used. The circumstances are: setcachedevice or • After execution of in the setcachedevice2 BuildChar or BuildGlyph procedure of a font dictionary (see section 5.7, “Type 3 Fonts”). • In the procedure of a pattern whose PaintType is 2 (see sec- PaintProc tion 4.9, “Patterns”). In those circumstances, execution of any of the following operators will cause an undefined error: colorimage setcolortransfer image setgray setblackgeneration sethsbcolor setpattern setcmykcolor setcolor setrgbcolor setcolorrendering setscreen setcolorscreen settransfer setcolorspace setundercolorremoval Note that imagemask is not restricted, because it does not specify col- ors, but rather designates places where the current color is to be painted. 4.8.2 Device Color Spaces The device color spaces enable a page description to specify color values that are related to their representation on an output device. The directly color values map directly—or via simple conversions—to the applica- tion of device colorants, such as quantities of ink or intensities of dis- play phosphors. This enables a PostScript language program to control colors precisely for a particular device, but the results produced may not be consistent between different devices. The device color spaces are as follows: controls the intensities of red, green, and blue light, the • DeviceRGB three primary colors used in displays. Colors in this space can alter- natively be specified as hue, saturation, and brightness values. 4.8 Color Spaces 181

190 PLRM 2nd Edition Graphics January 26, 1994 DeviceCMYK • controls the concentrations of cyan, magenta, yellow, and black inks, the four process colors used in printing. DeviceGray controls the intensity of achromatic light, on a scale • from black to white. Although the notion of explicit color spaces is a Level 2 feature, the operators for specifying colors in the DeviceRGB and DeviceGray color spaces— setrgbcolor , sethsbcolor , and setgray —are supported by Level 1. The operator is also supported by some (but not all) setcmykcolor Level 1 implementations. DeviceRGB Color Space Colors in the DeviceRGB color space can be specified according to two color models, called the red-green-blue (RGB) and hue-saturation-bright- ness (HSB) models. Each of these models can specify any reproducible color by three numeric parameters, but the numbers mean different things in the two models. Example 4.6 shows different ways to select DeviceRGB the color space and a color in that space. Example 4.6 [/DeviceRGB] setcolorspace red green blue setcolor red green blue /DeviceRGB setcolorspace setcolor red green blue setrgbcolor hue saturation brightness sethsbcolor In the RGB model, a color is described as a combination of the three primary colors—red, green, and blue—in particular concentrations. The intensity of each primary color is specified by a number in the range 0 to 1, where 0 indicates no contribution at all and 1 indicates maximum intensity of that color. If all three colors have equal intensity, the perceived result theoretically is a pure gray on the scale from black to white. If the intensities are not all equal, the result is some color that is a function of the relative inten- sities of the primary colors. In the HSB model, a color is described as a combination of three parameters called hue , saturation , and brightness . HSB colors are often illustrated as arranged around a color wheel. The hue parameter specifies the angular position of a color on this wheel: 0 corresponds to pure red, 1/3 to pure green, 2/3 to pure blue, and 1 to red again. Intermediate val- ues correspond to mixtures of the adjacent colors. 182 Chapter 4: Graphics

191 PLRM 2nd Edition Graphics January 26, 1994 • Hue corresponds to the property that is intuitively meant by the term “color.” Common hues have names such as “yellow” or “blue- green.” • Saturation indicates how pure the color is. A saturation of 0 indicates that none of the color’s hue is visible; the result is a shade of gray. A saturation of 1 indicates that the color is pure—consists entirely of the color’s hue. Intermediate values indicate a mixture between a pure hue and white light. • Brightness determines how light the color determined by the hue and saturation will be. A brightness of 0 is always black. A brightness of 1 sets the lightness of the color to the maximum that the hue-sat- uration combination can allow. For example, pure red can never be as light as the brightest white because it is missing two components. Note HSB is not a color space in its own right. It is simply a convention for specifying DeviceRGB color values in a different coordinate system. As shown in Example 4.6, and setcolor select the color setcolorspace space and color value separately; setrgbcolor and sethsbcolor set them in combination. Of these operators, only setrgbcolor and sethsbcolor are supported by Level 1 implementations. For DeviceRGB , setcolorspace sets the three components of the current color to 0. When the current color space is DeviceRGB currentcolor and , both return the current color value as red, green, and blue, currentrgbcolor currenthsbcolor returns the current regardless of how it was specified. color value as hue, saturation, and brightness, converting among color models as necessary. Of these operators, only and currentrgbcolor currenthsbcolor are supported by Level 1 implementations. When the current color space is one of the other device color spaces ( DeviceCMYK or DeviceGray ), currentcolor returns the current color value in that color space. and currenthsbcolor first currentrgbcolor convert the current color value into the DeviceRGB color space. The conversions are described in section 6.2, “Conversions Among Device Color Spaces.” These operators cannot convert from CIE-based or spe- cial color spaces. DeviceCMYK Color Space Colors are formed either by adding light sources or by subtracting light from an illuminating source. Computer displays and film recorders typ- ically add colors, while printing inks typically subtract colors. These 4.8 Color Spaces 183

192 PLRM 2nd Edition Graphics January 26, 1994 two methods for forming colors give rise to two major complementary color specifications: the additive RGB specification and the subtractive DeviceCMYK color space allows specifying col- CMYK specification. The ors according to the CMYK model. A color component in a color value specifies the amount DeviceCMYK of light that component absorbs . In theory, each one of three standard printing process colors— cyan , magenta , and yellow —absorbs one of the standard light components— , green , and blue —respectively. Black , a red fourth standard printing process color, absorbs all components of light in equal amounts. In this CMYK color specification, each of the four components is a number between 0 and 1, where 0 represents no ink (that is, absorbs no light) and 1 represents maximum ink (absorbs all the light it can). Note that the sense of these numbers is opposite to that of RGB color components. Example 4.7 shows different ways to select the DeviceCMYK color space and a color in that space. Example 4.7 cyan magenta yellow black setcolor [/DeviceCMYK] setcolorspace /DeviceCMYK setcolorspace setcolor cyan magenta yellow black cyan magenta yellow black setcmykcolor setcolorspace and setcolor select the color space and color value sepa- setcmykcolor sets them in combination. For DeviceCMYK , rately; sets the four components of the current color to 0, 0, 0, setcolorspace and 1. currentcolor DeviceCMYK , both and When the current color space is currentcmykcolor return the current color value as cyan, magenta, yel- low, and black. When the current color space is one of the other device color spaces ( DeviceRGB or DeviceGray ), currentcolor returns the cur- rent color value in that color space. currentcmykcolor converts the cur- rent color value into the DeviceCMYK color space; the conversions are described in section 6.2, “Conversions Among Device Color Spaces.” This operator cannot convert from CIE-based or special color spaces. currentcmykcolor setcmykcolor and are supported by some, but not all, Level 1 implementations. 184 Chapter 4: Graphics

193 PLRM 2nd Edition Graphics January 26, 1994 DeviceGray Color Space Black, white, and intermediate shades of gray are special cases of full color. A gray-scale value is described by a single number in the range 0 to 1, where 0 corresponds to black, 1 to white, and intermediate values to different gray levels. Example 4.8 shows different ways to select the DeviceGray color space and a color in that space. Example 4.8 [/DeviceGray] setcolorspace gray setcolor /DeviceGray setcolorspace gray setcolor gray setgray setcolorspace and setcolor select the color space and color value sepa- rately; setgray sets them in combination. For DeviceGray , setcolorspace sets the current color to 0. currentcolor and When the current color space is DeviceGray , both currentgray return the current color value as a single gray component. When the current color space is one of the other device color spaces ( DeviceRGB or DeviceCMYK ), currentcolor returns the current color value in that color space. currentgray converts the current color value into the DeviceGray color space; the conversions are described in sec- tion 6.2, “Conversions Among Device Color Spaces.” This operator can- not convert from CIE-based or special color spaces. and currentgray are supported by all implementations. setgray 4.8.3 CIE-Based Color Spaces CIE-based color is defined relative to an international standard used in the graphic arts, television, and printing industries. It enables a page description to specify color values in a way that is related to human visual perception. The goal of this standard is for a given CIE-based color specification to produce consistent results on different output devices, up to the limitations of each device. The detailed semantics of the CIE colorimetric system and the theory on which it is based are beyond the scope of this manual. The bibliogra- phy lists several books that should be consulted for further informa- tion. 4.8 Color Spaces 185

194 PLRM 2nd Edition January 26, 1994 Graphics The semantics of the CIE-based color spaces are defined in terms of the relationship between the space’s components and the tristimulus values Y , and Z of the CIE 1931 (XYZ)-space. Level 2 implementations of X , the PostScript language support two CIE-based color spaces named CIEBasedABC CIEBasedA . Both CIE-based color spaces are invoked and by [ name dictionary ] setcolorspace where is one of two CIE-based color space names and dictionary is name a dictionary containing parameters that further characterize the color space. The key-value pairs in this dictionary have specific interpreta- tions that vary among the color spaces; some key-value pairs are required and some are optional. Having selected a color space, a PostScript language program can then setcolor operator. Color values in the specify color values using the color space consist of three components; those in the CIEBasedABC CIEBasedA color space consist of a single component. Interpretation of those values depends on the color space and its parameters. To use any of the CIE-based color spaces with the operator requires Note image using the 1-operand (dictionary) form of that operator, which causes to image interpret sample values according to the current color space. See section 4.10.5, “Image Dictionaries.” CIE-based color spaces are available only in Level 2 implementations. They are entirely separate from device color spaces. Operators that refer to device color spaces implicitly, such as setrgbcolor and currentrgbcolor , have no connection with CIE-based color spaces; they do not perform conversions between CIE-based and device color spaces. setrgbcolor changes the color space to DeviceRGB . When the current color space is a CIE-based or special color space, currentrgbcolor returns the initial value of the color space, which has nothing to do DeviceRGB with the current color in the graphics state. CIEBasedABC Color Space The CIEBasedABC color space is defined in terms of a two-stage, non- linear transformation of the CIE 1931 (XYZ)-space. The formulation of the CIEBasedABC color space models a simple zone theory of color vision, consisting of a non-linear trichromatic first stage combined with a non-linear opponent color second stage. This formulation allows col- ors to be digitized with minimum loss of fidelity; this is important in sampled images. 186 Chapter 4: Graphics

195 PLRM 2nd Edition January 26, 1994 Graphics CIEBasedABC include a variety of interesting and useful Special cases of color spaces, such as the CIE 1931 (XYZ)-space, a class of calibrated RGB spaces, and a class of opponent color spaces such as the CIE 1976 (L*a*b*)-space and the NTSC, SECAM, and PAL television spaces. CIEBasedABC Color values in have three components, arbitrarily C named A . They can represent a variety of independent color , B , and components, depending on how the space is parameterized. For exam- , B , and ple, may represent: A C X Y , and Z in the CIE 1931 (XYZ)-space. • , , G , and B in a calibrated RGB space. • R L* • a* , and b* in the CIE 1976 (L*a*b*)-space. , • , I , and Q in the NTSC space. Y Y U , and V in the SECAM and PAL spaces. • , A , B , and C are 0 unless the range of valid values for The initial values of a color component does not include 0, in which case the nearest valid value is substituted. CIEBasedABC The parameters for the color space must be provided in a dictionary that is the second element of the array operand to the operator. Table 4.5 describes the contents of this diction- setcolorspace ary. Table 4.5 Entries in a CIEBasedABC color space dictionary Type Key Semantics RangeABC array ) Array of six numbers [ A ( Optional B A C B C ] that specify the range of valid 1 1 1 0 0 0 A , B , and C components of the color space—that is, A values for the ≤ A ≤ A 0 1 , C ≤ ≤ B B , and B ≤ C ≤ C . Default value: [0 1 0 1 0 1]. 0 0 1 1 DecodeABC array Optional ) Array of three PostScript language procedures [ D ( D ] that decode D A B C the A , B , and C components of the color space into values that are linear with respect to an intermediate LMN representation; this is explained below. Default value: the array of identity procedures [{} {} {}]. Each of these procedures is called with an encoded A , B , or C component on the operand stack and must return the corresponding decoded value. The result must be a monotonic function of the operand. Because these procedures are called at unpredictable times and in unpredictable environments, they must operate as pure functions without side effects. 4.8 Color Spaces 187

196 PLRM 2nd Edition Graphics January 26, 1994 ( array L Optional M MatrixABC N ] that specify the L N M M N ) Array of nine numbers [ L B C C B C A A A B B , and C components of the color space A linear interpretation of the decoded , with respect to the intermediate LMN representation. Default value: the identity matrix [1 0 0 0 1 0 0 0 1]. DecodeABC MatrixABC entries is: The transformation defined by the and LD B L () C = D × ++ L () × A D × () L A B A C C B × M D B () M × D C () M × ++ = A () MD A A B B C C D ++ C () N D × × B N () () N = × A ND B A A C C B components of the color space are first decoded C , and In other words, the B , A DecodeABC procedures. The results are treated as a three ele- individually by the (a three by three matrix) to provide MatrixABC ment vector and multiplied by N the L , components of the intermediate LMN representation. M , and L RangeLMN array ( Optional ) Array of six numbers [ L N N M M ] that specify the range of 0 1 1 0 1 0 valid values for the , M , and L N components of the intermediate LMN ≤ N ≤ N N ≤ . Default representation—that is, L , and ≤ L ≤ L M ≤ M , M 0 0 0 1 1 1 value: [0 1 0 1 0 1]. DecodeLMN array D ( ) Array of three PostScript language procedures [ Optional D D ] that decode M L N L , M , and N components of the intermediate LMN representation into values the that are linear with respect to the CIE 1931 (XYZ)-space. This is explained below. Default value: the array of identity procedures [{} {} {}]. N L , M , or Each of these procedures is called with an encoded component on the operand stack and must return the corresponding decoded value. The result must be a monotonic function of the operand. Because these procedures are called at unpredictable times and in unpredictable environments, they must operate as pure functions without side effects. MatrixLMN array X ) Array of nine numbers [ Optional ( Y ] that specify the Y Z X Y Z X Z M N M N L M L N L linear interpretation of the decoded L , M , and N components of the intermediate LMN representation with respect to the CIE 1931 (XYZ)-space. Default value: the identity matrix [1 0 0 0 1 0 0 0 1]. and MatrixLMN entries is: The transformation defined by the DecodeLMN XD = ++ × X () N D × X () M D × X () L M N N M L L D = D ++ M L () Y × Y × Y () () N × YD N L N M L M Z () L = ++ × Z () N D × Z () M D × ZD N N M M L L X WhitePoint array ( Required ) Array of three numbers [ Z ] that specify the CIE 1931 (XYZ)- Y W W W space tristimulus value of the diffuse white point. This is explained below. The numbers X must be positive and and Z must be equal to 1. Y W W W array ( Optional ) Array of three numbers [ BlackPoint X ] that specify the CIE 1931 (XYZ)- Y Z B B B space tristimulus value of the diffuse black point. These numbers must be non- negative. Default value: [0 0 0]. 188 Chapter 4: Graphics

197 PLRM 2nd Edition Graphics January 26, 1994 The WhitePoint and BlackPoint entries control the overall effect of the CIE-based gamut mapping function described in section 6.1, “CIE- Based Color to Device Color.” Typically, the colors specified by WhitePoint and BlackPoint are mapped nearly to the lightest and the darkest achromatic colors that the output device is capable of rendering in a way that preserves color appearance and visual contrast. is assumed to represent the diffuse, achromatic highlight, WhitePoint and not a specular highlight. Specular highlights, achromatic or other- BlackPoint wise, are often reproduced lighter than the diffuse highlight. is assumed to represent the diffuse, achromatic shadow. Its value is typ- ically limited by the dynamic range of the input device. In images pro- duced by a photographic system, the values of WhitePoint and BlackPoint vary with exposure, system response, and artistic intent; hence, their values are image dependent. The following PostScript language program fragments illustrate various interesting and useful special cases of CIEBasedABC . Example 4.9 establishes the CIE 1931 (XYZ)-space with the CCIR XA/11 recommended white point. Example 4.9 [/CIEBasedABC << /RangeABC [0 0.9505 0 1 0 1.0890] /RangeLMN [0 0.9505 0 1 0 1.0890] /WhitePoint [0.9505 1 1.0890] >>] setcolorspace Example 4.10 establishes a calibrated RGB color space with the CCIR XA/11 recommended phosphor set, white point, and opto-electronic transfer function. Example 4.10 [/CIEBasedABC << /DecodeLMN [{1 0.45 div exp} bind dup dup] /MatrixLMN [0.4124 0.2126 0.0193 0.3576 0.7152 0.1192 0.1805 0.0722 0.9505] /WhitePoint [0.9505 1 1.0890] >>] setcolorspace In many cases, the parameters of calibrated RGB color spaces are speci- fied in terms of the CIE 1931 chromaticity coordinates ( x ,y ), ( x ,y ), G R G R ( x ,y ) of the red, green, and blue phosphors, respectively, and the B B chromaticity ( x ) of the diffuse white point corresponding to some y , W W 4.8 Color Spaces 189

198 PLRM 2nd Edition Graphics January 26, 1994 , G , B ), where usually R = G = linear RGB value ( = 1. Note that stan- B R dard CIE notation uses lower-case letters to specify chromaticity coordi- nates and upper-case letters to specify tristimulus values. Given this information, MatrixLMN and WhitePoint can be found as follows: zy × () × = − x × x + − () y × x y x () − () y − x x R R B R B G B G W G x − × + × y y () − x × x x − () y y x () x − R B B W G G W G B W Y = × L R z x 1 x − R R  Y × = X × − Z Y = 1 L L L L y  y R R x x + y × × − × y () − x x y () − x x y () − W B B R G W R R B W Y − × = M G z x x 1 − G G  = Y X × − 1 × = Z Y M M M M y  y G G x − () y y x × x () × − × − y x x x − () y + R R R G G W B W G W Y = × N B z x − x 1 B B  = Y X × × = Z − 1 Y N N N N y  y B B × × = + × BX GX X + RX N M W L Y = × + × + × GY RY BY W L N M Z BZ GZ + RZ = × × × + N M W L Example 4.11 establishes the CIE 1976 (L*a*b*)-space with the CCIR and XA/11 recommended white point. The b* a* components, although theoretically unbounded, are defined to lie in the useful range b* − 128 to +127. The transformation from L* , a* , and component val- is defined as: X , and ues to CIE 1931 (XYZ)-space tristimulus values Y Z , * L *16 + a () = g × + XX W 500 116 + *16 L g = × () YY W 116 * *16 + L b = () − × ZZ g W 116 200 Chapter 4: Graphics 190

199 PLRM 2nd Edition January 26, 1994 Graphics where the function g( ) is defined as: x 6 3 () x gx = ≥ x if 29 108 4 otherwise = () x gx − () × 841 29 Example 4.11 [/CIEBasedABC << 128 127 128 127] − /RangeABC [0 100 − /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] 1] /MatrixABC [1 1 1 1 0 0 0 0 − /DecodeLMN [{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.9505 mul} bind {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse} bind {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 1.0890 mul} bind] /WhitePoint [0.9505 1 1.0890] >>] setcolorspace CIEBasedA Color Space The color space is the one-dimensional and usually achro- CIEBasedA matic analog of CIEBasedABC . Color values in CIEBasedA have a single component, arbitrarily named A . It can represent a variety of color components, depending on how the space is parameterized. For exam- may represent: ple, A • The luminance Y component of the CIE 1931 (XYZ)-space. • The gray component of a calibrated gray space. L* component of the CIE 1976 • The CIE 1976 psychometric lightness (L*a*b*)-space. • The luminance Y component of the NTSC, SECAM, and PAL televi- sion spaces. is 0 unless the range of valid values does not The initial value of A include 0, in which case the nearest valid value is substituted. 191 4.8 Color Spaces

200 PLRM 2nd Edition January 26, 1994 Graphics CIEBasedA The parameters for the color space must be provided in a dictionary that is the second element of the array operand to the operator. Table 4.6 describes the contents of this diction- setcolorspace ary. CIEBasedA Table 4.6 color space dictionary Entries in a Key Type Semantics RangeA ) Array of two numbers [ A array ( Optional ] that specify the range of valid values for A 0 1 . Default value: [0 1]. component of the color space—that is, A ≤ A ≤ A A the 1 0 DecodeA procedure ( Optional ) PostScript language procedure D that decodes the A component of A the color space into a value that is linear with respect to an intermediate LMN representation. See DecodeABC in Table 4.5. Default value: the identity proce- dure {}. array Optional ) Array of three numbers [ L MatrixA ( ] that specify the linear interpreta- M N A A A tion of the decoded A component of the color space with respect to the interme- diate LMN representation. Default value: the matrix [1 1 1]. The transformation defined by the and MatrixA entries is: DecodeA = A () L × LD A A () = × M A MD A A × () A N = ND A A See MatrixABC in Table 4.5. L ) Array of six numbers [ RangeLMN Optional array ( N N M M L ] that specify the range of 1 0 1 0 1 0 components of the intermediate LMN valid values for the , , and L N M N ≤ . Default L representation—that is, , M L ≤ M ≤ M N , and ≤ L ≤ N ≤ 1 1 0 0 0 1 value: [0 1 0 1 0 1]. D ) Array of three PostScript language procedures [ array DecodeLMN Optional ( ] that decode D D L M N , L the M N components of the intermediate LMN representation into values , and in DecodeLMN that are linear with respect to the CIE 1931 (XYZ)-space. See Table 4.5. ) Array of nine numbers [ X Optional ( array MatrixLMN Y Y Z Z ] that specify the Y X X Z L L M M M N N N L linear interpretation of the decoded L , M , and N components of the intermediate LMN representation with respect to the CIE 1931 (XYZ)-space. See MatrixLMN in Table 4.5. ( array X ) Array of three numbers [ WhitePoint Required Y Z ] that specify the CIE 1931 (XYZ)- W W W space tristimulus value of the diffuse white point. See in Table 4.5. WhitePoint Optional BlackPoint array X ) Array of three numbers [ ( ] that specify the CIE 1931 (XYZ)- Y Z B B B in Table 4.5. space tristimulus value of the diffuse black point. See BlackPoint Chapter 4: Graphics 192

201 PLRM 2nd Edition January 26, 1994 Graphics The following PostScript language program fragments illustrate various interesting and useful special cases of CIEBasedA . dimension of the Example 4.12 establishes a space consisting of the Y CIE 1931 (XYZ)-space with the CCIR XA/11 recommended white point. Example 4.12 [/CIEBasedA << /MatrixA [0.9505 1 1.0890] /RangeLMN [0 0.9505 0 1 0 1.0890] /WhitePoint [0.9505 1 1.0890] >>] setcolorspace Example 4.13 establishes a calibrated gray space with the CCIR XA/11 recommended white point and opto-electronic transfer function. Example 4.13 [/CIEBasedA << /DecodeA {1 0.45 div exp} bind /MatrixA [0.9505 1 1.0890] /RangeLMN [0 0.9505 0 1 0 1.0890] /WhitePoint [0.9505 1 1.0890] >>] setcolorspace Example 4.14 establishes a space consisting of the L* dimension of the CIE 1976 (L*a*b*)-space with the CCIR XA/11 recommended white point. Example 4.14 [/CIEBasedA << /RangeA [0 100] /DecodeA {16 add 116 div dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse} bind /MatrixA [0.9505 1 1.0890] /RangeLMN [0 0.9505 0 1 0 1.0890] /WhitePoint [0.9505 1 1.0890] >>] setcolorspace 4.8 Color Spaces 193

202 PLRM 2nd Edition Graphics January 26, 1994 Special Color Spaces 4.8.4 Special color spaces add special semantics to an underlying color space. Pattern , Indexed , and Separation . There are three special color spaces: All of the special color spaces are Level 2 features. Pattern Color Space The Pattern color space enables painting with a “color” defined as a pattern , a graphical figure used repeatedly to cover the areas that are to be painted. Section 4.9, “Patterns,” describes how patterns are defined and used. Indexed Color Space The Indexed color space provides a color map or color table that allows a PostScript language program to use small integers to select from a table Indexed color of arbitrary colors in some other color space. With the space, a program can, for example, use image samples that are 8-bit index values rather than 24-bit RGB color values. For each sample, the PostScript interpreter uses the sample value to index into the color table and uses the color value it finds there. This technique can reduce con- siderably the amount of data required to represent a sampled image. An Indexed color space is installed as follows: [/Indexed base hival lookup ] setcolorspace In other words, the operand to setcolorspace is a four-element array. Indexed ; the remaining ele- The first element is the color space name ments are the parameters , hival , and lookup , which the Indexed base color space requires. setcolorspace sets the current color to 0. The base parameter is an array or name that identifies the base color space . This is the space in which the color values in the table are to be interpreted. It can be any device or CIE-based color space, but not a spe- , or cial color space ( Pattern , Indexed Separation ). For example, if the base color space is , the values in the table are to be inter- DeviceRGB preted as red , green , and blue components. If the base color space is CIEBasedABC , the values are to be interpreted as A , B , and C compo- nents. The base parameter should be constructed just as if it were to be . setcolorspace used as an operand to 194 Chapter 4: Graphics

203 PLRM 2nd Edition Graphics January 26, 1994 hival The parameter is an integer that specifies the maximum valid index value. In other words, the color table is to be indexed by integers hival , inclusive. hival in the range 0 to can be no greater than 4095, which is what would be required to index a table with 12-bit color sam- ple values. The color table is described by the lookup parameter, which can be either a procedure or a string. It provides the mapping between the val- ues of index and the colors in the base color space. If is a procedure, the PostScript interpreter calls it to transform an lookup index value into corresponding color component values in the base color space. The procedure is called with the index on the operand stack and must return the color component values in a form acceptable to the setcolor operator in the base color space. The number of compo- nents and interpretation of the component values depends on the base color space. Since the lookup procedure is called by the setcolor and image operators at unpredictable times, it must operate as a pure func- tion, without side effects. It must be able to return color component , inclusive. hival values for any integer between 0 and If is a string object, it must be of length m × ( hival + 1), where m is lookup the number of color components in the base color space. Each byte in the string is interpreted as an integer. To look up an index , the PostScript interpreter multiplies index by m and uses the result to access the lookup string. The m bytes located starting at that position in the string are interpreted as coded values for the color components of the base m color space. Those bytes are treated as 8-bit integers in the range 0 to 255, which are then divided by 255, yielding component values in the range 0 to 1. Example 4.15 illustrates specification of an Indexed color space that maps 8-bit index values to 3-component color values in the DeviceRGB color space. Example 4.15 [/Indexed /DeviceRGB 255 <000000 FF0000 00FF00 0000FF B57342 ... > ] setcolorspace The example shows only the first five color values in the lookup string; there should be 256 color values and the string should be 768 charac- ters long. Having established this color space, the program can now specify single-component color values in the range 0 to 255. For exam- ple, a color value of 4 selects an RGB color whose components are 4.8 Color Spaces 195

204 PLRM 2nd Edition Graphics January 26, 1994 coded as the hexadecimal integers B5, 73, and 42. Dividing these by 255 yields a color whose red, green, and blue components are .710, .451, and .259, respectively. Note To use the Indexed color space with the image operator requires using the 1-operand (dictionary) form of that operator, which causes image to interpret sample values according to the current color space. See section 4.10.5, “Image Dictionaries.” Although the color space is mainly useful for images, you can Indexed use index values with the setcolor operator. For example, 123 setcolor selects the same color as does an image sample value of 123. An index component should be an integer in the range 0 to hival , inclusive. If index is a real number, it is truncated to an integer. If it is outside the , it is clipped to the nearest bound. range 0 to hival Separation Color Space Color output devices produce full color by combining or process primary colors in varying amounts. In a display, the primaries consist of red, green, and blue phosphors. In a printer, they consist of cyan, magenta, yellow, and sometimes black inks. When the showpage or copypage operator is executed, most devices produce a single composite page on which all primary colors have been combined. However, some devices, such as typesetters, produce a col- lection of pages, one for each primary or process color. These pages are . Each separation is a monochromatic rendition of the separations called page for a single primary color. When the separations are later com- bined—on a printing press, for example—and the proper inks or other colorants are applied to them, a full-color page results. There are situations in which it is desirable to produce additional sepa- rations to control the application of special colorants, often called spot colors . There are many colors and other effects that cannot be achieved by combining the primary colors. Examples include metallic and fluo- rescent colors and special textures. color space provides a means for a PostScript language The Separation program to specify that additional separations are to be produced or special colors are to be applied. Those separations or colors are identi- 196 Chapter 4: Graphics

205 PLRM 2nd Edition Graphics January 26, 1994 fied by name. When the current color space is a particular named separation, the current color is a single-component value, called a , tint that controls application of colorant for that separation only. The effect of using the Separation color space depends on the nature and configuration of the device. Only a few devices, such as typesetters, support the production of arbitrary separations. Some other color print- ing devices support one or more special colorants that are to be applied to the composite page in addition to the primary colorants. In such devices, “separations” are not actually separate pages. Most devices do not support separations at all. The Separation color space provides pre- dictable behavior when a program requests separations that the device can’t produce. A color space is installed as follows: Separation [/Separation name alternativeSpace tintTransform ] setcolorspace In other words, the operand to setcolorspace is a four-element array. The first element is the color space name Separation . The remaining elements are the parameters name , alternativeSpace , and tintTransform , Separation color space requires. which the A color value in a color space consists of a single tint compo- Separation nent in the range 0 to 1. The value 0 represents application of the min- imum amount of colorant to the separation; 1 represents application of the maximum amount. Tints are treated as subtractive colors; this is the same as the convention for DeviceCMYK color components, but oppo- site the one for DeviceRGB and DeviceGray . The setcolor operator sets the current color in the graphics state to a tint value; the initial value is 1. A sampled image with single-component samples can also be treated as a source of tint values. Note To use the Separation color space with the image operator requires using the 1-operand (dictionary) form of that operator, which causes image to interpret sample values according to the current color space. See section 4.10.5, “Image Dictionaries.” The name parameter, a name or string object, specifies the name of the separation or colorant. The names of separations are arbitrary, and there can be an arbitrary number of separations, subject to implementa- tion limits. Name and string objects can be used interchangeably. Some separation names contain spaces or other special characters, so strings may be more convenient. 4.8 Color Spaces 197

206 PLRM 2nd Edition January 26, 1994 Graphics setcolorspace is executed, the device determines if it At the moment ignores the can produce the named separation. If it can, setcolorspace and tintTransform parameters. Subsequent painting oper- alternativeSpace ations apply colorant to the named separation according to the sup- plied tint values, as explained above. If the device cannot produce the named separation, setcolorspace arranges instead for subsequent painting operations to be performed in an alternative color space . This enables the special colors to be approxi- mated by colors in some device or CIE-based color space, which are then rendered using the usual primary or process colors. The way this works is as follows: • The alternativeSpace parameter must be an array or name object that identifies the alternative color space. This can be any device or CIE- based color space, but not a special color space ( , Indexed , or Pattern ). The alternativeSpace parameter should be constructed Separation setcolorspace . just as if it were to be used as an operand to • The tintTransform parameter must be a procedure. During subsequent painting operations, the PostScript interpreter calls this procedure to transform a tint value into color component values in the alternative on the operand stack tint color space. The procedure is called with and must return the color component values in a form acceptable to setcolor operator in the alternative color space. The number of the components and interpretation of the component values depends on the alternative color space. Since the tintTransform procedure is called by the setcolor and image operators at unpredictable times, it must operate as a pure function without side effects. Example 4.16 illustrates specification of a Separation color space that is intended to produce a separation named AdobeGreen . If the device can- AdobeGreen not produce an separation, the program selects DeviceCMYK as the alternative color space, and it provides a tintTransform procedure that maps tint values linearly into shades of a CMYK color value that approximates the “Adobe green” color. Example 4.16 [/Separation (AdobeGreen) /DeviceCMYK {dup .84 mul exch 0 exch dup .44 mul exch .21 mul} ] setcolorspace For convenience, the separation names Cyan , Magenta , Yellow , and Black correspond to the conventional subtractive device’s cyan, Red , magenta, yellow, and black colorants, respectively. The names 198 Chapter 4: Graphics

207 PLRM 2nd Edition January 26, 1994 Graphics , and Blue Green correspond to the conventional additive device’s red, green, and blue primaries, respectively. This enables a program to select one of the device’s primary colors as if it were a separation. Note Tint values are always subtractive, even if the device produces output for the named component by an additive method. The value 0 represents the lightest color; 1 represents the darkest color. refers to all separations that are produced, The separation named All including both process color separations and specific named separa- tions that have been requested previously. When the current color All space is the separation, painting operators apply tint values to all separations instead of to only one. This is useful for purposes such as painting registration marks in the same place on every separation. Ordi- narily, a program should do this as the last step of composing a page, showpage , when the set of separations immediately before executing the device will produce has been completely determined. The separation named will never be produced. If the device is None producing separations, none of them will be marked. In other words, painting on the separation named None does not change the current page. All implementations support the separation named , even if None they do not support any other named separations. The alternativeSpace and tintTransform parameters are ignored, though dummy values must still be provided. The graphics state contains an overprint parameter, controlled by the setoverprint operator. This parameter controls an aspect of color render- ing , not of color specification . However, it applies only when separations are being produced, so it is described here. When the device produces separations, the overprint parameter indi- cates if painting on one separation causes the corresponding areas of other separations—unrelated to the current color space—to be erased. To “erase” an area means to paint it with a tint value of 0. , painting in a false Separation If overprint is color space causes corre- sponding areas of all other separations, including the ones for the pri- mary colors, to be erased. Painting in any other color space, which is rendered onto the primary separations, causes the corresponding areas , these of all non-primary separations to be erased. If overprint is true erasing actions are not performed. Whatever was previously painted on the other separations is left undisturbed. 4.8 Color Spaces 199

208 PLRM 2nd Edition Graphics January 26, 1994 The effect of the overprint parameter becomes apparent when the sepa- rations are combined. If overprint is false , the color at any position on the page is whatever was painted there last. This is consistent with the normal opaque painting model of the PostScript language. If overprint is true , the color at some position may be a function of colors painted by several painting operations on different separations. The effect pro- duced by such “overprinting” is device dependent and is not defined by the PostScript language. The default value of the overprint parameter is . false When the device is not producing separations, the value of the over- print parameter has no effect on the current page. 4.9 Patterns When operators such as fill , stroke , and show paint areas of the page with the current color, they ordinarily apply a single color that covers the areas uniformly. Sometimes it is desirable to apply “paint” that con- sists of a repeating figure instead of a simple color. Such a repeating fig- ure is called a pattern . The ability to paint with patterns is a Level 2 feature. With some effort, it is possible to achieve a limited form of patterns in Level 1 by defining them as characters in a special font and showing them repeatedly. not rec- Another technique—defining patterns as halftone screens—is ommended, because the effect produced is device dependent. “Painting with a pattern” means replicating a small graphical figure (called a pattern cell ) at fixed intervals in x and y to cover the areas to be painted. The effect is as if one were to paint the figure on the surface of a clear glass tile, lay down copies of the tile in an array covering an area to be painted, and trim the tiles’ edges to the boundaries of the area. Laying down copies of a pattern cell to fill an area is called tiling . Patterns are quite general, and there are many uses for them. The appearance of a pattern cell is defined by an arbitrary PostScript lan- guage procedure. It can include graphical elements such as filled areas, text, and sampled images. The shape of a pattern cell need not be rec- tangular, and the spacing of tiles can differ from the size of the pattern cell. Patterns can be used to create various graphical textures, such as weaves, brick walls, and similar geometrical tilings. 200 Chapter 4: Graphics

209 PLRM 2nd Edition January 26, 1994 Graphics Using Patterns 4.9.1 Painting with a pattern is a four-step procedure: . This is done by creating a dictionary, 1. Describe the prototype pattern pattern dictionary , that contains information about the called a , a Post- pattern. A crucial element of the dictionary is the PaintProc Script language procedure that can be executed to paint a single pattern cell. Instantiate the pattern . The makepattern 2. operator copies a prototype pattern dictionary and produces an instance of the pattern that is locked to current user space. In other words, the size of a pattern cell and the phase of the tiling in device space are determined by the makepattern is executed. The pattern is unaffected CTM at the time by subsequent changes to the CTM or to other graphics state parameters. 3. . There is a special color space, Select the pattern as the current color named Pattern , whose color values are pattern dictionaries instead of the numeric color values used with other color spaces. The setcolor and setcolorspace operators set the color space and color value separately; the convenience operator installs a setpattern pattern as the current color in a single step. 4. Invoke painting operators , such as fill , stroke , imagemask , or show . All areas that normally would be painted with a uniform color are instead tiled with the pattern cell. To accomplish this, the PostScript interpreter calls the pattern dictionary’s PaintProc (with the graphics state altered in certain ways) to obtain the pattern cell. It then paints this cell on the current page as many times as necessary. To optimize execution, the interpreter maintains a cache of recently used pattern cells. 4.9.2 Pattern Dictionaries Table 4.7 lists the entries in a pattern dictionary. All entries except Implementation can appear in a prototype pattern dictionary (operand to makepattern ). The pattern dictionary returned by makepattern con- entry as well as the others. Implementation tains an 4.9 Patterns 201

210 PLRM 2nd Edition January 26, 1994 Graphics Entries in a pattern dictionary Table 4.7 Semantics Key Type ( ) Must be 1. integer Required PatternType ( Optional ) An extended unique ID that uniquely identifies the pattern; see section XUID array in a pattern XUID 5.8.2, “Extended Unique ID Numbers.” Presence of an dictionary enables the PostScript interpreter to save cached instances of the pattern cell for later use, even when the pattern dictionary is loaded into VM multiple times—by different jobs, for instance. To ensure correct behavior, XUID values must be assigned from a central registry. This is particularly appropriate for patterns treated as named resources. Patterns that are created dynamically by not contain an application program should entries. XUID PaintType ( Required ) Determines how the color of the pattern cell is to be specified. The integer choices are: 1 . The PaintProc itself specifies the colors used to paint the Colored pattern pattern cell. Uncolored pattern . The PaintProc 2 does not specify any color information. Instead, the entire pattern cell is painted with a separately specified color each time the pattern is used. Essentially, PaintProc describes a stencil through which the current color is to be poured. PaintProc must not execute operators that specify colors or other color-related parameters in error will occur (see section undefined the graphics state; otherwise, an 4.8.1, “Types of Color Spaces”). Use of the imagemask operator is permitted, however, because it does not specify any color information. TilingType integer ( ) Controls adjustments to the tiling to quantize it to the device pixel Required grid. The choices are: 1 Constant spacing . Pattern cells are spaced consistently—that is, by a multiple of a device pixel. To achieve this, makepattern may need to distort the pattern slightly by making small adjustments to , YStep , and the XStep transformation matrix. The amount of distortion does not exceed one device pixel. 2 No distortion . The pattern cell is not distorted, but the spacing between and pattern cells may vary by as much as one device pixel in both x y dimensions when the pattern is painted. This achieves the spacing and YStep on average, but not for individual pattern XStep requested by cells. Constant spacing and faster tiling . Like TilingType 1, but with additional 3 distortion of the pattern cell permitted to enable a more efficient implementation. BBox array ( Required ) An array of four numbers in the pattern cell coordinate system, giving of the pattern cell lower-left x , lower-left y , upper-right x , and upper-right y bounding box. This bounding box is used to clip the pattern cell and to determine its size for caching. 202 Chapter 4: Graphics

211 PLRM 2nd Edition January 26, 1994 Graphics number ( ) The desired horizontal spacing between pattern cells, measured in the XStep Required and may differ from the XStep pattern cell coordinate system. Note that YStep entry. This enables tiling dimensions of the pattern cell implied by the BBox and YStep may be either positive or with irregularly shaped figures. XStep negative, but not zero. number ( Required YStep ) The desired vertical spacing between pattern cells, measured in the pattern cell coordinate system. procedure Required ) A PostScript language procedure for painting the pattern cell (see PaintProc ( below). any This entry is inserted by makepattern Implementation . Its value consists of information used by the interpreter to achieve proper tiling of the pattern. The type and value of this entry are implementation dependent. The pattern dictionary can contain other constant information that is required by the PaintProc . The pattern cell is described in its own coordinate system, the pattern , which is defined by concatenating the operand coordinate system matrix of makepattern makepattern is executed. The with the CTM at the time XStep YStep , and BBox parameters are interpreted in the pattern coor- , dinate system; the PaintProc is executed in that coordinate system. The placement of pattern cells in the tiling is based on the location of one key pattern cell , which is then displaced by multiples of XStep and YStep to replicate the pattern cell. The origin of the key pattern cell coincides with the origin of the coordinate system defined by concate- nating is executed. The phase matrix with CTM at the time makepattern of the tiling can be controlled by the translation components of the operand. This tiling is frozen; that is, whenever the pattern dic- matrix tionary created by makepattern is used for painting, the same tiling is used, regardless of intervening changes to the CTM. In Display PostScript systems, there is a halftone phase parameter that controls the placement of halftone cells relative to device space. This is to support operations such as scrolling (see section 7.3.3, “Halftone Phase”). Changing the halftone phase also alters the placement of pat- terns by the same amount. This applies only to patterns subsequently painted using existing pattern dictionaries—those created by before the halftone phase was changed. It does not affect makepattern the placement of newly created patterns. 4.9 Patterns 203

212 PLRM 2nd Edition Graphics January 26, 1994 To paint with a pattern, one must first establish the pattern dictionary as the current color in the graphics state; this is described in section 4.9.3, “Pattern Color Space.” Subsequent painting operations will tile the painted areas with the pattern cell that is described in the diction- ary. Whenever it needs to obtain the pattern cell, the interpreter: 1. Executes gsave . 2. Installs the graphics state that was in effect at the time makepattern was executed, with certain parameters altered as documented in the makepattern . operator description for 3. Pushes the pattern dictionary on the operand stack. 4. Executes the pattern’s PaintProc . 5. Executes grestore . PaintProc is expected to consume its dictionary operand and to use The the information at hand to paint the pattern cell. It must obey certain guidelines to avoid disrupting the environment in which it is invoked. • It should not execute any of the operators that are unsuitable for use in encapsulated PostScript files; these are listed in Appendix I. showpage , copypage , or any device setup • It should not execute operator. • Except for removing its dictionary operand, it should leave the stacks unchanged. • It should have no side effects beyond painting the pattern cell. It should not alter objects in VM or anywhere else. Due to the effects of caching, the PaintProc is called at unpredictable times and in unpre- dictable environments. It should depend only on information in the pattern dictionary and it should produce the same effect every time it is called. 4.9.3 Pattern Color Space whose “color values” are There is a special color space called Pattern specified as pattern dictionaries. Selecting a pattern as the current color is a two-step process: 204 Chapter 4: Graphics

213 PLRM 2nd Edition Graphics January 26, 1994 setcolorspace Pattern . 1. Execute to set the current color space to setcolor with a pattern dictionary operand (and possibly 2. Execute other operands) to select that pattern as the current color. Section 4.8, “Color Spaces,” gives general information about color spaces and color values. Details of the Pattern color space and color value specifications appear below. The initial color value in a pattern color space selected by setcolorspace is a object, which is treated as if it were a pattern dictionary whose null PaintType is 1 and whose PaintProc is an empty procedure. Painting with this pattern does not produce any marks on the current page. A convenience operator, setpattern , combines the two steps for select- ing a pattern. It takes a pattern dictionary as an operand, selects the Pattern color space, and sets the pattern as the current color. Details of its behavior depend on the value of the PaintType entry in the pattern setpattern is the normal method for selecting patterns. For dictionary. the purpose of exposition, the descriptions below specify the color space and color value separately, even though it is rarely necessary to do so. Colored Patterns A colored pattern is one whose color is self-contained. As part of painting the pattern cell, the PaintProc explicitly sets the colors of all graphical elements it paints. A single pattern cell can contain elements that are painted different colors. It can also contain sampled gray-scale or color images. When used with colored patterns, the Pattern color space requires no additional parameters. The color space operand to setcolorspace can be either the name or a one-element array containing the name Pattern Pattern Pattern color space can also have a parameter, the underly- . The ing color space , as a second element of the array. This is required when using uncolored patterns, but is ignored when using colored patterns. A color value operand to setcolor in this space has a single component, a pattern dictionary whose PaintType is 1. Example 4.17 establishes a is a type 1 pattern colored pattern as the current color, where pattern dictionary. 4.9 Patterns 205

214 PLRM 2nd Edition Graphics January 26, 1994 Example 4.17 [/Pattern] setcolorspace % Alternatively, /Pattern setcolorspace pattern setcolor fill , Subsequent executions of painting operators, such as , show , stroke and imagemask , use the pattern to tile the areas to be painted. The Note operator use a image operator in its 5-operand form and the colorimage ) for , DeviceRGB , or DeviceCMYK DeviceGray predetermined color space ( interpreting their color samples, regardless of the current color space. A pattern color space has no effect on those operators. The 1-operand (dictionary) form of image is not allowed, because numeric color components operator is are not meaningful in a pattern color space. The imagemask allowed, because the image samples do not represent colors, but rather designate places where the current color is to be painted. Example 4.18 defines a colored pattern and then uses it to paint a rec- tangle and a character. Example 4.18 << % Begin prototype pattern dictionary /PaintType 1 % Colored pattern /PatternType 1 /TilingType 1 /BBox [0 0 60 60] /XStep 60 /YStep 60 /star { % Private procedure used by PaintProc gsave 0 12 moveto 4 { 144 rotate 0 12 lineto } repeat closepath fill grestore } /PaintProc { begin % Push pattern on dictionary stack 0.3 setgray % Set color for dark gray stars 15 15 translate star 30 30 translate star % Set color for light gray stars 0.7 setgray –30 0 translate star 30 –30 translate star end } >> % End prototype pattern dictionary matrix % Identity matrix makepattern % Instantiate the pattern /Star4 exch def 120 120 184 120 4 copy % 2 copies of rectangle operands /Pattern setcolorspace Star4 setcolor rectfill % Fill rectangle with stars 0 setgray rectstroke % Stroke black outline 206 Chapter 4: Graphics

215 PLRM 2nd Edition January 26, 1994 Graphics /Times-Roman 270 selectfont 160 100 translate 0.9 setgray 0 0 moveto (A) show % Paint character with gray Star4 setpattern 0 0 moveto (A) show % Paint character with stars Figure 4.7 Output from Example 4.18 ¢¢¢¢ QQQQ QQQQ ¢ ¢¢¢ Q QQQ ¢¢¢¢ ¢¢¢¢ ¢¢¢ QQQQ ¢ Q QQQ A ¢¢¢¢ QQQQ PaintProc The pattern consists of four stars in two different colors. The specifies the colors of the stars. There are several features of Example 4.18 that are noteworthy: • After constructing the prototype pattern dictionary, the program immediately invokes makepattern on it. The value that it assigns to is the pattern returned by instantiated . There is no Star4 makepattern need to save the prototype pattern unless the program desires to instantiate it in multiple ways, perhaps with different sizes or orien- tations. • The program illustrates both methods of selecting a pattern for setcolor painting. The first time, it invokes the setcolorspace and operators separately. The second time, it invokes the convenience . Note that the occurrences of also setgray operator setpattern . DeviceGray change the color space to 4.9 Patterns 207

216 PLRM 2nd Edition Graphics January 26, 1994 A • The rectangle and the letter are painted with the same pattern (the pattern dictionary returned by a single execution of makepattern ). The patterns align even though the CTM is altered between the two uses of the pattern. • The pattern cell does not completely cover the tile. There are areas of the tile (the spaces between the stars) that are not painted. When the pattern is used as a color, the stars are painted, but the background shows through the areas between the stars. The appearance of the letter A demonstrates this: It is painted once with gray and again with the star pattern. The gray shows between the stars. Uncolored Patterns An uncolored pattern is one that does not have any inherent color. Instead, the color must be specified separately whenever the pattern is used. This provides a way to tile different regions of the page with pattern cells having the same shape but different colors. The pattern’s PaintProc does not explicitly specify any colors; it cannot use the image or colorimage operators, but it can use the imagemask operator. When used with uncolored patterns, the Pattern color space requires a parameter: an array or name that identifies the underlying color space in which the actual color of the pattern is to be specified. A color value to color space has at least two compo- Pattern be given to setcolor in this nents: a color value in the underlying color space, given as one or more PaintType is 2. numbers, and a pattern dictionary whose Example 4.19 establishes an uncolored pattern as the current color, using DeviceRGB as the underlying color space. The values r , g , and b specify a color in the underlying color space; pattern is a type 2 pattern dictionary. Example 4.19 [/Pattern [/DeviceRGB]] setcolorspace r g b pattern setcolor Subsequent executions of painting operators, such as , fill , stroke , show imagemask , use the pattern to tile the areas to be painted. They and g paint the pattern cells with the color value described by r , , and b . Pattern Note The underlying color space of a Pattern color space cannot itself be a color space. 208 Chapter 4: Graphics

217 PLRM 2nd Edition January 26, 1994 Graphics Example 4.20 defines an uncolored pattern and then uses it to paint a rectangle and a circle with different colors applied through the pattern. Example 4.20 << % Begin prototype pattern dictionary /PaintType 2 % Uncolored pattern /PatternType 1 /TilingType 1 /BBox [–12 –12 12 12] /XStep 30 /YStep 30 /PaintProc { pop % Pop pattern dictionary 0 12 moveto 4 { 144 rotate 0 12 lineto } repeat closepath fill } >> % End prototype pattern dictionary % Identity matrix matrix % Instantiate the pattern makepattern /Star exch def 140 110 170 100 4 copy % 2 copies of rectangle operands 0.9 setgray rectfill % Fill rectangle with gray [/Pattern /DeviceGray] setcolorspace 1 Star setcolor rectfill % Fill rectangle with white stars 225 185 60 0 360 arc % Build circular path 0 Star setpattern gsave fill grestore % Fill circle with black stars 0 setgray stroke % Stroke black outline Output from Example 4.20 Figure 4.8 4.9 Patterns 209

218 PLRM 2nd Edition January 26, 1994 Graphics The pattern consists of a single star, which the PaintProc paints without first specifying a color. Most of the remarks after Example 4.18 on page 206 also apply to Example 4.20. Additionally: • The program paints the rectangle twice, first with gray, then with the pattern. To paint with the pattern, it supplies two operands to setcolor : the number 1, designating white in the DeviceGray color space, and the pattern dictionary. • The program paints the circle with the same pattern, but with the setpattern in this instance. It color set to 0 (black). Note the use of setpattern inherits parameters from the existing color space (see the operator description for details). 4.10 Images The PostScript language’s painting operators include general facilities for dealing with sampled images. A sampled image (or just “image” for short) is a rectangular array of sample values, each representing some color. This image may approximate the appearance of some natural scene obtained through a television camera or a color input scanner, or it may be generated synthetically. Figure 4.9 Typical sampled image An image is defined by a sequence of samples obtained by scanning the image rectangle in row or column order. Each sample in the array con- sists of 1, 3, or 4 components (for example, representing gray-scale, RGB, or CMYK color). Each component consists of a 1-, 2-, 4-, 8-, or 12- bit integer, permitting the representation of 2, 4, 16, 256, or 4096 differ- ent values for each component. 210 Chapter 4: Graphics

219 PLRM 2nd Edition January 26, 1994 Graphics Level 1 and Level 2 implementations of the PostScript language differ in the facilities they offer for images: • Most Level 1 implementations support only gray-scale images—that is, ones whose image samples consist of a single gray component. image These can be painted by means of the 5-operand form of the operator. Image samples must consist of 1, 2, 4, or 8 bits per compo- nent (12-bit components are not supported). The image source data must be provided by a procedure. Direct use of files or strings as data sources is not supported. • A few Level 1 implementations have been extended to support color images containing 3 or 4 components per sample interpreted as RGB or CMYK. These can be painted by means of the colorimage opera- tor. The Level 1 products containing this feature are primarily color printers. They also support the setcmykcolor operator and 4-color rendering features. • Level 2 implementations support all the features of Level 1. Addi- tionally, they support image dictionaries , which are a more general image operator. The means for specifying parameters to the image operator has a 1-operand form in which the operand is an image dic- tionary. Other features available only in Level 2 include interpreta- tion of sample values in any color space (CIE-based, for instance), 12-bit component values, direct use of files or strings as data sources, and additional decoding and rendering options. • All implementations support the operator, which paints imagemask the current color through a mask specified as a bitmap (see section 4.10.6, “Masks”). However, specification of its operands using an image dictionary is supported only in Level 2. There are often several ways to paint a given image, depending on what level of language features are to be used. Fortunately, most of the semantics of images do not depend on how painting is invoked or how operands are represented. In the sections that follow, frequent reference is made to specific features, such as colorimage or image dictionaries. Refer to the above summary to determine which features are supported in a particular implementation. 4.10.1 Image Parameters The properties of an image—resolution, orientation, scanning order, and so on—are entirely independent of the properties of the raster out- put device on which the image is to be rendered. The PostScript inter- 4.10 Images 211

220 PLRM 2nd Edition January 26, 1994 Graphics preter usually renders an image by a sampling and halftoning technique that attempts to approximate the color values of the source as accurately as possible. The accuracy depends on the resolution and other properties of the raster output device. To paint an image, a PostScript language program must specify four interrelated items: • The format of the source image: number of columns (width), num- ber of rows (height), number of components, and number of bits per component. • A data source capable of providing the image sample data, which height × width × components consist of bits/component bits of infor- × mation. • The correspondence between coordinates in user space and coordi- nates in the source image space, defining the region of user space that will receive the image. • The mapping from component values in the source image to compo- nent values in the current color space. The PostScript language program entirely controls these four aspects of image specification. 4.10.2 Sample Data Representation The source format for an image can be described by four parameters: . A PostScript language pro- bits/component width, height, components , and gram specifies , height , and bits/component explicitly. The inter- width preter infers the components parameter, as follows: • With the 5-operand form of the image operator and with imagemask , components is always 1. • With the 1-operand (image dictionary) form of the operator, image components is the number of components in the current color space. See section 4.8, “Color Spaces.” • With the colorimage operator, components is specified explicitly as ncomp operand. the 212 Chapter 4: Graphics

221 PLRM 2nd Edition Graphics January 26, 1994 Image data are represented as a stream of characters—specifically, 8-bit integers in the range 0 to 255, obtained from some data source (returned from a procedure or read from a file or string). These charac- ters represent a continuous bit stream, with the high-order bit of each character first. This bit stream is in turn divided into units of bits/compo- nent bits each, ignoring character boundaries. 12-bit sample values straddle character boundaries; other sizes never do. Each unit encodes a color component value, given high-order bit first. Each row of the source image begins on a character boundary. If the number of data bits per row is not a multiple of 8, the end of the row must be padded with extra bits to fill up the last character. The PostScript inter- preter ignores these bits. n Each source sample component is an integer in the range 0 to 2 –1, where n is the number of bits per component. The PostScript interpreter maps this to a color component value (equivalent to what could be used with operators such as setgray or setcolor ) by one of two methods: • With the 5-operand form of image , and with all forms of n colorimage , the integer 0 maps to the number 0.0, the integer 2 –1 maps to the number 1.0, and intermediate values map linearly to numbers between 0.0 to 1.0. image , the mapping is spec- • With the 1-operand (dictionary) form of Decode entry in the image dictionary. ified explicitly by the imagemask , image samples do not represent color values, so • With mapping is not relevant. See section 4.10.6, “Masks.” , and image , colorimage imagemask The imaging operators ( ) can obtain source data from any of three types of objects: Procedure . Whenever the interpreter requires additional data, it calls • the procedure, which is expected to return a string containing some more data. The amount of data returned by each call is arbitrary. However, returning one or more complete scan lines at a time sim- plifies programming, especially when reading image data that appear in-line in a PostScript language program. This is the only type of data source permitted by Level 1 implementations. • File . The interpreter simply reads data from the file as necessary. Note that performs some form of decoding that the file can be a filtered file or decompression (see section 3.8.4, “Filters”). This type of data source is a Level 2 feature. 4.10 Images 213

222 PLRM 2nd Edition January 26, 1994 Graphics • String . The interpreter simply reads data from the string, reusing it as many times as is necessary to provide the amount of data that the imaging operation expects. This type of data source is a Level 2 fea- ture, though equivalent behavior can be obtained with Level 1 by providing a procedure that simply returns the same string each time it is called. Data sources for images are much the same as data sources for filters. For further elaboration on the semantics of data sources, see section 3.13.1, “Data Sources and Targets.” When reading from a data source causes a PostScript language procedure to be invoked, that procedure must not do anything to disturb the ongoing imaging operation—for example, alter the graphics state or image dictionary, or initiate a new imaging operation. A data source can end prematurely. This occurs if a procedure returns a string of length zero or a file encounters end-of-file. If a data source ends before all source samples have been read, the remainder of the image that would have been painted by the missing samples is left unpainted. If the last source row is incomplete—that is, the data source ends in mid-row—the partial source row may be discarded and not painted. When there are multiple components per sample ( components is greater than 1), the source data can be organized in one of two ways: • Single data source . All components are obtained from the same source, interleaved on a per-sample basis. For example, in a 3-com- ponent RGB image, the red, green, and blue components for one sample are followed by the red, green, and blue components for the next sample. • Multiple data sources . Each component is obtained from a separate source—for example, all red components from one source, all green components from a second, all blue components from a third. The three sources must be of the same type and must actually be inde- pendent—for example, three different files, or three procedures using different strings to buffer the data, because the interpreter reads from them in parallel. If the data sources are procedures, all of them must return strings of the same length on any given call. 214 Chapter 4: Graphics

223 PLRM 2nd Edition Graphics January 26, 1994 A PostScript language program specifies which organization to use by MultipleDataSources multi operand of colorimage or the means of the entry in the image dictionary. Figure 4.10 illustrates some typical orga- nizations for data sources. It also shows the image sample decode map- ping operation. Figure 4.10 Image data organization and processing Single component image Image samples Data source* Decode Color values Multiple component image (e.g., RGB), single source R R Decode R Image samples interleaved ...RGBRGB... G G Decode G Color values Data source* B B Decode B Multiple component image (e.g. RGB), separate sources R image samples R Decode R Data source* G image samples G Decode G Data source* Independent Color values B image samples B Decode B Data source* * Data source is a single file, procedure, or string. 4.10.3 Source Coordinate System The image operators impose a coordinate system on the source image. They consider the source image to be a rectangle that is height units width high and units wide. Each sample occupies one square unit. The x values range from 0 to width origin (0, 0) is in the lower-left corner. inclusive, and y values range from 0 to height inclusive. The image operators assume that they receive sample data from their x -axis major indexing order. The coordinate of the lower- data source in left corner of the first sample is (0, 0), of the second (1, 0), and so on 215 4.10 Images

224 PLRM 2nd Edition January 26, 1994 Graphics through the last sample of the first row, whose lower-left corner is at width – 1, 0) and whose lower-right corner is at ( width ( , 0). The next samples after that are at coordinates (0, 1), (1, 1), and so on, until the final sample of the image, whose lower-left corner is at ( width –1, 1) and whose upper-right corner is at ( width , height ). height – Figure 4.11 illustrates the organization of the source coordinate system. The numbers inside the squares indicate the order of the samples, counting from 0. Figure 4.11 Source image coordinate system h (h–1)w+1 (h–1)w hw–1 h–1 2 w w+1 2w–1 1 0 w–1 1 0 w 0 1 2 w–1 The source coordinate system and scanning order imposed by the image operators do not preclude using different conventions in the actual source image. Coordinate transformation can map other conven- tions into the PostScript language convention. The correspondence between this source image coordinate system (or image space ) and user space is specified by a special matrix. This matrix is provided in one of two ways: image imagemask and in all forms of and • In the 5-operand forms of operand. colorimage , there is a separate matrix ImageMatrix • In image dictionaries, there is a required entry. This matrix defines a mapping from user space to image space. That is, a user space coordinate transformed by the matrix yields an image space coordinate. There are four points in user space that map to the coordi- nates of the four corners of the image in image space. This is a general Chapter 4: Graphics 216

225 PLRM 2nd Edition January 26, 1994 Graphics linear transformation that can include translation, rotation, reflection, and shearing (see section 4.3, “Coordinate Systems and Transforma- tions”). Figure 4.12 Mapping the source image source image unit square h in user space 1,1 0,1 image matrix CTM 0 0,0 1,0 0w current page Although it’s possible to map directly from current user space to image space by appropriate definition of the image matrix, it’s easier to think about the transformation by dividing it into two steps: of user space, bounded by unit square 1. The image matrix maps the (0, 0) and (1, 1) in user space, to the boundary of the source image in image space. 2. The CTM maps the unit square of user space to the rectangle or par- allelogram on the page that is to receive the image. This is just a convention, but it is a useful one that is recommended (see Figure 4.12). With this convention, the image matrix is used solely to describe the image itself, independent of how it is to be positioned, ori- ented, and scaled on a particular page. It defines an idealized image space consisting of a unit square that corresponds to the PostScript lan- guage’s conventions for coordinate system and scanning order. A pro- gram can then map this idealized image space into current user space by altering the CTM in straightforward ways. An image that happens to use the PostScript language conventions (scanning left-to-right, bottom-to-top) can be described by the image matrix width height [ 0 0] 0 0 217 4.10 Images

226 PLRM 2nd Edition Graphics January 26, 1994 An image that is scanned left-to-right, top-to-bottom (a commonly used order) is described by the image matrix width 0 0 – height 0 height [ ] Images scanned in other common orders can be described in similar ways. An image that has been mapped into the unit square this way can then be placed on the output page in the desired position, orientation, and size by invoking the PostScript operators that transform user space: . translate , rotate , and scale For example, to map such an image into a rectangle whose lower-left corner is at (100, 200), is rotated 45 degrees counterclockwise, and is 150 units wide and 80 high, a program can execute 100 200 translate 45 rotate 150 80 scale image , before invoking the colorimage , or imagemask operator. This image that has been mapped into the unit square by an works for any appropriate image matrix. Of course, if the aspect ratio (ratio of width to height) of the source image in this example were different from the ratio 150:80, the result would be distorted. Although images themselves are always rectangular, you can clip an image to Note any desired shape by establishing a clipping path using the clip operator before invoking image , colorimage , or imagemask . 4.10.4 Images and Color Spaces The color samples in an image are interpreted according to some color space (see section 4.8, “Color Spaces”). The color space to be used depends on how imaging is invoked: • The 5-operand form of the image operator always interprets color color space, regardless of the DeviceGray samples according to the current color space. It does not alter the current color space parame- ter in the graphics state. operator always interprets color samples according • The colorimage to the DeviceGray , DeviceRGB , or DeviceCMYK color space, depend- operand is 1, 3, or 4. It neither reads nor ing on whether its ncomp alters the current color space parameter in the graphics state. 218 Chapter 4: Graphics

227 PLRM 2nd Edition January 26, 1994 Graphics image operator interprets • The 1-operand (dictionary) form of the color samples according to the current color space. The number of components per sample and the interpretation of the component values depend on the color space. This form of can be used image . with any color space except Pattern operator always interprets its source data as a mask imagemask • The for applying the current color in the current color space (see section any color space. 4.10.6, “Masks”). This works for 4.10.5 Image Dictionaries image imagemask operators, but not colorimage , In Level 2, the and have a 1-operand form in which all imaging parameters are bundled together as an operand. This arrangement provides image dictionary more flexibility than the 5-operand form of image or any form of colorimage . The following features can be accessed only by means of image dictionaries: CIEBasedABC . • Use of arbitrary color spaces, such as Separation or • User-defined decoding of image sample values. • Interpolation between samples. An image dictionary contains various entries, some of which are required and some optional. Table 4.8 describes the semantics of each of the image dictionary entries. There are many relationships among these entries. The current color space may limit the choices for various entries in the image dictionary. Attempting to use an image dictionary in which required entries are missing or of the wrong type will cause a typecheck error. Attempting to use an image dictionary whose entries are inconsistent with each other or with the current color space will result in a rangecheck error. Table 4.8 Entries in an image dictionary Key Type Semantics ImageType ) Must be 1. integer ( Required integer ( Required ) Width of the source image in samples. Width integer Height ( Required ) Height of the source image in samples. ) An array of six numbers that define a transformation from current user ImageMatrix array ( Required space to image source space. 4.10 Images 219

228 PLRM 2nd Edition Graphics January 26, 1994 boolean Optional ) The value true indicates that the image data are provided through MultipleDataSources ( multiple data sources, one per color component. The value false indicates that the image data for all color components are packed into one data stream, MultipleDataSources must be false or absent interleaved on a per-sample basis. in an image dictionary used with imagemask . Default value: false . DataSource (various) ( Required ) If MultipleDataSources is false or is not present, the value of DataSource must be a single data source (file, procedure, or string). If MultipleDataSources is true , DataSource must be an array of data sources; the length of the array must be the same as the number of components in the current color space. BitsPerComponent integer ( Required ) Specifies the number of bits used to represent each color component. The number must be 1, 2, 4, 8, or 12. Only a single number may be specified. The number of bits is the same for all color components. BitsPerComponent must be 1 in an image dictionary used with imagemask . Required ) An array of numbers. The length of the array must be twice the Decode array ( number of color components in the current color space. This describes how to map image sample values into the range of values appropriate for the current color space (see below). Interpolate ( Optional ) If present with the value true , requests that image interpolation be boolean false . performed (see below). Default value: The following sections describe the semantics of some of these entries in more detail. All of this information applies to image dictionaries used with the image operator. Most of it also applies to image dictionar- ies used with the imagemask operator. See section 4.10.6, “Masks.” Decode The bit stream of image data is initially decomposed into integers n between 0 and 2 is the value of – 1, where n BitsPerComponent . There is one of these integers for each component of a given color sample. The number of components depends on the current color space. The Decode array specifies a linear mapping of an integer component value to a number that would be appropriate as an operand to setcolor in the current color space. For each color component, Decode specifies a minimum and maximum output value for the mapping. The linear mapping is defined as: D D − max min oD = × i + min n 1 − 2 220 Chapter 4: Graphics

229 PLRM 2nd Edition January 26, 1994 Graphics where n ; is the value of BitsPerComponent n i is the input value, in the range 0 to 2 –1; D D Decode are the parameters in the and array; min max o is the output value, to be interpreted as a color component. In other words, an input value of zero will be mapped to D , an input min n value of 2 D , and intermediate input values – 1 will be mapped to max will be linearly mapped to values between D and D . min max The numbers in the Decode array are interpreted in pairs, with succes- sive pairs applying to successive components of the current color space in their standard order. Table 4.9 lists recommended Decode arrays for use with the various color spaces. Table 4.9 arrays Decode Typical Color space array Decode DeviceGray [0 1] DeviceRGB [0 1 0 1 0 1] DeviceCMYK [0 1 0 1 0 1 0 1] CIEBasedABC [0 1 0 1 0 1] CIEBasedA [0 1] Separation [0 1] n Indexed [0 N ] where N = 2 –1 ( image is not permitted) Pattern For most color spaces, the Decode arrays listed above map into the full CIEBasedABC and range of allowed component values. For the CIEBasedA color spaces, the suggested Decode array maps to compo- nent values in the range 0.0 to 1.0. This is typical for the class of cali- brated gray or RGB color spaces, but the appropriate values actually depend on how the color spaces have been parameterized. For the array ensures component Indexed color space, the suggested Decode values that index a color table are passed through unchanged. 4.10 Images 221

230 PLRM 2nd Edition Graphics January 26, 1994 inverts sample color intensities It is possible to specify a mapping that by specifying a D value which is greater than the D . For example, min max if the current color space is DeviceGray and the Decode array is [1 0] , an input value of 0 will be mapped to 1.0 (white), while an input value of n 2 – 1 will be mapped to 0.0 (black). parameters for a color component are not required and D The D min max to fall within the range of values allowed for that component. For instance, if an application uses 6-bit numbers as its native image sample format, it can send those samples to the PostScript interpreter in 8-bit format, setting the two unused high-order bits of each sample to zero. When imaging that data, it should specify a Decode array of [0 4.04762] , which maps the input values 0 to 63 into the range 0.0 to 1.0. If an output value falls outside the range allowed for a component, the value will be automatically adjusted to the nearest allowed value. Interpolate When the resolution of a source image is significantly lower than the resolution of the device, each source sample covers many device pixels. This can result in a “jaggy” appearance of binary images or a “blocky” appearance of continuous-tone images. image interpolation These visual artifacts can be reduced by applying an algorithm during rendering. Instead of painting all of the pixels cov- ered by a source sample with the same color, it attempts to make a smooth transition between adjacent sample values. Setting the Interpolate entry to true in the image dictionary for either image imagemask enables image interpolation. The default is not to or interpolate. Enabling interpolation may increase the time required to render the image. 4.10.6 Masks The image and colorimage operators are consistent with other painting operators in that all areas of a page affected by an image are marked as though by opaque paint (see section 4.1, “Imaging Model”). Any por- tion of an image, whether black, white, color, or gray, completely obscures any marks that previously existed in the same place on the page. 222 Chapter 4: Graphics

231 PLRM 2nd Edition January 26, 1994 Graphics mask , whose prop- There is a special variant of a binary image, called a erties are quite different. Whereas an image is opaque, a mask is par- imagemask tially transparent. The operator applies masks. The samples of a mask do not represent colors; they designate places on the page that should be marked with the current color in the current color space or not marked at all. The places that are not marked retain their former color values. One should think of pouring paint “through” a mask, where a 1 sample permits the paint to reach the page, but a 0 blocks it, or vice versa. Masks are most often useful for painting characters represented as bit- maps. Ordinarily, when painting such characters, one wants the “black” bits of the character to be transferred to the page, but the “white” bits, which are really just background, to be left alone. For reasons discussed in section 5.5, “Font Cache,” imagemask Note rather than image should almost always be used to paint bitmap characters. imagemask image ; most A program invokes in much the same way as image , there is a of the parameters have equivalent meanings. As with 5-operand form supported by all implementations and a 1-operand imagemask differs image dictionary form, which is a Level 2 feature. from image in the following significant ways: • The number of components per sample is always 1, regardless of the do not imagemask current color space, because sample values for represent color values. • The number of bits per component is always 1. When an image dic- tionary is used with imagemask , the BitsPerComponent entry must be 1. • The 5-operand form of imagemask includes a polarity operand that determines how the source samples are to be interpreted. If polarity is false , 0 designates a painted sample and 1 designates an unpainted sample. If polarity is true , 1 designates a painted sample and 0 desig- nates an unpainted sample. The 1-operand form of uses imagemask the Decode entry in the image dictionary for the same purpose. Decode false [0 1] and [1 0] correspond to polarity values of arrays of , respectively. true and 4.10 Images 223

232 PLRM 2nd Edition Graphics January 26, 1994 Using Images 4.10.7 This section contains some simple examples that demonstrate typical uses of images. The examples are incomplete; they cannot show the image data itself, since it is very bulky. For further information about the imaging operators themselves, see the operator descriptions in Chapter 8. Monochrome Image Example 4.21 uses the image operator to paint a gray-scale image, using facilities available in Level 1 implementations. Example 4.21 /picstr 256 string def % String to hold image data 45 140 translate % Locate lower-left corner of image 132 132 scale % Map image to 132 unit square 256 256 8 % Dimensions of source image [256 0 0 –256 0 256] % Map unit square to source {currentfile % Read image data from program file picstr readhexstring pop} image 4c47494b4d4c524c4d50535051554c5152 ... ...Total of 131072 hex digits of image data, representing 65536 samples... This program paints an image consisting of 256 × 256 samples at 8 bits per sample. It positions the image with its lower-left corner at (45, 140) in current user space and scales it to a width and height of 132 user space units. The image data are represented with the first sample in the upper-left corner, so the program uses the image matrix to match its coordinate system with the normal PostScript language convention. See section 4.10.3, “Source Coordinate System.” The image data appear in-line in the PostScript language program. This is the most common way to access image data in a document. Only occasionally will a program refer to image data stored elsewhere—in a file, for instance. The image data are represented in hexadecimal, not 8- bit binary, so as to maximize portability of the document. The program specifies a data source which is a procedure. Each time the procedure is called by image , it executes readhexstring to read one row image . It of image sample data into a string, which it then returns to 224 Chapter 4: Graphics

233 PLRM 2nd Edition Graphics January 26, 1994 reuses this string during every call. It is not necessary to read one row at a time, but doing so simplifies programming. If the procedure reads multiple rows at a time, or an amount of data that is not a multiple of the image’s width, it must take special care not to read past the end of the image data the last time it is called by image . Doing so would cause some program text following the image data to be lost. With most images, it’s very important to read the image data incremen- tally, as shown in this example. Attempting to read the entire image into a single string or to represent it as a PostScript language string lit- eral would run the risk of exceeding implementation limits or exhaust- ing available VM. Color Image with Single Source As indicated earlier, color images with multiple components per sample can be organized in two ways: interleaved components obtained from a single source, or separate components obtained from separate sources. The first organization is the only one that is useful for images whose data are provided in-line in a PostScript language program. The second organization is limited to situations in which the separate components are stored elsewhere, such as in separate files that can be read in parallel. Example 4.22 illustrates use of the operator to paint an colorimage image consisting of interleaved RGB data from a single source. This example works in Level 2 implementations, and also in those Level 1 implementations that have the CMYK color extensions. Example 4.22 /picstr 768 string def % String to hold 256 RGB samples 45 140 translate % Locate lower-left corner of image 132 132 scale % Map image to 132 unit square % Dimensions of source image 256 256 8 [256 0 0 –256 0 256] % Map unit square to source {currentfile % Read image data from program file picstr readhexstring pop} false 3 % Single data source, 3 colors colorimage 94a1bec8c0b371a3a5c4d281... ...393216 hex digits of image data, representing 65536 samples... 4.10 Images 225

234 PLRM 2nd Edition Graphics January 26, 1994 colorimage image example This example is superficially similar to the given earlier. The major change is that two additional operands are sup- colorimage , specifying that the image has a single data source plied to and 3 components. The image data consists of 8-bit red, green, and blue color components for each sample in turn. Image Dictionary Example 4.23 is a program that produces the same output as Example 4.22, but uses an image dictionary and other features available only in Level 2. Example 4.23 /DeviceRGB setcolorspace % How color values will be interpreted 45 140 translate % Locate lower-left corner of image 132 132 scale % Map image to 132 unit square << % Start image dictionary /ImageType 1 /Width 256 /Height 256 % Dimensions of source image /BitsPerComponent 8 % Decode color values in normal way /Decode [0 1 0 1 0 1] /ImageMatrix [256 0 0 –256 0 256] % Map unit square to source /DataSource currentfile /ASCIIHexDecode filter % Obtain in-line data through filter >> % End image dictionary image 94a1bec8c0b371a3a5c4d281... ...393216 hex digits of image data, representing 65536 samples... In this program, the image data source is a file instead of a procedure. The file is a that converts the hexadecimal encoded data from filtered file currentfile to binary form. For an explanation of this and an example of how to obtain image data that has been compressed, see section 3.8.4, “Filters.” 4.11 Device Setup This section explains the PostScript language facilities for setting up a raster output device in order to fulfill the processing requirements of a page description. Setting up a raster output device (hereafter, simply ) includes: device • Selecting the proper input media. 226 Chapter 4: Graphics

235 PLRM 2nd Edition Graphics January 26, 1994 • Establishing a default transformation matrix from user space to device space, along with other device dependent rendering parameters for producing output on the media. • Selecting processing options, such as multiple copies, or special fea- tures of the output device, such as duplex printing (2-sided). Once a device has been set up, a PostScript language program can describe a sequence of pages. For each page in turn, the program paints the current page in raster memory with everything that is to appear on it—text, graphics, and images. It then executes the showpage operator to cause the page to be produced. showpage transmits the contents of raster memory to the physical output device, then erases the current page and partially resets the graphics state in preparation for the next page. This model is appropriate to PostScript language programs that are page descriptions . A page description is intended to produce a sequence of pages on a page device , usually causing the page images to appear on physical media, such as sheets of paper. On the other hand, this model not appropriate for applications that use the PostScript language to is control the appearance of a display interactively (see Chapter 7). Level 1 and Level 2 implementations of the PostScript language differ in the facilities they offer for setting up a device to meet the requirements of a page description. • Level 1 implementations provide a collection of device control oper- ators, defined in a special dictionary named statusdict . The contents of statusdict are product dependent, although an attempt has been made to maintain a consistent specification for common features. statusdict features are not described in this manual, but in the docu- mentation for each product. Application programs desiring to use statusdict PostScript printer features can extract information from (PPD) files. Specifications for those files are available from description Adobe Systems Developers’ Association. • Level 2 implementations support a page device setup operator setpagedevice named . This operator provides a standard framework for specifying the requirements of a page description and for control- ling both standard and optional features of a device. Although the page device facilities are oriented toward devices that produce hard operator copy, such as printers or typesetters, the setpagedevice exists in all Level 2 implementations. 4.11 Device Setup 227

236 PLRM 2nd Edition Graphics January 26, 1994 The remainder of this section describes the page device setup facilities supported by Level 2. 4.11.1 Using Page Devices In the following discussion, the term media indicates the physical mate- rial on which the output appears (paper, transparency material, film, a virtual page on a display, or whatever). Most of the processing options are oriented toward printers that produce paper output, so “paper” is a good universal material to envision when you read “media.” Many products have special hardware features, such as multiple paper trays with different sizes of paper, duplex printing, collation, finishing options, and so on. The PostScript interpreter supports the special fea- tures of each product. It knows what features are currently available and ready for use. The setpagedevice operator is the way a page descrip- tion specifies its processing requirements and selects optional features. setpagedevice is the way a user or system administrator specifies Also, default device setup or configuration parameters to be used when a page description doesn’t specify them. Not all features are available in all products. setpagedevice provides a uniform framework for specifying processing requirements and options. It uses a standard syntax to request features supported by all devices, such as selecting a page size, and features supported only by some devices, such as duplex printing. setpagedevice also provides a standard mechanism for determining what to do when a page descrip- tion makes requests the device can’t fulfill. A page description must contain the minimum required device setup information, because including such information limits the set of devices on which the document can be printed. It is useful, at least in concept, to envision two separate tasks when printing from an application: 1. Generate the device-independent page description. 2. Request that the page description be printed on a particular device. At this point, the user should have an opportunity to add processing options, including device-dependent ones, to the page description. Even if a single application provides both of these functions, it is best to maintain this distinction. Most applications have an option to store the generated page description in a file for later use. That file should not contain unnecessary device-dependent processing options. The distinc- 228 Chapter 4: Graphics

237 PLRM 2nd Edition January 26, 1994 Graphics tion between document generation and document printing is essential when using PostScript language programs for document storage and interchange. While there is no clear division between device-independent processing requests and device-dependent ones, you should keep in mind the important goal of producing device-independent page descriptions. One important criterion to apply is whether a particular feature is inherently a part of the document specification or only a processing option. For example, the page size—in particular, the aspect ratio between width and height—is an important part of the document spec- ification, because the application generating the document must make formatting decisions based on the page size. On the other hand, the number of copies to be printed or the color of the paper to be used are an inherent part of the document description, but rather are pro- not cessing options. 4.11.2 Page Device Dictionary dictionary The current internal state of a page device is modelled as a containing some number of key-value pairs. The keys in the dictionary represent particular device features or processing options; the values represent the current settings of those features or options. This diction- ary is not directly accessible to a PostScript language program, but it can be altered and read by the and currentpagedevice opera- setpagedevice tors. is a dictionary supplying information in setpagedevice The operand of the form of key-value pairs that request particular device features or processing options. The dictionary is simply a container that can hold multiple key-value pairs to be supplied in a single call to setpagedevice . The interpreter uses the information in the dictionary to alter its inter- nal device state, but it does not retain the dictionary. The currentpagedevice operator returns a dictionary describing the current state of the page device using the same key-value organization. Executing setpagedevice alters the PostScript interpreter’s internal cumulative device state. Its effects are over multiple executions. That is, merges new requests into the existing state of the device. setpagedevice The effect of specifying a particular key-value pair persists through sub- until overridden explicitly or until the sequent calls to setpagedevice device is restored to some previous state by restore , grestore , . This cumulative behavior also applies recur- grestoreall , or setgstate sively (to one level) to the contents of subsidiary dictionaries that are 4.11 Device Setup 229

238 PLRM 2nd Edition Graphics January 26, 1994 Policies InputAttributes , and OutputAttributes . It the values of the keys , does not apply to the contents of other entries whose values happen to be dictionaries. Since the effects of are cumulative, a PostScript language setpagedevice program can make independent calls to setpagedevice , each requesting particular features or processing options, but leaving the settings for other features undisturbed. This allows different options to be specified at different times; in particular: 1. When an application generates a page description, it can include a call to specifying parameters, such as PageSize and setpagedevice ImagingBBox , that reflect assumptions the application has made in formatting the document. 2. When a user requests printing, an additional call to setpagedevice can be prepended to the page description to specify processing options, such as NumCopies , Duplex , or MediaColor . setpagedevice , 3. The person who is operating the printer can invoke as part of an unencapsulated job, to configure the available input media ( InputAttributes ), to establish policies for dealing with unsat- ), and to establish default values for other Policies isfied requests ( device options. For certain options, there is a “null” value that indicates absence of any request or preference for the value of that option. In all cases, the null null in systemdict ) is used for this purpose. For exam- object (value of MediaColor value of null ple, a indicates that no specific paper color has been requested. Null values are permitted only for certain features; see the tables in section 4.11.3, “Semantics of Specific Entries.” setpagedevice has Omitting a particular key in a dictionary passed to an effect different from providing that key with a null value. The absence of the key allows the value to be inherited from the previous state of the device. The presence of the key with a null value causes the value in the device to be set to null , cancelling any previous request for that feature. The dictionary returned by currentpagedevice always contains an entry for every feature supported by that specific device. For some features, null the value might be , indicating that the feature is supported, but no request has been made for that feature yet. 230 Chapter 4: Graphics

239 PLRM 2nd Edition January 26, 1994 Graphics setpagedevice includes any requests that the If the dictionary passed to device cannot satisfy, the PostScript interpreter invokes a uniform pol- icy for determining what to do. This policy is based on information in the sub-dictionary of the page device dictionary. Policies can be Policies altered by setpagedevice . For example, if a program requests duplex printing on a device that doesn’t support it, the policy existing at that time may be either to ignore the request (print simplex) or to generate a configurationerror (reject the job). setpagedevice does not If a device does not support a particular feature, recognize any request to specify a value for that feature. For example, if a device does not have a duplexing mechanism, does not setpagedevice Duplex recognize the key , even if the request is to set the value of to false , which indicates no duplexing. Instead, it consults Duplex Policies to determine what to do. This behavior might seem surprising, but it is necessitated by the fact that the set of device features is open- ended. A page device is only one of several kinds of raster output devices. Other devices include the to put characters into the font cache cache device and the null device to discard output entirely. These are set, usually tem- setcachedevice nulldevice operators. A Display porarily, by the and window devices that allow paint- PostScript system provides one or more ing onto various portions of a display. Ordinarily, a window device is not a page device; however, Display PostScript products often provide a preview capability that emulates a page device using a display window. If setpagedevice is executed when the current device is not a page device, the effect produced is device dependent. Note The setpagedevice operator is a page-oriented operator used to control the output processing of one or more pages of a page description. Any call to implicitly performs erasepage and initgraphics ; thus, it must setpagedevice precede the descriptions of the pages to be affected. 4.11.3 Semantics of Specific Entries The following tables describe the entries in a page device dictionary that have been defined at the time of publication of this manual. In the future, other entries will be defined to satisfy requirements for new pro- cessing options or product features. Once defined in any product, a given key will always be used for the same feature in any subsequent products that support it. Note Not all keys listed in the tables are recognized by all products. Consult each product’s documentation to see exactly which keys it recognizes. 4.11 Device Setup 231

240 PLRM 2nd Edition Graphics January 26, 1994 The entries are divided into four categories. This classification is not rigid; entries in different categories can sometimes interact with each other. However, organizing the entries this way facilitates understand- ing their purpose. • Input media selection entries (Table 4.10) provide information that can be used to select the appropriate type of paper or other media. The PageSize entry should be specified by the application generating the page description. Other entries should generally be specified only when printing is requested. There is a fairly elaborate interac- tion among these entries. See section 4.11.4, “Media Selection.” entries (Table 4.11) specify how pages are to be Processing and output • rendered onto the media and how the media are to be processed thereafter. The ImagingBBox entry should be specified by the appli- cation generating the page description. Other entries should gener- ally be specified only when printing is requested. • Roll media entries (Table 4.12) provide additional information that is usually relevant only to devices that feed media from a continuous roll, such as film in a typesetter. entries (Table 4.13) specify how requests for • Policy and special action unsupported features are to be handled and define special actions to be performed when the device is installed and before and after each page is printed. The PostScript language does not prescribe a default value for any entry. false null , but The usual default value for optional features is either or this is not invariably the case in all products. A PostScript language pro- gram can change the defaults by executing as part of an setpagedevice unencapsulated job. Table 4.10 Input media selection entries Key Type Semantics PageSize array Defines the overall page size that was assumed during generation of the page ] description. is an array of two numbers, [ width height PageSize , indicating the width and height of the assumed page, expressed in units of the default user coordinate system (1/72 inch). These are the overall dimensions of the page, including borders, if any. In other words, the lower-left corner and upper-right corner of the assumed physical page are at user space coordinates (0, 0) and height ), respectively. ( width , 232 Chapter 4: Graphics

241 PLRM 2nd Edition January 26, 1994 Graphics uses PageSize MediaColor , MediaWeight , MediaType , setpagedevice with ManualFeed Policies to select the appropriate medium. , InputAttributes , and Section 4.11.4, “Media Selection,” describes the matching rules that are used. setpagedevice attempts to match the size requirements of the pages with the media sizes currently available. Each media size is considered to be available in [ ] width height either of two orientations. Whether the media size is expressed as height width [ is immaterial insofar as matching is concerned. Likewise, the or ] orientation of media in the printing mechanism is unspecified and varies from one device to another. The PostScript interpreter takes care of setting up the transformation from user space to device space so the long and short dimensions PageSize specified by are oriented with the long and short dimensions of the physical media. If a of [ ab ] specifies a “portrait” orientation (that is, a < b ), then a PageSize of [ ba ] specifies a “landscape” orientation of the same size page. PageSize setpagedevice follows a rule that allows the portrait and landscape orientations of a given size page to be related to each other. The default user space in the landscape orientation will be rotated 90 degrees counterclockwise with respect to the default user space in the portrait orientation. This relationship holds only between the two orientations of the same size media. No such relationship is guaranteed between different media. PageSize The tolerance for matching with an available media size is –5 default user space units in either dimension. A match falling within this tolerance is considered to be exact. Failure to match any available media within this toler- . Policies ance triggers the PageSize recovery policy specified in MediaColor string or null is not null , setpagedevice com- MediaColor Specifies the color of the media. If values, if any, in the InputAttributes entries for all MediaColor pares it with the media that it considers. See section 4.11.4, “Media Selection.” number or null Specifies the weight of the media. If MediaWeight is not null , setpagedevice MediaWeight compares it with the MediaWeight values, if any, in the InputAttributes entries for all media that it considers. See section 4.11.4, “Media Selection.” Weight is expressed in grams per square meter. “Basis weight” or “ream weight” in pounds can be converted to grams per square meter by multiplying by 3.76; 10-pound paper is approximately 37.6 grams per square meter. MediaType string or null Specifies the type of the media. If MediaType is not null , setpagedevice com- pares it with the values, if any, in the InputAttributes entries for all MediaType media that it considers. See section 4.11.4, “Media Selection.” The value of MediaType is an arbitrary string that can identify such things as preprinted forms or other media attributes not covered by size, color, or weight. InputAttributes dictionary Contains an entry for each source of input media currently available for use by this device—for example, each input paper tray in a printer. The sources are arbi- trarily numbered by integers. Those integers are the keys for entries in the InputAttributes dictionary. The value of each entry is a dictionary describing the media currently available from that physical source. Keys used in these dictionaries include PageSize , , which have the same meanings as MediaType MediaColor , MediaWeight , and 4.11 Device Setup 233

242 PLRM 2nd Edition Graphics January 26, 1994 Priority the corresponding keys described above. Two other entries, and MatchAll , control details of the matching algorithm. See section 4.11.4, “Media Selection,” for a complete description of how this matching is done. Changes to the contents of the InputAttributes dictionary are cumulative. That InputAttributes entries in a is, the request are merged with the setpagedevice existing InputAttributes entries for the current device. However, the sub-diction- aries that are the values of InputAttributes entries are not merged. ManualFeed boolean If true , input media are drawn from the manual feed position. If false , automatic feeding takes place. Setting to true is an assertion that the person ManualFeed operating the device will manually feed media that conform to the specified attributes— PageSize , MediaColor , MediaWeight , and MediaType . Thus, those attributes are used to select from available media sources as is done normally. not Their values may be presented to the user as an aid in selecting the correct media. In products that offer more than one manual feeding mechanism, the attributes may select among them. Table 4.11 Processing and output entries Key Type Semantics null , the value is an array of four numbers in ImagingBBox array or null Optional page bounding box. If not the default user coordinate system stating lower-left x y , upper-right x , , lower-left y of the page image bounding box. This defines a rectangle, and upper-right which should lie within the boundaries of the page specified by PageSize . When a PostScript language program specifies an ImagingBBox , it asserts that it will not paint any marks outside this rectangle. Any marks that do fall outside the rectangle may or may not be painted. Although the information provided by ImagingBBox is optional, specifying it can improve performance by freeing raster memory for other purposes. If an application knows that unpainted borders appear on all pages, it should specify an appropriate value for ImagingBBox . The effect of specifying ImagingBBox is . not necessarily the same as executing clip should not be used for ImagingBBox purposefully clipping page content. An value of null requests the largest bounding box that is possible ImagingBBox PageSize for the given . This may not enclose the entire page; many devices are incapable of placing marks close to the edges of the media. If a program specifies PageSize , but chooses not to provide ImagingBBox information, it should explicitly set ImagingBBox to null to prevent an inappropriate value from being inherited from the previous device state. MediaType string or null OutputType is analogous to the input OutputType , but for output. If not null , the value is an arbitrary string that requests special output treatment, such as plac- ing the finished media into a selected output tray. This is used in conjunction to make such a selection. OutputAttributes with 234 Chapter 4: Graphics

243 PLRM 2nd Edition Graphics January 26, 1994 dictionary Contains an entry for each media destination currently available for use by this OutputAttributes device—for example, each output paper tray in a printer. The destinations are arbitrarily numbered by integers. Those integers are the keys for entries in the OutputAttributes dictionary. has the same structure and analogous function as the OutputAttributes InputAttributes dictionary. The matching is somewhat simpler because the only key considered in the match is . See section 4.11.4, “Media Selec- OutputType tion.” NumCopies integer or null If NumCopies is not null , it specifies the number of copies to produce. This value applies to each page individually or to the entire document, depending on the setting of Collate . A null value indicates that showpage and copypage should consult the value of in the current dictionary stack each time they are #copies executed (this is compatible with the convention used by Level 1 implementa- tions). See the showpage operator description. Collate boolean Determines how the output is to be organized when multiple copies are requested (by NumCopies or #copies ) for a multiple-page document. Output consists of “sets” of pages that are delivered together. If is true , a set con- Collate sists of one copy of all pages of the document. If Collate is false , a set consists of all copies of one page of the document. This concept of a “set” is also used by features. AdvanceMedia the Jog , CutMedia , and How collation is performed is device-dependent. If the device has a physical sorter and the number of copies requested is no greater than the number of bins in the sorter, the sorter handles the collation. Otherwise, the interpreter may need to reorder the output in order to deliver all pages of a set together. In the Collate value of true implies that the interpreter must store the latter case, a results of executing the entire page description in order to deliver multiple cop- ies correctly ordered. This use of Collate is supported by relatively few products and is subject to resource limits in products that do support it. If Collate is true , a set can span multiple invocations of setpagedevice within a single job, so long as NumCopies doesn’t change and the device is physically capable of delivering the output sorted that way. If that is not possible, multiple invocations of setpagedevice within a job will cause multiple documents to be produced. If Duplex boolean true , the pages are printed duplex—that is, each pair of consecutive pages is printed on opposite sides of a single sheet of paper. If , the pages are printed false simplex—one side only. When a duplex device is activated, it always prints the first page on a new sheet of paper. When the device is deactivated, it automatically delivers the last sheet if it has been printed on only one side. Device activation and deactivation are explained in section 4.11.6, “BeginPage and EndPage.” Tumble boolean When Duplex is true , Tumble specifies how the page images on opposite sides of a sheet are oriented with respect to each other. If is false , the default user Tumble spaces of the two pages are oriented such that the highest values of y in the two spaces lie along the same edge of the media. If Tumble is true , the default user y lie along opposite edges of spaces are oriented such that the highest values of 4.11 Device Setup 235

244 PLRM 2nd Edition Graphics January 26, 1994 Tumble false produces output suitable for bind- the media. Informally, a value of ing on the left or right; true produces output suitable for binding at the top or bottom. Tumble is defined in terms of default user space —the user space estab- Note that setpagedevice lished by . The orientation of default user space with respect to PageSize and Orientation the media is determined by the entries, possibly altered by the Install procedure. Consistent results are obtained across all prod- ucts that support duplexing, regardless of how the media move through the mechanism. However, if the page description alters user space by executing oper- ators such as , the visual orientation of the material printed on the page rotate may differ from the orientation of default user space. boolean If true , pages are stacked so the back side of page n is placed against the front side OutputFaceUp , pages are stacked so the front side of page n − 1. If false n of page is placed against the back side of page − 1. These are the effects usually achieved by n “face up” and “face down” stackers, respectively. Most products support only one stacking method; the value of OutputFaceUp indicates which method that is. Relatively few products allow both values of OutputFaceUp to be specified. Requests that output pages be “jogged”—physically shifted in the output tray— Jog integer at specific times indicated by an integer code: 0 Don’t jog pages at all. Jog at device deactivation. The notion of “device deactivation” is explained 1 in section 4.11.6, “BeginPage and EndPage.” 2 Jog at the end of the job. The notion of a “job” is explained in section 3.7.7, “Job Execution Environment.” Jogging between jobs is controlled by the value of for the page device that is current between jobs. Thus, this Jog feature can be turned on or off only by executing setpagedevice as part of an unencapsulated job. 3 Jog after each set. The notion of a “set” is explained in the description of the entry. Collate Separations boolean If true , the device should produce each page by printing multiple color separa- tions—one for each device colorant (primary or spot color). If false , the device should produce each page as a single composite page with all the colors, if any, combined on the same page. Color separations are explained in section 4.8, “Color Spaces.” The availability of this feature is product dependent. Most products cannot pro- duce separations. HWResolution Array of two numbers, [ xy ] , that indicates resolution of the physical device in array x and y dimensions of device space. Most products sup- pixels per inch along the port only a single resolution. The few products that permit the resolution to be varied usually support only certain specific resolutions, not arbitrary ones. , that relocates the page image on the media by Margins Array of two numbers, [ xy ] array x device units in the direction of the device x coordinate and by y device units in coordinate. This positioning is usually accom- the direction of the device y plished by device-dependent means that are independent of the graphics state 236 Chapter 4: Graphics

245 PLRM 2nd Edition January 26, 1994 Graphics (the CTM in particular). The range and precision of the parameter values may be restricted by the physical implementation. The purpose of Margins is to com- pensate for mechanical misadjustments in the device, not to perform purposeful positioning of output in a page description. NegativePrint If true , the device should produce a negative image of the page. This is accom- boolean plished by device-dependent means that are independent of the graphics state inverts the entire page, per- (the transfer functions in particular). NegativePrint haps including portions that lie outside the imageable area or that are generated by means independent of the PostScript interpreter. This feature is supported only by certain products, such as typesetters, that produce output intended for further photographic processing. MirrorPrint If true , the device should produce a page image that is reflected along one of the boolean axes of device space. This is usually accomplished by device-dependent means that are independent of the graphics state (the CTM in particular). This feature is supported only by certain products, such as typesetters, that produce output intended for further photographic processing. For example, when output is pro- MirrorPrint controls whether the page image should duced on transparent film, be viewed with the film emulsion face up or face down. Table 4.12 Roll media entries Key Type Semantics may not unam- PageSize Orientation integer For roll media, pages have no inherent orientation, so biguously select the orientation of the page image on the medium. The entry selects one of four orientations: Orientation 0 Normal default orientation for the specified PageSize . 1 Rotate the image on the medium 90 degrees counterclockwise with respect to the default orientation. 2 Rotate the image 180 degrees counterclockwise. 3 Rotate the image 270 degrees counterclockwise. CutMedia integer Indicates when to cut the medium. Valid codes are: 0 Don’t cut the medium. 1 Cut the medium at device deactivation. 2 Cut the medium at the end of the job. 3 Cut the medium after each set. 4 Cut the medium after each showpage or copypage . See Jog for an explanation of the terminology. AdvanceMedia integer Indicates when to advance the medium by an extra amount—that is, in addition to the amount occupied by the page images themselves. Valid codes are: Don’t advance the medium. 0 4.11 Device Setup 237

246 PLRM 2nd Edition January 26, 1994 Graphics Advance the medium at device deactivation. 1 2 Advance the medium at the end of the job. Advance the medium after each set. 3 4 showpage or copypage . Advance the medium after each for an explanation of the terminology. See Jog Indicates the distance, in default user space units, to advance the medium when integer AdvanceDistance it is advanced as controlled by AdvanceMedia . Table 4.13 Policy and special action entries Type Semantics Key dictionary Policies setpagedevice should do when a Contains feature-policy pairs that specify what feature request cannot be satisfied. It contains an overall policy and can option- ally contain individual policies for specific named features. A policy is an integer that specifies a choice of one of several ways to handle an unsatisfied request. See section 4.11.5, “Policies,” for an explanation of how this dictionary is used. Policies are cumulative; setpagedevice adds new Changes to the contents of entries to the ones already present. procedure Executed to install values in the graphics state during each invocation of set- Install pagedevice . setpagedevice calls this procedure after setting up the device and installing it as the current device in the graphics state, but before executing the and . implicit erasepage initgraphics This procedure can execute graphics state operators to install device-dependent parameters, such as halftone, color rendering, flatness, and so on. It can also alter the CTM. The resulting CTM becomes the default device matrix used by defaultmatrix , initmatrix , and initgraphics . The procedure cannot usefully alter most of the device-independent parameters, such as current path or color, because initgraphics resets those parameters to standard values. The Install pro- cedure should not do anything besides alter parameters in the graphics state. , procedure Executed at the beginning of each page. This occurs at the end of setpagedevice BeginPage at the end of each showpage or copypage , and during any operation that acti- vates a page device, such as a that reinstates a page device different grestore from the existing one. When is called, the graphics state has been ini- BeginPage tialized and the current page has been erased, if appropriate. BeginPage is sup- showpage has plied an integer on the operand stack indicating how many times been invoked since the current device was activated. See section 4.11.6, “BeginPage and EndPage.” EndPage procedure Executed at the end of each page. This occurs at the beginning of each showpage or copypage , and also when the current page device is about to be deactivated (replaced by a different page device). EndPage is supplied two inte- executions for this gers on the operand stack: a count of previous showpage device and a code indicating the condition under which this call is being made. 238 Chapter 4: Graphics

247 PLRM 2nd Edition Graphics January 26, 1994 must return a boolean value specifying whether to transmit the page EndPage image to the physical output device. See section 4.11.6, “BeginPage and EndPage.” Media Selection 4.11.4 A page description specifies its processing requirements by including appropriate entries in the dictionary it passes to setpagedevice . Certain Media- of these entries— PageSize , MediaColor , MediaWeight , and Type —control the selection of input media. Another entry— OutputType —controls the disposition of the media after they have been printed. This section describes how setpagedevice uses this infor- mation to determine the physical media source and destination to be used in the device. A given product supports one or more physical sources and one or more physical destinations for media. These sources and destinations are often called “trays” or “positions.” They are arbitrarily numbered by small integers. A particular integer usually refers to a specific physical location in the hardware, though it might refer to some logical capabil- ity such as a pair of trays that contain the same media and are used alternately. The correspondence between numbers and positions is product dependent; it is not described in this manual but in product documentation. InputAttributes The device includes two special dictionaries, and OutputAttributes , that describe the attributes of each of the sources and destinations, respectively. This information is discovered automatically by the implementation or is configured manually by a human operator or system administrator. setpagedevice matches the media requirements specified by the page description against the attributes described in InputAttributes and OutputAttributes to determine which media source and destination to select. InputAttributes dictionary are integers representing The keys in the media sources. The value of each entry is a dictionary containing key- value pairs describing the attributes of the media currently available from that source. The keys used in this dictionary are PageSize , Media- Color , MediaWeight , and MediaType . These keys have the same mean- ings as the corresponding ones described in Table 4.10 on page 232, but they specify the actual attributes of the media instead of the requirements of the page description. 4.11 Device Setup 239

248 PLRM 2nd Edition January 26, 1994 Graphics is treated similarly, but its entries contain only the OutputAttributes OutputType attribute. A page description can request a specific setpagedevice OutputType , which matches against the OutputType to determine which destina- attributes of entries in OutputAttributes and OutputType are supported only in OutputAttributes tion to select. those products that provide choices for output handling. A simple example illustrates the most common use of this approach for input media selection. (Output selection works analogously.) Suppose InputAttributes the current value of the dictionary for the device is: << 0 << /PageSize [612 1008] >> 1 << /PageSize [612 792] >> >> In other words, the product has two paper trays. Tray 0 contains legal- × 14 inch) paper; tray 1 contains letter-size (8.5 × 11 inch) size (8.5 paper. Now suppose a page description executes: << /PageSize [612 792] >> setpagedevice The attribute PageSize PageSize request to setpagedevice matches the for media source 1, and there are no non-matching requests. Therefore, selects tray 1. setpagedevice Matching Requests With Attributes Each time setpagedevice is executed, it uses the following algorithm to match media requests with media attributes in order to select a source and destination. 1. Merge the entries in the setpagedevice operand dictionary with the ones in the existing state of the device, as described in section 4.11.2, “Page Device Dictionary.” The resulting set of key-value pairs is considered together, without regard to which ones are specified in setpagedevice the operand dictionary and which ones are inherited from the existing state of the device. MediaWeight PageSize , MediaColor , 2. Collect together those of the , and MediaType entries whose values are not null and treat them as . null an “input media request.” Ignore the entries whose values are 240 Chapter 4: Graphics

249 PLRM 2nd Edition Graphics January 26, 1994 InputAttributes 3. Enumerate the entries in the dictionary. Each entry’s key is an integer identifying a media source; its value is a dictionary containing the attributes of the media. For each entry in the input media request (step 2), compare its value with the corresponding media attribute. If all the values are equal, we say that the media PageSize values are compared request matches the media source. ( with a tolerance of –5 units in each dimension.) 4. If the result of step 3 is that the media request matches exactly one media source, select that source. If there is more than one match, select the source with the highest priority (see Priority , below). If there are no matches at all, consult to determine what to do Policies (see section 4.11.5, “Policies”). 5. Similarly, perform steps 2 through 4 to select a media destination, using the OutputType entry as an “output media request” and the OutputAttributes dictionary as a description of the attributes of the available destinations. For example, consider a product with two paper trays. Tray 0 contains white letter-size (8.5 × 11 inches) office paper and tray 1 contains a much less expensive letter-size paper (also 8.5 × 11 inches). The dictionary in the device state might be as follows: InputAttributes << 0 << /PageSize [612 792] /MediaColor (white) /MediaType (office) >> 1 << /PageSize [612 792] >> /Priority [1 0] >> (How the InputAttributes dictionary got to be this way is discussed later, as is the meaning of the Priority entry.) Note In each InputAttributes entry, PageSize is required, but other attributes are optional. A non-null media request will not match an InputAttributes entry in which the corresponding attribute is absent. In the example above, only is given for source 1 and MediaWeight is not given for either source. PageSize If a page description now executes << /PageSize [612 792] /MediaColor (white) >> setpagedevice then setpagedevice will select input tray 0. This is because the PageSize and MediaColor entries in the setpagedevice request match only the InputAttributes dictionary. The values attributes given in entry 0 of the 4.11 Device Setup 241

250 PLRM 2nd Edition Graphics January 26, 1994 MediaType MediaWeight in the request are null (assuming that of and non-null values haven’t been inherited from the existing state of the null device). A value in a request means “don’t care.” Given the same InputAttributes , execution of << /PageSize [612 792] /MediaColor (red) >> setpagedevice will not match either tray. The requested MediaColor does not match the MediaColor attribute for tray 0. The MediaColor for tray 1 is unknown and therefore does not satisfy a request for a specific color. Now consider what happens during execution of << /PageSize [612 792] >> setpagedevice This request matches both tray 0 and tray 1 (again, assuming that non- null values for MediaColor , MediaType , or MediaWeight haven’t been inherited from the existing state of the device). In this situation, if a Priority entry exists in the InputAttributes dictionary, setpagedevice is not present, Priority consults it to determine which tray to select. If setpagedevice chooses one of the matching trays arbitrarily. The value of Priority is an array of integers. The first integer in the array represents the highest-priority media source; subsequent integers repre- sent media sources in decreasing priority. When a setpagedevice request matches two or more media sources, setpagedevice chooses the one whose number appears earliest in the Priority array. If none of the matching sources appears in the array, setpagedevice chooses among them arbitrarily. The effect of the InputAttributes definition given in the example above is that a document requesting a of MediaColor of white or a MediaType (or both) will be printed on paper from tray 0, but a document office not requesting either of those attributes will be printed on the less expensive paper from tray 1. Certain media are special-purpose, such as company letterhead or pre- printed forms. Such media should be selected only if a page description specifically requests all the attributes of the media. For example, com- pany letterhead should be selected only if a program requests company letterhead. If a program simply requests letter-size paper, it’s inappropri- to satisfy this request by selecting company letter- ate for setpagedevice head, even if company letterhead happens to be the only available media of the correct size. 242 Chapter 4: Graphics

251 PLRM 2nd Edition Graphics January 26, 1994 Suppose the available media consist of legal-size paper in tray 0 and company letterhead (letter-size) in tray 1. The diction- InputAttributes ary for the device might be something like this: << 0 << /PageSize [612 1008] >> 1 << /PageSize [612 792] /MediaType (letterhead) /MatchAll true >> >> MatchAll attribute in entry 1 indicates that media source 1 The special can satisfy only requests for all the source’s attributes. That is, << /PageSize [612 792] /MediaType (letterhead) >> setpagedevice will select media source 1, but << /PageSize [612 792] >> setpagedevice will not select media source. (Information in the Policies diction- either ary determines what to do when there is no match with any available media; see section 4.11.5, “Policies.”) The precise semantics of MatchAll are as follows. If MatchAll is present in an InputAttributes entry and its value is true , a setpagedevice request will match that entry only if it specifies matching (non-null) values for attribute MatchAll all the attributes present in the entry (except the itself). If MatchAll false or absent, a setpagedevice request will match is any subset the entry if it specifies of the entry’s attributes and leaves the others null (indicating “don’t care”). Note All implementations of setpagedevice support media selection by means of the PageSize , MediaColor , MediaWeight , and MediaType input attributes, whether or not the product can sense those media attributes automatically. In some products, other attributes also influence media selection. In such products, those attributes can appear in the InputAttributes dictionary as well. Managing InputAttributes and OutputAttributes The InputAttributes and OutputAttributes dictionaries are part of the state of the device and can be altered by executing setpagedevice . How- ever, a page description should never do this. These dictionaries are intended to describe the attributes of the available media sources and destinations. They should be changed only by a human operator or sys- tem management software in control of the physical device. 4.11 Device Setup 243

252 PLRM 2nd Edition Graphics January 26, 1994 Some products can sense the attributes of the available media sources and destinations automatically. For example, many printers can sense the size of paper installed in an input paper tray. Some printers can sense other attributes as well, usually by reading coded tags attached to the trays. When an implementation can sense media attributes, it automatically InputAttributes updates the contents of the OutputAttributes dic- and tionaries to reflect the physical state of the hardware. How and when this is done is product dependent, but the following conventions are typical. • At the beginning of a job (see section 3.7.7, “Job Execution Environ- ment”), the job server senses the attributes of all available media setpagedevice to update sources and destinations. It then executes the InputAttributes and OutputAttributes dictionaries. • Additionally, the job server selects a default media source and desti- nation. These defaults are used if a page description fails to specify its media requirements. (Non-null attributes of the default media will be inherited during a setpagedevice request that does not explicitly override those attributes.) How defaults are selected is product-dependent; a common method is to use the first element of array if one is present. Priority the • Execution of setpagedevice at other times may also result in and being updated to reflect the InputAttributes OutputAttributes Policies recovery state of the hardware. In particular, this occurs if a policy specifies interaction with a human operator and the operator installs different media (see section 4.11.5, “Policies”). It can occur at other times as well. Some products cannot sense media attributes automatically, or they can sense PageSize but not other attributes. For such products, explicit exe- cution of setpagedevice is required to update InputAttributes and OutputAttributes whenever media are changed. This is usually done by a system management program submitted by a human operator and executed as an unencapsulated job. Some products provide a “front panel” user interface to accomplish this. Changes to the contents of the InputAttributes and OutputAttributes dictionaries are cumulative. setpagedevice combines the key-value pairs supplied to it with those in the existing state of the device, replac- ing or adding entries as appropriate. However, this cumulative behavior does not extend to the contents of the sub-dictionaries that are the val- 244 Chapter 4: Graphics

253 PLRM 2nd Edition January 26, 1994 Graphics InputAttributes and . For ues of individual entries in OutputAttributes diction- InputAttributes example, suppose the contents of the device’s ary are as follows: << 0 << /PageSize [612 1008] >> 1 << /PageSize [612 792] /MediaType (letterhead) /MatchAll true >> >> If a program executes << /InputAttributes << 1 << /PageSize [612 792] >> /Priority [1 0] >> >> setpagedevice InputAttributes then the device’s dictionary becomes << 0 << /PageSize [612 1008] >> 1 << /PageSize [612 792] >> /Priority [1 0] >> In other words, entry 0 is left undisturbed, entry 1 is replaced by the setpagedevice one given to Priority entry is inserted. Note , and the new that the value of entry 1 is not merged but is simply replaced. Note has a null value instead of OutputAttributes If an entry in InputAttributes or a dictionary, it indicates an input or output position that is unavailable for use—for example, no paper tray is installed. If a single execution of setpagedevice includes changes to InputAttributes or OutputAttributes as well as requests for other features, the merging of these dictionaries occurs before processing of other features. 4.11.5 Policies When a page description makes a request that the device cannot satisfy, consults the setpagedevice dictionary to determine what to do. Policies Inability to satisfy a request arises in two situations. • The device does not support the requested feature at all—for exam- ple, duplex printing is requested but the device has no duplex capa- bility. The key Duplex is not defined in the device dictionary; the implementation has no idea what Duplex means. If a request includes an entry with the key Duplex , setpagedevice treats it as a . false request for an unknown feature—even if the requested value is 4.11 Device Setup 245

254 PLRM 2nd Edition Graphics January 26, 1994 • The device supports the requested feature but cannot achieve the requested value at the moment—for example, an A4-size page is requested when the A4 paper tray is not currently installed. Policies is a dictionary that is part of the state of the device. For most entries in this dictionary, the key is the name of a feature; the value is an integer code specifying a policy for handling unsatisfied requests for that feature. For most features, there are three policy choices: generate an error ( ), ignore the request, or interact with a configurationerror human operator. For PageSize requests, there are additional policy choices. Table 4.14 describes the entries that can appear in the Policies dictionary. Table 4.14 Entries in the Policies dictionary Key Semantics Type PolicyNotFound integer Specifies the policy to use when a requested feature (other than PageSize ) can- not be satisfied and the feature’s name is not present as a key in the Policies dic- tionary. The policy is an integer code with the following meanings. 0 Generate a configurationerror —that is, do not attempt recovery but simply abandon execution of setpagedevice , leaving the current device undis- is a standard PostScript language error, much configurationerror turbed. the same as undefined typecheck . Before generating the error, or inserts an entry into the $error dictionary. Error setpagedevice errorinfo errorinfo in particular are described in section handling in general and 3.10, “Errors.” 1 Ignore the feature request. This is the usual default policy in most prod- ucts. 2 Interact with a human operator or print manager to determine what to do. The semantics of this policy vary among different products and environ- ments. Some products issue a message (on a front panel, for instance) indi- cating an operator action that is required, then wait for confirmation. Other products have no ability to interact with an operator and generate a in this case. The details are product dependent. configurationerror any feature name integer Specifies the policy to use when a specific named feature (other than PageSize ) cannot be satisfied. The policy is an integer code whose meaning is as specified above for PolicyNotFound . Any key that can appear in a dictionary supplied to setpagedevice may also be used as a key in the Policies dictionary. This is not limited to keys recognized by the implementation but may include any key. That is, setpagedevice consults Policies the same way for an unknown feature as it does for a known feature whose requested value cannot be achieved. 246 Chapter 4: Graphics

255 PLRM 2nd Edition January 26, 1994 Graphics integer Specifies the recovery policy to use when the cannot be matched PageSize PageSize (within a tolerance of –5 units) with any available media. The policy is an inte- ger code with the following meanings. 0 , as described above for PolicyNotFound . This Generate a configurationerror is the usual default policy in most products. Ignore the requested PageSize . 1 Interact with a human operator or print manager, as described above for 2 . PolicyNotFound Select the nearest available medium and adjust the page to fit. This adjust- 3 ment is described below. 4 Select the next larger available medium and adjust the page to fit. 5 Select the nearest available medium but do not adjust the page. Select the next larger available medium but do not adjust the page. 6 procedure Called upon successful completion of setpagedevice if it needed to consult PolicyReport Policies in order to handle one or more unsatisfied feature requests. This proce- dure can report the actions that were taken or perform alternative actions. . {pop} PolicyReport is described below. The default value of PolicyReport is The dictionary is part of the state of the device and can be Policies altered by executing setpagedevice . Ordinarily, a page description com- posed by an application program should not do this; policies should be changed only by a human operator or by system management software in control of the physical device. However, if a user requests special pol- icies when submitting a print job, it’s appropriate for print manager software to insert a setpagedevice command to change Policies at the beginning of the page description. For example, the user might con- sider it essential that a particular job use certain features; if the features aren’t available, the job should be rejected instead of being executed with the feature requests ignored. Changes to the contents of the dictionary are cumulative. Policies setpagedevice combines the key-value pairs supplied to it with those in the existing state of the device, replacing or adding entries as appropri- ate. If a single invocation of setpagedevice includes changes to Policies as well as requests for other features, the merging of Policies entries occurs before the processing of other features. Thus, the revised Policies dictionary is consulted to determine policy if one of the other feature requests can’t be satisfied. For example, << /Duplex true /Policies << /Duplex 0 >> >> setpagedevice 4.11 Device Setup 247

256 PLRM 2nd Edition Graphics January 26, 1994 requests duplex printing and generates a configurationerror if the device doesn’t support duplex printing. Policies and Media Selection If a media request fails to match any of the available media sources or destinations described in InputAttributes or OutputAttributes , setpagedevice consults Policies in an attempt to make an alternative Media- media selection. For each relevant media request ( PageSize , MediaWeight , and MediaType for a source; OutputType for a , Color Policies is 1 destination), if the value of the corresponding entry in (ignore), setpagedevice replaces the media request with null . It then repeats the matching algorithm (steps 2 through 4 on page 240). Note Ignoring media requests cannot result in selection of a media source or attribute of true. destination that has a MatchAll If this second attempt at media selection succeeds, the resulting device dictionary contains values for all the media requests other than null PageSize that were ignored. If PageSize was ignored, the resulting device dictionary contains the PageSize of the media source that was actually selected. If the second attempt at media selection fails, the next action depends on whether any of the non-matching requests have a corresponding Policies entry of 2 (interact with a human operator or print manager). If so, setpagedevice performs such interaction, which may cause new or InputAttributes OutputAttributes media to be installed and to be updated. It then restarts the media selection process from the begin- Policies entry specifies user interaction or if user interaction ning. If no is not possible, setpagedevice terminates unsuccessfully and generates a configurationerror . For PageSize , there are additional policy choices that permit compro- mises to be made in matching the requested page size to the set of avail- able media. These include all four combinations of the following pair of choices: • Select an alternative medium that is either nearest in size or the next . larger size to the requested PageSize • Either adjust the page (by scaling and centering) to fit the alternative medium or perform no adjustment. 248 Chapter 4: Graphics

257 PLRM 2nd Edition Graphics January 26, 1994 The nearest size is the one closest in area to the requested size. The next larger size is the one that is at least as large as the requested size in both width and height and is smallest in area. If the policy is to select the next larger size but no larger size is available, the nearest size is used. Once an alternative medium has been selected, the adjustment option determines how the page image is to be placed on the medium—in other words, how the CTM defining the device’s default user space is to be computed. To the page means to scale the page image (if necessary) to fit the adjust medium, then center the image on the medium. In more detail, adjust- ment consists of the following two steps. 1. If the selected medium is smaller than the requested PageSize in either dimension, scale the page image to fit the medium in the most restrictive dimension. Scaling is the same in both dimensions so as to preserve the page’s aspect ratio (height to width). No scaling is performed if the selected medium is at least as large as the requested in both dimensions. PageSize 2. Center the page image on the medium along both dimensions. The effect of this adjustment is to set up a “virtual page” conforming to the requested (scaled down if necessary), centered on the PageSize physical medium. The origin of user space is the lower-left corner of the virtual page, not of the physical medium. The PageSize in the resulting device dictionary is the PageSize that was requested, not that of the physical medium. In the case where the page is not adjusted, the default user space is not scaled and is aligned with its origin at the lower-left corner of the medium. The effect is precisely as if the medium’s had been PageSize PageSize is smaller than the requested in the first place. If the actual requested one along either dimension, the page image will be clipped. The limited set of built-in policies for handing unsatisfied requests can be augmented by judicious use of the PolicyReport procedure in the Policies dictionary (described below). Additional adjustments to the procedure in the device CTM can be implemented as part of the Install dictionary. 4.11 Device Setup 249

258 PLRM 2nd Edition Graphics January 26, 1994 PolicyReport The dictionary contains an entry whose key is PolicyReport and Policies setpagedevice whose value is a procedure. Upon successful completion, PolicyReport procedure if it needed to consult Policies during calls the its execution to determine how to handle one or more unsatisfied requests. setpagedevice does not call PolicyReport if it was able to sat- isfy all requests without consulting or if it terminated unsuc- Policies cessfully with a configurationerror . Before calling PolicyReport , setpagedevice constructs a dictionary and pushes it on the operand stack. The dictionary contains one entry for each requested feature that was initially unsatisfied. The key is the name of the feature that was requested; the value is the integer policy code that was obtained from Policies . The PolicyReport procedure is expected to consume this dictionary from the stack. setpagedevice request includes: For example, suppose a • A request for that cannot be met, and the Policies entry for Duplex Duplex is 1 (ignore the request). •A PageSize request that doesn’t match any available media, and the Policies entry for PageSize is 5 (select the nearest available medium and don’t adjust). Then upon successful completion, setpagedevice calls the PolicyReport procedure with the operand stack containing: << /Duplex 1 /PageSize 5 >> setpagedevice At the time calls , it has completed setting PolicyReport up the new page device and installing it as the current device in the BeginPage procedure (see graphics state. It has also called the device’s section 4.11.6, “BeginPage and EndPage”). Thus, executing current- pagedevice within the PolicyReport procedure will return the newly installed device’s dictionary. It is permissible for the PolicyReport proce- dure to execute setpagedevice recursively. There are two main uses for a PolicyReport procedure. • It can transmit a notification to the human operator or print man- ager, warning that one or more requests were unsatisfied and that substitute actions have been taken. 250 Chapter 4: Graphics

259 PLRM 2nd Edition January 26, 1994 Graphics • It can inspect the resulting device dictionary and perhaps make addi- tional alterations. This provides additional flexibility when the stan- dard set of policy choices is found to be inadequate. 4.11.6 BeginPage and EndPage The and EndPage entries in the device dictionary are Post- BeginPage Script language procedures that are called each time showpage and are executed and also at certain other times. The interpreter copypage calls BeginPage before beginning to execute the description of each page and after execution of each page has finished. With suit- EndPage able definitions, these procedures can • Cause multiple virtual pages within a document to be printed on a single physical page (“2-up” or “ -up” printing). n • Shift the positions of even- and odd-page images differently for bind- ing. • Add marks to each page that either underlay or overprint the mate- rial provided by the page description. Use of BeginPage and EndPage to achieve effects spanning multiple pages Note sacrifices whatever page independence the document may have. In general, a EndPage or page description should not include definitions of BeginPage in its invocations of . Instead, a print manager should prepend setpagedevice such commands to the page description when printing is requested. The interpreter calls the current device’s BeginPage procedure at the beginning of executing each page. Precisely, • setpagedevice calls BeginPage as its last action before returning. (However, if it calls PolicyReport , it does so after calling BeginPage .) first This indicates the beginning of the page to be rendered on the device. showpage and copypage call BeginPage as their last action before • returning. This indicates the beginning of the next page, following the one that showpage or copypage has just ended. as • Operators that reactivate an existing page device call BeginPage their last action before returning. Device activation and deactivation are explained later. 4.11 Device Setup 251

260 PLRM 2nd Edition Graphics January 26, 1994 When BeginPage is called, the graphics state has been initialized and the current page erased, if appropriate, in preparation for beginning execution of the PostScript language commands describing a page. The operand stack contains an integer stating the number of executions of showpage (but not copypage ) that have occurred since the device was activated. That is, the operand is 0 at the first call to BeginPage , 1 at the call that occurs during the first showpage , and so on. The BeginPage procedure is expected to consume this operand. The procedure is per- mitted to alter the graphics state and to paint marks on the current page. EndPage procedure at the end The interpreter calls the current device’s of executing each page. Precisely, • showpage and copypage call EndPage as their first action. This indi- cates the end of the preceding page. • Operators that deactivate the device call EndPage as their first action. Device activation and deactivation are explained later. When EndPage is called, the PostScript language commands describing the preceding page have been completely executed, but the contents of raster memory have not yet been transferred to the medium and the graphics state is undisturbed. The operand stack contains two integers: • The number of executions of (but not copypage ) that showpage have occurred since the device was activated, not including this one. That is, the operand is 0 at the call to EndPage during the first showpage , 1 during the second showpage , and so on. • A code indicating the circumstance under which EndPage is being , 1 during called: 0 during showpage , 2 during device deac- copypage tivation (see below). EndPage procedure is expected to consume these operands. The The procedure is permitted to alter the graphics state and to paint marks on the current page; such marks are added to the page just completed. EndPage must return a boolean result specifying the disposition of the current page: • The value true means transfer the contents of raster memory to the medium. Then, if showpage is being executed, execute the equiva- lent of initgraphics and erasepage in preparation for the next page. .) copypage (The latter actions are not performed during 252 Chapter 4: Graphics

261 PLRM 2nd Edition Graphics January 26, 1994 false • The value means do not transfer the contents of raster memory to the medium or erase the current page. (If showpage is being exe- cuted, initgraphics is still performed.) EndPage The normal definition of true during showpage or returns copypage (code 0 or 1) but false during device deactivation (code 2). causes a physical page That is, normally every showpage and copypage to be produced, but an incomplete last page (not ended by or showpage copypage ) produces no output. Other behavior can be obtained by defining EndPage differently. The state of any device, including a page device, is represented as an internal object that is an element of the graphics state. Each execution of a device setup operator— setpagedevice , nulldevice , setcachedevice , and perhaps others in a Display PostScript system—creates a new instance of an internal device object (hereafter, simply “device”). Multi- ple devices can refer to the same physical resource, such as a print engine, perhaps with different values of device parameters such as or feature settings. PageSize Only one device is active at any given time, namely the current device in the graphics state. However, there can be multiple inactive devices , save that belong to copies of the graphics state that have been saved by gsave , or currentgstate . An inactive device can be reactivated when a restore , grestore , saved graphics state is reinstated by execution of or setgstate . When a device is reactivated, it brings its grestoreall device parameters with it. , setpagedevice is executed or when restore , grestore grestoreall When or setgstate different page causes a page device to be deactivated and a device to be activated, the interpreter EndPage procedure of the device that is being deactivated, 1. Calls the passing it a reason code of 2. At the time this call is made, the cur- rent device in the graphics state is still the old device. This enables any necessary cleanup actions to be performed, such as printing an incomplete “ n -up” page. 2. Performs any actions that the Jog , AdvanceMedia , and CutMedia entries indicate are to be done upon device deactivation. Also, if true Duplex is and the last sheet has been printed on only one side, the sheet is delivered at this time. 4.11 Device Setup 253

262 PLRM 2nd Edition Graphics January 26, 1994 3. Calls the BeginPage procedure of the device that is being activated. At the time this call is made, the current device in the graphics state is the new one. Its count of previous showpage executions is reset to zero. The above actions occur only when switching from a page device to a dif- ). ferent page device (however, setpagedevice always calls BeginPage They do not occur when switching to or from other kinds of devices, nulldevice and setcachedevice operators. such as the ones set up by the Usually, those devices are installed temporarily. For example, setcachedevice and the operations for rendering a character into the font cache are bracketed by gsave and grestore , thereby reinstating the page device that was previously in effect. The page device’s BeginPage and EndPage procedures are not called in such cases and the current page is not erased or otherwise disturbed. A few examples illustrate this distinction. Example 4.24 switches between two page devices. All of the activations and deactivations cause the devices’ and EndPage procedures to be called, as BeginPage described above. Example 4.24 dict1 setpagedevice % BeginPage for device 1 gsave dict2 setpagedevice % EndPage for device 1, BeginPage for device 2 grestore % EndPage for device 2, BeginPage for device 1 In Example 4.25, on the other hand, temporary activation of the null device does not cause the page device’s EndPage procedure to be called, nor does reactivation of the page device cause its BeginPage procedure to be called. In fact, the state of the page device is not disturbed in any way, since the null device is not a page device. Example 4.25 dict3 setpagedevice % BeginPage for device 3 gsave nulldevice grestore It is possible to switch devices in an order that prevents a page device’s EndPage procedure from ever being called. Example 4.26 switches from a page device to a null device without saving a graphics state that refers to the page device. Thus, there is no possibility of reactivating the page device in order to call its EndPage procedure. This sequence of opera- not recommended . tions is 254 Chapter 4: Graphics

263 PLRM 2nd Edition January 26, 1994 Graphics Example 4.26 gsave dict4 setpagedevice % BeginPage for device 4 nulldevice grestore Example 4.27 shows the skeleton structure of a simple two-page document. For completeness, it includes the recommended document structuring conventions, which are explained in Appendix G. The com- ments to the right indicate the points at which the interpreter calls and BeginPage EndPage and the arguments it passes to each. Example 4.27 %!PS-Adobe-3.0 ..Document prolog... . %%BeginSetup %%BeginFeature: *Duplex % 0 BeginPage << /Duplex true >> setpagedevice %%EndFeature %%BeginFeature: *PageSize Letter << /PageSize [612 792] /ImagingBBox null >> setpagedevice % 0 2 EndPage 0 BeginPage %%EndFeature %%EndSetup %%Page: 1 1 save ...PostScript language description for page 1... restore showpage % 0 0 EndPage 1 BeginPage %%Page: 2 2 save ...PostScript language description for page 2... restore showpage % 1 0 EndPage 2 BeginPage %%EOF ...Job server executes restore, which deactivates the page device... % 2 2 EndPage 4.11 Device Setup 255

264 PLRM 2nd Edition January 26, 1994 Graphics 256 Chapter 4: Graphics

265 PLRM 2nd Edition January 21, 1994 Fonts Example 1.0 Example 2.0 Example 3.0 Example 4.0 Example 5.0 Example 5.0 Table 5.0 Example 6.0 5 CHAPTER Figure 5.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Fonts This chapter describes the special facilities in the PostScript language characters fonts . A from for dealing with text—more generally, with character is a general graphical shape and is subject to all graphical manipulations, such as coordinate transformation. Because of the importance of text in most page descriptions, the PostScript language provides higher-level facilities that permit a program to describe, select, and render characters conveniently and efficiently. The first section is a general description of how fonts are organized and accessed. This description covers all normal uses of fonts that are already installed. The information in subsequent sections is somewhat more complex, but it is required only by programs with sophisticated needs. It dis- cusses the organization of font dictionaries, the encoding scheme that maps character codes to character names and descriptions, the metric information available for fonts, and the operation of the font cache. Finally, it describes how to construct new base and composite fonts. Details of the individual PostScript operators are given in Chapter 8. All facilities are supported by Level 1 implementations except for the ones specifically documented as Level 2 features. Some of the Level 2 features are also available as part of composite font or Display PostScript extensions; for details, consult Appendix A. 5.1 Organization and Use of Fonts A font for use with the Post- Sets of characters are organized into fonts. Script interpreter is prepared in the form of a program. When such a is introduced into a PostScript interpreter, its execution font program causes a font dictionary to come into existence and to be associated with a font name. 257

266 PLRM 2nd Edition January 21, 1994 Fonts In the PostScript language, the term font refers to a font dictionary, through which the PostScript interpreter obtains definitions that gener- ate character shapes. The interpreter uses a character’s code to select the is a pro- definition that represents the character. A character’s definition cedure that executes graphics operations to produce the character’s shape. The procedure is usually encoded in a special compact represen- tation. To render a character, the PostScript interpreter executes this procedure. If you have experience with scan conversion of general shapes, you may be concerned about the amount of computation that this description seems to imply. However, this is only the abstract behavior of character shapes and font programs, not how they are implemented. In fact, the PostScript font machinery works very efficiently. Basic Text Setting 5.1.1 Example 5.1 illustrates the most straightforward use of a font. Suppose ABC , 10 inches from the bottom of the page you wish to place the text and 4 inches from the left edge, using 12-point Helvetica. Example 5.1 /Helvetica findfont 12 scalefont setfont 288 720 moveto (ABC) show The four lines of this program perform the following steps: 1. Select the font to use. 2. Scale it to the desired size and install it as the current font in the graphics state. 3. Specify a starting position on the page. 4. Paint a string of characters there. The following paragraphs explain these operations in more detail. Each PostScript implementation includes a collection of fonts that are either built-in or can be obtained automatically from sources such as disks or cartridges. A user can download additional fonts, and a Post- Script language program can define special fonts for its own use. The font directory associating the names of fonts, interpreter maintains a 258 Chapter 5: Fonts

267 PLRM 2nd Edition Fonts January 21, 1994 which are name objects, with their definitions, which are font diction- aries. The operator takes the name of the font and returns on findfont the operand stack a font dictionary containing all information the Post- Script interpreter needs to render any of that font’s characters. A font specifies the shapes of its characters for one standard size. This standard is so arranged that the nominal height of tightly-spaced lines of text is 1 unit. In the default user coordinate system, this means the standard character size is one unit in user space, or 1/72 of an inch. The standard size font must then be scaled to be usable. The scalefont operator scales the characters in a font without affecting the user coordinate system. takes two operands: the original scalefont font dictionary and the desired scale factor. It returns a new font dic- tionary that renders character shapes in the desired size. It is possible to scale the user coordinate system with the coordinate system operators, but it is usually more convenient to encapsulate the desired size in the font dictionary. Another operator, makefont , applies more complicated linear transformations to a font. In Example 5.1, the scalefont operator scales the Helvetica font left on to a 12-unit size and returns the scaled font on the findfont the stack by operand stack. The operator establishes the resulting font dic- setfont tionary as the current font in the graphics state. Once the font has been selected, scaled, and set, it can be used to paint characters. The moveto operator (described in section 4.4, “Path Con- struction”) sets the current position to the specified x and y coordi- nates—in units of 1/72 inch—in the default user coordinate system. This determines the position on the page at which to begin painting characters. The show operator takes a string from the operand stack and renders it using the current font. The show operator treats each element of the string (an integer in the range 0 to 255) as a character code. Each code selects a character description in the font dictionary; the character description is executed to paint the desired character on the page. This for base fonts, such as ordinary Roman text is the behavior of show fonts. Its behavior is more complex for composite fonts, described in section 5.9, “Composite Fonts.” 5.1 Organization and Use of Fonts 259

268 PLRM 2nd Edition January 21, 1994 Fonts Note What these steps produce on the page is not a 12-point character, but rather a 12-unit character, where the unit size is that of the user space at the time the characters are rendered on the page. If the user space is later scaled to make the unit size one centimeter, showing characters from the same 12-unit font will generate results that are 12 centimeters high. 5.1.2 Selecting Fonts Example 5.1 used PostScript operators in a direct way. It is usually desir- able to define procedures to help the application that is generating the text. To illustrate this point, assume that an application is setting many independently positioned text strings and requires switching frequently among three fonts: Helvetica, Helvetica-Oblique, and Helvetica-Bold, all in a 10-point size. Example 5.2 shows the programming to do this. Example 5.2 /FSD {findfont exch scalefont def} bind def % In the document prolog: define /SMS {setfont moveto show} bind def % some useful procedures /MS {moveto show} bind def /F1 10 /Helvetica FSD % At the start of the script: set up /F2 10 /Helvetica-Oblique FSD % commonly used font dictionaries /F3 10 /Helvetica-Bold FSD (This is in Helvetica.) 10 78 F1 SMS % In the body of the script: show (And more in Helvetica.) 10 66 MS % some text (This is in Helvetica-Oblique.) 10 54 F2 SMS (This is in Helvetica-Bold.) 10 42 F3 SMS (And more Helvetica-Bold.) 10 30 MS Figure 5.1 Results of Example 5.2 This is in Helvetica. And more in Helvetica. This is in Helvetica-Oblique. This is in Helvetica-Bold. And more Helvetica-Bold. There are several features of Example 5.2 that are noteworthy. The document prolog defines three procedures: 260 Chapter 5: Fonts

269 PLRM 2nd Edition January 21, 1994 Fonts FSD takes a variable name, a scale factor, and a font name. It gener- • ates a font dictionary described by the font name and scale factor, def to associate the font dictionary with the variable then executes name. This assists in setting up fonts. takes a string, a pair of coordinates, and a font dictionary; it • SMS shows the string starting at those coordinates, using the specified font. • MS takes a string and a pair of coordinates. It shows the string at those coordinates, using the current font. At the beginning of the document script, the program sets up font dic- tionaries and associates them with the names , F2 , and F3 . The body F1 of the script sets text using the procedures and font dictionaries defined earlier. This example avoids switching fonts when it’s unnecessary to do so; taking care in this respect is important for efficient execution. Many applications must switch frequently among arbitrarily named fonts, where the names and sizes are not known in advance. To facili- tate this, the Level 2 operator selectfont combines the actions of the selectfont operators. findfont , scalefont (or makefont ), and setfont saves information from one call to the next to avoid calling findfont or scalefont makefont computations unnecessarily. In performing the or the common case of selecting a font and size combination that has selectfont works with great efficiency. been used recently, 5.1.3 Achieving Special Graphical Effects Normal uses of show and other character painting operators cause black-filled characters to be painted. By combining font operators with general graphics operators, one can obtain other effects. The color used for painting characters is determined by the current color in the graphics state. The default color is black, but other colors may be obtained by executing setgray or some other color-setting oper- ator before painting characters. Example 5.3 paints characters in 50 per- cent gray. Example 5.3 /Helvetica-Bold findfont 48 scalefont setfont 20 40 moveto .5 setgray (ABC) show 5.1 Organization and Use of Fonts 261

270 PLRM 2nd Edition Fonts January 21, 1994 Characters painted in 50 percent gray Figure 5.2 ABC More general graphical manipulations can be performed by treating the charpath character outline as a path instead of immediately painting it. is a path construction operator that appends the outlines of one or more characters to the current path in the graphics state. This is useful mainly with characters that are defined as outlines (as all Type 1 fonts are). Paths derived from characters defined as strokes can be used in limited ways. It is not possible to obtain paths for characters defined as images or bitmaps; charpath produces an empty path. Also, a path consisting of the outlines of more than a few characters is likely to exceed the limit on number of path elements (see Appendix B). If possi- ble, it is best to deal with only one character’s path at a time. Example 5.4 uses character outlines as a path to be stroked. This pro- to obtain the outlines for the string of characters gram uses charpath ABC false operand to charpath is explained in in the current font. The the description of charpath in Chapter 8. The program then strokes this path with a line 2 points thick, rendering the characters’ outlines on the page. Example 5.4 /Helvetica findfont 48 scalefont setfont 20 38 moveto (ABC) false charpath 2 setlinewidth stroke 262 Chapter 5: Fonts

271 PLRM 2nd Edition Fonts January 21, 1994 Character outlines treated as a path Figure 5.3 ABC Example 5.5 obtains the characters’ path as before, then establishes it as the current clipping path. All subsequent painting operations will mark the page only within this path. This state persists until some other clip- ping path is established—for example, by the grestore operator. Example 5.5 /Helvetica findfont 48 scalefont setfont newpath 20 40 moveto (ABC) false charpath clip ...Graphics operators to draw a starburst... Graphics clipped by a character path Figure 5.4 Character Positioning 5.1.4 is the amount of space the character occupies along A character’s width the baseline of a line of text. In other words, it is the distance the cur- rent point moves when the character is shown. Note that the width is distinct from the dimensions of the character outline (see section 5.4, “Font Metric Information”). 5.1 Organization and Use of Fonts 263

272 PLRM 2nd Edition Fonts January 21, 1994 In some fonts, the width is constant; it does not vary from character to character. Such fonts are called fixed-pitch or monospaced . They are used mainly for typewriter-style printing. However, most fonts used for high- quality typography associate a different width with each character. Such fonts are called proportional fonts or variable-pitch fonts. In either case, the show operator positions consecutive characters of a string according to their widths. The width information for each character is stored in the font diction- ary. A PostScript language program can use any of several character , show , xshow , yshow , xyshow painting operators— widthshow , ashow , awidthshow —to obtain a variety of width modification effects. If neces- sary, it can execute stringwidth to obtain the width information itself. and its variants) are The standard operators for setting text ( show designed on the assumption that characters are ordinarily shown with their standard metrics. (See section 5.4, “Font Metric Information”). However, means are provided to vary the metrics in certain limited ways. For example, the ashow operator systematically adjusts the widths of all characters of a string during one show operation. The optional Metrics entry of a font dictionary can be added to adjust the widths of all instances of particular characters of a font. Certain applications that set text require very precise control of the positioning of each character. There are three Level 2 operators to streamline the setting of individually positioned characters: xyshow , xshow , and yshow . Each operator is given a string of text to be shown, the same as . Also, it expects a second operand, which is either an show array of numbers or a string that can be interpreted as an encoded num- ber string as described in section 3.12.5, “Encoded Number Strings.” The numbers are used in sequence to control the widths of the charac- ters being shown. They completely override the standard widths of the char- acters. The kshow and cshow operators provide ways for an arbitrary PostScript language procedure to intervene in the positioning and painting of each character in a string. cshow is a Level 2 operator. These are the most general but least efficient text setting operations. 5.2 Font Dictionaries Font dictionaries are ordinary dictionary objects, but with certain spe- cial key-value pairs. The PostScript language has several operators that deal with font dictionaries (see Chapter 8). Some of the contents of a 264 Chapter 5: Fonts

273 PLRM 2nd Edition January 21, 1994 Fonts font dictionary are optional and user-definable, while other key-value pairs must be present and have the correct semantics for the PostScript interpreter’s font machinery to operate properly. FontType There are several kinds of fonts, each distinguished by the entry in the font dictionary. Each type of font has its own conventions for organizing and representing the information within it. The font types defined at present are: • Type 0 is a base fonts , composite font composed of other fonts called organized hierarchically. Composite fonts are a Level 2 feature. See section 5.9, “Composite Fonts.” • Type 1 is a base font that defines character shapes by using specially encoded procedures. That encoded format is described in a separate Adobe Type 1 Font Format book, . • Type 3 is a user-defined base font that defines character shapes as ordi- nary PostScript language procedures, which are the values of entries named or BuildChar in the font dictionary. See section BuildGlyph 5.7, “Type 3 Fonts.” A PostScript language program creates a font dictionary by ordinary ), then makes it def means (operators such as dict , begin , end , and known to the interpreter by executing the operator. definefont definefont takes a name and a dictionary, checks that the dictionary is a well-formed font dictionary, makes the dictionary’s access read-only, and associates the font name with the dictionary in the font directory. It also inserts into the font dictionary an additional entry whose name is FID and whose value is an object of type fontID. This entry serves internal purposes in the font machinery. For this reason, a font diction- ary presented to definefont must have room for at least one additional key-value pair. The Level 2 operator undefinefont removes a named font from the font directory. A font dictionary that has been removed in this fashion is still a valid font assuming it is still accessible, but it can no longer be returned by findfont . named In Level 2 implementations, fonts are actually a special case of resources : A font is an instance of the Font resource category. A font dic- tionary can reside in either local or global VM. See section 3.9, “Named operator for com- Resources,” and the description of the defineresource plete information on how resource instances are named and are loaded into VM. 5.2 Font Dictionaries 265

274 PLRM 2nd Edition January 21, 1994 Fonts Table 5.1 lists the key-value pairs that have defined meanings in the font dictionaries of additional key-value all types of fonts. Table 5.2 lists fonts (types 1 and 3). Table 5.3 lists base pairs that are meaningful in all key-value pairs that are meaningful only in Type 1 fonts. Any additional font dictionary can have additional entries containing information that is useful to PostScript language procedures that are part of the font’s definition. The interpreter pays no attention to those entries. Table 5.1 Entries in all types of font dictionaries Semantics Key Type FontType integer ( Required ) Indicates where the information for the character descriptions is to be found and how it is represented. array ( FontMatrix ) Transforms the character coordinate system into the user coordinate sys- Required tem (see section 5.4, “Font Metric Information”). For example, Type 1 font pro- grams from Adobe are usually defined in terms of a 1000-unit character coordinate system, and their initial is [0.001 0 0 0.001 0 0]. When a FontMatrix font is derived by the scalefont or makefont operator, the new matrix is concate- FontMatrix to yield a new copy of the font with a different nated with the . FontMatrix FontName name ( Optional ) The font’s name. This entry is for information only; it is not used by the PostScript interpreter. Ordinarily, it is the same as the key passed to definefont , but it is not required to be the same. Optional dictionary FontInfo ) See Table 5.4 on page 268 for the entries that can be in this dictionary. ( LanguageLevel integer ) Minimum language level required for correct behavior of the font. ( Optional Any font that uses Level 2 features for rendering characters (for example, a char- rectfill or acter definition uses ) should specify a LanguageLevel of 2. glyphshow On the other hand, presence of Level 2 information that a Level 1 interpreter XUID entry in the font dictionary) does not can safely ignore (for example, an LanguageLevel of 2. Default value: 1. require a WMode integer Optional ) Indicates which of two sets of metrics will be used when characters are ( shown from the font. Level 1 implementations lacking composite font extensions ignore this entry. Default value: 0. Table 5.2 FontType not 0) Additional entries in all base fonts ( Key Type Semantics Encoding array ( Required ) Array of names that maps character codes (integers) to character names—the values in the array. This is described in section 5.3, “Character Encoding.” FontBBox array ( Required ) Array of four numbers in the character coordinate system giving y lower-left x , lower-left y , upper-right x , and upper-right of the font bounding box. The font bounding box is the smallest rectangle enclosing the shape that 266 Chapter 5: Fonts

275 PLRM 2nd Edition January 21, 1994 Fonts would result if all of the characters of the font were placed with their origins coincident, and then painted. This information is used in making decisions about character caching and clipping. If all four values are zero, the PostScript interpreter makes no assumptions based on the font bounding box. If any value is non-zero, it is essential that the font bounding box be accurate; if any character’s marks fall outside this bounding box, incorrect behavior may FontBBox must be accurate (not all zeros) if the font result. For a Type 1 font, the command for creating accented characters. See Adobe Type 1 Font uses the seac for more information. Format In many type 1 fonts, the FontBBox array is executable, though there is no good reason for this to be so. Programs that access the FontBBox should execute an get explicit load to avoid unintended execution. or 24 ( Optional ) Integer in the range 0 to 16777215 (2 UniqueID integer – 1) that uniquely identifies this font. See section 5.8, “Unique ID Generation.” array ( Optional ) Array of integers that uniquely identifies this font or any variant of it. XUID See section 5.8, “Unique ID Generation.” Level 1 implementations ignore this entry. Table 5.3 Additional entries specific to Type 1 fonts Key Type Semantics PaintType ) A code indicating how the characters of the font are to be painted. Required integer ( 0 The character outlines are filled. The character outlines (designed to be filled) are stroked. 2 Type 1 fonts are ordinarily created with a PaintType of 0. A program desiring to convert it to a stroked outline font can copy the font dictionary, change the from 0 to 2, add a StrokeWidth entry, and define a new font using this PaintType PaintType values of 1 and 3 are dictionary. Note that the previously documented not supported. ) Stroke width (in units of the number ( Optional coordinate system) for character StrokeWidth stroked outlined fonts ( 2). This field is not initially present in filled font PaintType descriptions. It must be added when creating a stroked font from an existing filled font. Default value: 0. Metrics dictionary ( Optional ) Width and sidebearing information for writing mode 0. This entry is not normally present in the original definition of a font. Adding a Metrics entry to a font overrides the widths and sidebearings encoded in the character descrip- tions. See sections 5.4, “Font Metric Information,” and 5.6.2, “Changing Charac- ter Metrics.” ) Dictionary containing metric information for writing mode 1 (see sec- Metrics2 dictionary ( Optional tion 5.6.2, “Changing Character Metrics”). Level 1 implementations lacking composite font extensions ignore this entry. 5.2 Font Dictionaries 267

276 PLRM 2nd Edition Fonts January 21, 1994 procedure Optional ) Procedure that algorithmically derives global changes to a font’s met- CDevProc ( rics. Level 1 implementations lacking composite font extensions ignore this entry. dictionary CharStrings Required ) Associates character names (keys) with shape descriptions. Each ( entry’s value is ordinarily a string that represents the character’s description in a special encoded format; see Adobe Type 1 Font Format for details. The value can also be a PostScript language procedure; see section 5.6.3, “Replacing or Adding Individual Characters.” Private ( Required ) Contains other internal information about the font. See Adobe Type 1 dictionary Font Format for details. Any font dictionary can contain a FontInfo entry whose value is a dic- tionary containing the information listed in Table 5.4. This information is entirely for the benefit of PostScript language programs using the font, or for documentation. It is not accessed by the PostScript interpreter. Table 5.4 Entries in a FontInfo dictionary Semantics Type Key FamilyName Human-readable name for a group of fonts that are stylistic variants of a single string design. All fonts that are members of such a group should have exactly the same FamilyName . FullName string Unique, human-readable name for an individual font. string Trademark or copyright notice, if applicable. Notice string Human-readable name for the weight, or “boldness,” attribute of a font. Weight version string Version number of the font program. number Angle in degrees counterclockwise from the vertical of the dominant vertical ItalicAngle strokes of the font. boolean If true , indicates that the font is a fixed-pitch (monospaced) font. isFixedPitch UnderlinePosition number Recommended distance from the baseline for positioning underlining strokes. This number is the y coordinate (in character space) of the center of the stroke. UnderlineThickness number Recommended stroke width for underlining, in units of the character coordinate system. The PostScript language does not specify any formal rules for the names dictionary. However, there are of fonts or for the entries in the FontInfo various conventions for organizing fonts that facilitate their use by application programs. 268 Chapter 5: Fonts

277 PLRM 2nd Edition Fonts January 21, 1994 FamilyName • Some applications use as part of a hierarchical font- selection user interface. This divides a very large set of individual fonts into a smaller, more manageable set of “font families.” The FamilyName parameter should be suitable for use in a font selection menu. • Typically, begins with FamilyName and continues with FullName various style descriptors separated by spaces—for example, Adobe Garamond Bold Italic . In some designs, a numbering system replaces or augments verbal descriptors—for example, Univers 55 Medium . • is derived from the FullName parameter by dropping every- Weight thing from the FullName that does not explicitly relate to weight. For example, the FullName ITC Franklin Gothic Condensed Extra Bold Oblique reduces to a Weight of Extra Bold . • The font dictionary’s FontName parameter, which is also usually , is a condensation of the definefont used as the key passed to . It is customary to remove spaces and to limit its length to FullName less than 40 characters. The resulting name should be unique. 5.3 Character Encoding encoding scheme by which character Font definitions use a flexible codes select character descriptions. The association between character codes and descriptions is not part of the character descriptions them- encoding vector selves, but instead is described by a separate . A PostScript language program can change a font’s encoding vector to match the requirements of the application generating the description. This section describes the character encoding scheme used with most base fonts. Composite fonts ( FontType 0) use a more complicated char- acter mapping algorithm, defined in section 5.9, “Composite Fonts.” Note Use of this encoding scheme is required for Type 1 fonts and is strongly Encoding recommended for Type 3 fonts. Every base font must have an entry. A Type 3 font’s procedure should use it in the standard way. BuildChar In a font dictionary, the descriptions of the individual characters are keyed by character names , not by character codes . Character names are ordinary PostScript language name objects. Descriptions of Roman alphabetic characters are normally associated with names consisting of single letters, such as A or a . Other characters are associated with names parenleft . composed of words, such as three , ampersand , or 5.3 Character Encoding 269

278 PLRM 2nd Edition Fonts January 21, 1994 The encoding vector is defined by the array object that is the value of Encoding in the font dictionary. The array is indexed by character code (an integer in the range 0 to 255). The elements of the array must be character names, and the array should be 256 elements long. The operand to the operator is a PostScript language string object. show Each element of the string is treated as a character code. When show paints a character: 1. It uses the character code as an index into the current font’s Encoding array to obtain a character name. 2. It invokes the character description by name. For a Type 1 font, it looks up the name in the font’s CharStrings dictionary to obtain an encoded character description, which it executes. For a Type 3 font, it calls the font’s BuildGlyph procedure (if present) with the name as operand. See section 5.7, “Type 3 Fonts.” For example, in the standard encoding vector used by Type 1 Roman text fonts such as Helvetica, the element at index 38 is the name object show encounters the value 38 (the ASCII character ampersand . When code for ) as an element of a string it is printing, it fetches the & encoding vector entry at index 38, obtaining the name object ampersand . It then uses ampersand as a key in the current font dictio- nary’s CharStrings subdictionary and executes the associated descrip- tion that renders the & letterform. Changing an existing font’s encoding involves creating a new font dic- tionary that is a copy of the existing one except for its entry. Encoding The subsidiary dictionaries, such as and FontInfo , continue CharStrings to be shared with the original font. Of course, a new font may be cre- ated with any desired encoding vector. This flexibility in character encoding is valuable for two reasons: • It permits printing text encoded by methods other than ASCII (EBCDIC, for example). • It allows applications to specify how characters outside a standard character set are to be encoded. Some fonts contain more than 256 characters, including ligatures, accented characters, and other sym- bols required for high-quality typography or non-Roman languages. 270 Chapter 5: Fonts

279 PLRM 2nd Edition Fonts January 21, 1994 Roman text font programs produced by Adobe Systems use the “Adobe standard” encoding vector, which is associated with the name in systemdict . An alternate encoding vector called StandardEncoding ISO Latin-1 is associated with the name . Complete ISOLatin1Encoding details of these encodings and of the characters present in typical fonts appear in Appendix E. All unused positions in an encoding vector must be filled with the name .notdef . The name .notdef is defined in CharStrings , just as is any other character. It is special in only one regard: If some encoding maps to a character name that does not exist in the font, .notdef is substi- tuted. Every font must contain a definition of the .notdef character. The .notdef character is at the discretion of effect produced by showing the the font designer. In Adobe Type 1 font programs, it is the same as the space character. The glyphshow operator, a Level 2 feature, shows a single character selected by name instead of by character code. This enables direct use of any character in the font regardless of the font’s Encoding . The princi- pal use of glyphshow is defining fonts whose character descriptions refer to other characters in the same or a different font. Referring to those characters by name ensures proper behavior if the font is subse- quently re-encoded. 5.4 Font Metric Information The is the space in which an individual char- character coordinate system acter shape is defined. All path coordinates and metrics are interpreted in character space. Figure 5.5 shows a typical character outline and its metrics. Figure 5.5 Character metrics bounding box next character character origin origin left side bearing character width 5.4 Font Metric Information 271

280 PLRM 2nd Edition Fonts January 21, 1994 origin reference point , of the character is the point (0, 0) in the The , or character coordinate system. and other character painting opera- show tors position the origin of the first character to be shown at the current point in user space. For example, 40 50 moveto (ABC) show places the origin of the A at coordinate (40, 50) in the user coordinate system. width of a character is the distance from the character’s origin to The the point at which the origin of the next character should normally be placed when painting the consecutive characters of a word. This dis- tance is a vector in the character coordinate system; it has x and y com- ponents. Most Indo-European alphabets, including Roman, have a x width. Semitic alphabets have a negative positive x width and a zero y width. Some Asian glyphs have a non-zero width. y The bounding box of a character is the smallest rectangle (oriented with the character coordinate system axes) that will just enclose the entire character shape. The bounding box is expressed in terms of its lower- left corner and upper-right corner relative to the character origin in the character coordinate system. The left sidebearing of a character is the position of the left sidebearing point in character space; this is usually the intersection of the left edge of the bounding box with the character’s baseline (see Adobe Type 1 Font Format x coordinate of the left sidebearing can be nega- ). Note that the tive for characters that extend to the left of their origin. The y coordi- nate is almost always 0. Type 1 fonts are defined in such a way that a character’s left sidebearing and width can be adjusted; that is, the character bounding box and the position of the next character can be shifted around relative to the ori- gin (see section 5.6, “Modifications to Existing Fonts”). In some writing systems, text is frequently aligned in two different directions. For example, it is common to write Japanese and Chinese characters either horizontally or vertically. To handle this, a font can optionally contain a second set of metrics for each character. This fea- ture is available only in Level 2 or in Level 1 implementations with composite font extensions. 272 Chapter 5: Fonts

281 PLRM 2nd Edition January 21, 1994 Fonts The metrics are accessed by and other operators according to a show writing mode, given by a WMode entry in the font dictionary or in some parent font dictionary in a composite font. By convention, writ- ing mode 0 (the default) specifies horizontal writing; mode 1 specifies WMode vertical writing. If a font contains only one set of metrics, the parameter is ignored. When a character has two sets of metrics, each set specifies a character origin and a width vector. Figure 5.6 illustrates the relationship between the two sets of metrics. Figure 5.6 Relationship between two sets of metrics ur origin 1 origin 1 v w0 origin 0 origin 0 w1 ll new current new current point point Writing mode 1 Mode 1 relative to mode 0 Writing mode 0 The left diagram illustrates the character metrics associated with writing ur specify the bounding box of the char- and ll mode 0. The coordinates acter relative to origin 0. w0 is the character width vector that specifies how the current point is changed after the character is shown in writ- ing mode 0. The center diagram illustrates writing mode 1; w1 is the character width vector for writing mode 1. In the right diagram, v is a vector defining the position of origin 1 relative to origin 0. Character metric information can be accessed procedurally by a Post- operator obtains character Script language program. The stringwidth widths. The sequence charpath flattenpath pathbbox computes character bounding boxes, though this is relatively ineffi- cient. The bounding box for an entire font appears in the font diction- . FontBBox ary as an array of four numbers associated with the key 273 5.4 Font Metric Information

282 PLRM 2nd Edition January 21, 1994 Fonts Character metric information is also available separately in the form of Adobe font metrics (AFM) and Adobe composite font metrics (ACFM) files . These files are for use by application programs that generate Post- Script language page descriptions and must make formatting decisions based on the widths and other metrics of characters. Kerning informa- tion is also available in the AFM and ACFM files. When possible, appli- cations should use this information directly instead of generating PostScript language instructions to compute it. Specifications for the AFM and ACFM file formats are available from the Adobe Systems Developers’ Association. 5.5 Font Cache The PostScript interpreter includes an internal data structure called the font cache whose purpose is to make the process of painting characters very efficient. For the most part, font cache operation is automatic. However, there are several operators that control the behavior of the font cache. Also, font definitions must adhere to certain conventions to take advantage of the font cache. Rendering a character from an outline or other high-level description is a relatively costly operation, because it involves performing scan con- version of arbitrary shapes. This presents special problems for printing text, because it is common for several thousand characters to appear on a single page. However, a page description that includes large amounts of text normally has many repetitions of the same character in a given font, size, and orientation. The number of distinct characters thus is very much smaller than the total number of characters. The font cache operates by saving the results of character scan conver- sions (including metric information and device pixel arrays) in tempo- rary storage and using those saved results when the same character is requested again. The font cache is usually large enough to accommo- date all of the distinct characters in a page description. Painting a char- acter that is already in the font cache is typically hundreds of times faster than scan converting it from the character description in the font. The font cache does not retain color information; it remembers only which pixels were painted and which pixels were left unchanged within the character’s bounding box. For this reason, there are a few restric- tions on the set of graphical operators that may be executed as part of image character descriptions that are to be cached. In particular, the 274 Chapter 5: Fonts

283 PLRM 2nd Edition January 21, 1994 Fonts imagemask operator is not permitted. However, may be used to define a character according to a bitmap representation; see section 4.10, “Images.” Execution of operators that specify colors or other color- related parameters in the graphics state is also not permitted; see sec- tion 4.8, “Color Spaces.” The principal manifestation of the font cache visible to the PostScript language program is that showing a character does not necessarily result in the character’s description being executed. This means that font definitions must interact with the font cache machinery so the results of their execution are properly saved. This is done by means of the setcachedevice or setcachedevice2 operators, described in section 5.7, “Type 3 Fonts.” 5.6 Modifications to Existing Fonts FontType , whose This section applies to base fonts is any value other than 0. Composite fonts are described in section 5.9, “Composite Fonts.” A PostScript language program can create a font in two ways: by copy- ing an existing font and modifying certain things in it, or by defining a new font from scratch. The programming examples given in this and the next section are compatible with Level 1 implementations. They can be significantly simplified by taking advantage of Level 2 features. Of course, doing so sacrifices Level 1 compatibility. 5.6.1 Changing the Encoding Vector The most common modification to an existing font is installing a dif- ferent encoding vector, discussed in section 5.3, “Character Encoding.” Example 5.6 creates a copy of the Helvetica font in which the Adobe standard encoding for the Helvetica font is replaced by the ISO Latin-1 encoding, described in Appendix E. Example 5.6 /Helvetica findfont dup length dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /Encoding ISOLatin1Encoding def currentdict end /Helvetica-ISOLatin1 exch definefont pop 5.6 Modifications to Existing Fonts 275

284 PLRM 2nd Edition Fonts January 21, 1994 This program performs the following steps: 1. Make a copy of the font dictionary including all entries, except the one whose name is FID . 2. Install the desired changes. This program replaces the font’s Encoding with the value of ISOLatin1Encoding , which is a built-in, 256-element array of character names defined in systemdict . 3. Register this modified font under some new name—for example, . Helvetica-ISOLatin1 In Type 1 fonts, some accented characters are produced by combining two or more other characters (for example, a letter and an accent) defined in the same font. In Level 1 implementations, if an encoding vector includes the name of an accented character, it must also include the names of the components of that character. Note If you create a new encoding for a Type 1 font, Adobe suggests that you place the accents in control character positions, which are typically unused. The built-in ISOLatin1Encoding uses this technique. 5.6.2 Changing Character Metrics Metrics entry to the font dic- To change a Type 1 font’s metrics, add a tionary. The value of this entry should be another dictionary contain- ing the new metric information. Note It is possible to change a Type 1 font’s metric information (character widths and sidebearings) on a per-character basis. However, determining a pleasing and correct character spacing is a difficult and laborious art that requires considerable skill. A font’s character shapes have been designed with certain metrics in mind. Changing those metrics haphazardly will almost certainly produce poor results. The Metrics dictionary consists of entries in which the keys are charac- CharStrings ter names, as they appear in the dictionary and Encoding array. The values of these entries take various forms. Entries in the dictionary override the normal metrics for the corresponding Metrics characters. An entry’s value may be: • A single number, indicating a new x width only (the y value is zero). • An array of two numbers, indicating the x components of a new left y values are zero). sidebearing and new width (the 276 Chapter 5: Fonts

285 PLRM 2nd Edition Fonts January 21, 1994 x y components of the left • An array of four numbers, indicating and x and y components of the width. sidebearing followed by Metrics dictionary. All of the These forms can be intermixed in one numeric values are in the character coordinate system of the font. In a font that supports two writing modes (see section 5.4, “Font Metric Information”), the Metrics dictionary is used during writing mode 0. Another dictionary, Metrics2 , is used during writing mode 1. The value of an entry in this dictionary must be an array of four numbers, which y x and y components of w1 followed by x and specify components of v (see Figure 5.6 on page 273). Whereas the Metrics and Metrics2 dictionaries allow modifications of individual character metrics in a given font, a procedure named CDevProc allows global changes to a font’s metrics to be algorithmically derived from the Type 1 metric data. , a Level 2 feature, is an optional entry in the font dictionary. CDevProc If present, CDevProc is called after metrics information has been extracted from the character description and from the Metrics and Metrics2 dictionaries, but immediately before the interpreter makes an internal call to setcachedevice2 . Eleven operands are on the stack: the ten values that are to be passed to setcachedevice2 followed by the character’s name. On return, there should be ten values, which are then passed to setcachedevice2 . 5.6.3 Replacing or Adding Individual Characters It is also possible to add characters to existing Type 1 fonts. If the cur- CharStrings dictionary is a rent font is a Type 1 font and an entry in the PostScript language procedure instead of a Type 1 encrypted string, the PostScript interpreter executes the procedure to render the character. This technique can be used to extend a Type 1 font that is already present in the VM of a PostScript interpreter. However, it should not be used to create a Type 1 font program for download purposes, as the font will not be compatible with any Type 1 font interpreter not containing a full PostScript language interpreter (for example, the Adobe Type Manager software). The required behavior of such a “charstring procedure” is very similar to the BuildGlyph mechanism for Type 3 fonts, described in section 5.7, “Type 3 Fonts.” The procedure must perform essentially the same func- procedure, including executing one of the BuildGlyph tions as a Type 3 5.6 Modifications to Existing Fonts 277

286 PLRM 2nd Edition Fonts January 21, 1994 setcachedevice , setcachedevice2 , or setcharwidth operators. Unlike the situation with BuildGlyph , there is potentially a different procedure for each character, although several characters can share one procedure. The execution environment of a charstring procedure is slightly differ- BuildGlyph procedure. ent from that of a Type 3 • Before executing a charstring procedure, the PostScript interpreter and then the font dictionary on the diction- first pushes systemdict ary stack, and pushes either the character code or the character name on the operand stack. The operand is a character code if the inter- variant that preter is in the midst of an ordinary show or any show takes a string operand. The operand is a character name if the inter- preter is executing the operator (a Level 2 feature). glyphshow • After executing the procedure, the PostScript interpreter pops the two dictionaries that it pushed on the dictionary stack. It expects the procedure to have consumed the character code or character name operand. Because a charstring procedure must be able to accept either a character code or a character name as operand, it is strongly recommended that every charstring procedure begin as follows: dup type /integertype eq {/Encoding load exch get} if This ensures that the object on the stack is a name object, which the procedure can now use to look up the character description. If the char- acter description is contained in the charstring procedure itself, the pro- cedure can simply discard its operand. The technique for extending a font, then, is to copy both the top-level CharStrings dictionary, add or replace entries in dictionary and the CharStrings , and define a new font. It is possible to replace .notdef the same as any other character. 5.7 Type 3 Fonts This section describes how to construct a Type 3 font from scratch. A Type 3 font is one whose behavior is determined entirely by PostScript language procedures. Type 3 fonts must be carefully constructed. The PostScript interpreter assumes that such fonts will be reasonably well- behaved. 278 Chapter 5: Fonts

287 PLRM 2nd Edition Fonts January 21, 1994 must: A Type 3 font • Contain the required entries listed in Table 5.1 and Table 5.2. FontType value of 3. • Have a BuildChar , and perhaps also one named • Contain a procedure named BuildGlyph . • Be able to render a character named . .notdef Level 2 implementations support the semantics, described BuildGlyph in section 5.7.1, “BuildGlyph.” Level 1 implementations support only the BuildChar semantics, described in section 5.7.2, “BuildChar.” 5.7.1 BuildGlyph When a PostScript language program tries to show a character from a Type 3 font, and the character is not already present in the font cache, the PostScript interpreter: Encoding 1. Uses the character code as an index into the current font’s array, obtaining the corresponding character name. (This step is omitted during .) glyphshow 2. Pushes the current font dictionary and the character name on the operand stack. BuildGlyph procedure. BuildGlyph must remove 3. Executes the font’s these two objects from the operand stack and use this information to construct the requested character. This typically involves determin- ing the character definition needed, supplying character metric information, constructing the character shape, and painting it. BuildGlyph is called within the confines of a gsave and a grestore , so any changes BuildGlyph makes to the graphics state do not persist after it finishes. Each call to BuildGlyph is independent of any other call. Because of the effects of font caching, no assumptions may be made about the order in which character descriptions will be executed. In should not depend on any non-constant infor- particular, BuildGlyph mation in VM, and it should not leave any side effects in VM or on stacks. 5.7 Type 3 Fonts 279

288 PLRM 2nd Edition January 21, 1994 Fonts BuildGlyph gets control, the current transformation matrix When in the cur- (CTM) is the concatenation of the font matrix ( FontMatrix show rent font dictionary) and the CTM that was in effect at the time was invoked. This means that shapes described in the character coordi- nate system will be transformed into the user coordinate system and will appear in the appropriate size and orientation on the page. BuildGlyph should describe the character in terms of absolute coordi- nates in the character coordinate system, placing the character origin at (0, 0) in this space. It should make no assumptions about the initial value of the current point parameter. Aside from the CTM, the graphics state is inherited from the environ- ment of the operator (or show variant) that caused BuildGlyph to show be invoked. To ensure predictable results despite font caching, must initialize any graphics state parameters on which it BuildGlyph depends. In particular, if BuildGlyph executes the operator, stroke BuildGlyph should explicitly set the line width, line join, line cap, and dash pattern to appropriate values. Normally, it is unnecessary and undesirable to initialize the current color parameter, because is show defined to paint characters with the current color. Before executing the graphics operators that describe the character, BuildGlyph must execute one of the following operators to pass width and bounding box information to the PostScript interpreter: • setcachedevice establishes a single set of metrics for both writing modes, and requests that the interpreter save the results in the font cache if possible. • setcachedevice2 establishes separate sets of metrics for writing modes 0 and 1, and requests that the interpreter save the results in the font cache. setcachedevice2 is a Level 2 feature. • setcharwidth passes just the character’s width (to be used once only), and requests that the character be cached. This is typically used not only if the character description includes operators to set the color explicitly. See the descriptions of setcachedevice , setcachedevice2 , and setcharwidth in Chapter 8 for more information. After executing one of these operators, BuildGlyph should execute a sequence of graphics operators to perform path construction and paint- ing. The PostScript interpreter transfers the results into the font cache, if appropriate, and onto the page at the correct position. It also uses the 280 Chapter 5: Fonts

289 PLRM 2nd Edition Fonts January 21, 1994 width information to control the spacing between this character and the next. The final position of the current point in the character coordi- nate system does not influence character spacing. 5.7.2 BuildChar In Level 2 implementations, if there is no BuildGlyph procedure for the font, the interpreter calls the BuildChar procedure instead. Level 1 BuildGlyph implementations always call BuildChar , whether or not a procedure is present. BuildChar are essentially the same as for BuildGlyph . The semantics of The only difference is that BuildChar is called with the font dictionary and the character code on the operand stack, instead of the font diction- ary and character name . The BuildChar procedure must then perform its own lookup to determine what character definition corresponds to the given character code. For backward compatibility with the installed base of Level 1 interpret- ers, all new Type 3 fonts should contain the following proce- BuildChar dure: /BuildChar { 1 index /Encoding get exch get 1 index /BuildGlyph get exec }bind def This defines BuildChar in terms of the same font’s BuildGlyph proce- dure, which contains the actual commands for painting the character. This permits the font to be used with Level 2 features such as BuildGlyph glyphshow , which requires to be present, yet retains com- patibility with Level 1 implementations. Constructing a Type 3 Font 5.7.3 All Type 3 fonts must include a character named .notdef . The BuildGlyph procedure should be able to accept that character name regardless of whether such a character is encoded in the Encoding array. If the BuildGlyph procedure is given a character name that it does not charac- recognize, it can handle that condition by painting the .notdef ter instead. 5.7 Type 3 Fonts 281

290 PLRM 2nd Edition Fonts January 21, 1994 Any Type 3 font that depends on Level 2 features to draw character shapes (for example, uses or rectfill ) should have an entry glyphshow /LanguageLevel 2 def in the font dictionary. A file containing a font program should use appropriate document structuring comments (see Appendix G). Example 5.7 shows the definition of a Type 3 font with only two char- acters—a filled square and a filled triangle—selected by the characters a . The character coordinate system is on a 1000-unit scale. This is and b not a realistic example, but it does illustrate all the elements of a Type 3 BuildGlyph procedure, an Encoding array, and a sub- font, including a sidiary dictionary for the individual character definitions. Example 5.7 8 dict begin /FontType 3 def % Required elements of font /FontMatrix [.001 0 0 .001 0 0] def /FontBBox [0 0 1000 1000] def % Trivial encoding vector /Encoding 256 array def 0 1 255 {Encoding exch /.notdef put} for Encoding 97 /square put % ASCII a = 97 Encoding 98 /triangle put % ASCII b = 98 /CharProcs 3 dict def % Subsidiary dictionary for CharProcs begin % individual character definitions /.notdef { } def /square {0 0 moveto 750 0 lineto 750 750 lineto 0 750 lineto closepath fill} bind def /triangle {0 0 moveto 375 750 lineto 750 0 lineto closepath fill} bind def end % of CharProcs /BuildGlyph { % Stack contains: font charname 1000 0 % Width 0 0 750 750 % Bounding box setcachedevice exch /CharProcs get exch % Get CharProcs dictionary 2 copy known not {pop /.notdef} if % See if charname is known get exec % Execute character procedure } bind def % Level 1 compatibility /BuildChar { 1 index /Encoding get exch get 282 Chapter 5: Fonts

291 PLRM 2nd Edition January 21, 1994 Fonts 1 index /BuildGlyph get exec } bind def currentdict end % of font dictionary /ExampleFont exch definefont pop /ExampleFont findfont 12 scalefont setfont % Now show some characters 36 52 moveto (ababab) show Output from Example 5.7 Figure 5.7 5.8 Unique ID Generation unique ID is an optional entry in a font dictionary that helps identify A the font to the interpreter. Its primary purpose is to identify cached characters built from that font. The PostScript interpreter can retain characters in the font cache even for a font that is not permanently in VM. Some implementations can save cached characters on disk. This can have a beneficial effect on performance when using fonts that are loaded into VM dynamically either by explicit downloading or auto- matically via the resource facility. If a font has a unique ID, the interpreter can recognize that the cached characters belong to that font, even if the font dictionary itself is removed from VM and is later reloaded (by a subsequent job, for instance). If a font does not have a unique ID, the interpreter can recog- nize cached characters for that font only while it remains in VM. When the font is removed, the cached characters must be discarded. 5.8 Unique ID Generation 283

292 PLRM 2nd Edition January 21, 1994 Fonts Correct management of unique IDs is essential to ensure predictable behavior. If two fonts have the same unique ID but produce characters with different appearances when executed, it is unpredictable which characters will appear when those fonts are used. Therefore, unique IDs must be assigned systematically from some central registry. The reason that font caching is based on a special unique ID entry rather than on the font’s name, or other identifying information, is that font names are not necessarily unique. A font with a particular name, such as Garamond-Bold, may be available from several sources, and there may be successive releases of a font from the same source. For information about assigning unique IDs, consult Adobe Type 1 Font Format , or contact Adobe Systems Incorporated. There are two kinds of unique ID entries that can appear in font dic- UniqueID and tionaries: . Both kinds are described below. The XUID UniqueID is supported by both Level 1 and Level 2 implementations; it XUID applies only to fonts. The is a Level 2 feature; it applies to fonts and also to certain other categories of resources. See section 4.7, “Forms,” and section 4.9, “Patterns.” When you create a new font program that will be saved permanently and perhaps will be distributed widely, you should assign and UniqueID XUID values for that font and embed those values in the definition of the font dictionary. On the other hand, when an application program constructs a font as part of building a page description, it should not UniqueID in the font dictionary, because there is no include a XUID or opportunity for registering the ID, and there is little to be gained from doing so in any event. When you copy a font dictionary for the purpose of creating a modified not copy the UniqueID . As an exception to this general font, you should UniqueID if rule, it is acceptable (and preferable) to retain the original FontMatrix FontName , FontInfo , , or the only modified entries are Encoding , because those changes do not affect the characters’ appear- ance or metrics. 5.8.1 UniqueID Numbers The UniqueID entry in a font dictionary is an integer in the range 0 to 24 16777215 (which is 2 – 1). Each FontType has its own space of UniqueID values. Therefore, a Type 1 font and a Type 3 font could have UniqueID the same number and be safely used together without causing conflicts in the font cache. 284 Chapter 5: Fonts

293 PLRM 2nd Edition Fonts January 21, 1994 UniqueID The numbers for Type 1 fonts are controlled. Adobe Systems maintains a registry of UniqueID numbers for Type 1 fonts. The num- bers between 4000000 and 4999999 are reserved for private interchange in closed environments and cannot be registered. Extended Unique ID Numbers 5.8.2 An XUID ( extended unique ID ) is an entry whose value is an array of inte- gers. XUID arrays provide for distributed, hierarchical management of the space of unique ID numbers. A font is uniquely identified by the sequence of numbers in the array. XUID s are a Level 2 feature. entire They are ignored by Level 1 implementations. The first element of an XUID array must be a unique organization identi- fier , assigned by the Adobe registry. The remaining elements—and the allowed length of XUID arrays starting with that organization ID—are controlled by the organization to which the organization ID is assigned. An organization can establish its own registry for managing the space XUID arrays, of numbers in the second and subsequent elements of which are interpreted relative to the organization ID. The organization ID value 1000000 is reserved for private interchange XUID arrays starting with this number may be in closed environments. of any length. This scheme also makes it possible to derive unique identifiers system- atically when modifying existing fonts. This is not possible for values since the space of numbers is too small. A program can UniqueID XUID array with a longer XUID array whose additional ele- replace an ments indicate exactly what modifications have been performed. XUID array ignore PostScript interpreters that recognize the UniqueID whenever an is present. For backward compatibility with the XUID installed base of interpreters, font creator and font modifier software should continue to use and maintain appropriate UniqueID numbers for the foreseeable future. 5.9 Composite Fonts This section describes how to build hierarchical composite fonts from base fonts. All fonts in the PostScript language are considered base fonts , FontType except those with a of 0. Base fonts contain individual char- acter descriptions; composite fonts are combinations of base fonts. The 5.9 Composite Fonts 285

294 PLRM 2nd Edition Fonts January 21, 1994 ability to use composite fonts is supported by all Level 2 implementa- tions and some Level 1 implementations that have the composite font extensions. A composite font is a collection of base fonts organized hierarchically. The font at the top level of the hierarchy is the root font . Fonts at a descendant fonts lower level of the hierarchy are called . When the cur- rent font is composite, the show operator (and its variants) behaves dif- ferently than it does with base fonts. It uses a mapping algorithm that decodes show strings to select characters from descendant base fonts. show This organization enables any given string to select characters from any of the descendant fonts. The composite font facility supports the use of very large character sets, such as those for the Japanese and Chinese languages. It also simplifies the organization of fonts that have complex encoding requirements. There are many uses of composite fonts that are not immediately appar- ent from the language specification. For more examples, see the docu- , available from the Adobe Systems ment Tutorial on Composite Fonts Developers’ Association. In addition to the required entries listed in Table 5.1 on page 266, com- posite font dictionaries can contain the entries listed in Table 5.5. Table 5.5 Additional entries specific to Type 0 (composite) fonts Key Type Semantics ) Indicates which mapping algorithm to use when interpreting the FMapType integer ( Required sequence of bytes in a string. See Table 5.6 on page 287. Encoding ( Required ) Array of integers, each used as an index to extract a font dictionary array from the FDepVector . Note that this is different from the use of Encoding in base fonts. FDepVector array ( Required ) Array of font dictionaries that are the descendants of this composite font. ) Array that is usually the same as the PrefEnc array ( Optional Encoding array that is most com- monly used by the descendant fonts. If this entry is not initially present, inserts one with a null value. definefont EscChar integer ( Optional ) Escape code value, used only when FMapType is 3 or 7. If this entry is not present but is needed, definefont inserts one with the value 255. ShiftOut integer ( Optional; Level 2 only ) Shift code value, used only when FMapType is 8. If this definefont inserts one with the value 14. entry is not present but is needed, 286 Chapter 5: Fonts

295 PLRM 2nd Edition Fonts January 21, 1994 integer Optional; Level 2 only ) Shift code value, used only when FMapType is 8. If this ShiftIn ( definefont entry is not present but is needed, inserts one with the value 15. SubsVector string ( Optional ) User-defined mapping algorithm, used only when FMapType is 6. 5.9.1 Character Mapping is an integer that indicates which mapping algorithm will be FMapType used to interpret the sequence of bytes in a show string. Instead of each byte selecting a character independently, as is done for base fonts, the show string encodes a more complex sequence of font and character selections. The mapping algorithm: 1. Decodes bytes from the show string to determine a font number and a character code. 2. Uses the font number as an index into the Encoding array of the composite font, obtaining an integer. array, 3. Uses that integer in turn as an index into the FDepVector selecting a descendant font. 4. Uses the character code to select a character from the descendant font, in whatever way is appropriate for that font. FMapType value can Table 5.6 lists the mapping algorithms that the select. If the mapping of any string passed to a show operator is incom- plete or if a font number or character code indexes beyond the end of an FDepVector or Encoding array, a rangecheck error results. Table 5.6 FMapType mapping algorithms Algorithm FMapType Explanation 8/8 mapping string. The first byte is the font number 2 Two bytes are extracted from the show and the second byte is the character code. 3 One byte is extracted from the show string. If it is equal to the value of the escape mapping EscChar entry, the next byte is the font number, and subsequent bytes (until the next escape code) are character codes for that font. At the beginning of a show string, font 0 is selected. A font number equal to the escape code is treated specially; see section 5.9.3, “Nested Composite Fonts.” string. The most significant bit is the font 1/7 mapping 4 One byte is extracted from the show number, and the remaining 7 bits are the character code. 5.9 Composite Fonts 287

296 PLRM 2nd Edition January 21, 1994 Fonts 5 Two bytes are extracted from the string and combined to form a 16-bit 9/7 mapping show number, high-order byte first. The most significant 9 bits are the font number, and the remaining 7 bits are the character code. SubsVector One or more bytes are extracted from the show string and decoded according to 6 mapping entry of the font. The format of SubsVector is information in the SubsVector described below. 7 ( Level 2 only ) This mapping is very similar to double escape mapping 3. However, when an FMapType escape code is immediately followed by an escape code, a third byte is extracted show from the string. The font number is the value of this byte plus 256. shift mapping 8 ( Level 2 only ) This mapping provides exactly two descendant fonts. A byte is show extracted from the ShiftIn code, subsequent bytes are string. If it is the character codes for font 0. If it is the ShiftOut code, subsequent bytes are character codes for font 1. At the beginning of a show string, font 0 is selected. ShiftOut EscChar are integers that determine the escape , ShiftIn , and and shift code values used with values 3, 7, and 8. If one of FMapType these entries is required but is not present, definefont inserts an entry with a default value as specified in Table 5.5 on page 286. SubsVector is a string that controls the mapping algorithm for a com- posite font with an FMapType of 6. This mapping algorithm allows the space of character codes to be divided into ranges, where each range corresponds to one descendant font. The ranges can be of irregular sizes that are not necessarily powers of two. The first byte of a SubsVector string specifies one fewer than the code show length —the number of bytes to be extracted from the string for each operation of the mapping algorithm. A value of 0 specifies a code length of one byte, 1 specifies two bytes, and so on. When a character code is longer than one byte, the bytes comprising it are interpreted high-order byte first. The code length cannot exceed the number of bytes representable in an integer (see Appendix B). The remainder of the SubsVector string defines a sequence of ranges of consecutive code values. The first range is the one for font 0, the second range is the one for font 1, and so on. Each range is described by one or more bytes; the number of bytes is the same as the code length. The value contained in those bytes (interpreted high-order byte first) gives the size of the code range. There is an implicit code range at the end of the sequence that contains all remaining codes. This range should not be specified explicitly. operator interprets a character code When using a SubsVector , the show extracted from the show string as follows: 288 Chapter 5: Fonts

297 PLRM 2nd Edition Fonts January 21, 1994 1. Determine the code range that contains the character code. The position of the code range in the SubsVector sequence (counting from zero) is used as the index into the font’s Encoding array, select- ing a descendant font. 2. Subtract the base of the code range from the character code. The result is treated as a character code to select a character from the descendant font. The following examples show how several of the other mapping algo- rithms could be described in terms of the mapping. This is SubsVector for illustrative purposes only. The other mapping algorithms should be used rather than the SubsVector mapping if they achieve the desired effect. The SubsVector strings are shown as hexadecimal string literals. • 1/7 mapping: <00 80> The code length is one byte. There are two code ranges. The first one is explicitly of length 80 hex. It contains character codes 0 to 127 decimal. The second code range implicitly contains all remaining characters that can be coded in one byte—that is, character codes in the range 128 to 255. <01 0080 0080 ... 0080> • 9/7 mapping: The code length is two bytes. There are up to 512 code ranges, each 80 hex (128 decimal) in size. The SubsVector string that describes all 512 code ranges would be 1023 bytes long. Remember that the last code range is specified implicitly. • 8/8 mapping: <01 0100 0100 ... 0100> The code length is two bytes. There are up to 256 code ranges, each 100 hex (256 decimal) in size. The SubsVector string that describes all 256 code ranges would be 511 bytes long. The last code range is specified implicitly. Escape and shift mappings cannot be described in terms of the SubsVector Note mapping. 5.9.2 Other Dictionary Entries for Composite Fonts FontMatrix plays the same role in a composite font as it does in a base font. When a character is shown, both the FontMatrix of the composite of the descendant base font are concatenated font and the FontMatrix to the CTM. 5.9 Composite Fonts 289

298 PLRM 2nd Edition Fonts January 21, 1994 is an integer with value 0 or 1, indicating which of two sets of WMode character metrics will be used when characters from the base fonts are shown (see section 5.4, “Font Metric Information”). If it is omitted, writing mode 0 will be used. The writing mode of the root composite font overrides the writing modes of all its descendants. This allows a given base font to be used as part of many composite fonts, some of which use writing mode 0 and some of which use writing mode 1. PrefEnc (preferred encoding) is an array that should be the same as the Encoding array of one or more of the descendant fonts. Characters from descendant fonts whose Encoding is the same as the PrefEnc of the par- ent will be processed more efficiently than characters from other descendant fonts. If this entry is not present, a null entry will be created by definefont . A composite font dictionary should be large enough to have three addi- tional entries—named FID , MIDVector , and CurMID —added to it by definefont . These entries serve internal purposes in the font machinery. In addition, a PrefEnc entry will be added if one is not already present, ShiftIn , and escape and mapping fonts will have any required EscChar , or entries added if not already present. ShiftOut 5.9.3 Nested Composite Fonts The descendant fonts of a composite font may themselves be composite fonts, nested to a maximum depth of five levels. The mapping algo- rithms nest according to two sets of rules, depending on whether the composite fonts are modal or non-modal. Fonts with FMapType 3, 7, or 8 are modal fonts, in that some byte codes select a descendant font, and then successive bytes of the show string are interpreted with respect to the selected font until a new descendant font is selected. Modal fonts follow these rules: • The parent of an 3 font must be either FMapType FMapType 3 or 7. The of the root font overrides the EscChar of descendant EscChar escape-mapped fonts. • Fonts with FMapType 7 and 8 may not be used as descendant fonts. • Occurrence of an escape or shift code in the show string causes the mapping algorithm to ascend the font hierarchy from the currently- selected descendant font to the nearest parent modal font. If that font’s FMapType is 8, the algorithm selects the new descendant FMapType is 3 or 7, the algorithm according to the shift code. If the 290 Chapter 5: Fonts

299 PLRM 2nd Edition Fonts January 21, 1994 extracts another byte from the show string. If the byte is not an escape code, the algorithm uses it as a font number to select a descendant of that font. But if the byte is an escape code and the FMapType is 3, the algorithm ascends to the parent of that font, extracts yet another byte from the show string, and repeats the selec- tion process. The other values (2, 4, 5, 6) are non-modal, in that their map- FMapType ping algorithm restarts for each new character. Non-modal fonts follow these rules: • The parent of a non-modal font may be any type of composite font, including a modal font. • If the parent of a non-modal font is a modal font, the modal font’s escape or shift code is recognized only when it appears as the first byte of a multi-byte mapping sequence for the non-modal font. • If the descendant of a non-modal composite font is itself a non- modal composite font, the second part (character code) of the value extracted from the string is reused as the first part of the show descendant font’s mapping algorithm. The FontMatrix entries of nested composite fonts are treated in a non- obvious way. When a character is shown, the interpreter consults the entries of only the selected base font and the immediate FontMatrix parent of the base font. The immediate parent’s contains FontMatrix the concatenation of the FontMatrix entries of all ancestor fonts. To achieve this, definefont concatenates the root font’s FontMatrix to the FontMatrix entries of all descendant composite fonts, but not base scalefont fonts. Similarly, makefont and apply their transformations to all descendant composite fonts. 5.9 Composite Fonts 291

300 PLRM 2nd Edition January 21, 1994 Fonts 292 Chapter 5: Fonts

301 PLRM 2nd Edition January 25, 1994 Rendering Example 1.0 Example 2.0 Example 3.0 Example 4.0 Example 6.0 Example 5.0 Table 6.0 Example 6.0 6 CHAPTER Figure 6.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Rendering (the specification of shapes The PostScript language separates graphics rendering (controlling a raster output device). Figure and colors) from 4.5 and Figure 4.6 on pages 178 and 179 show this division. Chapter 4 also explains the facilities for describing the appearance of pages in a device independent way. This chapter explains the facilities for control- ling how shapes and colors are rendered on the raster output device. Use of any of these facilities requires knowing the characteristics of the device. A PostScript language program that is intended to be device independent should not access any of the facilities described in this chapter. Nearly all of the rendering facilities that are under program control have to do with the reproduction of color. The interpreter renders col- ors by a multiple-step process outlined below. Depending on the cur- rent color space and on the characteristics of the device, it is not always necessary to perform every step. 1. If a color has been specified in a CIE-based color space, as described in section 4.8, “Color Spaces,” the interpreter must first transform it , DeviceCMYK , or to one of the device color spaces ( DeviceRGB ) appropriate for the raster output device. This transfor- DeviceGray mation is controlled by a CIE-based . color rendering dictionary 2. If a color has been specified in a device color space that is inappro- priate for the output device (for example, RGB color with a CMYK or . gray-scale device), the interpreter invokes a color conversion function A PostScript language program can also request explicit conversions between device color spaces. 3. The interpreter now maps the device color values through transfer , one for each component. The transfer functions compen- functions sate for peculiarities of the output device, such as non-linear gray- gamma correction . level response. This step is sometimes called 293

302 PLRM 2nd Edition Rendering January 25, 1994 4. If the device cannot reproduce continuous tones, but only certain discrete colors, such as black and white pixels, the interpreter invokes a halftone function , which approximates the desired colors by means of patterns of pixels. 5. Finally, the interpreter performs scan conversion to paint the appro- priate pixels of the raster output device with the requested colors. Level 1 and Level 2 implementations of the PostScript language differ in the facilities they offer for rendering: • CIE-based color spaces and CIE-based color rendering dictionaries are supported only in Level 2 implementations. • Most Level 1 implementations support only a single transfer func- tion controlled by the settransfer operator and a single halftone function controlled by the setscreen operator. • Level 1 implementations with the color extensions support multiple , multiple halftone setcolortransfer transfer functions controlled by functions controlled by , and various color conversion setcolorscreen facilities. These operators provide separate control over rendering each of four color components. The Level 1 products containing this feature also support the setcmykcolor and colorimage operators. • Level 2 implementations and the Display PostScript system also offer halftone dictionaries . A halftone dictionary is an object that can con- tain halftone screen thresholds, transfer functions, and many other rendering details. Halftone dictionaries are more general and more flexible than the Level 1 facilities, and they override those facilities when used. Of course, Level 2 implementations fully support the Level 1 facilities. 6.1 CIE-Based Color to Device Color As discussed in section 4.8, “Color Spaces,” the CIE-based color spaces are mathematically related to the CIE 1931 (XYZ)-space, which is based on a model of human color perception. To render CIE-based colors on a device, a PostScript interpreter must convert from the specified CIE- based color space to the device’s native color space, taking into account the known properties of the device. The goal of this process is to pro- duce output that accurately reproduces the requested CIE-based color values as perceived by a human observer. CIE-based color specification and rendering are supported only by Level 2 implementations. 294 Chapter 6: Rendering

303 PLRM 2nd Edition Rendering January 25, 1994 The conversion from CIE-based color to device color is complex; the theory on which it is based is beyond the scope of this manual (see the bibliography). The algorithm has many parameters, including an optional, full three-dimensional color lookup table. The color fidelity of the output depends on these parameters being properly set, usually by a procedure that includes some form of calibration. Each product includes a default set of color rendering parameters that have been cho- sen to produce reasonable output based on the nominal characteristics of the device. The PostScript language does not prescribe procedures for calibrating the device or for computing a proper set of color rendering parameters. Conversion from a CIE-based color value to a device color value requires two main operations: CIE-based gamut map- 1. Adjust the CIE-based color value according to a ping function . A gamut is a subset of all possible colors in some color space. A page description has a source gamut consisting of all colors that it uses. A device has a device gamut which consists of all colors it can reproduce. This step transforms colors from the source gamut to the device gamut in a way that preserves color appearance and visual contrast. CIE-based 2. Generate a corresponding device color value according to a color mapping function . For a given CIE-based color value, this func- tion computes a color value in the device’s native color space. The CIE-based gamut and color mapping functions are applied only to color values presented in a CIE-based color space. By definition, color values in device color spaces directly control the device color compo- nents. The source gamut is specified by a page description when it selects a CIE-based color space by executing setcolorspace . This specification, which includes the values defined by the WhitePoint and BlackPoint entries of the parameter dictionary of , is device indepen- setcolorspace dent. The device gamut, the gamut mapping function, and the color map- ping function are described together by a CIE-based color rendering dic- , which is a parameter of the graphics state that is set when the tionary device is installed or recalibrated. Everything in this dictionary is device dependent. The setcolorrendering operator installs a color rendering returns the cur- dictionary in the graphics state; currentcolorrendering rent color rendering dictionary. 6.1 CIE-Based Color to Device Color 295

304 PLRM 2nd Edition Rendering January 25, 1994 6.1.1 CIE-Based Color Rendering Dictionaries The CIE-based gamut and color mapping functions, embodied by the color rendering dictionary, are defined in an extensible way. The Post- Script language supports one standard type of color rendering diction- ary, which works in all implementations. Some products support additional types of color rendering dictionaries that select other, possi- bly proprietary, gamut and color mapping methods. The set of available types and the meanings of specific color rendering dictionaries are product dependent. They are not described in this manual but in product documentation. Most of the entries in a color rendering dictionary together define a composite color rendering function that transforms CIE-based color values to device color values by applying the gamut and color mapping functions. The output from this color rendering function is subject to further transformations—device color space conversion, transfer func- tion, and halftoning. Device color space conversion is not normally needed, because a properly defined dictionary will produce output in the device’s native color space. key Every color rendering dictionary must have a ColorRenderingType whose value is an integer. The value specifies the architecture of the composite color rendering function as a whole. The remaining entries in the dictionary are interpreted according to this value. Type 1 Color Rendering Dictionary 6.1.2 The type 1 color rendering dictionary is a standard part of the Post- Script language. Some products support other types, and the default color rendering dictionary in any particular product may have a type other than 1. CIEBasedABC color space, The type 1 color rendering is based on the which is a two-stage, non-linear transformation of the CIE 1931 (XYZ)- space. This space is called the render color space . Values in this space can be treated in one of two ways: • Used directly as color values in the DeviceRGB or DeviceGray color space. • Used to index a three-dimensional lookup table that in turn contains or color values to be interpreted in the DeviceRGB DeviceCMYK color space. 296 Chapter 6: Rendering

305 PLRM 2nd Edition Rendering January 25, 1994 The first method usually works well with additive, linear color devices, which include many black and white and color displays. The second method is required for high-fidelity reproductions with most color printers, whose color rendition cannot be described by a simple formula. Conceptually, conversion of a color value from a CIE-based color space to a device color space involves the following steps. In reality, the implementation does not perform these steps in sequence but in com- bination. Furthermore, there are important special cases in which the effects of two or more of the steps cancel out. The implementation detects these cases and omits the unnecessary transformations. 1. Transform the CIE-based color value from its original color space ( CIEBasedABC or CIEBasedA ) to the CIE 1931 (XYZ)-space. This transformation depends on various parameters of the color space. 2. Adjust the X , Y , and Z values to account for differences in the WhitePoint BlackPoint of the source and the device. This trans- and formation attempts to preserve color appearance and visual contrast, according to the MatrixPQR and TransformPQR entries of the color rendering dictionary. The diffuse white and black points of the source are given as the WhitePoint and BlackPoint parameters of the color space; the diffuse white and black points of the device are entries of the color render- BlackPoint given by the WhitePoint and ing dictionary. If the corresponding WhitePoint BlackPoint and entries in the color space and color rendering dictionary are equal, this step reduces to the identity transformation. 3. Transform the color value from the CIE 1931 (XYZ)-space into the MatrixLMN , EncodeLMN , render color space according to the MatrixABC , and EncodeABC entries of the CIE-based color rendering dictionary, producing three components A , B , and C . (These have nothing to do with the A components of color values in , B , and C the source or CIEBasedA color spaces.) CIEBasedABC 4. If a RenderTable entry is present in the color rendering dictionary, use the A , B , and C components to index into this three-dimensional lookup table, yielding an interpolated color value. This value con- sists of three or four color components, depending on how the table is defined. Each of these components is transformed by a procedure to produce color components in device color space. If there are three components, they specify red, green and blue values according to 6.1 CIE-Based Color to Device Color 297

306 PLRM 2nd Edition January 25, 1994 Rendering DeviceRGB color space. If there are four components, they spec- the DeviceCMYK ify cyan, magenta, yellow, and black according to the color space. A B , and C components as RenderTable If there is no , entry, use the the device color value directly. If the device’s native color space is component specifies the gray value and the B and A DeviceGray , the A , B , and C C components are ignored. Otherwise, the components specify the red, green, and blue values, respectively, according to the DeviceRGB color space. Table 6.1 describes the key-value pairs that a type 1 color rendering dic- tionary can contain and specifies the details of the transformations. Table 6.1 Entries in a type 1 CIE-based color rendering dictionary Key Type Semantics ( Required ColorRenderingType integer ) Must be 1. array ( Optional ) Array of nine numbers [ L MatrixLMN M N N ] that specify the L M M L N Y X Z Y Z X Z X Y X linear interpretation of the , and Z components of the CIE 1931 (XYZ)-space , Y with respect to an intermediate LMN representation. This is explained below. Default value: the identity matrix [1 0 0 0 1 0 0 0 1]. array ( Optional ) Array of three PostScript language procedures [ E EncodeLMN E ] that encode E N L M L , M , and N components of the intermediate LMN representation. Default the value: the array of identity procedures [{} {} {}]. component on , M , or N Each of these procedures is called with an unencoded L the operand stack and must return the corresponding encoded value. The result must be a monotonic function of the operand. Because these procedures are called at unpredictable times and in unpredictable environments, they must operate as pure functions without side effects. EncodeLMN and The transformation defined by the MatrixLMN entries is: LE = XL () × YL ++ × ZL × Z L Y X ME × = () × YM ++ XM ZM × Z Y X M NE = XN × ZN × YN × ++ () N Z Y X , and Y Z , components of the CIE 1931 (XYZ)-space are X In other words, the treated as a three element vector and multiplied by MatrixLMN (a three by three matrix). The results are individually transformed by the EncodeLMN procedures to provide the L , M , and N components of the intermediate LMN representation. L RangeLMN array ( Optional ) Array of six numbers [ M N M ] that specify the range of N L 1 1 0 1 0 0 valid values for the components of the intermediate LMN N , and M , L M ≤ M M . Default , L ≤ L ≤ L representation—that is, N ≤ N ≤ N , and ≤ 1 0 0 1 0 1 value: [0 1 0 1 0 1]. 298 Chapter 6: Rendering

307 PLRM 2nd Edition January 25, 1994 Rendering array ( ) Array of nine numbers [ A MatrixABC B Optional C ] that specify the A C B B C A M M N M N L L L N , M , and N components of the intermedi- linear interpretation of the encoded L ate LMN representation with respect to the render color space. This is explained below. Default value: the identity matrix [1 0 0 0 1 0 0 0 1]. ( Optional ) Array of three PostScript language procedures [ E EncodeABC array E ] that encode E B C A A , B , and C the components of the color space. Default value: the array of iden- tity procedures [{} {} {}]. , A , or C component on B Each of these procedures is called with an unencoded the operand stack and must return the corresponding encoded value. The result must be a monotonic function of the operand. Because these procedures are called at unpredictable times and in unpredictable environments, they must operate as pure functions without side effects. The transformation defined by the MatrixABC and EncodeABC entries is: AE NA LA MA × = () × + × + N A M L BE × = NB () MB × LB + × + B L M N CE × + × + × NC MC LC = () M N L C ) Array of six numbers [ ( A Optional RangeABC array A C C B B ] that specify the range of valid 0 1 1 0 0 1 B values for the A , B , and C components—that is, A ≤ A ≤ A , B ≤ B ≤ , and 1 1 0 0 RenderTable C C ≤ C entry, these ranges must lie within the . If there is no ≤ 1 0 range 0 to 1, since the render color space maps directly onto a device color space. If a RenderTable entry is present, these ranges define the boundaries of the three-dimensional lookup table. Default value: [0 1 0 1 0 1]. array ( Required ) Array of three numbers [ X WhitePoint Y Z ] that specify the CIE 1931 (XYZ)- W W W and X space tristimulus value of the device’s diffuse white point. The numbers W Z must be equal to 1. must be positive and Y W W WhitePoint is assumed to represent the device’s diffuse, achromatic highlight, and hence its value must correspond to the nearly lightest, achromatic color that the device can produce. A color somewhat darker that the absolutely lightest color may be used to avoid blocking of highlights and to provide some flexibility for rendering specular highlights. BlackPoint ( array Optional ) Array of three numbers [ X Y Z ] that specify the CIE 1931 (XYZ)- B B B space tristimulus value of the device’s diffuse black point. These numbers must be non-negative. Default value: [0 0 0]. BlackPoint is assumed to represent the device’s diffuse, achromatic shadow. Its value is defined by the nearly darkest, nearly achromatic color that the device can produce. A color somewhat lighter than the absolutely darkest color may be used to avoid blocking of shadows. A slightly chromatic color may be used to increase dynamic range in situations where the darkest color that the device can produce is slightly chromatic. 299 6.1 CIE-Based Color to Device Color

308 PLRM 2nd Edition Rendering January 25, 1994 Optional ) Array of nine numbers [ P MatrixPQR Q ( R array P ] that specify the Q R R Q P Z X Y Z Y Y X X Z , and Z , X Y linear interpretation of the components of the CIE 1931 (XYZ)-space, respectively, with respect to an intermediate PQR representation. This is explained below. Default value: the identity matrix [1 0 0 0 1 0 0 0 1]. ( ) Array of six numbers [ P array RangePQR Optional P Q Q R ] that specify the range of valid R 1 1 0 1 0 0 Q R components of the intermediate PQR representation— , P values for the , and ≤ P ≤ P that is, , Q P ≤ Q ≤ Q . Default value: [0 1 0 1 0 1]. , and R R ≤ R ≤ 0 1 0 0 1 1 Required array TransformPQR ) Array of three PostScript language procedures [ ( T ] that T T R P Q R transform the , and Q , P components of the intermediate PQR representation in a way that accommodates for the differences between the source’s and the device’s diffuse white and black points while preserving color appearance and visual contrast. X Let , and X , Z Y , Z be the CIE 1931 (XYZ)-space tristimulus val- Y , Ws Bs Ws Bs Ws Bs Y , ues of the source’s diffuse white and black points, respectively. Let X , Wd Wd Z X and Y Z , be the CIE 1931 (XYZ)-space tristimulus values of the , Bd Bd Wd Bd device’s diffuse white and black points. Then the source and device tristimulus Z , Y values , Z in the CIE 1931 (XYZ)-space, respectively, are and X X , Y , d s s d s d TransformPQR entries as follows: and MatrixPQR related by the Y P Z P × + × + × P X P = Z s Y s X s s + × Q Q Z × X + Q × Y = Q X Z s Y s s s R = R Y R X Z × + × + × R s X Y s s s Z P () ,, , , P = B W T W B s d d d s P s () B ,, , , W = B Q W T Q d d s s Q d s R T () B = ,, , , B R W W s s s d R d d × X P X Q X R X × + + × = Q P d d d R d + + P × Y Y Q × × R = Y Y d R Q d d P d Z Z P + = × × + × Z R Z Q P R d Q d d d where Q P ] Y =[ R X Z W s Ws Ws Ws Ws Ws Ws Z Q ] =[ R X Y P B s Bs Bs Bs Bs Bs Bs Q R =[ X Y Z ] P W d Wd Wd Wd Wd Wd Wd R =[ X Y Z P Q ] B d Bd Bd Bd Bd Bd Bd P = X P P × Y P + × × + Z Ws Y Ws Ws Z X Ws Q × = X × Q Q Y × + Q + Z Ws Y Ws X Z Ws Ws R × = R X × R + Y Z + × R Y Ws Ws X Ws Ws Z 300 Chapter 6: Rendering

309 PLRM 2nd Edition January 25, 1994 Rendering P Y + × P Z + × P × P = X Bs Bs Y Bs Z X Bs + = Y Q X × × + Z Q × Q Q Bs X Bs Bs Z Bs Y R R Z + × + × Y × R = X R Bs Bs Y X Bs Bs Z + P X × P = Y × × P + P Z Wd Wd Wd X Wd Z Y × Y Q Q × X + = Z × Q + Q Wd Wd X Y Wd Z Wd X Z × R R × + × Y + R = R Wd Wd X Wd Y Wd Z P = × P + Z P × + Y P X × Y Bd X Bd Bd Z Bd = + × X Y Q Q × Z Q × + Q Bd Z Y Bd Bd Bd X × + Z R × + Y R X = × R R X Bd Bd Z Bd Bd Y − 1 X Z Q Y P R P P X P X X = X Q P Z R Y Y Y Y Q Q Q R Q X Y Z P Z R Z Z R R components of the source color in CIE 1931 Y In other words, the , and , Z X s s s (XYZ)-space are treated as a three element vector and multiplied by MatrixPQR P Q , and R , components of the source (a three by three matrix), yielding the s s s color with respect to the intermediate PQR representation. These components procedures, producing the P are individually transformed by the TransformPQR , d , and Q R components of the corresponding device color. Each of the d d components is transformed separately; there is no interaction between P components. Finally, the R components of the device color are Q , and , d d d treated as a three element vector and multiplied by the inverse of MatrixPQR . Z Y , X , and The results provide the components of the device color in the CIE d d d 1931 (XYZ)-space. procedures usually consists TransformPQR The transformation embodied by the of two conceptually separate processes. The first allows for the chromatic adapta- tion involved when the two diffuse white points differ. The second allows for the contrast adaptation involved when the dynamic ranges between the two sets of diffuse white and black points differ. In addition to the appropriate P component, each of the , Q R , or s s s TransformPQR procedures takes the additional four operands W B , B , and , W d s s d that specify the source’s diffuse white and black points and the device’s diffuse white and black points, respectively. Each of these operands is an array of six ele- ments giving the white or black point twice: once in CIE 1931 (XYZ)-space and again in PQR space. W Each of these procedures is called with the four arrays and the , W B , and B , s d s d appropriate P R , Q , or component on the operand stack (in that order) and s s s , must return the corresponding transformed P Q , or component. The result R d d d 6.1 CIE-Based Color to Device Color 301

310 PLRM 2nd Edition Rendering January 25, 1994 must be a monotonic function of the last operand. Because these procedures are called at unpredictable times and in unpredictable environments, they must operate as pure functions without side effects. RenderTable ( Optional ) Array of the form [ N array N ... T N ], which, if present, table m T T 1 m C B A 2 describes a three-dimensional lookup table that maps colors in render color space to colors in device color space via table look-up and interpolation. The N encoded color × N m table contains N entries, each of which consists of × C B A component values. The element m must be the integer 3 or 4; N N , N , and B C A must be integers greater than 1. The entry at integer coordinates ( a , b , c ) in the table, where 0 c a < N ≤ , 0 ≤ b < N , contains the encoded device , and 0 ≤ N < C A B A , color value that corresponds to render color space components , and C , B where: aA () N 1 − () ⁄ × + = A − AA 0 A 1 0 () + bB × B ⁄ − () N = 1 − BB B 0 1 0 CC + = ⁄ − cC () C × − () N 1 C 0 1 0 B , RangeABC entry. , and C , are given in the B C , A , A The values 1 0 0 1 1 0 must be an array of N table The element strings, which define the contents of A m the lookup table. Each string must contain × N × characters. Within the N B C a in the array, the m characters starting at position string at index × m × ( b c N , + c ) constitute the table entry at location ( a , b ). These characters C e , , which are are interpreted as encoded device color components e e , ... 1 2 m integers in the range 0 to 255. The elements T T T , ... are PostScript language procedures that transform the , 1 2 m interpolated, encoded components to device color component values. These transformations are: e T = () ⁄ 255 d 1 1 1 = () T e ⁄ 255 d 2 2 2 ... e = () ⁄ T 255 d m m m In other words, the interpreter divides an encoded component by 255, producing a number in the range 0 to 1, and pushes it on the operand stack. It T then calls the appropriate procedure, which is expected to consume its operand and produce a result in the range 0 to 1. Because these procedures are called at unpredictable times and in unpredictable environments, they must operate as pure functions without side effects. constitute the final device color value. That is, if The values d , ... d is 3, d , m 1 2 m d is 4, then d , d then , and , d , d are the red, green, and blue components; if m 2 3 1 1 2 d , and d are the cyan, magenta, yellow, and black components. 3 4 302 Chapter 6: Rendering

311 PLRM 2nd Edition January 25, 1994 Rendering 6.2 Conversions Among Device Color Spaces Each raster output device has a native device color space, which corre- , DeviceGray sponds to one of the PostScript language color spaces DeviceRGB DeviceCMYK . In other words, the device supports repro- , or duction of colors according to a gray-scale (monochrome), red-green- blue, or cyan-magenta-yellow-black model. If the device supports con- tinuous-tone output, reproduction occurs directly. Otherwise, it is accomplished by means of halftoning. The PostScript interpreter knows the native color space and other out- put capabilities of the device. It can automatically convert color values as specified in a document to the appropriate color values for the native color space of the device. For example, if a PostScript language program DeviceRGB color space, but the device supports specifies colors in the gray scale, such as a monochrome display, or CMYK, such as a color printer, the interpreter performs the necessary conversions. If a pro- gram specifies colors in the device’s native color space, no conversions are necessary. A program can also request explicit conversions among device color , currentrgbcolor spaces by executing the operators currentgray , currenthsbcolor , or , which return color values currentcmykcolor according to specific color spaces. These operators are described in sec- tion 4.8.2, “Device Color Spaces.” Conversions between DeviceRGB and DeviceGray are supported by all implementations. Conversions to and from DeviceCMYK are a Level 2 feature. Note These operators can convert colors only among device color spaces, not to or from CIE-based or special color spaces. The conversions described here do not involve use of transfer functions or halftone functions. When colors are to be rendered on the output device, the transfer functions and halftone functions are applied at a later stage to the output of the color conversion operation. When colors are simply read back by a PostScript language program by executing one of the above-mentioned operators, the transfer functions and halftone functions are not applied at all. The algorithms used to convert among device color spaces are very sim- ple. As perceived by a human viewer, the conversions produce only crude approximations of the original colors. Device color conversions ordinarily are not performed when a program specifies colors in CIE- 6.2 Conversions Among Device Color Spaces 303

312 PLRM 2nd Edition January 25, 1994 Rendering based color spaces; the CIE-based color rendering functions map directly to the device’s native color space (see section 6.1, “CIE-Based Color to Device Color”). 6.2.1 Conversion Between DeviceRGB and DeviceGray Black, white, and intermediate shades of gray can be considered special cases of RGB color. A gray-scale value is described by a single number: 0 corresponds to black, 1 to white, and intermediate values to different gray levels. A gray value is equivalent to an RGB value with all three components the same. In other words, the RGB color value equivalent to a specific gray value is simply: red = gray = gray green blue gray = The gray value for a given RGB value is computed according to the NTSC video standard. This standard determines how a color television signal is rendered on a black and white television. blue × gray = .3 × red + .59 × green + .11 Colors specified according to the HSB (hue-saturation-brightness) model are equivalent to those specified in the RGB model, but expressed in a different coordinate system called the “hexcone” model. See the bibliography. Either form of specification produces colors in the DeviceRGB color space. HSB is not a color space in its own right. 6.2.2 Conversion Between DeviceCMYK and DeviceGray Nominally, a gray value is the complement of the black component of CMYK. Therefore, the CMYK color value equivalent to a specific gray value is simply: cyan = 0.0 magenta = 0.0 yellow = 0.0 black = 1.0 – gray To obtain the gray value for a given CMYK value, one must take the contributions of all components into account. 304 Chapter 6: Rendering

313 PLRM 2nd Edition January 25, 1994 Rendering yellow = 1.0 – min (1.0, .3 + .59 × magenta + .11 × cyan + black ) gray × The interactions between the black component and the other three are explained below. 6.2.3 Conversion from DeviceRGB to DeviceCMYK Conversion of a color value from RGB to CMYK is a two-step process. The first step is described by the equations that express the relationship between red-green-blue and cyan-magenta-yellow. The second step is to use black generation and undercolor removal to generate a black com- ponent and alter the other components to produce a better approxima- tion of the original color. The subtractive color primaries , magenta , and yellow are the com- cyan . For example, a blue plements of the additive primaries red , green , and cyan ink subtracts the red component of white light. In theory, the con- version is very simple: = 1.0 – red cyan magenta = 1.0 – green = 1.0 – blue yellow For example, a color that is 0.2 red, 0.7 green, and 0.4 blue can also be expressed as 1.0 – 0.2 = 0.8 cyan, 1.0 – 0.7 = 0.3 magenta, and 1.0 – 0.4 = 0.6 yellow. Logically, only cyan, magenta, and yellow are needed to generate a printing color. An equal percentage of cyan, magenta, and yellow should create the equivalent percentage of black. In reality, colored printing inks do not mix perfectly; such combina- tions often form dark brown shades instead. It is often desirable to sub- stitute real black ink for the mixed-black portion of a color to obtain a truer color rendition on a printer. Most color printers support a black component (the K component of CMYK). Computing the quantity of this component requires some additional steps: • Black generation calculates the amount of black to be used when try- ing to reproduce a particular color. reduces the amount of cyan, magenta, and yellow • Undercolor removal components to compensate for the amount of black that was added by the black generation. 6.2 Conversions Among Device Color Spaces 305

314 PLRM 2nd Edition January 25, 1994 Rendering Flexibility in performing these functions is important for achieving good results under a variety of printing conditions. The PostScript lan- guage provides limited control over black generation and undercolor to color removal when converting from DeviceRGB DeviceCMYK spaces. Applications requiring finer control must specify colors in CIE- based color spaces and control conversion to CMYK by means of the CIE-based color rendering dictionary (see section 6.1, “CIE-Based Color to Device Color”). The complete conversion from RGB to CMYK is as follows, where k ) and UCR ( k ) are invocations of the black generation and under- BG ( color removal functions, respectively: = 1.0 – red c = 1.0 – m green = 1.0 – y blue = min ( c , m , k ) y cyan = min (1.0, max (0.0, c – UCR ( k ))) ))) k magenta = min (1.0, max (0.0, m – UCR ( yellow = min (1.0, max (0.0, – UCR ( k ))) y = min (1.0, max (0.0, BG( k ))) black The black generation and undercolor removal functions are defined as PostScript language procedures. The setblackgeneration and setundercolorremoval operators set these parameters in the graphics state. The interpreter calls these procedures when it needs to perform RGB to CMYK conversion. Each procedure is called with a single numeric operand and is expected to return a single numeric result. The procedures are called at unpredictable times, so they must operate as pure functions without side effects. k The operand of both procedures is , the minimum of the intermediate m , and y values that have been computed by subtracting the original , c green , blue , and red values from 1. Nominally, k is the amount of black that can be removed from the cyan, magenta, and yellow components and be substituted as a separate black component. The black generation function computes the black component as a operand or it function of the nominal k value. It can simply return its k can return a larger value for extra black, a smaller value for less black, or zero for no black at all. 306 Chapter 6: Rendering

315 PLRM 2nd Edition January 25, 1994 Rendering The undercolor removal function computes the amount that is to be subtracted from each of the intermediate m , and y values to produce c , the final cyan, magenta, and yellow components. It can simply return k operand or it can return zero (so no color is removed), some frac- its tion of the black amount, or even a negative amount, thereby adding to the total amount of ink. The component values that result from black generation and under- color removal are expected to be in the range 0 to 1. If a value falls out- side this range, the nearest valid value is substituted automatically, without error indication. This is indicated explicitly by invocations of and operations in the formulas given above. min max The correct choice of black generation and undercolor removal func- tions depends on the characteristics of the output device—for example, how inks mix. Each device is configured with default values that are appropriate for that device. 6.2.4 Conversion from DeviceCMYK to DeviceRGB Conversion of a color value from CMYK to RGB is a simple operation that does not involve the black generation or undercolor removal func- tions: black = 1.0 – min (1.0, red ) cyan + green magenta + black ) = 1.0 – min (1.0, blue = 1.0 – min (1.0, yellow + black ) In other words, the black component is simply added to each of the other components. Then those components are converted to their com- plementary colors by subtracting each of them from 1. 6.3 Transfer Functions A transfer function adjusts the values of color components to compen- sate for non-linear response in an output device and in the human eye. Each component of a device color space—for example, the red compo- nent of the DeviceRGB color space—is intended to represent the per- ceived lightness or intensity of that component in proportion to the numeric value. Many devices do not behave this way; a transfer func- tion can compensate for the device’s actual behavior. This operation is sometimes called gamma correction (not to be confused with the CIE- performed as part of CIE-based color ren- based gamut mapping function dering). 6.3 Transfer Functions 307

316 PLRM 2nd Edition Rendering January 25, 1994 In the sequence of steps for processing colors, the PostScript interpreter applies the transfer function after performing conversions between before applying the halftone function, if color spaces, if necessary, but necessary. A separate transfer function applies to each color compo- nent. There is no interaction between components. Transfer functions operate in the native color space of the output device regardless of the color space in which colors were originally specified. For example, for a CMYK device, the transfer functions apply to the device’s cyan, magenta, yellow, and black color components, even if the colors were originally specified in, say, the DeviceRGB or CIEBasedABC color space. There are three ways to specify transfer functions: • The settransfer operator establishes a single transfer function to be applied to all color components of the device. Most Level 1 imple- mentations support only a single transfer function. operator establishes four separate transfer func- setcolortransfer • The tions, one each for red, green, blue, and gray or their complements cyan, magenta, yellow, and black. An RGB device uses the first three; a monochrome device uses the gray transfer function only, and a CMYK device uses all four. setcolortransfer is supported in Level 2 and in certain Level 1 implementations, primarily those in color printers. • The sethalftone operator can establish transfer functions as optional entries in halftone dictionaries (see section 6.4.3, “Halftone Dictionar- ies”). This is the only way to set transfer functions for separation color components—those that are not primary colors for the device. Transfer functions specified in halftone dictionaries override those specified by settransfer or setcolortransfer . Halftone dictionaries are supported by all Level 2 and Display PostScript implementations. A transfer function is a PostScript language procedure that can be called with a number in the range 0.0 to 1.0 (inclusive) on the operand stack and must return a number in the same range. The procedure’s operand is the value of a color component in the device’s native color space, either specified directly or produced by conversion from some other color space. The procedure’s result is the transformed value that is to be transmitted to the device (after halftoning, if necessary). 308 Chapter 6: Rendering

317 PLRM 2nd Edition January 25, 1994 Rendering The operand and result of a transfer function are always interpreted as if the component were additive —red, green, blue, or gray. That is, larger (cyan, subtractive numbers indicate lighter colors. If the component is magenta, yellow, black, or a separation), the PostScript interpreter con- verts it to additive form by subtracting it from 1.0 before passing it to the transfer function. The result from the transfer function is always in additive form; it is passed on to the halftone function in this form. The PostScript interpreter calls transfer functions at unpredictable times and in unpredictable environments. A transfer function procedure must behave as a pure function. It must not depend on variable data other than its operand, and it must not have side effects. In addition to their intended use for gamma correction, transfer func- tions can be used to produce a variety of special, device-dependent effects. For example, on a monochrome device, the transfer function {1 exch sub} inverts the output colors, producing a negative rendition of the page. In general, this method does not work for color devices; inversion can be more complicated than merely inverting each of the components. Because the effects produced are device dependent, transfer functions should not be altered by a page description that is intended to be device independent. DeviceGray When the current color space is and the output device’s native color space is DeviceCMYK , the interpreter uses only the gray DeviceGray to transfer function. The normal conversion from DeviceCMYK produces 0 for the cyan, magenta, and yellow compo- nents. Those components are not passed through their respective trans- fer functions, but are rendered directly, producing output containing no colored inks. This special case applies only to colors specified in the DeviceGray color space. It exists for compatibility with existing applica- tions that use settransfer to obtain special effects on monochrome devices. 6.4 Halftones Halftoning is the process by which continuous-tone colors are approxi- mated by a pattern of pixels that can achieve only a limited number of discrete colors. The most familiar case of this is rendering of gray tones with black and white pixels, as in a newspaper photograph. 6.4 Halftones 309

318 PLRM 2nd Edition January 25, 1994 Rendering If halftoning is required, it occurs after all color components have been transformed by the appropriate transfer function. The input to the half- tone function consists of continuous-tone, gamma-corrected color components in the device’s native color space. The output consists of pixels representing colors the device can reproduce. Some devices can reproduce continuous-tone colors directly. For such devices, halftoning is not required. After gamma correction by the transfer functions, the color components are transmitted directly to the device. The PostScript language provides a high degree of control over details of the halftoning process. For example, in color printing, one must specify independent halftone screens for each of three or four color sep- arations. When rendering on low-resolution displays, one must have fine control over halftone patterns to achieve the best approximations of gray levels or colors, and to minimize visual artifacts. Remember that everything pertaining to halftones is, by definition, device Note dependent. In general, when an application provides its own halftone specifications, it sacrifices portability. Associated with every device is a default halftone definition that is appropriate for most applications. Only relatively sophisticated applications need to define their own halftones to achieve special effects. All halftones are defined in device space , unaffected by the current trans- formation matrix. For correct results, a PostScript language program that defines a new halftone must know the resolution and orientation of device space. The best choice of halftone parameters often depends on specific physical properties of the output device—for example, pixel shape, overlap between pixels, and effects of electronic or mechanical noise. 6.4.1 How Halftones Are Defined There are three ways to specify halftones: • The setscreen operator establishes a single halftone screen that is to be applied to all color components of the device. The halftone screen can be specified in only one way: as frequency, angle, and spot func- tion. Most Level 1 implementations support only a single halftone screen. 310 Chapter 6: Rendering

319 PLRM 2nd Edition January 25, 1994 Rendering setcolorscreen operator establishes four separate halftone • The screens, one each for red, green, blue, and gray or their complements cyan, magenta, yellow, and black. An RGB device uses the first three, a monochrome device uses the gray screen only, and a CMYK device setcolorscreen is supported in Level 2 and in certain uses all four. Level 1 implementations, primarily those in color printers. • The sethalftone operator installs a halftone dictionary, which can describe any of several types of halftones. The dictionary contains the parameters of the halftoning algorithm, either for all compo- nents together or for each component separately. It optionally con- tains other rendering controls, such as transfer functions. sethalftone is the most general way to specify halftones. Any halftone that can be defined in the other two ways can also be defined as a half- tone dictionary. However, halftone dictionaries are supported only in Level 2 and Display PostScript implementations, whereas setscreen (and sometimes setcolorscreen ) is available in Level 1 implementations. setscreen The operator specifies a halftone screen by three operands: frequency , angle , and spot function . These operands are interpreted the Frequency entries in a type 1 same as the SpotFunction , Angle , and halftone dictionary, described in section 6.4.4, “Spot Functions.” This is the only form of halftone specification supported in most Level 1 implementations. For compatibility between Level 1 and Level 2 implementations, the , setcolorscreen , setscreen , currentscreen , currentcolor- sethalftone screen , and currenthalftone operators interact in various ways to ensure reasonable behavior when a halftone that has been defined in one way is read out in a different way. The details of these interactions are given in the descriptions of the six operators. 6.4.2 How Halftone Screens Work The halftone functions supported by the PostScript language are based on the use of a halftone screen . A screen is defined by conceptually lay- ing a uniform rectangular grid of halftone cells over the device pixel array. Each pixel belongs to one cell of the grid; a halftone cell usually contains many device pixels. The screen grid is defined entirely in device space, unchanged by modifications to the current transforma- tion matrix (CTM). This property is essential for ensuring that adjacent areas colored by halftones are properly stitched together without “seams.” 6.4 Halftones 311

320 PLRM 2nd Edition Rendering January 25, 1994 For a black and white device, each cell of a screen can be made to approximate a shade of gray by painting some of the cell’s pixels black and some white. Numerically, the gray level produced within a cell is the ratio of the cell’s pixels that are white to the total number of pixels n pixels, then it can render in that cell. If a cell contains + 1 different n gray levels: all pixels black, one pixel white, two pixels white, ... n –1 in the range 0 to 1 pixels white, all n pixels white. A desired gray value g is produced by making ). pixels white, where i = floor( g × n i The foregoing description also applies to color output devices whose pixels consist of primary colors that are either completely on or com- pletely off. Most color printers, but not color displays, work this way. Halftoning is applied to each color component independently, produc- ing shades of that color. Color components are presented to the halftoning machinery in addi- form, regardless of whether they were originally specified in addi- tive tive (RGB or gray) or subtractive (CMYK or tint) form. Larger values of a color component represent lighter colors—greater intensity in an addi- tive device, such as a display, and less ink in a subtractive device, such as a printer. Transfer functions produce color values in additive form. See section 6.3, “Transfer Functions.” 6.4.3 Halftone Dictionaries A halftone dictionary is a dictionary object whose entries are parameters to the halftoning machinery. The graphics state includes a current half- tone dictionary, which specifies the halftoning process to be used by the painting operators. The operator currenthalftone returns the current halftone dictionary. sethalftone establishes a different halftone diction- ary as the current one. The halftone dictionary is a feature of Level 2 and Display PostScript implementations. In Level 1 implementations, setscreen operator controls halftoning in a more limited way. the A halftone dictionary is a self-contained description of a halftoning process. Painting operations, such as fill , stroke , and show , consult the current halftone dictionary when they require information about the halftoning process. The interpreter consults the halftone dictionary at unpredictable times. It can cache the results internally for later use. For these reasons, once a halftone dictionary has been passed to , its contents should be considered read only. Some of the sethalftone entries in the dictionary are procedures that are called to compute the required information. Such procedures must compute results that 312 Chapter 6: Rendering

321 PLRM 2nd Edition Rendering January 25, 1994 depend only on information in the halftone dictionary, not on outside information—for example, the graphics state itself—and they must not have side effects. Note This rules out certain techniques, such as the “pattern fill” example in the PostScript Language Tutorial and Cookbook, that depend on the spot function being executed at predictable times. Such techniques work for halftones defined by , but not for halftones defined by halftone dictionaries. setscreen See section 4.9, “Patterns,” for recommended ways to create device- independent patterns. Every halftone dictionary must have a HalftoneType entry whose value is an integer. This specifies the major type of halftoning process. The remaining entries in the dictionary are interpreted according to the type. Table 6.2 lists the standard halftone types. Table 6.2 Types of halftone dictionaries Type Semantics 1 Defines a single halftone screen by frequency , angle , and spot function . The setscreen operator, available in Level 1, also defines halftones this way, but it expects the parameters to be given as separate operands instead of being bundled into a halftone dictionary. Defines four separate halftone screens, one for each primary color 2 component. Each screen is given as a frequency, angle, and spot function. 3 Defines a single halftone screen directly by a threshold array at device resolution. 4 Defines four separate halftone screens, one for each primary color component. Each screen is given as a threshold array. 5( Level 2 ) Defines an arbitrary number of halftone screens, one for each color component, including both primary and separation (spot color) components. The keys in this dictionary are names of color components. The values are halftone dictionaries (type 1 or 3), each of which describes the halftone screen for a single color component. 6.4.4 Spot Functions A halftone dictionary whose is 1 defines a halftone screen HalftoneType setscreen frequency , angle , and spot function . The according to a operator, which is available in Level 1 implementations, defines a halftone screen as operands. Whichever way it given a frequency , angle , and spot function is defined, this type of halftone screen works as described below. The 6.4 Halftones 313

322 PLRM 2nd Edition Rendering January 25, 1994 features that can be specified by optional entries in the halftone dic- tionary are not available for screens defined by setscreen or by . setcolorscreen The halftone screen grid has a frequency (number of halftone cells per inch) and angle (orientation of the grid lines relative to the device coor- dinate system). The sethalftone or setscreen operator may make slight adjustments to the requested frequency and angle to ensure that the patterns of enclosed pixels remain constant as the screen cells are repli- cated over the entire page. Figure 6.1 Various halftoning effects ° 75/inch at 30 150/inch at 45 ° 100/inch at 45 ° 50/inch at 45 ° round dot screen round dot screen line screen round dot screen As a cell’s desired gray value varies from black to white, individual pix- els in the cell change from black to white in a well-defined sequence. If a particular gray includes certain white pixels, lighter grays will include the same white pixels and some additional pixels. The order in which pixels change from black to white for increasing gray levels is specified by a spot function , which is defined by a PostScript language procedure. The spot function describes the order of pixel whitening in an indirect way that minimizes interactions with screen frequency and angle. Consider a halftone cell to have its own coordinate system: The center . In this of the square is the origin and the corners are at 1 in x and y ± system, each pixel in the cell is centered at x and y coordinates that are both in the range –1 to 1. For each pixel, the interpreter pushes the pix- el’s coordinates on the operand stack and calls the spot function proce- dure. The procedure must return a single number in the range –1 to 1 that defines the pixel’s position in the ordering. 314 Chapter 6: Rendering

323 PLRM 2nd Edition January 25, 1994 Rendering The values the spot function returns are not significant. All that matters is the relative spot function values for different pixels. As a cell’s gray value varies from black to white, the first pixel whitened is the one whose spot function has the lowest value, the next pixel is the one with the next higher spot function value, and so on. If two pixels have the setscreen chooses their relative order arbi- same spot function value, trarily. There are relatively simple spot functions that define common halftone patterns. A spot function whose value is inversely related to the dis- tance from the center of the cell produces a “dot screen” in which the black pixels are clustered within a circle whose area is inversely propor- tional to the gray level. An example of such a spot function is: {180 mul cos exch 180 mul cos add 2 div} A spot function whose value is the distance from a line through the center of the cell produces a “line screen” in which the white pixels grow away from that line. More complex patterns are occasionally useful. Table 6.3 Entries in a type 1 halftone dictionary Key Type Semantics integer ( HalftoneType ) Must be 1. Required Frequency number ( Required ) Screen frequency, measured in halftone cells per inch in device space. ) Screen angle: Number of degrees by which the screen is to be rotated Required Angle number ( with respect to the device coordinate system. SpotFunction ( Required ) Procedure that defines the order in which device pixels within a screen procedure cell are adjusted for different gray levels. AccurateScreens ( Optional; Level 2 ) If present and the value is true , invokes a special halftone boolean algorithm that is extremely precise, but computationally expensive. ActualFrequency number ( Optional; Level 2 ) If present, sethalftone replaces its value with the actual frequency that was achieved. number ( Optional; Level 2 ) If present, sethalftone replaces its value with the actual angle ActualAngle that was achieved. TransferFunction procedure ( Optional; Level 2 ) Overrides the transfer function specified by settransfer or setcolortransfer . Required in a type 1 halftone dictionary that is used as an element of a type 5 halftone dictionary for a non-primary color component. 6.4 Halftones 315

324 PLRM 2nd Edition Rendering January 25, 1994 A type 1 halftone dictionary can optionally contain the key AccurateScreens , with a boolean value. If the value is true , a highly pre- cise halftoning algorithm is enabled; if it is false or if the AccurateScreens entry is not present, ordinary halftoning is used. Accu- rate halftoning achieves the requested screen angle and frequency with very high accuracy, whereas ordinary halftoning adjusts the angle and frequency so a single screen cell is quantized to device pixels. High accuracy is important mainly for making color separations on high-res- olution devices. However, it may be computationally expensive and so is ordinarily disabled. is true , sethalftone intentionally defers calling AccurateScreens When the spot function until the screen is needed by some operator (for example, fill ) that renders marks on the current page. This means that the sethalftone operator itself executes quickly. The potentially high cost of building the screen is not incurred until the screen is used. This values makes it convenient to obtain ActualFrequency and ActualAngle for various candidate screens without incurring the cost of building them. ActualFrequency and ActualAngle appear in the halftone If the entries dictionary, the sethalftone operator replaces their values with the actual frequency and angle that were achieved. The Frequency and Angle entries remain undisturbed; they reflect the values that were requested by the program. In principle, the PostScript language permits defining screens with arbi- trarily large cells—in other words, arbitrarily low frequencies. However, cells that are very large relative to device resolution or that are at unfa- vorable angles may exceed available memory. If this occurs, setscreen or executes a limitcheck error. The AccurateScreens feature sethalftone often requires very large amounts of memory to achieve highest accu- racy. See Appendix C for information on system parameters affecting halftone screens. 6.4.5 Threshold Arrays A halftone dictionary whose HalftoneType is 3 defines a halftone as an array of threshold values that directly control individual device pixels in a halftone cell. This provides a high degree of control over halftone rendering. Also, it permits halftone cells to be rectangular, whereas half- tone cells defined by a spot function are always square. Both of these capabilities are important for low-resolution display devices. 316 Chapter 6: Rendering

325 PLRM 2nd Edition Rendering January 25, 1994 A threshold array is much like a sampled image: It is a rectangular array of pixel values. However, it is defined entirely in device space, and the sample values always occupy 8 bits each. The pixel values nominally represent gray levels in the usual way, where 0 is black and 255 is white. The threshold array is replicated to tile the entire device space; each pixel of device space is mapped to a particular sample of the threshold array. On a bi-level device, where each pixel is either black or white, halftoning with a threshold array proceeds as follows: • For each device pixel that is to be painted with some gray level, con- sult the corresponding pixel of the threshold array. • If the desired gray level is less than the pixel value in the threshold array, paint the device pixel black; otherwise, paint it white. Gray values in the range 0 to 1 (inclusive) correspond to pixel values 0 to 255 in the threshold array. Note A threshold value of 0 is treated as if it were 1; therefore, a gray value of 0 paints all pixels black, regardless of what is in the threshold array. This scheme easily generalizes to monochrome devices with multiple bits per pixel. For example, if there are 2 bits per pixel, then each pixel can directly represent one of four different gray levels: black, dark gray, light gray, and white, encoded as 0, 1, 2, and 3, respectively. For each device pixel that is to be painted with some in-between gray level, the algorithm consults the corresponding pixel of the threshold array to determine whether to use the next-lower or next-higher representable gray level. In this situation, the samples in the threshold array do not represent absolute gray values, but rather gradations between two adja- cent representable gray levels. A halftone defined in this way can also be used with color displays that have a limited number of values for each color component. The red, green, and blue values are simply treated independently as gray levels. The same threshold array applies to each color. (This technique also works for a screen defined as a spot function, since the interpreter uses the spot function to compute a threshold array internally.) Table 6.4 Entries in a type 3 halftone dictionary Key Semantics Type HalftoneType integer ( Required ) Must be 3. Width integer ( Required ) Width of threshold array, in pixels. ) Height of threshold array, in pixels. Required Height integer ( 6.4 Halftones 317

326 PLRM 2nd Edition Rendering January 25, 1994 characters long. string Required ) Threshold values. This string must be width Thresholds height ( × The individual characters represent threshold values as described above. The order of pixels is the same as for a sampled image mapped directly onto device space, with the first sample at device coordinates (0, 0) and x coordinates coordinates. changing faster than y ( Optional; Level 2 ) If present, overrides the transfer function specified by procedure TransferFunction setcolortransfer or . Required in a type 3 halftone dictionary used as settransfer an element of a type 5 halftone dictionary for a non-primary color component. 6.4.6 HalftoneType 5 Dictionaries Some devices, particularly color printers, require different halftones for each of the device’s color components. Also, devices that can produce named separations may require individual halftones for each of those 5 dictionary allows specification of indi- separations. The HalftoneType vidual halftones for an arbitrary number of color components. A type 5 halftone dictionary contains entries whose keys are separation or colorant names and whose values are halftone dictionaries. The keys opera- setcolorspace are the separation names used as operands of the tor for the Separation color space (see section 4.8.4, “Special Color Spaces”). The values are type 1 or type 3 halftone dictionaries, each of which describes the halftone and transfer function for a single separation or colorant. Red , Green , and Blue in an RGB device; The primary colors are named , Magenta Cyan , Yellow , and Black in a CMYK device; and Gray in a monochrome device. In a device that supports named separations, non- primary separations can have arbitrary names. The keys can be either names or strings, which are treated equivalently. A type 5 halftone dictionary must also contain an entry whose key is Default . The value of this entry is the halftone dictionary to be used for any separation that does not have its own entry. When a type 1 or type 3 halftone dictionary appears as the value of an entry in a type 5 halftone dictionary, it applies only to a single color component. This is in contrast to such a dictionary appearing as the sethalftone main halftone dictionary (operand to ), which applies to all color components. 318 Chapter 6: Rendering

327 PLRM 2nd Edition January 25, 1994 Rendering If non-primary separations are requested when the current halftone is defined by any means other than a type 5 halftone dictionary, the gray screen and transfer function are used for all such separations. 6.4.7 Other Types of Halftone Dictionaries There are two additional standard halftone types. However, their use is not recommended because the same effects can be obtained using the type 5 halftone dictionary, described above. They are supported only for compatibility with existing Display PostScript applications. The type 2 halftone dictionary is similar to type 1, but it defines four halftone screens—as frequency, angle, and spot function—instead of just one. Each primary color has its own screen. In place of a Frequency entry, the dictionary has entries named , RedFrequency GreenFrequency BlueFrequency , and GrayFrequency . Likewise, in place , Angle and SpotFunction entries, the dictionary has entries of the , and so on. The optional entries of RedSpotFunction named RedAngle , a type 1 halftone dictionary are not available in a type 2 halftone dic- tionary. The type 4 halftone dictionary is similar to type 3, but it defines four halftone screens (as threshold arrays) instead of just one. Width , , and Thresholds are replicated for each color, just as in a type 2 Height halftone dictionary. Optional entries are not available. There are many techniques for rendering halftones in addition to those supported as a standard part of the PostScript language. Some tech- niques work well only with certain types of output device technology, or they require special hardware to work efficiently. Some products support special halftone techniques, in addition to the standard ones. The HalftoneType entry in the halftone dictionary selects the halftone technique to be used. It also determines how the other entries in the dictionary are to be interpreted. The set of available types and the meanings of specific types are product dependent. They are not described in this manual, but rather in product documentation. Ordinarily, a page description should not define halftone dictionaries with non-standard types; doing so ties the page description to a specific any product. Indeed, use of halftone dictionaries in a page description compromises device independence. 6.4 Halftones 319

328 PLRM 2nd Edition January 25, 1994 Rendering In some products, a device’s default halftone dictionary may have a non-standard type. This arises when a non-standard halftone technique is the one best suited to the device technology. A program that executes HalftoneType currenthalftone may obtain a halftone dictionary whose it doesn’t recognize. 6.5 Scan Conversion Details The final step of rendering is scan conversion . As discussed in section 2.2, “Scan Conversion,” the PostScript interpreter executes a scan conver- sion algorithm to paint graphics, text, and images in the raster memory of the output device. defined as part of The specifics of the scan conversion algorithm are not the PostScript language. Different implementations can perform scan conversion in different ways; techniques that are appropriate for one device may be inappropriate for another. Most scan conversion details are not under program control. Still, it is useful to have a general understanding of how scan conver- sion works. When creating applications that are intended to drive com- puter displays, one must pay some attention to scan conversion details. At the low resolutions that are typical of displays, variations of even one pixel’s width can have a noticeable effect on the appearance of painted shapes. The following sections describe the scan conversion algorithms that are typical of Level 2 and Display PostScript implementations from Adobe, including the basic rules and the effects of using the automatic stroke adjustment feature. Once again, these details are a standard part of not the PostScript language. 6.5.1 Scan Conversion Rules The following rules determine which device pixels a painting operation will affect. All references to coordinates and pixels are in device space. A “shape” is a path to be painted with the current color or with an image. Its coordinates are mapped into device space, but not rounded to device pixel boundaries. At this level, curves have been flattened to sequences of straight lines, and all “insideness” computations have been per- formed. 320 Chapter 6: Rendering

329 PLRM 2nd Edition January 25, 1994 Rendering Pixel boundaries always fall on integer coordinates in device space. A pixel is a square region identified by the coordinates of its minimum , x minimum y corner. A pixel is a half-open region, meaning that it includes half of its boundary points. More precisely, for any point x, y ), let i = floor( x whose real number coordinate is ( j = floor( y ). ) and The pixel that contains this point is the one identified as ( , j ). The i x’ , y’ ) region belonging to that pixel is defined to be the set of points ( j < such that i ≤ x’ < i + 1 and j ≤ y’ +1. Like pixels, shapes to be painted by operators such as fill stroke are or also treated as half-open regions that include the boundaries along their “floor” sides, but not along their “ceiling” sides. A shape is scan converted by painting any pixel whose square region intersects the shape, no matter how small the intersection is. This ensures that no shape ever disappears as a result of unfavorable place- ment relative to the device pixel grid, as might happen with other pos- sible scan conversion rules. The area covered by painted pixels is always at least as large as the area of the original shape. This scan conversion rule applies to both fill operations and to strokes with non-zero width. Zero-width strokes are done in a device- dependent manner that may include fewer pixels than this rule specifies. The region of device space to be painted by the image operator is deter- mined similarly to that of a filled shape, though not identically. The interpreter transforms the image source rectangle into device space and defines a half-open region, just as for fill operations. However, only those pixels whose centers lie within the region are painted. The posi- tion of the center of such a pixel—in other words, the point whose coor- dinate values have fractional parts of one-half—is mapped back into source space to determine how to color the pixel. There is no averaging over the pixel area; if the resolution of the source image is higher than that of device space, some source samples will not be used. For clipping, the clip region consists of the set of pixels that would be included by a fill . A subsequent painting operation affects a region that is the intersection of the set of pixels defined by the clip region with the set of pixels for the region to be painted. Scan conversion of character shapes is performed by a different algo- rithm than the one above. That font rendering algorithm uses hints in the character descriptions and techniques that are specialized to charac- ter rasterization. 6.5 Scan Conversion Details 321

330 PLRM 2nd Edition January 25, 1994 Rendering Automatic Stroke Adjustment 6.5.2 When a stroke is drawn along a path, the scan conversion algorithm may produce lines of non-uniform thickness because of rasterization effects. In general, the line width and the coordinates of the endpoints, transformed into device space, are arbitrary real numbers not quantized to device pixels. A line of a given width can intersect with a different number of device pixels, depending on where it is positioned. Figure 6.2 shows this. Figure 6.2 Rasterization without stroke adjustment line width line width path path 1 pixel resulting line resulting line For best results, it is important to compensate for the rasterization effects to produce strokes of uniform thickness. This is especially impor- tant in low-resolution display applications. To meet this need, Level 2 and Display PostScript implementations provide an optional stroke feature. When stroke adjustment is enabled, the line width adjustment and the coordinates of a stroke are automatically adjusted as necessary to produce lines of uniform thickness. The thickness is as near as possi- ble to the requested line width—no more than half a pixel different. Note If stroke adjustment is enabled and the requested line width, transformed into device space, is less than half a pixel, the stroke is rendered as a single-pixel line. This is the thinnest line that can be rendered at device resolution. It is equivalent to the effect produced by setting the line width to zero (see section 6.5.1, “Scan Conversion Rules”). Chapter 6: Rendering 322

331 PLRM 2nd Edition Rendering January 25, 1994 Because automatic stroke adjustment can have a substantial effect on the appearance of lines, an application must be able to control whether setstrokeadjust or not the adjustment is to be performed. The operator alters a boolean value in the graphics state that determines if stroke adjustment will be performed during subsequent stroke and related operators. 323 6.5 Scan Conversion Details

332 PLRM 2nd Edition January 25, 1994 Rendering 324 Chapter 6: Rendering

333 PLRM 2nd Edition January 21, 1994 Display PostScript Example 1.0 Example 2.0 Example 3.0 Example 4.0 Example 7.0 Example 5.0 Table 7.0 Example 6.0 7 CHAPTER Figure 7.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Display PostScript This chapter introduces the concepts and PostScript language operators specific to display applications. Display PostScript system features are not part of Level 2. The Display PostScript system provides application programs with a device-independent imaging model for displaying information on a screen. It is only a component of a complete application programming environment, consisting of: • The PostScript interpreter. • The Client Library, a C language interface to the basic facilities of the Display PostScript system. • , a preprocessor that facilitates invoking arbitrary PostScript pswrap language programs from a C program. • Window system support libraries, such as one for the X Window System™. • Operating system, runtime library, and libraries of higher-level tools. This chapter describes the PostScript language extensions that are sup- ported by the interpreter in a Display PostScript system. Other compo- nents of the application programming environment are described in a . The separate document, the Display PostScript System Reference Manual language extensions include: Multiple execution contexts . The Display PostScript system can support • the execution of multiple independent PostScript language programs at the same time. 325

334 PLRM 2nd Edition January 21, 1994 Display PostScript • User name encodings . The Client Library can dynamically encode arbi- trary name objects as small integers instead of as full text strings, resulting in improved efficiency. Support for windowing systems • . These features extend the imaging model to deal with special display-specific requirements, including incremental update, hit detection, and halftone phase adjustment. • Bitmap font coordination . The Display PostScript system provides sup- port for hand-tuned screen resolution bitmap fonts to improve legi- bility of text. 7.1 Multiple Execution Contexts The Display PostScript system can support multiple, concurrent execu- tion contexts. Each context has an environment consisting of stacks, local and global VM, graphics state, and certain variables, such as VM allocation mode and array packing mode. Except for VM, a context’s environment is entirely private to that context and is never visible to any other context. Under suitable conditions, a context’s VM can be shared with other contexts. 7.1.1 Creating Contexts Applications normally access the Display PostScript system through the Client Library , which includes procedures for creating, communicating with, and destroying PostScript execution contexts. The Client Library facilities are not part of the PostScript language definition; they are described in the Display PostScript System Reference Manual . When an application creates a context, it chooses whether the context is to share VM with some other existing context. The choices are: 1. Local and global VM are completely private to the context. 2. Local VM is private to the context, but global VM is shared with some other context. 3. Local and global VM are shared with some other context. 326 Chapter 7: Display PostScript

335 PLRM 2nd Edition Display PostScript January 21, 1994 The Client Library procedure that creates a context provides a means to specify how the new context’s VM is to be set up and which other con- text’s VM, if any, it is to share. A PostScript language program can also create a context by executing the fork operator, which always uses method 3. Method 1 creates a context that is completely isolated from other con- , and other texts. The context has its own private userdict , globaldict standard dictionaries, all of which have their standard initial contents. A context that is to operate as a “job server,” supporting the encapsu- lated job model described in section 3.7.7, “Job Execution Environ- ment,” must be created by method 1, because the semantics of job encapsulation conflict with the semantics of shared VM. Method 2 creates a context with its own private local VM but sharing the global VM of one or more other contexts. In other words, objects in local VM, such as userdict , are private to the context; objects in global VM, such as globaldict and GlobalFontDirectory , are shared with the other contexts. When one context modifies the value of a global object, the effect is immediately visible to the other contexts. Method 3 creates a context that shares both the local VM and the glo- bal VM of one or more other contexts. When one context modifies the object in VM, the effect is immediately visible to the other any value of contexts. 7.1.2 Context Operators context is an integer that identifies a Post- For the context operators, a Script execution context. Each context has a unique identifier, whether it was created by calling a Client Library procedure or by executing the fork operator. This integer identifies the context during communication between the application and the Display PostScript system, and during execution of the join and detach operators. Identifiers for contexts that have terminated become invalid and are not reused during the lifetime of any currently active session. The currentcontext operator returns the identifier for the context that is executing. The fork operator creates a new context that shares the local and global is a VM of the context that executes fork . One of the operands to fork procedure the new context is to execute. The remaining operands are used to initialize the new context’s operand stack. 7.1 Multiple Execution Contexts 327

336 PLRM 2nd Edition January 21, 1994 Display PostScript join fork The operator waits for a context that was previously created by to return from its top-level procedure. It then copies that context’s operand stack to the caller’s operand stack and destroys the context. If there is no need for the context to return results when it terminates, it can declare this by means of the detach operator. suspend its own execution by any of a variety of means: A context can wait execute the monitor , or yield operators (described below) or return , join . The context retains the state from its top-level procedure to await a it had at the moment of suspension and can ordinarily be resumed from the point of suspension. quit by executing the A context can terminate operator or as a result of an explicit termination request from the Client Library. Termination also occurs if an error occurs that is not caught by an explicit use of stopped . When a context terminates, its stacks are destroyed, its stan- dard input and output files are closed, and its context identifier becomes invalid. There is no hierarchical relationship among contexts. Termination of a context has no effect on other contexts that it may have created. An integer that identifies a context has the same meaning in every context; it may be referenced in a context different from the one that created it. An invalidcontext error occurs if an invalid context identifier is pre- sented to any of the context operators or if certain other improper con- ditions are detected. See section 7.1.4, “Programming Restrictions.” 7.1.3 Context Synchronization When multiple contexts share objects in a single VM, they require a way to synchronize their activities. To facilitate this, the language includes two special types of synchronization objects and several opera- tors for manipulating them. A lock is a semaphore for mutual exclusion. Cooperating contexts can use it to guard against concurrent access to data that they are sharing. A context acquires a lock before accessing the data and releases it after- ward. During that time, other contexts are prevented from acquiring the lock—they cannot access the data when it is in a possibly inconsis- tent state. The association between a lock object and the data protected by the lock is entirely a matter of programming convention. 328 Chapter 7: Display PostScript

337 PLRM 2nd Edition Display PostScript January 21, 1994 condition is a binary semaphore that cooperating contexts can use to A synchronize their activity. One or more contexts can wait on a condition—in other words, suspend execution for an arbitrary length of time until notified by another context that the condition has been sat- isfied. Once again, the association between the condition object and the event or state it represents is a matter of programming convention. are distinct types of objects, created by The objects lock and condition the operators lock and condition , respectively. They are composite objects in the sense that their values occupy space in VM separate from the objects themselves. When a lock or condition object is stored in multiple places, all the instances share the same value. However, the values of locks and conditions can be accessed only by the synchroniza- tion operators. Locks and conditions are ordinarily used together in a stylized way. The monitor operator acquires a lock (waiting if necessary), executes an wait arbitrary PostScript language procedure, then releases the lock. The operator is executed within a procedure invoked by monitor . It releases the lock, waits for the condition to be satisfied, and reacquires the lock. The notify operator indicates that a condition has been satisfied and resumes any contexts waiting on that condition. The recommended style of use of wait and notify is based on the notion that a context first waits for a shared data structure to reach some desired state, then performs some computation based on that state, and finally alerts other contexts of any changes it has made to the data. A lock and a condition are used to implement this protocol. The lock pro- tects against concurrent access to the data; the condition is used to notify other contexts that some potentially interesting change has occurred. Note Locks and conditions are treated separately because one may want to have several conditions that represent different states of the same shared data. 7.1 Multiple Execution Contexts 329

338 PLRM 2nd Edition Display PostScript January 21, 1994 This protocol is illustrated by the following two program fragments, which are likely to be executed by different contexts. Example 7.1 /lock1 lock def /cond1 condition def lock1 { { ... boolean expression testing monitored data ... {exit} {lock1 cond1 wait} ifelse } loop ... computation involving monitored data ... } monitor Example 7.2 lock1 { ... computation that changes monitored data ... cond1 notify } monitor Example 7.1 executes monitor to acquire the lock named lock1 ; it must do so to safely access the shared data associated with it. The program boolean expression has become true ; it waits on then checks whether the the condition named cond1 (repeatedly, if necessary) until the expres- sion evaluates to true . Now, while still holding the lock, it performs some computation based on this state of the shared data. It might alter the data in such a way that the boolean expression would evaluate false . . monitor Finally, it releases lock1 by leaving the procedure invoked by Example 7.2 acquires lock1 and then performs some computation that alters the data in a way that might favorably affect the outcome of the . It then notifies cond1 and releases . If there is a boolean expression lock1 context suspended at the wait in Example 7.1, it now resumes and gets boolean expression . (If multiple contexts another chance to evaluate the cond1 , the notify resumes all of them; however, only are waiting for one context at a time gets to acquire lock1 .) Note that it is unsafe to assume that the state tested by the boolean expression true immediately after resumption from a wait . Even if it is was true at the moment of the notify , it might have become false due to intervening execution by some other context. Notifying cond1 does not certify that the value of the boolean expression is true , only that it might true be . Programs that conform to this protocol are immune from dead- locks due to “lost notifies” or malfunctions due to “extra notifies.” 330 Chapter 7: Display PostScript

339 PLRM 2nd Edition January 21, 1994 Display PostScript A program must not make any assumptions regarding context schedul- ing. In some environments, the PostScript interpreter switches control among contexts pre-emptively and at any time; therefore, program exe- cution in different contexts may be interleaved arbitrarily. Pre-emption may occur within a single operator, such as one that causes a PostScript language procedure to be executed or that reads or writes a file. To ensure predictable behavior, contexts must use the synchronization primitives to control access to shared data. In any environment that supports concurrent execution of indepen- dent threads of control, there is the possibility of deadlock. The most familiar form of deadlock occurs among two or more contexts when each waits for a notification from the other or each attempts to acquire a lock already held by the other. Another deadlock situation arises when all available communication buffers become filled with data for a context that is waiting for notification from some other context, but the other context cannot proceed because it has no way to communi- cate. Such deadlocks can be avoided only through careful system and application design. The synchronization primitives can be used to synchronize access to shared data in either local or global VM. Of course, this requires prear- rangement among all contexts involved; the lock and condition objects used for this purpose should be in the same VM as the data being shared. 7.1.4 Programming Restrictions Each context has its own private pair of standard input and output files. That is, different contexts obtain different file objects as a result of exe- operator to the special device file cuting currentfile or applying the names and %stdout . A context must not attempt to make its %stdin standard input and output files available for use by other contexts. Doing so will cause unpredictable behavior. The behavior of the save and restore operators varies according to how the executing context was created. In the case of an isolated context, created by method 1 as described in section 7.1.1, “Creating Contexts,” the outermost save apply to both global and local VM; and restore save and restore apply only to local VM. This supports the nested encapsulated job model. In the case of a context that can share VM with other contexts, created always apply only to local VM, by method 2 or 3, save and restore never to global VM. Additionally, when multiple contexts share local 7.1 Multiple Execution Contexts 331

340 PLRM 2nd Edition Display PostScript January 21, 1994 save restore become restricted. VM (method 3), the semantics of and restore is logically to restore local VM to The operation performed by save was executed. If one context does this, another con- its state when text sharing the same local VM might observe the effect of the restore at some totally unpredictable time during its own execution. That is, its recent computations would be undone unexpectedly. If any context executes save , all other contexts sharing the same local VM are suspended until the original context executes the matching . This ensures that the restore does not disrupt the activities of restore those other contexts. This restriction applies only to contexts sharing the same local VM. Contexts that have different local VMs proceed unhindered. Note In contexts that can share VM, save and restore never affect global VM. Therefore, contexts with separate local VMs but shared global VM cannot restore . interfere with each other by executing save and There are some restrictions on the synchronization operators that a save pending. For context may execute while it has an unmatched example, attempting to acquire a lock that is already held by another context sharing the same local VM is not allowed because it would surely lead to deadlock. If a context terminates when it has an unmatched save pending, an automatic restore is executed, allowing other contexts to proceed. As a practical matter, save and restore are not of much use when a local VM is shared among multiple contexts. Programs organized this way should avoid using save . On the other hand, programs and restore and restore without save organized as one local VM per context can use restriction. The semantics described above are designed to maintain compatibility with existing page descriptions and font programs. 7.2 Encoded User Names Section 3.12, “Binary Encoding Details,” discusses binary token and binary object sequence encodings. Both encodings provide optional ways to represent names as small integers instead of as full text strings. . Care- Such an integer is either a system name index or a user name index ful use of encoded names can result in substantial space savings and execution performance improvement. 332 Chapter 7: Display PostScript

341 PLRM 2nd Edition Display PostScript January 21, 1994 name index As discussed in section 3.12.3, “Encoded System Names,” a is a reference to an element of a name table already known to the Post- system name index is an index into the system name Script interpreter. A table, which is built-in and has a standard value. Encoded system names are supported by all Level 2 implementations. is an index into the user name table, whose contents A user name index may be defined by a PostScript language program using the defineusername operator. This provides efficient encodings of arbitrary names that are used frequently. However, there are various restrictions on user name encodings, making them suitable for use only with the Display PostScript system. Note Do not confuse encoded user names with user objects, described in section 3.7.6, “User Objects,” and available in all Level 2 implementations. The user name index facility is intended for use only during interactive sessions, where the application generates PostScript language com- mands that are immediately consumed by the Display PostScript sys- tem. It should not be used in a PostScript language program that must stand by itself, such as one sent to a printer or written to a file for later If a program contains user name index encodings, it cannot be composed use. with or embedded in other PostScript language programs, and it cannot easily be translated to the ASCII encoding. The Client Library has an option to disable generation of user name encodings and produce plain text names always. This option may be invoked dynamically in an applica- tion program to produce a PostScript language program that is to be captured in a file or diverted to a printer. As with everything else related to binary encodings, encoded names are intended for machine generation only. The pswrap and Client Library facilities are the preferred means for application programs to generate binary-encoded programs. Those facilities maintain the user name table automatically and can encode names using both the system and user name tables. An application should not attempt to alter the user name table itself, because that would interfere with the activity of the Client Library. The meaning of a given user name index is local to a specific PostScript execution context—precisely, to a context’s local VM. If several con- texts share the same local VM, a user name index defined in one con- text may be used in another context. In this case, it is the application programmer’s responsibility to synchronize execution of the contexts so definition and use occur in the correct order. 7.2 Encoded User Names 333

342 PLRM 2nd Edition Display PostScript January 21, 1994 defineusername accumulate Entries placed in the user name table by during the lifetime of the context’s local VM; they do not obey and save restore , and they cannot be removed or replaced. These restrictions are intentional: they permit the Client Library to manage user name defi- nitions without understanding the semantics of the PostScript language program being generated. If the scanner encounters a binary encoded system or user name index undefined error. for which no name has been defined, it generates an The name object produced is system n or user n . For example, if entry number 123 is missing from the user name table, the name object pro- user123 . duced is 7.3 Graphics and Window Systems For each windowing system that uses the Display PostScript system for graphical output, there is a collection of operators for doing such things as specifying the window that is to be affected by subsequent painting operators, for scrolling the contents of the window, for obtaining input events (keystrokes and mouse clicks), and so on. These operators are because their syntax and semantics vary accord- window system specific ing to the properties and capabilities of the underlying window system. They are not documented in this manual, but in manuals for specific window systems or operating systems. In addition to the window system specific operators, there are several operators that are window related but have a consistent meaning across all window systems. They fall into the following categories: • View clipping , to control the areas affected by incremental updates. • Hit detection , to associate cursor positions with displayed objects. • Halftone phase adjustment , to compensate for the effect of scrolling. , to obtain characteristics of the display device. • Device information The Display PostScript system supports these features with all window- ing systems. 334 Chapter 7: Display PostScript

343 PLRM 2nd Edition Display PostScript January 21, 1994 7.3.1 View Clipping Interactive applications frequently make incremental updates to the displayed image. Such updates arise from changes to the displayed graphical objects and from window system manipulations that cause formerly obscured objects to become visible. For efficiency’s sake, it is desirable for the application to redraw only those graphical objects that are affected by the change. This function is assisted by operators that do view clipping. One way to handle incremental updating is to define a path that encloses the changed areas of the display, then redraw only those graphical objects that are enclosed or partially enclosed within the path. To produce correct results, it is necessary to impose this path as a clipping path while redrawing. Otherwise, portions of objects that are redrawn might incorrectly obscure objects that are not redrawn. This clipping could be accomplished by adjusting the clipping path in the graphics state in the normal way. However, this is not particularly convenient, because the program that imposes the clipping and the program that is executed to redraw objects on the display may have dif- ferent ideas about what the clipping path should be. This problem becomes particularly acute given the ability to switch entire graphics states arbitrarily. To alleviate this, the Display PostScript system provides another level of clipping, the , that is entirely independent of the graphics state. view clip Objects are rendered on the device only in areas that are enclosed by both the current clipping path and the current view clipping path. The view clipping path is part of the PostScript execution context, not the graphics state. A context initially has no view clipping path (see initviewclip in Chapter 8). The operators that alter the view clipping path do not affect the clipping path in the graphics state or vice versa. The view clipping path is not affected by and gsave grestore . However, a restore will reinstate the view clipping path that was in effect at the time of the matching save . View clips do not nest; rather, a new view clipping path replaces the existing one. Note View clipping is temporarily disabled when the current output device is a setcachedevice . mask device, such as the one installed by 7.3 Graphics and Window Systems 335

344 PLRM 2nd Edition Display PostScript January 21, 1994 The following operators manipulate view clips: • viewclip replaces the current view clipping path by a copy of the cur- rent path in the graphics state. • eoviewclip is similar to viewclip , but it uses the even-odd rule instead of the non-zero winding number rule to determine the inside of the current path. See section 4.5.2, “Filling.” rectviewclip replaces the current view clipping path by a rectangular • path. See section 4.6.5, “Rectangles.” • initviewclip replaces the current view clipping path with one that encloses the entire imageable area of the output device. • viewclippath replaces the current path by a copy of the current view clipping path. Hit Detection 7.3.2 Interactive windowing systems usually have some system specific method of detecting the movement and clicking of pointing devices. Some means is required to associate this information with the position of graphical objects that are visible on the display. This operation is hit detection . called The insideness testing operators, such as and instroke , can assist in infill hit detection. Those operators are a standard part of Level 2 implemen- tations, not just of Display PostScript. They are described in section 4.5.3, “Insideness Testing.” Having obtained the user space coordinates of some interesting point, a program can: • Determine whether that point would be painted by filling or strok- ing some object defined by either the current path or a user path. • Determine whether an aperture surrounding the point would inter- sect any painted area of the object. The aperture defines a “sensitive area,” that can have various shapes such as a circle or a diamond. If a window system specific extension provides a way for a PostScript language program to receive input events directly, the program itself can perform operations such as mouse tracking and hit detection. With some window systems, however, the application always receives input events. In that case, the application must either perform such computa- tions itself or issue queries to the Display PostScript system. This deci- 336 Chapter 7: Display PostScript

345 PLRM 2nd Edition Display PostScript January 21, 1994 sion involves a trade-off between performance and application complexity. One possible approach is for the application to perform hit detection itself for simple shapes, but to query for more complex shapes. Some window systems report the coordinates of an input event in a window coordinate system that is translated from the PostScript inter- wtranslation preter’s device space. The operator returns the amount of this translation. A PostScript language program can shift the coordi- nates by this amount, then use itransform to transform them into user space for testing by means of the insideness testing operators. Halftone Phase 7.3.3 Normally, the halftone screen tiles the device space starting at the device space origin. That is, the halftone grid is aligned such that the lower-left corner of the lower-left halftone cell is positioned at (0, 0) in device space, independent of the value of the current transformation matrix. This ensures that adjacent gray areas will be painted with half- tones having the same phase, avoiding “seams” or other such artifacts. On a display, the phase relationship between the halftone grid and device space must be more flexible. This need arises because most win- dow systems provide a scrolling operation in which the existing con- tents of raster memory are copied from one place to another in device space. This operation can alter the phase of halftones that have already been scan converted. It is necessary to alter the phase of the halftone generation algorithm correspondingly so that newly painted halftones will align with the existing ones. In the Display PostScript system, the graphics state includes a pair of halftone phase and one for y . These integers define x parameters, one for an offset from the device space origin to the halftone grid origin. Of course, the halftone grid does not actually have an origin, so the offset modulo the width and height of the halftone cell. values are interpreted some halftone cell will have its lower-left corner at They ensure that y x , ) in device space. ( The intended use of the halftone phase operators and sethalftonephase currenthalftonephase is with window system operations that perform scrolling. If the application scrolls the displayed image by ( dx , dy ) pixels in device space, it should simply add dx and dy to the halftone phase the size parameters; it should not worry about computing them modulo of the halftone cell. This has the correct effect even if the displayed image is composed of several different halftone screens. 7.3 Graphics and Window Systems 337

346 PLRM 2nd Edition Display PostScript January 21, 1994 The halftone phase is defined to be part of the graphics state , not part of the device. This is because an application may subdivide device space into multiple regions that it scrolls independently. A recommended technique is to associate a separate gstate (graphics state) object with each such region. This object carries all the parameters required to paint within that region, including the halftone phase. Altering the halftone phase also alters the placement of any patterns (see section 4.9, “Pat- that were previously instantiated by makepattern terns”). This ensures that in areas painted with the same pattern before and after the halftone phase adjustment, the pattern cells will align. The current halftone phase does not affect makepattern itself; rather, changes to the halftone phase affect the placement of existing patterns. 7.3.4 Device Information A program may require information about certain properties of the ras- ter output device, such as whether or not it supports color and how many distinguishable color or gray values it can reproduce. A PostScript language program that is a page description should not need such infor- mation; using it compromises device independence. However, an inter- active application may need to vary its behavior according to the available display technology. For example, a computer aided design application may use stipple patterns on a binary black-and-white dis- play, but separate colors on a color display. The deviceinfo operator returns a dictionary whose entries describe static information about the device. (Dynamic information must be read from the graphics state or obtained through operators such as wtranslation .) Some of the entries in this dictionary have standard names that are described in Table 7.1; others may have meanings that are device dependent. Most entries are optional and are present only if they are relevant for that type of device. Table 7.1 dictionary Entries in the deviceinfo Type Semantics Key Number of independent color components: Colors integer 1 Black-and-white or gray scale only 3 Red, green, and blue Red, green, blue, and gray or their complements: cyan, magenta, yellow, 4 and black, as is typically used in printers. 338 Chapter 7: Display PostScript

347 PLRM 2nd Edition January 21, 1994 Display PostScript GrayValues integer Number of different gray values that individual pixels can reproduce without halftoning. For example: 2 Binary black-and-white device 256 8 bits-per-pixel, gray-scale device. integer RedValues Number of different red values that individual pixels can reproduce, independent of other colors. GreenValues integer Number of different green values. integer BlueValues Number of different blue values. ColorValues integer Total number of different color values that each pixel can reproduce. If this entry is present and the entries for gray, red, green, and blue are absent, this means the color components cannot be varied independently, only in combination. 7.4 Bitmap Fonts In display systems, the resolution of the device is typically quite low when compared with printers and typesetters. Resolutions in the range of 60 to 100 pixels per inch are common. When characters are pro- duced algorithmically from outlines in typical sizes (10 to 12 points), the results are often not as legible as they must be for comfortable read- ing. The usual way to deal with this problem is to use screen fonts con- sisting of bitmap characters that have been tuned manually. The hand tuning increases legibility, although possibly at the expense of fidelity to the original character shapes. The Display PostScript system includes the ability to take advantage of hand-tuned bitmap fonts when they are available. This facility is fully integrated with the font machinery. Its operation is almost totally invis- ible to a PostScript language program. When a program sets text by executing an operator such as show , this is what happens internally: 1. The PostScript interpreter consults the font cache. 2. If the character is not there, the interpreter consults the current device, requesting it to provide a bitmap form of the character at the required size. 3. If the device can provide such a bitmap, it does so. The PostScript interpreter places the bitmap in the font cache for subsequent use. 7.4 Bitmap Fonts 339

348 PLRM 2nd Edition Display PostScript January 21, 1994 4. If there is no such character, the interpreter executes the character description, placing the scan converted result in the font cache. The mechanism by which bitmap characters are provided by a device is not part of the language and is entirely hidden from a PostScript lan- guage program. The conventions for locating and representing bitmap characters are environment dependent; they vary from one window system to another. Re-encoding a font preserves the association with bitmap characters. Most other modifications to a font dictionary destroy the association. Bitmap fonts are typically provided in one orientation and a range of sizes from 10 to 24 points. Beyond 24 points, characters scan converted from outlines are perfectly acceptable. The PostScript interpreter can usually choose a bitmap character whose size is sufficiently close to the one requested and render it directly. Associated with each hand-tuned bitmap is a width —a displacement from the origin of the character to the origin of the next character. This inter- width is also hand-tuned for maximum legibility; it is an integer preted in device space. It is different from the width produced when the same character is scan converted from the font definition, because that width (the ) is defined by a real number scaled according scalable width to the requested font size. Note Hand-tuned bitmaps are carefully designed so the bitmap widths and scalable widths are as similar as possible when averaged over large amounts of text. To achieve fidelity between displays and printers when rendering char- acters, an application must use the scalable widths to position charac- ters on the display. Unfortunately, this leads to uneven letter spacing due to the need to round character positions to device pixel boundaries. At display resolution, this unevenness is objectionable. On the other hand, using the integer bitmap widths to produce evenly spaced text on the display leads to incorrect results on the printer. One solution is to use integer widths for spacing within a word, but to use scalable widths for word-positioning and word-wrapping. This pro- vides correctness at the cost of maintaining two current points. Many word processing and page layout programs use the following technique when rendering text on the display: • Set the characters according to their integer bitmap widths, but keep track of the accumulated difference between the bitmap widths and the true scalable widths. 340 Chapter 7: Display PostScript

349 PLRM 2nd Edition January 21, 1994 Display PostScript • Adjust the spaces between words to compensate for the accumulated error. The most accurate way to do this is to compute the error for an entire line and then distribute the accumulated error among all the spaces in that line. This technique allows minor variation between display and printer within a line but maintains fidelity on a line-by-line basis. The Display PostScript system determines whether to use bitmap widths or scalable widths for a font by checking the BitmapWidths entry in the font dictionary. If this entry is present, it must have a bool- ean value: true indicates that bitmap widths are to be used if available; false indicates that scalable widths are to be used always. If the entry is not present or if the device does not provide bitmaps for this font, scal- able widths are always used. The hand-tuned bitmaps are ordinarily used at rotations that are multi- ples of 90 degrees (0, 90, 180, and 270) relative to device space. In all other cases, the scan converted outlines are used. There is usually a dif- ference in appearance between the hand-tuned bitmaps and the scan converted outlines for a given character at a given size. If this difference is found to be objectionable, the application can request that trans- formed characters be produced by transforming the bitmaps instead of scan converting the transformed outlines. Hand-tuned bitmaps are provided in a range of discrete sizes. When a size is requested that doesn’t match the hand-tuned bitmap size exactly, but lies between two discrete sizes, one of the discrete sizes is used and its widths are scaled accordingly. An application can request that the bitmaps be scaled for these in-between sizes or that the scan converted outlines be used. There are three entries that can be added to a font dictionary to control the behavior for each of three cases: ExactSize , InBetweenSize , and TransformedChar . Each entry’s value is an integer code: 0 Use outlines. 1 Use the discrete size directly. Transform the discrete size. 2 7.4 Bitmap Fonts 341

350 PLRM 2nd Edition January 21, 1994 Display PostScript The entries are interpreted as follows: • ExactSize determines what to do when there is an exact match between the size requested and a hand-tuned bitmap, the user coor- dinate system axes are perpendicular to each other, the scale is uni- form in x and y , and the angle of rotation is a multiple of 90 degrees. (Default value: 1) • InBetweenSize determines what to do when a size requested falls between discrete hand-tuned bitmap sizes under the same condi- . (Default value: 0) ExactSize tions as • determines what to do for any size request when TransformedChar the transformation is other than the ones described for ExactSize . (Default value: 0) Since font dictionaries are read-only, the usual way to change whether bitmap widths are used for a font and to control their behavior is to cre- ate a copy of the font dictionary, modify the copy, and execute a new definefont . Example 7.3 creates a copy of the Helvetica font and adds the BitmapWidths key. Example 7.3 /Helvetica findfont dup length 1 add dict begin {1 index /FID ne {def} {pop pop} ifelse} forall /BitmapWidths true def currentdict end /Helvetica-BitmapWidths exch definefont pop 342 Chapter 7: Display PostScript

351 PLRM 2nd Edition January 26, 1994 Operators Example 1.0 Example 2.0 Example 3.0 Example 4.0 Example 8.0 Example 5.0 Table 8.0 Example 6.0 8 CHAPTER Figure 8.0 Example 7.0 Example 8.0 Example 9.0 Example 10.0 Operators This chapter contains detailed information about all the standard oper- ators in the PostScript language. It is divided into two parts. First, there is a summary of the operators, organized into groups of related functions. The summary is intended to help locate the operators needed to perform specific tasks. Second, there are detailed descriptions of all operators, organized alpha- betically by operator name. Each operator description is presented in the following format: operator operator result ... result ... operand operand operand 1 1 n m 2 Detailed explanation of the operator. Example An example of the use of this operator. ⇒ designates the values left on the operand stack by the example. The symbol Errors: A list of errors that this operator might execute. See Also: A list of related operators. operand operand are through At the head of an operator description, 1 n operand the operands that the operator requires, with being the top- n most element on the operand stack. The operator pops these objects from the operand stack and consumes them. After executing, the opera- tor leaves the objects result result through result on the stack, with m m 1 being the topmost element. 343

352 PLRM 2nd Edition Operators January 26, 1994 Normally, the operand and result names suggest either their types or their uses. Table 8.1 summarizes names (other than basic type names) that appear commonly. Table 8.1 Operand and result types Name Description angle Angle (in degrees) any Value of any type bool Boolean ( true or false ) value context Integer representing an execution context dict Dictionary object font Font dictionary form Form dictionary halftone Halftone dictionary int Integer number Array of six numbers describing a transformation matrix matrix Number (integer or floating point) num numarray Array of numbers numstring Encoded number string pattern Pattern dictionary proc Procedure (executable array or executable packed array) real Floating point (real) number userpath Array of path construction operators and their operands Some operators are polymorphic: their operands may be any of several types. For example, the notation file | proc | string indicates an operand that is a file, procedure, or string. The notation “ ” indicates the bottom of the stack. The notation “–” in the operand position indicates that the operator expects no oper- ands, and a “–” in the result position indicates that the operator returns no results. 344 Chapter 8: Operators

353 PLRM 2nd Edition January 26, 1994 Operators The documented effects on the operand stack and the possible errors are those produced directly by the operator itself. Many operators invoke arbitrary PostScript language procedures. Such procedures can have arbitrary effects that are not mentioned in the operator descriptions. Note In several descriptions of operators, the semantics of an operator are described as “being equivalent to” a PostScript language program using lower-level operators. Unless explicitly documented to the contrary, operator definitions are independent; redefining an operator name does not change the behavior of any other operator. The PostScript language consists of three distinct groups of operators: Level 1, Level 2, and Display PostScript operators. This chapter clearly identifies Level 2 and Display PostScript operators with the following icons: LEVEL 2 Level 2 operator DPS Display PostScript operator Level 1 operators are not identified with a specific icon. Note that some Level 2 operators are present in Level 1 implementations that contain various language extensions; see Appendix A for details. 345

354 PLRM 2nd Edition Operators January 26, 1994 8.1 Operator Summary Operand Stack Manipulation Operators – discard top element any pop exchange top two elements any exch any any any 1 2 1 2 any dup any any duplicate top element elements ... any n n copy any duplicate top ... any ... any any any 1 n 1 n 1 n n any index any ... any ... any any duplicate arbitrary element 0 0 n n n times a j ... a elements up n j roll a n ... a roll a ... a n–1 0 0 n–1 j mod n (j–1) mod n any ... any clear discard all elements n 1 any count elements on stack ... any n count any ... any 1 n 1 n – mark mark push mark on stack mark discard elements down through ... obj – cleartomark mark obj n 1 mark obj mark count elements down to counttomark mark obj ... obj n ... obj 1 n n 1 Arithmetic and Math Operators num num add sum num plus num 2 1 2 1 num num div quotient num divided by num 1 2 1 2 quotient int int integer divide idiv 1 2 int mod remainder int mod int int 2 1 2 1 num mul product num times num num 2 1 2 1 num num num sub difference num minus 1 2 2 1 num num abs num absolute value of 2 1 1 neg num negative of num num 1 2 1 num num ceiling num ceiling of 2 1 1 num num floor num floor of 2 1 1 num round to nearest integer num num round 2 1 1 truncate remove fractional part of num num num 1 1 2 real square root of num sqrt num num den angle arctangent of num / den in degrees atan angle cos real cosine of angle (degrees) angle sin real sine of angle (degrees) base exponent real raise base to exponent power exp num ln real natural logarithm (base e ) num real logarithm (base 10) log – rand int generate pseudo-random integer int srand – set random number seed int return random number seed – rrand 346 Chapter 8: Operators

355 PLRM 2nd Edition January 26, 1994 Operators Array Operators int create array of length int array array mark – start array construction [ obj mark obj array end array construction ... ] n-1 0 int number of elements in array array length any array index index get get array element indexed by – put put into array at index array index any any getinterval subarray subarray of array index count starting at index for count array elements starting at index array putinterval – replace subarray of array array by index 2 1 1 array 2 array ... any any array astore array pop elements from stack into 0 n–1 ... a array push all elements of array on stack aload a array 0 n–1 subarray to initial subarray of array copy elements of array array copy 2 2 1 1 array 2 forall – execute proc for each element of array array proc Packed Array Operators create packed array consisting of the ... any any n packedarray packedarray n–1 0 n elements specified currentpacking return array packing mode – bool setpacking – set array packing mode for {...} syntax bool ( = packedarray) true packedarray length int number of elements in packedarray element indexed by index packedarray index get any get packedarray starting at packedarray index count subarray subarray of packedarray getinterval index for count elements packedarray packedarray aload a packedarray ... a push all elements of on stack n–1 0 packedarray array copy subarray copy elements of packedarray to initial 1 2 1 2 subarray of array 2 packedarray for each element of packedarray proc forall – execute proc 347 8.1 Operator Summary

356 PLRM 2nd Edition Operators January 26, 1994 Dictionary Operators int create dictionary with capacity for int dict dict elements << start dictionary construction – mark mark key end dictionary construction ... key value value dict >> n 1 1 n length int number of key-value pairs in dict dict dict int current capacity of dict maxlength begin push dict on dictionary stack dict – end – pop dictionary stack – def – associate key and value in current dictionary key value key load value search dictionary stack for key and return associated value store replace topmost definition of key key value – get any get value associated with key in dict key dict dict key value put – associate key with value in dict dict key undef – remove key and its value from dict dict key bool test whether key is in dict known key where dict true find dictionary in which key is defined or false dict copy dict copy contents of dict dict to dict 2 2 2 1 1 dict proc forall proc for each element of dict – execute dict currentdict – push current dictionary on operand stack dict error handler dictionary – errordict $error error control and status dictionary – dict – systemdict dict system dictionary userdict dict writable dictionary in local VM – globaldict – dict writable dictionary in global VM dict product-dependent dictionary statusdict – countdictstack int count elements on dictionary stack – dictstack subarray copy dictionary stack into array array cleardictstack – pop all non-permanent dictionaries off – dictionary stack String Operators int string string create string of length int string length number of elements in string int get get string element indexed by index string index int put – string index int int into string at index put string index count getinterval substring substring of string starting at index for count elements replace substring of by index string index putinterval – string string starting at 1 2 1 string 2 to initial substring of string string string copy elements of copy substring 2 2 1 1 string 2 348 Chapter 8: Operators

357 PLRM 2nd Edition January 26, 1994 Operators forall – proc for each element of string string proc execute post match true determine if is initial substring of string string seek anchorsearch seek or string false search seek in string seek string search for post match pre true string false or string post token true read token from start of string token or false Relational, Boolean, and Bitwise Operators any eq bool test equal any 1 2 any ne bool test not equal any 1 2 | str num num test greater or equal | str bool ge 2 2 1 1 bool | str gt test greater than str | num num 1 1 2 2 str num | num test less or equal | str bool le 2 2 1 1 test less than | str num num bool | str lt 2 1 1 2 logical | bitwise and | int int bool bool | int bool and | 2 2 1 3 1 3 int bool not bool | | int logical | bitwise not 1 2 1 2 int logical | bitwise inclusive or bool | | int bool bool or | int 2 2 3 1 3 1 | | bool bool logical | bitwise exclusive or | int int xor bool int 3 1 3 2 1 2 true push boolean value true – true false false push boolean value – false int shift bitshift int (positive is left) bitwise shift of int 1 1 2 Control Operators exec – execute arbitrary object any bool proc – execute proc if bool is true if is proc bool proc if proc proc ifelse – execute bool is true, if bool 1 2 1 2 false init incr limit proc – execute proc with values from init by steps of for to limit incr int proc repeat execute proc int times – proc – execute proc an indefinite number of times loop exit innermost active loop – – exit – – terminate stopped context stop any stopped bool establish context for catching stop – int countexecstack count elements on exec stack array execstack subarray copy exec stack into array – quit – terminate interpreter executed at interpreter startup – – start 8.1 Operator Summary 349

358 PLRM 2nd Edition January 26, 1994 Operators Type, Attribute, and Conversion Operators any return name identifying the type of any type name any any make object be literal cvlit make object be executable any any cvx any bool test executable attribute xcheck packedarray | file | string executeonly array | packedarray | file | array | string reduce access to execute-only packedarray | dict | file | string noaccess array | packedarray | dict | file | string array | disallow any access | packedarray | dict | array | string readonly array | packedarray | dict | file | string file reduce access to read-only string | dict | file | | rcheck bool test read access packedarray array | packedarray | dict | file | string wcheck bool test write access array | cvi int convert to integer num string string cvn name convert to name num string cvr real convert to real | num radix string cvrs substring convert to string with radix substring any string convert to string cvs File Operators string string with access file file open file identified by string 1 1 2 string 2 | tgt param establish filtered file ... param file src filter name n 1 file closefile – close file file read int true read one character from file or false file int write – write one character to file file string readhexstring substring bool read hex from file into string file string writehexstring – write string to file as hex substring bool file string readstring file read string from file string writestring write string to file – readline string read line from file into file string substring bool token read token from file file token true or false file bytesavailable int number of bytes available to read – flush – send buffered data to standard output file file flushfile send buffered data or read to EOF – resetfile – file discard buffered characters file status bool return status of file string status pages bytes referenced created true or return information about named file false string run – execute contents of named file – currentfile file return file currently being executed delete named file – string deletefile 350 Chapter 8: Operators

359 PLRM 2nd Edition Operators January 26, 1994 string renamefile – rename file string to string string 1 2 1 2 filenameforall – execute proc for each file name matching template proc scratch template setfileposition – file int file to specified position set file int return current position in file fileposition print string write string to standard output file – any – write text representation of any to standard = output file any == – write syntactic representation of any to standard output file any ... any print stack non-destructively using = stack ... any any 1 1 n n any print stack non-destructively using == ... any ... any pstack any 1 n 1 n printobject obj int write binary object to standard output file, – using int as tag file obj int writeobject – write binary object to file , using int as tag int setobjectformat – set binary object format (0=disable, 1=IEEE high, 2=low, 3=native high, 4=low) return binary object format int – currentobjectformat Resource Operators key instance category instance register named resource instance in category defineresource undefineresource remove resource registration key category – findresource instance key category instance identified by key in return resource category key category resourcestatus status size true return status of resource instance or false template proc scratch category resourceforall – enumerate resource instances in category Virtual Memory Operators – save save create VM snapshot save restore – restore VM snapshot setglobal bool = local, – set VM allocation mode ( false true = global) currentglobal bool return current VM allocation mode – gcheck bool true if any is simple or in global VM, false if in any local VM bool password startjob bool start new job that will alter initial VM if bool 2 1 1 is true index any defineuserobject – define user object associated with index index execuserobject – execute user object associated with index index undefineuserobject – remove user object associated with index userdict array defined in – UserObjects array current UserObjects 8.1 Operator Summary 351

360 PLRM 2nd Edition January 26, 1994 Operators Miscellaneous Operators proc replace operator names in proc by operators bind proc null null on operand stack null – push – version string interpreter version int return real time in milliseconds – realtime int return execution time in milliseconds – usertime int languagelevel level of language features – string product name – product int product revision level revision – serialnumber int – machine serial number – – invoke interactive executive executive echo – bool turn on/off echoing – executed when ready for interactive input prompt – Graphics State Operators—Device Independent – gsave – push graphics state grestore – pop graphics state – – grestoreall pop to bottommost graphics state – initgraphics reset graphics state parameters – – gstate gstate – create graphics state object gstate setgstate – set graphics state from gstate copy current graphics state into gstate gstate currentgstate gstate num setlinewidth – set line width num currentlinewidth – return current line width int setlinecap – set shape of line ends for stroke (0 = butt, 1 = round, 2 = square) int return current line cap – currentlinecap int setlinejoin – set shape of corners for stroke (0 = miter, 1 = round, 2 = bevel) currentlinejoin return current line join int – num setmiterlimit – set miter length limit currentmiterlimit num return current miter limit – setstrokeadjust – set stroke adjust ( bool = disable, false true = enable) – currentstrokeadjust return current stroke adjust bool setdash set dash pattern for stroking array offset – currentdash array offset – return current dash pattern array setcolorspace – set color space – currentcolorspace array return current color space comp ... comp setcolor – set color components n 1 return current color components currentcolor comp ... comp – 1 n DeviceGray num setgray – set color space to and color to specified gray value (0 = black, 1 = white) 352 Chapter 8: Operators

361 PLRM 2nd Edition January 26, 1994 Operators currentgray num – return current color as gray value – set color space to and color to hue sat brt sethsbcolor DeviceRGB specified hue, saturation, brightness hue sat brt return current color as hue, saturation, – currenthsbcolor brightness – setrgbcolor DeviceRGB and color to red green blue set color space to specified red, green, blue currentrgbcolor red green blue return current color as red, green, blue – setcmykcolor – set color space to cyan magenta yellow black and color to DeviceCMYK specified cyan, magenta, yellow, black currentcmykcolor cyan magenta yellow black – lor as cyan, magenta, return curre nt co yellow, black Graphics State Operators—Device Dependent sethalftone – set halftone dictionary dict currenthalftone – return current halftone dictionary dict frequency angle proc – set gray halftone screen setscreen currentscreen – frequency angle proc return current gray halftone screen redfreq redang redproc greenfreq greenang greenproc bluefreq blueang blueproc – grayfreq grayang grayproc set all four halftone screens setcolorscreen – currentcolorscreen redfreq redang redproc greenfreq greenang greenproc bluefreq blueang blueproc grayfreq grayang grayproc return all four halftone screens proc – set gray transfer function settransfer proc return current gray transfer function – currenttransfer redproc greenproc blueproc setcolortransfer – set all four transfer functions grayproc – currentcolortransfer redproc greenproc blueproc grayproc return current transfer functions proc setblackgeneration – set black generation function – currentblackgeneration proc return current black generation function proc setundercolorremoval – set undercolor removal function – currentundercolorremoval return current undercolor removal function proc setcolorrendering – dict set CIE based color rendering dictionary – currentcolorrendering dict return current CIE based color rendering dictionary num – set flatness tolerance setflat – currentflat num return current flatness bool setoverprint – set overprint parameter return current overprint parameter bool – currentoverprint 8.1 Operator Summary 353

362 PLRM 2nd Edition January 26, 1994 Operators Coordinate System and Matrix Operators – create identity matrix matrix matrix – set CTM to device default initmatrix – fill matrix identmatrix matrix matrix with identity transform fill with device default matrix matrix defaultmatrix matrix matrix fill matrix with CTM currentmatrix matrix matrix – replace CTM by matrix setmatrix matrix t ) t – translate user space by translate , t (t x y x y t ) matrix translate matrix define translation by (t t , t y y x x s s scale – scale user space by s s and x y y x s s s matrix scale matrix define scaling by s and x y x y rotate – angle degrees angle rotate user space by matrix define rotation by degrees rotate angle matrix angle – matrix × CTM concat matrix replace CTM by matrix matrix matrix × concatmatrix matrix matrix fill matrix with matrix 3 3 1 3 2 2 1 transform x’ y’ x y x , y ) by CTM transform ( x y matrix x’ y‘ transform ( x , y ) by matrix transform dtransform transform distance ( dx , dy ) by CTM dx dy dx’ dy’ dtransform dx’ dy’ transform distance ( dx dx dy matrix dy ) by matrix , x’ y’ itransform x y inverse transform ( x‘ , y‘ ) by CTM x y matrix x’ y’ matrix itransform ) by inverse transform ( x‘ , y‘ dx‘ dy‘ idtransform dx‘ , dy‘ ) by CTM dx dy inverse transform distance ( dx dy dx‘ , dy‘ ) by matrix dx‘ dy‘ matrix idtransform inverse transform distance ( matrix matrix invertmatrix matrix matrix fill matrix with inverse of 2 2 1 1 2 Path Construction Operators – newpath – initialize current path to be empty currentpoint x y return current point coordinate – moveto x set current point to ( x y , y ) – rmoveto relative moveto dx dy – lineto – append straight line to ( x , y ) x y rlineto dx dy relative lineto – x y r ang arc – append counterclockwise arc ang 1 2 x y r ang append clockwise arc ang – arcn 2 1 x y x y r arct – append tangent arc 1 2 1 2 xt x append tangent arc x yt y xt r arcto y yt 1 1 2 2 2 2 1 1 x append Bézier cubic section y – x curveto y y x 3 3 2 1 1 2 dx curveto dy relative dx – dy rcurveto dx dy 3 2 2 1 1 3 – closepath – connect subpath back to its starting point – flattenpath – convert curves to sequences of straight lines – reversepath – reverse direction of current path – strokepath – compute outline of stroked path userpath compute outline of stroked userpath ustrokepath – 354 Chapter 8: Operators

363 PLRM 2nd Edition Operators January 26, 1994 ustrokepath – userpath userpath matrix compute outline of stroked – append character outline to current path charpath string bool uappend – interpret userpath and append to current userpath path clippath – set current path to clipping path – ur ur set bounding box for current path ll – ll setbbox y x y x ur – pathbbox ll return bounding box of current path ll ur y x y x pathforall enumerate current path move line curve close – upath userpath create bool for current path; include userpath ucache if bool is true – – initclip set clipping path to device default – clip using non-zero winding number rule clip – – eoclip – clip using even-odd inside rule rectclip – x y width height clip with rectangular path | numstring rectclip – clip with rectangular paths numarray declare that user path is to be cached – ucache – Painting Operators – erasepage paint current page white – fill fill current path with current color – – eofill – fill using even-odd rule – – – draw line along current path stroke userpath ufill – interpret and fill userpath userpath ueofill – fill userpath using even-odd rule userpath – interpret and stroke userpath ustroke userpath matrix ustroke – interpret userpath , concatenate matrix , and stroke x y width height – rectfill fill rectangular path numarray | rectfill – fill rectangular paths numstring rectstroke – x y width height stroke rectangular path numarray | numstring rectstroke – stroke rectangular paths dict image – paint any sampled image width height bits/samp matrix image – paint monochrome sampled image datasrc width height bits/comp matrix datasrc ... datasrc n–1 0 multi ncomp colorimage – paint color sampled image dict imagemask – paint current color through mask width height polarity matrix paint current color through mask – datasrc imagemask 8.1 Operator Summary 355

364 PLRM 2nd Edition January 26, 1994 Operators Insideness Testing Operators x y test whether point ( x , y ) would be painted by infill bool fill infill test whether pixels in userpath would be userpath bool painted by fill bool test whether point ( x , y ) would be painted by x y ineofill eofill userpath test whether pixels in userpath would be ineofill bool eofill painted by x y userpath bool test whether point ( x , y ) would be painted by inufill ufill userpath of userpath userpath would be inufill bool test whether pixels in userpath 1 1 2 painted by inufill of userpath 2 inueofill bool test whether point ( x , y ) would be painted by x y userpath of userpath ueofill userpath inueofill bool test whether pixels in userpath userpath would be 1 2 1 painted by ueofill of userpath 2 ) would be painted by y x y instroke bool test whether point ( x , stroke x y userpath bool test whether point ( x , inustroke ) would be painted by y ustroke of userpath x y userpath matrix inustroke bool test whether point ( x , y ) would be painted by ustroke userpath of userpath would be userpath userpath inustroke bool test whether pixels in 2 1 1 painted by ustroke of userpath 2 bool userpath would be userpath test whether pixels in matrix inustroke userpath 2 1 1 ustroke of userpath painted by 2 Form and Pattern Operators pattern matrix makepattern pattern’ create pattern instance from prototype comp as current color ... comp pattern pattern setpattern – install n 1 execform – paint form form Device Setup and Output Operators – showpage – transmit and reset current page – copypage – transmit current page dict setpagedevice – install page-oriented output device – currentpagedevice dict return current page device parameters install no-output device – – nulldevice 356 Chapter 8: Operators

365 PLRM 2nd Edition Operators January 26, 1994 Character and Font Operators key font register font as a font dictionary definefont font – undefinefont key remove font registration key findfont font return font dictionary identified by key scalefont font’ scale font by scale to produce new font font scale ′ font matrix font’ transform font by matrix to produce new font ′ makefont font setfont set font dictionary in graphics state – currentfont font – return current font dictionary – rootfont font return root composite font dictionary key scale | matrix selectfont – set font dictionary given name and transform string – paint characters of string on page show ashow string – add ( a a , a ) to width of each character while a y y x x showing string c while showing c char char string widthshow – add (c to width of , c ) y y x x string c and c ashow char a widthshow a combine effects of string awidthshow – y y x x x widths in string numarray | numstring xshow – paint characters of string using numarray | numstring using | – paint characters of string xyshow x and y string numarray numstring numarray widths in numstring | string numarray numstring yshow – | string using y widths in paint characters of numarray | numstring name – paint character identified by name glyphshow string stringwidth w in current font w string width of y x proc string cshow – invoke show mapping algorithm and call proc proc string kshow – execute proc between characters shown from string – dictionary of font dictionaries FontDirectory dict – GlobalFontDirectory dictionary of font dictionaries in global VM dict StandardEncoding Adobe standard font encoding vector – array ISOLatin1Encoding array international ISO Latin-1 font encoding – vector key findencoding array find encoding array w declare cached character metrics w – ll setcachedevice ll ur ur x y x y x y w0 ur w0 ur ll ll x y x x y y w1 – declare cached character metrics setcachedevice2 v v w1 x y y x – declare uncached character metrics w setcharwidth w y x 8.1 Operator Summary 357

366 PLRM 2nd Edition January 26, 1994 Operators Interpreter Parameter Operators dict set system-wide interpreter parameters setsystemparams – dict return system-wide interpreter parameters – currentsystemparams set per-context interpreter parameters dict – setuserparams – dict return per-context interpreter parameters currentuserparams – set parameters for input/output device string dict setdevparams currentdevparams dict string return device parameters – vmreclaim control garbage collector int – control garbage collector int setvmthreshold level used maximum report VM status vmstatus – cachestatus – bsize bmax msize mmax csize cmax blimit return font cache status and parameters setcachelimit – num set maximum bytes in cached character – setcacheparams mark size lower upper change font cache parameters mark size lower upper – currentcacheparams return current font cache parameters setucacheparams – set user path cache parameters mark blimit ucachestatus – mark bsize bmax rsize rmax blimit return user path cache status and parameters Display PostScript Operators – context return current context identifier currentcontext with ... obj mark obj proc fork context create context executing proc 1 n j ob obj as operands ... 1 n join ... obj await context termination and return its context mark obj 1 n results context – enable context to terminate immediately detach when done – lock lock create lock object lock proc monitor – execute proc while holding lock – condition create condition object condition lock condition wait lock release lock , wait for condition , reacquire – condition notify condition resume contexts waiting for – – suspend current context momentarily – yield index name defineusername – define encoded name index viewclip – set view clip from current path – eoviewclip – set view clip using even-odd rule – rectviewclip – x y width height set rectangular view clipping path numarray numstring rectviewclip – set rectangular view clipping paths | – initviewclip – reset view clip – viewclippath – set current path from view clip dict – deviceinfo return dictionary containing information about current device 358 Chapter 8: Operators

367 PLRM 2nd Edition Operators January 26, 1994 wtranslation return translation from window origin to – x y device space origin sethalftonephase – set halftone phase x y currenthalftonephase x y return current halftone phase – Errors configurationerror setpagedevice request cannot be satisfied dictfull no more room in dictionary dictstackoverflow begin s too many dictstackunderflow too many end s execstackoverflow exec nesting too deep handleerror called to report error information interrupt external interrupt request (e.g., Control-C) invalidaccess attempt to violate access attribute invalidcontext improper use of context operation exit not in loop invalidexit invalidfileaccess unacceptable access string invalidfont invalid font name or dictionary invalidid invalid identifier for external object invalidrestore improper restore ioerror input/output error occurred limitcheck implementation limit exceeded nocurrentpoint current point is undefined rangecheck operand out of bounds stackoverflow operand stack overflow stackunderflow operand stack underflow syntaxerror PostScript language syntax error timeout time limit exceeded typecheck operand of wrong type undefined name not known undefinedfilename file not found undefinedresource resource instance not found undefinedresult over/underflow or meaningless result unmatchedmark expected mark not on stack unregistered internal error VMerror VM exhausted 8.1 Operator Summary 359

368 PLRM 2nd Edition Operators January 26, 1994 8.2 Operator Details [ [ mark – mark ). The customary use of the pushes a mark object on the operand stack (see operator is to mark the beginning of an indefinitely long sequence of objects [ that will eventually be formed into a new array object by the ] operator. See the discussion of the array syntax in section 3.2, “Syntax,” and of array construction in section 3.6, “Overview of Basic Operators.” Errors: stackoverflow See Also: ], mark, array, astore mark obj ... obj ] array ] 0 n-1 creates a new array of n elements, where n is the number of elements above the topmost mark on the operand stack; stores those elements into the array; and returns the array on the operand stack. The ] operator stores the topmost object and the bottommost one (the one array from the stack into element n –1 of immediately above the mark) into element 0 of . It removes all the array ele- array ments from the stack, as well as the mark object. The array is allocated in local or global VM according to the current VM alloca- invalidaccess error occurs if the array is in global VM and any of tion mode. An obj ... obj are in local VM. See section 3.7.2, “Local and Global VM.” n-1 0 Example [5 4 3] ⇒ % a 3-element array, with elements 5, 4, 3 ⇒ mark 5 4 3 counttomark array astore exch pop [5 4 3] [1 2 add] % a 1-element array, with element 3 ⇒ The second line of the example has the same effect as the first, but uses lower- level array and stack manipulation primitives instead of [ and ] . In the last line of the example, note that the PostScript interpreter acts on all of the array elements as it encounters them (unlike its behavior with the {...} syntax for executable array construction) so the add operator is executed before the array is constructed. stackoverflow, unmatchedmark, VMerror Errors: See Also: [, mark, array, astore 360 Chapter 8: Operators

369 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 << – << mark pushes a mark object on the operand stack (same as mark and [ operators). Errors: stackoverflow See Also: >>, mark LEVEL 2 value >> value dict ... key >> mark key 1 n n 1 creates and returns a dictionary containing the specified key-value pairs. The operands are a mark followed by an even number of objects, which the operator uses alternately as keys and values to be inserted into the dictionary. The dic- tionary is allocated space for precisely the number of key-value pairs supplied. The dictionary is allocated in local or global VM according to the current VM allocation mode. An invalidaccess error occurs if the dictionary is in global VM and any keys or values are in local VM. See section 3.7.2, “Local and Global VM.” A rangecheck error occurs if there is an odd number of objects above the topmost mark on the stack. is equivalent to: >> counttomark 2 idiv dup dict begin {def} repeat pop currentdict end Example << /Duplex true /PageSize [612 792] /Collate false >> setpagedevice This example constructs a dictionary containing three key-value pairs, which it immediately passes to the operator. setpagedevice Errors: invalidaccess, rangecheck, unmatchedmark, VMerror See Also: <<, mark, dict 361 8.2 Operator Details

370 PLRM 2nd Edition Operators January 26, 1994 any – = = pops an object from the operand stack, produces a text representation of that object’s value, and writes the result followed by a newline character to the stan- cvs dard output file. The text is that produced by the = prints the operator; thus, value of a number, boolean, string, name, or operator object and prints --nostringval-- for an object of any other type. The name = is not special. In PostScript language programs it must be delimited by white space or special characters the same as names composed of alphabetical = is not an operator, but rather a built-in procedure. characters. The value of Errors: stackunderflow See Also: ==, stack, cvs, print, flush == any == – pops an object from the operand stack, produces a text representation of that object followed by a newline character, and writes the result to the standard out- put file. == attempts to produce a result that resembles the PostScript syntax for (...) , and creating the object. It precedes literal names by / , brackets strings with expands the values of arrays and packed arrays and brackets them with [...] or . For an object with no printable representation, produces the name of its {...} == -mark- or -dict- type in the form . For an operator object, it produces the opera- tor’s name in the form --add-- . The name == is not special. In PostScript language programs it must be delimited by white space or special characters the same as names composed of alphabetical characters. The value of is not an operator, but rather a built-in procedure. == The == operator is intended for convenience in debugging. The details of how == formats its output are intentionally unspecified. A program requiring detailed control over output format should do its own formatting explicitly, using lower- level operators, such as cvs . Also, printobject and writeobject (Level 2 features) may be more suitable for generating machine-readable output. Errors: stackunderflow See Also: =, print, pstack, flush 362 Chapter 8: Operators

371 PLRM 2nd Edition Operators January 26, 1994 $error – $error dict pushes the dictionary object $error on the operand stack (see section 3.10, “Errors”). $error is not an operator; it is a name in systemdict associated with the dictionary object. stackoverflow Errors: See Also: errordict num num abs abs 1 2 returns the absolute value of num . The type of the result is the same as the type 1 is the most negative integer, in which case the result is a of num num unless 1 1 real. Example 4.5 ⇒ 4.5 abs –3 abs ⇒ 3 ⇒ 0 0 abs Errors: stackunderflow, typecheck See Also: neg add num num add sum 1 2 returns the sum of and num . If both operands are integers and the result is num 1 2 within integer range, the result is an integer; otherwise, the result is a real. Example 3 4 add ⇒ 7 9.9 1.1 add ⇒ 11.0 stackunderflow, typecheck, undefinedresult Errors: See Also: div, mul, sub, idiv, mod 8.2 Operator Details 363

372 PLRM 2nd Edition January 26, 1994 Operators array aload aload ... array array array n–1 0 packedarray packedarray ... packedarray packedarray aload 0 n–1 elements of successively pushes all or packedarray on the operand stack n array n is the length of the operand), and finally pushes the operand itself. (where Example ⇒ [23 (ab) –6] aload 23 (ab) –6 [23 (ab) –6] Errors: invalidaccess, stackoverflow, stackunderflow, typecheck See Also: astore, get, getinterval anchorsearch anchorsearch post match true (if found) string seek string false (if not found) seek matches the initial substring of string (that is, determines if the string string is at least as long as and the corresponding characters are equal). If it seek anchorsearch matches, string into two segments: match, the portion of splits string seek, string that matches ; it then pushes the and post, the remainder of post string objects match and the boolean true. If not, anchorsearch pushes and string anchorsearch false. the original is a special case of the and the boolean operator. search Example (abbc) (ab) anchorsearch ⇒ (bc) (ab) true (abbc) (bb) anchorsearch ⇒ (abbc) false (abbc) (bc) anchorsearch ⇒ (abbc) false (abbc) (B) anchorsearch ⇒ (abbc) false Errors: invalidaccess, stackoverflow, stackunderflow, typecheck See Also: search, token and bool bool and bool 1 3 2 int int and int 1 2 3 If the operands are booleans, and returns their logical conjunction. If the oper- and of their binary representations. ands are integers, and returns the bitwise 364 Chapter 8: Operators

373 PLRM 2nd Edition January 26, 1994 Operators Example true true and true % a complete truth table ⇒ true false and false ⇒ false true and ⇒ false false false and ⇒ false 99 1 and ⇒ 1 52 7 and ⇒ 4 Errors: stackunderflow, typecheck See Also: or, xor, not, true, false – arc x y r ang arc ang 2 1 appends a counterclockwise arc of a circle to the current path, possibly preceded the angle by a straight line segment. The arc has ( x, y ) as center, r as radius, ang 1 of a vector from ( x, y ) of length r to the first endpoint of the arc, and ang the second 2 endpoint angle of a vector from ( x, y ) of length r to the second endpoint of the arc. If there is a current point, the operator includes a straight line segment from arc the current point to the first endpoint of this arc and then adds the arc into the first r ang current path. If the current path is empty, the arc operator does not produce the 2 endpoint initial straight line segment. In any event, the second endpoint of the arc becomes the new current point. ang 1 x,y Angles are measured in degrees counterclockwise from the positive x -axis of the current user coordinate system. The curve produced is circular in user space. If current and arc user space is scaled non-uniformly (i.e., differently in y ) x will produce point elliptical curves in device space. ) represent them inter- arcto , and arc, arcn, arct The operators that produce arcs ( curveto ) that approximate the nally as one or more Bézier cubic curves (see required shape. This is done with sufficient accuracy that a faithful rendition of an arc is produced. However, a program that reads the constructed path using segments where arcs were specified originally. pathforall will encounter curveto Example newpath 0 0 moveto 0 0 1 0 45 arc closepath This constructs a 1-unit radius, 45-degree “pie slice.” 45° Errors: limitcheck, stackunderflow, typecheck 0,0 1,0 See Also: arcn, arct, arcto, curveto 8.2 Operator Details 365

374 PLRM 2nd Edition January 26, 1994 Operators arcn ang arcn – x y r ang 2 1 arc, but arcn builds its arc segment in a clockwise (arc negative) behaves like direction in user space. Example newpath 0 0 2 0 90 arc 0 0 1 90 0 arcn closepath This constructs a 2-unit radius, 1-unit wide, 90-degree “windshield wiper swath.” Errors: limitcheck, stackunderflow, typecheck 90° See Also: arc, arct, arcto, curveto 0,0 1,0 2,0 LEVEL 2 arct x x y y r arct – 2 1 1 2 appends an arc of a circle to the current path, possibly preceded by a straight line r segment. The arc is defined by a radius and two tangent lines.The tangent lines , x ), , x y are those drawn from the current point, here called ( y ), and from to ( 1 0 1 0 x ,y 22 executes the error ) to ( y ). If the current point is undefined, arct , , x ( y x 2 2 1 1 nocurrentpoint . The center of the arc is located within the inner angle between the tangent lines. in a direction perpendicular to both r It is the only point located at distance xt ,yt xt lines. The arc begins at the first tangent point ( ) on the first tangent line, , yt 22 1 1 , y x ), and ends at the second tangent passes between its center and the point ( 1 1 ) on the second tangent line. , yt xt point ( 2 2 r Before constructing the arc, adds a straight line segment from the current arct x ,y x ,y xt ,yt , yt ) xt ) to ( ), unless those points are the same. In any event, ( xt x point ( , yt , y 00 1 1 11 2 1 0 1 2 0 becomes the new current point. The curve produced is circular in user space. If user space is scaled non-uni- ) formly (i.e., differently in x and y arct will produce elliptical curves in device space. xt If the two tangent lines are collinear, ( , yt xt ) are identical. In this ) and ( , yt 1 1 2 2 merely appends a straight line seg- arct case, the joining arc has length zero and ment from ( , x x ) to ( , y y ). 0 1 1 0 Chapter 8: Operators 366

375 PLRM 2nd Edition January 26, 1994 Operators Example 0,4 1,4 4,4 newpath 0 0 moveto 0 4 4 4 1 arct 1 4 4 lineto 0,3 This constructs a 4-unit wide, 4-unit high right angle with a 1-unit radius “rounded corner.” limitcheck, nocurrentpoint, stackunderflow, typecheck, Errors: 0,0 undefinedresult See Also: arc, arcn, arcto, curveto y r arcto xt x y xt yt x arcto yt 2 2 1 2 1 2 1 1 . It also returns the two tangent point coordi- arct produces the same effect as , yt nates ( ) and ( xt xt , yt is not allowed as an element of a ) in user space. arcto 2 1 1 2 is allowed. See section 4.6, “User Paths.” arct user path, whereas limitcheck, nocurrentpoint, stackunderflow, typecheck, Errors: undefinedresult See Also: arc, arcn, arct, curveto array array int array int , each of whose elements is initialized with a null creates an array of length object, and pushes this array on the operand stack. The int operand must be a non-negative integer not greater than the maximum allowable array length (see Appendix B). The array is allocated in local or global VM according to the cur- rent VM allocation mode. See section 3.7.2, “Local and Global VM.” Example 3 array [null null null] ⇒ Errors: limitcheck, rangecheck, stackunderflow, typecheck, VMerror See Also: [, ], aload, astore, packedarray 367 8.2 Operator Details

376 PLRM 2nd Edition Operators January 26, 1994 a a string ashow – ashow y x string paints the characters of show . But while doing so, in a manner similar to ashow adjusts the width of each character shown by adding a to the character’s x width and x width, thus modifying the spacing between characters. a y to its y and The numbers a displacements in the user coordinate system, and a y are x y x not in the character coordinate system. This operator enables a string of text to be fitted to a specific width by adjusting all the spaces between characters by a uniform amount. For a discussion about character widths, see section 5.4, “Font Metric Information.” Example /Helvetica findfont 12 scalefont setfont Normal spacing 14 61 moveto (Normal spacing) show Wide spacing 14 47 moveto 4 0 (Wide spacing) ashow Errors: invalidaccess, invalidfont, nocurrentpoint, stackunderflow, typecheck See Also: show, awidthshow, cshow, kshow, widthshow, xshow, xyshow, yshow astore any array astore array ... any 0 n–1 stores the objects any n through any where from the operand stack into array, n–1 0 array. operand from astore operator first removes the array is the length of The the stack and determines its length. It then removes that number of objects from the stack, storing the topmost one into element n –1 of array and the bottom- most one into element 0 of array. Finally, it pushes array back on the stack. Note that cannot be performed on packed arrays. astore If the value of array is in global VM and any of any are composite ... any n–1 0 objects whose values are in local VM, an invalidaccess error occurs. See section 3.7.2, “Local and Global VM.” Example (a) (bcd) (ef) 3 array astore ⇒ [(a) (bcd) (ef)] into it as This creates a three element array, stores the strings , (bcd) , and (ef) (a) elements 0, 1, and 2, and leaves the array object on the operand stack. Errors: invalidaccess, stackunderflow, typecheck See Also: aload, put, putinterval Chapter 8: Operators 368

377 PLRM 2nd Edition Operators January 26, 1994 num den angle atan atan returns the angle (in degrees between 0 and 360) whose tangent is num/den. num or den Either num and den determine may be zero, but not both. The signs of the quadrant in which the result will lie: a positive num yields a result in the pos- plane. The result is a itive y plane, a positive den yields a result in the positive x real. Example ⇒ 0.0 0 1 atan ⇒ 90.0 1 0 atan ⇒ 270.0 –100 0 atan 4 4 atan ⇒ 45.0 Errors: stackunderflow, typecheck, undefinedresult See Also: cos, sin awidthshow awidthshow c c char a a – string x y y x paints the characters of show, but combines the spe- in a manner similar to string cial effects of ashow and widthshow. awidthshow adjusts the width of each char- a acter shown by adding to its x width and a width, thus modifying the to its y y x spacing between characters. Furthermore, awidthshow modifies the width of char each occurrence of the character . The inter- by an additional amount (c ) , c y x operator. pretation of char is as described for the widthshow This operator enables fitting a string of text to a specific width by adjusting all of the spaces between characters by a uniform amount, while independently con- trolling the width of some specific character, such as the space character. For a discussion about character widths, see section 5.4, “Font Metric Information.” Example /Helvetica findfont 12 scalefont setfont Normal spacing 30 60 moveto (Normal spacing) show Wide spacing 30 46 moveto 6 0 8#040 .5 0 (Wide spacing) awidthshow Errors: invalidaccess, invalidfont, nocurrentpoint, rangecheck, stackunderflow, typecheck See Also: ashow, cshow, kshow, show, widthshow, xshow, xyshow, yshow 8.2 Operator Details 369

378 PLRM 2nd Edition January 26, 1994 Operators dict – begin begin pushes dict on the dictionary stack, making it the current dictionary and install- ing it as the first of the dictionaries consulted during implicit name lookup and def , load , store , and where . by Errors: dictstackoverflow, invalidaccess, stackunderflow, typecheck See Also: end, countdictstack, dictstack bind bind proc proc proc by their values. For each element of replaces executable operator names in that is an executable name, bind looks up the name in the context of the proc current dictionary stack as if by load . If the name is found and its value is an proc operator object, . If the name is bind replaces the name by the operator in not found or its value is not an operator, bind does not make a change. proc bind applies itself recursively to that proce- For each procedure object in , proc dure, makes the procedure read-only, and stores it back into bind oper- . The ator applies to both arrays and packed arrays, but it treats their access attributes differently. It will ignore a read-only array; that is, it will neither bind elements of the array nor examine nested procedures. On the other hand, bind will oper- ate on a packed array (which is always read-only), disregarding its access attribute. No error occurs in either case. The effect of bind is that all operator names in proc and in procedures nested in proc to any depth become “tightly bound” to the operators themselves. During subsequent execution of proc, the interpreter encounters the operators them- selves rather than the names of operators. See section 3.11, “Early Name Bind- ing.” Errors: typecheck See Also: load 370 Chapter 8: Operators

379 PLRM 2nd Edition Operators January 26, 1994 int shift bitshift int bitshift 2 1 int shifts the binary representation of left by shift bits and returns the result. Bits 1 shifted out are lost; bits shifted in are zero. If shift is negative, then a right shift by –shift bits is performed. This produces an arithmetically correct result only for must be integers. positive values of int . Both int shift and 1 1 Example 7 3 bitshift ⇒ 56 142 –3 bitshift ⇒ 17 Errors: stackunderflow, typecheck See Also: and, or, xor, not bytesavailable bytesavailable int file file returns the number of bytes that are immediately available for reading from without waiting. The result is –1 if end-of-file has been encountered or if the number of bytes available cannot be determined for other reasons. ioerror, stackunderflow, typecheck Errors: See Also: read, readhexstring, readline, readstring – cachestatus bsize bmax msize mmax csize cmax blimit cachestatus returns measurements of several aspects of the font cache (see section 5.5, “Font Cache”). cachestatus reports the current consumption and limit for each of three font cache resources: bytes of bitmap storage ( and bmax ), font/matrix bsize combinations ( msize and mmax ), and total number of cached characters ( csize and cmax ). It also reports the limit on the number of bytes occupied by a single cached character (blimit) . Characters whose bitmaps are larger than this are not cached. Errors: stackoverflow See Also: setcachelimit, setsystemparams 8.2 Operator Details 371

380 PLRM 2nd Edition Operators January 26, 1994 num ceiling num ceiling 2 1 num returns the least integer value greater than or equal to . The type of the 1 result is the same as the type of the operand. Example 3.2 ceiling ⇒ 4.0 –4.8 ceiling –4.0 ⇒ 99 ⇒ 99 ceiling Errors: stackunderflow, typecheck See Also: floor, round, truncate, cvi charpath string bool charpath – obtains the character path outlines that would result if string were shown at the charpath current point using show . Instead of painting the path, however, appends the path to the current path. This yields a result suitable for general fill- ing, stroking, or clipping (see sections 4.4, “Path Construction,” 4.5, “Painting,” and 5.1, “Organization and Use of Fonts”). The bool operand determines what happens if the character path is designed to be stroked rather than filled or outlined. If bool is false , charpath simply appends the character path to the current path; the result is suitable only for stroking. If applies the bool is true , charpath strokepath operator to the character path; the result is suitable for filling or clipping, but not for stroking. does not charpath produce results for portions of a character defined as images or masks rather than as paths. The outlines of some fonts are protected. (In Level 1 implementations, this applies to all fonts; in Level 2, only to certain special fonts and not to ordinary Type 1 or Type 3 fonts.) If the current font is protected, using charpath to obtain its outlines causes the pathforall and upath operators to be disabled for as long as those outlines remain in the current path. limitcheck, nocurrentpoint, stackunderflow, typecheck Errors: See Also: show, flattenpath, pathbbox, clip 372 Chapter 8: Operators

381 PLRM 2nd Edition January 26, 1994 Operators clear any ... any clear 1 n pops all objects from the operand stack and discards them. Errors: (none) See Also: count, cleartomark, pop – cleardictstack – cleardictstack pops all dictionaries off the dictionary stack except for the permanent entries. In Level 1 implementations the permanent entries are systemdict and userdict ; in . (In Level 1 implementa- userdict Level 2 they are systemdict , globaldict , and tions, userdict instead of an operator is a procedure defined in cleardictstack defined in systemdict .) (none) Errors: See Also: begin, end cleartomark mark obj ... obj cleartomark – 1 n pops the operand stack repeatedly until it encounters a mark, which it also pops from the stack ( obj through obj are any objects other than marks). 1 n Errors: unmatchedmark See Also: clear, mark, counttomark, pop 8.2 Operator Details 373

382 PLRM 2nd Edition Operators January 26, 1994 – – clip clip intersects the inside of the current clipping path with the inside of the current path to produce a new, smaller current clipping path. The inside of the current path is determined by the normal PostScript non-zero winding number rule (see section 4.5, “Painting”), while the inside of the current clipping path is deter- mined by whatever rule was used at the time that path was created. In general, clip produces a new path whose inside (according to the non-zero winding number rule) consists of all areas that are inside both of the original paths. The way this new path is constructed (the order of its segments, whether it self-intersects, etc.) is not specified. clip treats an open subpath of the current path as though it were closed; it does not actually alter the path itself. It is per- clip is always a missible for the current path to be empty. The result of executing non-empty clipping path, though it may enclose zero area. There is no way to enlarge the current clipping path (other than by initclip or initgraphics ) or to set a new clipping path without reference to the current one. The recommended way of using clip is to bracket the clip and the sequence of will restore the grestore graphics to be clipped with gsave and grestore . The clipping path that was in effect before the gsave setgstate operator can also . The be used to reset the clipping path to an earlier state. after it has fin- and stroke, clip Unlike newpath fill does not implicitly perform a ished using the current path. Any subsequent path construction operators will append to the current path unless newpath is executed explicitly. This can cause unexpected behavior. Errors: limitcheck See Also: eoclip, clippath, initclip, rectclip – clippath – clippath sets the current path to one that describes the current clipping path. This opera- tor is useful for determining the exact extent of the imaging area on the current output device. If the current clipping path is the result of application of the clip or eoclip opera- tor, the path set by clippath is generally suitable only for filling or clipping. It is not suitable for stroking because it may contain interior segments or discon- nected subpaths produced by the clipping process. Example clippath 1 setgray fill This erases (fills with white) the interior of the current clipping path. 374 Chapter 8: Operators

383 PLRM 2nd Edition January 26, 1994 Operators Errors: (none) See Also: clip, eoclip, initclip, rectclip closefile file closefile – closes file —in other words, breaks the association between the file object and the underlying file. For an output file, closefile first performs a flushfile . It may also take device-dependent actions, such as truncating a disk file to the current posi- tion or transmitting an end-of-file indication. See section 3.8, “File Input and Output.” ioerror, stackunderflow, typecheck Errors: See Also: file, filter, status – closepath – closepath closes the current subpath by appending a straight line segment connecting the current point to the subpath’s starting point—generally, the point most recently specified by moveto . If the current subpath is already closed or the current path is empty, closepath does not do anything (see section 4.4, “Path Construction”). closepath terminates the current subpath. Appending another segment to the current path will begin a new subpath, even if it is drawn from the endpoint reached by the closepath. Errors: limitcheck See Also: newpath, moveto, lineto 8.2 Operator Details 375

384 PLRM 2nd Edition Operators January 26, 1994 width height bits/comp matrix colorimage LEVEL 2 datasrc multi ncomp colorimage – ... datasrc 0 n–1 paints a sampled image onto the current page. The description here only sum- marizes the operator. See section 4.10, “Images” for full details. colorimage width × height sample values. The sampled image is a rectangular array of matrix interprets the , height , and colorimage operands in the same way as width does image . Each image sample consists of 1, 3, or 4 color components, as specified by the ncomp operand. Each component consists of bits (1, 2, 4, 8, or 12). All bits/comp components are the same size. If ncomp is 1, the samples have only one (gray) component; the operation of colorimage is equivalent to that of image using the first five operands. If ncomp is 3, the samples consist of red, green, and blue components. If ncomp is 4, the samples consist of cyan, magenta, yellow, and black components. The 1, 3, and 4 , DeviceGray , DeviceRGB component values are interpreted according to the and DeviceCMYK color spaces, respectively (see section 4.8, “Color Spaces”), regard- less of the current color space. is to obtain sam- The multi operand is a boolean that determines how colorimage ple data from its data sources. If multi false , there is a single data source, is colorimage obtains all components from that source, interleaved on a ; datasrc 0 multi is true , there are ncomp per-sample basis. If datasrc ... data sources, 0 datasrc , one for each component. The data sources can be procedures, strings, n-1 or files, including filtered files. They must all be of the same type (see section 4.10.2, “Sample Data Representation”). Unlike image and imagemask , colorimage does not have an alternate form in which the parameters are bundled into a single image dictionary operand. In image Level 2 implementations, given the appropriate image dictionary, the operator can do anything that colorimage can do, and many other things. For example, image can interpret color samples in any color space, whereas colorimage is limited to the DeviceGray , DeviceRGB , and DeviceCMYK color spaces. Execution of this operator is not permitted in certain circumstances; see section 4.8, “Color Spaces.” Errors: invalidaccess, ioerror, limitcheck, rangecheck, stackunderflow, typecheck, undefined, undefinedresult See Also: image, imagemask 376 Chapter 8: Operators

385 PLRM 2nd Edition January 26, 1994 Operators concat matrix concat – concatenates matrix with the current transformation matrix (CTM). Precisely, concat replaces the CTM by matrix × CTM (see section 4.3, “Coordinate Systems and Transformations”). The effect of this is to define a new user space whose coordinates are transformed into the former user space according to matrix. Examples [72 0 0 72 0 0] concat 72 72 scale The two examples have the same effect on the current transformation. Errors: rangecheck, stackunderflow, typecheck See Also: concatmatrix, matrix, rotate, scale, setmatrix, translate matrix concatmatrix concatmatrix matrix matrix matrix 2 1 3 3 , and replaces the value of matrix matrix by the result of multiplying matrix × 1 3 2 back on the operand stack. This operator does not pushes the modified matrix 3 affect the CTM. Errors: rangecheck, stackunderflow, typecheck See Also: concat, matrix, rotate, scale, setmatrix, translate DPS condition condition – condition creates a new condition object, unequal to any condition object already in exist- ence, and pushes it on the operand stack. The condition initially has no contexts waiting on it (see section 7.1, “Multiple Execution Contexts”). Since a condition is a composite object, creating one consumes VM. The condition’s value is allo- cated in local or global VM according to the current VM allocation mode. Errors: stackoverflow, VMerror See Also: wait, notify 377 8.2 Operator Details

386 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 configurationerror (error) or occurs when setdevparams setpagedevice has been executed with a request for a feature that either is not available in the interpreter implementation or is , setpagedevice not currently available because of the state of the hardware. For PolicyDict entry in a page device dictionary this error is generated only if the specifies that an error should be generated. is generated, a two-element array called errorinfo is configurationerror When a placed in $error. This array contains the key and value of the request that could not be met. See section 3.10, “Errors.” See Also: setpagedevice, setdevparams any ... any ... any copy n copy any any ... any n n 1 1 n 1 subarray copy array array 2 2 1 dict dict copy dict 2 2 1 string string substring copy 2 1 2 packedarray copy subarray array 2 2 1 copy gstate gstate gstate 1 2 2 performs two entirely different functions, depending on the type of the topmost operand. In the first instance, where the top element on the operand stack is a non-nega- n, copy tive integer n from the stack and duplicates the top n elements on pops the operand stack as shown above. This form of copy operates only on the objects themselves, not on the values of composite objects. Example ⇒ 1 2 3 2 3 1 2 3 2 copy 1 2 3 0 copy ⇒ 1 2 3 In the other instances, copy copies all the elements of the first composite object into the second. The composite object operands must be of the same type, except that a packed array can be copied into an array. This form of copy copies the of a composite object. This is quite different from dup and other opera- value tors that copy only the objects themselves (see section 3.3.1, “Simple and Com- posite Objects”). However, copy performs only one level of copying. It does not apply recursively to elements that are themselves composite objects; instead, the values of those elements become shared. 378 Chapter 8: Operators

387 PLRM 2nd Edition Operators January 26, 1994 In the case of arrays or strings, the length of the second object must be at least as great as the first; returns the initial subarray or substring of the second oper- copy array and into which the elements were copied. Any remaining elements of or 2 string are unaffected . copy cannot copy into packed arrays, because they are 2 read-only, but it can copy packed arrays into ordinary arrays. In the case of dictionaries, Level 1 implementations require that dict have a 2 of zero and a maxlength at least as great as the length of dict . Level 2 length 1 implementations do not impose this restriction, since dictionaries can expand when necessary. The attributes (literal or executable and access) of the result are normally the same as those of the second operand. However, in Level 1 implementations, the access attribute of dict is copied from that of dict . 2 1 If the value of the destination object is in global VM and any of the elements copied from the source object are composite objects whose values are in local error occurs (see section 3.7.2, “Local and Global VM”). invalidaccess VM, an Example /a1 [1 2 3] def ⇒ a1 dup length array copy [1 2 3] Errors: invalidaccess, rangecheck, stackunderflow, stackoverflow, typecheck See Also: dup, get, put, putinterval – copypage – copypage transmits one copy of the current page to the current output device without erasing the current page or changing the graphics state. This is in contrast to showpage , which performs the equivalent of an erasepage and an initgraphics . Aside from these differences, the behavior of copypage is identical to that of showpage . copypage is intended primarily as a debugging aid or as a means of printing suc- cessive pages with incrementally accumulated contents. Routine use of copypage as a substitute for showpage may severely degrade the page through- put of some PostScript printers. To print multiple copies of the same page, use the #copies implicit parameter of showpage or the NumCopies parameter of setpagedevice . Errors: (none) See Also: showpage, erasepage 8.2 Operator Details 379

388 PLRM 2nd Edition Operators January 26, 1994 angle cos real cos angle, which is interpreted as an angle in degrees. The result returns the cosine of is a real. Example 0 cos ⇒ 1.0 90 cos 0.0 ⇒ Errors: stackunderflow, typecheck See Also: atan, sin ... any any ... any n count any count 1 n 1 n counts the number of items on the operand stack and pushes this count on the operand stack. Example clear count ⇒ 0 clear 1 2 3 count ⇒ 1 2 3 3 Errors: stackoverflow See Also: counttomark countdictstack – countdictstack int counts the number of dictionaries currently on the dictionary stack and pushes this count on the operand stack. Errors: stackoverflow See Also: dictstack, begin, end 380 Chapter 8: Operators

389 PLRM 2nd Edition Operators January 26, 1994 countexecstack – countexecstack int counts the number of objects on the execution stack and pushes this count on the operand stack. Errors: stackoverflow See Also: execstack counttomark mark obj ... obj counttomark mark obj n ... obj 1 n 1 n counts the number of objects on the operand stack starting with the top element obj and continuing down to but not including the first mark encountered. 1 through obj are any objects other than marks. n Example 1 mark 2 3 counttomark ⇒ 1 mark 2 3 2 1 mark counttomark ⇒ 1 mark 0 stackoverflow, unmatchedmark Errors: See Also: mark, count LEVEL 2 proc string cshow – cshow invokes proc once for each operation of the font mapping algorithm (see section 5.9.1, “Character Mapping”). The value of currentfont during the execution of proc is the base font that the algorithm ultimately selects. When proc is invoked, the stack contains three values: the selected character’s code (an integer) and the x and y components of the width vector for the character in the user coordinate system. does not paint the character and does not change the current cshow point, although may do so. When proc completes execution, the value of proc currentfont is restored. cshow can be used to provide careful positioning of individual characters while taking advantage of the composite font mapping machinery of the interpreter. cshow is intended primarily for use with composite fonts (see section 5.9, “Com- posite Fonts”). However, it can also be used with a base font. The mapping algo- rithm for a base font simply selects consecutive characters from the string. Errors: invalidfont, invalidaccess, nocurrentpoint, rangecheck, stackunderflow, typecheck See Also: show, ashow, awidthshow, kshow, widthshow, xshow, xyshow, yshow 8.2 Operator Details 381

390 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 currentblackgeneration – proc currentblackgeneration returns the current black generation function in the graphics state. Errors: stackoverflow See Also: setblackgeneration LEVEL 2 – currentcacheparams mark size lower upper currentcacheparams pushes a mark object followed by the current cache parameters on the operand stack. The number of cache parameters returned is variable (see setcacheparams ). stackoverflow Errors: See Also: setcacheparams, setsystemparams, setuserparams LEVEL 2 currentcmykcolor – currentcmykcolor cyan magenta yellow black returns the current color in the graphics state according to the cyan-magenta- , DeviceCMYK yellow-black color space. If the current color space is currentcmykcolor returns the color values most recently specified by or setcolor . If the current color space is DeviceRGB or DeviceGray , setcmykcolor converts the current color to CMYK according to the conven- currentcmykcolor tions described in section 6.2, “Conversions Among Device Color Spaces.” For any other color space, currentcmykcolor returns 0.0 0.0 0.0 1.0. Errors: stackoverflow See Also: setcmykcolor LEVEL 2 currentcolor comp currentcolor – comp ... comp m 2 1 returns the components, in the current color space, of the color specified by the current color parameters in the graphics state. Errors: stackoverflow See Also: setcolor, setcolorspace Chapter 8: Operators 382

391 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 currentcolorrendering currentcolorrendering dict – returns the value of the CIE based color rendering dictionary parameter in the graphics state. Errors: stackoverflow See Also: setcolorrendering LEVEL 2 currentcolorscreen currentcolorscreen redfreq redang redproc – greenfreq greenang greenproc bluefreq blueang blueproc grayfreq grayang grayproc If the current halftone screen was specified by setcolorscreen , currentcolorscreen returns all 12 current halftone screen parameters in the graphics state. If the current screen was specified by setscreen , currentcolorscreen returns the three screen parameters repeated four times. If sethalftone , currentcolorscreen the current screen was specified by returns 60, 0, and the halftone dictionary, repeated four times. Errors: stackoverflow See Also: setcolorscreen, setscreen, sethalftone LEVEL 2 – array currentcolorspace currentcolorspace returns an array containing the identifying key and parameters of the color space in the graphics state. always returns an array, even if the currentcolorspace color space has no parameters and was selected by presenting just a name to . setcolorspace stackoverflow Errors: See Also: setcolorspace, setcolor 383 8.2 Operator Details

392 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 – currentcolortransfer redproc greenproc blueproc grayproc currentcolortransfer returns the current transfer functions in the graphics state for all four color com- ponents. If the current transfer functions were specified by setcolortransfer , currentcolortransfer returns those four operands. If settransfer was used, returns the single transfer function, repeated four times. currentcolortransfer Errors: stackoverflow See Also: setcolortransfer, settransfer DPS – currentcontext context currentcontext returns an integer that identifies the current execution context. See section 7.1, “Multiple Execution Contexts.” Errors: stackoverflow See Also: fork, join, detach – currentdash array offset currentdash returns the current dash array and offset in the graphics state. Errors: stackoverflow See Also: setdash, stroke LEVEL 2 string dict currentdevparams currentdevparams returns a dictionary containing the keys and current values of all parameters for string the device identified by . The returned dictionary is merely a container for currentdevparams allocates and returns a new key-value pairs. Each execution of dictionary. stackoverflow, VMerror Errors: See Also: setdevparams Chapter 8: Operators 384

393 PLRM 2nd Edition January 26, 1994 Operators – currentdict currentdict dict pushes the current dictionary (the dictionary on top of the dictionary stack) on currentdict the operand stack. does not pop the dictionary stack; it just pushes a duplicate of its top element on the operand stack. Errors: stackoverflow See Also: begin, dictstack – currentfile file currentfile returns the file object from which the PostScript interpreter is currently or was most recently reading program input. Precisely, returns the topmost currentfile file object on the execution stack. If there isn’t one, it returns an invalid file object that doesn’t correspond to any file. This never occurs during execution of ordinary user programs. The file returned by is usually but not always the standard input file. currentfile An important exception occurs during interactive mode operation (see section 3.8.3, “Special Files”). In this case, the interpreter does not read directly from the standard input file; instead, it reads from a file representing an edited statement (each statement is represented by a different file). The currentfile operator is useful for obtaining images or other data residing in the program file itself (see the example below). At any given time, this file is positioned at the end of the last PostScript language token read from the file by the interpreter. If that token was a number or a name immediately followed by a white space character, the file is positioned after the white space character (the first, if there are several). Otherwise it is positioned after the last character of the token. Example /str 100 string def currentfile str readline here is a line of text pop /textline exch def After execution of this example, the name / textline is associated with the string “here is a line of text ”. stackoverflow Errors: See Also: exec, run 8.2 Operator Details 385

394 PLRM 2nd Edition Operators January 26, 1994 – num currentflat currentflat returns the current value of the flatness parameter in the graphics state. stackoverflow Errors: See Also: setflat, flattenpath, stroke, fill currentfont – currentfont font returns the current font dictionary in the graphics state. Normally, this is the font most recently established by . However, when executed setfont or selectfont BuildGlyph or BuildChar procedure or a procedure invoked by inside a font’s cshow , currentfont returns the currently selected base font (descendant of a composite font). stackoverflow Errors: See Also: rootfont, selectfont, setfont LEVEL 2 – currentglobal bool currentglobal returns the VM allocation mode currently in effect. Errors: stackoverflow See Also: setglobal – currentgray num currentgray returns the gray value of the current color parameter in the graphics state. If the current color space is DeviceGray , currentgray returns the color value most DeviceRGB recently specified to setgray or setcolor . If the current color space is or , currentgray converts the current color to a gray value according DeviceCMYK to the conventions described in section 6.2, “Conversions Among Device Color Spaces.” For any other color space, currentgray returns 0.0. Errors: stackoverflow See Also: setgray, currentcolor, currentcolorspace, currenthsbcolor, currentrgbcolor 386 Chapter 8: Operators

395 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 gstate currentgstate gstate currentgstate replaces the value of the gstate object by a copy of the current graphics state and pushes gstate back on the operand stack. If gstate is in global VM (see section 3.7, “Memory Management”), will generate an invalidaccess error if currentgstate any of the composite objects in the current graphics state are in local VM. Such objects might include the current font, screen function, halftone dictionary, transfer function, or dash pattern. In general, allocating gstate objects in global VM is risky and should be avoided. Errors: invalidaccess, stackunderflow, typecheck See Also: gstate, setgstate LEVEL 2 currenthalftone – currenthalftone halftone returns the current halftone dictionary in the graphics state. If the current half- tone was defined by or setcolorscreen instead of by sethalftone, setscreen fabricates and returns a halftone dictionary (type 1 or 2) that currenthalftone contains the screen parameters. Errors: stackoverflow, VMerror See Also: setscreen, setcolorscreen, sethalftone DPS – currenthalftonephase x y currenthalftonephase returns the current values of the halftone phase parameters in the graphics state. If sethalftonephase has not been executed, zero is returned for both values. Errors: stackoverflow See Also: sethalftonephase 387 8.2 Operator Details

396 PLRM 2nd Edition January 26, 1994 Operators – hue saturation brightness currenthsbcolor currenthsbcolor returns the current color parameter in the graphics state according to the hue- saturation-brightness model. If the current color space is DeviceRGB , returns the color values most recently specified by sethsbcolor , currenthsbcolor setrgbcolor , or , converting them from RGB to HSB coordinates if neces- setcolor DeviceGray or sary. If the current color space is , currenthsbcolor DeviceCMYK first converts the current color to RGB according to the conventions described in section 6.2, “Conversions Among Device Color Spaces.” For any other color returns 0.0 0.0 0.0. currenthsbcolor space, Errors: stackoverflow See Also: sethsbcolor, currentcolor, currentgray, currentrgbcolor currentlinecap – currentlinecap int returns the current value of the line cap parameter in the graphics state. Errors: stackoverflow See Also: setlinecap, stroke, currentlinejoin currentlinejoin – currentlinejoin int returns the current value of the line join parameter in the graphics state. Errors: stackoverflow See Also: setlinejoin, stroke, currentlinecap currentlinewidth – currentlinewidth num returns the current value of the line width parameter in the graphics state. Errors: stackoverflow See Also: setlinewidth, stroke 388 Chapter 8: Operators

397 PLRM 2nd Edition January 26, 1994 Operators currentmatrix currentmatrix matrix matrix replaces the value of matrix with the value of the current transformation matrix (CTM) in the graphics state, and pushes the modified matrix back on the oper- and stack (see section 4.3, “Coordinate Systems and Transformations”). Errors: rangecheck, stackunderflow, typecheck See Also: setmatrix, defaultmatrix, initmatrix, rotate, scale, translate currentmiterlimit – currentmiterlimit num returns the current value of the miter limit parameter in the graphics state. Errors: stackoverflow See Also: setmiterlimit, stroke LEVEL 2 int currentobjectformat – currentobjectformat returns the object format parameter currently in effect. stackoverflow Errors: See Also: setobjectformat LEVEL 2 – currentoverprint bool currentoverprint returns the value of the overprint parameter in the graphics state. Errors: stackoverflow See Also: setoverprint LEVEL 2 – currentpacking bool currentpacking returns the array packing mode currently in effect. Errors: stackoverflow See Also: setpacking, packedarray 8.2 Operator Details 389

398 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 currentpagedevice – dict currentpagedevice returns a read-only dictionary that describes the page-oriented output device in the current graphics state. creates a new dictionary if neces- currentpagedevice sary. If the device in the current graphics state is not a page device, currentpagedevice ) . See section 4.11, returns an empty dictionary (length of 0 “Device Setup.” Changes made to the hardware state of the output device since the last execu- tion of setpagedevice , such as changing paper trays or switches, are not immedi- ately reflected in this dictionary. If the current context is under the control of a job server (see section 3.7.7, “Job Execution Environment”), the server sets up a device that matches the hardware state before starting each job. At the begin- ning of each job, therefore, the dictionary currentpagedevice returns matches the current hardware state. Errors: stackoverflow, VMerror See Also: setpagedevice currentpoint – currentpoint x y coordinates of the current point in the graphics state (i.e., the returns the x and y trailing endpoint of the current path). If the current point is undefined because the current path is empty, executes the nocurrentpoint error. currentpoint The current point is reported in the user coordinate system. As discussed in sec- tion 4.4, “Path Construction,” points entered into a path are immediately con- verted to device coordinates by the current transformation matrix (CTM); existing points are not changed by subsequent modifications to the CTM. computes the user space coordinate that corresponds to the current currentpoint point according to the current value of the CTM. If a current point is set and then the CTM is changed, currentpoint will report a different position in user space than it did before. Errors: nocurrentpoint, stackoverflow, undefinedresult See Also: moveto, lineto, curveto, arc – currentrgbcolor red green blue currentrgbcolor returns the three components of the current color in the graphics state accord- ing to the red-green-blue color model. If the current color space is DeviceRGB , currentrgbcolor returns the color values most recently specified to setrgbcolor or setcolor (or transformed values specified to sethsbcolor ). If the current color 390 Chapter 8: Operators

399 PLRM 2nd Edition Operators January 26, 1994 DeviceGray converts the current color DeviceCMYK , currentrgbcolor space is or to RGB according to the conventions described in section 6.2, “Conversions currentrgbcolor returns Among Device Color Spaces.” For any other color space, 0.0 0.0 0.0. Errors: stackoverflow See Also: setrgbcolor, currentcolor, currentgray, currenthsbcolor currentscreen frequency angle proc – currentscreen – currentscreen frequency angle halftone returns the current halftone screen parameters ( frequency , angle , and proc ) in the graphics state, assuming the current screen was established by setscreen . If currentscreen returns the parameters for the gray setcolorscreen was executed, screen. If currentscreen returns the frequency, angle, was executed, sethalftone frequency angle and halftone dictionary. For type 1 halftone dictionaries, the and values are extracted from the halftone dictionary. For all other types, currentscreen returns a frequency of 60 and an angle of 0. Errors: stackoverflow See Also: setcolorscreen, setscreen, sethalftone LEVEL 2 currentshared – currentshared bool has the same semantics as currentglobal . This operator is defined for compatibil- ity with existing Display PostScript applications. Errors: stackoverflow See Also: setglobal, setshared LEVEL 2 currentstrokeadjust – currentstrokeadjust bool returns the current stroke adjust parameter in the graphics state. Errors: stackoverflow See Also: setstrokeadjust 8.2 Operator Details 391

400 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 currentsystemparams – currentsystemparams dict returns a dictionary containing the keys and current values of all system param- eters that are defined in the implementation. The returned dictionary is merely a container for key-value pairs. Each execution of currentsystemparams allocates and returns a new dictionary. See Appendix C for information about specific sys- tem parameters. Errors: stackoverflow, VMerror See Also: setsystemparams currenttransfer – currenttransfer proc returns the current transfer function in the graphics state, assuming that it was currenttransfer established by settransfer . If setcolortransfer was executed, returns the gray transfer function. stackoverflow Errors: See Also: settransfer, setcolortransfer LEVEL 2 – currentundercolorremoval proc currentundercolorremoval returns the current undercolor removal function in the graphics state. Errors: stackoverflow See Also: setundercolorremoval LEVEL 2 – currentuserparams dict currentuserparams returns a dictionary containing the keys and current values of all user parame- ters that are defined in the implementation. The returned dictionary is a con- currentuserparams allocates and tainer for key-value pairs. Each execution of returns a new dictionary. See Appendix C for more information about specific user parameters. stackoverflow, VMerror Errors: See Also: setuserparams 392 Chapter 8: Operators

401 PLRM 2nd Edition January 26, 1994 Operators curveto x y – x curveto y y x 3 3 2 1 1 2 adds a Bézier cubic section to the current path between the current point, x ) as the , y y ), and the point ( x , , y referred to here as ( ), using ( x x , y ) and ( 1 1 2 3 0 2 0 3 x , y 22 makes ( x ) , y Bézier cubic control points. After constructing the curve, curveto 3 3 x , y 11 the new current point. If the current point is undefined because the current path . is empty, curveto executes the error nocurrentpoint The four points define the shape of the curve geometrically. The curve starts at x , y x , y 33 00 , y ), it is tangent to the line from ( ) to ( x x , x y ) at that point, and it leaves , ( y 1 0 0 1 0 0 , y x ), it is tangent to the line the point in that direction. The curve ends at ( 3 3 x , y 11 ) to ( x , , x from ( y ) at that point, and it approaches the point from that direc- y 2 3 3 2 y , ) and ( x ) to ( , y y ) to ( x , , x tion. The lengths of the lines ( ) represent, in y x 3 1 0 1 3 2 0 2 x , y 33 a sense, the “velocity” of the path at the endpoints. The curve is always entirely enclosed by the convex quadrilateral defined by the four points. x , y 00 x , y 22 The mathematical formulation of a Bézier cubic curve is derived from a pair of parametric cubic equations: x , y 11 x , y 22 3 2 +++ b tx () c = xt t a t x x 0 x 2 3 c t b ty = +++ t () yt a y 0 y y x , y 33 x , y 00 as t The cubic section produced by curveto is the path traced by x(t) and y(t) ranges from 0 to 1. The Bézier control points corresponding to this curve are: x = x + c ⁄ 3 ⁄ + = y 3 y c 0 y 1 x 0 1 b x = x + c ⁄ = 3 + () 3 ⁄ + y () y + c b y 1 2 x x 1 2 y x x c = b ++ + a y a b ++ + c y = x x 0 3 x 3 0 y y y limitcheck, nocurrentpoint, stackunderflow, typecheck Errors: See Also: lineto, moveto, arc, arcn, arct, arcto 393 8.2 Operator Details

402 PLRM 2nd Edition Operators January 26, 1994 num int cvi cvi cvi int string (convert to integer) takes an integer, real, or string object from the stack and pro- duces an integer result. If the operand is an integer, cvi simply returns it. If the operand is a real, it truncates any fractional part (i.e., rounds it toward 0) and converts it to an integer. If the operand is a string, it interprets the characters of the string as a number according to the PostScript syntax rules. If that number is error if a real is too cvi converts it to an integer. cvi executes a rangecheck a real, large to convert to an integer. (See the round, truncate, floor, and ceiling opera- tors, which remove fractional parts without performing type conversion.) Example 33 ⇒ (3.3E1) cvi –47.8 cvi ⇒ –47 ⇒ 520.9 cvi 520 Errors: invalidaccess, rangecheck, stackunderflow, syntaxerror, typecheck, undefinedresult See Also: cvr, ceiling, floor, round, truncate any cvlit any cvlit (convert to literal) makes the object on the top of the operand stack have the lit- eral instead of executable attribute. Errors: stackunderflow See Also: cvx, xcheck string cvn name cvn (convert to name) converts the string operand to a name object that is lexically the same as the string. The name object is executable if the string was. Example (abc) cvn ⇒ /abc (abc) cvx cvn ⇒ abc Errors: invalidaccess, limitcheck, stackunderflow, typecheck See Also: cvs, type 394 Chapter 8: Operators

403 PLRM 2nd Edition January 26, 1994 Operators num cvr cvr real real cvr string (convert to real) takes an integer, real, or string object and produces a real result. converts it to a real. If the operand is a real, cvr If the operand is an integer, cvr simply returns it. If the operand is a string, it interprets the characters of the string as a number according to the PostScript syntax rules. If that number is an integer, cvr converts it to a real. Errors: invalidaccess, limitcheck, stackunderflow, syntaxerror, typecheck, undefinedresult See Also: cvi cvrs cvrs substring num radix string num (convert to string with radix) produces a text representation of the number radix, stores the text into the supplied string (overwriting some in the specified initial portion of its value), and returns a string object designating the substring string is too small to hold the result of the conversion, cvrs exe- actually used. If cutes the error rangecheck. cvs radix If when applied to either an inte- is 10, cvrs produces the same result as ger or a real. That is, it produces a signed integer or real token that conforms to the PostScript language syntax for that number. radix . Then it treats the cvrs converts num to an integer, as if by cvi If is not 10, machine representation of that integer as an unsigned positive integer and con- verts it to text form according to the specific radix. The resulting text is not nec- essarily a valid number. However, if it is immediately preceded by the same radix and # , the combination is a valid PostScript language token that represents the same number. Example /temp 12 string def 123 10 temp cvrs (123) ⇒ –123 10 temp cvrs ⇒ (–123) 123.4 10 temp cvrs ⇒ (123.4) 123 16 temp cvrs ⇒ (7B) –123 16 temp cvrs ⇒ (FFFFFF85) 123.4 16 temp cvrs ⇒ (7B) Errors: invalidaccess, rangecheck, stackunderflow, typecheck See Also: cvs 8.2 Operator Details 395

404 PLRM 2nd Edition January 26, 1994 Operators any string cvs cvs substring , any (convert to string) produces a text representation of an arbitrary object (overwriting some initial portion of its string stores the text into the supplied value), and returns a string object designating the substring actually used. If the is too small to hold the result of conversion, cvs executes the error string rangecheck. If any cvs produces a string representation of that number. If any is a is a number, cvs boolean, true or the string false . If any is a string, produces either the string any produces cvs copies its contents into string . If cvs is a name or an operator, the text representation of that name or the operator’s name. If any is any other cvs --nostringval-- . type, produces the text any is a real number, the precise format of the result string is implementation If dependent and not under program control. For example, the value 0.001 might be represented as 0.001 or as 1.0E-3 . Example /str 20 string def ⇒ (579) 123 456 add str cvs mark str cvs ⇒ (--nostringval--) Errors: invalidaccess, rangecheck, stackunderflow, typecheck See Also: cvi, cvr, string, type cvx any cvx any (convert to executable) makes the object on top of the operand stack have the executable instead of literal attribute. Errors: stackunderflow See Also: cvlit, xcheck 396 Chapter 8: Operators

405 PLRM 2nd Edition January 26, 1994 Operators def key value def – associates key with value in the current dictionary—the one on the top of the dic- tionary stack (see section 3.4, “Stacks”). If key is already present in the current dictionary, def simply replaces its value. Otherwise, def creates a new entry for value with it. key and stores If the current dictionary is in global VM and is a composite object whose value value is in local VM, an invalidaccess error occurs (see section 3.7.2, “Local and Global VM”). Example /ncnt 1 def % Define ncnt to be 1 in current dict /ncnt ncnt 1 add def % ncnt now has value 2 Errors: dictfull, invalidaccess, limitcheck, stackunderflow, typecheck, VMerror See Also: store, put matrix defaultmatrix matrix defaultmatrix replaces the value of matrix with the default transformation matrix for the cur- rent output device and pushes this modified matrix back on the operand stack. rangecheck, stackunderflow, typecheck Errors: See Also: currentmatrix, initmatrix, setmatrix 8.2 Operator Details 397

406 PLRM 2nd Edition Operators January 26, 1994 key font font definefont definefont registers font as a font dictionary associated with key (usually a name), as dis- definefont cussed in section 5.2, “Font Dictionaries.” font is a first checks that well-formed font dictionary—in other words, contains all required key-value pairs. It inserts an additional entry whose key is FID and whose value is an object of type fontID. The dictionary must be large enough to accommodate this addi- tional entry. It makes the dictionary’s access read-only. Finally, it associates key with font in the font directory. In Level 2, it is permissible to associate a font dictionary with more than one key. If has already been registered, definefont does not alter it in any way. font font is a composite font (see section 5.9, “Composite Fonts”), definefont also If inserts the entries MIDVector and CurMID , and adds entries PrefEnc , EscChar , ShiftIn , and ShiftOut if they are required and are not already present. All the previously. definefont descendant fonts must have been registered by Subsequent invocation of key will return font . Font registration is with findfont subject to the normal semantics of VM (see section 3.7, “Memory Manage- ment”). In particular, the lifetime of the definition depends on the VM alloca- tion mode at the time definefont is executed. A local definition can be undone by a subsequent restore . definefont is actually a special case of defineresource operating on the Font cat- egory. For details, see defineresource and section 3.9, “Named Resources.” limitcheck, rangecheck, dictfull, invalidfont, stackunderflow, Errors: typecheck, invalidaccess See Also: makefont, scalefont, setfont, defineresource, FontDirectory, GlobalFontDirectory, setglobal LEVEL 2 defineresource defineresource instance key instance category associates a resource instance with a resource name in a specified category. category is a name object that identifies a resource category, such as Font (see sec- tion 3.9.2, “Resource Categories”). key is a name or string object that will be used to identify the resource instance. (Names and strings are interchangeable; other instance is the resource types of keys are permitted but are not recommended.) instance itself; its type must be appropriate to the resource category. Before defining the resource instance, defineresource verifies that the instance object is the correct type. Depending on the resource category, it may also per- form additional validation of the object and may have other side effects. Finally, it makes the object read-only if its access is not already restricted. 398 Chapter 8: Operators

407 PLRM 2nd Edition Operators January 26, 1994 The lifetime of the definition depends on the VM allocation mode in effect at the time is executed. If local VM allocation is in effect defineresource currentglobal ( false ), the effect of defineresource is undone by the next returns non-nested restore . If global VM allocation is in effect ( currentglobal returns true defineresource persists until global VM is restored at the end ), the effect of of the job. If the current job is not encapsulated, the effect of a global defineresource persists indefinitely, and may be visible to other execution contexts. Local and global definitions are maintained separately. If a new resource instance is defined with the same category and key as an existing one, the new definition overrides the old one. The precise effect depends on whether the old definition is local or global and whether the new definition (current VM alloca- tion mode) is local or global. There are two main cases: defineresource installs the new local definition, 1. New definition is local— replacing an existing local definition if there is one. If there is an existing glo- bal definition, does not disturb it. However, the global defini- defineresource tion is obscured by the local one. If the local definition is later removed, the global definition reappears. defineresource first removes an existing local defi- 2. New definition is global— nition if there is one. It then installs the new global definition, replacing an existing global definition if there is one. It is permissible to use defineresource multiple times to associate a given resource instance with more than one key. If the category name is unknown, an undefined error occurs. If the instance is of the wrong type for the specified category, a error occurs. If the typecheck instance is in local VM but the current VM allocation mode is global, an invalidaccess error occurs. This is analogous to storing a local object into a global dictionary. Other errors can occur for specific categories. For example, when error. Font category, defineresource can execute an invalidfont dealing with the Errors: invalidaccess, stackunderflow, typecheck, undefined See Also: undefineresource, findresource, resourcestatus, resourceforall 8.2 Operator Details 399

408 PLRM 2nd Edition Operators January 26, 1994 DPS defineusername defineusername – index name establishes an association between the non-negative integer index and the name name in the user name table. Subsequently, the scanner will substitute object name when it encounters any binary encoded name token or object that refers to index . Because binary encoded names specify their own the specified user name literal or executable attributes, it does not matter whether is literal or exe- name cutable. See section 7.2, “Encoded User Names.” The user name table is an adjunct to the current context’s local VM (see section 7.1, “Multiple Execution Contexts”). The effect of adding an entry to the table is immediately visible to all contexts that share the same local VM. Additions to the table are not affected by save restore . The association between index and and persists for the remaining lifetime of the local VM. name The specified index must previously be unused in the name table or must already be associated with the same name . Changing an existing association is not per- mitted (an invalidaccess error will occur). There may be an implementation limit on index values. Assigning index values sequentially starting at zero is strongly recommended. Errors: invalidaccess, limitcheck, rangecheck, stackunderflow, typecheck LEVEL 2 defineuserobject index any – defineuserobject index establishes an association between the non-negative integer and the object in the UserObjects array. First, it creates a UserObjects array in userdict if any one is not already present. It extends an existing UserObjects array if necessary. It then executes the equivalent of userdict /UserObjects get 3 1 roll put any into the array at the position specified by In other words, it simply stores index. See section 3.7.6, “User Objects.” If defineuserobject creates or extends the UserObjects array, it allocates the array in local VM, regardless of the current VM allocation mode. defineuserobject obeys normal PostScript language semantics in The behavior of all respects. In particular, the modification to the UserObjects array and to userdict, if any, is immediately visible to all contexts that share the same local VM. It can be undone by a subsequent restore according to the usual VM rules. index values must be within the range permitted for arrays; a large index value may cause allocation of an array that would exhaust VM resources. Assigning index values sequentially starting at zero is strongly recommended. 400 Chapter 8: Operators

409 PLRM 2nd Edition Operators January 26, 1994 Errors: limitcheck, rangecheck, stackunderflow, typecheck, VMerror See Also: execuserobject, undefineuserobject, UserObjects LEVEL 2 deletefile filename deletefile – removes the specified file from its storage device. If no such file exists, an undefinedfilename error occurs. If the device does not allow this operation, an invalidfileaccess error occurs. If an environment dependent error is detected, an ioerror occurs. See section 3.8.2, “Named Files.” Errors: invalidfileaccess, ioerror, stackunderflow, typecheck, undefinedfilename See Also: file, renamefile, status DPS detach detach – context specifies that the execution context identified by the integer context is to termi- nate immediately when it finishes executing its top-level procedure whereas , ordinarily it would wait for a join. If the context is already waiting for a join, detach causes it to terminate immediately. See section 7.1, “Multiple Execution Contexts.” invalidcontext executes an detach error if context is not a valid context identifier context or if the context has already been joined or detached. It is permissible for to identify the current context. Errors: invalidcontext, stackunderflow, typecheck See Also: currentcontext, fork, join 401 8.2 Operator Details

410 PLRM 2nd Edition Operators January 26, 1994 DPS deviceinfo – deviceinfo dict returns a read-only dictionary containing static information about the current device. The composition of this dictionary varies according to the properties of the device. Typical entries are given in the table in section 7.3, “Graphics and Window Systems.” The information in the dictionary may not be meaningful for a page-oriented or other non-display device. deviceinfo after a setcachedevice operation within the scope of a The use of procedure is not permitted. An undefined error results. BuildChar Errors: stackoverflow, undefined dict int dict dict creates an empty dictionary with an initial capacity of int elements and pushes the created dictionary object on the operand stack. int is expected to be a non- negative integer. The dictionary is allocated in local or global VM according to the VM allocation mode. See section 3.7.2, “Local and Global VM.” In Level 1 implementations, the resulting dictionary has a maximum capacity of elements. Attempting to exceed that limit causes a error. int dictfull int operand specifies only the initial capacity; In Level 2 implementations, the dict operator the dictionary can grow beyond that capacity if necessary. The immediately consumes sufficient VM to hold int key-value pairs. If more than that number of entries are subsequently stored in the dictionary, additional VM is consumed at that time. There is a cost associated with expanding a dictionary beyond its initial alloca- tion. For efficiency reasons, a dictionary is expanded in chunks rather than one element at a time, so it may contain a substantial amount of unused space. If a program knows how large a dictionary it needs, it should create one of that size initially. On the other hand, if a program cannot predict how large the diction- ary will eventually grow, it should choose a small initial allocation sufficient for its immediate needs. The built-in writable dictionaries (for example, userdict ) follow the latter convention. Errors: limitcheck, stackunderflow, typecheck, VMerror See Also: begin, end, length, maxlength 402 Chapter 8: Operators

411 PLRM 2nd Edition January 26, 1994 Operators (error) dictfull or store attempts to define a new entry in a dictionary occurs when def, put, and are already length that is already full—in other words, whose maxlength equal. This can occur only in Level 1 implementations, where a dictionary has a fixed limit on the number of entries with distinct keys it can hold. This limit is dict operator that creates the dictionary. established by the operand to the See Also: def, put, store, dict dictstack dictstack subarray array stores all elements of the dictionary stack into and returns an object array n n array , where describing the initial is the current depth of -element subarray of dictstack copies the topmost dictionary into element n –1 of the dictionary stack. array array . The dictionary stack itself and the bottommost one into element 0 of is unchanged. If the length of array is less than the depth of the dictionary stack, executes a error. dictstack rangecheck Errors: invalidaccess, rangecheck, stackunderflow, typecheck See Also: countdictstack dictstackoverflow (error) The dictionary stack has grown too large. Too many begin operators without corresponding end operators have pushed too many dictionaries on the diction- ary stack. See Appendix B for the limit on the size of the dictionary stack. Before invoking this error, the interpreter creates an array containing all ele- dictstack , pushes this array on the ments of the dictionary stack stored as if by operand stack, and resets the dictionary stack to contain only the permanent entries . See Also: begin, countdictstack, cleardictstack dictstackunderflow (error) An attempt has been made to remove ( end ) the bottommost instance of userdict from the dictionary stack. This occurs if an end is executed for which there was no corresponding begin. See Also: end 8.2 Operator Details 403

412 PLRM 2nd Edition January 26, 1994 Operators num div quotient div num 1 2 num by num , producing a result that is always a real even if both oper- divides 2 1 idiv if an integer result is desired. ands are integers. Use Example 3 2 div 1.5 ⇒ ⇒ 4 2 div 2.0 Errors: stackunderflow, typecheck, undefinedresult See Also: idiv, add, mul, sub, mod dtransform dtransform dx‘ dy‘ dx dy dx dy matrix dtransform dx‘ dy‘ dtransform operand, With no matrix (delta transform) transforms the distance vector ( dx, dy dx‘, dy‘ ) ) by the CTM to produce the corresponding distance vector ( matrix operand is supplied, in device space. If the transforms the dis- dtransform tance vector by matrix rather than by CTM. A delta transformation is similar to a normal transformation (see section 4.3, “Coordinate Systems and Transformations”), but the translation components ( t ) of the transformation matrix are not used, making the distance vec- and t y x tors positionless in both user space and device space. This is useful for determin- ing how distances map from user space to device space. Errors: rangecheck, stackunderflow, typecheck See Also: idtransform, transform, itransform dup any dup any any duplicates the top element on the operand stack. Note that dup copies only the object. The value of a composite object is not copied but is shared. See section 3.3, “Data Types and Objects.” Errors: stackoverflow, stackunderflow See Also: copy, index 404 Chapter 8: Operators

413 PLRM 2nd Edition January 26, 1994 Operators bool echo echo – and are to copy char- %lineedit specifies whether the special files %statementedit acters from the standard input file to the standard output file. This affects only ; it does not apply to normal communication with the the behavior of executive is not defined in products that do not support PostScript interpreter. echo executive . See section 2.4.4, “Using the Interpreter Interactively,” and section 3.8.3, “Special Files.” Errors: stackunderflow, typecheck See Also: executive, file eexec file – eexec eexec string – causes the contents of file (open for reading) or string to be decrypted and then exec executed in a manner similar to the operator. The decryption operation does not cause the file or string to be modified. eexec creates a new file object that serves as a decryption filter on the specified or . It pushes the new file object on the execution stack, making it the file string current file for the PostScript interpreter. Subsequently, each time the interpreter currentfile , the reads a character from this file, or a program reads explicitly from decryption filter reads one character from the original file or string and decrypts it. The decryption filter file is closed automatically when the end of the original file or is encountered. It may also be closed explicitly by closefile . If the file string passed to eexec was currentfile , this resumes direct execution of that file with the decryption filter removed. The file may consist of encrypted text followed by unencrypted text if the last thing executed in the encrypted text is currentfile closefile . Before beginning execution, eexec pushes systemdict on the dictionary stack. This ensures that the operators executed by the encrypted program have their standard meanings. When the decryption filter file is closed either explicitly or implicitly, the dictionary stack is popped. The program must be aware that it is being executed with systemdict as the current dictionary; in particular, any defi- nitions that it makes must be into a specific dictionary rather than the current one, since systemdict is read-only. The encrypted file may be represented in either binary or hex; the eexec opera- tor can decrypt it without being told which type it is. The recommended repre- sentation is hex, because hex data can be transmitted through communication channels that are not completely transparent. Regardless of the representation of 8.2 Operator Details 405

414 PLRM 2nd Edition Operators January 26, 1994 the encrypted file, the encryption and decryption processes are transparent. That is, an arbitrary binary file can be encrypted, transmitted as either binary or hex, and decrypted to yield the original information. The encryption employed by is intended primarily for use in Type 1 font eexec programs. The book Adobe Type 1 Font Format contains a complete description of the encryption algorithm and recommended uses of eexec . Errors: dictstackoverflow, invalidaccess, invalidfileaccess, limitcheck, stackunderflow, typecheck See Also: exec, filter end – end – pops the current dictionary off the dictionary stack, making the dictionary below it the current dictionary. If end tries to pop the bottommost instance of dictstackunderflow. it executes the error userdict, Errors: dictstackunderflow See Also: begin, dictstack, countdictstack eoclip – eoclip – intersects the inside of the current clipping path with the inside of the current path to produce a new, smaller current clipping path. The inside of the current path is determined by the even-odd rule (see section 4.5, “Painting”), while the inside of the current clipping path is determined by whatever rule was used at the time that path was created. Except for the choice of insideness rule, the behavior of is identical to that eoclip of clip. Errors: limitcheck See Also: clip, clippath, initclip eofill – eofill – paints the inside of the current path with the current color, using the even-odd rule (see section 4.5, “Painting”) to determine what points are inside. Except for is identical to that of fill. the choice of insideness rule, the behavior of eofill 406 Chapter 8: Operators

415 PLRM 2nd Edition Operators January 26, 1994 Errors: limitcheck See Also: fill, ineofill, ueofill DPS – eoviewclip eoviewclip viewclip , except that it uses the even-odd rule (see section 4.5, is similar to “Painting”) to determine the inside of the current path. Errors: limitcheck See Also: viewclip any eq any eq bool 2 1 true pops two objects from the operand stack and pushes the boolean value if false if not. The definition of equality depends on the types of the they are equal, objects being compared. Simple objects are equal if their types and values are the same. Strings are equal if their lengths and individual elements are equal. Other composite objects (arrays and dictionaries) are equal only if they share the same value. Separate values are considered unequal, even if all the components of those values are the same. Some type conversions are performed by eq . Integers and reals can be compared freely: An integer and a real representing the same mathematical value are con- sidered equal by eq . Strings and names can likewise be compared freely: A name defined by some sequence of characters is equal to a string whose elements are the same sequence of characters. The literal/executable and access attributes of objects are not considered in com- parisons between objects. Example 4.0 4 eq ⇒ true % A real and an integer may be equal (abc) (abc) eq ⇒ true % Strings with equal elements are equal (abc) /abc eq true % A string and a name may be equal ⇒ [1 2 3] dup eq ⇒ true % An array is equal to itself [1 2 3] [1 2 3] eq ⇒ false % Distinct array objects not equal Errors: invalidaccess, stackunderflow See Also: ne, le, lt, ge, gt 8.2 Operator Details 407

416 PLRM 2nd Edition Operators January 26, 1994 – erasepage – erasepage erases the entire current page by painting it with gray level 1, which is ordinarily white, but may be some other color if an atypical transfer function has been defined. The entire page is erased, regardless of the clip path currently in force. erasepage affects only the contents of raster memory. It does not modify the graphics state nor does it cause a page to be transmitted to the output device. erasepage is executed automatically by showpage after imaging. There are few situations in which a PostScript language page description should execute explicitly, because the operator affects portions of the current page erasepage outside the current clip path. It is usually more appropriate to erase just the inside of the current clip path (see clippath ). Then the page description can be embedded within another, composite page without undesirable effects. Errors: (none) See Also: showpage, clippath, fill errordict dict errordict – pushes the dictionary object on the operand stack (see section 3.10, errordict errordict is not an operator; it is a name in systemdict associated with “Errors”). the dictionary object. stackoverflow Errors: See Also: $error exch any any exch any any 1 1 2 2 exchanges the top two elements on the operand stack. Example 1 2 exch ⇒ 2 1 stackunderflow Errors: See Also: dup, roll, index, pop 408 Chapter 8: Operators

417 PLRM 2nd Edition January 26, 1994 Operators any – exec exec pushes the operand on the execution stack, executing it immediately. The effect of executing an object depends on the object’s type and literal/executable attribute; this is discussed in detail in section 3.5, “Execution.” In particular, exe- cuting a literal object will cause it only to be pushed back on the operand stack. Executing a procedure, however, will cause the procedure to be called. Example ⇒ 5 (3 2 add) cvx exec ⇒ 3 2 /add exec 3 2 /add ⇒ 5 3 2 /add cvx exec (3 2 add) is made executable and then executed. Exe- In the first line, the string cuting a string causes its characters to be scanned and interpreted according to the PostScript language syntax rules. are pushed on the operand /add In the second line, the literal objects 3 , 2 , and is a literal name, executing stack, then add . Since the add is applied to the exec it simply causes it to be pushed back on the operand stack. The exec in this case has no useful effect. In the third line, the literal name /add on the top of the operand stack is made executable by cvx . Applying exec to this executable name causes it to be looked up and the add operation to be performed. Errors: stackunderflow See Also: xcheck, cvx, run 8.2 Operator Details 409

418 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 execform form – execform paints a form specified by a form dictionary constructed as described in section 4.7, “Forms.” The graphical output produced by is defined by the form execform dictionary’s PaintProc procedure. If this is the first invocation of execform for form , execform first verifies that the dictionary contains the required entries. Then it adds an entry to the dictionary Implementation , whose value is private to the implementation. with the key Finally, it makes the dictionary read-only. ( execform performs these alterations directly to the operand dictionary; it does not copy the dictionary.) When execform needs to call the PaintProc procedure, it pushes the form dic- tionary on the operand stack, then executes the equivalent of gsave % Operand stack: dict dup /Matrix get concat % Stack: dict llx lly urx ury dup /BBox get aload pop exch 3 index sub exch 2 index sub % Stack: dict llx lly width height % Also does a newpath rectclip % Stack: dict proc dup /PaintProc get exec % Execute PaintProc with dict on stack grestore The procedure is expected to consume the dictionary operand and to PaintProc execute a sequence of graphics operators to paint the form. The PaintProc must always produce the same output, given the same graphics state parameters, inde- pendent of the number of times it is called and independent, for example, of the contents of . The PostScript language program should not expect any userdict particular execution of execform to cause execution of the specified PaintProc . The documented errors are those produced directly by execform . Obviously, the PaintProc can cause other errors. Errors: limitcheck, rangecheck, stackunderflow, typecheck, undefined, VMerror See Also: findresource 410 Chapter 8: Operators

419 PLRM 2nd Edition Operators January 26, 1994 array subarray execstack execstack array and returns an object stores all elements of the execution stack into describing the initial -element subarray of array, where n is the current depth of n –1 of the execution stack. execstack copies the topmost object into element n array array . The execution stack itself and the bottommost one into element 0 of is unchanged. If the length of array is less than the depth of the execution stack, execstack executes a rangecheck error. Errors: invalidaccess, rangecheck, stackunderflow, typecheck See Also: countexecstack, exec execstackoverflow (error) The execution stack has grown too large; procedure invocation is nested deeper than the PostScript interpreter permits. See Appendix B for the limit on the size of the execution stack. See Also: exec LEVEL 2 execuserobject execuserobject – index executes the object associated with the non-negative integer index in the UserObjects array. execuserobject is equivalent to: userdict /UserObjects get exch get exec execuserobject ’s semantics are similar to those of exec or other explicit execu- tion operators. That is, if the object is executable, it is executed; otherwise, it is pushed on the operand stack. See section 3.7.6, “User Objects.” userdict If UserObjects is not defined in has never because defineuserobject been executed, an error occurs. If index is not a valid index for the undefined existing UserObjects array, a rangecheck error occurs. If index is a valid index but defineuserobject has not been executed previously for that index, a null object is returned. Errors: invalidaccess, rangecheck, stackunderflow, typecheck, undefined See Also: defineuserobject, undefineuserobject, UserObjects 8.2 Operator Details 411

420 PLRM 2nd Edition Operators January 26, 1994 array executeonly array executeonly executeonly packedarray packedarray file executeonly file string executeonly string reduces the access attribute of an array, packed array, file, or string object to exe- cute-only (see section 3.3.2, “Attributes of Objects”). Access can only be reduced by these means, never increased. When an object is execute-only, its value can- not be read or modified explicitly by PostScript operators (an invalidaccess error will result), but it can still be executed by the PostScript interpreter—for exam- ple, by invoking it with exec . executeonly affects the access attribute only of the object that it returns. If there are other composite objects that share the same value, their access attributes are unaffected. invalidaccess, stackunderflow, typecheck Errors: See Also: rcheck, wcheck, xcheck, readonly, noaccess executive – – executive invokes the interactive executive, which facilitates direct user interaction with the PostScript interpreter. See section 2.4.4, “Using the Interpreter Interactively” for complete information. executive uses the special %statementedit file to obtain commands from the user (see section 3.8.3, “Special Files”). The echo operator and the value of prompt also affect the behavior of executive . executive is not necessarily defined in all products. It should not be considered a standard part of the PostScript language. Errors: undefined See Also: prompt, echo, file 412 Chapter 8: Operators

421 PLRM 2nd Edition January 26, 1994 Operators – exit exit – terminates execution of the innermost, dynamically enclosing instance of a looping context without regard to lexical relationship. A looping context is a procedure invoked repeatedly by one of the following control operators: cshow pathforall forall filenameforall kshow repeat loop resourceforall for pops the execution stack down to the level of that operator. The interpreter exit then resumes execution at the next object in normal sequence after that operator. does not affect the operand or dictionary stacks. Any objects pushed on exit those stacks during execution of the looping context remain after the context is exited. If would escape from the context of a run or stopped operator, it executes exit stopped invalidexit the ). If there is no error (still in the context of the run or enclosing looping context, the interpreter prints an error message and executes the built-in operator . This never occurs during execution of ordinary user quit stopped context. programs, because they are enclosed by a Errors: invalidexit See Also: stop, stopped exp base exponent exp real raises base to the exponent power. The operands may be either integers or reals. If the exponent has a fractional part, the result is meaningful only if the base is non-negative. The result is always a real. Example 9 0.5 exp ⇒ 3.0 –9 –1 exp ⇒ –0.111111 Errors: stackunderflow, typecheck, undefinedresult See Also: sqrt, ln, log, mul 8.2 Operator Details 413

422 PLRM 2nd Edition January 26, 1994 Operators – false false false on the operand stack. is not an false false pushes a boolean object whose value is associated with the boolean value operator; it is a name in . systemdict false stackoverflow Errors: See Also: true, and, or, not, xor file filename access file file filename creates a file object for the file identified by , accessing it as specified by access . Both operands are strings. Conventions for both file names and access specifications depend on the operating system environment in which the Post- Script interpreter is running. See section 3.8.2, “Named Files.” file object remains valid until the file is closed Once created and opened, the either explicitly (by executing closefile ) or implicitly (by encountering end-of- restore file while reading or executing the file). A file is also closed by if the file object was created more recently than the snapshot being restored, or is save closed by garbage collection if the file object is no longer accessible. There is a limit on the number of files that can be open simultaneously. See Appendix B. If the specified filename is malformed or if the file doesn’t exist and access does not permit creating a new file, file executes an undefinedfilename error. If access is malformed or the requested access is not permitted by the device, an invalidfileaccess error occurs. If the number of files opened by the current con- error occurs. If an environ- limitcheck text exceeds an implementation limit, a ment-dependent error is detected, an ioerror occurs. Example (%stdin) (r) file ⇒ % standard input file object (myfile) (w) file ⇒ % output file object, writing to named file invalidfileaccess, ioerror, limitcheck, stackunderflow, typecheck, Errors: undefinedfilename See Also: closefile, currentfile, filter, status 414 Chapter 8: Operators

423 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 filenameforall template proc scratch – filenameforall template enumerates all files whose names match the specified string. For each matching file, filenameforall copies the file’s name into the supplied scratch scratch string, pushes a string object designating the substring of actually used, and calls proc . filenameforall does not return any results of its own, but proc may do so. The details of template matching are device dependent, but the following con- vention is typical. All characters in the template are treated literally and are case sensitive, except the following special characters: * matches zero or more consecutive characters. ? matches exactly one character. \ causes the next character of the template to be treated literally, even if it is * , ?, or \. If template does not begin with % , it is matched against device relative file names of all devices in the search order (see section 3.8.2, “Named Files”). When a is likewise device relative—in other match occurs, the file name passed to proc words, it does not have a % % prefix. device template %, it is matched against complete file names in the If does begin with % device form file . Template matching can be performed on the device , the file , or % both parts of the name. When a match occurs, the file name passed to proc is likewise in the complete form device % file . % The order of enumeration is unspecified and device dependent. There are no restrictions on what proc can do. However, if proc causes new files to be created, it is unspecified whether or not those files will be encountered later in the same enumeration. Likewise, the set of file names considered for template matching is device dependent. Errors: invalidaccess, ioerror, rangecheck, stackoverflow, stackunderflow, typecheck See also: file, status 8.2 Operator Details 415

424 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 fileposition fileposition position file returns the current position in an existing open file. The result is a non-negative integer interpreted as number of bytes from the beginning of the file. If the file ioerror occurs. object is not valid or the underlying file is not positionable, an Errors: ioerror, stackunderflow, typecheck See also: setfileposition, file fill – fill – paints the area enclosed by the current path with the current color. Any previous contents of that area on the current page are obscured, so areas may be erased by filling with color set to white. Before painting, fill implicitly closes any open subpaths of the current path. The inside of the current path is determined by the normal non-zero winding num- ber rule (see section 4.5, “Painting”). fill implicitly performs a newpath after it has finished filling the current path. To operation, use the sequence: preserve the current path across a fill gsave fill grestore limitcheck Errors: See Also: clip, eofill, stroke, ufill LEVEL 2 src | filter ... param name filter file tgt param 1 n creates and returns a filtered file . Filters are described in section 3.8.4, “Filters,” and section 3.13, “Filtered Files Details.” src The | tgt operand specifies the underlying data source or data target that the filter is to read or write. It can be a file, procedure, or string. The param operands are additional parameters that control how the ... param n 1 filter is to operate. The number and types of these operands depend on the filter name. Most filters require no additional parameters. 416 Chapter 8: Operators

425 PLRM 2nd Edition Operators January 26, 1994 The name operand identifies the data transformation that the filter is to perform. The standard filter names are: ASCIIHexEncode ASCIIHexDecode ASCII85Encode ASCII85Decode LZWEncode LZWDecode RunLengthDecode RunLengthEncode CCITTFaxDecode CCITTFaxEncode DCTEncode DCTDecode NullEncode SubFileDecode An encoding filter is an output (writable) file. A decoding filter is an input (read- able) file. The file object returned by the filter can be used as an operand of nor- . Reading from an mal file input and output operators, such as read and write input filtered file causes the filter to read from the underlying data source and transform the data. Similarly, writing to an output filtered file causes the filter to transform the data and write it to the underlying data target. Errors: limitcheck, undefined, typecheck, rangecheck, stackunderflow, invalidaccess See Also: file, closefile, resourceforall LEVEL 2 findencoding key findencoding array obtains an encoding vector identified by the specified key and pushes it onto the operand stack. Encoding vectors are described in section 5.3, “Character Encoding.” is a special case of findencoding category findresource applied to the Encoding (see section 3.9, “Named Resources”). If the encoding array specified by does key not exist or cannot be found, findencoding executes the undefinedresource error. Errors: stackunderflow, typecheck, undefinedresource See Also: findresource, StandardEncoding, ISOLatin1Encoding 8.2 Operator Details 417

426 PLRM 2nd Edition January 26, 1994 Operators key findfont findfont font and pushes it on the key obtains a font dictionary identified by the specified key may be a operand stack (see section 5.1, “Organization and Use of Fonts”). key previously passed to definefont , in which case the font dictionary associated key (in the font directory) is returned. with key is not registered as a font in VM, findfont takes an action that varies If according to the environment in which the PostScript interpreter is operating. In some environments, may attempt to read a font definition from an findfont findfont external source, such as a file. In other environments, substitutes a invalidfont . findfont is a special case of default font or executes the error findresource Font category. See section 3.9, “Named Resources.” applied to the findfont , like findresource , normally looks first for fonts defined in local VM, then for fonts defined in global VM. However, if the current VM allocation mode needs to findfont is global, findfont considers only fonts defined in global VM. If load a font into VM, it may use either local or global VM, depending on the font. Generally, Type 1 fonts are loaded into global VM; fonts of other types are loaded in to local VM. See section 3.9.2, “Resource Categories,” for an explana- tion of the VM behavior of font definitions. findfont is not an operator, but rather a built-in procedure. It may be redefined by a PostScript language program that requires different strategies for finding fonts. Errors: invalidfont, stackunderflow, typecheck See Also: scalefont, makefont, setfont, selectfont, definefont, findresource, FontDirectory, GlobalFontDirectory LEVEL 2 findresource key category findresource instance attempts to obtain a named resource instance in a specified category. category is a (see section 3.9.2, name object that identifies a resource category, such as Font “Resource Categories”). is a name or string object that identifies the resource key instance. (Names and strings are interchangeable; other types of keys are permit- ted but are not recommended.) If it succeeds, findresource pushes the resource instance on the operand stack; this is an object whose type depends on the resource category. findresource first attempts to obtain a resource instance that has previously been defined in VM by defineresource . If the current VM allocation mode is local, findresource considers local resource definitions first, then global definitions (see defineresource ). However, if the current VM allocation mode is global, findresource considers only global resource definitions. 418 Chapter 8: Operators

427 PLRM 2nd Edition January 26, 1994 Operators findresource If the requested resource instance is not currently defined in VM, attempts to obtain it from an external source. The way this is done is not speci- fied by the PostScript language; it varies among different implementations and different resource categories. The effect of this action is to create an object in VM and execute . findresource then returns the newly created object. defineresource is not a name or string, If will not attempt to obtain an external key findresource resource. When findresource loads an object into VM, it ordinarily attempts to use global VM, regardless of the current VM allocation mode. In other words, it sets the VM true setglobal allocation mode to global ( ) while loading the resource instance and executing . However, certain resource instances do not func- defineresource findresource tion correctly when loaded into global VM; uses local VM instead. This always occurs for type 3 font definitions and for any resource instance whose definition includes an explicit false setglobal . findresource During its execution, may remove the definitions of resource instances that were previously loaded into VM by findresource . The mechanisms and policies for this depend on the category and the implementation; reclama- tion of resources may occur at times other than during execution of findresource . However, resource definitions that were made by explicit execu- defineresource tion of are never disturbed by automatic reclamation. If the specified resource category does not exist, an undefined error occurs. If the key undefinedresource category exists but there is no instance whose name is , an error occurs. Errors: stackunderflow, typecheck, undefined, undefinedresource See Also: defineresource, resourcestatus, resourceforall, undefineresource – flattenpath – flattenpath replaces the current path with an equivalent path that preserves all straight line segments, but has all curveto segments replaced by sequences of lineto (straight line) segments that approximate the curves. If the current path does not contain any segments, flattenpath leaves it unchanged. curveto This “flattening” of curves to straight line segments is done automatically when a path is used to control painting (for example, by stroke , fill , or clip ). Only rarely does a program need to flatten a path explicitly (see pathbbox ). The accu- racy of the approximation to the curve is controlled by the current flatness parameter in the graphics state (see setflat ). Errors: limitcheck See Also: setflat, curveto, lineto, pathbbox 8.2 Operator Details 419

428 PLRM 2nd Edition January 26, 1994 Operators num num floor floor 1 2 num . The type of the returns the greatest integer value less than or equal to 1 result is the same as the type of the operand. Example ⇒ 3.0 3.2 floor –4.8 floor ⇒ –5.0 ⇒ 99 floor 99 Errors: stackunderflow, typecheck See Also: ceiling, round, truncate, cvi flush flush – – causes any buffered characters for the standard output file to be delivered imme- diately. In general, a program requiring output to be sent immediately, such as after generating that flush during real-time, two-way interactions, should call output. Errors: ioerror See Also: flushfile, print flushfile flushfile – file If is an output file, flushfile causes any buffered characters for that file to be file delivered immediately. In general, a program requiring output to be sent imme- diately, such as during real-time, two-way interactions, should call flushfile after generating that output. file file is an input file, flushfile reads and discards data from If until the end-of- file indication is encountered. This is useful during error recovery, and the Post- Script job server uses it for that purpose. flushfile does not close the file, unless it is a decoding filter file. Errors: ioerror, stackunderflow, typecheck See Also: flush, read, write 420 Chapter 8: Operators

429 PLRM 2nd Edition Operators January 26, 1994 – FontDirectory dict FontDirectory FontDirectory is not pushes a dictionary of defined fonts on the operand stack. an operator; it is a name in systemdict associated with the dictionary object. The FontDirectory dictionary associates font names with font dictionaries. looks there first. The dic- definefont FontDirectory , and findfont places entries in tionary is read-only; only definefont and undefinefont can change it. contains all fonts that are currently defined in VM, it FontDirectory Although does not necessarily describe all the fonts available to a PostScript language pro- findfont operator can sometimes obtain fonts from an gram. This is because the external source and load them into VM dynamically. Consequently, examining FontDirectory is not a reliable method of inquiring about available fonts. The preferred method is to use the resourcestatus and resourceforall operators, which are Level 2 features, to inquire about the Font resource category. See sec- tion 3.9, “Named Resources.” In Level 2, when global VM allocation mode is in effect (see section 3.7.2, “Local and Global VM”), the name FontDirectory is temporarily rebound to the value of GlobalFontDirectory , which contains only those fonts that have been defined in global VM. This ensures the correct behavior of fonts that are defined in terms of other fonts. stackoverflow Errors: See Also: definefont, undefinefont, findfont, findresource, GlobalFontDirectory 8.2 Operator Details 421

430 PLRM 2nd Edition Operators January 26, 1994 initial increment limit proc – for for executes proc repeatedly, passing it a sequence of values from initial by steps of to increment . The for operator expects initial , increment , and limit to be num- limit bers. It maintains a temporary internal variable, known as th e control variable , which it first sets to . Then, before each repetition, it compares the control initial variable with the termination value limit . If limit has not been exceeded, it pushes the control variable on the operand stack, executes proc , and adds increment to the control variable. The termination condition depends on whether increment is positive or negative. If increment is positive, for terminates when the control variable becomes greater terminates when the control variable for than limit . If increment is negative, becomes less than . If initial meets the termination condition, for does not limit execute proc at all. If proc executes the exit operator, for terminates prematurely. Usually, will use the value on the operand stack for some purpose. However, proc if proc does not remove the value, it will remain there. Successive executions of proc will cause successive values of the control variable to accumulate on the operand stack. Example 0 1 1 4 {add} for ⇒ 10 1 2 6 { } for ⇒ 1 3 5 ⇒ 3.0 2.5 2.0 1.5 1.0 3 –.5 1 { } for In the first example, the value of the control variable is added to whatever is on the stack, so 1, 2, 3, and 4 are added in turn to a running sum whose initial value is 0. The second example has an empty procedure, so the successive values of the control variable are left on the stack. The last example counts backward from 3 to 1 by halves, leaving the successive values on the stack. Beware of using reals instead of integers for any of the first three operands. Most real numbers are not represented exactly. This can cause an error to accumulate in the value of the control variable, with possibly surprising results. In particular, is a multiple of initial and limit if the difference between increment , as in the third line of the example, the control variable may not achieve the limit value. stackoverflow, stackunderflow, typecheck Errors: See Also: repeat, loop, forall, exit 422 Chapter 8: Operators

431 PLRM 2nd Edition Operators January 26, 1994 array proc – forall forall forall – packedarray proc forall – dict proc string proc forall – enumerates the elements of the first operand, executing the procedure proc for each element. If the first operand is an array, string, or packed array, forall pushes an element on the operand stack and executes proc for each element in the array, string, or packed array, beginning with the element whose index is 0 and continuing sequentially. The objects pushed on the operand stack are the array, packed array, or string elements. In the case of a string, these elements are integers in the range 0 to 255, not one-character strings. If the first operand is a dictionary, forall pushes a key and a value on the operand stack and executes proc for each key-value pair in the dictionary. The order in forall enumerates the entries in the dictionary is arbitrary. New entries which put in the dictionary during execution of proc may or may not be included in the enumeration. If the first operand is empty (i.e., has length 0), does not execute proc at all. forall If executes the exit operator, forall terminates prematurely. proc Although forall does not leave any results on the operand stack when it is fin- ished, the execution of may leave arbitrary results there. If proc does not proc remove each enumerated element from the operand stack, the elements will accumulate there. Example 0 [13 29 3 –8 21] {add} forall ⇒ 58 /d 2 dict def d /abc 123 put d /xyz (test) put d {} forall ⇒ /xyz (test) /abc 123 Errors: invalidaccess, stackoverflow, stackunderflow, typecheck See Also: for, repeat, loop, exit 8.2 Operator Details 423

432 PLRM 2nd Edition Operators January 26, 1994 DPS fork mark obj ... obj proc fork context n 1 creates a new execution context using the same local and global VM as the cur- rent context. The new context begins execution concurrent with continued exe- cution of the current context. Which context executes first is unpredictable. See section 7.1, “Multiple Execution Contexts.” The new context’s environment is formed by copying the dictionary and graph- obj ics state stacks of the current context. The initial operand stack consists of 1 through obj , pushed in the same order ( obj through obj are objects of any type 1 n n other than mark). consumes all operands down to and including the top- fork most mark. It then pushes an integer that uniquely identifies the new context. The forked context inherits its object format from the current context; other per- context parameters are initialized to default values. When the new context begins execution, it executes the procedure proc . If proc runs to completion and returns, the context ordinarily will suspend until some other context executes a join on . However, if the context has been context detached, it will terminate immediately (see ). join and detach If proc stop that causes the execution of proc to end prematurely, the executes a proc context will terminate immediately. is effectively called as follows: stopped {handleerror quit} if proc ...Wait for % or detach ... join quit In other words, if proc stops due to an error, the context invokes the error han- dler in the usual way to report the error. Then it terminates regardless of whether it has been detached. It is illegal to execute fork if there has been any previous save not yet matched by a restore . Attempting to do so will cause an invalidcontext error. Errors: invalidaccess, invalidcontext, limitcheck, stackunderflow, typecheck, unmatchedmark See Also: join, detach, currentcontext 424 Chapter 8: Operators

433 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 gcheck any bool gcheck true returns if the operand is simple or if it is composite and its value resides in false if the operand is composite and its value resides in global VM. It returns local VM. In other words, returns true if one could legally store its oper- gcheck and as an element of another object in global VM. See section 3.7.2, “Local and Global VM.” Errors: stackunderflow ge num bool num ge 2 1 string string ge bool 1 2 if the pops two objects from the operand stack and pushes the boolean value true first operand is greater than or equal to the second, false otherwise. If both oper- ge ands are numbers, compares their mathematical values. If both operands are strings, ge compares them element by element, treating the elements as integers in the range 0 to 255, to determine whether the first string is lexically greater than or equal to the second. If the operands are of other types or one is a string and the other is a number, ge executes the typecheck error. Example 4.2 4 ge true ⇒ (abc)(d) ge ⇒ false (aba)(ab) ge ⇒ true (aba)(aba) ge ⇒ true Errors: invalidaccess, stackunderflow, typecheck See Also: gt, eq, ne, le, lt 8.2 Operator Details 425

434 PLRM 2nd Edition Operators January 26, 1994 array index any get get packedarray index get any dict key any get string index get int gets a single element from the value of an array, packed array, dictionary, or string. If the first operand is an array, packed array, or string, get treats the second oper- and as an index and returns the element identified by the index, counting from index must be in the range 0 to n –1, where n is the length of the array, zero. packed array, or string. If it is outside this range, get will execute a rangecheck error. If the first operand is a dictionary, get looks up the second operand as a key in the dictionary and returns the associated value. If the key is not present in the undefined error. dictionary, get executes the Example ⇒ 31 [31 41 59] 0 get [0 (a mixed-type array) [ ] {add 2 div}] 2 get ⇒ [ ] % An empty array /mykey (myvalue) def currentdict /mykey get ⇒ (myvalue) (abc) 1 get ⇒ 98 % Character code for “b” (a) 0 get ⇒ 97 Errors: invalidaccess, rangecheck, stackunderflow, typecheck, undefined See Also: put, getinterval array index count getinterval subarray getinterval getinterval packedarray index count subarray string index count getinterval substring creates a new array, packed array, or string object whose value consists of some subsequence of the original array, packed array, or string. The subsequence con- in the original object. The sists of count elements starting at the specified index elements in the subsequence are shared between the original and new objects (see section 3.3.1, “Simple and Composite Objects”). 426 Chapter 8: Operators

435 PLRM 2nd Edition Operators January 26, 1994 The returned subarray or substring is an ordinary array, packed array, or string object whose length is and whose elements are indexed starting at 0. The count subarray is the same as the element at index element at index 0 in in the index original array . getinterval requires index to be a valid index in the original object and count to be a non-negative integer such that + count is not greater than the length of index the original object. Example [9 8 7 6 5] 1 3 getinterval ⇒ [8 7 6] (abcde) 1 3 getinterval ⇒ (bcd) () % An empty string (abcde) 0 0 getinterval ⇒ invalidaccess, rangecheck, stackunderflow, typecheck Errors: See Also: get, putinterval LEVEL 2 globaldict – globaldict dict on the operand stack (see section 3.7.5, pushes the dictionary object globaldict “Standard and User-Defined Dictionaries”). globaldict is not an operator; it is a name in systemdict associated with the dictionary object. Errors: stackoverflow See Also: systemdict, userdict LEVEL 2 GlobalFontDirectory GlobalFontDirectory dict – pushes a dictionary of defined fonts on the operand stack. Its contents are lim- ited to those fonts that have been defined in global VM. See FontDirectory for a complete explanation. GlobalFontDirectory is not an operator; it is a name in systemdict associated with the dictionary object. Errors: stackoverflow See Also: FontDirectory 8.2 Operator Details 427

436 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 glyphshow name – glyphshow name shows a single character, identified by , from the current font. Unlike all show variants, glyphshow bypasses the current font’s Encoding other . It can access any character in the font, whether or not that character’s name is present in the font’s encoding vector. The behavior of glyphshow depends on the current font’s FontType . For FontType 1, glyphshow looks up name in the font’s CharStrings dictionary to obtain a character description to execute. If is not present in the name CharStrings dictionary, glyphshow substitutes the .notdef entry, which must be present in every Type 1 font. For FontType 3, if the font dictionary contains a BuildGlyph procedure, on the operand stack, glyphshow pushes the current font dictionary and name then invokes BuildGlyph in the usual way (see section 5.7, “Type 3 Fonts”). If BuildGlyph BuildChar procedure, glyphshow there is no procedure, but only a Encoding array for an occurrence of searches the font’s . If it finds one, it name pushes the font dictionary and the array index on the operand stack, then invokes BuildChar in the usual way. If name is not present in the encoding, glyphshow substitutes the name .notdef and repeats the search. If .notdef isn’t present either, an error occurs. invalidfont Like show , glyphshow can access characters that are already in the font cache. glyphshow does not always need to execute the character’s description. glyphshow operates only with base fonts. If the current font is composite ( FontType 0), an invalidfont error occurs. Errors: invalidaccess, invalidfont, nocurrentpoint, stackunderflow, typecheck See Also: show 428 Chapter 8: Operators

437 PLRM 2nd Edition January 26, 1994 Operators – – grestore grestore resets the current graphics state from the one on the top of the graphics state stack and pops the graphics state stack, restoring the graphics state in effect at gsave . This operator provides a simple way to undo the time of the matching complicated transformations and other graphics state modifications without having to re-establish all graphics state parameters individually. If there is no matching gsave or if the most recent gsave preceded the most grestore save recent unmatched does not pop the graphics state stack, although , it does restore the graphics state from the top of the graphics state stack. (none) Errors: See Also: gsave, grestoreall, setgstate grestoreall – grestoreall – repeatedly pops the graphics state stack until it encounters either the bottom- most graphics state or one that was saved by save as opposed to gsave , leaving that state on top of the graphics state stack. It then resets the current graphics state from that saved one. Errors: (none) See Also: gsave, grestore, setgstate 8.2 Operator Details 429

438 PLRM 2nd Edition January 26, 1994 Operators – gsave gsave – pushes a copy of the current graphics state on the graphics state stack. All ele- ments of the graphics state are saved, including the CTM, current path, clip path, and identity of the raster output device, but not the contents of raster grestore . See sec- memory. The saved state may later be restored by a matching tion 4.2, “Graphics State.” save operator implicitly performs a gsave , but restoring a graphics state The save saved by gsave (see the is slightly different from restoring one saved by grestore and descriptions of ). grestoreall Note that, unlike save , gsave does not return a save object on the operand stack grestore to represent the saved state. work strictly in a stack-like fash- gsave and restore and grestoreall . ion, except for the wholesale restoration performed by Errors: limitcheck See Also: grestore, grestoreall, restore, save, gstate, currentgstate LEVEL 2 gstate – gstate gstate creates a new gstate (graphics state) object and pushes it on the operand stack. Its initial value is a copy of the current graphics state. This operator consumes VM; it is the only graphics state operator that does. The gstate is allocated in either local or global VM according to the current VM allo- cation mode (see section 3.7, “Memory Management”). error if gstate is allocated in global VM, gstate will generate an invalidaccess If any of the composite objects in the current graphics state are in local VM. Such objects might include the current font, screen function, halftone dictionary, transfer function, or dash pattern. In general, allocating gstate objects in global VM is risky and should be avoided. Errors: invalidaccess, stackoverflow, VMerror See Also: currentgstate, setgstate 430 Chapter 8: Operators

439 PLRM 2nd Edition January 26, 1994 Operators num num gt bool gt 2 1 bool string string gt 2 1 true if the pops two objects from the operand stack and pushes the boolean value false otherwise. If both operands are first operand is greater than the second, gt compares their mathematical values. If both operands are strings, gt numbers, compares them element by element, treating the elements as integers in the range 0 to 255, to determine whether the first string is lexically greater than the second. If the operands are of other types or one is a string and the other is a gt error. number, typecheck executes the Errors: invalidaccess, stackunderflow, typecheck See Also: ge, eq, ne, le, lt handleerror (error) is looked up in errordict and executed to report error information saved by the default error handlers (see section 3.10, “Errors”). There is also a procedure named handleerror in systemdict ; it merely calls the procedure in errordict . identmatrix matrix identmatrix matrix replaces the value of matrix with the value of the identity matrix [1.0 0.0 0.0 1.0 0.0 0.0] and pushes this modified matrix back on the operand stack. The identity matrix transforms any coordinate to itself. Errors: rangecheck, stackunderflow, typecheck See Also: matrix, currentmatrix, defaultmatrix, initmatrix 8.2 Operator Details 431

440 PLRM 2nd Edition Operators January 26, 1994 int quotient int idiv idiv 2 1 divides by int and returns the integer part of the quotient, with any frac- int 1 2 tional part discarded. Both operands of idiv must be integers and the result is an integer. Example 3 2 idiv ⇒ 1 4 2 idiv ⇒ 2 –5 2 idiv ⇒ –2 Errors: stackunderflow, typecheck, undefinedresult See Also: div, add, mul, sub, mod, cvi idtransform dx‘ dy‘ idtransform dx dy idtransform dx dy dx‘ dy‘ matrix With no operand, idtransform (inverse delta transform) transforms the matrix device space distance vector ( dx‘ , dy‘ ) by the inverse of CTM to produce the cor- responding distance vector ( dx , dy ) in user space. If the matrix operand is sup- transforms the distance vector by the inverse of plied, idtransform matrix rather than by the inverse of CTM. A delta transformation is similar to a normal transformation (see section 4.3, “Coordinate Systems and Transformations”), but the translation components ( t and t ) of the transformation matrix are not used, making the distance vec- y x tors be positionless in both user space and device space. idtransform is the inverse of dtransform . It is useful for determining how distances map from device space to user space. rangecheck, stackunderflow, typecheck, undefinedresult Errors: See Also: dtransform, transform, itransform 432 Chapter 8: Operators

441 PLRM 2nd Edition January 26, 1994 Operators if bool proc if – if removes both operands from the stack, then executes proc if bool is true . The may do proc operator pushes no results of its own on the operand stack, but the so (see section 3.5, “Execution”). Example 3 4 lt {(3 is less than 4)} if ⇒ (3 is less than 4) Errors: stackunderflow, typecheck See Also: ifelse ifelse ifelse bool proc – proc 1 2 proc if bool is true or removes all three operands from the stack, then executes 1 bool proc operator pushes no results of its own on the oper- if is ifelse false . The 2 and stack, but the procedure it executes may do so (see section 3.5, “Execution”). Example 4 3 lt {(TruePart)} {(FalsePart)} ifelse ⇒ (FalsePart) % Since 4 is not less than 3 stackunderflow, typecheck Errors: See Also: if 8.2 Operator Details 433

442 PLRM 2nd Edition Operators January 26, 1994 image width height bits/sample matrix datasrc image – dict image – paints a sampled image onto the current page. The description here only sum- marizes the image operator. See section 4.10, “Images.” The sampled image is a rectangular array of width × height sample values, each of bits of data (1, 2, 4, 8, or 12). The data is received as which consists of bits/sample a sequence of characters—in other words, 8-bit integers in the range 0 to 255. If is less than 8, sample values are packed left to right within a character bits/sample (see section 4.10.2, “Sample Data Representation”). In the first form of image , the parameters are specified as separate operands. This renders a mono- is the only form Level 1 implementations support. image chrome image according to the DeviceGray color space, regardless of the current color space. In the second form, the parameters are contained as key-value pairs in an image dictionary, which is specified as the single operand of image . This form is a Level renders either a monochrome or color image according to the 2 feature. image current color space parameter in the graphics state. The number of component values per source sample and the interpretations of those values depend on the current color space. The image is considered to exist in its own coordinate system. The rectangular boundary of the image has its lower-left corner at (0, 0) and its upper-right cor- ner at ( width , height ). The matrix operand specifies a transformation from user space to the image coordinate system. In Level 1, datasrc must be a procedure. In Level 2, datasrc may be any data source (see section 3.13, “Filtered Files Details”)—a procedure, string, or readable file object (including a filtered file). image If datasrc is a procedure, executes repeatedly to obtain the actual datasrc must return (on the operand stack) a string containing any datasrc image data. number of additional characters of sample data. If datasrc returns a string of will terminate execution prematurely. The sample values are length zero, image assumed to be received in a fixed order: (0, 0) through ( width– 1, 0), then (0, 1) through ( width– 1, 1), and so on. Execution of this operator is not permitted in certain circumstances; see section 4.8, “Color Spaces.” limitcheck, invalidaccess, ioerror, rangecheck, stackunderflow, Errors: typecheck, undefinedresult, undefined See Also: imagemask, colorimage 434 Chapter 8: Operators

443 PLRM 2nd Edition January 26, 1994 Operators width height polarity matrix datasrc imagemask imagemask – – imagemask dict image operator. However, it treats the source image as a mask of is similar to the 1-bit samples that are used to control where to apply paint with the current color and where not to apply any paint. See the description of the image opera- tor and section 4.10, “Images.” In the first form of imagemask , the parameters are specified as separate oper- ands. This is the only form Level 1 implementations support. In the second form, the parameters are contained as key-value pairs in an image dictionary. imagemask do not The second form is a Level 2 feature. The semantics of depend on which way the operands are specified. imagemask width , height , matrix , and datasrc operands in precisely the uses the same way image polarity operand is a boolean that determines uses them. The the polarity of the mask. It controls the sense of the mask only; it has no effect on the color of the pixels that are painted. If is false , portions of the polarity image corresponding to source sample values of 0 are painted, while those corre- , sample val- true sponding to sample values of 1 are left unchanged. If polarity is ues of 1 are painted and sample values of 0 are left unchanged. imagemask , the polarity is specified by means of the In the second form of Decode entry in the image dictionary. Decode values of [0 1] and [1 0] corre- spond to polarity values of false and true , respectively. In Level 1, datasrc must be a procedure. In Level 2, datasrc may be any data source (see section 3.13, “Filtered Files Details”)—a procedure, string, or readable file object (including a filtered file). imagemask is most useful for painting characters represented as bitmaps. Such bitmaps represent masks through which a color is to be transferred; the bitmaps themselves do not have a color (see section 4.10.6, “Masks”). Example % Locate lower-left corner of square 54 112 translate 120 120 scale % Scale 1 unit to 120 points 0 0 moveto 0 1 lineto % Fill square with gray background 1 1 lineto 1 0 lineto closepath .9 setgray fill 0 setgray % Paint mask black 24 23 % Dimensions of source mask true % Paint the 1 bits [24 0 0 –23 0 23] % Map unit square to mask {<003B00 002700 002480 0E4940 114920 14B220 3CB650 75FE88 17FF8C 175F14 1C07E2 3803C4 703182 F8EDFC B2BBC2 BB6F84 31BFC2 18EA3C 0E3E00 07FC00 % Mask data 03F800 1E1800 1FF800>} imagemask 8.2 Operator Details 435

444 PLRM 2nd Edition January 26, 1994 Operators Errors: stackunderflow, typecheck, undefinedresult, limitcheck, invalidaccess, ioerror See Also: image, colorimage any index any ... any ... any any n index n 0 n 0 n removes the non-negative integer n from the operand stack, counts down to the n th element from the top of the stack, and pushes a copy of that element on the stack. Example (a)(b)(c)(d) 0 index ⇒ (a)(b)(c)(d)(d) (a)(b)(c)(d) 3 index ⇒ (a)(b)(c)(d)(a) Errors: rangecheck, stackunderflow, typecheck See Also: copy, dup, roll LEVEL 2 bool ineofill x y ineofill userpath bool ineofill is similar to infill , but its “insideness” test is based on eofill instead of fill . Errors: invalidaccess, limitcheck, rangecheck, stackunderflow, typecheck See Also: eofill, infill 436 Chapter 8: Operators

445 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 x y infill bool infill infill bool userpath if the device pixel containing the point ( x , The first form returns ) in user true y space would be painted by a fill of the current path in the graphics state. Other- false wise, it returns . In the second form, the device pixels that would be painted by filling userpath true if any of the pixels become an “aperture.” This form of the operator returns in the aperture would be painted by a of the current path in the graphics fill state. Otherwise, it returns false . Both forms of this operator ignore the current clipping path and current view clip; that is, they detect a “hit” anywhere within the current path, even if filling that path would not mark the current page due to clipping. They do not place any marks on the current page nor do they disturb the current path. The follow- ing program fragment takes the current clipping path into account: gsave clippath infill grestore xy infill and xy invalidaccess, limitcheck, rangecheck, stackunderflow, typecheck Errors: See Also: fill, ineofill – initclip – initclip replaces the current clip path parameter in the graphics state by the default clip path for the current output device. This path usually corresponds to the bound- ary of the maximum imageable area for the current output device. For a page- oriented output device, its dimensions are those established by the setpagedevice operator. For a display device, the clipping region established by initclip is not well defined. Display PostScript applications should not make the assumption that the clipping region corresponds to the window boundary (see viewclippath ). There are few situations in which a PostScript language program should execute initclip explicitly. A page description that executes initclip usually produces incorrect results if it is embedded within another, composite page. Errors: (none) See Also: clip, eoclip, clippath, initgraphics 8.2 Operator Details 437

446 PLRM 2nd Edition Operators January 26, 1994 – initgraphics – initgraphics resets several values in the current graphics state to their default values: current transformation matrix (default for current device) current path (empty) current point (undefined) current clipping path (default for current device) current color space ( ) DeviceGray current color (black) current line width (one user space unit) current line cap style (butt end caps) current line join style (miter joins) current dash description (undashed, i.e., solid lines) current miter limit (10) The initgraphics operator does not change the other graphics state parameters. device- These include the current output device, font, stroke adjust, and all dependent parameters. This operator affects only the graphics state, not the con- tents of raster memory or the output device. is equivalent to the PostScript language sequence: initgraphics initmatrix newpath initclip 1 setlinewidth 0 setlinecap 0 setlinejoin [ ] 0 setdash 0 setgray 10 setmiterlimit There are few situations in which a PostScript language program should execute initgraphics explicitly. A page description that executes initgraphics usually pro- duces incorrect results if it is embedded within another, composite page. A pro- gram requiring information about its initial graphics state should read and save that state at the beginning of the program rather than assume that the default state prevailed initially. (none) Errors: See Also: grestoreall initmatrix – initmatrix – sets the current transformation matrix (CTM) to the default matrix for the cur- rent output device. This matrix transforms the default user coordinate system to device space (see section 4.3, “Coordinate Systems and Transformations”). For a page-oriented device, the default matrix is initially established by the operator. setpagedevice 438 Chapter 8: Operators

447 PLRM 2nd Edition Operators January 26, 1994 There are few situations in which a PostScript language program should execute initmatrix explicitly. A page description that executes initmatrix usually produces incorrect results if it is embedded within another, composite page. (none) Errors: See Also: defaultmatrix, currentmatrix, setmatrix DPS initviewclip – initviewclip – returns the context to its initial view clipping state, in which no view clipping path exists. Errors: (none) See Also: viewclip, viewclippath LEVEL 2 instroke x y bool instroke instroke userpath bool true if the device pixel containing the point ( x The first form returns y ) in user , space would be painted by a stroke of the current path in the graphics state. Otherwise, it returns false . It does not place any marks on the current page nor does it disturb the current path. In the second form of the operator, the device pixels that would be painted by filling userpath become an “aperture.” instroke returns true if any of the pixels in the aperture would be painted by a of the current path in the graphics stroke state. Otherwise, it returns false . As with infill , this operator ignores the current clipping path and current view clip; that is, it detects a “hit” on any pixel that lies beneath a stroke drawn along the current path, even if stroking that path would not mark the current page due to clipping. The shape against which the point ( x , y ) or the aperture, userpath , is tested is computed according to the current, stroke-related parameters in the graphics state: line width, line cap, line join, miter limit, dash pattern, and stroke adjust. If the current line width is zero, the set of pixels considered to be part of the stroke is device dependent. Errors: invalidaccess, limitcheck, rangecheck, stackunderflow, typecheck See Also: infill, inustroke, stroke 439 8.2 Operator Details

448 PLRM 2nd Edition Operators January 26, 1994 int dict internaldict internaldict int operand pushes the internal dictionary object on the operand stack. The must be the integer 1183615869. The internal dictionary is in local VM and is writ- able. It contains operators and other information whose purpose is internal to the PostScript interpreter. It should be referenced only in special circumstances, such as during construction of Type 1 font programs. (See the book Adobe Type 1 Font Format for specific information about constructing Type 1 fonts.) The con- tents of are undocumented and subject to change at any time. internaldict This operator is not present in some PostScript interpreters. Errors: invalidaccess, stackunderflow, undefined interrupt (error) processes an external request to interrupt execution of a PostScript language pro- gram. When the interpreter receives an interrupt request, it executes interrupt as if it were an error—in other words, it looks up the name interrupt in errordict . is sandwiched between execution of two objects being interrupt Execution of interpreted in normal sequence. interrupt does not cause the object Unlike most other errors, occurrence of an being executed to be pushed on the operand stack nor does it disturb the oper- and stack in any way. The precise nature of an external interrupt request depends on the environment in which the PostScript interpreter is running. For example, in some environ- ments, receipt of a control-C character from a serial communication channel gives rise to the interrupt error. This enables a user to explicitly abort a PostScript . computation. The default definition of interrupt executes a stop LEVEL 2 x y userpath inueofill bool inueofill userpath userpath inueofill bool 2 1 is similar to inufill , but its “insideness” test is based on ueofill instead of ufill . Errors: invalidaccess, limitcheck, rangecheck, stackunderflow, typecheck See Also: inufill, eofill 440 Chapter 8: Operators

449 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 inufill inufill bool x y userpath userpath userpath inufill bool 1 2 The first form returns true if the device pixel containing the point ( x , y ) in user space would be painted by a of the specified userpath (see section 4.6, “User ufill Paths”). Otherwise, it returns false . In the second form, the device pixels that would be painted by filling userpath 1 true become an “aperture.” if any of the pixels in the aperture returns inufill would be painted by a ufill userpath of . Otherwise, it returns false . 2 This operator does not place any marks on the current page nor does it disturb the current path in the graphics state. Except for the manner in which the path is specified, inufill behaves the same as infill . By itself, this operator is seemingly a trivial composition of several other operators: gsave newpath uappend infill grestore However, when used with a user path that specifies ucache , inufill can access the user path cache, potentially resulting in improved performance. Errors: invalidaccess, limitcheck, rangecheck, stackunderflow, typecheck See also: inueofill, infill, ufill 8.2 Operator Details 441

450 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 inustroke x y userpath bool inustroke inustroke bool x y userpath matrix inustroke userpath bool userpath 2 1 userpath matrix inustroke bool userpath 1 2 The first form returns true if the device pixel containing the point ( x , y ) in user space would be painted by a applied to the same operands (see section ustroke 4.6, “User Paths”). Otherwise it returns false . In the second form, inustroke concatenates matrix to the CTM after interpreting the user paths, but before computing the stroke (see ustroke operator). In the third and fourth forms, the device pixels that would be painted by filling become an “aperture.” if any of the pixels in the true userpath inustroke returns 1 . false . Otherwise it returns userpath of ustroke aperture would be painted by a 2 This operator does not place any marks on the current page nor does it disturb the current path in the graphics state. Except for the manner in which the path is specified, inustroke behaves the same as instroke . is already present in the user path cache, As with inufill , if userpath can inustroke take advantage of the cached information to optimize execution. invalidaccess, limitcheck, rangecheck, stackunderflow, typecheck Errors: See also: stroke, ustroke, instroke invalidaccess (error) An access violation has occurred. Principal causes of invalidaccess are: • Accessing the value of a composite object in violation of its access attribute (for example, storing into a read-only array). • Storing a composite object in local VM as an element of a composite object in global VM. • Executing pathforall if the current path contains an outline for a protected font. See Also: rcheck, wcheck, gcheck, readonly, executeonly, noaccess 442 Chapter 8: Operators

451 PLRM 2nd Edition Operators January 26, 1994 DPS invalidcontext (error) indicates that an invalid use of the context synchronization facilities has been detected. Possible causes include: • Presenting an invalid context identifier to join or . detach • Executing monitor on a lock already held by the current context. • Executing wait on a lock not held by the current context. • Executing any of several synchronization operators when an unmatched save is pending if the result would be a deadlock. The PostScript interpreter detects only the simplest types of deadlock. It is possi- ble to encounter deadlocks for which no invalidcontext error is generated. invalidexit (error) An exit has been executed for which there is no dynamically enclosing looping , context (for example, for ) or it has attempted to leave loop , repeat , or pathforall the context of a run stopped operator. or (error) invalidfileaccess file operator is unacceptable or a file opera- The access string specification to the tion has been attempted (for example, deletefile ) that is not permitted by the storage device. See section 3.8.2, “Named Files.” invalidfont (error) Either the operand to findfont is not a valid font name or the operand to makefont or setfont is not a well-formed font dictionary. The invalidfont error may also be executed by other font operators upon discovering a font dictionary is malformed. 8.2 Operator Details 443

452 PLRM 2nd Edition Operators January 26, 1994 DPS invalidid (error) indicates that an invalid identifier has been presented to a window system spe- cific operator. In each integration of the Display PostScript system with a win- dow system, there is a collection of window system specific operators. The operands of such operators are usually integers that identify windows and other objects that exist outside the PostScript language. This error occurs when the operand does not identify a valid object. It is generated only by window system specific operators and not by any standard operator. (error) invalidrestore restore has been attempted. One or more of the operand, diction- An improper ary, or execution stacks contains composite objects whose values were created more recently than the save whose context is being restored. Since restore would destroy those values, but the stacks are unaffected by restore , the out- come would be undefined and cannot be allowed. See Also: restore, save invertmatrix matrix matrix invertmatrix matrix 1 2 2 replaces the value of matrix with the result of inverting matrix and pushes the 2 1 back on the operand stack. The result of inverting a matrix is modified matrix 2 transforms matrix matrix transforms a coordinate ( x , y that if x‘ , y‘ ) then ) to ( 1 2 x ( x‘ , y‘ ) to ( ). See section 4.3, “Coordinate Systems and Transformations.” , y Errors: rangecheck, stackunderflow, typecheck, undefinedresult See Also: itransform, idtransform ioerror (error) An exception other than end-of-file has occurred during execution of one of the file operators. The nature of the exception is environment dependent, but may include such events as parity or checksum errors, or broken network connec- tions. Attempting to write to an input file or to a file that has been closed will also cause an ioerror . Occurrence of an ioerror does not cause the file to become closed unless it was already closed or the error occurs during closefile . 444 Chapter 8: Operators

453 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 ISOLatin1Encoding – array ISOLatin1Encoding pushes the ISO Latin-1 encoding vector on the operand stack. This is a 256-element literal array object, indexed by character codes whose values are the ISOLatin1Encoding is not an operator; it is a character names for those codes. name in associated with the array object. systemdict Roman text fonts produced by Adobe usually use the StandardEncoding encoding vector. However, they contain all the characters needed to support the use of ISOLatin1Encoding . A font can have its Encoding changed to ISOLatin1Encoding by means of the procedure shown in section 5.6.1, “Chang- ing the Encoding Vector.” The contents of ISOLatin1Encoding are documented in Appendix E. Errors: stackoverflow See Also: StandardEncoding, findencoding x y itransform x‘ y‘ itransform x‘ y‘ matrix itransform x y matrix operand, itransform With no (inverse transform) transforms the device space coordinate ( x’ , y’ ) by the inverse of CTM to produce the corresponding user space coordinate ( x , y ). If the matrix operand is supplied, itransform transforms ( x’ , y’ ) by the inverse of matrix rather than by the inverse of CTM. Errors: rangecheck, stackunderflow, typecheck, undefinedresult See Also: transform, dtransform, idtransform, invertmatrix 8.2 Operator Details 445

454 PLRM 2nd Edition Operators January 26, 1994 DPS join context mark obj join ... obj n 1 context to finish execut- waits for the execution context identified by the integer proc ing its top-level procedure (the fork ). It then pushes a mark fol- operand of lowed by the entire contents of that context’s operand stack onto the current context’s operand stack. Finally, it causes the other context to terminate. The objects obj are those left on the operand stack by the context through obj n 1 that is terminating. Ordinarily, there should not be a mark among those objects, because its presence might cause confusion in the context that executes the join . If context is not a valid context identifier, perhaps because the context has termi- nated prematurely due to executing quit or encountering an error, join executes an invalidcontext error. This also occurs if the context has already been joined or identifies the current context, or if the context does not detached, if context share the current context’s local and global VM. It is illegal to execute if there has been any previous save not yet matched by join restore error. invalidcontext a . Attempting to do so will cause an invalidcontext, stackunderflow, stackoverflow, typecheck Errors: See Also: fork, detach, currentcontext known dict key known bool returns the boolean value true if there is an entry in the dictionary dict whose key is . Otherwise, it returns false . dict does not have to be on the dictionary stack. key Example /mydict 5 dict def mydict /total 0 put mydict /total known ⇒ true mydict /badname known ⇒ false Errors: invalidaccess, stackunderflow, typecheck See Also: where, load, get 446 Chapter 8: Operators

455 PLRM 2nd Edition Operators January 26, 1994 proc string – kshow kshow paints the characters of string in a manner similar to show , but allowing program string are c , intervention between characters. If the character codes in c c , ... , 1 n 0 kshow proceeds as follows: First it shows c at the current point, updating the 0 current point by c on the ’s width. Then it pushes the character codes c c and 0 0 1 operand stack (as integers) and executes proc . The proc may perform any actions it wishes; typically, it will modify the current point to affect the subsequent placement of c c on the stack, kshow continues by showing c and , pushing c . 1 1 1 2 c on the stack, execut- executing proc , and so on. It finishes by pushing c and n–1 n proc , and finally showing c . ing n proc is called for the first time, the graphics state (in particular, the CTM) When kshow was invoked, except that the current is the same as it was at the time . Execution of proc is permitted to have point has been updated by the width of c 0 any side effects, including changes to the graphics state. Such changes persist proc to the next and may affect graphical output for the remain- from one call of der of kshow ’s execution and afterward. The name kshow is derived from “kern-show.” To kern characters is to adjust the spacing between adjacent pairs of characters in order to achieve a visually pleas- operator enables user-defined kerning and other manipu- ing result. The kshow lations, because arbitrary computations can be performed between each pair of characters. kshow can be applied only to base fonts. If the current font is composite, kshow issues an invalidfont error. Errors: invalidaccess, invalidfont, nocurrentpoint, stackunderflow, typecheck See Also: show, ashow, awidthshow, widthshow, xshow, xyshow, yshow, cshow LEVEL 2 languagelevel – languagelevel int is an integer designating the PostScript language level supported by the Post- Script interpreter. If the value of is 2, the PostScript interpreter languagelevel supports all PostScript Level 2 language features. If the value of languagelevel is 1 or if languagelevel is not defined in systemdict , the PostScript interpreter does not support all PostScript Level 2 language features. Errors: stackoverflow, undefined See Also: product, revision, serialnumber, version 8.2 Operator Details 447

456 PLRM 2nd Edition January 26, 1994 Operators num le bool le num 1 2 string le bool string 1 2 if the pops two objects from the operand stack and pushes the boolean value true otherwise. If both operands false first operand is less than or equal to the second, are numbers, le compares their mathematical values. If both operands are strings, compares them element by element (treating the elements as integers le in the range 0 to 255) to determine whether the first string is lexically less than or equal to the second. If the operands are of other types or one is a string and the other is a number, executes the typecheck error. le Errors: invalidaccess, stackunderflow, typecheck See Also: lt, eq, ne, ge, gt length length int array packedarray length int dict length int int length string name int length depends on the type of its operand. If the operand is an array, packed array, or string, length returns the number of elements in its value. If the operand is a dic- tionary, length returns the current number of key-value pairs it contains, as opposed to its maximum capacity, which is returned by maxlength . If the oper- and is a name object, the length is the number of characters in the text string that defines it. Example [1 2 4] length ⇒ 3 [ ] length ⇒ 0 % An array of zero length /ar 20 array def ar length 20 ⇒ /mydict 5 dict def ⇒ 0 mydict length mydict /firstkey (firstvalue) put mydict length ⇒ 1 (abc\n) length ⇒ 4 % The “\n” is one character () length ⇒ 0 % No characters between ( and ) /foo length ⇒ 3 invalidaccess, stackunderflow, typecheck Errors: See Also: maxlength 448 Chapter 8: Operators

457 PLRM 2nd Edition January 26, 1994 Operators (error) limitcheck An implementation limit has been exceeded (for example, too many files have been opened simultaneously or a path has become too complex). Appendix B gives typical values for all such limits. lineto x y lineto – appends a straight line segment to the current path (see section 4.4, “Path Con- struction”). The line extends from the current point to the point ( , y ) in user x space; ( x , y ) then becomes the current point. If the current point is undefined lineto . because the current path is empty, nocurrentpoint executes the error limitcheck, nocurrentpoint, stackunderflow, typecheck Errors: See Also: rlineto, moveto, arc, curveto, closepath ln num ln real ) of returns the natural logarithm (base e num . The result is a real. Example 10 ln ⇒ 2.30259 100 ln ⇒ 4.60517 rangecheck, stackunderflow, typecheck Errors: See Also: log, exp 8.2 Operator Details 449

458 PLRM 2nd Edition Operators January 26, 1994 key value load load key in each dictionary on the dictionary stack, starting with the top- searches for key is found in some dictionary, load pushes the most (current) dictionary. If associated value on the operand stack. If key is not found in any dictionary on the dictionary stack, executes the error undefined . load load looks up key the same way the interpreter looks up executable names that it encounters during execution. However, load always pushes the associated value on the operand stack; it never executes that value. Example /avg {add 2 div} def {add 2 div} ⇒ /avg load invalidaccess, stackunderflow, typecheck, undefined Errors: See Also: where, get, store DPS lock – lock lock creates a new lock object, unequal to any lock object already in existence, and pushes it on the operand stack. The state of the lock is initially free (see section 7.1, “Multiple Execution Contexts”). Since a lock is a composite object, creating one consumes VM. The lock’s value is allocated in local or global VM according to the current VM allocation mode (see section 3.7.2, “Local and Global VM”). Errors: stackoverflow, VMerror See Also: monitor, wait log real num log returns the common logarithm (base 10) of . The result is a real. num Example 10 log ⇒ 1.0 100 log ⇒ 2.0 Errors: rangecheck, stackunderflow, typecheck See Also: ln, exp 450 Chapter 8: Operators

459 PLRM 2nd Edition Operators January 26, 1994 proc – loop loop proc repeatedly executes proc executes the exit operator, at which point until loop interpretation resumes at the object next in sequence after the . Control also leaves exit if the stop operator is executed. If proc never executes proc or stop , an infinite loop results, which can be broken only via an external interrupt (see interrupt ). stackunderflow, typecheck Errors: See Also: for, repeat, forall, exit bool lt num num lt 1 2 string string lt bool 1 2 pops two objects from the operand stack and pushes the boolean value true if the first operand is less than the second, otherwise. If both operands are num- false bers, compares their mathematical values. If both operands are strings, lt com- lt pares them element by element (treating the elements as integers in the range 0 to 255) to determine whether the first string is lexically less than the second. If the operands are of other types or one is a string and the other is a number, lt executes the typecheck error. invalidaccess, stackunderflow, typecheck Errors: See Also: le, eq, ne, ge, gt 8.2 Operator Details 451

460 PLRM 2nd Edition January 26, 1994 Operators font matrix makefont ′ makefont font to , producing a new font ′ whose characters are transformed by matrix font applies matrix first creates a copy of font . Then it when they are shown. makefont FontMatrix entry with the result of concatenating the replaces the new font’s FontMatrix with matrix . It inserts two additional entries, OrigFont and existing , whose purpose is internal to the implementation. Finally, it returns ScaleMatrix font ′ the result as . , makefont , and selectfont operators produce a font dictionary The scalefont FontMatrix derived from an original font dictionary, but with the entry altered. The derived font dictionary is allocated in local or global VM according to whether the original font dictionary is in local or global VM. This is indepen- dent of the current VM allocation mode. Normally, makefont copies only the font dictionary. Subsidiary objects, such as CharStrings and FontInfo dictionaries, are shared with the original font. the font also copies the font dictionaries of However, if makefont is a composite font, any descendant composite fonts. It does not copy descendant base fonts. Showing characters from the transformed font produces the same results as showing from the original font after having transformed user space by the same matrix. makefont is essentially a convenience operator that permits the desired transformation to be encapsulated in the font description. The most common x and transformation is to scale a font by a uniform factor in both . scalefont is y a special case of the more general and should be used for such uniform makefont scaling. Another operator, , combines the effects of findfont and selectfont . makefont The interpreter keeps track of font dictionaries recently created by makefont . Calling makefont multiple times with the same font and matrix will usually return the same font rather than create a new one. However, it is usually more ′ makefont efficient for a PostScript language program to apply only once for each font that it needs and to keep track of the resulting font dictionaries on its own. See Chapter 5 for general information about fonts and section 4.3, “Coordinate Systems and Transformations,” for a discussion of transformations. Example /Helvetica findfont [10 0 0 12 0 0] makefont setfont This obtains the standard Helvetica font, which is defined with a one unit line height, and scales it by a factor of 10 in the x dimension and 12 in the y dimen- sion. This produces a 12-unit high font (i.e., a 12-point font in default user space) whose characters are “condensed” in the x dimension by a ratio of 10/12. Errors: invalidfont, rangecheck, stackunderflow, typecheck, VMerror See Also: scalefont, setfont, findfont, selectfont 452 Chapter 8: Operators

461 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 makepattern makepattern pattern dict matrix verifies that dict is a prototype pattern dictionary with all required key-value pairs (see section 4.9, “Patterns”). It then creates a copy of dict in local VM, add- ing an entry, with key Implementation , for use by the implementation. makepattern dict itself, not the values of subsidiary copies only the contents of composite objects, which are shared with the original dictionary. makepattern saves a copy of the current graphics state, to be used later when the interpreter calls the PaintProc to render the pattern cell. It then modifies certain graphics state, as follows: parameters in the saved • Concatenates matrix with the saved copy of the CTM. • Adjusts the resulting matrix to ensure that the device space can be tiled prop- erly with a pattern cell of the given size in accordance with the TilingType . • Resets the path to empty. • Replaces the clipping path by the pattern cell bounding box specified by the BBox entry in the pattern dictionary. • Replaces the device by a special one the implementation provides. Finally, makepattern makes the new dictionary read-only and pushes it on the operand stack. The resulting pattern dictionary is suitable for use as an operand of setpattern or as a “color value” in the Pattern color space. Errors: limitcheck, rangecheck, stackunderflow, typecheck, undefined, VMerror See Also: setpattern, findresource 8.2 Operator Details 453

462 PLRM 2nd Edition Operators January 26, 1994 – mark mark mark mark (an object whose type is mark, not the mark pushes a operator itself) on the operand stack. All marks are identical, and the operand stack may contain any number of them at once. The primary use of marks is to indicate the stack position of the beginning of an indefinitely long list of operands being passed to an operator or procedure. The ] operator (array construction) is the most common operator that works this way. It treats as operands all elements of the stack down to a mark that was pushed by [ operator ( [ is a synonym for mark ). It is possible to define procedures that the work similarly. Operators such as counttomark and cleartomark are useful within such procedures. Errors: stackoverflow See Also: counttomark, cleartomark, pop matrix matrix matrix – creates a 6-element array object, fills it in with the values of an identity matrix [1.0 0.0 0.0 1.0 0.0 0.0] and pushes this array on the operand stack. The array is allocated in local or global VM according to the current VM allocation mode (see section 3.7.2, “Local and Global VM”). Example matrix ⇒ [1.0 0.0 0.0 1.0 0.0 0.0] ⇒ [1.0 0.0 0.0 1.0 0.0 0.0] 6 array identmatrix The two lines in the example yield identical results. Errors: stackoverflow, VMerror See Also: currentmatrix, defaultmatrix, initmatrix, setmatrix, array maxlength dict maxlength int returns the capacity of dict —in other words, the maximum number of key-value pairs that can hold using the VM currently allocated to it. In Level 1 imple- dict mentations, maxlength returns the length operand of the dict operator that cre- ated the dictionary; this is the dictionary’s maximum capacity (exceeding it causes a dictfull error). In a Level 2 implementation, which permits a dictionary to grow beyond its initial capacity, maxlength returns its current capacity, a length . number at least as large as that returned by 454 Chapter 8: Operators

463 PLRM 2nd Edition Operators January 26, 1994 Example /mydict 5 dict def mydict length ⇒ 0 ⇒ 5 mydict maxlength Errors: invalidaccess, stackunderflow, typecheck See Also: length, dict int int mod remainder mod 1 2 . The sign of the by int int returns the remainder that results from dividing 2 1 result is the same as the sign of the dividend int . Both operands must be inte- 1 gers. The result is an integer. Example 5 3 mod ⇒ 2 5 2 mod ⇒ 1 –5 3 mod ⇒ –2 operation remainder The last line of the example demonstrates that mod is a rather than a true operation. modulo Errors: stackunderflow, typecheck, undefinedresult See Also: idiv, div DPS monitor lock proc monitor – acquires lock , first waiting if necessary for it to become free, then executes proc , and finally releases lock again. The release of lock occurs whether proc runs to completion or terminates prematurely for any reason. See section 7.1, “Multiple Execution Contexts.” lock is already held by the current context, monitor executes an invalidcontext If error without disturbing the lock. If the current context has previously executed a save not yet matched by a restore and lock is already held by another context sharing the same local VM as the current context, an invalidcontext error results. These restrictions prevent the most straightforward cases of a context deadlock- ing with itself. Errors: invalidcontext, stackunderflow, typecheck See Also: lock, fork, wait 8.2 Operator Details 455

464 PLRM 2nd Edition Operators January 26, 1994 moveto x y moveto – starts a new subpath of the current path. moveto sets the current point in the graphics state to the user space coordinate ( x , y ) without adding any line seg- ments to the current path. , If the previous path operation in the current path was also a moveto or rmoveto point replaces moveto that point is deleted from the current path and the new it. Errors: limitcheck, stackunderflow, typecheck See Also: rmoveto, lineto, curveto, arc, closepath mul num mul num product 2 1 . If both operands are integers and the returns the product of num num and 1 2 result is within integer range, the result is an integer. Otherwise, the result is a real. Errors: stackunderflow, typecheck, undefinedresult See Also: div, idiv, add, sub, mod ne any any ne bool 1 2 pops two objects from the operand stack and pushes the boolean value false if they are equal, true if not. What it means for objects to be equal is presented in the description of the eq operator. Errors: invalidaccess, stackunderflow See Also: eq, ge, gt, le, lt neg neg num num 1 2 returns the negative of num . The type of the result is the same as the type of 1 num is the most negative integer, in which case the result is a real. , unless num 1 1 Example 4.5 neg ⇒ –4.5 3 ⇒ –3 neg 456 Chapter 8: Operators

465 PLRM 2nd Edition Operators January 26, 1994 stackunderflow, typecheck Errors: See Also: abs – newpath – newpath initializes the current path to be empty, causing the current point to become undefined. Errors: (none) See Also: closepath, stroke, fill array noaccess array noaccess noaccess packedarray packedarray dict dict noaccess file noaccess file tring string noaccess s reduces the access attribute of an array, packed array, dictionary, file, or string object to none (see section 3.3.2, “Attributes of Objects”). The value of a no- access object cannot be executed or accessed directly by PostScript operators. No- access objects are of no use to PostScript language programs, but serve certain internal purposes that are not documented in this manual. For an array, packed array, file, or string, noaccess affects the access attribute only of the object that it returns. If there are other objects that share the same value, their access attributes are unaffected. However, in the case of a dictionary, affects the value of the object, so all dictionary objects sharing the same noaccess dictionary are affected. Errors: invalidaccess, stackunderflow, typecheck See Also: rcheck, wcheck, xcheck, readonly, executeonly (error) nocurrentpoint The current path is empty, and thus there is no current point, but an operator requiring a current point has been executed (for example, lineto , curveto , currentpoint , show ). The most common cause of this error is neglecting to per- moveto form an initial . See Also: moveto 8.2 Operator Details 457

466 PLRM 2nd Edition Operators January 26, 1994 not bool bool not 1 2 int not int 1 2 returns its logical negation. If the operand is an If the operand is a boolean, not returns the bitwise complement (one’s complement) of its binary not integer, representation. Example false ⇒ % A complete truth table true not false not ⇒ true 52 not ⇒ –53 stackunderflow, typecheck Errors: See Also: and, or, xor, if DPS – notify notify condition wait resumes execution of all contexts, if any, that are suspended in a for condition . See section 7.1, “Multiple Execution Contexts.” notify should be invoked only within the execution of a monitor Ordinarily, that references the same lock used in the wait for condition . This ensures that notifica- tions cannot be lost due to a race between a context executing and one notify executing . However, this recommendation is not enforced by the language. wait Errors: stackunderflow, typecheck See Also: wait, monitor, condition null – null null pushes a literal null object on the operand stack. null is not an operator; it is a name in systemdict associated with the null object. Errors: stackoverflow 458 Chapter 8: Operators

467 PLRM 2nd Edition Operators January 26, 1994 – – nulldevice nulldevice installs the “null device” as the current output device. The null device corre- sponds to no physical output device and has no raster memory associated with show or it. Marks placed on the current page by painting operators (for example, stroke showpage and copypage ) do nothing. ) are discarded; output operators ( However, in all other respects the null device behaves like a real raster output device: the graphics operators have their normal side-effects on the graphics state, the character operators invoke the font machinery, and so on. nulldevice sets the default transformation matrix to be the identity transform [1.0 0.0 0.0 1.0 0.0 0.0]. A PostScript language program may change this to any setmatrix ) if it desires to simulate the device coordinate sys- other matrix (using tem of some real device. nulldevice also establishes the clipping path as a degen- erate path consisting of a single point at the origin. The null device is useful for exercising the PostScript interpreter’s graphics and font machinery for such purposes as operating on paths, computing bounding boxes for graphical shapes, and performing coordinate transformations using CTM without generating output. Such manipulations should be bracketed by gsave and grestore so the former device can be reinstated and the other side effects of nulldevice undone. Errors: (none) See Also: setpagedevice bool or bool bool or 2 3 1 int int or int 1 2 3 If the operands are booleans, or returns their logical disjunction. If the operands are integers, or returns the bitwise “inclusive or” of their binary representations. Example ⇒ true % A complete truth table true true or true false or ⇒ true false true or ⇒ true false false or ⇒ false 17 5 or ⇒ 21 stackunderflow, typecheck Errors: See Also: and, not, xor 8.2 Operator Details 459

468 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 packedarray ... any n packedarray packedarray any n–1 0 n containing the objects any through creates a packed array object of length 0 any n as elements. packedarray first removes the non-negative integer from n–1 the operand stack. It then removes that number of objects from the operand stack, creates a packed array containing those objects as elements, and finally pushes the resulting packed array object on the operand stack. The resulting object has a type of packedarraytype , a literal attribute, and read- only access. In all other respects, its behavior is identical to that of an ordinary array object. The packed array is allocated in local or global VM according to the current VM allocation mode. An invalidaccess error occurs if the packed array is in global ... any are in local VM (see section 3.7.2, “Local and Glo- VM and any of any 0 n–1 bal VM”). Errors: invalidaccess, rangecheck, stackunderflow, typecheck, VMerror See Also: aload 460 Chapter 8: Operators

469 PLRM 2nd Edition Operators January 26, 1994 ur – ll ur pathbbox pathbbox ll y x x y returns the bounding box of the current path in the current user coordinate sys- tem. The results are four real numbers: lower-left x , lower-left y , upper-right x , and upper-right y . These coordinates describe a rectangle, oriented with its sides parallel to the x and y axes in user space, that completely encloses all elements of pathbbox executes the error the path. If the current path is empty, nocurrentpoint . pathbbox first computes the bounding box of the current path in device space. It then transforms these coordinates to user space by the inverse of CTM and com- putes the bounding box of the resulting figure in user space. If the user coordi- nate system is rotated (other than by multiples of 90 degrees) or skewed, pathbbox may return a bounding box that is larger than expected. If the path includes curve segments, the bounding box encloses the control points of the curves as well as the curves themselves. To obtain a bounding box that fits the path more tightly, one should first “flatten” the curve segments by executing flattenpath . In Level 2 implementations of the PostScript language, if the current path ends moveto , the bounding box does not necessarily include it, unless the with a moveto is the only element of the path. If an explicit bounding box has been established by setbbox , pathbbox returns a result derived from that bounding box, not from the actual path. nocurrentpoint, stackoverflow Errors: See Also: flattenpath, clippath, charpath, setbbox 8.2 Operator Details 461

470 PLRM 2nd Edition January 26, 1994 Operators move line curve close pathforall pathforall – removes four operands from the stack, all of which must be procedures. then enumerates the current path in order, executing one of the four pathforall procedures for each element in the path. The four basic kinds of elements in a , lineto , path are , and closepath . The relative variants rmoveto , moveto curveto , and rcurveto are converted to the corresponding absolute forms; arc rlineto , arcn arcto are converted to sequences of curveto . For each element in the , and pathforall path, pushes the element’s coordinates on the operand stack and exe- cutes one of the four procedures as follows: push xy ; execute moveto move lineto push x y ; execute line x curve curveto push execute ; y y x x y 2 2 1 3 1 3 execute closepath close The operands passed to the procedures are coordinates in user space. pathforall transforms them from device space to user space using the inverse of the CTM. Ordinarily, these coordinates will be the same as the ones originally entered by moveto lineto , and so forth. However, if the CTM has been changed since the , path was constructed, the coordinates reported by pathforall will be different from those originally entered. enables a path constructed in one user coordinate pathforall Among other uses, system to be read out in another user coordinate system. enumerates the current path existing at the time it begins execution. pathforall If any of the procedures change the current path, such changes do not alter the behavior of pathforall . If charpath was used to construct any portion of the current path from a font whose outlines are protected, pathforall is not allowed. Its execution will pro- duce an invalidaccess error (see charpath ). Errors: invalidaccess, stackoverflow, stackunderflow, typecheck See Also: moveto, lineto, curveto, closepath, charpath Chapter 8: Operators 462

471 PLRM 2nd Edition January 26, 1994 Operators pop any pop – removes the top element from the operand stack and discards it. Example 1 2 3 pop ⇒ 1 2 1 2 3 pop pop ⇒ 1 Errors: stackunderflow See Also: clear, dup print – print string string to the standard output file (see section 3.8, “File writes the characters of Input and Output”). The print operator provides the simplest means to send text is a to an application or an interactive user. Note that print file operator that has nothing to do with painting character shapes on the current page (see show ) or with sending the current page to a raster output device (see showpage ). invalidaccess, ioerror, stackunderflow, typecheck Errors: See Also: write, flush, =, ==, printobject 8.2 Operator Details 463

472 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 printobject obj tag – printobject writes a binary object sequence to the standard output file; see section 3.12.6, “Structured Output.” The binary object sequence contains a top-level array whose length is one; its single element is an encoding of . If obj is composite, obj the binary object sequence also includes subsidiary array and string values for the components of obj . The tag operand, which must be an integer in the range 0 to 255, is used to tag the top-level object; it appears as the second byte of the object’s representation. Tag values 0 through 249 are available for general use; tag values 250 through 255 are reserved for special purposes, such as reporting errors. The binary object sequence uses the number representation established by the most recent execution of setobjectformat . The token type given as the first byte of the binary object sequence reflects the number representation that was used. If the object format parameter has been set to zero, printobject executes an error. undefined The object obj and its components must be of type null, integer, real, name, boolean, string, array, or mark (see section 3.12, “Binary Encoding Details”). Appearance of an object of any other type, including packed array, will result in typecheck error. If arrays are nested too deeply or are cyclical, a limitcheck a error occurs. printobject always encodes a name object as a reference to a text name in the string value portion of the binary object sequence, never as a system or user name index. As is the case for all operators that write to files, the output produced by may accumulate in a buffer instead of being transmitted immedi- printobject ately. To ensure immediate transmission, a flush is required. This is particularly important in situations where the output produced by printobject is the response to a query from the application. Errors: invalidaccess, ioerror, limitcheck, rangecheck, stackunderflow, typecheck, undefined See Also: print, setobjectformat, writeobject 464 Chapter 8: Operators

473 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 product – string product is a read-only string object that is the name of the product in which the Post- Script interpreter is running. The value of this string is typically a manufacturer defined trademark; it has no direct connection with specific features of the Post- Script language. stackoverflow Errors: See Also: languagelevel, revision, serialnumber, version prompt – prompt – is a procedure executed by executive whenever it is ready for the user to enter a new statement. The standard definition of is “ (PS>) print flush ” and is prompt defined in or ; it can be overridden by defining prompt in userdict systemdict is not defined in some other dictionary higher on the dictionary stack. prompt products that do not support . See section 2.4.4, “Using the Interpreter executive Interactively.” Errors: (none) See Also: executive pstack any ... any ... any any pstack n 1 n 1 writes text representations of every object on the stack to the standard output file, but leaves the stack unchanged. pstack applies the == operator to each ele- ment of the stack, starting with the topmost element. See the == operator for a description of its effects. Errors: (none) See Also: stack, =, == 8.2 Operator Details 465

474 PLRM 2nd Edition Operators January 26, 1994 array index any – put put dict key any put – string index int – put replaces a single element of the value of an array, dictionary, or string. If the first operand is an array or string, put treats the second operand as an index and stores the third operand at the position identified by the index, counting from zero. index must be in the range 0 to n –1,where n is the length of the array or string. If it is outside this range, will execute a rangecheck error. put If the first operand is a dictionary, put uses the second operand as a key and the third operand as a value, and it stores this key-value pair into dict . If key is any . Otherwise, already present as a key in dict , put simply replaces its value by put key and associates any with it. In Level 1 implemen- creates a new entry for tations, if dict is already full, put executes the error dictfull . If the value of array or dict is in global VM and any is a composite object whose value is in local VM, an invalidaccess error occurs (see section 3.7.2, “Local and Global VM”). Example /ar [5 17 3 8] def ar 2 (abcd) put ar ⇒ [5 17 (abcd) 8] /d 5 dict def d /abc 123 put d {} forall ⇒ /abc 123 /st (abc) def st 0 65 put % 65 is ASCII code for character “A” st ⇒ (Abc) dictfull, invalidaccess, rangecheck, stackunderflow, typecheck Errors: See Also: get, putinterval 466 Chapter 8: Operators

475 PLRM 2nd Edition Operators January 26, 1994 putinterval array – index array putinterval 2 1 array index packedarray putinterval – 1 2 – string putinterval index string 2 1 replaces a subsequence of the elements of the first operand by the entire con- tents of the third operand. The subsequence that is replaced begins at the speci- fied index in the first operand; its length is the same as the length of the third operand. The objects are copied from the third operand to the first, as if by a sequence of s and individual get s. In the case of arrays, if the copied elements are them- put array selves composite objects, the values of those objects are shared between 2 array and (see section 3.3.1, “Simple and Composite Objects”). 1 such that index string or index to be a valid index in array putinterval requires 1 1 plus the length of array or string is not greater than the length of array or 2 1 2 string . 1 is in global VM and any of the elements copied from array If the value of array 1 2 or packedarray are composite objects whose values are in local VM, an 2 invalidaccess error occurs (see section 3.7.2, “Local and Global VM”). Example /ar [5 8 2 7 3] def ar 1 [(a) (b) (c)] putinterval ar ⇒ [5 (a) (b) (c) 3] /st (abc) def st 1 (de) putinterval st ⇒ (ade) invalidaccess, rangecheck, stackunderflow, typecheck Errors: See Also: getinterval, put 8.2 Operator Details 467

476 PLRM 2nd Edition January 26, 1994 Operators – quit quit – depends on quit terminates operation of the interpreter. The precise action of the environment in which the PostScript interpreter is running. It may give con- trol to an operating system command interpreter, halt or restart the machine, and so on. In an interpreter that supports multiple execution contexts (see section 7.1, “Multiple Execution Contexts”), the quit operator causes termination of the cur- rent context only. Termination is immediate, even if the context was created by fork in the expectation of a subsequent . join In a context that is under the control of a job server (see section 3.7.7, “Job Exe- cution Environment”), the definition of the operator in systemdict is quit quit in userdict , which usually is searched masked by another definition of , stop before systemdict . The default definition of quit in userdict is the same as which terminates the current job, but not the interpreter as a whole. The quit systemdict can be executed only by an unencapsulated job; in an operator in encapsulated job, it causes an invalidaccess error. invalidaccess Errors: See Also: stop, start rand – rand int 31 returns a random integer in the range 0 to 2 − 1, produced by a pseudo-ran- dom number generator. The random number generator’s state can be reset by and interrogated by rrand . srand Errors: stackoverflow See Also: srand, rrand rangecheck (error) A numeric operand’s value is outside the range expected by an operator—for example, an array or string index is out of bounds, or a negative number appears rangecheck where a non-negative number is required. can also occur if a matrix operand does not contain exactly six elements. 468 Chapter 8: Operators

477 PLRM 2nd Edition January 26, 1994 Operators array rcheck rcheck bool bool rcheck packedarray rcheck bool dict file rcheck bool bool string rcheck tests whether the operand’s access permits its value to be read explicitly by Post- rcheck true if the operand’s access is unlimited or read- Script operators. returns otherwise. only, false Errors: stackunderflow, typecheck See Also: executeonly, noaccess, readonly, wcheck – dx dy rcurveto dx dy dy dx rcurveto 2 2 3 1 1 3 curveto (relative ) adds a Bézier cubic section to the current path in the same curveto . However, the three number pairs are interpreted as displace- manner as ments relative to the current point , y ) rather than as absolute coordinates. (x 0 0 dx ) to ( That is, rcurveto constructs a curve from ( x + , y x , x ), using ( + dx dy ,y + 0 0 0 0 0 1 3 3 y ) as Bézier control points. See the description of + dy dy ) and ( x + + dx y , 2 0 0 1 2 0 curveto for complete information. Errors: limitcheck, nocurrentpoint, stackunderflow, typecheck, undefinedresult See Also: curveto, rlineto, rmoveto read file read int true (if not end-of-file) false (if end-of-file) reads the next character from the input file file, pushes it on the stack as an inte- ger, and pushes true as an indication of success. If an end-of-file indication is read closes the file and returns encountered before a character has been read, false . If some other error indication is encountered (for example, parity or check- sum error), read executes ioerror . invalidaccess, ioerror, stackoverflow, stackunderflow, typecheck Errors: See Also: readhexstring, readline, readstring, bytesavailable 469 8.2 Operator Details

478 PLRM 2nd Edition January 26, 1994 Operators readhexstring file string readhexstring substring bool reads characters from file , expecting to encounter a sequence of hexadecimal dig- its 0 through 9 and A through F (or a through f ). readhexstring interprets each successive pair of digits as a two-digit hexadecimal number representing an inte- ger value in the range 0 to 255. It then stores these values into successive ele- ments of string starting at index 0 until either the entire string has been filled or an end-of-file indication is encountered in file . Finally, readhexstring returns the substring of string that was filled and a boolean indicating the outcome ( true nor- mally, false if end-of-file was encountered before the string was filled). readhexstring ignores any characters that are not valid hexadecimal digits, so may be interspersed with spaces, newlines, etc., without changing file the data in the interpretation of the data. See section 3.8.4, “Filters,” for more information about ASCII-encoded, binary data representations and how to deal with them. Errors: invalidaccess, ioerror, rangecheck, stackunderflow, typecheck See Also: read, readline, readstring, filter readline file string readline substring bool reads a line of characters (terminated by a newline character) from and stores file them into successive elements of string . readline then returns the substring of string that was filled and a boolean indicating the outcome ( true normally, false if end-of-file was encountered before a newline character was read). A “line of characters” is a sequential string of ASCII characters, including space, tab, and non-printing “control” characters. A line terminates with a newline —a carriage return character, a line-feed character, or both. See section 3.2, “Syntax,” and section 3.8, “File Input and Output.” The terminating newline character is not stored into string or included at the end of the returned substring . If readline completely fills string before encountering a newline character, it executes the error rangecheck . Errors: invalidaccess, ioerror, rangecheck, stackunderflow, typecheck See Also: read, readhexstring, readonly 470 Chapter 8: Operators

479 PLRM 2nd Edition Operators January 26, 1994 array readonly array readonly readonly packedarray packedarray dict readonly dict file readonly file string string readonly reduces the access attribute of an array, packed array, dictionary, file, or string object to read-only (see section 3.3.2, “Attributes of Objects”). Access can only be reduced this way, never increased. When an object is read-only, its value can- not be modified by PostScript operators (an invalidaccess error will result), but it can still be read by operators or executed by the PostScript interpreter. For an array, packed array, file, or string, readonly affects the access attribute only of the object that it returns. If there are other objects that share the same value, their access attributes are unaffected. However, in the case of a dictionary, of the object, so all dictionary objects sharing the same value readonly affects the dictionary are affected. invalidaccess, stackunderflow, typecheck Errors: See Also: executeonly, noaccess, rcheck, wcheck readstring file string readstring substring bool reads characters from file and stores them into successive elements of string until either the entire string has been filled or an end-of-file indication is encountered file in . that was filled and a bool- readstring then returns the substring of string true normally, false if end-of-file was encountered ean indicating the outcome ( before the string was filled). All character codes are treated the same—as integers in the range 0 to 255. There are no special characters (in particular, the newline character is not treated spe- cially). However, the communication channel may usurp certain control charac- ters; see section 3.8, “File Input and Output.” invalidaccess, ioerror, rangecheck, stackunderflow, typecheck Errors: See Also: read, readhexstring, readline 8.2 Operator Details 471

480 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 realtime – realtime int returns the value of a clock that counts in real time, independent of the execu- tion of the PostScript interpreter. The clock’s starting value is arbitrary; it has no defined meaning in terms of calendar time. The unit of time represented by the realtime value is one millisecond. However, the rate at which it changes is implementation dependent. As the time value becomes greater than the largest integer allowed in a particular implementation, it “wraps” to the smallest (most negative) integer. Errors: stackoverflow See Also: usertime LEVEL 2 rectclip x y width height – rectclip rectclip numarray – rectclip – numstring intersects the inside of the current clipping path with a rectangular path the operands describe. In the first form, the operands are four numbers that describe a single rectangle. In the other two forms, the operand is an array or an encoded number string that describes an arbitrary number of rectangles (see section 3.12.5, “Encoded Number Strings,” and section 4.6.5, “Rectangles”). After com- puting the new clipping path, rectclip resets the current path to empty, as if by newpath . In the first form, assuming width and height are positive, rectclip is equivalent to: newpath moveto xy width 0 rlineto 0 height rlineto width neg 0 rlineto closepath clip newpath Note that if the second or third form is used to specify multiple rectangles, the clip opera- rectangles are treated together as a single path and used for a single tion. The “inside” of this combined path is the union of all the rectangular sub- paths, because the paths are all drawn in the same direction and the non-zero winding number rule is used. Errors: limitcheck, stackunderflow, typecheck See Also: clip, rectfill, rectstroke Chapter 8: Operators 472

481 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 rectfill rectfill – x y width height numarray rectfill – numstring rectfill – fills a path consisting of one or more rectangles the operands describe. In the first form, the operands are four numbers that describe a single rectangle. In the other two forms, the operand is an array or an encoded number string that describes an arbitrary number of rectangles (see section 3.12.5, “Encoded Num- ber Strings,” and section 4.6.5, “Rectangles”). rectfill neither reads nor alters the current path in the graphics state. height In the first form, assuming is equivalent to: and width are positive, rectfill gsave newpath xy moveto width 0 rlineto 0 height rlineto width neg 0 rlineto closepath fill grestore Errors: limitcheck, stackunderflow, typecheck See Also: fill, rectclip, rectstroke 8.2 Operator Details 473

482 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 rectstroke x y width height – rectstroke rectstroke x y width height matrix – rectstroke – numarray numarray matrix – rectstroke numstring rectstroke – numstring matrix rectstroke – strokes a path consisting of one or more rectangles the operands describe. In the first two forms, the operands are four numbers that describe a single rectangle. In the remaining forms, the operand is an array or an encoded number string that describes an arbitrary number of rectangles (see section 3.12.5, “Encoded Number Strings,” and section 4.6.5, “Rectangles”). rectstroke neither reads nor alters the current path in the graphics state. If the matrix operand is present, rectstroke concatenates to the CTM after matrix defining the path, but before stroking it. The applies to the line width and matrix dash pattern, if any, but not to the path itself. In the first two forms, assuming and height are positive, rectstroke is equiv- width alent to: gsave newpath xy moveto width 0 rlineto 0 height rlineto width neg 0 rlineto closepath matrix concat % If matrix operand is supplied stroke grestore Errors: limitcheck, rangecheck, stackunderflow, typecheck See Also: stroke, rectclip, rectfill 474 Chapter 8: Operators

483 PLRM 2nd Edition Operators January 26, 1994 DPS rectviewclip rectviewclip – x y width height numarray rectviewclip – numstring rectviewclip – replaces the current view clip with a rectangular path the operands describe. In the first form, the operands are four numbers that describe a single rectangle. In the other two forms, the operand is an array or an encoded number string that describes an arbitrary number of rectangles (see section 3.12.5, “Encoded Num- ber Strings,” section 7.3.1, “View Clipping,” and section 4.6.5, “Rectangles”). After computing the new view clipping path, resets the current path rectviewclip to empty, as if by . newpath Except for the manner in which the path is defined, behaves the rectviewclip same as viewclip . Note that if the second or third form is used to specify multiple rectangles, the rectangles are treated together as a single path and used for a single viewclip operation. The “inside” of this combined path is the union of all the rectangular subpaths, because the paths are all drawn in the same direction and the non- zero winding number rule is used. Errors: limitcheck, stackunderflow, typecheck See Also: rectclip, viewclip 8.2 Operator Details 475

484 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 renamefile old new – renamefile new old new , where changes the name of a file from and to are strings that old specify file names on the same storage device. If no such file exists, an undefinedfilename error occurs. If the device does not allow this operation, an invalidfileaccess error occurs. If an environment-dependent error is detected, an ioerror new already exists occurs. Whether or not an error occurs if a file named is environment dependent. See section 3.8.2, “Named Files.” Errors: invalidfileaccess, ioerror, stackunderflow, typecheck, undefinedfilename See Also: file, deletefile, status repeat int proc repeat – is a non-negative integer. The executes proc int operator int times, where repeat removes both operands from the stack before executing proc for the first time. If leaves no executes the operator, repeat proc repeat exit terminates prematurely. results of its own on the stack, but proc may do so. Example 4 {(abc)} repeat ⇒ (abc)(abc)(abc)(abc) 1 2 3 4 3 {pop} repeat 1 % Pops 3 values (down to the 1) ⇒ 4 {} repeat ⇒ % Does nothing four times mark 0 {(won’t happen)} repeat ⇒ mark In the last example, a zero repeat count meant that the procedure is not exe- cuted at all, hence the mark is still topmost on the stack. Errors: rangecheck, stackunderflow, typecheck See Also: for, loop, forall, exit 476 Chapter 8: Operators

485 PLRM 2nd Edition Operators January 26, 1994 resetfile file resetfile – discards buffered characters belonging to a file object. For an input file, resetfile discards any characters that have been received from the source, but not yet con- sumed. For an output file, it discards any characters that have been written to the file, but not yet delivered to their destination. resetfile may have other side effects that depend on the properties of the under- lying file. For example, it may restart communication via a channel that was blocked waiting for buffer space to become available. resetfile never waits for characters to be received or transmitted. stackunderflow, typecheck Errors: See Also: file, closefile, flushfile 8.2 Operator Details 477

486 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 resourceforall template proc scratch category – resourceforall enumerates the names of all instances of a specified resource category or a subset selected by . category is a name object that identifies a resource category, template Font (see section 3.9.2, “Resource Categories”). such as is a string object template to be matched against names of resource instances. For each matching name, resourceforall copies the name into the supplied scratch string, pushes a string object that is the substring of scratch that was actually used, and calls proc . resourceforall proc may do so. does not return any results of its own, but The template is matched against the names of resource instances, treating them as if they were strings. Within the template, all characters are treated literally and are case sensitive, with the exception of the following: * matches zero or more consecutive characters. ? matches exactly one character. \ causes the next character of the template to be treated literally, even if it is *, ?, or \. wishes to Note that the scratch string is reused during every call to proc . If proc save the string that is passed to it, it must make a copy or use cvn to convert the resourceforall string to a name. Use of strings instead of names allows to func- tion without creating new name objects, which would consume VM needlessly during a large enumeration. It is prudent to provide a scratch string at least as long as the implementation limit for names (see Appendix B). It is possible for a resource instance to have a key which is not a name or string. resourceforall passes the Such a key matches only the template (*). In this case, proc instead of copying it into the scratch string. This case can key directly to arise only for a resource instance defined in VM by a previous defineresource ; the keys for external resource instances are always names or strings. Like resourcestatus , but unlike findresource , resourceforall never loads a resource instance into VM. enumerates the resource instances in order of status (the status resourceforall value returned by resourcestatus ); that is, it enumerates groups in this order: 1. Instances defined in VM by an explicit defineresource ; not subject to auto- matic removal. 2. Instances defined in VM by a previous execution of findresource ; subject to automatic removal. 3. Instances not currently defined in VM, but available from external storage. 478 Chapter 8: Operators

487 PLRM 2nd Edition Operators January 26, 1994 Within each group, the order of enumeration is unpredictable. It is unrelated to order of definition or to whether the definition is local or global. A given resource instance is enumerated only once, even if it exists in more than one group. If proc adds or removes resource instances, those instances may or may not appear later in the same enumeration. resourceforall considers both local and global definitions if Like resourcestatus , the current VM allocation mode is local, but only global definitions if the cur- rent VM allocation mode is global (see resourcestatus and defineresource ). If the specified resource category does not exist, an undefined error occurs. How- ever, no error occurs if there are no instances whose names match the template. Of course, the proc that is called can generate errors of its own. invalidaccess, stackoverflow, stackunderflow, typecheck, undefined Errors: See Also: defineresource, undefineresource, findresource, resourcestatus 8.2 Operator Details 479

488 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 resourcestatus key category status size true (if resource exists) resourcestatus (if not) false category is a name returns status information about a named resource instance. Font object that identifies a resource category, such as (see section 3.9.2, “Resource Categories”). key is a name or string object that identifies the resource instance. (Names and strings are interchangeable; keys of other types are permit- ted but are not recommended.) If the named resource instance exists, either defined in VM or available from resourcestatus returns two integers and the value true ; some external source, otherwise, it returns false . Unlike findresource , resourcestatus never loads a resource instance into VM. status is an integer with the following meanings: ; not subject to automatic 0 Defined in VM by an explicit defineresource removal. 1 findresource ; subject to Defined in VM by a previous execution of automatic removal. 2 Not currently defined in VM, but available from external storage. size is an integer giving the estimated VM consumption of the resource instance in bytes. This information may not be available for certain resources; if the size is unknown, –1 is returned. Usually, can obtain the size of a status 1 resourcestatus or 2 resource (derived from the %%VMusage comment in the resource file), but it has no general way to determine the size of a status 0 resource. See section 3.9.4, “Resources as Files,” for an explanation of how the size is determined. A size value of 0 is returned for implicit resources, whose instances do not occupy VM. resourcestatus considers both local If the current VM allocation mode is local, and global resource definitions, in that order (see defineresource ). However, if the current VM allocation mode is global, only global resource definitions are visible to resourcestatus . Resource instances in external storage are visible with- out regard to the current VM allocation mode. If the specified resource category does not exist, an undefined error occurs. Errors: stackoverflow, stackunderflow, typecheck, undefined See Also: defineresource, undefineresource, findresource, resourceforall 480 Chapter 8: Operators

489 PLRM 2nd Edition Operators January 26, 1994 save – restore restore resets the virtual memory (VM) to the state represented by the supplied save save was exe- object—in other words, the state at the time the corresponding cuted. See section 3.7, “Memory Management,” for a description of the VM and save and restore . the effects of If the current execution context supports job encapsulation and if save repre- sents the outermost saved VM state for this context, then objects in both local and global VM revert to their saved state. If the current context does not support save is not the outermost saved VM state for this context, job encapsulation or if then only objects in local VM revert to their saved state; objects in global VM are undisturbed. Job encapsulation is described in section 3.7.7, “Job Execution Environment.” Its relationship to multiple contexts is described in section 7.1, “Multiple Execution Contexts.” restore can reset the VM to the state represented by any save object that is still valid, not necessarily the one produced by the most recent save . After restoring the VM, restore invalidates its save operand along with any other save objects created more recently than that one. That is, a VM snapshot can be used only once; to restore the same environment repeatedly, it is necessary to do a new save each time. restore does not alter the contents of the operand, dictionary, or execution stack, except to pop its save operand. If any of these stacks contains composite objects whose values reside in local VM and are newer than the snapshot being restored, restore executes the invalidrestore error. This restriction applies to save objects and, in Level 1 implementations, to name objects. restore does alter the graphics state stack: It performs the equivalent of a grestoreall and then removes the graphics state created by save from the graph- restore ics state stack. also resets several per-context parameters to their state at the time of . These include: save • Array packing mode (see setpacking ). • VM allocation mode (see setglobal ). • Object output format (see setobjectformat ). • View clipping path (see viewclip ). • All user interpreter parameters (see setuserparams ). invalidrestore, stackunderflow, typecheck Errors: See Also: save, grestoreall, vmstatus, startjob 8.2 Operator Details 481

490 PLRM 2nd Edition January 26, 1994 Operators – reversepath – reversepath replaces the current path with an equivalent one whose segments are defined in the reverse order. Precisely, reversepath reverses the directions and order of seg- ments within each subpath of the current path. However, it does not alter the order of the subpaths in the path with respect to each other. limitcheck Errors: LEVEL 2 revision – int revision is an integer designating the current revision level of the product in which the PostScript interpreter is running. Each product has its own numbering system for revisions, independent of those of any other product. This is distinct from version in the value of , which is the revision level of the PostScript systemdict interpreter, without regard to the product in which it is running. Errors: stackoverflow See Also: languagelevel, product, serialnumber, version rlineto rlineto – dx dy (relative lineto ) appends a straight line segment to the current path in the same manner as . However, the number pair is interpreted as a displacement rel- lineto ative to the current point ( x , y ) rather than as an absolute coordinate. That is, rlineto ) constructs a line from ( x , y ) to ( x + dx , y + dy ) and makes ( x + dx , y + dy the new current point. If the current point is undefined because the current path nocurrentpoint is empty, rlineto executes the error . Errors: limitcheck, nocurrentpoint, stackunderflow, typecheck See Also: lineto, rmoveto, rcurveto 482 Chapter 8: Operators

491 PLRM 2nd Edition Operators January 26, 1994 dx dy – rmoveto rmoveto (relative moveto ) starts a new subpath of the current path in the same manner as moveto . However, the number pair is interpreted as a displacement relative to the current point ( x , y ) rather than as an absolute coordinate. That is, rmoveto makes ( x + dx , y + dy ) the new current point, without connecting it to the previ- ous point. If the current point is undefined because the current path is empty, executes the error nocurrentpoint . rmoveto Errors: limitcheck, nocurrentpoint, stackunderflow, typecheck See Also: moveto, rlineto, rcurveto roll any ... any ... any any n j roll any ... any (j–1) mod n 0 0 n–1 n–1 j mod n any on the operand stack performs a circular shift of the objects any through n–1 0 by the amount j . Positive j indicates upward motion on the stack, whereas nega- tive j indicates downward motion. n must be a non-negative integer and j must be an integer. roll first removes these operands from the stack; there must be at least n additional elements. roll then performs a circular shift of these n elements by j positions. is positive, each shift consists of removing an element from the top of the j If stack and inserting it between element − 1 and element n of the stack, moving n all intervening elements one level higher on the stack. If j is negative, each shift consists of removing element n − 1 of the stack and pushing it on the top of the stack, moving all intervening elements one level lower on the stack. Example (a)(b)(c) 3 –1 roll ⇒ (b)(c)(a) (a)(b)(c) 3 1 roll ⇒ (c)(a)(b) (a)(b)(c) 3 0 roll ⇒ (a)(b)(c) Errors: rangecheck, stackunderflow, typecheck See Also: exch, index, copy, pop 8.2 Operator Details 483

492 PLRM 2nd Edition January 26, 1994 Operators LEVEL 2 rootfont – font rootfont setfont selectfont . returns the font that has been selected most recently by or rootfont returns the same result as Normally, . If the current font is a currentfont composite font and rootfont is invoked from a descendant font’s BuildGlyph or BuildChar procedure or from cshow , rootfont returns the root composite font, whereas would return the currently selected base font. currentfont stackoverflow Errors: See Also: setfont, selectfont, currentfont rotate angle rotate – angle matrix rotate matrix With no matrix operand, rotate builds a temporary matrix θ cos 0 θ sin R = cos 0 −θ sin θ 001 is the operand where θ angle in degrees, and concatenates this matrix with the rotate current transformation matrix (CTM). Precisely, replaces the CTM by R CTM. The effect of this is to rotate the user coordinate system axes about × degrees (positive is counterclockwise) with respect to their angle their origin by former orientation. The position of the user coordinate origin and the sizes of units are unchanged. y and x the matrix If the and rotate operand is supplied, R matrix by replaces the value of back on the operand stack (see section 4.3.3, “Matrix pushes the modified matrix Representation and Manipulation,” for a discussion of how matrices are repre- rotate sented as arrays). In this case, does not affect the CTM. rangecheck, stackunderflow, typecheck Errors: See Also: scale, translate, concat Chapter 8: Operators 484

493 PLRM 2nd Edition January 26, 1994 Operators round num round num 1 2 returns the integer value nearest to num is equally close to its two near- . If num 1 1 est integers, round returns the greater of the two. The type of the result is the same as the type of the operand. Example 3.2 round ⇒ 3.0 ⇒ 7.0 6.5 round –4.8 round ⇒ –5.0 ⇒ –6.0 –6.5 round 99 round 99 ⇒ Errors: stackunderflow, typecheck See Also: ceiling, floor, truncate, cvi rrand – rrand int returns an integer representing the current state of the random number genera- tor used by rand . This may later be presented as an operand to srand to reset the random number generator to the current position in the sequence of numbers produced. Errors: stackoverflow See Also: rand, srand 8.2 Operator Details 485

494 PLRM 2nd Edition Operators January 26, 1994 run string run – executes the contents of the file identified by string —in other words, interprets the characters in that file as a PostScript language program. When run encoun- ters end-of-file or terminates for some other reason (for example, stop ), it closes the file. run is essentially a convenience operator for the sequence (r) file cvx exec except for its behavior upon abnormal termination. Also, the context of a run cannot be left by executing exit ; an attempt to do so produces the error invalidexit . The run operator leaves no results on the operand stack, but the pro- gram executed by run may alter the stacks arbitrarily. ioerror, limitcheck, stackunderflow, typecheck, undefinedfilename Errors: See Also: exec, file save save save – creates a snapshot of the current state of the virtual memory (VM) and returns a save object representing that snapshot. Subsequently, this save object may be presented to restore to reset the VM to this snapshot. See section 3.7, “Memory Management,” for a description of the VM and of the effects of save and restore . restore See the operator for a detailed description of what is saved in the snap- shot. also saves the current graphics state by pushing a copy of it on the graphics save state stack in a manner similar to gsave . This saved graphics state is restored by restore and grestoreall . Example /saveobj save def ...arbitrary computation... saveobj restore % Restore saved VM state limitcheck, stackoverflow Errors: See Also: restore, gsave, grestoreall, vmstatus 486 Chapter 8: Operators

495 PLRM 2nd Edition January 26, 1994 Operators – s scale s scale x y s matrix s matrix scale y x With no matrix operand, scale builds a temporary matrix s 00 x S = 0 s 0 y 001 and concatenates this matrix with the current transformation matrix (CTM). replaces the CTM by x scale Precisely, × S CTM. The effect of this is to make the units in the former and s units in the user coordinate system the size of y and s y x user coordinate system. The position of the user coordinate origin and the orientation of the axes are unchanged. matrix by and If the matrix operand is supplied, scale replaces the value of S pushes the modified matrix back on the operand stack (see section 4.3, “Coordi- nate Systems and Transformations,” for a discussion of how matrices are repre- sented as arrays). In this case, does not affect the CTM. scale Errors: rangecheck, stackunderflow, typecheck See Also: rotate, translate, concat 8.2 Operator Details 487

496 PLRM 2nd Edition Operators January 26, 1994 font scale font ′ scalefont scalefont scale to font , producing a new font ′ applies the scale factor whose characters are scaled by scale (in both x and y ) when they are shown. scalefont first creates a copy of font , then replaces the new font’s FontMatrix entry with the result of scaling the existing FontMatrix scale . It inserts two additional entries, by and OrigFont , whose purpose is internal to the implementation. ScaleMatrix Finally, it returns the result as font ′ . Showing characters from the transformed font produces the same results as showing from the original font after having scaled user space by the factor scale in both x and y by means of the scale operator. scalefont is essentially a conveni- ence operator that enables the desired scale factor to be encapsulated in the font makefont , performs more general transforma- description. Another operator, tions than simple scaling. See the description of makefont for more information selectfont on how the transformed font is derived. combines the effects of findfont and scalefont . The interpreter keeps track of font dictionaries recently created by scalefont . scalefont multiple times with the same Calling and scale will usually return font the same font ′ rather than create a new one each time. However, it is usually more efficient for a PostScript language program to apply scalefont only once for each font that it needs and to keep track of the resulting font dictionaries on its own. See Chapter 5 for general information about fonts and section 4.3, “Coordinate Systems and Transformations.” selectfont , scalefont The makefont operators produce a font dictionary , and derived from an original font dictionary, but with the FontMatrix entry altered. The derived font dictionary is allocated in local or global VM according to whether the original font dictionary is in local or global VM. This is indepen- dent of the current VM allocation mode. Example /Helvetica findfont 12 scalefont setfont This obtains the standard Helvetica font, which is defined with a 1-unit line height, and scales it by a factor of 12 in both x and y dimensions. This produces a 12-unit high font (i.e., a 12-point font in default user space) whose characters have the same proportions as those in the original font. Errors: invalidfont, stackunderflow, typecheck, undefined See Also: makefont, setfont, findfont, selectfont 488 Chapter 8: Operators

497 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 scheck any bool scheck gcheck has the same semantics as . This operator is defined for compatibility with existing Display PostScript applications. Errors: stackunderflow See Also: gcheck search search post match pre true (if found) string seek string false (if not found) looks for the first occurrence of the string seek within string and returns results of this search on the operand stack. The topmost result is a boolean that indicates if the search succeeded. If search finds a subsequence of string whose elements are equal to the elements of seek , it splits string into three segments: pre , the portion of string preceding the string match; , the remainder of , the portion of match that matches seek ; and post string . It then pushes the string objects , match , and pre on the operand stack, post true . All three of these strings are substrings sharing followed by the boolean intervals of the value of the original string . If search does not find a match, it pushes the original string and the boolean false . Example (abbc) (ab) search ⇒ (bc) (ab) ( ) true (abbc) (bb) search ⇒ (c) (bb) (a) true (abbc) (bc) search ⇒ () (bc) (ab) true (abbc) (B) search ⇒ (abbc) false Errors: invalidaccess, stackoverflow, stackunderflow, typecheck See Also: anchorsearch, token 8.2 Operator Details 489

498 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 selectfont selectfont – key scale key matrix selectfont – key , transforms it according to obtains a font whose name is or matrix , and scale establishes it as the current font dictionary in the graphics state. selectfont is equivalent to one of the following, according to whether the second operand is a number or a matrix: key findfont scale scalefont setfont key matrix makefont setfont findfont If the font named by key is already defined in VM, selectfont obtains the font dictionary directly and does not execute findfont . However, if the font is not defined, selectfont invokes findfont in the normal way. In the latter case, it actu- ally executes the name object findfont , so it uses the current definition of that name in the environment of the dictionary stack. On the other hand, redefining exch , makefont , or setfont would not alter the behavior of selectfont . scalefont , can give rise to any of the errors possible for the component opera- selectfont findfont procedure. tions, including arbitrary errors from a user-defined Example /Helvetica 10 selectfont /Helvetica findfont 10 scalefont setfont The two lines of the example have the same effect, but the first one is almost always more efficient. The makefont , scalefont , and selectfont operators produce a font dictionary derived from an original font dictionary, but with the FontMatrix entry altered. The derived font dictionary is allocated in local or global VM according to whether the original font dictionary is in local or global VM. This is indepen- dent of the current VM allocation mode. Errors: invalidfont, rangecheck, stackunderflow, typecheck See Also: findfont, makefont, scalefont, setfont LEVEL 2 serialnumber serialnumber int – returns an integer that purports to represent the specific machine on which the PostScript interpreter is running. The precise significance of this number (includ- ing any claim of its uniqueness) is product dependent. Errors: stackoverflow See Also: languagelevel, product, revision, version 490 Chapter 8: Operators

499 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 setbbox ll ll ur – ur setbbox y y x x establishes a bounding box for the current path, within which the coordinates of all subsequent path construction operators must fall. The bounding box is ll and ll specify the lower-left defined by two pairs of coordinates in user space: y x ur the upper-right corner. It is a rectangle oriented with the user and ur corner, y x space coordinate system axes. The bounding box remains in effect for the lifetime of the current path—that is, newpath or operator that resets the path implicitly. Any attempt until the next to append a path element with a coordinate lying outside the bounding box will give rise to a error. rangecheck Note that arcs are converted to sequences of curveto operations. The coordinates computed as control points for those curveto s must also fall within the bound- ing box. This means that the figure of the arc must be entirely enclosed by the bounding box. On the other hand, the bounds checking applies only to the path itself, not to the result of rendering the path. For example, stroking the path may place marks outside the bounding box. This does not cause an error. Although the operator can be used when defining any path, its main setbbox use is in defining a user path, where it is mandatory. That is, a user path proce- dure passed to one of the user path rendering operators, such as ufill , must begin with a optionally preceded by a ucache . The bounding box information setbbox passed to setbbox enables the user path rendering operator to optimize execu- tion. See section 4.6, “User Paths.” If setbbox appears more than once during definition of a path, the path’s effec- tive bounding box is successively enlarged to enclose the union of all specified bounding boxes. This is not legal in a user path definition. However, this case might arise if uappend is executed multiple times in building up a single current path by concatenating several user paths. If setbbox has established a bounding box, execution of pathbbox returns a result derived from that bounding box instead of one derived from the actual path. The upper-right coordinate values must be greater than or equal to the lower-left values. Otherwise, a rangecheck error will occur. Errors: rangecheck, stackunderflow, typecheck See Also: pathbbox 8.2 Operator Details 491

500 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 setblackgeneration proc – setblackgeneration proc sets the black generation function parameter in the graphics state. The oper- and must be a procedure that can be called with a number in the range 0.0 to 1.0 (inclusive) on the operand stack and that returns a number in the same range. This procedure computes the value of the black component during conversion DeviceRGB color space to DeviceCMYK . For additional information, see from section 6.2.3, “Conversion from DeviceRGB to DeviceCMYK.” setblackgeneration sets a graphics state parameter whose effect is device depen- dent. It should not be used in a page description that is intended to be device independent. Execution of this operator is not permitted in certain circumstances; see section 4.8, “Color Spaces.” Errors: stackunderflow, typecheck, undefined See Also: setundercolorremoval setcachedevice w ll ll ur ur w setcachedevice – y x x x y y passes width and bounding box information to the PostScript interpreter’s font machinery. setcachedevice may be executed only within the context of the BuildGlyph or BuildChar procedure for a type 3 font. See section 5.7, “Type 3 BuildChar Fonts.” , or BuildGlyph must invoke setcachedevice , setcachedevice2 or setcharwidth executing graphics operators to define and paint the char- before setcachedevice acter. requests the font machinery to transfer the results of those operators both into the font cache, if possible, and onto the current page. setcachedevice are all numbers interpreted in the character coor- The operands to dinate system (see section 5.4, “Font Metric Information”). and w comprise w x y the basic width vector for this character—in other words, the normal position of the origin of the next character relative to origin of this one. ll and are the coordinates of the lower-left corner and ur ll and ur are the coor- x y y x dinates of the upper-right corner of the character bounding box. The character bounding box is the smallest rectangle, oriented with the character coordinate system axes, that completely encloses all marks placed on the page as a result of executing the character’s description. For a character defined as a path, this may be determined by means of the pathbbox operator. The font machinery needs this information to make decisions about clipping and caching. The declared bounding box must be correct—in other words, sufficiently large to enclose the entire character. If any marks fall outside this bounding box, they will be clipped off and not moved to the current page. 492 Chapter 8: Operators

501 PLRM 2nd Edition January 26, 1994 Operators setcachedevice installs identical sets of metrics for writing modes 0 and 1, while setcachedevice2 installs separate metrics. or After execution of setcachedevice and until the termination of the BuildGlyph procedure, execution of color setting operators or image is not BuildChar allowed; see section 4.8, “Color Spaces.” Note that use of the imagemask opera- tor is permitted. stackunderflow, typecheck, undefined Errors: See Also: setcachedevice2, setcharwidth, setcachelimit, cachestatus LEVEL 2 w setcachedevice2 – w setcachedevice2 ll v ll v ur w ur w 0x y x 1y y x x y 0y 1x passes two sets of character metrics to the font machinery. w and are the w 0x 0y distances from the current point to the new current point when showing text in ,ur writing mode 0. ll are the distances from origin 0 to the lower-left ,ll ur and y x y x w , w are the distances and upper-right corners of the character bounding box. 1y 1x from the current point to the new current point when showing text in writing mode 1. and v are the distances from origin 0 to origin 1. See section 5.4, v x y “Font Metric Information.” setcachedevice2 Aside from its interpretation of the operands, works the same as setcachedevice in all respects. After execution of setcachedevice2 and until the termination of the BuildGlyph or BuildChar procedure, execution of color setting operators or image is not allowed; see section 4.8, “Color Spaces.” Note that use of the imagemask opera- tor is permitted. Errors: stackunderflow, typecheck, undefined See Also: setcachedevice, setcharwidth, setcachelimit, cachestatus 8.2 Operator Details 493

502 PLRM 2nd Edition January 26, 1994 Operators setcachelimit int setcachelimit – establishes the maximum number of bytes the pixel array of a single cached character may occupy. Any character larger than this (according to the character bounding box information passed to setcachedevice ) is not saved in the font cache. Instead, its description is executed every time the character is encoun- tered. setcachelimit affects the decision whether to place new characters in the font cache; it does not disturb any characters already in the cache. Making the limit larger allows larger characters to be cached, but may decrease the total number of different characters that can be held in the cache simultaneously. Changing this parameter is appropriate only in very unusual situations. int is implementation dependent, representing the total The maximum limit for available size of the font cache (see ). As a practical matter, int should cachestatus not be larger than a small fraction of the total font cache size. Modifications to the cache limit parameter obey save and restore . In a Display PostScript system, which supports multiple contexts, this parameter is main- tained separately for each context. MaxFontItem The parameter set by setcachelimit is the same as the user parame- ter set by setuserparams (see Appendix C). limitcheck, rangecheck, stackunderflow, typecheck Errors: See Also: cachestatus, setuserparams 494 Chapter 8: Operators

503 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 setcacheparams mark size lower upper – setcacheparams sets cache parameters as specified by the integer objects above the topmost mark on the stack, then removes all operands and the mark object as if by cleartomark. The number of cache parameters is variable. In future versions of the PostScript interpreter, there may be more than three cache parameters defined. If more setcacheparams than are needed, the topmost ones are operands are supplied to used and the remainder ignored. If fewer are supplied than are needed, setcacheparams implicitly inserts default values between the mark and the first supplied operand. The upper operand specifies the maximum number of bytes the pixel array of a single cached character may occupy, as determined from the information pre- sented by the operator. This is the same parameter set by setcachedevice setcachelimit . The lower operand specifies the threshold at which characters may be stored in compressed form rather than as full pixel arrays. If a character’s pixel array requires more than lower bytes to represent, it may be compressed in the cache and reconstituted from the compressed representation each time it is needed. Some devices do not support compression of characters. Setting lower to zero forces all characters to be compressed, permitting more characters to be stored in the cache, but increasing the work required to print disables compression them. Setting lower to a value greater than or equal to upper altogether. The operand specifies the new size of the font cache in bytes (the bmax value size cachestatus size returned by is not specified, the font cache size is ). If unchanged. If lies outside the range of font cache sizes permitted by the size implementation, the nearest permissible size is substituted with no error indica- tion. Reducing the font cache size can cause some existing cached characters to be discarded, increasing execution time when those characters are next shown. The parameters set by setcacheparams are the same as the MaxFontCache sys- tem parameter and the and MaxFontItem user parameters, set MinFontCompress by setsystemparams and setuserparams , respectively (see Appendix C). Errors: rangecheck, typecheck, unmatchedmark See Also: currentcacheparams, setcachelimit, setsystemparams, setuserparams 8.2 Operator Details 495

504 PLRM 2nd Edition Operators January 26, 1994 setcharwidth w – w setcharwidth y x is similar to setcachedevice , but it passes only width information to the Post- Script interpreter’s font machinery and it declares that the character being defined is not to be placed in the font cache. is useful, for example, in defining characters that incorporate two setcharwidth or more specific opaque colors, such as opaque black and opaque white. This is unusual. Most characters have no inherent color, but are painted with the cur- rent color within the character’s outline, leaving the area outside unpainted (transparent). Another use of setcharwidth is in defining characters that intentionally change their behavior based on the environment in which they execute. Such characters must not be cached, because that would subvert the intended variable behavior. stackunderflow, typecheck, undefined Errors: See Also: setcachedevice, setcachedevice2 LEVEL 2 setcmykcolor setcmykcolor – cyan magenta yellow black sets the color space to DeviceCMYK , then sets the current color parameter in the graphics state to a color described by the parameters cyan , magenta , yellow , and black , each of which must be a number in the range 0.0 to 1.0. This establishes the color subsequently used to paint shapes, such as lines, areas, and characters on the current page (see section 4.8.2, “Device Color Spaces”). Color values set by setcmykcolor are not affected by the black generation and undercolor removal operations. setcmykcolor does not give an error for a value outside the range 0 to 1. It substi- tutes the nearest legal value. Execution of this operator is not permitted in certain circumstances; see section 4.8, “Color Spaces.” Errors: stackunderflow, typecheck, undefined See Also: setcolorspace, setcolor, currentcmykcolor 496 Chapter 8: Operators

505 PLRM 2nd Edition Operators January 26, 1994 LEVEL 2 ... comp – comp setcolor comp setcolor n 1 2 sets the current color parameter in the graphics state to that described by the color components comp in the current color space (see section , comp ..., comp 2 1 n 4.8, “Color Spaces”). The number of color components and the valid range of color component values depends on the current color space. If the wrong number of components is spec- ified, an error will occur, such as stackunderflow or typecheck . If a component value is outside the valid range, the nearest valid value will be substituted with- out error indication. The initial value of the color parameter varies by color space. It is initialized by the setcolorspace operator. Execution of thi