mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
parent
2d6da3763e
commit
d9e047e5d5
8 changed files with 139 additions and 53 deletions
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -145,9 +145,13 @@ showpage(int page, Menu *m)
|
|||
showbottom = 0;
|
||||
}
|
||||
|
||||
if((doc->type == Tgfx) && fitwin)
|
||||
fit();
|
||||
else{
|
||||
redraw(screen);
|
||||
flushimage(display, 1);
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
writebitmap(void)
|
||||
|
@ -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",
|
||||
|
@ -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");
|
||||
/* no op if pdf or ps*/
|
||||
if (dd->type == Tgfx){
|
||||
fitwin = 1;
|
||||
fit();
|
||||
}
|
||||
resample(im, tmp);
|
||||
im = tmp;
|
||||
delayfreeimage(tmp);
|
||||
setcursor(mc, nil);
|
||||
ul = screen->r.min;
|
||||
redraw(screen);
|
||||
flushimage(display, 1);
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue