9 static char *pdf_title
; /* document title */
10 static int pdf_width
; /* page width */
11 static int pdf_height
; /* page height */
12 static int pdf_pages
; /* pages object id */
13 static int pdf_root
; /* root object id */
14 static int pdf_pos
; /* current pdf file offset */
15 static int *obj_off
; /* object offsets */
16 static int obj_sz
, obj_n
; /* number of pdf objects */
17 static int *page_id
; /* page object ids */
18 static int page_sz
, page_n
; /* number of pages */
20 static struct sbuf
*pg
; /* current page contents */
21 static int o_f
, o_s
, o_m
; /* font and size */
22 static int o_h
, o_v
; /* current user position */
23 static int p_h
, p_v
; /* current output position */
24 static int o_pf
, p_pf
; /* output and pdf fonts; indices into o_fs[] */
25 static int p_f
, p_s
, p_m
; /* output font */
26 static int o_queued
; /* queued character type */
27 static int *o_fs
; /* page fonts */
28 static int o_fsn
, o_fssz
; /* page fonts */
30 #define PSFN_MK(fn, ix) (((fn) << 16) | (ix))
31 #define PSFN_FN(fi) ((fi) >> 16)
32 #define PSFN_IX(fi) ((fi) & 0xffff)
35 char name
[128]; /* font PostScript name */
36 char path
[1024]; /* font path */
37 char desc
[1024]; /* font descriptor path */
38 int *gmap
; /* the sub-font assigned to each glyph */
39 int *gpos
; /* the location of the glyph in its sub-font */
40 int gcnt
; /* glyph count */
41 int lastfn
; /* the last sub-font */
42 int lastgl
; /* the number of glyphs in the last subfont */
43 int obj
[64]; /* sub-font object ids */
44 int objdes
; /* font descriptor object id */
47 static struct psfont
*psfonts
;
48 static int psfonts_n
, psfonts_sz
;
50 /* print formatted pdf output */
51 static void pdfout(char *s
, ...)
55 pdf_pos
+= vprintf(s
, ap
);
59 /* print pdf output */
60 static void pdfouts(char *s
)
66 /* allocate an object number */
67 static int obj_map(void)
69 if (obj_n
== obj_sz
) {
71 obj_off
= mextend(obj_off
, obj_n
, obj_sz
, sizeof(obj_off
[0]));
76 /* start the definition of an object */
77 static int obj_beg(int id
)
81 obj_off
[id
] = pdf_pos
;
82 pdfout("%d 0 obj\n", id
);
86 /* end an object definition */
87 static void obj_end(void)
92 void out(char *s
, ...)
96 /* the length of the clear-text, encrypted, and fixed-content portions */
97 static int type1lengths(char *t1
, int l
, int *l1
, int *l2
, int *l3
)
100 char *cleartext
= t1
;
101 char *encrypted
= NULL
;
102 char *fixedcont
= NULL
;
103 for (i
= 0; i
< l
- 5 && !encrypted
; i
++)
104 if (t1
[i
] == 'e' && !memcmp("eexec", t1
+ i
, 5))
108 for (; i
< l
- 512 && !fixedcont
; i
++)
109 if (t1
[i
] == '0' && !memcmp("00000", t1
+ i
, 5))
111 *l1
= encrypted
- cleartext
;
112 *l2
= fixedcont
? fixedcont
- cleartext
: 0;
116 /* return font type: 't': TrueType, '1': Type 1, 'o': OpenType */
117 static int fonttype(char *path
)
119 char *ext
= strrchr(path
, '.');
120 if (ext
&& !strcmp(".ttf", ext
))
122 if (ext
&& !strcmp(".otf", ext
))
127 static void encodehex(struct sbuf
*d
, char *s
, int n
)
129 static char hex
[] = "0123456789ABCDEF";
131 for (i
= 0; i
< n
; i
++) {
132 sbuf_chr(d
, hex
[((unsigned char) s
[i
]) >> 4]);
133 sbuf_chr(d
, hex
[((unsigned char) s
[i
]) & 0x0f]);
134 if (i
% 80 == 79 && i
+ 1 < n
)
140 /* include font descriptor; returns object id */
141 static int psfont_writedesc(struct psfont
*ps
)
146 if (fonttype(ps
->path
) == '1' || fonttype(ps
->path
) == 't') {
147 int fd
= open(ps
->path
, O_RDONLY
);
148 struct sbuf
*ffsb
= sbuf_make();
149 struct sbuf
*sb
= sbuf_make();
150 int l1
= 0, l2
= 0, l3
= 0;
152 /* reading the font file */
153 while ((nr
= read(fd
, buf
, sizeof(buf
))) > 0)
154 sbuf_mem(ffsb
, buf
, nr
);
157 /* initialize Type 1 lengths */
158 if (fonttype(ps
->path
) == '1') {
159 if (type1lengths(sbuf_buf(ffsb
), sbuf_len(ffsb
),
162 /* remove the fixed-content portion of the font */
164 sbuf_cut(ffsb
, l1
+ l2
);
167 /* encoding file contents */
168 encodehex(sb
, sbuf_buf(ffsb
), sbuf_len(ffsb
));
169 /* write font data if it has nonzero length */
171 str_obj
= obj_beg(0);
173 pdfout(" /Filter /ASCIIHexDecode\n");
174 pdfout(" /Length %d\n", sbuf_len(sb
));
175 pdfout(" /Length1 %d\n", l1
);
176 if (fonttype(ps
->path
) == '1')
177 pdfout(" /Length2 %d\n", l2
);
178 if (fonttype(ps
->path
) == '1')
179 pdfout(" /Length3 %d\n", l3
);
182 pdfouts(sbuf_buf(sb
));
183 pdfout("endstream\n");
189 /* the font descriptor */
190 des_obj
= obj_beg(0);
192 pdfout(" /Type /FontDescriptor\n");
193 pdfout(" /FontName /%s\n", ps
->name
);
194 pdfout(" /Flags 4\n");
195 pdfout(" /FontBBox [-1000 -1000 1000 1000]\n");
196 pdfout(" /MissingWidth 1000\n");
197 pdfout(" /StemV 100\n");
198 pdfout(" /ItalicAngle 0\n");
199 pdfout(" /CapHeight 100\n");
200 pdfout(" /Ascent 100\n");
201 pdfout(" /Descent 100\n");
203 pdfout(" /FontFile%s %d 0 R\n",
204 fonttype(ps
->path
) == 't' ? "2" : "", str_obj
);
210 /* write the object corresponding to font font_id[f] */
211 static void psfont_write(struct psfont
*ps
, int ix
)
215 struct font
*fn
= dev_fontopen(ps
->desc
);
217 int gcnt
= ix
< ps
->lastfn
? 256 : ps
->lastgl
;
218 /* finding out the mapping */
219 for (i
= 0; i
< 256; i
++)
221 for (i
= 0; i
< ps
->gcnt
; i
++)
222 if (ps
->gmap
[i
] == ix
)
223 map
[ps
->gpos
[i
]] = i
;
224 /* the encoding object */
225 enc_obj
= obj_beg(0);
227 pdfout(" /Type /Encoding\n");
228 pdfout(" /Differences [ 0");
229 for (i
= 0; i
< gcnt
; i
++)
230 pdfout(" /%s", map
[i
] >= 0 ? font_glget(fn
, map
[i
])->id
: ".notdef");
234 /* the font object */
235 obj_beg(ps
->obj
[ix
]);
237 pdfout(" /Type /Font\n");
238 if (fonttype(ps
->path
) == 't')
239 pdfout(" /Subtype /TrueType\n");
241 pdfout(" /Subtype /Type1\n");
242 pdfout(" /BaseFont /%s\n", ps
->name
);
243 pdfout(" /FirstChar 0\n");
244 pdfout(" /LastChar %d\n", gcnt
- 1);
245 pdfout(" /Widths [");
246 for (i
= 0; i
< gcnt
; i
++)
247 pdfout(" %d", (long) (map
[i
] >= 0 ? font_glget(fn
, map
[i
])->wid
: 0)
248 * 100 * 72 / dev_res
);
250 pdfout(" /FontDescriptor %d 0 R\n", ps
->objdes
);
251 pdfout(" /Encoding %d 0 R\n", enc_obj
);
257 static int psfont_find(struct glyph
*g
)
259 struct font
*fn
= g
->font
;
260 char *name
= font_name(fn
);
261 struct psfont
*ps
= NULL
;
264 for (i
= 0; i
< psfonts_n
; i
++)
265 if (!strcmp(name
, psfonts
[i
].name
))
267 if (i
== psfonts_n
) {
268 if (psfonts_n
== psfonts_sz
) {
270 psfonts
= mextend(psfonts
, psfonts_n
,
271 psfonts_sz
, sizeof(psfonts
[0]));
275 snprintf(ps
->name
, sizeof(ps
->name
), "%s", name
);
276 snprintf(ps
->path
, sizeof(ps
->path
), "%s", font_path(fn
));
277 snprintf(ps
->desc
, sizeof(ps
->desc
), "%s", font_desc(fn
));
278 while (font_glget(fn
, ps
->gcnt
))
280 ps
->gmap
= calloc(ps
->gcnt
, sizeof(ps
->gmap
));
281 ps
->gpos
= calloc(ps
->gcnt
, sizeof(ps
->gpos
));
286 gidx
= font_glnum(fn
, g
);
287 if (!ps
->gmap
[gidx
]) {
288 if (ps
->lastgl
== 256) {
291 ps
->obj
[ps
->lastfn
] = obj_map();
293 ps
->gmap
[gidx
] = ps
->lastfn
;
294 ps
->gpos
[gidx
] = ps
->lastgl
++;
296 return PSFN_MK(i
, ps
->gmap
[gidx
]);
299 static int psfont_gpos(struct glyph
*g
)
301 int fn
= psfont_find(g
);
302 return psfonts
[PSFN_FN(fn
)].gpos
[font_glnum(g
->font
, g
)];
305 static void psfont_done(void)
308 for (i
= 0; i
< psfonts_n
; i
++) {
309 struct psfont
*ps
= &psfonts
[i
];
310 ps
->objdes
= psfont_writedesc(ps
);
311 for (j
= 1; j
<= ps
->lastfn
; j
++)
314 for (i
= 0; i
< psfonts_n
; i
++) {
315 free(psfonts
[i
].gmap
);
316 free(psfonts
[i
].gpos
);
321 static void o_flush(void)
324 sbuf_printf(pg
, ">] TJ\n");
328 static int o_loadfont(struct glyph
*g
)
330 int fn
= psfont_find(g
);
332 for (i
= 0; i
< o_fsn
; i
++)
335 if (o_fsn
== o_fssz
) {
337 o_fs
= mextend(o_fs
, o_fsn
, o_fssz
, sizeof(o_fs
[0]));
343 /* like pdfpos() but assume that uh and uv are multiplied by 100 */
344 static char *pdfpos00(int uh
, int uv
)
347 int h
= (long) uh
* 72 / dev_res
;
348 int v
= (long) pdf_height
* 100 - (long) uv
* 72 / dev_res
;
349 sprintf(buf
, "%s%d.%02d %s%d.%02d",
350 h
< 0 ? "-" : "", abs(h
) / 100, abs(h
) % 100,
351 v
< 0 ? "-" : "", abs(v
) / 100, abs(v
) % 100);
355 /* convert troff position to pdf position; returns a static buffer */
356 static char *pdfpos(int uh
, int uv
)
358 return pdfpos00(uh
* 100, uv
* 100);
361 /* troff length to thousands of a unit of text space; returns a static buffer */
362 static char *pdfunit(int uh
, int sz
)
365 int h
= (long) uh
* 1000 * 72 / sz
/ dev_res
;
366 sprintf(buf
, "%s%d", h
< 0 ? "-" : "", abs(h
));
370 /* convert troff color to pdf color; returns a static buffer */
371 static char *pdfcolor(int m
)
374 int r
= CLR_R(m
) * 1000 / 255;
375 int g
= CLR_G(m
) * 1000 / 255;
376 int b
= CLR_B(m
) * 1000 / 255;
377 sbuf_printf(pg
, "%d.%03d %d.%03d %d.%03d",
378 r
/ 1000, r
% 1000, g
/ 1000, g
% 1000, b
/ 1000, b
% 1000);
382 static void o_queue(struct glyph
*g
)
386 sbuf_printf(pg
, "1 0 0 1 %s Tm\n", pdfpos(o_h
, o_v
));
391 sbuf_printf(pg
, "[<");
394 sbuf_printf(pg
, "> %s <", pdfunit(p_h
- o_h
, o_s
));
395 sbuf_printf(pg
, "%02x", psfont_gpos(g
));
396 p_h
= o_h
+ font_wid(g
->font
, o_s
, g
->wid
);
399 static void out_fontup(void)
403 sbuf_printf(pg
, "%s rg\n", pdfcolor(o_m
));
406 if (o_pf
>= 0 && (o_pf
!= p_pf
|| o_s
!= p_s
)) {
407 int fn
= PSFN_FN(o_fs
[o_pf
]);
408 int ix
= PSFN_IX(o_fs
[o_pf
]);
410 sbuf_printf(pg
, "/%s.%d %d Tf\n", psfonts
[fn
].name
, ix
, o_s
);
420 g
= dev_glyph(c
, o_f
);
421 fn
= g
? g
->font
: dev_font(o_f
);
423 outrel(*c
== ' ' && fn
? font_swid(fn
, o_s
) : 1, 0);
426 o_pf
= o_loadfont(g
);
441 void outrel(int h
, int v
)
464 void outrotate(int deg
)
468 void outeps(char *eps
)
472 void outlink(char *spec
)
499 static int draw_path
; /* number of path segments */
500 static int draw_point
; /* point was set for postscript newpath */
508 sbuf_printf(pg
, "%s m\n", pdfpos(o_h
, o_v
));
511 void drawend(int close
, int fill
)
516 if (!fill
) /* stroking color */
517 sbuf_printf(pg
, "%s RG\n", pdfcolor(o_m
));
519 sbuf_printf(pg
, "f\n");
521 sbuf_printf(pg
, close
? "s\n" : "S\n");
524 void drawmbeg(char *s
)
528 void drawmend(char *s
)
532 void drawl(int h
, int v
)
535 sbuf_printf(pg
, "%s l\n", pdfpos(o_h
, o_v
));
538 /* draw circle/ellipse quadrant */
539 static void drawquad(int ch
, int cv
)
542 long x0
= o_h
* 1000;
543 long y0
= o_v
* 1000;
544 long x3
= x0
+ ch
* 1000 / 2;
545 long y3
= y0
+ cv
* 1000 / 2;
547 long y1
= y0
+ cv
* b
/ 1000 / 2;
548 long x2
= x0
+ ch
* b
/ 1000 / 2;
551 x1
= x3
- ch
* b
/ 1000 / 2;
554 y2
= y3
- cv
* b
/ 1000 / 2;
556 sbuf_printf(pg
, "%s ", pdfpos00(x1
/ 10, y1
/ 10));
557 sbuf_printf(pg
, "%s ", pdfpos00(x2
/ 10, y2
/ 10));
558 sbuf_printf(pg
, "%s c\n", pdfpos00(x3
/ 10, y3
/ 10));
559 outrel(ch
/ 2, cv
/ 2);
572 /* draw an ellipse */
573 void drawe(int h
, int v
)
583 void drawa(int h1
, int v1
, int h2
, int v2
)
585 drawl(h1
+ h2
, v1
+ v2
);
589 void draws(int h1
, int v1
, int h2
, int v2
)
592 sbuf_printf(pg
, "%s l\n", pdfpos(o_h
, o_v
));
595 void ps_header(char *title
, int pagewidth
, int pageheight
, int linewidth
)
599 pdf_root
= obj_map();
600 pdf_pages
= obj_map();
602 pdfout("%%PDF-1.6\n");
603 pdf_width
= (pagewidth
* 72 + 127) / 254;
604 pdf_height
= (pageheight
* 72 + 127) / 254;
607 void ps_trailer(int pages
)
612 /* pdf pages object */
615 pdfout(" /Type /Pages\n");
616 pdfout(" /MediaBox [ 0 0 %d %d ]\n", pdf_width
, pdf_height
);
617 pdfout(" /Count %d\n", page_n
);
619 for (i
= 0; i
< page_n
; i
++)
620 pdfout(" %d 0 R", page_id
[i
]);
624 /* pdf root object */
627 pdfout(" /Type /Catalog\n");
628 pdfout(" /Pages %d 0 R\n", pdf_pages
);
634 info_id
= obj_beg(0);
637 pdfout(" /Title (%s)\n", pdf_title
);
638 pdfout(" /Creator (Neatroff)\n");
639 pdfout(" /Producer (Neatpost)\n");
645 pdfout("0 %d\n", obj_n
);
646 pdfout("0000000000 65535 f \n");
647 for (i
= 1; i
< obj_n
; i
++)
648 pdfout("%010d 00000 n \n", obj_off
[i
]);
652 pdfout(" /Size %d\n", obj_n
);
653 pdfout(" /Root %d 0 R\n", pdf_root
);
654 pdfout(" /Info %d 0 R\n", info_id
);
656 pdfout("startxref\n");
657 pdfout("%d\n", xref_off
);
663 void ps_pagebeg(int n
)
666 sbuf_printf(pg
, "BT\n");
669 void ps_pageend(int n
)
674 sbuf_printf(pg
, "ET\n");
676 cont_id
= obj_beg(0);
678 pdfout(" /Length %d\n", sbuf_len(pg
));
681 pdfouts(sbuf_buf(pg
));
682 pdfout("endstream\n");
684 /* the page object */
685 if (page_n
== page_sz
) {
687 page_id
= mextend(page_id
, page_n
, page_sz
, sizeof(page_id
[0]));
689 page_id
[page_n
++] = obj_beg(0);
691 pdfout(" /Type /Page\n");
692 pdfout(" /Parent %d 0 R\n", pdf_pages
);
693 pdfout(" /Resources <<\n");
695 for (i
= 0; i
< o_fsn
; i
++) {
696 int fn
= PSFN_FN(o_fs
[i
]);
697 int ix
= PSFN_IX(o_fs
[i
]);
698 pdfout(" /%s.%d %d 0 R",
699 psfonts
[fn
].name
, ix
, psfonts
[fn
].obj
[ix
]);
703 pdfout(" /Contents %d 0 R\n", cont_id
);