123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /*
- * pdf.c
- *
- * pdf file support for page
- */
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- #include <event.h>
- #include <bio.h>
- #include "page.h"
- typedef struct PDFInfo PDFInfo;
- struct PDFInfo {
- GSInfo;
- Rectangle *pagebbox;
- };
- static Image* pdfdrawpage(Document *d, int page);
- static char* pdfpagename(Document*, int);
- char *pdfprolog =
- #include "pdfprolog.c"
- ;
- Rectangle
- pdfbbox(GSInfo *gs)
- {
- char *p;
- char *f[4];
- Rectangle r;
-
- r = Rect(0,0,0,0);
- waitgs(gs);
- gscmd(gs, "/CropBox knownoget {} {[0 0 0 0]} ifelse PAGE==\n");
- p = Brdline(&gs->gsrd, '\n');
- p[Blinelen(&gs->gsrd)-1] ='\0';
- if(p[0] != '[')
- return r;
- if(tokenize(p+1, f, 4) != 4)
- return r;
- r = Rect(atoi(f[0]), atoi(f[1]), atoi(f[2]), atoi(f[3]));
- waitgs(gs);
- return r;
- }
- Document*
- initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
- {
- Document *d;
- PDFInfo *pdf;
- char *p;
- char *fn;
- char fdbuf[20];
- int fd;
- int i, npage;
- Rectangle bbox;
- if(argc > 1) {
- fprint(2, "can only view one pdf file at a time\n");
- return nil;
- }
- fprint(2, "reading through pdf...\n");
- if(b == nil){ /* standard input; spool to disk (ouch) */
- fd = spooltodisk(buf, nbuf, &fn);
- sprint(fdbuf, "/fd/%d", fd);
- b = Bopen(fdbuf, OREAD);
- if(b == nil){
- fprint(2, "cannot open disk spool file\n");
- wexits("Bopen temp");
- }
- }else
- fn = argv[0];
- /* sanity check */
- Bseek(b, 0, 0);
- if(!(p = Brdline(b, '\n')) && !(p = Brdline(b, '\r'))) {
- fprint(2, "cannot find end of first line\n");
- wexits("initps");
- }
- if(strncmp(p, "%PDF-", 5) != 0) {
- werrstr("not pdf");
- return nil;
- }
- /* setup structures so one free suffices */
- p = emalloc(sizeof(*d) + sizeof(*pdf));
- d = (Document*) p;
- p += sizeof(*d);
- pdf = (PDFInfo*) p;
- d->extra = pdf;
- d->b = b;
- d->drawpage = pdfdrawpage;
- d->pagename = pdfpagename;
- d->fwdonly = 0;
- if(spawngs(pdf) < 0)
- return nil;
- gscmd(pdf, "%s", pdfprolog);
- waitgs(pdf);
- setdim(pdf, Rect(0,0,0,0), ppi, 0);
- gscmd(pdf, "(%s) (r) file pdfopen begin\n", fn);
- gscmd(pdf, "pdfpagecount PAGE==\n");
- p = Brdline(&pdf->gsrd, '\n');
- npage = atoi(p);
- if(npage < 1) {
- fprint(2, "no pages?\n");
- return nil;
- }
- d->npage = npage;
- d->docname = argv[0];
- gscmd(pdf, "Trailer\n");
- bbox = pdfbbox(pdf);
- pdf->pagebbox = emalloc(sizeof(Rectangle)*npage);
- for(i=0; i<npage; i++) {
- gscmd(pdf, "%d pdfgetpage\n", i+1);
- pdf->pagebbox[i] = pdfbbox(pdf);
- if(Dx(pdf->pagebbox[i]) <= 0)
- pdf->pagebbox[i] = bbox;
- }
- return d;
- }
- static Image*
- pdfdrawpage(Document *doc, int page)
- {
- PDFInfo *pdf = doc->extra;
- Image *im;
- gscmd(pdf, "%d DoPDFPage\n", page+1);
- im = readimage(display, pdf->gsdfd, 0);
- if(im == nil) {
- fprint(2, "fatal: readimage error %r\n");
- wexits("readimage");
- }
- waitgs(pdf);
- return im;
- }
- static char*
- pdfpagename(Document*, int page)
- {
- static char str[15];
- sprint(str, "p %d", page+1);
- return str;
- }
|