diff options
Diffstat (limited to 'troff/troff.d/t10.c')
-rw-r--r-- | troff/troff.d/t10.c | 1139 |
1 files changed, 1139 insertions, 0 deletions
diff --git a/troff/troff.d/t10.c b/troff/troff.d/t10.c new file mode 100644 index 0000000000000..52cfc40c0751c --- /dev/null +++ b/troff/troff.d/t10.c @@ -0,0 +1,1139 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1989 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + + +/* from OpenSolaris "t10.c 1.11 05/06/08 SMI" */ + +/* + * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany + * + * Sccsid @(#)t10.c 1.98 (gritter) 8/19/08 + */ + +/* + * Changes Copyright (c) 2014 Carsten Kunze (carsten.kunze at arcor.de) + */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California + * All Rights Reserved + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ + +#include <stdlib.h> +#include "tdef.h" +#include <ctype.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#ifdef EUC +#include <locale.h> +#endif +#include "ext.h" +#include "dev.h" +#include "afm.h" +#include "pt.h" +#include "troff.h" +#include "unimap.h" +#include "fontmap.h" +/* + * troff10.c + * + * typesetter interface + */ + +int vpos = 0; /* absolute vertical position on page */ +int hpos = 0; /* ditto horizontal */ + +int initbdtab[NFONT+1]; + +short *chtab; +char *chname; +int **fontab; +char **kerntab; +unsigned short **fitab; +unsigned short **codetab; + +int Inch; +int Hor; +int Vert; +int Unitwidth; +int nfonts; +int nsizes; +int nchtab; +int lettrack; +float horscale; + +static float mzoom; +static int mtrack; +static float mhorscale; + +/* these characters are used as various signals or values + * in miscellaneous places. + * values are set in specnames in t10.c + */ + +int c_hyphen; +int c_emdash; +int c_endash; +int c_rule; +int c_minus; +int c_fi; +int c_fl; +int c_ff; +int c_ffi; +int c_ffl; +int c_acute; +int c_grave; +int c_under; +int c_rooten; +int c_boxrule; +int c_lefthand; +int c_dagger; + +struct dev dev; +struct Font **fontbase; + +int Nfont; + +static int okern(tchar *, tchar *, int); +static void pthorscale(int); +static void pttrack(int); +static void ptanchor(int); +static void ptlink(int); +static void ptulink(int); +static void ptyon(int); +static void ptchar(int, int); +static void pnc(int, struct afmtab *); + +void +growfonts(int n) +{ + int i, j; + + fontbase = realloc(fontbase, n * sizeof *fontbase); + memset(&fontbase[Nfont], 0, (n - Nfont) * sizeof *fontbase); + fontab = realloc(fontab, n * sizeof *fontab); + memset(&fontab[Nfont], 0, (n - Nfont) * sizeof *fontab); + kerntab = realloc(kerntab, n * sizeof *kerntab); + memset(&kerntab[Nfont], 0, (n - Nfont) * sizeof *kerntab); + codetab = realloc(codetab, n * sizeof *codetab); + memset(&codetab[Nfont], 0, (n - Nfont) * sizeof *codetab); + fitab = realloc(fitab, n * sizeof *fitab); + memset(&fitab[Nfont], 0, (n - Nfont) * sizeof *fitab); + fontlab = realloc(fontlab, n * sizeof *fontlab); + memset(&fontlab[Nfont], 0, (n - Nfont) * sizeof *fontlab); + cstab = realloc(cstab, n * sizeof *cstab); + memset(&cstab[Nfont], 0, (n - Nfont) * sizeof *cstab); + ccstab = realloc(ccstab, n * sizeof *ccstab); + memset(&ccstab[Nfont], 0, (n - Nfont) * sizeof *ccstab); + bdtab = realloc(bdtab, n * sizeof *bdtab); + memset(&bdtab[Nfont], 0, (n - Nfont) * sizeof *bdtab); + tracktab = realloc(tracktab, n * sizeof *tracktab); + memset(&tracktab[Nfont], 0, (n - Nfont) * sizeof *tracktab); + fallbacktab = realloc(fallbacktab, n * sizeof *fallbacktab); + memset(&fallbacktab[Nfont], 0, (n - Nfont) * sizeof *fallbacktab); + zoomtab = realloc(zoomtab, n * sizeof *zoomtab); + memset(&zoomtab[Nfont], 0, (n - Nfont) * sizeof *zoomtab); + lhangtab = realloc(lhangtab, n * sizeof *lhangtab); + memset(&lhangtab[Nfont], 0, (n - Nfont) * sizeof *lhangtab); + rhangtab = realloc(rhangtab, n * sizeof *rhangtab); + memset(&rhangtab[Nfont], 0, (n - Nfont) * sizeof *rhangtab); + kernafter = realloc(kernafter, n * sizeof *kernafter); + memset(&kernafter[Nfont], 0, (n - Nfont) * sizeof *kernafter); + kernbefore = realloc(kernbefore, n * sizeof *kernbefore); + memset(&kernbefore[Nfont], 0, (n - Nfont) * sizeof *kernbefore); + ftrtab = realloc(ftrtab, n * sizeof *ftrtab); + for (i = Nfont; i < n; i++) { + ftrtab[i] = malloc(NCHARS * sizeof **ftrtab); + for (j = 0; j < NCHARS; j++) + ftrtab[i][j] = j; + } + lgtab = realloc(lgtab, n * sizeof *lgtab); + memset(&lgtab[Nfont], 0, (n - Nfont) * sizeof *lgtab); + lgrevtab = realloc(lgrevtab, n * sizeof *lgrevtab); + memset(&lgrevtab[Nfont], 0, (n - Nfont) * sizeof *lgrevtab); + Nfont = n; +} + +void +ptinit(void) +{ + int i, nw; + char *filebase, *p, *ap, *descp; + char *p2; + size_t l; + size_t l2; + + if (!strcmp(devname, "html")) html = 1; + growfonts(NFONT+1); + memcpy(bdtab, initbdtab, + max((NFONT+1) * sizeof *bdtab, sizeof initbdtab)); + uninit(); + /* open table for device, + * read in resolution, size info, font info, etc. + * and set params + */ + l = strlen(termtab) + strlen(devname) + 10; + l2 = l + 3; + p = malloc(l); + p2 = malloc(l2); + n_strcpy(p, termtab, l); + termtab = p; + n_strcat(termtab, "/dev", l); + n_strcat(termtab, devname, l); + n_strcpy(p2, termtab, l2); + n_strcat(p2, "/FONTMAP", l2); + rdftmap(p2); + free(p2); + n_strcat(termtab, "/DESC", l); /* makes "..../devXXX/DESC" */ + if ((descp = readdesc(termtab)) == NULL) + done3(1); + memcpy(&dev, descp, sizeof dev); + Inch = dev.res; + Hor = dev.hor; + Vert = dev.vert; + Unitwidth = dev.unitwidth; + nfonts = dev.nfonts; + nsizes = dev.nsizes; + nchtab = dev.nchtab; + if (nchtab >= NCHARS - 128) { + errprint("too many special characters in file %s", + termtab); + done3(1); + } + filebase = malloc(dev.filesize + 3*EXTRAFONT); /* enough room for whole file */ + memcpy(filebase, &descp[sizeof dev], dev.filesize); /* all at once */ + free(descp); + pstab = (int *) filebase; + for (i = 0; pstab[i]; i++) + pstab[i] = pts2u(pstab[i]); + chtab = (short *)(pstab + nsizes + 1); + chname = (char *) (chtab + dev.nchtab); + p = chname + dev.lchname; + specnames(); /* install names like "hyphen", etc. */ + for (i = 1; i <= nfonts; i++) { + fontbase[i] = (struct Font *) p; + nw = *p & BYTEMASK; /* 1st thing is width count */ + fontlab[i] = PAIR(fontbase[i]->namefont[0], fontbase[i]->namefont[1]); + /* for now, still 2 char names */ + if (smnt == 0 && fontbase[i]->specfont == 1) + smnt = i; /* first special font */ + p += sizeof(struct Font); /* that's what's on the beginning */ + if ((ap = strstr(fontbase[i]->namefont, ".afm")) != NULL) { + *ap = 0; + if (ap == &fontbase[i]->namefont[1]) + fontlab[i] &= BYTEMASK; + loadafm(i, fontlab[i], fontbase[i]->namefont, NULL, + 1, SPEC_NONE); + } else { + makefont(i, p, p + nw, p + 2 * nw, p + 3 * nw, nw); + } + p += 3 * nw + dev.nchtab + 128 - 32; + } + fontbase[0] = (struct Font *) p; /* the last shall be first */ + memset(fontbase[0], 0, sizeof *fontbase[0]); + nw = EXTRAFONT - dev.nchtab - (128-32) - sizeof (struct Font); + fontbase[0]->nwfont = nw; + makefont(0, p, p + nw, p + 2 * nw, p + 3 * nw, nw); + /* there are a lot of things that used to be constant + * that now require code to be executed. + */ + sps = SPS; + ses = SES; + for (i = 0; i < 16; i++) + tabtab[i] = DTAB * (i + 1); + pl = 11 * INCH; + po = PO; + spacesz = SS; + sesspsz = SSS; + lss = lss1 = VS; + ll = ll1 = lt = lt1 = LL; + apts = pts2u(apts); + apts1 = pts2u(apts1); + pts = pts2u(pts); + pts1 = pts2u(pts1); + ics = ICS; + for (i = 0; i <= nfonts; i++) + setlig(i, fontbase[i]->ligfont); + kern = xflag; + if (ascii) + return; + fdprintf(ptid, "x T %s\n", devname); + fdprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert); + fdprintf(ptid, "x init\n"); /* do initialization for particular device */ + /* + for (i = 1; i <= nfonts; i++) + fdprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); + fdprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth); + fdprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n", + dev.nchtab, dev.lchname, dev.nchtab+128-32); + fdprintf(ptid, "x xxx sizes:\nx xxx "); + for (i = 0; i < nsizes; i++) + fdprintf(ptid, " %d", pstab[i]); + fdprintf(ptid, "\nx xxx chars:\nx xxx "); + for (i = 0; i < dev.nchtab; i++) + fdprintf(ptid, " %s", &chname[chtab[i]]); + fdprintf(ptid, "\nx xxx\n"); + */ +#ifdef EUC + ptlocale(setlocale(LC_CTYPE, NULL)); +#endif /* EUC */ + free(termtab); +} + +void +specnames(void) +{ + static struct { + int *n; + char *v; + } spnames[] = { + { &c_hyphen , "hy" }, + { &c_emdash , "em" }, + { &c_endash , "en" }, + { &c_rule , "ru" }, + { &c_minus , "\\-"}, + { &c_fi , "fi" }, + { &c_fl , "fl" }, + { &c_ff , "ff" }, + { &c_ffi , "Fi" }, + { &c_ffl , "Fl" }, + { &c_acute , "aa" }, + { &c_grave , "ga" }, + { &c_under , "ul" }, + { &c_rooten , "rn" }, + { &c_boxrule , "br" }, + { &c_lefthand, "lh" }, + { &c_dagger , "dg" }, + { 0 , 0 } + }; + static int twice; + int i; + + if (twice++) + return; + for (i = 0; spnames[i].n; i++) + *spnames[i].n = findch(spnames[i].v); +} + +int +findch(register char *s) /* find char s in chname */ +{ + register int i; + + for (i = 0; i < nchtab; i++) + if (strcmp(s, &chname[chtab[i]]) == 0) + return(i + 128); + return(0); +} + +void +ptout(register tchar i) +{ + register int dv; + register tchar *k; + int temp, a, b; + + if (isadjspc(i)) + return; + if (olinep >= &oline[olinesz]) { + olinesz += 100; + k = realloc(oline, olinesz * sizeof *oline); + olinep = (tchar *)((char *)olinep + ((char *)k-(char *)oline)); + oline = k; + } + if (cbits(i) != '\n') { + *olinep++ = i; + return; + } + if (olinep == oline) { + lead += lss; + return; + } + + hpos = po; /* ??? */ + esc = 0; /* ??? */ + ptesc(); /* the problem is to get back to the left end of the line */ + dv = 0; + for (k = oline; k < olinep; k++) { + if (ismot(*k) && isvmot(*k)) { + temp = absmot(*k); + if (isnmot(*k)) + temp = -temp; + dv += temp; + } + } + if (dv) { + vflag++; + *olinep++ = makem(-dv); + vflag = 0; + } + + b = dip->blss + lss; + lead += dip->blss + lss; + dip->blss = 0; + if (linkout) + linkhp = hpos; + for (k = oline; k < olinep; ) + k = ptout0(k, olinep); /* now passing a pointer! */ + olinep = oline; + lead += dip->alss; + a = dip->alss; + dip->alss = 0; + if (linkout) + ptlink(linkout); + /* + fdprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); +*/ + fdprintf(ptid, "n%d %d\n", b, a); /* be nice to chuck */ +} + +tchar * +ptout0(tchar *pi, tchar *pend) +{ + struct afmtab *a; + register int j; + register int k, w = 0; + int z, dx, dy, dx2, dy2, n, c; + register tchar i; + int outsize; /* size of object being printed */ + double f; + int tfont; + + outsize = 1; /* default */ + i = *pi; + k = cbits(i); + if (k == FILLER) + return(pi+outsize); + if (ismot(i)) { + j = absmot(i); + if (isnmot(i)) + j = -j; + if (isvmot(i)) + lead += j; + else + esc += j; + return(pi+outsize); + } + if (k == XON) { + if (xfont != mfont) + ptfont(); + if (xpts != mpts || zoomtab[xfont] != mzoom) + ptps(); + if (lead) + ptlead(); + if (esc) + ptesc(); + fdprintf(ptid, "x X "); + /* + * not guaranteed of finding a XOFF if a word overflow + * error occured, so also bound this loop by olinep + */ + pi++; + while( cbits(*pi) != XOFF && pi < olinep ) + outascii(*pi++); + oput('\n'); + if ( cbits(*pi) == XOFF ) + pi++; + return pi; + } + ; + if (k == CHARHT) { + if (xflag) { + xfont = fbits(i); + if (xfont != mfont) + ptfont(); + } + if (xpts != mpts || zoomtab[xfont] != mzoom) + ptps(); + j = f = u2pts(sbits(i)); + if (j != f && xflag && dev.anysize) + fdprintf(ptid, "x H -23 %g\n", f); + else + fdprintf(ptid, "x H %d\n", j); + return(pi+outsize); + } + if (k == SLANT) { + if (xflag) { + xfont = fbits(i); + if (xfont != mfont) + ptfont(); + } + fdprintf(ptid, "x S %d\n", (int)sbits(i)-180); + return(pi+outsize); + } + if (k == WORDSP) { + oput('w'); + return(pi+outsize); + } + if (k == FONTPOS) { + n = i >> 22; + ptfpcmd(0, macname(n), NULL, 0); + return(pi+outsize); + } + if (k == XFUNC) { + switch (fbits(i)) { + case ANCHOR: + ptanchor(sbits(i)); + return(pi+outsize); + case LINKON: + linkout = sbits(i); + linkhp = hpos + esc; + if (html) ptlink(sbits(i)); + return(pi+outsize); + case LINKOFF: + ptlink(html ? 0 : sbits(i)); + linkout = 0; + return(pi+outsize); + case ULINKON: + linkout = sbits(i); + linkhp = hpos + esc; + if (html) ptulink(sbits(i)); + return(pi+outsize); + case ULINKOFF: + ptulink(html ? 0 : sbits(i)); + linkout = 0; + return(pi+outsize); + case INDENT: + if (linkout) + linkhp += sbits(i); + return(pi+outsize); + case LETSP: + lettrack = sbits(i); + return(pi+outsize); + case NLETSP: + lettrack = -sbits(i); + return(pi+outsize); + case LETSH: + horscale = 1 + (double)sbits(i) / LAFACT; + return(pi+outsize); + case NLETSH: + horscale = 1 - (double)sbits(i) / LAFACT; + return(pi+outsize); + case YON: + if (&pi[outsize] >= pend) + return(pi+outsize); + ptyon(fetchrq(&pi[outsize])); + return(pi+outsize+1); + case CHAR: + ptchar(sbits(i), iszbit(i) != 0); + if (!iszbit(i)) + esc += okern(pi, pend, outsize); + return(pi+outsize); + default: + return(pi+outsize); + } + } + if (sfbits(i) == oldbits) { + xfont = pfont; + xpts = ppts; + } else + xbits(i, 2); + if (k < 040 && k != DRAWFCN) + return(pi+outsize); + if (k >= 32) { + if (html && k >= NCHARS) + w = getcw(0); + else + if (widcache[k-32].fontpts == xfont + (xpts<<8) && !setwdf && + kern == 0 && horscale == 0) { + w = widcache[k-32].width; + lasttrack = widcache[k-32].track; + bd = 0; + cs = 0; + } else { + tfont = xfont; + w = getcw(k-32); + if (tfont != xfont) + k = ftrans(xfont, k); + } + } + if (xfont != mfont) + ptfont(); + if (xpts != mpts || zoomtab[xfont] != mzoom) + ptps(); + if (lead) + ptlead(); + if (lettrack || lasttrack || mtrack) + pttrack(0); + if (horscale || mhorscale) + pthorscale(0); + w += okern(pi, pend, outsize); + if (afmtab && (j = (fontbase[xfont]->afmpos) - 1) >= 0) + a = afmtab[j]; + else + a = NULL; + j = z = 0; + if (k != DRAWFCN) { + if (cs && !fmtchar) { + if (bd) + w += (bd - 1) * HOR; + j = (cs - w) / 2; + w = cs - j; + if (bd) + w -= (bd - 1) * HOR; + } + if (iszbit(i)) { + if (cs && !fmtchar) + w = -j; + else + w = 0; + z = 1; + } + } + esc += j; + /* put out the real character here */ + if (k == DRAWFCN) { + if (esc) + ptesc(); + dx = absmot(pi[3]); + if (isnmot(pi[3])) + dx = -dx; + dy = absmot(pi[4]); + if (isnmot(pi[4])) + dy = -dy; + switch ((c=cbits(pi[1]))) { + case DRAWCIRCLE: /* circle */ + case DRAWCIRCLEFI: + fdprintf(ptid, "D%c %d\n", c, dx); /* dx is diameter */ + w = 0; + hpos += dx; + break; + case DRAWELLIPSE: + case DRAWELLIPSEFI: + fdprintf(ptid, "D%c %d %d\n", c, dx, dy); + w = 0; + hpos += dx; + break; + case DRAWLINE: /* line */ + k = cbits(pi[2]); + fdprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); + if (k < 128) + fdprintf(ptid, "%c\n", k); + else + fdprintf(ptid, "%s\n", &chname[chtab[k - 128]]); + w = 0; + hpos += dx; + vpos += dy; + break; + case DRAWARC: /* arc */ + dx2 = absmot(pi[5]); + if (isnmot(pi[5])) + dx2 = -dx2; + dy2 = absmot(pi[6]); + if (isnmot(pi[6])) + dy2 = -dy2; + fdprintf(ptid, "D%c %d %d %d %d\n", DRAWARC, + dx, dy, dx2, dy2); + w = 0; + hpos += dx + dx2; + vpos += dy + dy2; + break; + case DRAWSPLINE: /* spline */ + default: /* something else; copy it like spline */ + fdprintf(ptid, "D%c %d %d", (int)cbits(pi[1]), dx, dy); + w = 0; + hpos += dx; + vpos += dy; + if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) { + /* it was somehow defective */ + fdprintf(ptid, "\n"); + break; + } + for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) { + dx = absmot(pi[n]); + if (isnmot(pi[n])) + dx = -dx; + dy = absmot(pi[n+1]); + if (isnmot(pi[n+1])) + dy = -dy; + fdprintf(ptid, " %d %d", dx, dy); + hpos += dx; + vpos += dy; + } + fdprintf(ptid, "\n"); + break; + } + for (n = 3; cbits(pi[n]) != DRAWFCN; n++) + ; + outsize = n + 1; + } else if (k < 128) { + /* try to go faster and compress output */ + /* by printing nnc for small positive motion followed by c */ + /* kludgery; have to make sure set all the vars too */ + if (esc > 0 && esc < 100) { + oput(esc / 10 + '0'); + oput(esc % 10 + '0'); + oput(k); + hpos += esc; + esc = 0; + } else { + if (esc) + ptesc(); + oput('c'); + oput(k); + oput('\n'); + } + } else { + if (esc) + ptesc(); + pnc(k, a); + } + if (bd && !fmtchar) { + bd -= HOR; + if (esc += bd) + ptesc(); + if (k < 128) { + fdprintf(ptid, "c%c\n", k); + } else + pnc(k, a); + if (z) + esc -= bd; + } + esc += w; + lettrack = 0; + horscale = 0; + return(pi+outsize); +} + +static void +pnc(int k, struct afmtab *a) { + int j; + + if (k >= nchtab + 128) { + if (a && (j = a->fitab[k-nchtab-128-32]) < a->nchars && + a->nametab[j] != NULL) { + fdprintf(ptid, "CPS%s\n", a->nametab[j]); + } else { + fdprintf(ptid, "N%d\n", + k - (html ? 0 : (nchtab + 128)) ); + } + } else { + fdprintf(ptid, "C%s\n", &chname[chtab[k - 128]]); + } +} + +static int +okern(tchar *pi, tchar *pend, int outsize) +{ + int j; + + for (j = outsize; &pi[j] < pend; j++) + if (cbits(pi[j]) != XFUNC || (fbits(pi[j]) != LETSP && + fbits(pi[j]) != NLETSP && + fbits(pi[j]) != LETSH && + fbits(pi[j]) != NLETSH)) + break; + if (&pi[j] < pend) + return getkw(pi[0], pi[j]); + else + return 0; +} + +static void +pthorscale(int always) +{ + if (horscale || mhorscale) { + if (always || mhorscale != horscale) + fdprintf(ptid, "x X HorScale %g\n", + horscale ? horscale : 1.0); + mhorscale = horscale; + } else + mhorscale = 0; +} + +static void +pttrack(int always) +{ + if (xflag && (lasttrack || lettrack || mtrack)) { + if (always || mtrack != (lasttrack + lettrack)) + fdprintf(ptid, "x X Track %d\n", lasttrack + lettrack); + mtrack = lasttrack + lettrack; + } else + mtrack = 0; +} + +void +ptps(void) +{ + register int i, j, k; + double s, z; + int found; + + i = xpts; + for (j = 0; i > (k = pstab[j]); j++) + if (!k) { + k = pstab[--j]; + break; + } + found = k == i; + if (dev.anysize && xflag) + k = i; + s = u2pts(k); + if ((z = zoomtab[xfont]) != 0 && dev.anysize && xflag) + s *= z; + if (dev.anysize && xflag && (!found || (z != 0 && z != 1))) + fdprintf(ptid, "s-23 %g\n", s); + else + fdprintf(ptid, "s%d\n", (int)s); /* really should put out string rep of size */ + mpts = i; + mzoom = z; + pttrack(0); + pthorscale(0); +} + +void +ptfont(void) +{ + mfont = xfont; + fdprintf(ptid, "f%d\n", xfont); + mtrack = 0; + pttrack(1); + pthorscale(1); +} + +void +ptfpcmd(int f, char *s, char *path, int flags) +{ + if (ascii) + return; + fdprintf(ptid, "x font %d %s", f, s); + if (path) { + fdprintf(ptid, " %s", path); + if (flags) + fdprintf(ptid, " %d", flags); + } + fdprintf(ptid, "\n"); + ptfont(); /* make sure that it gets noticed */ +} + +void +ptlead(void) +{ + vpos += lead; + if (!ascii) + fdprintf(ptid, "V%d\n", vpos); + lead = 0; +} + +void +ptesc(void) +{ + hpos += esc; + if (esc > 0) { + oput('h'); + if (esc>=10 && esc<100) { + oput(esc/10 + '0'); + oput(esc%10 + '0'); + } else + fdprintf(ptid, "%d", esc); + } else + fdprintf(ptid, "H%d\n", hpos); + esc = 0; +} + +void +ptsupplyfont(char *fontname, char *file) +{ + if (ascii) + return; + fdprintf(ptid, "x X SupplyFont %s %s\n", fontname, file); +} + +void +ptpapersize(void) +{ + if (ascii || mediasize.flag == 0) + return; + fdprintf(ptid, "x X PaperSize %d %d %d\n", + mediasize.val[2], mediasize.val[3], + mediasize.flag&2?1:0); +} + +static void +cut1(const char *name, struct box *bp) +{ + if (bp->flag) + fdprintf(ptid, "x X %s %d %d %d %d\n", name, + bp->val[0], bp->val[1], bp->val[2], bp->val[3]); +} + +void +ptcut(void) +{ + if (ascii) + return; + cut1("TrimAt", &trimat); + cut1("BleedAt", &bleedat); + cut1("CropAt", &cropat); +} + +void +ptlocale(const char *cp) +{ + static char *lp; + + if (cp != NULL) { + size_t l; + free(lp); + l = strlen(cp) + 1; + lp = malloc(l); + n_strcpy(lp, cp, l); + } + if (ascii || realpage == 0 || lp == NULL || dev.lc_ctype == 0) + return; + fdprintf(ptid, "x X LC_CTYPE %s\n", lp); +} + +static void +ptanchor(int n) +{ + struct ref *rp; + + if (ascii) + return; + for (rp = anchors; rp; rp = rp->next) + if (rp->cnt == n) { + if (html) { + fdprintf(ptid, "x X Anchor %s\n", rp->name); + } else { + fdprintf(ptid, "x X Anchor %d,%d %s\n", + vpos + lead - lss, hpos + esc, rp->name); + } + break; + } +} + +static void +_ptlink(int n, struct ref *rstart, const char *type) +{ + struct ref *rp; + + if (ascii) + return; + if (html && !n) { + fdprintf(ptid, "x X %s\n", type); + return; + } + for (rp = rstart; rp; rp = rp->next) + if (rp->cnt == n) { + if (html) + fdprintf(ptid, "x X %s %s\n", type, rp->name); + else + fdprintf(ptid, "x X %s %d,%d,%d,%d %s\n", + type, + linkhp, vpos + pts2u(1), + hpos + esc, vpos - pts * 8 / 10, + rp->name); + break; + } +} + +static void +ptlink(int n) +{ + _ptlink(n, links, "Link"); +} + +static void +ptulink(int n) +{ + _ptlink(n, ulinks, "ULink"); +} + +static void +ptyon(int i) +{ + struct contab *cp; + tchar c; + int k, nl; + filep savip; + + if ((cp = findmx(i)) == NULL || !cp->mx) { + nosuch(i); + return; + } + if (xfont != mfont) + ptfont(); + if (xpts != mpts || zoomtab[xfont] != mzoom) + ptps(); + if (lead) + ptlead(); + if (esc) + ptesc(); + fdprintf(ptid, "x X "); + savip = ip; + ip = (filep)cp->mx; + app = 1; + k = -1; + nl = 0; + while ((c = rbf()) != 0) { + if ((k = cbits(c)) != '\n') { + while (nl--) + oputs("\n+"); + nl = 0; + outascii(c); + } else + nl++; + } + while (nl-- > 1) + oputs("\n+"); + oput('\n'); + app = 0; + ip = savip; +} + +static void +ptchar1(struct charout *cp, int z) +{ + filep savip; + tchar i, *k, *savoline, *savolinep; + size_t savolinesz; + int savhpos, savvpos, savlettrack; + + savoline = oline; + savolinep = olinep; + savolinesz = olinesz; + olinep = oline = NULL; + olinesz = 0; + savlettrack = lettrack; + lettrack = 0; + savhpos = hpos + esc; + savvpos = vpos + lead; + savip = ip; + ip = cp->op; + app++; + fmtchar++; + while ((i = rbf()) != 0 && cbits(i) != '\n' && cbits(i) != FLSS) + pchar(i); + for (k = oline; k < olinep; ) + k = ptout0(k, olinep); + fmtchar--; + app--; + ip = savip; + free(oline); + oline = savoline; + olinep = savolinep; + olinesz = savolinesz; + lettrack = savlettrack; + esc = savhpos - hpos; + if (!z) + esc += cs ? cs : cp->width + lettrack; + lead = savvpos - vpos; +} + +static void +ptchar(int n, int z) +{ + struct charout *cp = &charout[n]; + int savbd; + + ptchar1(cp, z); + if (bd) { + bd -= HOR; + if (esc += bd) + ptesc(); + savbd = bd; + bd = 0; + ptchar1(cp, z); + bd = savbd; + if (iszbit(cp->ch)) + esc -= bd; + } + lettrack = 0; +} + +void +newpage(int n) /* called at end of each output page (we hope) */ +{ + int i; + + realpage++; + ptlead(); + vpos = 0; + if (ascii) + return; + fdprintf(ptid, "p%d\n", n); /* new page */ + for (i = 0; i <= nfonts; i++) { + if (fontbase[i] == NULL) + continue; + if (afmtab && fontbase[i]->afmpos) { + struct afmtab *a = afmtab[(fontbase[i]->afmpos)-1]; + if (a->encpath == NULL) + a->encpath = afmencodepath(a->path); + fdprintf(ptid, "x font %d %s %s %d\n", i, + macname(fontlab[i]), + a->encpath, (int)a->spec); + if (a->supply) + ptsupplyfont(a->fontname, a->supply); + } else if (fontbase[i]->namefont[0]) + fdprintf(ptid, "x font %d %s\n", i, macname(fontlab[i])); + } + ptps(); + ptfont(); + ptpapersize(); + ptcut(); + ptlocale(NULL); +} + +void +pttrailer(void) +{ + fdprintf(ptid, "x trailer\n"); +} + +void +ptstop(void) +{ + fdprintf(ptid, "x stop\n"); +} + +void +dostop(void) +{ + if (ascii) + return; + ptlead(); + vpos = 0; + /* fdprintf(ptid, "x xxx end of page\n");*/ + if (!nofeed) + pttrailer(); + ptlead(); + fdprintf(ptid, "x pause\n"); + flusho(); + mpts = mfont = 0; + ptesc(); + esc = po; + hpos = vpos = 0; /* probably in wrong place */ +} |