Subject: Things I found while trying to make psview work

From: [email-masked] (John Gilmore)
Date: Wed, 1 Jul 87 20:57:37 EDT

Date: Mon, 22 Jun 87 16:26:51 PDT
From: [email-masked] (John Gilmore)
Subject: Things I found while trying to make psview work
To: [email-masked]

I haven't yet hit a PostScript file that psview would work for,
and typically the error message was useless (e.g. it would say
that some word was undefined, but never say what the word was!).

By a long learning process I figured out some of what is going on.
Here are some notes I made during the process.  By the way, I did
not fix psview; I manually modified its output file (/tmp/psview*)
to make it work, more or less
  Trying to fix the general case is
a whole nother ball game.

* There seems to be no documentation on the NeWS process model.
The words (e.g. "fork") are documented, but little else.  E.g. how
can I write a "ps" for NeWS, that will list all the processes and
what they are doing?

* The hokey implementation of "save" and "restore" does not save the
graphics state.  This caused a "nocurrentpath" bug in the troff
output I was displaying.  I circumvented it by redefining:

systemdict begin
/save { gsave 1 } def
/restore { pop grestore } def
end

This is not perfect but it worked for my case.

* There seems to be no portable method to get from a "window" to its
"canvases".  Apparantly you are just supposed to put all your display
writing into the PaintClient proc of the window and it apparantly defaults
to "the right canvas".  I have noticed little turds lying around
in the supplied files that say

%	ClientCanvas setcanvas

so I tried it (minus the %) and it seems to work.  But it doesn't
look very "object oriented".

* The "retained" attribute of a canvas would be assumed by the uninitiated
to mean the same thing as the "retained" attribute of SunView or SunWindows
windows; that is, a copy of the bitmap is saved at all times so that
the user's code is never called upon to repaint the screen due to damage
(except if the window size is changed).  Unfortunately it seems that
the retained attribute in NeWS just means that in case you draw on part
of a canvas that happens at that moment to be obscured, it will save those
pixels for you.  If you draw on something that is visible, but which becomes
later obscured, NeWS does not save the pixels.  I consider this a lose
both in performance and in the model.

* The debugging facilities are primitive in the extreme, and very badly
documented.  There seems to be a way to tell what a process was doing
when it errored, but I can't find it.  When printing the stack, it can
display you a whole function, but can't tell you the function's name.
It can't even tell you the undefined name that caused the interpreter
to stop.  Also, I can't even tell which process got the error; e.g.
when psview errors, and there is a psh running a debugger, somehow the
psview PROCESS stops, but the psview WINDOW still handles input events
and such.  And the process that was claimed to stop seems not to be in
a breakpoint wait, but an input_wait.  Also, I have blown away the
debugger by simply printing a large function (such as the PaintProc
generated by psview when run on a file containing a readhexstring).
This apparantly blew the stack of the debugger, which is for some
reason limited to 1500 bytes, according to the "Implementation Limits"
section.  There also seems to be a way to patch something but the
documentation says "Patch the implicit process".  Nothing more.  While
it's a good idea to discourage patching, you'd do better by simply not
documenting it rather than claiming it exists but not telling us what
it does or how it does it.  If the manual had a sample debug session it
would help a lot.  I suggest a run of "why doesn't psview display my
text which prints fine on the LaserWriter" debugging as the first
example.

* definefont is unimplemented, and the Ditroff to PostScript converter
that produced my output was trying to define a font to match the ditroff
symbol font, by pulling characters out of the PostScript fonts.  This
had to be circumvented.  If real font support is going to be a long
time coming, at least implement creating new fonts out of pieces of old
ones.

Now on to psview problems.

* It tries to encapsulate the PostScript it is trying to display into a
function.  This does not work for many common cases, such as the use of
readhexstring, which is the only half-reasonable way to print a bitmap;
such code must be executed as it is encountered, rather than saved up
and run later, since some of the input is intended for the PostScript
interpreter and other parts are input for the PostScript program itself
-- and these are intermixed in a way reminiscent of old IBM 360
assembler programs' instructions and data.  This bodes ill for
PostScript as a structured language, since there seems to be no good
way around mashing your instructions and input data together, and
no good way to automatically take such a program and restructure it
cleanly.

* On the other hand, if psview doesn't put its input into a function,
there is no way to re-execute it if the window gets damaged or
stretched.  This probably calls for having an active process on the
other end, which can take requests from the PostScript code to feed it
"page N again" or whatever.

* The psview output never calls 'pause', so it locks up the NeWS
server while it runs.  (Actually this should be fixed by providing
preemptive scheduling.)

* It ignores the PostScript document structuring conventions, so it
encapsulates the prologue, all the pages, and the epilogue into a
single document.  These should be separated, and it should be possible
to display multiple-page documents if they follow the structuring
conventions.

Has anybody written a decent previewer for PostScript output under NeWS?