tR=rsc CC=codebot http://codereview.appspot.com/193069 - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d9e047e5d5560912da6d2860fa25e427322f08bb
 (DIR) parent 2d6da3763ec643f353a1c48e2e7a2ed7c25046a7
 (HTM) Author: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
       Date:   Thu,  4 Feb 2010 02:05:03 -0800
       
       R=rsc
       CC=codebot
       http://codereview.appspot.com/193069
       
       Diffstat:
         M CONTRIBUTORS                        |       1 +
         M src/cmd/page/cache.c                |      19 ++++++++++++++++++-
         M src/cmd/page/gfx.c                  |       1 +
         M src/cmd/page/page.c                 |       6 +++++-
         M src/cmd/page/page.h                 |      30 ++++++++++++++++++++++++++++++
         M src/cmd/page/pdf.c                  |       7 +------
         M src/cmd/page/ps.c                   |      23 +++++------------------
         M src/cmd/page/view.c                 |     105 +++++++++++++++++++++++--------
       
       8 files changed, 139 insertions(+), 53 deletions(-)
       ---
 (DIR) diff --git a/CONTRIBUTORS b/CONTRIBUTORS
       t@@ -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>
 (DIR) diff --git a/src/cmd/page/cache.c b/src/cmd/page/cache.c
       t@@ -17,6 +17,7 @@ struct Cached
                int page;
                int angle;
                Image *im;
       +        int ppi;
        };
        
        static Cached cache[5];
       t@@ -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;
                        }
       t@@ -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);
       t@@ -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);
 (DIR) diff --git a/src/cmd/page/gfx.c b/src/cmd/page/gfx.c
       t@@ -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)
 (DIR) diff --git a/src/cmd/page/page.c b/src/cmd/page/page.c
       t@@ -21,6 +21,7 @@ int truecolor;
        int imagemode;
        int notewatcher;
        int notegp;
       +int fitwin;
        char tempfile[40];
        
        int
       t@@ -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");
        }
        
       t@@ -142,6 +143,9 @@ threadmain(int argc, char **argv)
                case 'W':
                        winsize = EARGF(usage());
                        break;
       +        case 'f':
       +                fitwin = 1;
       +                break; 
                default:
                        usage();
                }ARGEND;
 (DIR) diff --git a/src/cmd/page/page.h b/src/cmd/page/page.h
       t@@ -12,6 +12,7 @@ struct Document {
                int        (*rmpage)(Document*, int);
                Biobuf *b;
                void *extra;
       +        int type;
        };
        
        typedef struct Graphic        Graphic;
       t@@ -37,6 +38,12 @@ enum {
                Ibmp,
        };
        
       +enum {
       +        Tgfx,
       +        Tpdf,
       +        Tps,
       +}
       +;
        
        void *emalloc(int);
        void *erealloc(void*, int);
       t@@ -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*);
       t@@ -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;
       t@@ -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*);
       t@@ -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];
        
 (DIR) diff --git a/src/cmd/page/pdf.c b/src/cmd/page/pdf.c
       t@@ -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);
        
       t@@ -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;
 (DIR) diff --git a/src/cmd/page/ps.c b/src/cmd/page/ps.c
       t@@ -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);
       t@@ -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;
 (DIR) diff --git a/src/cmd/page/view.c b/src/cmd/page/view.c
       t@@ -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*
       t@@ -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",
       t@@ -281,7 +287,7 @@ viewer(Document *dd)
                };
                Alt alts[CN+1];
                Plumbmsg *pm;
       -
       +        
                cp = chancreate(sizeof pm, 0);
                assert(cp);
        
       t@@ -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;
        
       t@@ -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);
       t@@ -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 */
       t@@ -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);
       +}