ref: e02a200628b9f7e0b2a98d6d051e4a7610ecc739
parent: aac54a6c5e68705d99d817575b95a144f4749649
author: Ali Gholami Rudi <ali@rudi.ir>
date: Mon Apr 2 08:03:41 EDT 2018
pdf: embedding Type 1 fonts
--- a/pdf.c
+++ b/pdf.c
@@ -1,7 +1,9 @@
+#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "post.h"
static char *pdf_title; /* document title */
@@ -84,35 +86,90 @@
{}
+/* the length of the clear-text, encrypted, and fixed-content portions */
+static int type1lengths(char *t1, int l, int *l1, int *l2, int *l3)
+{+ int i;
+ char *cleartext = t1;
+ char *encrypted = NULL;
+ char *fixedcont = NULL;
+ for (i = 0; i < l - 5 && !encrypted; i++)
+ if (t1[i] == 'e' && !memcmp("eexec", t1 + i, 5))+ encrypted = t1 + i;
+ if (!encrypted)
+ return 1;
+ for (; i < l - 512 && !fixedcont; i++)
+ if (t1[i] == '0' && !memcmp("00000", t1 + i, 5))+ fixedcont = t1 + i;
+ *l1 = encrypted - cleartext;
+ *l2 = fixedcont ? fixedcont - cleartext : 0;
+ return 0;
+}
+
+/* return font type: 't': TrueType, '1': Type 1, 'o': OpenType */
+static int fonttype(char *path)
+{+ char *ext = strrchr(path, '.');
+ if (ext && !strcmp(".ttf", ext))+ return 't';
+ if (ext && !strcmp(".otf", ext))+ return 'o';
+ return '1';
+}
+
/* include font descriptor; returns object id */
static int psfont_writedesc(struct psfont *ps)
{- int c, i;
int str_obj = -1;
int des_obj;
- char *ext = strrchr(ps->path, '.');
- if (ext && !strcmp(".ttf", ext)) {- FILE *fp = fopen(ps->path, "r");
+ char buf[1 << 10];
+ int i;
+ if (fonttype(ps->path) == '1' || fonttype(ps->path) == 't') {+ int fd = open(ps->path, O_RDONLY);
+ struct sbuf *ffsb = sbuf_make();
struct sbuf *sb = sbuf_make();
- c = fgetc(fp);
- for (i = 0; c != EOF; i++) {- sbuf_printf(sb, "%02x", c);
- c = fgetc(fp);
- if (i % 40 == 39 && c != EOF)
+ int l1 = 0, l2 = 0, l3 = 0;
+ int nr;
+ /* reading the font file */
+ while ((nr = read(fd, buf, sizeof(buf))) > 0)
+ sbuf_mem(ffsb, buf, nr);
+ close(fd);
+ l1 = sbuf_len(ffsb);
+ /* initialize Type 1 lengths */
+ if (fonttype(ps->path) == '1') {+ if (type1lengths(sbuf_buf(ffsb), sbuf_len(ffsb),
+ &l1, &l2, &l3))
+ l1 = 0;
+ /* remove the fixed-content portion of the font */
+ if (l3)
+ sbuf_cut(ffsb, l1 + l2);
+ l1 -= l3;
+ }
+ /* encoding file contents */
+ for (i = 0; i < sbuf_len(ffsb); i++) {+ sbuf_printf(sb, "%02x", (unsigned char) sbuf_buf(ffsb)[i]);
+ if (i % 40 == 39 && i + 1 < sbuf_len(ffsb))
sbuf_chr(sb, '\n');
}
sbuf_str(sb, ">\n");
- fclose(fp);
- str_obj = obj_beg(0);
- pdfout("<<\n");- pdfout(" /Filter /ASCIIHexDecode\n");- pdfout(" /Length %d\n", sbuf_len(sb));- pdfout(" /Length1 %d\n", i);- pdfout(">>\n");- pdfout("stream\n");- pdfout("%s", sbuf_buf(sb));- pdfout("endstream\n");- obj_end();
+ /* write font data if it has nonzero length */
+ if (l1) {+ str_obj = obj_beg(0);
+ pdfout("<<\n");+ pdfout(" /Filter /ASCIIHexDecode\n");+ pdfout(" /Length %d\n", sbuf_len(sb));+ pdfout(" /Length1 %d\n", l1);+ if (fonttype(ps->path) == '1')
+ pdfout(" /Length2 %d\n", l2);+ if (fonttype(ps->path) == '1')
+ pdfout(" /Length3 %d\n", l3);+ pdfout(">>\n");+ pdfout("stream\n");+ pdfout("%s", sbuf_buf(sb));+ pdfout("endstream\n");+ obj_end();
+ }
+ sbuf_free(ffsb);
sbuf_free(sb);
}
/* the font descriptor */
@@ -129,7 +186,8 @@
pdfout(" /Ascent 100\n"); pdfout(" /Descent 100\n");if (str_obj >= 0)
- pdfout(" /FontFile2 %d 0 R\n", str_obj);+ pdfout(" /FontFile%s %d 0 R\n",+ fonttype(ps->path) == 't' ? "2" : "", str_obj);
pdfout(">>\n");obj_end();
return des_obj;
@@ -140,7 +198,6 @@
{int i;
int enc_obj;
- char *ext = strrchr(ps->path, '.');
struct font *fn = dev_fontopen(ps->desc);
int map[256];
int gcnt = ix < ps->lastfn ? 256 : ps->lastgl;
@@ -164,8 +221,10 @@
obj_beg(ps->obj[ix]);
pdfout("<<\n"); pdfout(" /Type /Font\n");- pdfout(" /Subtype /%s\n",- ext && !strcmp(".ttf", ext) ? "TrueType" : "Type1");+ if (fonttype(ps->path) == 't')
+ pdfout(" /Subtype /TrueType\n");+ else
+ pdfout(" /Subtype /Type1\n"); pdfout(" /BaseFont /%s\n", ps->name); pdfout(" /FirstChar 0\n"); pdfout(" /LastChar %d\n", gcnt - 1);@@ -462,6 +521,7 @@
sbuf_printf(pg, "%s l\n", pdfpos(o_h, o_v));
}
+/* draw circle/ellipse quadrant */
static void drawquad(int ch, int cv)
{long b = 551915;
@@ -485,6 +545,7 @@
outrel(ch / 2, cv / 2);
}
+/* draw a circle */
void drawc(int c)
{drawquad(+c, +c);
@@ -494,6 +555,7 @@
outrel(c, 0);
}
+/* draw an ellipse */
void drawe(int h, int v)
{drawquad(+h, +v);
@@ -503,11 +565,13 @@
outrel(h, 0);
}
+/* draw an arc */
void drawa(int h1, int v1, int h2, int v2)
{- outrel(h1 + h2, v1 + v2);
+ drawl(h1 + h2, v1 + v2);
}
+/* draw an spline */
void draws(int h1, int v1, int h2, int v2)
{outrel(h1, v1);
--- a/post.h
+++ b/post.h
@@ -117,3 +117,5 @@
void sbuf_str(struct sbuf *sbuf, char *s);
void sbuf_printf(struct sbuf *sbuf, char *s, ...);
void sbuf_chr(struct sbuf *sbuf, int c);
+void sbuf_mem(struct sbuf *sbuf, char *s, int len);
+void sbuf_cut(struct sbuf *sb, int len);
--
⑨