mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-24 11:41:58 +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>
|
Jeff Sickel <jas@corpus-callosum.com>
|
||||||
Kris Maglione <jg@suckless.org>
|
Kris Maglione <jg@suckless.org>
|
||||||
Mathieu Lonjaret <lejatorn@gmail.com>
|
Mathieu Lonjaret <lejatorn@gmail.com>
|
||||||
|
Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
|
||||||
Michael Teichgräber <mt4swm@googlemail.com>
|
Michael Teichgräber <mt4swm@googlemail.com>
|
||||||
Michael Teichgräber <mt@ib.wmipf.de>
|
Michael Teichgräber <mt@ib.wmipf.de>
|
||||||
Russ Cox <rsc@swtch.com>
|
Russ Cox <rsc@swtch.com>
|
||||||
|
|
|
@ -17,6 +17,7 @@ struct Cached
|
||||||
int page;
|
int page;
|
||||||
int angle;
|
int angle;
|
||||||
Image *im;
|
Image *im;
|
||||||
|
int ppi;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Cached cache[5];
|
static Cached cache[5];
|
||||||
|
@ -57,14 +58,28 @@ _cachedpage(Document *doc, int angle, int page, char *ra)
|
||||||
int i;
|
int i;
|
||||||
Cached *c, old;
|
Cached *c, old;
|
||||||
Image *im, *tmp;
|
Image *im, *tmp;
|
||||||
|
int ppi = 100;
|
||||||
|
PDFInfo *pdf;
|
||||||
|
PSInfo *ps;
|
||||||
|
|
||||||
if((page < 0 || page >= doc->npage) && !doc->fwdonly)
|
if((page < 0 || page >= doc->npage) && !doc->fwdonly)
|
||||||
return nil;
|
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:
|
Again:
|
||||||
for(i=0; i<nelem(cache); i++){
|
for(i=0; i<nelem(cache); i++){
|
||||||
c = &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);
|
if(chatty) fprint(2, "cache%s hit %d\n", ra, page);
|
||||||
goto Found;
|
goto Found;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +95,7 @@ Again:
|
||||||
c->im = nil;
|
c->im = nil;
|
||||||
c->doc = nil;
|
c->doc = nil;
|
||||||
c->page = -1;
|
c->page = -1;
|
||||||
|
c->ppi = -1;
|
||||||
|
|
||||||
if(chatty) fprint(2, "cache%s load %d\n", ra, page);
|
if(chatty) fprint(2, "cache%s load %d\n", ra, page);
|
||||||
im = doc->drawpage(doc, page);
|
im = doc->drawpage(doc, page);
|
||||||
|
@ -129,6 +145,7 @@ Again:
|
||||||
c->page = page;
|
c->page = page;
|
||||||
c->angle = angle;
|
c->angle = angle;
|
||||||
c->im = im;
|
c->im = im;
|
||||||
|
c->ppi = ppi;
|
||||||
|
|
||||||
Found:
|
Found:
|
||||||
if(chatty) fprint(2, "cache%s mtf %d @%d:", ra, c->page, i);
|
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->rmpage = rmpage;
|
||||||
doc->extra = gfx;
|
doc->extra = gfx;
|
||||||
doc->fwdonly = 0;
|
doc->fwdonly = 0;
|
||||||
|
doc->type = Tgfx;
|
||||||
|
|
||||||
fprint(2, "reading through graphics...\n");
|
fprint(2, "reading through graphics...\n");
|
||||||
if(argc==0 && buf)
|
if(argc==0 && buf)
|
||||||
|
|
|
@ -21,6 +21,7 @@ int truecolor;
|
||||||
int imagemode;
|
int imagemode;
|
||||||
int notewatcher;
|
int notewatcher;
|
||||||
int notegp;
|
int notegp;
|
||||||
|
int fitwin;
|
||||||
char tempfile[40];
|
char tempfile[40];
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -80,7 +81,7 @@ afmt(Fmt *fmt)
|
||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprint(2, "usage: page [-biRrw] [-p ppi] file...\n");
|
fprint(2, "usage: page [-biRrwf] [-p ppi] file...\n");
|
||||||
wexits("usage");
|
wexits("usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +143,9 @@ threadmain(int argc, char **argv)
|
||||||
case 'W':
|
case 'W':
|
||||||
winsize = EARGF(usage());
|
winsize = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
fitwin = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
}ARGEND;
|
}ARGEND;
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct Document {
|
||||||
int (*rmpage)(Document*, int);
|
int (*rmpage)(Document*, int);
|
||||||
Biobuf *b;
|
Biobuf *b;
|
||||||
void *extra;
|
void *extra;
|
||||||
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Graphic Graphic;
|
typedef struct Graphic Graphic;
|
||||||
|
@ -37,6 +38,12 @@ enum {
|
||||||
Ibmp,
|
Ibmp,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Tgfx,
|
||||||
|
Tpdf,
|
||||||
|
Tps,
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
void *emalloc(int);
|
void *emalloc(int);
|
||||||
void *erealloc(void*, int);
|
void *erealloc(void*, int);
|
||||||
|
@ -65,6 +72,7 @@ extern int truetoboundingbox;
|
||||||
extern int wctlfd;
|
extern int wctlfd;
|
||||||
extern int resizing;
|
extern int resizing;
|
||||||
extern int mknewwindow;
|
extern int mknewwindow;
|
||||||
|
extern int fitwin;
|
||||||
|
|
||||||
void rot180(Image*);
|
void rot180(Image*);
|
||||||
Image *rot90(Image*);
|
Image *rot90(Image*);
|
||||||
|
@ -73,6 +81,9 @@ Image *resample(Image*, Image*);
|
||||||
|
|
||||||
/* ghostscript interface shared by ps, pdf */
|
/* ghostscript interface shared by ps, pdf */
|
||||||
typedef struct GSInfo GSInfo;
|
typedef struct GSInfo GSInfo;
|
||||||
|
typedef struct PDFInfo PDFInfo;
|
||||||
|
typedef struct Page Page;
|
||||||
|
typedef struct PSInfo PSInfo;
|
||||||
struct GSInfo {
|
struct GSInfo {
|
||||||
Graphic g;
|
Graphic g;
|
||||||
int gsfd;
|
int gsfd;
|
||||||
|
@ -80,6 +91,24 @@ struct GSInfo {
|
||||||
int gspid;
|
int gspid;
|
||||||
int ppi;
|
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*);
|
void waitgs(GSInfo*);
|
||||||
int gscmd(GSInfo*, char*, ...);
|
int gscmd(GSInfo*, char*, ...);
|
||||||
int spawngs(GSInfo*, char*);
|
int spawngs(GSInfo*, char*);
|
||||||
|
@ -98,6 +127,7 @@ int bell(void*, char*);
|
||||||
Image* convert(Graphic *g);
|
Image* convert(Graphic *g);
|
||||||
Image* cachedpage(Document*, int, int);
|
Image* cachedpage(Document*, int, int);
|
||||||
void cacheflush(void);
|
void cacheflush(void);
|
||||||
|
void fit(void);
|
||||||
|
|
||||||
extern char tempfile[40];
|
extern char tempfile[40];
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,6 @@
|
||||||
#include <bio.h>
|
#include <bio.h>
|
||||||
#include "page.h"
|
#include "page.h"
|
||||||
|
|
||||||
typedef struct PDFInfo PDFInfo;
|
|
||||||
struct PDFInfo {
|
|
||||||
GSInfo gs;
|
|
||||||
Rectangle *pagebbox;
|
|
||||||
};
|
|
||||||
|
|
||||||
static Image* pdfdrawpage(Document *d, int page);
|
static Image* pdfdrawpage(Document *d, int page);
|
||||||
static char* pdfpagename(Document*, int);
|
static char* pdfpagename(Document*, int);
|
||||||
|
|
||||||
|
@ -97,6 +91,7 @@ initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
|
||||||
d->drawpage = pdfdrawpage;
|
d->drawpage = pdfdrawpage;
|
||||||
d->pagename = pdfpagename;
|
d->pagename = pdfpagename;
|
||||||
d->fwdonly = 0;
|
d->fwdonly = 0;
|
||||||
|
d->type = Tpdf;
|
||||||
|
|
||||||
if(spawngs(&pdf->gs, "-dDELAYSAFER") < 0)
|
if(spawngs(&pdf->gs, "-dDELAYSAFER") < 0)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
|
@ -13,24 +13,6 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "page.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 int pswritepage(Document *d, int fd, int page);
|
||||||
static Image* psdrawpage(Document *d, int page);
|
static Image* psdrawpage(Document *d, int page);
|
||||||
static char* pspagename(Document*, int);
|
static char* pspagename(Document*, int);
|
||||||
|
@ -348,6 +330,11 @@ Keepreading:
|
||||||
|
|
||||||
d->fwdonly = ps->clueless = dumb;
|
d->fwdonly = ps->clueless = dumb;
|
||||||
d->docname = argv[0];
|
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)
|
if(spawngs(&ps->gs, "-dSAFER") < 0)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
|
@ -145,9 +145,13 @@ showpage(int page, Menu *m)
|
||||||
showbottom = 0;
|
showbottom = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((doc->type == Tgfx) && fitwin)
|
||||||
|
fit();
|
||||||
|
else{
|
||||||
redraw(screen);
|
redraw(screen);
|
||||||
flushimage(display, 1);
|
flushimage(display, 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
writebitmap(void)
|
writebitmap(void)
|
||||||
|
@ -252,6 +256,8 @@ viewer(Document *dd)
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
int size[2];
|
int size[2];
|
||||||
Image *tmp;
|
Image *tmp;
|
||||||
|
PDFInfo *pdf;
|
||||||
|
PSInfo *ps;
|
||||||
static char *fwditems[] = { "this page", "next page", "exit", 0 };
|
static char *fwditems[] = { "this page", "next page", "exit", 0 };
|
||||||
static char *miditems[] = {
|
static char *miditems[] = {
|
||||||
"orig size",
|
"orig size",
|
||||||
|
@ -542,7 +548,25 @@ viewer(Document *dd)
|
||||||
zerox();
|
zerox();
|
||||||
break;
|
break;
|
||||||
case Zin: /* zoom in */
|
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;
|
double delta;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
|
||||||
|
@ -574,30 +598,12 @@ viewer(Document *dd)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Fit: /* fit */
|
case Fit: /* fit */
|
||||||
{
|
/* no op if pdf or ps*/
|
||||||
double delta;
|
if (dd->type == Tgfx){
|
||||||
Rectangle r;
|
fitwin = 1;
|
||||||
|
fit();
|
||||||
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;
|
break;
|
||||||
}
|
|
||||||
case Rot: /* rotate 90 */
|
case Rot: /* rotate 90 */
|
||||||
angle = (angle+90) % 360;
|
angle = (angle+90) % 360;
|
||||||
showpage(page, &menu);
|
showpage(page, &menu);
|
||||||
|
@ -607,6 +613,25 @@ viewer(Document *dd)
|
||||||
showpage(page, &menu);
|
showpage(page, &menu);
|
||||||
break;
|
break;
|
||||||
case Restore: /* restore */
|
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);
|
showpage(page, &menu);
|
||||||
break;
|
break;
|
||||||
case Reverse: /* reverse */
|
case Reverse: /* reverse */
|
||||||
|
@ -1019,3 +1044,29 @@ zerox(void)
|
||||||
writeimage(pfd[1], im, 0);
|
writeimage(pfd[1], im, 0);
|
||||||
close(pfd[1]);
|
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