According to the American Heritage Dictionary, an idiom is "an expression that... cannot be understood from the individual meanings of its elements." A secondary definition is "a style... characteristic of a given individual, school, period, or medium." It is with this secondary meaning in mind that we'll explore the PostScript Level 3 "Idiom Recognition" mechanism.
In any programming language, a procedure is meant to be reusable. The process of converting inline code into a procedure, then, is to remove all variables from the inline code, leaving only static values and operators behind. The variables will then be passed into the procedure.
Consider the following PostScript code to draw a rectangle:
0 0 moveto 288 0 rlineto 0 72 rlineto -288 0 rlineto closepath stroke
If one wanted to write a generic "drawRect" procedure, all the variables must be taken out. One approach would be to write a procedure that took 4 arguments on the stack: the "x" and "y" starting coordinates, the height, and the width. Thus the procedure could draw any rectangle at any position on the page.
/drawRect
{
4 2 roll moveto
exch dup 0 rlineto 0 3 -1 roll
rlineto neg 0 rlineto closepath
stroke
} bind def
There are no variables in the procedure; the numbers are for stack manipulation. The above code is the "canonical" way to draw a rectangle in PostScript Level 2. In terms of an "idiom", it is a procedure that is characteristic of the PostScript Level 2 "period".
PostScript Level 3 introduced the "rectstroke" operator. That operator could nicely replace our entire drawRect procedure. It takes the same arguments, in the same order. In other words, it's a new "idiom" for the same function. What's needed is a way to replace the old procedure with the new operator. PostScript Level 3 also introduced Idiom Recognition for precisely that reason.
PostScript Level 3 introduced a new resource type - the "IdiomSet". As with all resources, you'll pass in a dictionary and a name into the defineresource operator. The dictionary contains the procedure you'd like to replace, the new procedure, and some other structure. The name is /IdiomSet.
Let's examine the following code to define an IdiomSet that will replace our old drawRect procedure with the newer more efficient "rectstroke" operator:
<< /IdiomRecognition false >> setuserparams
/RectSet
<<
/XYZ
[
{
4 2 roll moveto
exch dup 0 rlineto 0 3 -1 roll
rlineto neg 0 rlineto closepath
stroke
} bind
{ rectstroke } bind
]
>> /IdiomSet defineresource pop
<< /IdiomRecognition true >> setuserparams
First, we turn Idiom Recognition off. This is controlled by the /IdiomRecognition user parameter. We turn it off because we don't want it interfering with the procedure bodies in our new IdiomSet.
Next comes a name, which you can make anything you like, and a dictionary.
The dictionary contains an arbitrary name, and an array as a value. The array contains two procedure bodies: the old and the new. The name truly is arbitrary. You can use anything you like; you don't have to give it the same name as the original procedure. It's the contents of the procedure itself that matter.
Then we define the resource, and lastly we turn Idiom Recognition back on.
When does the procedure actually get replaced? When you "bind" your procedures. Consider the following code:
%!PS
serverdict begin 0 exitserver
<< /IdiomRecognition false >> setuserparams
/RectSet
<<
/XYZ
[
{
4 2 roll moveto
exch dup 0 rlineto 0 3 -1 roll
rlineto neg 0 rlineto closepath
stroke
} bind
{ rectfill } bind
]
>> /IdiomSet defineresource pop
<< /IdiomRecognition true >> setuserparams
/drawRect
{
4 2 roll moveto
exch dup 0 rlineto 0 3 -1 roll
rlineto neg 0 rlineto closepath
stroke
} bind def
0 0 72 288 drawRect
showpage
When you "bind" the drawRect procedure, bind will search the IdiomSet resources for the procedure body. If it finds a match, it will replace it with the new procedure, and then bind that. In essence, it swaps out the procedure body so that drawRect now defines { rectstroke } instead.
If you don't believe me, try it yourself. In fact, change "rectstroke" in the Idiom Dictionary to "rectfill". Even though your drawRect procedure contains a stroke, you'll end up with a filled rectangle instead, because of Idiom Recognition.
Idiom Recognition is most often used by devices to "update" driver-produced PostScript. PostScript Level 3 also introduced smooth shading dictionaries, which give much better performance than older "gradient" techniques. When a RIP sees a gradient, it can replace it with a smooth shading dictionary.
However, Idiom Recognition can be extremely powerful for user-written PostScript. I often have to work with client PostScript files. One technique I use is operator redefinition, to store and act on certain positions or strings. That doesn't work with procedures, because the last procedure defined becomes the current active version of that procedure. However, with Idiom Recognition, I can substitute my own version of a particular procedure.
I'd be interested in hearing how others are using Idiom Recognition. If you have a unique use, or would like to discuss this article or ask questions, please post on the T. Greer PrintForum.
Thomas D. Greer has years of experience in the printing business. He held the position of Director of Development for Consolidated Graphics, where he wrote the COIN eCommerce platform. Prior to that he was Vice-President of Technology of a large printing company acquired by Consolidated Graphics, where he was responsible for the development of a completely custom-written plant management system still in use.
Today Thomas provides consulting, development, implementation, and training services to commercial printers. He can be reached on the web at www.tgreer.com.
Did this article help you out? If you'd like to show your appreciation, consider a PayPal Donation.
Or, perhaps you'd like to read some other technical articles I've written?
If you'd like to discuss this article, or make suggestions for future articles, join my free discussion forum.
My logo was designed by Rus Anderson, a skilled graphic artist with a wealth of experience in user interface and web design. I told Rus I wanted something simple and clean, that conveyed my expertise in document automation technologies. I also wanted an association with PostScript and PDF. I'm very pleased with the result. The "document icon" has become ubiquitous. It's obvious, when viewing the logo, that I'm involved in document production and automation. The red color is associated with Adobe, PostScript, and PDF. Overall, the effect is clean and memorable. Thanks, Rus!