PostScript
PostScript (or PS) is a page description language used primarily in the
electronic and desktop publishing areas.
History
The concepts of the PostScript language were seeded in 1976 when John
Warnock was working at Evans and Sutherland, a famous computer graphics
company. At that time John Gaffney was developing an interpreter for a large
three-dimensonal graphics database of New York harbour. Gaffney conceived
the Design System language to process the graphics, very similar to the
Forth programming language.
In 1978 Evans and Sutherland asked Warnock to move from the San Francisco
bay area to their main headquarters in Utah, but he was not interested in
moving. He then joined Xerox PARC to work with Martin Newell. They rewrote
Design System to create JaM (John and Martin) which was used for VLSI design
and the investigation of type and graphics printing. This work later evolved
into an expanded system known as Interpress.
After watching Xerox sit on Interpress, as they had with many of their other
technologies, Warnock left with Chuck Geschke and founded Adobe Systems in
December 1982. They started selling a simpler version of Interpress as
PostScript, which went on the market in 1985. At about this time they were
visited by Steve Jobs, who urged them to adapt PostScript to be used as the
language for driving laser printers, which was added to a Canon printing
engine to create the LaserWriter.
In March of 1985, the Apple LaserWriter was the first printer to ship with
PostScript, sparking the desktop publishing (DTP) revolution in the
mid-1980s. The combination of technical merits and widespread availability
made PostScript a language of choice for graphical output for printing
applications. For a time an interpreter for this language was an ubiquitous
component of laser printers, into the 1990s.
Once the de facto standard for electronic distribution of final documents,
PostScript has effectively been succeeded by PDF in this area. By 2001 there
were fewer printer models which came with support for PostScript, largely as
a result of the increasing power of the built-in printing systems supplied
with most operating systems.
Usage in Printing
Traditional Printing
Prior to the introduction of PostScript, printers were designed to print
character output given the text—typically in ASCII—as input.
There were a number of technologies for this task, but most shared the
property that the characters were physically difficult to change, as they
were stamped onto typewriter keys, bands of metal, or optical plates.
This changed to some degree with the increasing popularity of dot matrix
printers. The characters on these systems were "drawn" as a series of dots,
the proper dots to use defined as a font table inside the printer. As they
grew in sophistication, dot matrix printers started including several
built-in fonts from which the user could select, and some models allowed the
user to download their own custom character graphics into the printer.
Dot matrix printers also introduced the ability to print raster graphics.
The graphics were interpreted by the computer and sent as a series of dots
to the printer using a series of escape sequences. These printer control
languages varied from printer to printer, requiring program authors to
create numerous drivers.
"Real" graphics printing was left to special-purpose devices, called
plotters. Plotters did share a common command language, HPGL, but were of
limited use for anything other than printing graphics. In addition, they
tended to be expensive and slow, and thus rare.
PostScript Printing
PostScript broke tradition by combining the best features of both printers
and plotters. Like plotters, PostScript offered a high quality line art and
a single control language that could be used across any brand of printer.
Like dot-matrix printers, PostScript offered simple ways to generate pages
of text and raster graphics. Unlike either, PostScript could place all of
these types of media on a single page, which offered far more flexibility
than any printer or plotter previously had.
PostScript went beyond the typical printer control language, and was a
complete programming language of its own. Many applications can transform a
document into a PostScript program whose execution will result in the
original document. This program can be sent to an interpreter in a printer,
which results in a printed document, or to one inside another application,
which will display the document on-screen. Since the document-program is the
same regardless of its destination, it is called device-independent.
PostScript is also noteworthy for implementing on-the fly rasterisation;
everything, even text, is specified in terms of straight lines and Bˇzier
curves (previously found only in CAD applications), which allows arbitrary
scaling, rotating and other transformations. When the PostScript program is
interpreted, the interpreter converts these instructions into the dots
needed to form the output.
Font Handling
Almost as complex as PostScript itself was PS's handling of fonts. The rich
font system used the PS graphics primitives to draw characters as line art,
which could then be rendered at any resolution. This might sound like a
reasonably straightforward concept, but there are a number of typographic
issues that had to be considered.
One is that fonts do not actually scale linearly at small sizes; features of
the characters will become proportionally too large or small and they start
to "look wrong". PostScript avoided this problem with the inclusion of hints
which could be saved along with the font outlines. Basically they are
additional information in horizontal or vertical bands that help identify
the features in each letter that are important for the rasterizer to
maintain. The result was significantly better-looking fonts even at low
resolution; it was formerly believed that hand-tuned bitmap fonts were
required for this task.
At the time the technology for including these hints in fonts was carefully
guarded, and the hinted fonts were compressed and encrypted into what Adobe
called a Type 1 Font. Type 1 was effectively a simplification of the PS
system to store outline information only, as opposed to being a complete
language (PDF is similar in this regard). Adobe would then sell licenses to
the Type 1 technology at a very high cost to those wanting to add hints to
their own fonts. Those who were happy without hints, or didn't want to spend
the money, were left with the so-called Type 3 Font. Type 3 fonts allowed
for all the sophistication of the PostScript language, but without the
standardized approach to hinting. Other differences further added to the
confusion.
The cost of the licensing was considered by many to be too high, and Adobe
continued to stonewall on more attractive rates. It was this issue that led
Apple and Microsoft to collaborate on their own system, TrueType, around
1991. Immediately following the announcement of TrueType, Adobe published
the specification for Type 1 fonts. Retail tools such as Altsys Fontographer
(now owned by Macromedia) added the ability to create Type 1 fonts. Since
then, many free Type 1 fonts have been released; for instance, the fonts
used with the TeX typesetting system are available in this format.
In the early 1990s there were several other systems for storing
outline-based fonts, developed by Bitstream and Metafont for instance, but
none included a general-purpose printing solution and they were therefore
not widely used as a result.
Other Implementations
Adobe derived most of their licensing fees from their implementation of
PostScript for printers, known as a Raster Image Processor or RIP. These
were fairly expensive, and typically ran on a limited selection of hardware.
With the introduction of a number of RISC-based platforms in the mid 1980s,
Adobe always seemed to be a step behind in supporting the new machines.
Third-party implementations of PostScript interpreters became quite common
as a result. These tended to be found either in low-cost laser printers, or
in high-end typesetting equipment. Some of these third-party solutions are
still widely used in the typesetting world, particularly the one developed
by Phoenix Systems that is standard in all black-and-white Hewlett-Packard
laser printers (as of 2003).
However, many printers don't support any RIP in their basic versions. For
these, a free PostScript interpreter called Ghostscript is available. It
prints PostScript documents on non-PostScript printers using the CPU of the
host computer to do the rasterization, sending the result as a single large
bitmap to the printer. It can also be used to preview PostScript documents
on a computer monitor.
Usage as a Display System
With PostScript becoming a de-facto standard for printed output, it was
natural to consider using the same language for describing the screen output
as well. The rapid increase in CPU power in the late 1980s, combined with an
interest in windowing systems, led to several attempts to create a display
system that used PostScript as its primary display technology.
There are a number of advantages to using PS as the display system. One is
that the fonts on other systems required the user to keep not only bitmaps
for the screen, but also Type 1 for the printer. Using PS on the display
would eliminate this and require only one set. Another advantage is that it
allows for the "dumbing down" of printers. When the LaserWriter was released
it was the most powerful (and expensive) machine in Apple's lineup, a result
of needing considerable processing power and memory to render the page at a
"high" resolution of 300 dpi in a reasonable amount of time. In contrast,
the 400-dpi printer that shipped with the NeXT platform contained no CPU at
all, instead using the computer's CPU to do the rendering and passing off
the rendered page as a bitmap to the printer.
But the main advantage in using PostScript as a windowing system is that it
allows one to write desktop publishing (DTP) and other graphically-intensive
applications with a single set of graphics routines. The same code that is
drawing to the window can be used to draw to the printer without any
translation. DTP applications on traditional systems require the programmer
to construct the GUI editor in the platform's own graphics system (for
example, QuickDraw on the Macintosh, or GDI on Microsoft Windows) and then
write additional code to translate the graphics into proper PostScript for
printing. This often takes up the majority of the programming effort on such
projects and is a major source of bugs.
The two main examples of PostScript as a display technology are Display
PostScript (DPS) and NeWS. They differed dramatically in terms of where the
display logic was applied; in DPS the view system was left to the hosting
OS, whereas under NeWS the entire display was written in PS and ran in a
single complex interpreter. While certainly very interesting, it's not clear
that NeWS is in fact a better approach.
The Language
PostScript is a full-fledged programming language. Typically, PostScript
programs are not produced by humans, but by other programs. However, it is
perfectly possible to produce graphics or to perform calculations by
hand-crafting PostScript programs.
PostScript is an interpreted, stack-based language similar to Forth. The
language syntax uses Reverse Polish Notation, which makes parentheses
unnecessary, but reading a program requires some practice, because one has
to keep the layout of the stack in mind. Most operators (what other
languages term functions) take their arguments from the stack, and place
their results onto the stack. Literals (for example numbers) have the effect
of placing a copy of themselves on the stack.
Example:
3 4 add 5 1 sub mul
will compute (3 + 4) * (5 - 1).
A look at what happens in detail:
3 and 4 are both literals, so will push themselves onto the stack. So after
these two instructions, the stack will look like this:
4
3
add is an operand, taking the two top-most elements from the stack (3 and 4
in our example), adds them together, and pushes the result onto the stack:
7
Next come two literals again, which will make the stack look like this (note
that action is usually constrained to the top of the stack, leaving lower
elements unchanged):
1
5
7
Another operand, sub, takes two elements from the top, subtracts the first
(higher one) from the second, and pushes the result onto the stack:
4
7
It should be obvious that mul works like the other operators, taking its two
arguments from the stack, and pushing their product:
28
But this did nothing more than an old RPN calculator. Of course, PostScript
has variables. In detail, it has a dictionary where everything that is not a
literal is looked up; on a match, the current value stored under the name is
pushed; mismatches will result in an error. To place something in the
dictionary one needs the def operator, which takes a name and a value as its
arguments. Names are constructed by prefixing (or quoting) with a slash. So
/x1 15 def
will first push the name "x1" on the stack, then the value 15, then execute
def which will take both from the stack, and write 15 into the dictionary
under the name "x1". Later occurrences of "x1" (not to be confused with
"/x1") will push 15 onto the stack as long as the variable is unchanged.
This code will increment the content of x1 by 2:
/x1 x1 2 add def
Some real programming language power is offered by { and }. The opening
brace puts the interpreter in deferred execution mode, so that everything is
just placed on the stack, even operators and other executable objects. The
one exception is the closing brace, which takes everything put on the stack
since the opening brace, bundles it up into an (anonymous) procedure, and
places that on the stack.
This construct is used in various ways, for subroutine definition (the
anonymous procedure is assigned to a variable), loops, conditionals, etc.
Example:
x1 0 eq { 0 } { 1 x1 div } ifelse
This code first uses the eq operator to test whether the value of x1 is
equal to 0; depending on the outcome eq will push true or false onto the
stack. After that, two procedures are pushed onto the stack. Then ifelse is
executed, which takes three arguments from the stack, and will execute
either the second (if the third is true) or first (if the third is false).
In summary, 0 results if x1 is 0, 1/x1 is the result for all other cases.
/inc3 { 3 add } def
Here def is used to place something in the dictionary, only this time it is
a procedure instead of a simple integer. This works because the values
coming from the dictionary are executed, not just pushed (as simplistically
stated above). Since executing a literal amounts to pushing it, that did not
make a difference before. Now executing "inc3" will first look it up in the
dictionary, find the procedure object representing "{ 3 add }" and execute
that. One value must reside on the stack for this to work, since add needs
two arguments, only one of which is given in the procedure itself.
Naturally, one passes arguments to procedures by placing them on the stack,
so we can simply view "inc3" as a procedure that takes one argument. Example
call:
71 inc3
will put 71 on the stack, which inc3 will increment by three, for a final
result of 74.
To produce graphics, PostScript uses an ordinary cartesian coordinate
system.
100 200 moveto 300 400 lineto stroke
moves the "cursor" to the point with coordinates (100, 200) and then draws a
line to the point (300, 400).
50 70 moveto 100 200 50 80 100 100 curve stroke
produces a Bˇzier curve from (50, 70) to (100, 100) with control points
(100, 200) and (50, 80).
250 250 moveto (Wikipedia) show
will create the text "Wikipedia" at coordinate location (250, 250), rendered
in the default font.
Graphics are initially produced in the "user coordinate system" and may then
optionally be rotated, scaled or skewed before being copied to the "device
coordinate system" specifying the final output.
200 300 translate 45 rotate
will translate the contents of the user coordinate system 200 points
upwards, 300 points to the right and rotate it 45 degrees before they are
copied to the device coordinate system.
The character "%" is used to introduce comments in PostScript programs. As a
general convention, every PostScript program should start with the
characters "%!" so that all devices will properly interpret it as PostScript.
This content from Wikipedia is licensed under the GNU Free Documentation License.
|
|