From 255b7ff3a0fcea3fb9f041c4ce371ef8ca66e5fa Mon Sep 17 00:00:00 2001 From: ben Date: Sat, 13 May 2006 15:52:03 +0000 Subject: [PATCH] Generate a more-or-less valid /FontDescriptor dictionary for non-standard fonts in PDF output. git-svn-id: svn://svn.tartarus.org/sgt/halibut@6684 cda61777-01e9-0310-a592-d414129be87e --- bk_pdf.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- in_afm.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ paper.h | 12 ++++++++++++ 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/bk_pdf.c b/bk_pdf.c index 99ad908..0a9336b 100644 --- a/bk_pdf.c +++ b/bk_pdf.c @@ -164,10 +164,23 @@ void pdf_backend(paragraph *sourceform, keywordlist *keywords, objtext(font, "\n]\n>>\n"); +#define FF_FIXEDPITCH 0x00000001 +#define FF_SERIF 0x00000002 +#define FF_SYMBOLIC 0x00000004 +#define FF_SCRIPT 0x00000008 +#define FF_NONSYMBOLIC 0x00000020 +#define FF_ITALIC 0x00000040 +#define FF_ALLCAP 0x00010000 +#define FF_SMALLCAP 0x00020000 +#define FF_FORCEBOLD 0x00040000 + if (!is_std_font(fe->font->info->name)){ object *widths = new_object(&olist); + object *fontdesc = new_object(&olist); int firstchar = -1, lastchar = -1; char buf[80]; + font_info const *fi = fe->font->info; + int flags; for (i = 0; i < 256; i++) if (fe->indices[i] >= 0) { if (firstchar < 0) firstchar = i; @@ -180,19 +193,45 @@ void pdf_backend(paragraph *sourceform, keywordlist *keywords, objtext(font, "\n"); objtext(widths, "[\n"); for (i = firstchar; i <= lastchar; i++) { - char buf[80]; double width; if (fe->indices[i] < 0) width = 0.0; else - width = fe->font->info->widths[fe->indices[i]]; + width = fi->widths[fe->indices[i]]; sprintf(buf, "%g\n", 1000.0 * width / FUNITS_PER_PT); objtext(widths, buf); } objtext(widths, "]\n"); + objtext(font, "/FontDescriptor "); + objref(font, fontdesc); + objtext(fontdesc, "<<\n/Type /FontDescriptor\n/Name /"); + objtext(fontdesc, fi->name); + flags = 0; + if (fi->italicangle) flags |= FF_ITALIC; + flags |= FF_NONSYMBOLIC; + sprintf(buf, "\n/Flags %d\n", flags); + objtext(fontdesc, buf); + sprintf(buf, "/FontBBox [%g %g %g %g]\n", fi->fontbbox[0], + fi->fontbbox[1], fi->fontbbox[2], fi->fontbbox[3]); + objtext(fontdesc, buf); + sprintf(buf, "/ItalicAngle %g\n", fi->italicangle); + objtext(fontdesc, buf); + sprintf(buf, "/Ascent %g\n", fi->ascent); + objtext(fontdesc, buf); + sprintf(buf, "/Descent %g\n", fi->descent); + objtext(fontdesc, buf); + sprintf(buf, "/CapHeight %g\n", fi->capheight); + objtext(fontdesc, buf); + sprintf(buf, "/XHeight %g\n", fi->xheight); + objtext(fontdesc, buf); + sprintf(buf, "/StemH %g\n", fi->stemh); + objtext(fontdesc, buf); + sprintf(buf, "/StemV %g\n", fi->stemv); + objtext(fontdesc, buf); + objtext(fontdesc, ">>\n"); } - objtext(font, ">>\n"); + objtext(font, "\n>>\n"); } objtext(resources, ">>\n>>\n"); diff --git a/in_afm.c b/in_afm.c index 0935bf3..f771af7 100644 --- a/in_afm.c +++ b/in_afm.c @@ -58,6 +58,9 @@ void read_afm_file(input *in) { fi->glyphs = NULL; fi->widths = NULL; fi->kerns = newtree234(kern_cmp); + fi->fontbbox[0] = fi->fontbbox[1] = fi->fontbbox[2] = fi->fontbbox[3] = 0; + fi->capheight = fi->xheight = fi->ascent = fi->descent = 0; + fi->stemh = fi->stemv = fi->italicangle = 0; in->pos.line = 0; line = afm_read_line(in); if (!line || !afm_require_key(line, "StartFontMetrics", in)) @@ -87,6 +90,63 @@ void read_afm_file(input *in) { goto giveup; } fi->name = dupstr(val); + } else if (strcmp(key, "FontBBox") == 0) { + int i; + for (i = 0; i < 3; i++) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 4); + goto giveup; + } + fi->fontbbox[i] = atof(val); + } + } else if (strcmp(key, "CapHeight") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->capheight = atof(val); + } else if (strcmp(key, "XHeight") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->xheight = atof(val); + } else if (strcmp(key, "Ascender") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->ascent = atof(val); + } else if (strcmp(key, "Descender") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->descent = atof(val); + } else if (strcmp(key, "CapHeight") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->capheight = atof(val); + } else if (strcmp(key, "StdHW") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->stemh = atof(val); + } else if (strcmp(key, "StdVW") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->stemv = atof(val); + } else if (strcmp(key, "ItalicAngle") == 0) { + if (!(val = strtok(NULL, " \t"))) { + error(err_afmval, &in->pos, key, 1); + goto giveup; + } + fi->italicangle = atof(val); } else if (strcmp(key, "StartCharMetrics") == 0) { char const **glyphs; int *widths; diff --git a/paper.h b/paper.h index b8d7698..68da8c2 100644 --- a/paper.h +++ b/paper.h @@ -87,6 +87,18 @@ struct font_info_Tag { * it), whose elements are indices into the above two arrays. */ unsigned short bmp[65536]; + /* + * Various bits of metadata needed for the /FontDescriptor dictionary + * in PDF. + */ + float fontbbox[4]; + float capheight; + float xheight; + float ascent; + float descent; + float stemv; + float stemh; + float italicangle; }; /* -- 2.11.0