home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1994 Paul Vojta. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * NOTE:
- * This module is based on prior work as noted below.
- */
-
- /*
- * Support drawing routines for TeXsun and TeX
- *
- * Copyright, (C) 1987, 1988 Tim Morgan, UC Irvine
- * Adapted for xdvi by Jeffrey Lee, U. of Toronto
- *
- * At the time these routines are called, the values of hh and vv should
- * have been updated to the upper left corner of the graph (the position
- * the \special appears at in the dvi file). Then the coordinates in the
- * graphics commands are in terms of a virtual page with axes oriented the
- * same as the Imagen and the SUN normally have:
- *
- * 0,0
- * +-----------> +x
- * |
- * |
- * |
- * \ /
- * +y
- *
- * Angles are measured in the conventional way, from +x towards +y.
- * Unfortunately, that reverses the meaning of "counterclockwise"
- * from what it's normally thought of.
- *
- * A lot of floating point arithmetic has been converted to integer
- * arithmetic for speed. In some places, this is kind-of kludgy, but
- * it's worth it.
- */
-
- #include "config.h"
- #include <kpathsea/c-fopen.h>
- #include <kpathsea/c-ctype.h>
- #include <kpathsea/line.h>
- #include <kpathsea/tex-file.h>
-
- #define MAXPOINTS 300 /* Max points in a path */
- #define TWOPI (3.14159265359*2.0)
- #define MAX_PEN_SIZE 7 /* Max pixels of pen width */
-
-
- static int xx[MAXPOINTS], yy[MAXPOINTS]; /* Path in milli-inches */
- static int path_len = 0; /* # points in current path */
- static int pen_size = 1; /* Pixel width of lines drawn */
-
- static Boolean whiten = False;
- static Boolean shade = False;
- static Boolean blacken = False;
-
- /* Unfortunately, these values also appear in dvisun.c */
- #define xRESOLUTION (pixels_per_inch/shrink_factor)
- #define yRESOLUTION (pixels_per_inch/shrink_factor)
-
-
- /*
- * Issue warning messages
- */
-
- static void
- Warning(fmt, msg)
- char *fmt, *msg;
- {
- Fprintf(stderr, fmt, msg);
- (void) fputc('\n', stderr);
- }
-
-
- /*
- * X drawing routines
- */
-
- #define toint(x) ((int) ((x) + 0.5))
- #define xconv(x) (toint(tpic_conv*(x))/shrink_factor + PXL_H)
- #define yconv(y) (toint(tpic_conv*(y))/shrink_factor + PXL_V)
-
- /*
- * Draw a line from (fx,fy) to (tx,ty).
- * Right now, we ignore pen_size.
- */
- static void
- line_btw(fx, fy, tx, ty)
- int fx, fy, tx, ty;
- {
- register int fcx = xconv(fx),
- tcx = xconv(tx),
- fcy = yconv(fy),
- tcy = yconv(ty);
-
- if ((fcx < max_x || tcx < max_x) && (fcx >= min_x || tcx >= min_x) &&
- (fcy < max_y || tcy < max_y) && (fcy >= min_y || tcy >= min_y))
- XDrawLine(DISP, currwin.win, ruleGC,
- fcx - currwin.base_x, fcy - currwin.base_y,
- tcx - currwin.base_x, tcy - currwin.base_y);
- }
-
- /*
- * Draw a dot at (x,y)
- */
- static void
- dot_at(x, y)
- int x, y;
- {
- register int cx = xconv(x),
- cy = yconv(y);
-
- if (cx < max_x && cx >= min_x && cy < max_y && cy >= min_y)
- XDrawPoint(DISP, currwin.win, ruleGC,
- cx - currwin.base_x, cy - currwin.base_y);
- }
-
- /*
- * Apply the requested attributes to the last path (box) drawn.
- * Attributes are reset.
- * (Not currently implemented.)
- */
- /* ARGSUSED */
- static void
- do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y)
- int last_min_x, last_max_x, last_min_y, last_max_y;
- {
- }
-
- /*
- * Set the size of the virtual pen used to draw in milli-inches
- */
-
- /* ARGSUSED */
- static void
- set_pen_size(cp)
- char *cp;
- {
- int ps;
-
- if (sscanf(cp, " %d ", &ps) != 1) {
- Warning("illegal .ps command format: %s", cp);
- return;
- }
- pen_size = (ps * (xRESOLUTION + yRESOLUTION) + 1000) / 2000;
- if (pen_size < 1) pen_size = 1;
- else if (pen_size > MAX_PEN_SIZE) pen_size = MAX_PEN_SIZE;
- }
-
-
- /*
- * Print the line defined by previous path commands
- */
-
- static void
- flush_path()
- {
- register int i;
- int last_min_x, last_max_x, last_min_y, last_max_y;
-
- last_min_x = 30000;
- last_min_y = 30000;
- last_max_x = -30000;
- last_max_y = -30000;
- for (i = 1; i < path_len; i++) {
- if (xx[i] > last_max_x) last_max_x = xx[i];
- if (xx[i] < last_min_x) last_min_x = xx[i];
- if (yy[i] > last_max_y) last_max_y = yy[i];
- if (yy[i] < last_min_y) last_min_y = yy[i];
- line_btw(xx[i], yy[i], xx[i+1], yy[i+1]);
- }
- if (xx[path_len] > last_max_x) last_max_x = xx[path_len];
- if (xx[path_len] < last_min_x) last_min_x = xx[path_len];
- if (yy[path_len] > last_max_y) last_max_y = yy[path_len];
- if (yy[path_len] < last_min_y) last_min_y = yy[path_len];
- path_len = 0;
- do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y);
- }
-
-
- /*
- * Print a dashed line along the previously defined path, with
- * the dashes/inch defined.
- */
-
- static void
- flush_dashed(cp, dotted)
- char *cp;
- Boolean dotted;
- {
- int i;
- int numdots;
- int lx0, ly0, lx1, ly1;
- int cx0, cy0, cx1, cy1;
- float inchesperdash;
- double d, spacesize, a, b, dx, dy, milliperdash;
-
- if (sscanf(cp, " %f ", &inchesperdash) != 1) {
- Warning("illegal format for dotted/dashed line: %s", cp);
- return;
- }
- if (path_len <= 1 || inchesperdash <= 0.0) {
- Warning("illegal conditions for dotted/dashed line", "");
- return;
- }
- milliperdash = inchesperdash * 1000.0;
- lx0 = xx[1]; ly0 = yy[1];
- lx1 = xx[2]; ly1 = yy[2];
- dx = lx1 - lx0;
- dy = ly1 - ly0;
- if (dotted) {
- numdots = sqrt(dx*dx + dy*dy) / milliperdash + 0.5;
- if (numdots == 0) numdots = 1;
- for (i = 0; i <= numdots; i++) {
- a = (float) i / (float) numdots;
- cx0 = lx0 + a * dx + 0.5;
- cy0 = ly0 + a * dy + 0.5;
- dot_at(cx0, cy0);
- }
- }
- else {
- d = sqrt(dx*dx + dy*dy);
- numdots = d / (2.0 * milliperdash) + 1.0;
- if (numdots <= 1)
- line_btw(lx0, ly0, lx1, ly1);
- else {
- spacesize = (d - numdots * milliperdash) / (numdots - 1);
- for (i = 0; i < numdots - 1; i++) {
- a = i * (milliperdash + spacesize) / d;
- b = a + milliperdash / d;
- cx0 = lx0 + a * dx + 0.5;
- cy0 = ly0 + a * dy + 0.5;
- cx1 = lx0 + b * dx + 0.5;
- cy1 = ly0 + b * dy + 0.5;
- line_btw(cx0, cy0, cx1, cy1);
- b += spacesize / d;
- }
- cx0 = lx0 + b * dx + 0.5;
- cy0 = ly0 + b * dy + 0.5;
- line_btw(cx0, cy0, lx1, ly1);
- }
- }
- path_len = 0;
- }
-
-
- /*
- * Add a point to the current path
- */
-
- static void
- add_path(cp)
- char *cp;
- {
- int pathx, pathy;
-
- if (++path_len >= MAXPOINTS) oops("Too many points");
- if (sscanf(cp, " %d %d ", &pathx, &pathy) != 2)
- oops("Malformed path command");
- xx[path_len] = pathx;
- yy[path_len] = pathy;
- }
-
-
- /*
- * Draw to a floating point position
- */
-
- static void
- im_fdraw(x, y)
- double x,y;
- {
- if (++path_len >= MAXPOINTS) oops("Too many arc points");
- xx[path_len] = x + 0.5;
- yy[path_len] = y + 0.5;
- }
-
-
- /*
- * Draw an ellipse with the indicated center and radices.
- */
-
- static void
- draw_ellipse(xc, yc, xr, yr)
- int xc, yc, xr, yr;
- {
- double angle, theta;
- int n;
- int px0, py0, px1, py1;
-
- angle = (xr + yr) / 2.0;
- theta = sqrt(1.0 / angle);
- n = TWOPI / theta + 0.5;
- if (n < 12) n = 12;
- else if (n > 80) n = 80;
- n /= 2;
- theta = TWOPI / n;
-
- angle = 0.0;
- px0 = xc + xr; /* cos(0) = 1 */
- py0 = yc; /* sin(0) = 0 */
- while ((angle += theta) <= TWOPI) {
- px1 = xc + xr*cos(angle) + 0.5;
- py1 = yc + yr*sin(angle) + 0.5;
- line_btw(px0, py0, px1, py1);
- px0 = px1;
- py0 = py1;
- }
- line_btw(px0, py0, xc + xr, yc);
- }
-
- /*
- * Draw an arc
- */
-
- static void
- arc(cp, invis)
- char *cp;
- Boolean invis;
- {
- int xc, yc, xrad, yrad, n;
- float start_angle, end_angle, angle, theta, r;
- double xradius, yradius, xcenter, ycenter;
-
- if (sscanf(cp, " %d %d %d %d %f %f ", &xc, &yc, &xrad, &yrad,
- &start_angle, &end_angle) != 6) {
- Warning("illegal arc specification: %s", cp);
- return;
- }
-
- if (invis) return;
-
- /* We have a specialized fast way to draw closed circles/ellipses */
- if (start_angle <= 0.0 && end_angle >= 6.282) {
- draw_ellipse(xc, yc, xrad, yrad);
- return;
- }
- xcenter = xc;
- ycenter = yc;
- xradius = xrad;
- yradius = yrad;
- r = (xradius + yradius) / 2.0;
- theta = sqrt(1.0 / r);
- n = 0.3 * TWOPI / theta + 0.5;
- if (n < 12) n = 12;
- else if (n > 80) n = 80;
- n /= 2;
- theta = TWOPI / n;
- flush_path();
- im_fdraw(xcenter + xradius * cos(start_angle),
- ycenter + yradius * sin(start_angle));
- angle = start_angle + theta;
- if (end_angle < start_angle) end_angle += TWOPI;
- while (angle < end_angle) {
- im_fdraw(xcenter + xradius * cos(angle),
- ycenter + yradius * sin(angle));
- angle += theta;
- }
- im_fdraw(xcenter + xradius * cos(end_angle),
- ycenter + yradius * sin(end_angle));
- flush_path();
- }
-
-
- /*
- * APPROXIMATE integer distance between two points
- */
-
- #define dist(x0, y0, x1, y1) (abs(x0 - x1) + abs(y0 - y1))
-
-
- /*
- * Draw a spline along the previously defined path
- */
-
- static void
- flush_spline()
- {
- int xp, yp;
- int N;
- int lastx, lasty;
- Boolean lastvalid = False;
- int t1, t2, t3;
- int steps;
- int j;
- register int i, w;
-
- #ifdef lint
- lastx = lasty = -1;
- #endif
- N = path_len + 1;
- xx[0] = xx[1];
- yy[0] = yy[1];
- xx[N] = xx[N-1];
- yy[N] = yy[N-1];
- for (i = 0; i < N - 1; i++) { /* interval */
- steps = (dist(xx[i], yy[i], xx[i+1], yy[i+1]) +
- dist(xx[i+1], yy[i+1], xx[i+2], yy[i+2])) / 80;
- for (j = 0; j < steps; j++) { /* points within */
- w = (j * 1000 + 500) / steps;
- t1 = w * w / 20;
- w -= 500;
- t2 = (750000 - w * w) / 10;
- w -= 500;
- t3 = w * w / 20;
- xp = (t1*xx[i+2] + t2*xx[i+1] + t3*xx[i] + 50000) / 100000;
- yp = (t1*yy[i+2] + t2*yy[i+1] + t3*yy[i] + 50000) / 100000;
- if (lastvalid) line_btw(lastx, lasty, xp, yp);
- lastx = xp;
- lasty = yp;
- lastvalid = True;
- }
- }
- path_len = 0;
- }
-
-
- /*
- * Shade the last box, circle, or ellipse
- */
-
- static void
- shade_last()
- {
- blacken = whiten = False;
- shade = True;
- }
-
-
- /*
- * Make the last box, circle, or ellipse, white inside (shade with white)
- */
-
- static void
- whiten_last()
- {
- whiten = True;
- blacken = shade = False;
- }
-
-
- /*
- * Make last box, etc, black inside
- */
-
- static void
- blacken_last()
- {
- blacken = True;
- whiten = shade = False;
- }
-
-
- /*
- * Code for PostScript<tm> specials begins here.
- */
-
- #if PS
-
- static void ps_startup ARGS((int, int, char *));
- void NullProc ARGS((void)) {}
- /* ARGSUSED */
- static void NullProc2 ARGS((char *));
-
- struct psprocs psp = { /* used for lazy startup of the ps machinery */
- /* toggle */ NullProc,
- /* destroy */ NullProc,
- /* interrupt */ NullProc,
- /* endpage */ NullProc,
- /* drawbegin */ ps_startup,
- /* drawraw */ NullProc2,
- /* drawfile */ NullProc2,
- /* drawend */ NullProc2};
-
- struct psprocs no_ps_procs = { /* used if postscript is unavailable */
- /* toggle */ NullProc,
- /* destroy */ NullProc,
- /* interrupt */ NullProc,
- /* endpage */ NullProc,
- /* drawbegin */ drawbegin_none,
- /* drawraw */ NullProc2,
- /* drawfile */ NullProc2,
- /* drawend */ NullProc2};
-
- #endif /* PS */
-
- static Boolean bbox_valid;
- static unsigned int bbox_width;
- static unsigned int bbox_height;
- static int bbox_voffset;
-
- void
- draw_bbox()
- {
- if (bbox_valid) {
- put_border(PXL_H - currwin.base_x,
- PXL_V - currwin.base_y - bbox_voffset,
- bbox_width, bbox_height, ruleGC);
- bbox_valid = False;
- }
- }
-
- #if PS
- static void
- actual_startup()
- {
- /*
- * Figure out what we want to use to display postscript figures
- * and set at most one of the following to True:
- * resource.useGS, resource.useDPS, resource.useNeWS
- *
- * Choose DPS then NEWS then GhostScript if they are available
- */
- if (!(
- #ifdef PS_DPS
- (resource.useDPS && initDPS())
- #if defined(PS_NEWS) || defined(PS_GS)
- ||
- #endif
- #endif /* PS_DPS */
-
- #ifdef PS_NEWS
- (resource.useNeWS && initNeWS())
- #ifdef PS_GS
- ||
- #endif
- #endif /* PS_NEWS */
-
- #ifdef PS_GS
- (resource.useGS && initGS())
- #endif
-
- ))
- psp = no_ps_procs;
- }
-
- static void
- ps_startup(xul, yul, cp)
- int xul, yul;
- char *cp;
- {
- if (!resource._postscript) {
- psp.toggle = actual_startup;
- draw_bbox();
- return;
- }
- actual_startup();
- psp.drawbegin(xul, yul, cp);
- }
-
- /* ARGSUSED */
- static void
- NullProc2(cp)
- char *cp;
- {}
-
- /* ARGSUSED */
- void
- #if NeedFunctionPrototypes
- drawbegin_none(int xul, int yul, char *cp)
- #else /* !NeedFunctionPrototypes */
- drawbegin_none(xul, yul, cp)
- int xul, yul;
- char *cp;
- #endif /* NeedFunctionPrototypes */
- {
- draw_bbox();
- }
- #endif /* PS */
-
-
- /* If FILENAME starts with a left quote, set *DECOMPRESS to 1 and return
- the rest of FILENAME. Otherwise, look up FILENAME along the usual
- path for figure files, set *DECOMPRESS to 0, and return the result
- (NULL if can't find the file). */
-
- static string
- find_fig_file (filename, decompress)
- char *filename;
- int *decompress;
- {
- char *name;
-
- if (*filename == '`') {
- name = filename + 1;
- *decompress = 1;
- } else {
- name = kpse_find_pict (filename);
- if (!name)
- fprintf (stderr, "xdvi: %s: Cannot open PS file.\n", filename);
- *decompress = 0;
- }
-
- return name;
- }
-
-
- #if PS
- /* If DECOMPRESS is zero, pass NAME to the drawfile proc. But if
- DECOMPRESS is nonzero, open a pipe to it and pass the resulting
- output to the drawraw proc (in chunks). */
-
- static void
- draw_file (psp, name, decompress)
- struct psprocs psp;
- char *name;
- int decompress;
- {
- if (decompress) {
- FILE *pipe;
- if (debug & DBG_PS)
- printf ("%s: piping to PostScript\n", name);
-
- pipe = popen (name, FOPEN_R_MODE);
- if (pipe == NULL)
- perror (name);
- else
- {
- char *line;
- int save_debug = debug;
- debug = 0; /* don't print every line we send */
- while ((line = read_line (pipe)) != NULL) {
- psp.drawraw (line);
- free (line);
- }
- pclose (pipe); /* Linux gives a spurious error, so don't check. */
- debug = save_debug;
- }
-
- } else { /* a regular file, not decompressing */
- psp.drawfile (name);
- }
- }
- #endif /* PS */
-
- static void
- psfig_special(cp)
- char *cp;
- {
- char *filename;
- int raww, rawh;
-
- if (strncmp(cp, ":[begin]", 8) == 0) {
- cp += 8;
- bbox_valid = False;
- if (sscanf(cp,"%d %d\n", &raww, &rawh) >= 2) {
- bbox_valid = True;
- bbox_width = pixel_conv(spell_conv(raww));
- bbox_height = pixel_conv(spell_conv(rawh));
- bbox_voffset = 0;
- }
- if (currwin.win == mane.win)
- #if PS
- psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y,
- cp);
- #else
- draw_bbox();
- #endif
- } else if (strncmp(cp, " plotfile ", 10) == 0) {
- cp += 10;
- while (isspace(*cp)) cp++;
- for (filename = cp; !isspace(*cp); ++cp);
- *cp = '\0';
- #if PS
- {
- int decompress;
- char *name = find_fig_file (filename, &decompress);
- if (name && currwin.win == mane.win) {
- draw_file(psp, name, decompress);
- if (!decompress && name != filename)
- free (name);
- }
- }
- #endif
- } else if (strncmp(cp, ":[end]", 6) == 0) {
- cp += 6;
- #if PS
- if (currwin.win == mane.win) psp.drawend(cp);
- #endif
- bbox_valid = False;
- } else { /* I am going to send some raw postscript stuff */
- if (*cp == ':')
- ++cp; /* skip second colon in ps:: */
- #if PS
- if (currwin.win == mane.win) {
- /* It's drawbegin that initializes the ps process, so make
- sure it's started up. */
- psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y, "");
- psp.drawend("");
- psp.drawraw(cp);
- }
- #endif
- }
- }
-
-
- /* Keys for epsf specials */
-
- static char *keytab[] = {"clip",
- "llx",
- "lly",
- "urx",
- "ury",
- "rwi",
- "rhi",
- "hsize",
- "vsize",
- "hoffset",
- "voffset",
- "hscale",
- "vscale",
- "angle"};
-
- #define KEY_LLX keyval[0]
- #define KEY_LLY keyval[1]
- #define KEY_URX keyval[2]
- #define KEY_URY keyval[3]
- #define KEY_RWI keyval[4]
- #define KEY_RHI keyval[5]
-
- #define NKEYS (sizeof(keytab)/sizeof(*keytab))
- #define N_ARGLESS_KEYS 1
-
- static void
- epsf_special(cp)
- char *cp;
- {
- char *filename, *name;
- int decompress;
- static char *buffer;
- static unsigned int buflen = 0;
- unsigned int len;
- char *p;
- char *q;
- int flags = 0;
- double keyval[6];
-
- if (memcmp(cp, "ile=", 4) != 0) {
- if (!hush_spec_now)
- Fprintf(stderr, "epsf special PSf%s is unknown\n", cp);
- return;
- }
-
- p = cp + 4;
- filename = p;
- if (*p == '\'' || *p == '"') {
- do ++p;
- while (*p != '\0' && *p != *filename);
- ++filename;
- }
- else
- while (*p != '\0' && *p != ' ' && *p != '\t') ++p;
- if (*p != '\0') *p++ = '\0';
- name = find_fig_file (filename, &decompress);
- while (*p == ' ' || *p == '\t') ++p;
- len = strlen(p) + NKEYS + 30;
- if (buflen < len) {
- if (buflen != 0) free(buffer);
- buflen = len;
- buffer = xmalloc(buflen, "epsf buffer");
- }
- Strcpy(buffer, "@beginspecial");
- q = buffer + strlen(buffer);
- while (*p != '\0') {
- char *p1 = p;
- int keyno;
-
- while (*p1 != '=' && !isspace(*p1) && *p1 != '\0') ++p1;
- for (keyno = 0;; ++keyno) {
- if (keyno >= NKEYS) {
- if (!hush_spec_now)
- Fprintf(stderr,
- "unknown keyword (%*s) in \\special will be ignored\n",
- (int) (p1 - p), p);
- break;
- }
- if (memcmp(p, keytab[keyno], p1 - p) == 0) {
- if (keyno >= N_ARGLESS_KEYS) {
- if (*p1 == '=') ++p1;
- if (keyno < N_ARGLESS_KEYS + 6) {
- keyval[keyno - N_ARGLESS_KEYS] = atof(p1);
- flags |= (1 << (keyno - N_ARGLESS_KEYS));
- }
- *q++ = ' ';
- while (!isspace(*p1) && *p1 != '\0') *q++ = *p1++;
- }
- *q++ = ' ';
- *q++ = '@';
- Strcpy(q, keytab[keyno]);
- q += strlen(q);
- break;
- }
- }
- p = p1;
- while (!isspace(*p) && *p != '\0') ++p;
- while (isspace(*p)) ++p;
- }
- Strcpy(q, " @setspecial\n");
-
- bbox_valid = False;
- if ((flags & 0x30) == 0x30 || ((flags & 0x30) && (flags & 0xf) == 0xf)){
- bbox_valid = True;
- bbox_width = 0.1 * ((flags & 0x10) ? KEY_RWI
- : KEY_RHI * (KEY_URX - KEY_LLX) / (KEY_URY - KEY_LLY))
- * dimconv / shrink_factor + 0.5;
- bbox_voffset = bbox_height = 0.1 * ((flags & 0x20) ? KEY_RHI
- : KEY_RWI * (KEY_URY - KEY_LLY) / (KEY_URX - KEY_LLX))
- * dimconv / shrink_factor + 0.5;
- }
-
- if (name && currwin.win == mane.win) {
- #if PS
- psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y,
- buffer);
- draw_file(psp, name, decompress);
- psp.drawend(" @endspecial");
- if (!decompress && name != filename)
- free (name);
- #else
- draw_bbox();
- #endif
- }
- bbox_valid = False;
- }
-
-
- static void
- bang_special(cp)
- char *cp;
- {
- bbox_valid = False;
-
- #if PS
- if (currwin.win == mane.win) {
- psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y,
- "@defspecial ");
- /* talk directly with the DPSHandler here */
- psp.drawraw(cp);
- psp.drawend(" @fedspecial");
- }
- #endif
-
- /* nothing else to do--there's no bbox here */
- }
-
- static void
- quote_special(cp)
- char *cp;
- {
- bbox_valid = False;
-
- #if PS
- if (currwin.win == mane.win) {
- psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y,
- "@beginspecial @setspecial ");
- /* talk directly with the DPSHandler here */
- psp.drawraw(cp);
- psp.drawend(" @endspecial");
- }
- #endif
-
- /* nothing else to do--there's no bbox here */
- }
-
-
- /*
- * The following copyright message applies to the rest of this file. --PV
- */
-
- /*
- * This program is Copyright (C) 1987 by the Board of Trustees of the
- * University of Illinois, and by the author Dirk Grunwald.
- *
- * This program may be freely copied, as long as this copyright
- * message remaines affixed. It may not be sold, although it may
- * be distributed with other software which is sold. If the
- * software is distributed, the source code must be made available.
- *
- * No warranty, expressed or implied, is given with this software.
- * It is presented in the hope that it will prove useful.
- *
- * Hacked in ignorance and desperation by jonah@db.toronto.edu
- */
-
- /*
- * The code to handle the \specials generated by tpic was modified
- * by Dirk Grunwald using the code Tim Morgan at Univ. of Calif, Irvine
- * wrote for TeXsun.
- */
-
- #define COMLEN 3
-
- void
- applicationDoSpecial(cp)
- char *cp;
- {
- char command[COMLEN + 1];
- char *q;
- char *orig_cp;
-
- orig_cp = cp;
- while (ISSPACE(*cp)) ++cp;
- q = command;
- while (!ISSPACE(*cp) && *cp && q < command + COMLEN) *q++ = *cp++;
- *q = '\0';
- if (strcmp(command, "pn") == 0) set_pen_size(cp);
- else if (strcmp(command, "fp") == 0) flush_path();
- else if (strcmp(command, "da") == 0) flush_dashed(cp, False);
- else if (strcmp(command, "dt") == 0) flush_dashed(cp, True);
- else if (strcmp(command, "pa") == 0) add_path(cp);
- else if (strcmp(command, "ar") == 0) arc(cp, False);
- else if (strcmp(command, "ia") == 0) arc(cp, True);
- else if (strcmp(command, "sp") == 0) flush_spline();
- else if (strcmp(command, "sh") == 0) shade_last();
- else if (strcmp(command, "wh") == 0) whiten_last();
- else if (strcmp(command, "bk") == 0) blacken_last();
- /* throw away the path -- jansteen */
- else if (strcmp(command, "ip") == 0) path_len = 0;
- else if (strcmp(command, "ps:") == 0) psfig_special(cp);
- else if (strcmp(command, "PSf") == 0) epsf_special(cp);
- else if (strcmp(command, "psf") == 0) epsf_special(cp);
- else if (*orig_cp == '"') quote_special(orig_cp + 1);
- else if (*orig_cp == '!') bang_special(orig_cp + 1);
- else if (!hush_spec_now)
- Fprintf(stderr, "%s: special \"%s\" not implemented\n", prog,
- orig_cp);
- }
-