/* * 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 #include #include "tdef.h" #include #include #include #include #ifdef EUC #include #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; static 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; dprintf(ptid, "x T %s\n", devname); dprintf(ptid, "x res %d %d %d\n", Inch, Hor, Vert); dprintf(ptid, "x init\n"); /* do initialization for particular device */ /* for (i = 1; i <= nfonts; i++) dprintf(ptid, "x font %d %s\n", i, fontbase[i]->namefont); dprintf(ptid, "x xxx fonts=%d sizes=%d unit=%d\n", nfonts, nsizes, Unitwidth); dprintf(ptid, "x xxx nchtab=%d lchname=%d nfitab=%d\n", dev.nchtab, dev.lchname, dev.nchtab+128-32); dprintf(ptid, "x xxx sizes:\nx xxx "); for (i = 0; i < nsizes; i++) dprintf(ptid, " %d", pstab[i]); dprintf(ptid, "\nx xxx chars:\nx xxx "); for (i = 0; i < dev.nchtab; i++) dprintf(ptid, " %s", &chname[chtab[i]]); dprintf(ptid, "\nx xxx\n"); */ #ifdef EUC ptlocale(setlocale(LC_CTYPE, NULL)); #endif /* EUC */ free(termtab); } void specnames(void) { static struct { int *n; const 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 const 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); /* dprintf(ptid, "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos); */ dprintf(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(); dprintf(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) dprintf(ptid, "x H -23 %g\n", f); else dprintf(ptid, "x H %d\n", j); return(pi+outsize); } if (k == SLANT) { if (xflag) { xfont = fbits(i); if (xfont != mfont) ptfont(); } dprintf(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: dprintf(ptid, "D%c %d\n", c, dx); /* dx is diameter */ w = 0; hpos += dx; break; case DRAWELLIPSE: case DRAWELLIPSEFI: dprintf(ptid, "D%c %d %d\n", c, dx, dy); w = 0; hpos += dx; break; case DRAWLINE: /* line */ k = cbits(pi[2]); dprintf(ptid, "D%c %d %d ", DRAWLINE, dx, dy); if (k < 128) dprintf(ptid, "%c\n", k); else dprintf(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; dprintf(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 */ dprintf(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 */ dprintf(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; dprintf(ptid, " %d %d", dx, dy); hpos += dx; vpos += dy; } dprintf(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) { dprintf(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) { dprintf(ptid, "CPS%s\n", a->nametab[j]); } else { dprintf(ptid, "N%d\n", k - (html ? 0 : (nchtab + 128)) ); } } else { dprintf(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) dprintf(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)) dprintf(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))) dprintf(ptid, "s-23 %g\n", s); else dprintf(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; dprintf(ptid, "f%d\n", xfont); mtrack = 0; pttrack(1); pthorscale(1); } void ptfpcmd(int f, const char *s, char *path, int flags) { if (ascii) return; dprintf(ptid, "x font %d %s", f, s); if (path) { dprintf(ptid, " %s", path); if (flags) dprintf(ptid, " %d", flags); } dprintf(ptid, "\n"); ptfont(); /* make sure that it gets noticed */ } void ptlead(void) { vpos += lead; if (!ascii) dprintf(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 dprintf(ptid, "%d", esc); } else dprintf(ptid, "H%d\n", hpos); esc = 0; } void ptsupplyfont(char *fontname, char *file) { if (ascii) return; dprintf(ptid, "x X SupplyFont %s %s\n", fontname, file); } void ptpapersize(void) { if (ascii || mediasize.flag == 0) return; dprintf(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) dprintf(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; dprintf(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) { dprintf(ptid, "x X Anchor %s\n", rp->name); } else { dprintf(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) { dprintf(ptid, "x X %s\n", type); return; } for (rp = rstart; rp; rp = rp->next) if (rp->cnt == n) { if (html) dprintf(ptid, "x X %s %s\n", type, rp->name); else dprintf(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(); dprintf(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; dprintf(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); dprintf(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]) dprintf(ptid, "x font %d %s\n", i, macname(fontlab[i])); } ptps(); ptfont(); ptpapersize(); ptcut(); ptlocale(NULL); } void pttrailer(void) { dprintf(ptid, "x trailer\n"); } void ptstop(void) { dprintf(ptid, "x stop\n"); } void dostop(void) { if (ascii) return; ptlead(); vpos = 0; /* dprintf(ptid, "x xxx end of page\n");*/ if (!nofeed) pttrailer(); ptlead(); dprintf(ptid, "x pause\n"); flusho(); mpts = mfont = 0; ptesc(); esc = po; hpos = vpos = 0; /* probably in wrong place */ }