diff options
| author | rsc <devnull@localhost> | 2005-01-04 21:23:50 +0000 |
|---|---|---|
| committer | rsc <devnull@localhost> | 2005-01-04 21:23:50 +0000 |
| commit | 24c02865d8fcc97d1fb5cb9281810d8074aa5eb1 (patch) | |
| tree | 3bb16794ded14341ee58d9f1f173ce92fb4d2be7 /src/cmd/page/pdf.c | |
| parent | d1e9002f81f14fbfef1ebc4261edccd9eb97b72c (diff) | |
| download | plan9port-24c02865d8fcc97d1fb5cb9281810d8074aa5eb1.tar.gz plan9port-24c02865d8fcc97d1fb5cb9281810d8074aa5eb1.zip | |
placeholder; does not yet build
Diffstat (limited to 'src/cmd/page/pdf.c')
| -rw-r--r-- | src/cmd/page/pdf.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/cmd/page/pdf.c b/src/cmd/page/pdf.c new file mode 100644 index 00000000..44615a21 --- /dev/null +++ b/src/cmd/page/pdf.c @@ -0,0 +1,155 @@ +/* + * 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 gs; + 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->gs) < 0) + return nil; + + gscmd(&pdf->gs, "%s", pdfprolog); + waitgs(&pdf->gs); + + setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0); + gscmd(&pdf->gs, "(%s) (r) file pdfopen begin\n", fn); + gscmd(&pdf->gs, "pdfpagecount PAGE==\n"); + p = Brdline(&pdf->gs.gsrd, '\n'); + npage = atoi(p); + if(npage < 1) { + fprint(2, "no pages?\n"); + return nil; + } + d->npage = npage; + d->docname = argv[0]; + + gscmd(&pdf->gs, "Trailer\n"); + bbox = pdfbbox(&pdf->gs); + + pdf->pagebbox = emalloc(sizeof(Rectangle)*npage); + for(i=0; i<npage; i++) { + gscmd(&pdf->gs, "%d pdfgetpage\n", i+1); + pdf->pagebbox[i] = pdfbbox(&pdf->gs); + 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->gs, "%d DoPDFPage\n", page+1); + im = readimage(display, pdf->gs.gsdfd, 0); + if(im == nil) { + fprint(2, "fatal: readimage error %r\n"); + wexits("readimage"); + } + waitgs(&pdf->gs); + return im; +} + +static char* +pdfpagename(Document *d, int page) +{ + static char str[15]; + USED(d); + sprint(str, "p %d", page+1); + return str; +} |
