Bug 688318 - Several bugs in gsnup
Summary: Several bugs in gsnup
Status: RESOLVED WONTFIX
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: General (show other bugs)
Version: master
Hardware: All All
: P3 enhancement
Assignee: Ken Sharp
URL:
Keywords: bountiable
Depends on: 687557
Blocks:
  Show dependency tree
 
Reported: 2005-10-01 16:55 UTC by Chapman Flack
Modified: 2013-06-19 11:07 UTC (History)
2 users (show)

See Also:
Customer:
Word Size: ---


Attachments
b688318af1.patch (4.37 KB, patch)
2009-07-24 03:34 UTC, Masaki Ushizaka
Details | Diff
gsnup2.png (24.49 KB, image/png)
2009-07-30 06:38 UTC, Masaki Ushizaka
Details
gsnup2.ps (3.46 KB, application/postscript)
2009-07-30 06:41 UTC, Masaki Ushizaka
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chapman Flack 2005-10-01 16:55:34 UTC
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.
Comment 1 Chapman Flack 2005-10-03 08:48:37 UTC
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.
Comment 2 Ray Johnston 2005-10-03 10:01:04 UTC
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.
Comment 3 Chapman Flack 2005-10-13 15:31:17 UTC
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
Comment 4 Ray Johnston 2007-11-06 16:50:29 UTC
This also affects an Artifex customer
Comment 5 Alex Cherepanov 2007-11-11 05:41:56 UTC
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.
Comment 6 Henry Stiles 2008-12-09 09:21:21 UTC
Ray please consult with contributor about the status of this.  Thanks.
Comment 7 Masaki Ushizaka 2009-07-24 03:34:24 UTC
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.
Comment 8 Ray Johnston 2009-07-24 08:28:49 UTC
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.

Comment 9 Masaki Ushizaka 2009-07-27 06:52:28 UTC
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.
Comment 10 Ken Sharp 2009-07-27 07:05:16 UTC
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.

Comment 11 Masaki Ushizaka 2009-07-30 06:38:18 UTC
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.
Comment 12 Masaki Ushizaka 2009-07-30 06:41:19 UTC
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 -
Comment 13 Shailesh Mistry 2011-07-16 11:52:34 UTC
Enhancement still missing in Ghostscript 9.03
Comment 14 Henry Stiles 2012-09-26 18:19:27 UTC
Alex can you review this ancient bug and see if any of it is still relevant?
Comment 15 Ken Sharp 2013-06-12 08:08:37 UTC
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.
Comment 16 Ken Sharp 2013-06-19 11:07:17 UTC
No replies, so closing as wontfix, as threatened.