7 static char *pdf_title
; /* document title */
8 static int pdf_width
; /* page width */
9 static int pdf_height
; /* page height */
10 static int pdf_pages
; /* pages object id */
11 static int pdf_root
; /* root object id */
12 static int pdf_pos
; /* current pdf file offset */
13 static int *obj_off
; /* object offsets */
14 static int obj_sz
, obj_n
; /* number of pdf objects */
15 static int *page_id
; /* page object ids */
16 static int page_sz
, page_n
; /* number of pages */
18 static struct sbuf
*pg
; /* current page contents */
19 static int o_f
, o_s
, o_m
; /* font and size */
20 static int o_h
, o_v
; /* current user position */
21 static int p_h
, p_v
; /* current output position */
22 static int o_pf
, p_pf
; /* output and pdf fonts; indices into o_fs[] */
23 static int p_f
, p_s
, p_m
; /* output font */
24 static int o_queued
; /* queued character type */
25 static int *o_fs
; /* page fonts */
26 static int o_fsn
, o_fssz
; /* page fonts */
28 #define PSFN_MK(fn, ix) (((fn) << 16) | (ix))
29 #define PSFN_FN(fi) ((fi) >> 16)
30 #define PSFN_IX(fi) ((fi) & 0xffff)
33 char name
[128]; /* font PostScript name */
34 char path
[1024]; /* font path */
35 char desc
[1024]; /* font descriptor path */
36 int *gmap
; /* the sub-font assigned to each glyph */
37 int *gpos
; /* the location of the glyph in its sub-font */
38 int gcnt
; /* glyph count */
39 int lastfn
; /* the last sub-font */
40 int lastgl
; /* the number of glyphs in the last subfont */
41 int obj
[64]; /* sub-font object ids */
42 int objdes
; /* font descriptor object id */
45 static struct psfont
*psfonts
;
46 static int psfonts_n
, psfonts_sz
;
48 /* print pdf output */
49 static void pdfout(char *s
, ...)
53 pdf_pos
+= vprintf(s
, ap
);
57 /* allocate an object number */
58 static int obj_map(void)
60 if (obj_n
== obj_sz
) {
62 obj_off
= mextend(obj_off
, obj_n
, obj_sz
, sizeof(obj_off
[0]));
67 /* start the definition of an object */
68 static int obj_beg(int id
)
72 obj_off
[id
] = pdf_pos
;
73 pdfout("%d 0 obj\n", id
);
77 /* end an object definition */
78 static void obj_end(void)
83 void out(char *s
, ...)
87 /* include font descriptor; returns object id */
88 static int psfont_writedesc(struct psfont
*ps
)
93 char *ext
= strrchr(ps
->path
, '.');
94 if (ext
&& !strcmp(".ttf", ext
)) {
95 FILE *fp
= fopen(ps
->path
, "r");
96 struct sbuf
*sb
= sbuf_make();
98 for (i
= 0; c
!= EOF
; i
++) {
99 sbuf_printf(sb
, "%02x", c
);
101 if (i
% 40 == 39 && c
!= EOF
)
106 str_obj
= obj_beg(0);
108 pdfout(" /Filter /ASCIIHexDecode\n");
109 pdfout(" /Length %d\n", sbuf_len(sb
));
110 pdfout(" /Length1 %d\n", i
);
113 pdfout("%s", sbuf_buf(sb
));
114 pdfout("endstream\n");
118 /* the font descriptor */
119 des_obj
= obj_beg(0);
121 pdfout(" /Type /FontDescriptor\n");
122 pdfout(" /FontName /%s\n", ps
->name
);
123 pdfout(" /Flags 4\n");
124 pdfout(" /FontBBox [-1000 -1000 1000 1000]\n");
125 pdfout(" /MissingWidth 1000\n");
126 pdfout(" /StemV 100\n");
127 pdfout(" /ItalicAngle 0\n");
128 pdfout(" /CapHeight 100\n");
129 pdfout(" /Ascent 100\n");
130 pdfout(" /Descent 100\n");
132 pdfout(" /FontFile2 %d 0 R\n", str_obj
);
138 /* write the object corresponding to font font_id[f] */
139 static void psfont_write(struct psfont
*ps
, int ix
)
143 char *ext
= strrchr(ps
->path
, '.');
144 struct font
*fn
= dev_fontopen(ps
->desc
);
146 char gcnt
= ps
->lastfn
== ix
? ps
->lastgl
: 256;
147 /* finding out the mapping */
148 for (i
= 0; i
< 256; i
++)
150 for (i
= 0; i
< ps
->gcnt
; i
++)
151 if (ps
->gmap
[i
] == ix
)
152 map
[ps
->gpos
[i
]] = i
;
153 /* the encoding object */
154 enc_obj
= obj_beg(0);
156 pdfout(" /Type /Encoding\n");
157 pdfout(" /Differences [ 0");
158 for (i
= 0; i
< gcnt
; i
++)
159 pdfout(" /%s", map
[i
] >= 0 ? font_glget(fn
, map
[i
])->id
: ".notdef");
163 /* the font object */
164 obj_beg(ps
->obj
[ix
]);
166 pdfout(" /Type /Font\n");
167 pdfout(" /Subtype /%s\n",
168 ext
&& !strcmp(".ttf", ext
) ? "TrueType" : "Type1");
169 pdfout(" /BaseFont /%s\n", ps
->name
);
170 pdfout(" /FirstChar 0\n");
171 pdfout(" /LastChar %d\n", gcnt
- 1);
172 pdfout(" /Widths [");
173 for (i
= 0; i
< gcnt
; i
++)
174 pdfout(" %d", (map
[i
] >= 0 ? font_glget(fn
, map
[i
])->wid
: 0)
177 pdfout(" /FontDescriptor %d 0 R\n", ps
->objdes
);
178 pdfout(" /Encoding %d 0 R\n", enc_obj
);
184 static int psfont_find(struct glyph
*g
)
186 struct font
*fn
= g
->font
;
187 char *name
= font_name(fn
);
188 struct psfont
*ps
= NULL
;
191 for (i
= 0; i
< psfonts_n
; i
++)
192 if (!strcmp(name
, psfonts
[i
].name
))
194 if (i
== psfonts_n
) {
195 if (psfonts_n
== psfonts_sz
) {
197 psfonts
= mextend(psfonts
, psfonts_n
,
198 psfonts_sz
, sizeof(psfonts
[0]));
202 snprintf(ps
->name
, sizeof(ps
->name
), "%s", name
);
203 snprintf(ps
->path
, sizeof(ps
->path
), "%s", font_path(fn
));
204 snprintf(ps
->desc
, sizeof(ps
->desc
), "%s", font_desc(fn
));
205 while (font_glget(fn
, ps
->gcnt
))
207 ps
->gmap
= calloc(ps
->gcnt
, sizeof(ps
->gmap
));
208 ps
->gpos
= calloc(ps
->gcnt
, sizeof(ps
->gpos
));
213 gidx
= font_glnum(fn
, g
);
214 if (!ps
->gmap
[gidx
]) {
215 if (ps
->lastgl
== 256) {
218 ps
->obj
[ps
->lastfn
] = obj_map();
220 ps
->gmap
[gidx
] = ps
->lastfn
;
221 ps
->gpos
[gidx
] = ps
->lastgl
++;
223 return PSFN_MK(i
, ps
->gmap
[gidx
]);
226 static int psfont_gpos(struct glyph
*g
)
228 int fn
= psfont_find(g
);
229 return psfonts
[PSFN_FN(fn
)].gpos
[font_glnum(g
->font
, g
)];
232 static void psfont_done(void)
235 for (i
= 0; i
< psfonts_n
; i
++) {
236 struct psfont
*ps
= &psfonts
[i
];
237 ps
->objdes
= psfont_writedesc(ps
);
238 for (j
= 1; j
<= ps
->lastfn
; j
++)
241 for (i
= 0; i
< psfonts_n
; i
++) {
242 free(psfonts
[i
].gmap
);
243 free(psfonts
[i
].gpos
);
248 static void o_flush(void)
251 sbuf_printf(pg
, "> Tj\n");
255 static int o_loadfont(struct glyph
*g
)
257 int fn
= psfont_find(g
);
259 for (i
= 0; i
< o_fsn
; i
++)
262 if (o_fsn
== o_fssz
) {
264 o_fs
= mextend(o_fs
, o_fsn
, o_fssz
, sizeof(o_fs
[0]));
273 /* convert troff position to pdf position; returns a static buffer */
274 static char *pdfpos(int uh
, int uv
)
277 int h
= uh
* PREC
* 72 / dev_res
;
278 int v
= pdf_height
* PREC
- (uv
* PREC
* 72 / dev_res
);
279 sprintf(buf
, "%d.%0" PRECN
"d %d.%0" PRECN
"d",
280 h
/ PREC
, h
% PREC
, v
/ PREC
, v
% PREC
);
284 /* convert troff color to pdf color; returns a static buffer */
285 static char *pdfcolor(int m
)
288 int r
= CLR_R(m
) * 1000 / 255;
289 int g
= CLR_G(m
) * 1000 / 255;
290 int b
= CLR_B(m
) * 1000 / 255;
291 sbuf_printf(pg
, "%d.%03d %d.%03d %d.%03d",
292 r
/ 1000, r
% 1000, g
/ 1000, g
% 1000, b
/ 1000, b
% 1000);
296 static void o_queue(struct glyph
*g
)
298 if (o_h
!= p_h
|| o_v
!= p_v
) {
300 sbuf_printf(pg
, "1 0 0 1 %s Tm\n", pdfpos(o_h
, o_v
));
305 sbuf_printf(pg
, "<");
307 sbuf_printf(pg
, "%02x", psfont_gpos(g
));
308 p_h
+= font_wid(g
->font
, o_s
, g
->wid
);
311 static void out_fontup(void)
315 sbuf_printf(pg
, "%s rg\n", pdfcolor(o_m
));
318 if (o_pf
!= p_pf
|| o_s
!= p_s
) {
319 int fn
= PSFN_FN(o_fs
[o_pf
]);
320 int ix
= PSFN_IX(o_fs
[o_pf
]);
322 sbuf_printf(pg
, "/%s.%d %d Tf\n", psfonts
[fn
].name
, ix
, o_s
);
332 g
= dev_glyph(c
, o_f
);
333 fn
= g
? g
->font
: dev_font(o_f
);
335 outrel(*c
== ' ' && fn
? font_swid(fn
, o_s
) : 1, 0);
338 o_pf
= o_loadfont(g
);
353 void outrel(int h
, int v
)
376 void outrotate(int deg
)
380 void outeps(char *eps
)
384 void outlink(char *spec
)
409 static int draw_path
; /* number of path segments */
410 static int draw_point
; /* point was set for postscript newpath */
418 sbuf_printf(pg
, "%s m\n", pdfpos(o_h
, o_v
));
421 void drawend(int close
, int fill
)
426 if (!fill
) /* stroking color */
427 sbuf_printf(pg
, "%s RG\n", pdfcolor(o_m
));
429 sbuf_printf(pg
, "f\n");
431 sbuf_printf(pg
, close
? "s\n" : "S\n");
434 void drawmbeg(char *s
)
438 void drawmend(char *s
)
442 void drawl(int h
, int v
)
446 sbuf_printf(pg
, "%s l\n", pdfpos(o_h
, o_v
));
454 void drawe(int h
, int v
)
459 void drawa(int h1
, int v1
, int h2
, int v2
)
461 outrel(h1
+ h2
, v1
+ v2
);
464 void draws(int h1
, int v1
, int h2
, int v2
)
469 void ps_header(char *title
, int pagewidth
, int pageheight
, int linewidth
)
473 pdf_root
= obj_map();
474 pdf_pages
= obj_map();
476 pdfout("%%PDF-1.6\n");
477 pdf_width
= (pagewidth
* 72 + 127) / 254;
478 pdf_height
= (pageheight
* 72 + 127) / 254;
481 void ps_trailer(int pages
)
486 /* pdf pages object */
489 pdfout(" /Type /Pages\n");
490 pdfout(" /MediaBox [ 0 0 %d %d ]\n", pdf_width
, pdf_height
);
491 pdfout(" /Count %d\n", page_n
);
493 for (i
= 0; i
< page_n
; i
++)
494 pdfout(" %d 0 R", page_id
[i
]);
498 /* pdf root object */
501 pdfout(" /Type /Catalog\n");
502 pdfout(" /Pages %d 0 R\n", pdf_pages
);
508 info_id
= obj_beg(0);
511 pdfout(" /Title (%s)\n", pdf_title
);
512 pdfout(" /Creator (Neatroff)\n");
513 pdfout(" /Producer (Neatpost)\n");
519 pdfout("0 %d\n", obj_n
);
520 pdfout("0000000000 65535 f \n");
521 for (i
= 1; i
< obj_n
; i
++)
522 pdfout("%010d 00000 n \n", obj_off
[i
]);
526 pdfout(" /Size %d\n", obj_n
);
527 pdfout(" /Root %d 0 R\n", pdf_root
);
528 pdfout(" /Info %d 0 R\n", info_id
);
530 pdfout("startxref\n");
531 pdfout("%d\n", xref_off
);
537 void ps_pagebeg(int n
)
540 sbuf_printf(pg
, "BT\n");
543 void ps_pageend(int n
)
548 sbuf_printf(pg
, "ET\n");
550 cont_id
= obj_beg(0);
552 pdfout(" /Length %d\n", sbuf_len(pg
));
555 pdfout("%s", sbuf_buf(pg
));
556 pdfout("endstream\n");
558 /* the page object */
559 if (page_n
== page_sz
) {
561 page_id
= mextend(page_id
, page_n
, page_sz
, sizeof(page_id
[0]));
563 page_id
[page_n
++] = obj_beg(0);
565 pdfout(" /Type /Page\n");
566 pdfout(" /Parent %d 0 R\n", pdf_pages
);
567 pdfout(" /Resources <<\n");
569 for (i
= 0; i
< o_fsn
; i
++) {
570 int fn
= PSFN_FN(o_fs
[i
]);
571 int ix
= PSFN_IX(o_fs
[i
]);
572 pdfout(" /%s.%d %d 0 R",
573 psfonts
[fn
].name
, ix
, psfonts
[fn
].obj
[ix
]);
577 pdfout(" /Contents %d 0 R\n", cont_id
);