[comp.windows.x] Fixes to xps

weening@Gang-of-Four.Stanford.EDU (Joe Weening) (09/21/89)

Here are a few fixes to the "xps" program (a Postscript previewer for
X11) that was posted to comp.sources.unix and is also available on
expo.lcs.mit.edu for anonymous ftp in the "contrib" directory.

I'm not completely sure these fixes are the best ones, so please
followup to this message if you see a better way.  Here is an
explanation of the problems that are fixed.

1. In stroke.c, the function LineSegment() could call atan2(0.0,0.0),
which is meaningless and causes an error on some systems.  I have it
check for this case and return 0.0 instead of calling atan2.

2. In X11.c, the program seems to expect that black = 1 and white = 0
on the display.  There is a comment by the author that "it's OK on
Suns" but this isn't a help for those of us who have the colors
reversed.  (Note that the comment gets them backwards but the meaning
is clear.)  I think I've fixed this below, but perhaps not in the most
elegant way.

What causes the problem is that the program uses some boolean
operations (such as AND and OR), whose effect depends on whether black
and white are 0 and 1 or vice versa.  E.g., if the background is white
and black is 1, then an OR of a black pixel and the background will be
black, while if black is 0, the result of the OR will be white.

As far as I can see, a program that wants to use boolean functions
must decide which ones to use based on the numerical values of the
black and white pixels.  This seems ugly to me.  Does X11 have a less
machine-dependent way of doing this?

3. The program doesn't have a real event loop; it calls XNextEvent
just once to get the initial expose event.  This doesn't work when
using twm because of the window manager's reparenting of the window,
so I stuck in a sleep(1) to wait for this.  (An ugly kludge; is there
a better way?)

Here are the diffs:


diff -c2 stroke.c.old stroke.c
*** stroke.c.old	Sat Oct 22 16:35:31 1988
--- stroke.c	Wed Sep 20 13:32:46 1989
***************
*** 316,321 ****
  float LineSegment (p, new, ehere, enow, width, last_angle, last_type) Path p, new; Point ehere, enow; float width, last_angle; enum pelem_type last_type;
   {
!  	float angle = atan2 (enow.y - ehere.y, enow.x - ehere.x),
!  		length = sqrt ((enow.y - ehere.y) * (enow.y - ehere.y) + (enow.x - ehere.x) * (enow.x - ehere.x));
  	Matrix old;
  	
--- 316,323 ----
  float LineSegment (p, new, ehere, enow, width, last_angle, last_type) Path p, new; Point ehere, enow; float width, last_angle; enum pelem_type last_type;
   {
! 	float dy = enow.y - ehere.y,
! 		dx = enow.x - ehere.x,
! 		angle = (dx == 0.0 && dy == 0.0) ? 0.0 : atan2 (dy, dx),
! 		length = sqrt (dy * dy + dx * dx);
  	Matrix old;
  	
diff -c2 X11.c.old X11.c
*** X11.c.old	Tue Jul  4 01:00:08 1989
--- X11.c	Wed Sep 20 13:39:24 1989
***************
*** 122,125 ****
--- 122,132 ----
      XGCValues values;
      int i;
+     /* The program expects black = 1, white = 0.  This is the array of
+        boolean functions to use if they are reversed. */
+     static char inv_rop[16] = {
+       ROP_TRUE, ROP_OR, ROP_ORNOT, ROP_SOURCE,
+       ROP_NOTOR, ROP_DEST, ROP_NXOR, ROP_AND,
+       ROP_NAND, ROP_XOR, ROP_NOTDEST, ROP_ANDNOT,
+       ROP_NOTSOURCE, ROP_NOTAND, ROP_NOR, ROP_FALSE };
      if ((dpy = XOpenDisplay(dpy)) == NULL)
  	Punt("Could not open display");
***************
*** 127,136 ****
      /* This defines our screen as being 11 inches high, no matter what its */
      /* real size.  What a hack. */
!     values.foreground = AllPlanes;
      for (i=0 ; i<16 ; i++) {
! 	values.function = i;
  	fillgc[i] = XCreateGC(dpy, RootWindow(dpy, SCREEN),
! 			      GCFunction | GCForeground, &values);
      }
  }
  /*
--- 134,146 ----
      /* This defines our screen as being 11 inches high, no matter what its */
      /* real size.  What a hack. */
!     values.foreground = BlackPixel(dpy, SCREEN);
!     values.background = WhitePixel(dpy, SCREEN);
      for (i=0 ; i<16 ; i++) {
! 	values.function = (values.background == 0) ? i : inv_rop[i];
  	fillgc[i] = XCreateGC(dpy, RootWindow(dpy, SCREEN),
! 			      GCFunction | GCForeground | GCBackground,
! 			      &values);
      }
+     return NULL;
  }
  /*
***************
*** 218,221 ****
--- 228,234 ----
      XSelectInput(dpy, hard->w, ExposureMask);
      XMapWindow(dpy, hard->w);
+     /* Give the window manager time to reparent and reexpose our window.  */
+     XFlush(dpy);
+     sleep(1);
      XNextEvent(dpy, &event);
      XSelectInput(dpy, hard->w, 0);
***************
*** 606,610 ****
  void HardUpdate ()
  {
!     XFlush(dpy, 0);
  }
  /*
--- 619,623 ----
  void HardUpdate ()
  {
!     XFlush(dpy);
  }
  /*
Joe Weening                                Computer Science Dept.
weening@Gang-of-Four.Stanford.EDU          Stanford University

root@cca.ucsf.edu (Systems Staff) (09/23/89)

 In article <11869@polya.Stanford.EDU>,
 weening@Gang-of-Four.Stanford.EDU (Joe Weening) writes:
 > Here are a few fixes to the "xps" program (a Postscript previewer
 > for X11) that was posted to comp.sources.unix and is also available
 > on expo.lcs.mit.edu for anonymous ftp in the "contrib" directory.
 > ...
 > Joe Weening                                Computer Science Dept.
 > weening@Gang-of-Four.Stanford.EDU          Stanford University

For those of you who were as mystified as I was by the reference to
"xps" being posted to comp.sources.unix here is the answer.

Volume 12 of comp.sources.unix contains a program (in 18 parts) by
Crispin Goswell. A supplementary posting was forwarded by Goswell to
the moderator of comp.sources.unix who posted it in

     comp.sources.bugs (!?)

under the title

     X11 Driver for Postscript interpreter.

The program in this posting was called "xps".

Thanks to Joe Weening and Rich Salz who helped resolve this.

For anyone who wishes to obtain all this you can get it by anonymous
FTP from ccb.ucsf.edu [128.218.1.13].

The original posting is in the subdirectory:

     ~ftp/Sources/Volume12/postscript

and the patches and additions are in the subdirectory:

     ~ftp/Sources/Notes/Postscipt


 Thos Sumner       Internet: thos@cca.ucsf.edu
 (The I.G.)        UUCP: ...ucbvax!ucsfcgl!cca.ucsf!thos
                   BITNET:  thos@ucsfcca

 U.S. Mail:  Thos Sumner, Computer Center, Rm U-76, UCSF
             San Francisco, CA 94143-0704 USA

I hear nothing in life is certain but death and taxes --  and  they're
working on death.

#include <disclaimer.std>