abair@oakhill.UUCP (Alan Bair) (07/11/88)
In article <113@kl-cs.cs.kl.ac.uk>, jonathan@cs.keele.ac.uk (Jonathan Knight) writes: > Does anyone have a Postscript Previewer for suntools? There > is an old old copy of ups hanging around here but it expired > last year (its version 0.2). If anyone has a more up to > date version or a better tool could they mail me with info please. > .... I am also looking for a Postscript previewer, either suntools or X11. They have been on the net before, but I have been unable to locate one at any of the UUCP or archive sites I know about. Any pointers would be greatly appreciated. Alan Bair SPS CAD Austin, Texas Motorola, Inc. UUCP cs.utexas.edu!oakhill!turbinia!abair
dana@dino.bellcore.com (Dana A. Chee) (07/13/88)
Yes, there is a postscript previewer called postscript which runs under X10 and X11. It is available from the comp.sources.unix archives as volume 12 issues 50 through 67 (18 files in all). This can be obtained from your favorite archive site (j.cc.purdue.edu or uunet.uu.net for ftp people). Below is the patch file to make those sources (which come for X10) run under X11. Hope this helps. ==================== X11 patches ==================== #!/bin/sh # # This is the source for my X11 interface to the postscript previewer. # This source did get posted, but not to comp.sources.unix; it ended up # in (I believe) comp.sources.bugs. Anyway, here it is, along with the # makefile I use (which you'll probably have to modify somewhat). # # - Terry Weissman weissman@decwrl.dec.com ...!decwrl!weissman # # # to extract, remove the header and type "sh filename" if `test ! -s ./X11.c` then echo "writing ./X11.c" cat > ./X11.c << '\Rogue\Monster\' /* * Copyright (C) Rutherford Appleton Laboratory 1987 * * This source may be copied, distributed, altered or used, but not sold for profit * or incorporated into a product except under licence from the author. * It is not in the public domain. * This notice should remain in the source unaltered, and any changes to the source * made by persons other than the author should be marked as such. * * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd */ #include "main.h" #include "graphics.h" #include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> #include "canon.h" static void Punt(str) char *str; { fprintf(stderr, "%s\n", str); exit(1); } static Display *dpy; typedef struct _HardwareRec { Drawable w; } HardwareRec, *Hardware; #ifdef CANON struct hardware { /* * Each driver is expected to provide its own definition of this * structure. It is only ever used as a pointer and is never dereferenced * outside the driver. */ int pad; }; #endif CANON /* * This file describes the interface that PostScript requires to the graphics * system at Version 1.4. * * ''Hardware'' in this context refers to a pointer to windows and/or bitmaps * and is the lowest level of access that PostScript is interested in. Any * Hardware parameter may be expected to be NULL. */ /********************* CREATION OF WINDOWS AND BITMAPS *******************/ #define SCREEN 0 /* What to use as our screen number. */ #define MIN(x, y) (((x) < (y)) ? (x) : (y)) static GC fillgc[16]; struct hardware *InitHardware () { XGCValues values; int i; if ((dpy = XOpenDisplay(dpy)) == NULL) Punt("Could not open display"); InitTransfer(DisplayHeight(dpy, SCREEN) / 11); /* 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); } } /* * InitHardware () returns a default device which PostScript may use * immediately (or NULL if not appropriate). Its size and shape are not * defined. Most typically the user will want to start up another device * before it is used anyway. No attempt will be made by PostScript to Destroy * the resulting device. */ static struct hardware *NewHardware(width, height) int width, height; { struct hardware *to; Hardware hard; to = (struct hardware *) malloc(sizeof(struct hardware)); hard = (Hardware) malloc(sizeof(HardwareRec)); to->hard.addr = (char *) hard; to->flags = 0; to->aux = to->clip = NULL; to->extent = NewDevicePoint(width, height); hard->w = NULL; return to; } struct hardware *NewBitmapHardware (width, height) int width, height; { struct hardware *to = NewHardware(width, height); Hardware hard = (Hardware) to->hard.addr; to->flags = NULL; hard->w = XCreatePixmap(dpy, RootWindow(dpy, SCREEN), width, height, DefaultDepth(dpy, SCREEN)); XFillRectangle(dpy, hard->w, fillgc[GXclear], 0, 0, width, height); /* { static int y = 0; XSetWindowAttributes attributes; hard->w = XCreateSimpleWindow(dpy, RootWindow(dpy, SCREEN), 700, y, width, height, 1, BlackPixel(dpy, SCREEN), WhitePixel(dpy, SCREEN)); attributes.override_redirect = TRUE; XChangeWindowAttributes(dpy, hard->w, CWOverrideRedirect, &attributes); XMapWindow(dpy, hard->w); y+=30; }*/ return to; } struct hardware *NewWindowHardware (width, height) int width, height; { struct hardware *to = NewHardware(width, height); Hardware hard = (Hardware) to->hard.addr; XEvent event; to->flags = ISWIN; hard->w = XCreateSimpleWindow(dpy, RootWindow(dpy, SCREEN), 0, 0, width, height, 1, BlackPixel(dpy, SCREEN), 0); XSelectInput(dpy, hard->w, ExposureMask); XMapWindow(dpy, hard->w); XNextEvent(dpy, &event); XSelectInput(dpy, hard->w, 0); return to; } /* * NewBitmapHardware () is expected to create a new bitmap. Only one plane * will be needed. * * NewWindowHardware () is expected to create a window on the screen. On a * colour system this will be expected to support full colour. */ #ifdef CANON int IsWindowHardware (h) struct hardware *h; {} #endif CANON /* * IsWindowHardware () should return TRUE if the hardware is a window, FALSE * otherwise. NULL is a window. */ void DestroyHardware (h) struct hardware *h; { if (h) { Hardware hard = (Hardware) h->hard.addr; if (IsWindowHardware(h)) XDestroyWindow(dpy, hard->w); else XFreePixmap(dpy, hard->w); } } /* * * DestroyHardware () should release the resources required by the hardware, * bitmap or window. This should cause a window device to vanish. NULL is not * an error (does nothing). */ #ifdef CANON Matrix DeviceMatrix (width, height) int width, height; {} #endif CANON /* * * DeviceMatrix () should return a matrix appropriate to a device of the given * height and width. For a typical display with a graphics origin at the top * left of a window, an appropriate definition would be: * * Matrix DeviceMatrix (width, height) * int width, height; * { * return NewMatrix (PIXELS_PER_INCH / 72.0, 0.0, 0.0, * -PIXELS_PER_INCH / 72.0, 0.0, (float) height); * } */ #ifdef CANON DevicePoint HardwareExtent (h) struct hardware *h; {} #endif /* * HardwareExtent () returns a DevicePoint describing the width and height of * the argument. NULL has extent NewDevicePoint (0, 0). */ /*************************** OUTPUT PRIMITIVES ******************************/ void BitBlt (from, to, fromPoint, toPoint, extent, rop) struct hardware *from, *to; DevicePoint toPoint, fromPoint, extent; int rop; { Hardware fromhard, tohard; static int count = 0; if (to == NULL) return; tohard = (Hardware) to->hard.addr; if (from == NULL) { XFillRectangle(dpy, tohard->w, fillgc[rop], toPoint.dx, toPoint.dy, extent.dx, extent.dy); } else { fromhard = (Hardware) from->hard.addr; XCopyArea(dpy, fromhard->w, tohard->w, fillgc[rop], fromPoint.dx, fromPoint.dy, extent.dx, extent.dy, toPoint.dx, toPoint.dy); } if (count++ % 50 == 0) XSync(dpy, 0); } #ifdef CANON void Paint (from, to, fromPoint, toPoint, extent, colour) struct hardware *from, *to; DevicePoint toPoint, fromPoint, extent; Colour colour; {} #endif /* * * BitBlt () is a full function RasterOp. The 'rop' argument will have values * as described in the header file hard.h. If the from argument is NULL it is * taken to be a bitmap full of ones the shape of the fromPoint and extent. If * the to argument is NULL, this is a no-op. * * Paint () is an addition to BitBlt. Bits that are set in the source are * Painted into the destination in the given colour with a copying rasterop so * that they replace pixels previously there. If the machine does not support * colour windows, half-toning should be performed. Colour values have hue, * saturation and brightness components. on a black and white or greyscale * system the brightness value will be a FP value between 0.0 (black) and 1.1 * (white), which can be used as a grey level. * * Paint is expected to mask with the clip mask. BitBlt is not, */ #ifdef CANON void BitBltTrapezoid(to, lefttop, leftbottom, righttop, rightbottom, top, bottom, rop) struct hardware *to; DevicePoint lefttop, leftbottom, righttop, rightbottom; int top, bottom, rop; {} #endif CANON #ifdef CANON void PaintTrapezoid (to, lefttop, leftbottom, righttop, rightbottom, top, bottom, colour) struct hardware *to; DevicePoint lefttop, leftbottom, righttop, rightbottom; int top, bottom; Colour colour; {} #endif CANON /* * BitBltTrapezoid () and PaintTrapezoid () render a complete trapezoidal * shape. The corners of the trapezoid may lie far outside the range of * interesting scan-lines, but the slope of the line should be clipped by the * top and bottom. The coordinates are half-open. */ void BitBltLine (h, fromPoint, toPoint, rop) struct hardware *h; DevicePoint fromPoint, toPoint; int rop; { if (h) { Hardware hard = (Hardware) h->hard.addr; XDrawLine(dpy, hard->w, fillgc[rop], fromPoint.dx, fromPoint.dy, toPoint.dx, toPoint.dy); } } #ifdef CANON void PaintLine (h, fromPoint, toPoint, colour) struct hardware *h; DevicePoint fromPoint, toPoint; Colour colour; {} #endif CANON /* * * BitBltLine () is expected to draw a line between the given points * with the given RasterOp and colour masking. * The line should be one pixel wide and half-open. * [Thicker lines are done with BitBlt.] * * PaintLine () is expected to Paint a line by analogy with Paint * and BitBlt. */ void BitBltBlob (to, top, height, left, right, rop) struct hardware *to; int top, height, *left, *right, rop; { int i; DevicePoint p1, p2; for (i=0 ; i<height ; i++) { p1.dx = left[i]; p2.dx = right[i]; p1.dy = p2.dy = top + i; BitBltLine(to, p1, p2, rop); } } /* * BitBltBlob () takes a set of pixel coordinates and fills the trapezon * figure half open. */ #ifdef SLOWANDWRONG void RasterTile (from, to, toPoint, extent, rop) struct hardware *from, *to; DevicePoint toPoint, extent; int rop; { Hardware fromhard, tohard; DevicePoint p1, p2, p3; int x, y; if (to == NULL) return; if (from == NULL) Punt("Can only RasterTile from Hardware."); fromhard = (Hardware) from->hard.addr; tohard = (Hardware) to->hard.addr; p1.dx = p1.dy = 0; for (x=toPoint.dx ; x < toPoint.dx + extent.dx ; x+=from->extent.dx) { for (y=toPoint.dy ; y < toPoint.dy + extent.dy ; y+=from->extent.dy) { p2.dx = x; p2.dy = y; p3.dx = MIN(toPoint.dx + extent.dx - x, from->extent.dx); p3.dy = MIN(toPoint.dy + extent.dy - y, from->extent.dy); BitBlt(from, to, p1, p2, p3, rop); } } } #endif SLOWANDWRONG void RasterTile (from, to, toPoint, extent, rop) struct hardware *from, *to; DevicePoint toPoint, extent; int rop; { Hardware fromhard, tohard; static GC gc = NULL; XGCValues values; int valuemask; if (to == NULL) return; if (from == NULL || IsWindowHardware(from)) Punt("Can only RasterTile from Bitmap."); fromhard = (Hardware) from->hard.addr; tohard = (Hardware) to->hard.addr; values.tile = fromhard->w; values.fill_style = FillTiled; values.function = rop; valuemask = GCFunction | GCTile | GCFillStyle; if (gc == NULL) gc = XCreateGC(dpy, RootWindow(dpy, SCREEN), valuemask, &values); else XChangeGC(dpy, gc, valuemask, &values); XFillRectangle(dpy, tohard->w, gc, toPoint.dx, toPoint.dy, extent.dx, extent.dy); } /* * RasterTile () replicates the whole of ``from'' over ``to'', but clipped by * the rectangle bounded by ``toPoint'' and ``extent''. */ /******************* BRIGHTNESS TRANSFER FUNCTION ************************/ #ifdef CANON int TransferSize () {} #endif CANON #ifdef CANON void SetTransfer (vec) float *vec; {} #endif CANON /* * * TransferSize () and SetTransfer () control the mapping function between * user brightnesses and device brightnesses. The interface is expected to * perform this mapping of brightnesses to a sufficient resolution. * SetTransfer takes a table of floating point numbers between 0 and 1. User * brightnesses are scaled to the size of this table and mapped through it. * The argument table given to SetTransfer () will be deleted after use. * TransferSize () simply enquires the required size of the table. * * It may be appropriate to half-tone on a grayscale or colour device to * improve rendering if it is not too expensive. TransferSize () returns the * size of the pattern table. */ /********************** BITMAP CONVERSION ********************************/ char *StringFromHardware (h) struct hardware *h; { XImage *image; Hardware hard; unsigned char *result, *ptr, c; int x, y, i; if (h == NULL) return NULL; hard = (Hardware) h->hard.addr; image = XGetImage(dpy, hard->w, 0, 0, h->extent.dx, h->extent.dy, AllPlanes, ZPixmap); result = (unsigned char *) malloc(((h->extent.dx + 7) / 8) * h->extent.dy); ptr = result; for (y=0 ; y<h->extent.dy ; y++) { for (x=0 ; x<h->extent.dx ; x+=8) { c = 0; for (i=0 ; i<8 ; i++) { c = c << 1; if (x+i < h->extent.dx) c |= XGetPixel(image, x+i, y); } } *ptr++ = c; } free((char *) image); return (char *) result; } struct hardware *HardwareFromString (s, width, height) char *s; int width, height; { struct hardware *h = NewBitmapHardware(width, height); Hardware hard = (Hardware) h->hard.addr; XImage *image; if (s == NULL) Punt("HardwareFromString called with NULL string!"); image = XCreateImage(dpy, DefaultVisual(dpy, SCREEN), DefaultDepth(dpy, SCREEN), ZPixmap, 0, s, width, height, 8, 0); image->bitmap_bit_order = MSBFirst; XPutImage(dpy, hard->w, fillgc[GXcopy], image, 0, 0, 0, 0, width, height); free((char *) image); return h; } /* * * StringFromHardware () produces a string from its argument which describes * the bitmap. The bitmap is returned in row-major order with the leftmost * bit of each byte in the most significant position. Rows are padded to byte * boundaries. Only single plane bitmaps are used. * * HardwareFromString () performs the inverse mapping, generating a bitmap * from a set of bits, given a width and height. Only single plane bitmaps are * used. */ /************************* HALF-TONE SCREEN *******************************/ #ifdef CANON int ScreenSize (freq, rotation) float freq, rotation; {} #endif CANON #ifdef CANON void BuildScreen (freq, rotation, x, y) float freq, rotation, *x, *y; {} #endif CANON #ifdef CANON void SetScreen (freq, rotation, thresh) float freq, rotation, *thresh; {} #endif CANON /* * ScreenSize () allows PostScript to determine how large an array of sample * points to expect. It should return the length of the side of the sample * square. * * BuildScreen () returns a set of sampling coordinates to PostScript to hand * to the users spot-function * * SetScreen () allows PostScript to set the thresholds for each sample point * so that half-tone bitmaps can be made. */ /************************* CLIPPING ******************************************/ #ifdef CANON void SetClipHardware (h, clip) struct hardware *h, *clip; {} #endif /* * * SetClipHardware sets hardware which is a clip mask for BitBlt. This mask * should be ANDed with any output operation. If clip is NULL, masking will * not be needed. */ /************************ UPDATE CONTROLS **********************************/ void HardUpdate () { XFlush(dpy, 0); } /* * HardUpdate is a hook to allow devices which do output buffering to flush * that buffering when appropriate. This allows an interactive user to see * completed graphics between prompts (it is called as a side-effect of the * PostScript flush operator). Typically is is a no-op. */ void UpdateControl (h, on) struct hardware *h; int on; {} /* * This call can be used to enable batching of output operations. * UpdateControl (h, FALSE) means ``start of batching'' UpdateControl (h, * TRUE) means ``end of batching''. It is used to improve performance on * machines where screen updates have a high locking overhead. It may be a * no-op. The operation should nest if batching is already in progress: FALSE * increments a counter, TRUE decrements a counter. Display changes are * allowed when the counter is non-zero. */ /********************************** CANONICAL IMPLEMENTATION LIBRARY ******************************/ /* * Some parts of the above interface can be supported by a canonical library. * This library contains: SetClipHardware HardUpdate IsWindowHardware HardwareExtent PaintTrapezoid BitBltTrapezoid Paint PaintLine DeviceMatrix InitTransfer TransferSize SetTransfer ScreenSize BuildScreen SetScreen * * As the driver matures, the user may provide his own versions of the * canonical routines. This leaves the following for implementation by * the user. * InitHardware NewBitmapHardware NewWindowHardware DestroyHardware HardwareFromString StringFromHardware UpdateControl RasterTile BitBlt BitBltLine BitBltBlob * There is a pedagogical implementation in null.c * * There are a number of interface issues concerning the canonical driver. * Firstly, a canonical struct hardware is defined, which contains a union of * a char * and an int handle. The remainder are expected to use this to store * device specific information. * * InitTransfer() should be called during InitHardware with the number of * pixels per inch on the display as an argument. */ \Rogue\Monster\ else echo "will not over write ./X11.c" fi if `test ! -s ./makefile` then echo "writing ./makefile" cat > ./makefile << '\Rogue\Monster\' OBJECTS=array.o boolean.o config.o control.o dictionary.o file.o\ integer.o main.o math.o misc.o name.o operator.o\ poly.o property.o real.o save.o stack.o string.o unix.o LIBS=libww.a -lsuntool -lsunwindow -lpixrect -g GRAPHICS=cache.o colour.o device.o fill.o font.o gsave.o image.o mat.o matrix.o\ pat.o path.o state.o stroke.o CFLAGS=-g -DX11 XLIB= /usr/src/X11/lib/X/libX11.a XLIBINCLUDES = -I/usr/src/X11/X11 -I/usr/src/X11 xps: $(OBJECTS) $(GRAPHICS) X11.o canon.a $(XLIB) makefile rm -f xps cc -o xps $(OBJECTS) $(GRAPHICS) X11.o canon.a -lm $(XLIB) OLDXLIB= /usr/src/x11/Xlib/libX11.a OLDXLIBINCLUDES = -I/usr/src/X11/X11 -I/usr/src/X11 xps.old: $(OBJECTS) $(GRAPHICS) X11.o canon.a $(OLDXLIB) makefile rm -f xps.old cc -o xps.old $(OBJECTS) $(GRAPHICS) X11.o canon.a -lm $(OLDXLIB) X11.o: X11.c cc -c $(CFLAGS) $(XLIBINCLUDES) X11.c PS: $(OBJECTS) $(GRAPHICS) hard.o canon.a cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm `libs` -o PS sunPS: $(OBJECTS) $(GRAPHICS) hard.o canon.a pixrect cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) hard.o canon.a -lm -lpixrect -o sunPS CPS: $(OBJECTS) $(GRAPHICS) colour-ww.o trapezoid.o canon.o cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) colour-ww.o canon.o trapezoid.o -lm `libs` -o CPS postscript: $(OBJECTS) $(GRAPHICS) adapter.o protocol.o cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) adapter.o protocol.o -lm -o postscript XPS: $(OBJECTS) $(GRAPHICS) X.o cc $(CFLAGS) $(OBJECTS) $(GRAPHICS) X.o -lm libX.a -o XPS canon.a: canon.o screen.o trapezoid.o paint.o ar ruv canon.a canon.o screen.o trapezoid.o paint.o ranlib canon.a viewer: protocol.o viewer.o hard.o canon.a cc protocol.o viewer.o hard.o canon.a `libs` -o viewer all: PS postscript viewer ww: ww.o wwlib installww pixrect: pixrect.o cp pixrect.o hard.o sun: ww wwsun orion: orion.o installorion orionlib X.o: cc -c X.c wwlib: if [ -f libww.a ]; \ then \ echo 'echo libww.a' >lww; \ else \ echo 'echo -lww' >lww; \ fi; \ chmod +x lww echo "echo `lww`" >libs; chmod +x libs wwsun: echo "echo `lww` -lsuntool -lsunwindow -lpixrect" >libs; chmod +x libs orionlib: echo 'echo -lG' >libs; chmod +x libs installww: cp ww.o hard.o installorion: cp orion.o hard.o \Rogue\Monster\ else echo "will not over write ./makefile" fi echo "Finished archive 1 of 1" exit -- +*************************************************************************+ * Dana Chee (201) 829-4488 * * Bellcore * * Room 2Q-250 * * 445 South Street ARPA: dana@bellcore.com * * Morristown, NJ 07960-1910 UUCP: {gateways}!bellcore!dana * +*************************************************************************+
leen@uva.UUCP (Leen Torenvliet) (07/14/88)
BTW does anyone know if a postscript previewer for Macintosh exists. I've been looking around for one for quite some time now but to no avail. I'd be grateful for any pointers. Thanks, Leen -- Dr L. Torenvliet Phone: +31 20 525 6065 EMAIL: leen@uva.uucp (...!mcvax!uva!leen) SNAIL: Dept. of Math. and Computer Science, University of Amsterdam, Nieuwe Achtergracht 166, 1018 WV Amsterdam, The Netherlands