gsnup.ps has a few bugs I'll just put in one report because they are simple. 1. cdef needs one more pop when 'where' returns true (currently the name that was to be cdef'd is left on the stack in that case). 2. for some devices, e.g. pdfwrite, BeginPage and EndPage are not present in currentpagedevice unless they have been set, and gsnup fails /undefined in get setting .BP and .EP if either one is not present. While one could view that as a pdfwrite problem and say all devices should have default values for BeginPage/EndPage in place, it would also be easy to make gsnup.ps behave gracefully if they are not there. 3. EndPage returns false for device deactivation in all cases. It should return false only if the page number is 0 mod .Nx .Ny, or an incomplete n-up page will be discarded at device deact. 4. The {currentfile cvx exec .EOJ} business makes it very inconvenient to run gsnup.ps from inside another script. As long as EndPage is right, no EOJ business should be needed at all, at least in 8.31 or later, which I believe has been fixed to do device deact when gs exits. 5. The scale computation (simply divide by max of .Nx .Ny) is only suitable for arranging several regions with the same aspect and orientation as the medium; for common uses like portrait pages 2-up on a landscape sheet, it will make the images too small. 6. gsnup blows the execution stack if used under -dDELAYBIND. Its restore procedure needs to take pains to refer to the previous restore, and not fall into recursion.
I couldn't remember what made me think the 'no 2 EndPage on normal exit' problem was fixed in 8.31, as I don't have 8.31 to test, but I must have seen the fix in imain.c r1.38, and that r1.39 was tagged for 8.31. I've added a dependency on the (presumably resolved) bug #687557, just to help keep the facts together.
To avoid working with an old version, I'd like to comment that the current release is 8.51 and as soon as we have one 'show stopper' bugs fixed we will be releasing 8.52. The src/imain.c file is now at 1.41. Any work on 8.31 version stuff is obsolete, but I suspect that the gsnup.ps bugs are still present. I am making this bug bountiable since the submitter has shown a good understanding of PostScript and willingness to work on bountiable bugs in the hope that this will be fixed (by someone). Note, the bounty will be for fixes to the CVS HEAD rev (8.52), not for 8.31 fixes.
I am having some second thoughts, about whether simply fixing these bugs in gsnup.ps would be the best use of effort. These 6 would not be that hard to blindly fix and get a usable gsnup (ok, no. 5 would be a bit harder, because it points out that the scale computation can't quite be automated without knowing more about what the user intends, so some additional UI would be needed in the form of another command-line parameter or so). But there's another issue I think is more serious: There's been only one substantive change to gsnup since 'populate cvs with 6.0 files', and that's this recent one: > The BeginPage called the previous BeginPage (stored in .BP) at the wrong > time, /BeginPage { - .BP .Nx .Ny .max + .Nx .Ny .max gsave initclip clippath pathbbox exch 4 -1 roll sub 3 1 roll exch sub grestore @@ -70,12 +70,17 @@ translate % Stack: nmax 1 exch div dup scale + .BP } Through 8.51, gsnup executed BeginPage procs in order oldest through most recently stacked. This change in 8.52 reverses that order; the question of which order is right or wrong is an example of debating which of two implementations is right when there isn't a defined requirement. The real issue is that Adobe defined BeginPage and EndPage without any design for stacking them, and gsnup is trying to implement a rudimentary stacking convention of its own, but it doesn't go nearly far enough. The question of what order to call the handlers in is only the tip of the design iceberg: how should arguments and return values transform as they propagate up and down the stack? What page number is passed to the next handler on the stack? Under what conditions should the next handler be called or the recursion terminated? Most of that gsnup does not address at all. Because Adobe specified none of that, the question is not which choices are right or wrong, but which choices lead to a design that can be demonstrated to facilitate doing nontrivial and interesting things with nested page handlers. I think (yes, it is a shameless plug) that the design of PageNest has been so demonstrated; it is documented; and the choices leading to the design involved a fair bit of thought. I suspect that anyone who works hard enough at giving gsnup a reasonably complete and credible convention for handler stacking will end up essentially reinventing PageNest--similarly but not quite compatibly, and that does nobody any good. I wrote PageNest because I did not see that anyone had seriously tackled the need already, and I put an unrestricted use/redistribution license on it to save others having to tackle it again. If it came to me to suggest what should be done with gsnup, I would propose replacing it with a simple wrapper that maintained gsnup's command-line parameter UI as a simplified interface to the capabilities of PageNest. The wrinkle, of course, is I would rather not assign copyright in PageNest itself. It is done in pure PostScript, not GS-specific, and I want it to be as widely available as possible. I would have no objection to its being redistributed--that's the whole idea--but I want its use and distribution to remain unrestricted, not to be sucked under AFPL or GPL. Any gsnup wrapper, on the other hand, would be assigned, naturally. Reactions? Comments? Suggestions? http://www.anastigmatix.net/postscript/PageNest.html
This also affects an Artifex customer
PageNest ProcSet cannot be bundled with Ghostscript because of a non-free license. Poor users are not permitted to fix bugs and the author doesn't promise to do it either. % Copyright Chapman Flack, www.anastigmatix.net. May be freely used and % distributed without modification provided this notice remains intact. % Provided ... AS-IS WITHOUT ANY EXPRESS OR IMPLIED WARRANTY ... This ProcSet would be a valuable addition to Free software and could be installed with Ghostscript on most GNU+Linux boxes if it is re-released under GPL or any GPL-compatible license.
Ray please consult with contributor about the status of this. Thanks.
Created attachment 5239 [details] b688318af1.patch I happened to have a chance to look at this and made a possible and partial fix. 1. Fixed with added functionality. 'cdef' now checks predefined object type and make sure it is a same type as provided object. Plus, now gsnup uses its private dictionary (gsnupdict), it always defines key value pair in current dictionary. 2. Fixed. To deal with this issue, there is a new procedure named 'kdef'. And I changed names: '.BP' and '.EP' are now 'BeginPage' and 'EndPage' in private dictionary. 3. Fixed. If reason code is 2 and there are already processed (sub-)pages, it returns true. Plus, EndPage now chains its call to original EndPage every time before processing itself. 4. '.EOJ' procedure is removed. 6. Fixed. gsnup now preserves original 'restore' in private dictionary and calls it. I have not touched #5. I think this is an enhancement rather than a problem and it needs deeper consideration to design. In theory, this version should be compatible with previous ones. However, by changing the place of parameters ('.Nx', '.Ny', and '.Landscape') from userdict to private dictionary, if a program modifies those parameters during its execution, it will not work anymore. If you know such a program in a field, please let me know.
This patch still doesn't work. gs -sDEVICE=ppmraw -o x-%d.ppm lib/gsnup.ps examples/tiger.eps examples/tiger.eps examples/tiger.eps produces 3 pages, not 1 as expected, and the 'tiger' on each page is in the upper left, not placed properly. Also the entire page is filled with light gray, not just the area of the sub-page. The results from: gs -dLastPage=4 -sDEVICE=ppmraw -o x-%d.ppm lib/gsnup.ps examples/annots.pdf produces 4 ppm files, each blank.
Gsnup.ps has many limitations by its nature. Basic idea is to employ BeginPage/EndPage, so if a job replaces one or both of these, it will not work. For example, a print job generated using HP's PPD files may contain original EndPage definition, and in that case it does not work with gsnup.ps. Gsnup.ps do not directly work with PDF/EPS files. Because Ghostscript's special way to treat those file types conflicts with BeginPage/EndPage. And, I don't think there is much BeginPage/EndPage can do about it. However, there are workaround for these. To gsnup PDF files, you can: (cat lib/gsnup.ps; pdf2ps examples/annots.pdf -) | gs -sDEVICE=ppmraw -o x-%d.ppm - And, to gsnup EPS files, you can: cat lib/gsnup.ps examples/golfer.eps examples/golfer.eps examples/golfer.eps | gs - sDEVICE=ppmraw -o x-%d.ppm - (Well, tiger.eps still has a problem from clippath, see below.) Gsnup.ps does not clip current subpages to its subpage area. This is a limitation inherited from previous versions. I agree gsnup should clip its subpages, but this is not the only problem regarding to subpage positioning as original reporter described in issue #5. And I intentionally left untouched #5 this time. Because it lacks clipping subpages, a job employs clippath most likely not to work correctly. For files in examples folder, snowflak.ps, tiger.eps, vasarely.ps and waterefal.ps uses clippath and do not work with gsnup.ps. There is also a possible Ghostscript problem when switching paper sizes between subpages, which I am working on to open a new bug about it.
Regarding BeginPage & EndPage. If you also override the definition of setpagedevice you can search the dictionary argument to see if it contains either/both of these keys and if it does you can concatenate the procedures. Though whether that will work correctly is debatable, it depends on the content of the procedures.
Created attachment 5254 [details] gsnup2.png For what Ken said, I will think twice about pros and cons of setpagedevice redifinition. About a problem I mentioned in #9, I posted a new bug 690667. I will look further what I can do regarding gsnup.ps and PDF (sometime later). Attached image is what I would expect when it said 'n-up'. Just for record.
Created attachment 5255 [details] gsnup2.ps And this is a PS file I used to create gsnup2.png. This is not finished. This is not compatible with gsnup.ps. It is just for record. $ cat gsnup2.ps examples/tiger.eps examples/tiger.eps examples/tiger.eps | bin/gs -sDEVICE=png16m -o gsnup2.png -
Enhancement still missing in Ghostscript 9.03
Alex can you review this ancient bug and see if any of it is still relevant?
Its unclear to me whether we should care about this, does anyone actually use gsnup ? So, I'm going to ask for opinions, particularly from Chapman Flack and Masaki Ushizaka, who are probably the only people who have any kind of clue what this is about. Is there any real purpose in changing psnup now ? If I don't hear anything in a week or so I'll close this as wontfix.
No replies, so closing as wontfix, as threatened.