ek@PRINCETON.EDU (Eleftherios Koutsofios) (03/14/89)
I just finished getting ghostscript 1.2 to run under suntools. Here's file gdevsv.c, which can be used in place of gdevx.c, or gdevega*. (you also need to change gsmain.c to use 'sv_device' instead of x_device or whatever). Link with -lsuntool -lsunwindow -lpixrect. It was tested on a sun3/60 running SunOS 4.0.1 and on a 3/50 running SunOS 3.2. Since there's no documentation describing things like the bitmap format, or the exact semantics of arguments like 'one' and 'zero', I had to make assumptions about them, which could of course be wrong, so I would appreciate any feedback. In this version of the code, suntools events are handled only when the sv_sync function is called, which means that when gs is waiting for input from the user (ie. when the GS> prompt is displayed), the only way to get gs to respond to events (like resize, move, close, etc.) is to press a few <CR>'s. Lefteris Koutsofios (ek@princeton.edu) ---------------------- cut here ------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # gdevsv.c # This archive created: Mon Mar 13 16:02:41 1989 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'gdevsv.c' then echo shar: "will not over-write existing file 'gdevsv.c'" else cat << \SHAR_EOF > 'gdevsv.c' /* Copyright (C) 1989 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. This file is part of Ghostscript. Ghostscript is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the Ghostscript General Public License for full details. Everyone is granted permission to copy, modify and redistribute Ghostscript, but only under the conditions described in the Ghostscript General Public License. A copy of this license is supposed to have been given to you along with Ghostscript so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* gdevsv.c */ /* SunView driver for GhostScript library */ /* Written by Lefteris Koutsofios (ek@princeton.edu) 3/12/89 */ #include <suntool/sunview.h> #include <suntool/canvas.h> #include <stdio.h> #include <malloc.h> #include <math.h> /* defines uint and ushort.... */ # define uint _uint # define ushort _ushort #include "gx.h" /* for gx_bitmap; includes std.h */ # undef _uint # undef _ushort #include "gxdevice.h" /* Procedures */ int sv_open(P1(gx_device *)); int sv_close(P1(gx_device *)); int sv_map_rgb_color(P4(gx_device *, ushort, ushort, ushort)); int sv_map_color_rgb(P3(gx_device *, int, ushort *)); int sv_sync(P1(gx_device *)); int sv_fill_rectangle(P6(gx_device *, int, int, int, int, int)); int sv_tile_rectangle(P8(gx_device *, gx_bitmap *, int, int, int, int, int, int)); int sv_copy_mono(P10(gx_device *, byte *, int, int, int, int, int, int, int, int)); int sv_copy_color(P9(gx_device *, byte *, int, int, int, int, int, int, int)); int sv_draw_line(P6(gx_device *, int, int, int, int, int)); int sv_fill_trapezoid(P8(gx_device *, int, int, int, int, int, int, int)); /* The device descriptor */ static gx_device_procs sv_procs = { sv_open, sv_close, sv_map_rgb_color, sv_map_color_rgb, sv_sync, sv_fill_rectangle, sv_tile_rectangle, sv_copy_mono, sv_copy_color, sv_draw_line, sv_fill_trapezoid, gx_default_tile_trapezoid }; /* Define the SunView device */ typedef struct gx_device_SV_s { gx_device_common; Frame frame; Canvas canvas; Pixwin *pw; int depth; unsigned char red[256], green[256], blue[256]; } gx_device_SV; /* The instance is public. */ gx_device_SV sv_device = { sizeof(gx_device_SV), &sv_procs, 612, 792, /* x and y extent */ /* Following parameters are initialized for color */ 1, /* has color */ 255, /* max r-g-b value */ 8, /* bits per color pixel */ /* End of monochrome/color parameters */ 1, /* bit-big-endian (for now) */ }; /* Macro for casting gx_device argument */ #define svdev ((gx_device_SV *)dev) static struct pixrect *pr1, *pr2, *pr3, *pr4, *pr5; int sv_open (gx_device *dev) { int winW = svdev->width, winH = svdev->height; if (!(svdev->frame = window_create(NULL, FRAME, WIN_X, 0, WIN_Y, 0, FRAME_LABEL, "Ghostscript", 0))) { fprintf(stderr, "Cannot open frame\n"); exit(1); } if (!(svdev->canvas = window_create(svdev->frame, CANVAS, WIN_WIDTH, winW, WIN_HEIGHT, winH, CANVAS_RETAINED, TRUE, 0))) { fprintf(stderr, "Cannot open canvas\n"); exit(1); } svdev->pw = canvas_pixwin (svdev->canvas); svdev->depth = svdev->pw->pw_pixrect->pr_depth; if (svdev->depth == 1) { svdev->has_color = 0, svdev->max_rgb_value = 1; svdev->bits_per_color_pixel; } else setcmap (dev); window_fit (svdev->frame); window_set (svdev->frame, WIN_SHOW, TRUE, 0); if ((pr1 = mem_create (10, 10, 1)) == NULL || (pr2 = mem_create (10, 10, svdev->depth)) == NULL || (pr3 = mem_create (10, 10, 1)) == NULL || (pr4 = mem_create (10, 10, 1)) == NULL || (pr5 = mem_create (10, 10, svdev->depth)) == NULL) { fprintf (stderr, "Cannot allocate temporary pixrects\n"); exit (1); } notify_dispatch (); return 0; } #define INVGAMMA 0.4 #define COLORINT 51.0 #define COLORSEG1 6 #define COLORSEG2 36 static int igm[256]; /* setcmap installs a gamma corrected colormap */ /* However, when the calling function asks for information about a color, (from functions: sv_map_rgb_color and sv_map_color_rgb) we respond as if a non gamma corrected colormap was used. If this isn't done the calling function seems to get confused. */ setcmap (gx_device *dev) { int i, j, k, l; for (i = 0; i < 256; i++) { igm[i] = (int) (0.5 + 255 * pow (i / 255.0, INVGAMMA)); } for (i = 0; i < COLORSEG1; i++) for (j = 0; j < COLORSEG1; j++) for (k = 0; k < COLORSEG1; k++) { l = i * COLORSEG2 + j * COLORSEG1 + k; svdev->red[l] = igm[(int) (COLORINT * (COLORSEG1 - i - 1) + 0.5)]; svdev->green[l] = igm[(int) (COLORINT * (COLORSEG1 - j - 1) + 0.5)]; svdev->blue[l] = igm[(int) (COLORINT * (COLORSEG1 - k - 1) + 0.5)]; } pw_setcmsname (svdev->pw, "ghostscript"); pw_putcolormap (svdev->pw, 0, 256, svdev->red, svdev->green, svdev->blue); for (i = 0; i < COLORSEG1; i++) for (j = 0; j < COLORSEG1; j++) for (k = 0; k < COLORSEG1; k++) { l = i * COLORSEG2 + j * COLORSEG1 + k; svdev->red[l] = COLORINT * (COLORSEG1 - i - 1) + 0.5; svdev->green[l] = COLORINT * (COLORSEG1 - j - 1) + 0.5; svdev->blue[l] = COLORINT * (COLORSEG1 - k - 1) + 0.5; } } /* Close the device. */ int sv_close (gx_device *dev) { window_destroy (svdev->canvas); window_destroy (svdev->frame); return 0; } /* Map a color. The "device colors" are just r,g,b packed together. */ int sv_map_rgb_color (register gx_device *dev, ushort r, ushort g, ushort b) { int foo; if (svdev->has_color) { foo = ((COLORSEG1 - (int) (r / COLORINT) - 1) * COLORSEG2 + (COLORSEG1 - (int) (g / COLORINT) - 1) * COLORSEG1 + (COLORSEG1 - (int) (b / COLORINT) - 1)); } else { if ((.3 * b + .59 * r + .11 * g) >= .5) foo = 0; else foo = 1; } return foo; } /* Map a "device color" back to r-g-b. */ int sv_map_color_rgb (register gx_device *dev, int color, ushort *prgb) { if (svdev->has_color) { prgb[0] = svdev->red[color]; prgb[1] = svdev->green[color]; prgb[2] = svdev->blue[color]; } else { if (color == 1) prgb[0] = prgb[1] = prgb[2] = 0; else prgb[0] = prgb[1] = prgb[2] = 1; } } /* Synchronize the display with the commands already given */ int sv_sync (register gx_device *dev) { notify_dispatch (); return 0; } /* Fill a rectangle with a color. */ int sv_fill_rectangle (register gx_device *dev, int x, int y, int w, int h, int color) { pw_rop (svdev->pw, x, y, w, h, (color ? PIX_SRC | PIX_COLOR (color) : PIX_CLR), NULL, x, y); return 0; } /* Tile a rectangle. */ int sv_tile_rectangle (register gx_device *dev, gx_bitmap *tile, int x, int y, int w, int h, int zero, int one) { char *data; int w0, w1, i, j; w0 = (tile->width + 7) / 8; w1 = ((tile->width + 15) / 16) * 2; if (pr1->pr_size.x != tile->width || pr1->pr_size.y != tile->height) { pr_destroy (pr1); pr1 = mem_create (tile->width, tile->height, 1); } data = (char *) mpr_d(pr1)->md_image; for (j = 0; j < tile->height; j++) for (i = 0; i < w0; i++) *(data + j * w1 + i) = *(tile->data + w0 * j + i); if (pr2->pr_size.x != w || pr2->pr_size.y != h) { pr_destroy (pr2); pr2 = mem_create (w, h, svdev->depth); } else pr_rop (pr2, 0, 0, w, h, PIX_CLR, pr2, 0, 0); if (pr3->pr_size.x != w || pr3->pr_size.y != h) { pr_destroy (pr3); pr3 = mem_create (w, h, 1); } if (one != -1) { if (one) pr_replrop (pr2, 0, 0, w, h, PIX_SRC | PIX_COLOR (one), pr1, 0, 0); pr_replrop (pr3, 0, 0, w, h, PIX_SRC, pr1, 0, 0); pw_stencil (svdev->pw, x, y, w, h, PIX_SRC, pr3, 0, 0, pr2, 0, 0); } pr_rop (pr2, 0, 0, w, h, PIX_CLR, pr2, 0, 0); if (zero != -1) { pr_rop (pr1, 0, 0, tile->width, tile->height, PIX_NOT (PIX_SRC), pr1, 0, 0); if (zero) pr_replrop (pr2, 0, 0, w, h, PIX_SRC | PIX_COLOR (zero), pr1, 0, 0); pr_replrop (pr3, 0, 0, w, h, PIX_SRC, pr1, 0, 0); pw_stencil (svdev->pw, x, y, w, h, PIX_SRC, pr3, 0, 0, pr2, 0, 0); } return 0; } /* Copy a monochrome bitmap. */ int sv_copy_mono (register gx_device *dev, byte *base, int sourcex, int raster, int x, int y, int w, int h, int zero, int one) { char *data; int w0, w1, i, j; w0 = (w + 7) / 8; w1 = ((w + 15) / 16) * 2; if (pr4->pr_size.x != w || pr4->pr_size.y != h) { pr_destroy (pr4); pr4 = mem_create (w, h, 1); } data = (char *) mpr_d(pr4)->md_image; for (j = 0; j < h; j++) for (i = 0; i < w0; i++) *(data + j * w1 + i) = *(base + w0 * j + i); if (pr5->pr_size.x != w || pr5->pr_size.y != h) { pr_destroy (pr5); pr5 = mem_create (w, h, svdev->depth); } else pr_rop (pr5, 0, 0, w, h, PIX_CLR, pr5, 0, 0); if (one != -1) { if (one) pr_rop (pr5, 0, 0, w, h, PIX_SRC | PIX_COLOR (one), pr4, sourcex, 0); pw_stencil (svdev->pw, x, y, w, h, PIX_SRC, pr4, 0, 0, pr5, 0, 0); } if (zero != -1) { pr_rop (pr4, 0, 0, w, h, PIX_NOT (PIX_SRC), pr4, 0, 0); if (zero) pr_rop (pr5, 0, 0, w, h, PIX_SRC | PIX_COLOR (zero), pr4, sourcex, 0); pw_stencil (svdev->pw, x, y, w, h, PIX_SRC, pr4, 0, 0, pr5, 0, 0); } return 0; } /* Copy a "color" bitmap. Since "color" is the same as monochrome, */ /* this just reduces to copying a monochrome bitmap. */ int sv_copy_color (register gx_device *dev, byte *base, int sourcex, int raster, int x, int y, int w, int h, int color_transparent) { int zero = 0, one = 1; switch (color_transparent) { case 0: zero = -1; break; case 1: one = -1; break; } return sv_copy_mono (dev, base, sourcex, raster, x, y, w, h, zero, one); } /* Draw a line */ int sv_draw_line (register gx_device *dev, int x0, int y0, int x1, int y1, int color) { pw_vector (svdev->pw, x0, y0, x1, y1, PIX_SRC, color); return 0; } /* Fill a trapezoid */ int sv_fill_trapezoid (register gx_device *dev, int x0, int y0, int w0, int x1, int y1, int w1, int color) { struct pr_pos vlist[4]; int n = 4; vlist[0].x = x0, vlist[0].y = y0; vlist[1].x = x0 + w0, vlist[1].y = y0; vlist[2].x = x1 + w1, vlist[2].y = y1; vlist[3].x = x1, vlist[3].y = y1; pw_polygon_2 (svdev->pw, 0, 0, 1, &n, vlist, (color ? PIX_SRC | PIX_COLOR (color) : PIX_CLR), NULL, 0, 0); return 0; } SHAR_EOF fi exit 0 # End of shell archive