placeholder; does not yet build
This commit is contained in:
parent
d1e9002f81
commit
24c02865d8
13 changed files with 3661 additions and 0 deletions
155
src/cmd/page/pdf.c
Normal file
155
src/cmd/page/pdf.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue