summaryrefslogtreecommitdiffstats
path: root/src/cmd/page/pdf.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-01-04 21:23:50 +0000
committerrsc <devnull@localhost>2005-01-04 21:23:50 +0000
commit24c02865d8fcc97d1fb5cb9281810d8074aa5eb1 (patch)
tree3bb16794ded14341ee58d9f1f173ce92fb4d2be7 /src/cmd/page/pdf.c
parentd1e9002f81f14fbfef1ebc4261edccd9eb97b72c (diff)
downloadplan9port-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.c155
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;
+}