From 44407fea05657f91da34fd83428b67e7100ab62b Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 14 May 2006 13:42:48 +0000 Subject: [PATCH] Fairly ropey font-embedding support. In particular, the PDF output is technically incorrect, though it works perfectly well with xpdf. To do it properly requires actually parsing the unencrypted part of a Type 1 font, which will be a bit tedious in C. git-svn-id: svn://svn.tartarus.org/sgt/halibut@6685 cda61777-01e9-0310-a592-d414129be87e --- Makefile | 2 +- bk_pdf.c | 15 ++++++++++++++- bk_ps.c | 25 ++++++++++++++++++++++--- halibut.h | 5 +++++ in_afm.c | 1 + in_pf.c | 34 ++++++++++++++++++++++++++++++++++ input.c | 3 +++ paper.h | 4 ++++ psdata.c | 1 + 9 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 in_pf.c diff --git a/Makefile b/Makefile index 8f53a51..0cb80a7 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ CFLAGS += -I$(LIBCHARSET_SRCDIR) -I$(LIBCHARSET_OBJDIR) include $(LIBCHARSET_SRCDIR)Makefile MODULES := main malloc ustring error help licence version misc tree234 -MODULES += input in_afm keywords contents index biblio +MODULES += input in_afm in_pf keywords contents index biblio MODULES += bk_text bk_html bk_whlp bk_man bk_info bk_paper bk_ps bk_pdf MODULES += winhelp psdata wcwidth diff --git a/bk_pdf.c b/bk_pdf.c index 0a9336b..0a36ad9 100644 --- a/bk_pdf.c +++ b/bk_pdf.c @@ -228,7 +228,20 @@ void pdf_backend(paragraph *sourceform, keywordlist *keywords, objtext(fontdesc, buf); sprintf(buf, "/StemV %g\n", fi->stemv); objtext(fontdesc, buf); - objtext(fontdesc, ">>\n"); + if (fi->fp) { + object *fontfile = new_object(&olist); + char buf[513]; + size_t len; + rewind(fi->fp); + do { + len = fread(buf, 1, sizeof(buf)-1, fi->fp); + buf[len] = 0; + objstream(fontfile, buf); + } while (len == sizeof(buf)-1); + objtext(fontdesc, "/FontFile "); + objref(fontdesc, fontfile); + } + objtext(fontdesc, "\n>>\n"); } objtext(font, "\n>>\n"); diff --git a/bk_ps.c b/bk_ps.c index 95d1383..496a7f6 100644 --- a/bk_ps.c +++ b/bk_ps.c @@ -56,8 +56,13 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords, fprintf(fp, "%%%%DocumentNeededResources:\n"); for (fe = doc->fonts->head; fe; fe = fe->next) /* XXX This may request the same font multiple times. */ - fprintf(fp, "%%%%+ font %s\n", fe->font->info->name); + if (!fe->font->info->fp) + fprintf(fp, "%%%%+ font %s\n", fe->font->info->name); fprintf(fp, "%%%%DocumentSuppliedResources: procset Halibut 0 0\n"); + for (fe = doc->fonts->head; fe; fe = fe->next) + /* XXX This may request the same font multiple times. */ + if (fe->font->info->fp) + fprintf(fp, "%%%%+ font %s\n", fe->font->info->name); fprintf(fp, "%%%%EndComments\n"); fprintf(fp, "%%%%BeginProlog\n"); @@ -94,9 +99,23 @@ void ps_backend(paragraph *sourceform, keywordlist *keywords, if (p->type == para_VersionID) ps_comment(fp, "% ", p->words); - for (fe = doc->fonts->head; fe; fe = fe->next) + for (fe = doc->fonts->head; fe; fe = fe->next) { /* XXX This may request the same font multiple times. */ - fprintf(fp, "%%%%IncludeResource: font %s\n", fe->font->info->name); + if (fe->font->info->fp) { + char buf[512]; + size_t len; + fprintf(fp, "%%%%BeginResource: font %s\n", fe->font->info->name); + rewind(fe->font->info->fp); + do { + len = fread(buf, 1, sizeof(buf), fe->font->info->fp); + fwrite(buf, 1, len, fp); + } while (len == sizeof(buf)); + fprintf(fp, "%%%%EndResource\n"); + } else { + fprintf(fp, "%%%%IncludeResource: font %s\n", + fe->font->info->name); + } + } /* * Re-encode the fonts. diff --git a/halibut.h b/halibut.h index eb62b9e..d109ade 100644 --- a/halibut.h +++ b/halibut.h @@ -391,6 +391,11 @@ paragraph *read_input(input *in, indexdata *idx); void read_afm_file(input *in); /* + * in_pf.c + */ +void read_pfa_file(input *in); + +/* * keywords.c */ struct keywordlist_Tag { diff --git a/in_afm.c b/in_afm.c index f771af7..6b7a9f3 100644 --- a/in_afm.c +++ b/in_afm.c @@ -57,6 +57,7 @@ void read_afm_file(input *in) { fi->nglyphs = 0; fi->glyphs = NULL; fi->widths = NULL; + fi->fp = 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; diff --git a/in_pf.c b/in_pf.c new file mode 100644 index 0000000..50e663e --- /dev/null +++ b/in_pf.c @@ -0,0 +1,34 @@ +#include +#include "halibut.h" +#include "paper.h" + +void read_pfa_file(input *in) { + char buf[512], *p; + size_t len; + char *fontname; + font_info *fi; + + len = fread(buf, 1, sizeof(buf) - 1, in->currfp); + buf[len] = 0; + if (strncmp(buf, "%!FontType1-", 12) && + strncmp(buf, "%!PS-AdobeFont-", 15)) + return; + p = buf; + p += strcspn(p, ":") + 1; + p += strspn(p, " \t"); + len = strcspn(p, " \t"); + fontname = snewn(len + 1, char); + memcpy(fontname, p, len); + fontname[len] = 0; + for (fi = all_fonts; fi; fi = fi->next) { + if (strcmp(fi->name, fontname) == 0) { + fi->fp = in->currfp; + sfree(fontname); + return; + } + } + fclose(in->currfp); + sfree(fontname); +} + + diff --git a/input.c b/input.c index 6e20488..d1b529d 100644 --- a/input.c +++ b/input.c @@ -1579,6 +1579,9 @@ paragraph *read_input(input *in, indexdata *idx) { if (strcmp(in->filenames[in->currindex] + strlen(in->filenames[in->currindex]) - 4, ".afm") == 0) read_afm_file(in); + else if (strcmp(in->filenames[in->currindex] + + strlen(in->filenames[in->currindex]) - 4, ".pfa") == 0) + read_pfa_file(in); else read_file(&hptr, in, idx, macros); } diff --git a/paper.h b/paper.h index 68da8c2..2811f37 100644 --- a/paper.h +++ b/paper.h @@ -65,6 +65,10 @@ struct font_info_Tag { */ const char *name; /* + * The file containing this font, if any. + */ + FILE *fp; + /* * An array of pointers to the available glyph names, and their * corresponding character widths. These two arrays have * parallel indices. diff --git a/psdata.c b/psdata.c index 68ee58c..8c3b9cd 100644 --- a/psdata.c +++ b/psdata.c @@ -4095,6 +4095,7 @@ void init_std_fonts(void) { if (done) return; for (i = 0; i < (int)lenof(ps_std_fonts); i++) { font_info *fi = snew(font_info); + fi->fp = NULL; fi->name = ps_std_fonts[i].name; fi->nglyphs = lenof(ps_std_glyphs) - 1; fi->glyphs = ps_std_glyphs; -- 2.11.0