CC=codebot
http://codereview.appspot.com/193069
This commit is contained in:
Mathieu Lonjaret 2010-02-04 02:05:03 -08:00 committed by Russ Cox
parent 2d6da3763e
commit d9e047e5d5
8 changed files with 139 additions and 53 deletions

View file

@ -12,6 +12,7 @@ J.R. Mauro <jrm8005@gmail.com>
Jeff Sickel <jas@corpus-callosum.com>
Kris Maglione <jg@suckless.org>
Mathieu Lonjaret <lejatorn@gmail.com>
Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
Michael Teichgräber <mt4swm@googlemail.com>
Michael Teichgräber <mt@ib.wmipf.de>
Russ Cox <rsc@swtch.com>

View file

@ -17,6 +17,7 @@ struct Cached
int page;
int angle;
Image *im;
int ppi;
};
static Cached cache[5];
@ -57,14 +58,28 @@ _cachedpage(Document *doc, int angle, int page, char *ra)
int i;
Cached *c, old;
Image *im, *tmp;
int ppi = 100;
PDFInfo *pdf;
PSInfo *ps;
if((page < 0 || page >= doc->npage) && !doc->fwdonly)
return nil;
if (doc->type == Tpdf){
pdf = (PDFInfo *) doc->extra;
ppi = pdf->gs.ppi;
}
else{
if (doc->type == Tps){
ps = (PSInfo *) doc->extra;
ppi = ps->gs.ppi;
}
}
Again:
for(i=0; i<nelem(cache); i++){
c = &cache[i];
if(c->doc == doc && c->angle == angle && c->page == page){
if(c->doc == doc && c->angle == angle && c->page == page && c->ppi == ppi){
if(chatty) fprint(2, "cache%s hit %d\n", ra, page);
goto Found;
}
@ -80,6 +95,7 @@ Again:
c->im = nil;
c->doc = nil;
c->page = -1;
c->ppi = -1;
if(chatty) fprint(2, "cache%s load %d\n", ra, page);
im = doc->drawpage(doc, page);
@ -129,6 +145,7 @@ Again:
c->page = page;
c->angle = angle;
c->im = im;
c->ppi = ppi;
Found:
if(chatty) fprint(2, "cache%s mtf %d @%d:", ra, c->page, i);

View file

@ -85,6 +85,7 @@ initgfx(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
doc->rmpage = rmpage;
doc->extra = gfx;
doc->fwdonly = 0;
doc->type = Tgfx;
fprint(2, "reading through graphics...\n");
if(argc==0 && buf)

View file

@ -21,6 +21,7 @@ int truecolor;
int imagemode;
int notewatcher;
int notegp;
int fitwin;
char tempfile[40];
int
@ -80,7 +81,7 @@ afmt(Fmt *fmt)
void
usage(void)
{
fprint(2, "usage: page [-biRrw] [-p ppi] file...\n");
fprint(2, "usage: page [-biRrwf] [-p ppi] file...\n");
wexits("usage");
}
@ -142,6 +143,9 @@ threadmain(int argc, char **argv)
case 'W':
winsize = EARGF(usage());
break;
case 'f':
fitwin = 1;
break;
default:
usage();
}ARGEND;

View file

@ -12,6 +12,7 @@ struct Document {
int (*rmpage)(Document*, int);
Biobuf *b;
void *extra;
int type;
};
typedef struct Graphic Graphic;
@ -37,6 +38,12 @@ enum {
Ibmp,
};
enum {
Tgfx,
Tpdf,
Tps,
}
;
void *emalloc(int);
void *erealloc(void*, int);
@ -65,6 +72,7 @@ extern int truetoboundingbox;
extern int wctlfd;
extern int resizing;
extern int mknewwindow;
extern int fitwin;
void rot180(Image*);
Image *rot90(Image*);
@ -73,6 +81,9 @@ Image *resample(Image*, Image*);
/* ghostscript interface shared by ps, pdf */
typedef struct GSInfo GSInfo;
typedef struct PDFInfo PDFInfo;
typedef struct Page Page;
typedef struct PSInfo PSInfo;
struct GSInfo {
Graphic g;
int gsfd;
@ -80,6 +91,24 @@ struct GSInfo {
int gspid;
int ppi;
};
struct PDFInfo {
GSInfo gs;
Rectangle *pagebbox;
};
struct Page {
char *name;
int offset; /* offset of page beginning within file */
};
struct PSInfo {
GSInfo gs;
Rectangle bbox; /* default bounding box */
Page *page;
int npage;
int clueless; /* don't know where page boundaries are */
long psoff; /* location of %! in file */
char ctm[256];
};
void waitgs(GSInfo*);
int gscmd(GSInfo*, char*, ...);
int spawngs(GSInfo*, char*);
@ -98,6 +127,7 @@ int bell(void*, char*);
Image* convert(Graphic *g);
Image* cachedpage(Document*, int, int);
void cacheflush(void);
void fit(void);
extern char tempfile[40];

View file

@ -12,12 +12,6 @@
#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);
@ -97,6 +91,7 @@ initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
d->drawpage = pdfdrawpage;
d->pagename = pdfpagename;
d->fwdonly = 0;
d->type = Tpdf;
if(spawngs(&pdf->gs, "-dDELAYSAFER") < 0)
return nil;

View file

@ -13,24 +13,6 @@
#include <ctype.h>
#include "page.h"
typedef struct PSInfo PSInfo;
typedef struct Page Page;
struct Page {
char *name;
int offset; /* offset of page beginning within file */
};
struct PSInfo {
GSInfo gs;
Rectangle bbox; /* default bounding box */
Page *page;
int npage;
int clueless; /* don't know where page boundaries are */
long psoff; /* location of %! in file */
char ctm[256];
};
static int pswritepage(Document *d, int fd, int page);
static Image* psdrawpage(Document *d, int page);
static char* pspagename(Document*, int);
@ -348,6 +330,11 @@ Keepreading:
d->fwdonly = ps->clueless = dumb;
d->docname = argv[0];
/*
* "tag" the doc as an image for now since there still is the "blank page"
* problem for ps files.
*/
d->type = Tgfx;
if(spawngs(&ps->gs, "-dSAFER") < 0)
return nil;

View file

@ -145,8 +145,12 @@ showpage(int page, Menu *m)
showbottom = 0;
}
redraw(screen);
flushimage(display, 1);
if((doc->type == Tgfx) && fitwin)
fit();
else{
redraw(screen);
flushimage(display, 1);
}
}
char*
@ -252,6 +256,8 @@ viewer(Document *dd)
Rectangle r;
int size[2];
Image *tmp;
PDFInfo *pdf;
PSInfo *ps;
static char *fwditems[] = { "this page", "next page", "exit", 0 };
static char *miditems[] = {
"orig size",
@ -281,7 +287,7 @@ viewer(Document *dd)
};
Alt alts[CN+1];
Plumbmsg *pm;
cp = chancreate(sizeof pm, 0);
assert(cp);
@ -542,7 +548,25 @@ viewer(Document *dd)
zerox();
break;
case Zin: /* zoom in */
{
if (dd->type == Tpdf){ /* pdf */
pdf = (PDFInfo *) dd->extra;
if (pdf != nil){
ppi+= 50;
setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0);
showpage(page, &menu);
}
break;
}
if (dd->type == Tps){ /* ps */
ps = (PSInfo *) dd->extra;
if (ps != nil){
ppi+= 50;
setdim(&ps->gs, Rect(0,0,0,0), ppi, 0);
showpage(page, &menu);
}
break;
}
else{ /* image */
double delta;
Rectangle r;
@ -574,30 +598,12 @@ viewer(Document *dd)
break;
}
case Fit: /* fit */
{
double delta;
Rectangle r;
delta = (double)Dx(screen->r)/(double)Dx(im->r);
if((double)Dy(im->r)*delta > Dy(screen->r))
delta = (double)Dy(screen->r)/(double)Dy(im->r);
r = Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta));
setcursor(mc, &reading);
tmp = xallocimage(display, r, im->chan, 0, DBlack);
if(tmp == nil) {
fprint(2, "out of memory during fit: %r\n");
wexits("memory");
}
resample(im, tmp);
im = tmp;
delayfreeimage(tmp);
setcursor(mc, nil);
ul = screen->r.min;
redraw(screen);
flushimage(display, 1);
break;
/* no op if pdf or ps*/
if (dd->type == Tgfx){
fitwin = 1;
fit();
}
break;
case Rot: /* rotate 90 */
angle = (angle+90) % 360;
showpage(page, &menu);
@ -607,6 +613,25 @@ viewer(Document *dd)
showpage(page, &menu);
break;
case Restore: /* restore */
if (dd->type == Tpdf){ /* pdf */
pdf = (PDFInfo *) dd->extra;
if (pdf != nil){
ppi = 100;
setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0);
}
showpage(page, &menu);
break;
}
if (dd->type == Tps){ /* ps */
ps = (PSInfo *) dd->extra;
if (ps != nil){
ppi = 100;
setdim(&ps->gs, Rect(0,0,0,0), ppi, 0);
}
showpage(page, &menu);
break;
}
fitwin = 0;
showpage(page, &menu);
break;
case Reverse: /* reverse */
@ -1019,3 +1044,29 @@ zerox(void)
writeimage(pfd[1], im, 0);
close(pfd[1]);
}
void
fit()
{
double delta;
Rectangle r;
Image* tmp;
delta = (double)Dx(screen->r)/(double)Dx(im->r);
if((double)Dy(im->r)*delta > Dy(screen->r))
delta = (double)Dy(screen->r)/(double)Dy(im->r);
r = Rect(0, 0, (int)((double)Dx(im->r)*delta), (int)((double)Dy(im->r)*delta));
setcursor(mc, &reading);
tmp = xallocimage(display, r, im->chan, 0, DBlack);
if(tmp == nil) {
fprint(2, "out of memory during fit: %r\n");
wexits("memory");
}
resample(im, tmp);
im = tmp;
delayfreeimage(tmp);
setcursor(mc, nil);
ul = screen->r.min;
redraw(screen);
flushimage(display, 1);
}