Print this page
9718 update mandoc to 1.14.4

*** 1,9 **** ! /* $Id: term_ps.c,v 1.85 2017/06/07 17:38:26 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * --- 1,10 ---- ! /* $Id: term_ps.c,v 1.91 2017/11/10 23:42:52 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2017 Marc Espie <espie@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. *
*** 64,73 **** --- 65,75 ---- #define PS_NEWPAGE (1 << 2) /* new page, no words yet */ #define PS_BACKSP (1 << 3) /* last character was backspace */ size_t pscol; /* visible column (AFM units) */ size_t pscolnext; /* used for overstrike */ size_t psrow; /* visible row (AFM units) */ + size_t lastrow; /* psrow of the previous word */ char *psmarg; /* margin buf */ size_t psmargsz; /* margin buf size */ size_t psmargcur; /* cur index in margin buf */ char last; /* last non-backspace seen */ enum termfont lastf; /* last set font */
*** 75,84 **** --- 77,87 ---- size_t scale; /* font scaling factor */ size_t pages; /* number of pages shown */ size_t lineheight; /* line height (AFM units) */ size_t top; /* body top (AFM units) */ size_t bottom; /* body bottom (AFM units) */ + const char *medianame; /* for DocumentMedia and PageSize */ size_t height; /* page height (AFM units */ size_t width; /* page width (AFM units) */ size_t lastwidth; /* page width before last ll */ size_t left; /* body left (AFM units) */ size_t header; /* header pos (AFM units) */
*** 106,116 **** static void ps_printf(struct termp *, const char *, ...) __attribute__((__format__ (__printf__, 2, 3))); static void ps_putchar(struct termp *, char); static void ps_setfont(struct termp *, enum termfont); static void ps_setwidth(struct termp *, int, int); ! static struct termp *pspdf_alloc(const struct manoutput *); static void pdf_obj(struct termp *, size_t); /* * We define, for the time being, three fonts: bold, oblique/italic, and * normal (roman). The following table hard-codes the font metrics for --- 109,119 ---- static void ps_printf(struct termp *, const char *, ...) __attribute__((__format__ (__printf__, 2, 3))); static void ps_putchar(struct termp *, char); static void ps_setfont(struct termp *, enum termfont); static void ps_setwidth(struct termp *, int, int); ! static struct termp *pspdf_alloc(const struct manoutput *, enum termtype); static void pdf_obj(struct termp *, size_t); /* * We define, for the time being, three fonts: bold, oblique/italic, and * normal (roman). The following table hard-codes the font metrics for
*** 509,548 **** }; void * pdf_alloc(const struct manoutput *outopts) { ! struct termp *p; ! ! if (NULL != (p = pspdf_alloc(outopts))) ! p->type = TERMTYPE_PDF; ! ! return p; } void * ps_alloc(const struct manoutput *outopts) { ! struct termp *p; ! ! if (NULL != (p = pspdf_alloc(outopts))) ! p->type = TERMTYPE_PS; ! ! return p; } static struct termp * ! pspdf_alloc(const struct manoutput *outopts) { struct termp *p; unsigned int pagex, pagey; size_t marginx, marginy, lineheight; const char *pp; p = mandoc_calloc(1, sizeof(*p)); p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol)); p->maxtcol = 1; p->enc = TERMENC_ASCII; p->fontq = mandoc_reallocarray(NULL, (p->fontsz = 8), sizeof(*p->fontq)); p->fontq[0] = p->fontl = TERMFONT_NONE; --- 512,542 ---- }; void * pdf_alloc(const struct manoutput *outopts) { ! return pspdf_alloc(outopts, TERMTYPE_PDF); } void * ps_alloc(const struct manoutput *outopts) { ! return pspdf_alloc(outopts, TERMTYPE_PS); } static struct termp * ! pspdf_alloc(const struct manoutput *outopts, enum termtype type) { struct termp *p; unsigned int pagex, pagey; size_t marginx, marginy, lineheight; const char *pp; p = mandoc_calloc(1, sizeof(*p)); p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol)); p->maxtcol = 1; + p->type = type; p->enc = TERMENC_ASCII; p->fontq = mandoc_reallocarray(NULL, (p->fontsz = 8), sizeof(*p->fontq)); p->fontq[0] = p->fontl = TERMFONT_NONE;
*** 557,566 **** --- 551,561 ---- p->setwidth = ps_setwidth; p->width = ps_width; /* Default to US letter (millimetres). */ + p->ps->medianame = "Letter"; pagex = 216; pagey = 279; /* * The ISO-269 paper sizes can be calculated automatically, but
*** 568,591 **** * do that. So just do it the easy way for now. Since this * only happens once, I'm not terribly concerned. */ pp = outopts->paper; ! if (pp && strcasecmp(pp, "letter")) { ! if (0 == strcasecmp(pp, "a3")) { pagex = 297; pagey = 420; ! } else if (0 == strcasecmp(pp, "a4")) { pagex = 210; pagey = 297; ! } else if (0 == strcasecmp(pp, "a5")) { pagex = 148; pagey = 210; ! } else if (0 == strcasecmp(pp, "legal")) { pagex = 216; pagey = 356; ! } else if (2 != sscanf(pp, "%ux%u", &pagex, &pagey)) warnx("%s: Unknown paper", pp); } /* * This MUST be defined before any PNT2AFM or AFM2PNT --- 563,592 ---- * do that. So just do it the easy way for now. Since this * only happens once, I'm not terribly concerned. */ pp = outopts->paper; ! if (pp != NULL && strcasecmp(pp, "letter") != 0) { ! if (strcasecmp(pp, "a3") == 0) { ! p->ps->medianame = "A3"; pagex = 297; pagey = 420; ! } else if (strcasecmp(pp, "a4") == 0) { ! p->ps->medianame = "A4"; pagex = 210; pagey = 297; ! } else if (strcasecmp(pp, "a5") == 0) { ! p->ps->medianame = "A5"; pagex = 148; pagey = 210; ! } else if (strcasecmp(pp, "legal") == 0) { ! p->ps->medianame = "Legal"; pagex = 216; pagey = 356; ! } else if (sscanf(pp, "%ux%u", &pagex, &pagey) == 2) ! p->ps->medianame = "CustomSize"; ! else warnx("%s: Unknown paper", pp); } /* * This MUST be defined before any PNT2AFM or AFM2PNT
*** 594,605 **** p->ps->scale = 11; /* Remember millimetres -> AFM units. */ ! pagex = PNT2AFM(p, ((double)pagex * 2.834)); ! pagey = PNT2AFM(p, ((double)pagey * 2.834)); /* Margins are 1/9 the page x and y. */ marginx = (size_t)((double)pagex / 9.0); marginy = (size_t)((double)pagey / 9.0); --- 595,606 ---- p->ps->scale = 11; /* Remember millimetres -> AFM units. */ ! pagex = PNT2AFM(p, ((double)pagex * 72.0 / 25.4)); ! pagey = PNT2AFM(p, ((double)pagey * 72.0 / 25.4)); /* Margins are 1/9 the page x and y. */ marginx = (size_t)((double)pagex / 9.0); marginy = (size_t)((double)pagey / 9.0);
*** 731,751 **** int i; size_t len, base; /* * Close out a page that we've already flushed to output. In ! * PostScript, we simply note that the page must be showed. In * PDF, we must now create the Length, Resource, and Page node * for the page contents. */ assert(p->ps->psmarg && p->ps->psmarg[0]); ps_printf(p, "%s", p->ps->psmarg); if (TERMTYPE_PS != p->type) { - ps_printf(p, "ET\n"); - len = p->ps->pdfbytes - p->ps->pdflastpg; base = p->ps->pages * 4 + p->ps->pdfbody; ps_printf(p, "endstream\nendobj\n"); --- 732,750 ---- int i; size_t len, base; /* * Close out a page that we've already flushed to output. In ! * PostScript, we simply note that the page must be shown. In * PDF, we must now create the Length, Resource, and Page node * for the page contents. */ assert(p->ps->psmarg && p->ps->psmarg[0]); ps_printf(p, "%s", p->ps->psmarg); if (TERMTYPE_PS != p->type) { len = p->ps->pdfbytes - p->ps->pdflastpg; base = p->ps->pages * 4 + p->ps->pdfbody; ps_printf(p, "endstream\nendobj\n");
*** 757,767 **** pdf_obj(p, base + 2); ps_printf(p, "<<\n/ProcSet [/PDF /Text]\n"); ps_printf(p, "/Font <<\n"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, "/F%d %d 0 R\n", i, 3 + i); ! ps_printf(p, ">>\n>>\n"); /* Page node. */ pdf_obj(p, base + 3); ps_printf(p, "<<\n"); ps_printf(p, "/Type /Page\n"); --- 756,766 ---- pdf_obj(p, base + 2); ps_printf(p, "<<\n/ProcSet [/PDF /Text]\n"); ps_printf(p, "/Font <<\n"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, "/F%d %d 0 R\n", i, 3 + i); ! ps_printf(p, ">>\n>>\nendobj\n"); /* Page node. */ pdf_obj(p, base + 3); ps_printf(p, "<<\n"); ps_printf(p, "/Type /Page\n");
*** 822,832 **** ps_printf(p, "]\n>>\nendobj\n"); pdf_obj(p, base); ps_printf(p, "<<\n"); ps_printf(p, "/Type /Catalog\n"); ps_printf(p, "/Pages 2 0 R\n"); ! ps_printf(p, ">>\n"); xref = p->ps->pdfbytes; ps_printf(p, "xref\n"); ps_printf(p, "0 %zu\n", base + 1); ps_printf(p, "0000000000 65535 f \n"); --- 821,831 ---- ps_printf(p, "]\n>>\nendobj\n"); pdf_obj(p, base); ps_printf(p, "<<\n"); ps_printf(p, "/Type /Catalog\n"); ps_printf(p, "/Pages 2 0 R\n"); ! ps_printf(p, ">>\nendobj\n"); xref = p->ps->pdfbytes; ps_printf(p, "xref\n"); ps_printf(p, "0 %zu\n", base + 1); ps_printf(p, "0000000000 65535 f \n");
*** 846,855 **** --- 845,855 ---- } static void ps_begin(struct termp *p) { + size_t width, height; int i; /* * Print margins into margin buffer. Nothing gets output to the * screen yet, so we don't need to initialise the primary state.
*** 863,872 **** --- 863,873 ---- /*p->ps->pdfbytes = 0;*/ p->ps->psmargcur = 0; p->ps->flags = PS_MARGINS; p->ps->pscol = p->ps->left; p->ps->psrow = p->ps->header; + p->ps->lastrow = 0; /* impossible row */ ps_setfont(p, TERMFONT_NONE); (*p->headf)(p, p->argf); (*p->endline)(p);
*** 887,911 **** * Print header and initialise page state. Following this, * stuff gets printed to the screen, so make sure we're sane. */ if (TERMTYPE_PS == p->type) { ps_printf(p, "%%!PS-Adobe-3.0\n"); ps_printf(p, "%%%%DocumentData: Clean7Bit\n"); ps_printf(p, "%%%%Orientation: Portrait\n"); ps_printf(p, "%%%%Pages: (atend)\n"); ps_printf(p, "%%%%PageOrder: Ascend\n"); ! ps_printf(p, "%%%%DocumentMedia: " ! "Default %zu %zu 0 () ()\n", ! (size_t)AFM2PNT(p, p->ps->width), ! (size_t)AFM2PNT(p, p->ps->height)); ps_printf(p, "%%%%DocumentNeededResources: font"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, " %s", fonts[i].name); ! ps_printf(p, "\n%%%%EndComments\n"); } else { ps_printf(p, "%%PDF-1.1\n"); pdf_obj(p, 1); ps_printf(p, "<<\n"); ps_printf(p, ">>\n"); --- 888,935 ---- * Print header and initialise page state. Following this, * stuff gets printed to the screen, so make sure we're sane. */ if (TERMTYPE_PS == p->type) { + width = AFM2PNT(p, p->ps->width); + height = AFM2PNT(p, p->ps->height); + ps_printf(p, "%%!PS-Adobe-3.0\n"); ps_printf(p, "%%%%DocumentData: Clean7Bit\n"); ps_printf(p, "%%%%Orientation: Portrait\n"); ps_printf(p, "%%%%Pages: (atend)\n"); ps_printf(p, "%%%%PageOrder: Ascend\n"); ! ps_printf(p, "%%%%DocumentMedia: man-%s %zu %zu 0 () ()\n", ! p->ps->medianame, width, height); ps_printf(p, "%%%%DocumentNeededResources: font"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, " %s", fonts[i].name); ! ps_printf(p, "\n%%%%DocumentSuppliedResources: " ! "procset MandocProcs 1.0 0\n"); ! ps_printf(p, "%%%%EndComments\n"); ! ps_printf(p, "%%%%BeginProlog\n"); ! ps_printf(p, "%%%%BeginResource: procset MandocProcs " ! "10170 10170\n"); ! /* The font size is effectively hard-coded for now. */ ! ps_printf(p, "/fs %zu def\n", p->ps->scale); ! for (i = 0; i < (int)TERMFONT__MAX; i++) ! ps_printf(p, "/f%d { /%s fs selectfont } def\n", ! i, fonts[i].name); ! ps_printf(p, "/s { 3 1 roll moveto show } bind def\n"); ! ps_printf(p, "/c { exch currentpoint exch pop " ! "moveto show } bind def\n"); ! ps_printf(p, "%%%%EndResource\n"); ! ps_printf(p, "%%%%EndProlog\n"); ! ps_printf(p, "%%%%BeginSetup\n"); ! ps_printf(p, "%%%%BeginFeature: *PageSize %s\n", ! p->ps->medianame); ! ps_printf(p, "<</PageSize [%zu %zu]>>setpagedevice\n", ! width, height); ! ps_printf(p, "%%%%EndFeature\n"); ! ps_printf(p, "%%%%EndSetup\n"); } else { ps_printf(p, "%%PDF-1.1\n"); pdf_obj(p, 1); ps_printf(p, "<<\n"); ps_printf(p, ">>\n");
*** 916,926 **** ps_printf(p, "<<\n"); ps_printf(p, "/Type /Font\n"); ps_printf(p, "/Subtype /Type1\n"); ps_printf(p, "/Name /F%d\n", i); ps_printf(p, "/BaseFont /%s\n", fonts[i].name); ! ps_printf(p, ">>\n"); } } p->ps->pdfbody = (size_t)TERMFONT__MAX + 3; p->ps->pscol = p->ps->left; --- 940,950 ---- ps_printf(p, "<<\n"); ps_printf(p, "/Type /Font\n"); ps_printf(p, "/Subtype /Type1\n"); ps_printf(p, "/Name /F%d\n", i); ps_printf(p, "/BaseFont /%s\n", fonts[i].name); ! ps_printf(p, ">>\nendobj\n"); } } p->ps->pdfbody = (size_t)TERMFONT__MAX + 3; p->ps->pscol = p->ps->left;
*** 941,953 **** if (PS_NEWPAGE & p->ps->flags) { if (TERMTYPE_PS == p->type) { ps_printf(p, "%%%%Page: %zu %zu\n", p->ps->pages + 1, p->ps->pages + 1); ! ps_printf(p, "/%s %zu selectfont\n", ! fonts[(int)p->ps->lastf].name, ! p->ps->scale); } else { pdf_obj(p, p->ps->pdfbody + p->ps->pages * 4); ps_printf(p, "<<\n"); ps_printf(p, "/Length %zu 0 R\n", --- 965,975 ---- if (PS_NEWPAGE & p->ps->flags) { if (TERMTYPE_PS == p->type) { ps_printf(p, "%%%%Page: %zu %zu\n", p->ps->pages + 1, p->ps->pages + 1); ! ps_printf(p, "f%d\n", (int)p->ps->lastf); } else { pdf_obj(p, p->ps->pdfbody + p->ps->pages * 4); ps_printf(p, "<<\n"); ps_printf(p, "/Length %zu 0 R\n",
*** 968,981 **** ps_printf(p, "BT\n/F%d %zu Tf\n", (int)p->ps->lastf, p->ps->scale); ps_printf(p, "%.3f %.3f Td\n(", AFM2PNT(p, p->ps->pscol), AFM2PNT(p, p->ps->psrow)); ! } else ! ps_printf(p, "%.3f %.3f moveto\n(", ! AFM2PNT(p, p->ps->pscol), AFM2PNT(p, p->ps->psrow)); p->ps->flags |= PS_INLINE; } assert( ! (PS_NEWPAGE & p->ps->flags)); --- 990,1006 ---- ps_printf(p, "BT\n/F%d %zu Tf\n", (int)p->ps->lastf, p->ps->scale); ps_printf(p, "%.3f %.3f Td\n(", AFM2PNT(p, p->ps->pscol), AFM2PNT(p, p->ps->psrow)); ! } else { ! ps_printf(p, "%.3f", AFM2PNT(p, p->ps->pscol)); ! if (p->ps->psrow != p->ps->lastrow) ! ps_printf(p, " %.3f", AFM2PNT(p, p->ps->psrow)); + ps_printf(p, "("); + } p->ps->flags |= PS_INLINE; } assert( ! (PS_NEWPAGE & p->ps->flags));
*** 1019,1032 **** */ if ( ! (PS_INLINE & p->ps->flags)) return; ! if (TERMTYPE_PS != p->type) { ps_printf(p, ") Tj\nET\n"); ! } else ! ps_printf(p, ") show\n"); p->ps->flags &= ~PS_INLINE; } /* If we have a `last' char that wasn't printed yet, print it now. */ --- 1044,1061 ---- */ if ( ! (PS_INLINE & p->ps->flags)) return; ! if (TERMTYPE_PS != p->type) ps_printf(p, ") Tj\nET\n"); ! else if (p->ps->psrow == p->ps->lastrow) ! ps_printf(p, ")c\n"); ! else { ! ps_printf(p, ")s\n"); ! p->ps->lastrow = p->ps->psrow; ! } p->ps->flags &= ~PS_INLINE; } /* If we have a `last' char that wasn't printed yet, print it now. */
*** 1241,1252 **** if (PS_NEWPAGE & p->ps->flags) return; if (TERMTYPE_PS == p->type) ! ps_printf(p, "/%s %zu selectfont\n", ! fonts[(int)f].name, p->ps->scale); else ps_printf(p, "/F%d %zu Tf\n", (int)f, p->ps->scale); } --- 1270,1280 ---- if (PS_NEWPAGE & p->ps->flags) return; if (TERMTYPE_PS == p->type) ! ps_printf(p, "f%d\n", (int)f); else ps_printf(p, "/F%d %zu Tf\n", (int)f, p->ps->scale); }