rokicki@Neon.Stanford.EDU (Tomas G. Rokicki) (01/09/90)
Thanks, Brian, for your comments; I agree. And now for something completely different. The structuring conventions separate a document into four sections (for the purpose of this discussion): prolog, setup, pages, and trailer. A lot of programs rearrange pages to do 2-up and the like by assuming the state between pages is the same as the state before the prolog. I claim this is incorrect, and indeed these programs should look at not the original state, or the state between pages, but the changes between the two (there is a matrix divide in PostScript, right?) to perform there magic. Consider the following program. ... %%EndProlog %%BeginSetup 2 2 scale %%EndSetup %%Page 1 ... gsave showpage grestore %%Page 2 ... gsave showpage grestore %%Trailer The graphics state at the beginning is completely unknown (this file, or a subset, might be included and scaled, rotated, etc.) The setup can completely alter the state, and gsave/grestore can be used to maintain that state across page boundaries. Thus, a program that attempts to 2-up this document cannot simply redefine the `showpage' operator, as there could be any number of (including zero) gsave/grestore pairs around showpage. Rather, the 2-up program needs to store away the initial state somewhere. Then, after setup, it needs to divide the new state by the initial state, and save this information away for its later use. Each `transformation' it wants to make must then be divided by this new matrix we created before it is applied. Why do I bring all this up? With the large number of PostScript clones, previewers, and manipulators being released, issues such as these must be clearly stated and carefully dealt with. Most PostScript previewers and manipulators make completely invalid assumptions that cause problems with correctly-written PostScript. Comments? -tom
amanda@mermaid.intercon.com (Amanda Walker) (01/09/90)
In article <1990Jan8.195614.27489@Neon.Stanford.EDU>, rokicki@Neon.Stanford.EDU (Tomas G. Rokicki) writes: > A lot of programs rearrange pages to do 2-up and the like > by assuming the state between pages is the same as the state before > the prolog. I claim this is incorrect, and indeed these programs > should look at not the original state, or the state between pages, > but the changes between the two (there is a matrix divide in PostScript, > right?) to perform there magic. I'd agree, almost. In particular, I believe that the document setup should be considered to be effectively part of the prolog (at least, as far as the state at the beginning of the page is concerned), since by its nature it does things that affect the global state (paper size, etc.). However, it is also very much a part of the Document Structuring Conventions that there can be *no* persistent state from page to page. Each page should be thought of as sitting inside a save/restore pair. > Consider the following program. > > ... > %%EndProlog > %%BeginSetup > 2 2 scale > %%EndSetup > %%Page 1 > ... gsave showpage grestore > %%Page 2 > ... gsave showpage grestore > %%Trailer The '...'s are evil :-) if they change the global graphics state at all. > Thus, a program that attempts to 2-up this document cannot simply > redefine the `showpage' operator, as there could be any number of > (including zero) gsave/grestore pairs around showpage. Rather, > the 2-up program needs to store away the initial state somewhere. > Then, after setup, it needs to divide the new state by the initial > state, and save this information away for its later use. Each > `transformation' it wants to make must then be divided by this > new matrix we created before it is applied. Well, inclusion of multi-page documents is a problem. Aside from that, however, how about doing a 'save' after the setup, and a 'restore save' before each page? That way, any transformations the new showpage does are automatically added to the ones that the setup did. I have in fact used this very technique: I have a version of "showpage" that prints two-up with cut and fols marks. The setup code tests to see if 11x17 paper is available, and if not it translates, rotates, and scales so that you get both pages (somewhat reduced) on a landscape-oriented letter size page. The 'showpage' doesn't care, since all of its transformations are additive. Ordering of setup code does become a problem, however, unless each program that manipulates the PostScript file also produces a completely conforming file as output (which I think should indeed happen). Not always easy, though... Amanda Walker InterCon Systems Corporation --
woody@rpp386.cactus.org (Woodrow Baker) (01/09/90)
In article <1990Jan8.195614.27489@Neon.Stanford.EDU>, rokicki@Neon.Stanford.EDU (Tomas G. Rokicki) writes: > I claim this is incorrect, and indeed these programs > should look at not the original state, or the state between pages, > but the changes between the two...... I would agree with this, but the state is fairly complex, and not easily gotten to. > > the 2-up program needs to store away the initial state somewhere. > Then, after setup, it needs to divide the new state by the initial > state, and save this information away for its later use. Each > `transformation' it wants to make must then be divided by this > new matrix we created before it is applied. The gsave /grestore context saves a lot more that just the CTM. It also saves the current path, positions, etc,etc. There is no composite "state" object that one could assign. It would be really handy to have one. It should be added, and gsave should place a composite object somewhere that you could then define a variable to contain. It, however cannot be "divided". Only the matrix can be divided. It makes little sense to think about dividing the path..... cheers Woody
amanda@mermaid.intercon.com (Amanda Walker) (01/10/90)
I'm usually not too annoyed at the strict stack behavior of gsave & grestore, but among the things that I would love to see in some future version of PostScript is the path as a first class data type. In most of the cases that I end up using gsave & grestore, it's to get around the fact that I can't save a path away in a variable and then bring it back later to stroke or fill it. This is one of the things that I love about Metafont, that PostScript does clumsily at best, and I really feel this lack when trying to describe complex glyphs in a font. It would also be very useful for doing step-and-repeat work for things that aren't straightforward linear tilings. For some tilings (i.e. those that parallelogram-shaped tiles), you can get by pretty well by defining a font of tiles, much the way Adobe Illustrator does pattern fills. However, for anything less text-like, the only approach seems to be to build an exectuable array with pathforall and execute it later. Unless of course you want to draw strings as part of the tile... Even if path objects were occasionally opaque in the same ways the current path is (such as when character outlines are in the path), they'd still be very useful. Tough to implement, though, especially without a better storage allocator (the old persistent variable-size data structure problem again). Amanda Walker Speaker To PostScript InterCon Systems Corporation --
gelphman@adobe.COM (David Gelphman) (01/10/90)
In article <1699@intercon.com> amanda@mermaid.intercon.com (Amanda Walker) writes: >I'm usually not too annoyed at the strict stack behavior of gsave & grestore, >but among the things that I would love to see in some future version of >PostScript is the path as a first class data type. In most of the cases that ... Two things in the PostScript language extensions contained in the Display PostScript system help this particular situation. One is the user path facility. Basically a user path is a procedure which contains pure path construction (with optional caching) and can be passed directly to operators like 'ustroke' and 'ufill' to stroke and fill a user path. You can keep these objects around like normal procedure bodies and repeatedly fill and/or stroke them. A second facility is the gstate object. These are essentially an object which is equivalent to the PostScript graphics state that can be used to arbitrarily switch between graphics states (without concern about the graphics state stack). It could be used to recover an already constructed path had you saved away the gstate. Clearly the user path machinery is more likely what you want since the graphics state contains more state than what you wish to recover. These facilities are documented in the document "Extensions for the Display PostScript System", available as part of a package from Adobe of documentation on the Display PostScript system. >Amanda Walker David Gelphman Adobe Systems Incorporated
amanda@mermaid.intercon.com (Amanda Walker) (01/10/90)
In article <1596@adobe.UUCP>, gelphman@adobe.COM (David Gelphman) writes: > Basically a user path is a procedure which contains > pure path construction (with optional caching) and can be passed directly > to operators like 'ustroke' and 'ufill' to stroke and fill a user path. > You can keep these objects around like normal procedure bodies and repeatedly > fill and/or stroke them. Now, this is what I was hoping to hear :-). Any plans to retrofit this into "hardcopy PostScript"? I like the caching part particularly. Looks like it's time for to read up on Display PostScript. Now if only I could buy it for a Macintosh :-)... Amanda Walker InterCon Systems Corporation --
gelphman@adobe.COM (David Gelphman) (01/11/90)
In article <1708@intercon.com> amanda@mermaid.intercon.com (Amanda Walker) writes: >In article <1596@adobe.UUCP>, gelphman@adobe.COM (David Gelphman) writes: >> Basically a user path is a procedure which contains > >Now, this is what I was hoping to hear :-). Any plans to retrofit this >into "hardcopy PostScript"? I like the caching part particularly. Looks >like it's time for to read up on Display PostScript. >Now if only I could buy it for a Macintosh :-)... >Amanda Walker The extensions in the Display PostScript system are part of the language as it is evolving. When we introduced the Display PostScript system it was made clear that extensions which are appropriate for printers would be incorporated into printers in the future. I can't comment further. David Gelphman Adobe Systems Incorporated