Blame


1 24c02865 2005-01-04 devnull /*
2 24c02865 2005-01-04 devnull * pdf.c
3 24c02865 2005-01-04 devnull *
4 24c02865 2005-01-04 devnull * pdf file support for page
5 24c02865 2005-01-04 devnull */
6 24c02865 2005-01-04 devnull
7 24c02865 2005-01-04 devnull #include <u.h>
8 24c02865 2005-01-04 devnull #include <libc.h>
9 24c02865 2005-01-04 devnull #include <draw.h>
10 17157e4a 2006-03-20 devnull #include <cursor.h>
11 05a4d855 2007-03-26 devnull #include <thread.h>
12 24c02865 2005-01-04 devnull #include <bio.h>
13 24c02865 2005-01-04 devnull #include "page.h"
14 24c02865 2005-01-04 devnull
15 24c02865 2005-01-04 devnull typedef struct PDFInfo PDFInfo;
16 24c02865 2005-01-04 devnull struct PDFInfo {
17 24c02865 2005-01-04 devnull GSInfo gs;
18 24c02865 2005-01-04 devnull Rectangle *pagebbox;
19 24c02865 2005-01-04 devnull };
20 24c02865 2005-01-04 devnull
21 24c02865 2005-01-04 devnull static Image* pdfdrawpage(Document *d, int page);
22 24c02865 2005-01-04 devnull static char* pdfpagename(Document*, int);
23 24c02865 2005-01-04 devnull
24 24c02865 2005-01-04 devnull char *pdfprolog =
25 24c02865 2005-01-04 devnull #include "pdfprolog.c"
26 24c02865 2005-01-04 devnull ;
27 24c02865 2005-01-04 devnull
28 24c02865 2005-01-04 devnull Rectangle
29 24c02865 2005-01-04 devnull pdfbbox(GSInfo *gs)
30 24c02865 2005-01-04 devnull {
31 24c02865 2005-01-04 devnull char *p;
32 24c02865 2005-01-04 devnull char *f[4];
33 24c02865 2005-01-04 devnull Rectangle r;
34 24c02865 2005-01-04 devnull
35 24c02865 2005-01-04 devnull r = Rect(0,0,0,0);
36 24c02865 2005-01-04 devnull waitgs(gs);
37 24c02865 2005-01-04 devnull gscmd(gs, "/CropBox knownoget {} {[0 0 0 0]} ifelse PAGE==\n");
38 24c02865 2005-01-04 devnull p = Brdline(&gs->gsrd, '\n');
39 24c02865 2005-01-04 devnull p[Blinelen(&gs->gsrd)-1] ='\0';
40 24c02865 2005-01-04 devnull if(p[0] != '[')
41 24c02865 2005-01-04 devnull return r;
42 24c02865 2005-01-04 devnull if(tokenize(p+1, f, 4) != 4)
43 24c02865 2005-01-04 devnull return r;
44 24c02865 2005-01-04 devnull r = Rect(atoi(f[0]), atoi(f[1]), atoi(f[2]), atoi(f[3]));
45 24c02865 2005-01-04 devnull waitgs(gs);
46 24c02865 2005-01-04 devnull return r;
47 24c02865 2005-01-04 devnull }
48 24c02865 2005-01-04 devnull
49 24c02865 2005-01-04 devnull Document*
50 24c02865 2005-01-04 devnull initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
51 24c02865 2005-01-04 devnull {
52 24c02865 2005-01-04 devnull Document *d;
53 24c02865 2005-01-04 devnull PDFInfo *pdf;
54 24c02865 2005-01-04 devnull char *p;
55 24c02865 2005-01-04 devnull char *fn;
56 24c02865 2005-01-04 devnull char fdbuf[20];
57 24c02865 2005-01-04 devnull int fd;
58 24c02865 2005-01-04 devnull int i, npage;
59 24c02865 2005-01-04 devnull Rectangle bbox;
60 24c02865 2005-01-04 devnull
61 24c02865 2005-01-04 devnull if(argc > 1) {
62 24c02865 2005-01-04 devnull fprint(2, "can only view one pdf file at a time\n");
63 24c02865 2005-01-04 devnull return nil;
64 24c02865 2005-01-04 devnull }
65 24c02865 2005-01-04 devnull
66 24c02865 2005-01-04 devnull fprint(2, "reading through pdf...\n");
67 24c02865 2005-01-04 devnull if(b == nil){ /* standard input; spool to disk (ouch) */
68 24c02865 2005-01-04 devnull fd = spooltodisk(buf, nbuf, &fn);
69 05a4d855 2007-03-26 devnull sprint(fdbuf, "/dev/fd/%d", fd);
70 24c02865 2005-01-04 devnull b = Bopen(fdbuf, OREAD);
71 24c02865 2005-01-04 devnull if(b == nil){
72 24c02865 2005-01-04 devnull fprint(2, "cannot open disk spool file\n");
73 24c02865 2005-01-04 devnull wexits("Bopen temp");
74 24c02865 2005-01-04 devnull }
75 24c02865 2005-01-04 devnull }else
76 24c02865 2005-01-04 devnull fn = argv[0];
77 24c02865 2005-01-04 devnull
78 24c02865 2005-01-04 devnull /* sanity check */
79 24c02865 2005-01-04 devnull Bseek(b, 0, 0);
80 24c02865 2005-01-04 devnull if(!(p = Brdline(b, '\n')) && !(p = Brdline(b, '\r'))) {
81 24c02865 2005-01-04 devnull fprint(2, "cannot find end of first line\n");
82 24c02865 2005-01-04 devnull wexits("initps");
83 24c02865 2005-01-04 devnull }
84 24c02865 2005-01-04 devnull if(strncmp(p, "%PDF-", 5) != 0) {
85 24c02865 2005-01-04 devnull werrstr("not pdf");
86 24c02865 2005-01-04 devnull return nil;
87 24c02865 2005-01-04 devnull }
88 24c02865 2005-01-04 devnull
89 24c02865 2005-01-04 devnull /* setup structures so one free suffices */
90 24c02865 2005-01-04 devnull p = emalloc(sizeof(*d) + sizeof(*pdf));
91 24c02865 2005-01-04 devnull d = (Document*) p;
92 24c02865 2005-01-04 devnull p += sizeof(*d);
93 24c02865 2005-01-04 devnull pdf = (PDFInfo*) p;
94 24c02865 2005-01-04 devnull
95 24c02865 2005-01-04 devnull d->extra = pdf;
96 24c02865 2005-01-04 devnull d->b = b;
97 24c02865 2005-01-04 devnull d->drawpage = pdfdrawpage;
98 24c02865 2005-01-04 devnull d->pagename = pdfpagename;
99 24c02865 2005-01-04 devnull d->fwdonly = 0;
100 24c02865 2005-01-04 devnull
101 17157e4a 2006-03-20 devnull if(spawngs(&pdf->gs, "-dDELAYSAFER") < 0)
102 24c02865 2005-01-04 devnull return nil;
103 24c02865 2005-01-04 devnull
104 24c02865 2005-01-04 devnull gscmd(&pdf->gs, "%s", pdfprolog);
105 24c02865 2005-01-04 devnull waitgs(&pdf->gs);
106 24c02865 2005-01-04 devnull
107 24c02865 2005-01-04 devnull setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0);
108 17157e4a 2006-03-20 devnull gscmd(&pdf->gs, "(%s) (r) file { DELAYSAFER { .setsafe } if } stopped pop pdfopen begin\n", fn);
109 24c02865 2005-01-04 devnull gscmd(&pdf->gs, "pdfpagecount PAGE==\n");
110 24c02865 2005-01-04 devnull p = Brdline(&pdf->gs.gsrd, '\n');
111 24c02865 2005-01-04 devnull npage = atoi(p);
112 24c02865 2005-01-04 devnull if(npage < 1) {
113 24c02865 2005-01-04 devnull fprint(2, "no pages?\n");
114 24c02865 2005-01-04 devnull return nil;
115 24c02865 2005-01-04 devnull }
116 24c02865 2005-01-04 devnull d->npage = npage;
117 24c02865 2005-01-04 devnull d->docname = argv[0];
118 24c02865 2005-01-04 devnull
119 24c02865 2005-01-04 devnull gscmd(&pdf->gs, "Trailer\n");
120 24c02865 2005-01-04 devnull bbox = pdfbbox(&pdf->gs);
121 24c02865 2005-01-04 devnull
122 24c02865 2005-01-04 devnull pdf->pagebbox = emalloc(sizeof(Rectangle)*npage);
123 24c02865 2005-01-04 devnull for(i=0; i<npage; i++) {
124 24c02865 2005-01-04 devnull gscmd(&pdf->gs, "%d pdfgetpage\n", i+1);
125 05a4d855 2007-03-26 devnull pdf->pagebbox[i] = pdfbbox(&pdf->gs);
126 24c02865 2005-01-04 devnull if(Dx(pdf->pagebbox[i]) <= 0)
127 24c02865 2005-01-04 devnull pdf->pagebbox[i] = bbox;
128 24c02865 2005-01-04 devnull }
129 24c02865 2005-01-04 devnull return d;
130 24c02865 2005-01-04 devnull }
131 24c02865 2005-01-04 devnull
132 24c02865 2005-01-04 devnull static Image*
133 24c02865 2005-01-04 devnull pdfdrawpage(Document *doc, int page)
134 24c02865 2005-01-04 devnull {
135 24c02865 2005-01-04 devnull PDFInfo *pdf = doc->extra;
136 24c02865 2005-01-04 devnull Image *im;
137 24c02865 2005-01-04 devnull
138 24c02865 2005-01-04 devnull gscmd(&pdf->gs, "%d DoPDFPage\n", page+1);
139 05a4d855 2007-03-26 devnull im = convert(&pdf->gs.g);
140 24c02865 2005-01-04 devnull if(im == nil) {
141 24c02865 2005-01-04 devnull fprint(2, "fatal: readimage error %r\n");
142 24c02865 2005-01-04 devnull wexits("readimage");
143 24c02865 2005-01-04 devnull }
144 24c02865 2005-01-04 devnull waitgs(&pdf->gs);
145 24c02865 2005-01-04 devnull return im;
146 24c02865 2005-01-04 devnull }
147 24c02865 2005-01-04 devnull
148 24c02865 2005-01-04 devnull static char*
149 24c02865 2005-01-04 devnull pdfpagename(Document *d, int page)
150 24c02865 2005-01-04 devnull {
151 24c02865 2005-01-04 devnull static char str[15];
152 17157e4a 2006-03-20 devnull
153 24c02865 2005-01-04 devnull USED(d);
154 24c02865 2005-01-04 devnull sprint(str, "p %d", page+1);
155 24c02865 2005-01-04 devnull return str;
156 24c02865 2005-01-04 devnull }