fbpdf: add fit to width and fit to height command
authorAli Gholami Rudi <ali@rudi.ir>
Wed, 29 Aug 2012 08:19:29 +0000 (29 12:49 +0430)
committerAli Gholami Rudi <ali@rudi.ir>
Wed, 29 Aug 2012 08:19:29 +0000 (29 12:49 +0430)
README
djvulibre.c
doc.h
fbpdf.c
mupdf.c
poppler.c

diff --git a/README b/README
index 7ca4e81..53cb050 100644 (file)
--- a/README
+++ b/README
@@ -45,4 +45,6 @@ L             show bottom
 ^H/^U          (backspace) page up
 ^L             redraw
 e              reload current file
+f              fit to height
+w              fit to width
 ============== ================================================
index 5d395bf..8f54cdc 100644 (file)
@@ -43,8 +43,8 @@ static void djvu_render(ddjvu_page_t *page, int mode, void *bitmap, int cols,
 #define SIZE           (1 << 13)
 static char img[SIZE * SIZE];
 
-int doc_draw(struct doc *doc, fbval_t *bitmap, int p, int rows, int cols,
-               int zoom, int rotate)
+int doc_draw(struct doc *doc, int p, int zoom, int rotate,
+               fbval_t *bitmap, int *rows, int *cols)
 {
        ddjvu_page_t *page;
        ddjvu_rect_t rect;
@@ -68,13 +68,15 @@ int doc_draw(struct doc *doc, fbval_t *bitmap, int p, int rows, int cols,
        djvu_render(page, DDJVU_RENDER_FOREGROUND, img, SIZE, &rect, &rect);
        ddjvu_page_release(page);
        zoom /= 4;
-       w = MIN(cols, rect.w * zoom / 10);
-       h = MIN(rows, rect.h * zoom / 10);
+       w = MIN(*cols, rect.w * zoom / 10);
+       h = MIN(*rows, rect.h * zoom / 10);
        for (i = 0; i < h; i++) {
-               int xs = i * cols + (cols - w) / 2;
+               int xs = i * *cols + (*cols - w) / 2;
                for (j = 0; j < w; j++)
                        bitmap[xs + j] = img[i * 10 / zoom * SIZE + j * 10 / zoom];
        }
+       *cols = w;
+       *rows = h;
        return 0;
 }
 
diff --git a/doc.h b/doc.h
index fcc50cf..88ba15c 100644 (file)
--- a/doc.h
+++ b/doc.h
@@ -6,5 +6,6 @@ typedef unsigned int fbval_t;
 
 struct doc *doc_open(char *path);
 int doc_pages(struct doc *doc);
-int doc_draw(struct doc *doc, fbval_t *bitmap, int page, int rows, int cols, int zoom, int rotate);
+int doc_draw(struct doc *doc, int page, int zoom, int rotate,
+               fbval_t *bitmap, int *rows, int *cols);
 void doc_close(struct doc *doc);
diff --git a/fbpdf.c b/fbpdf.c
index 0256997..1001c71 100644 (file)
--- a/fbpdf.c
+++ b/fbpdf.c
@@ -25,8 +25,9 @@
 #define PDFCOLS                        (1 << 11)
 #define PDFROWS                        (1 << 12)
 
-static fbval_t pbuf[PDFROWS * PDFCOLS];
 static struct doc *doc;
+static fbval_t pbuf[PDFROWS * PDFCOLS];        /* current page */
+static int prows, pcols;               /* the dimensions of current page */
 
 static int num = 1;
 static struct termios termios;
@@ -51,13 +52,22 @@ static int showpage(int p, int h)
        if (p < 1 || p > doc_pages(doc))
                return 0;
        memset(pbuf, 0x00, sizeof(pbuf));
-       doc_draw(doc, pbuf, p, PDFROWS, PDFCOLS, zoom, rotate);
+       prows = PDFROWS;
+       pcols = PDFCOLS;
+       doc_draw(doc, p, zoom, rotate, pbuf, &prows, &pcols);
        num = p;
        head = h;
        draw();
        return 0;
 }
 
+static void zoom_page(int z)
+{
+       int _zoom = zoom;
+       zoom = z;
+       showpage(num, MIN(PDFROWS - fb_rows(), head * zoom / _zoom));
+}
+
 static int readkey(void)
 {
        unsigned char b;
@@ -113,13 +123,10 @@ static void mainloop(void)
        int step = fb_rows() / PAGESTEPS;
        int hstep = fb_cols() / PAGESTEPS;
        int c, c2;
-       int _zoom;
        term_setup();
        signal(SIGCONT, sigcont);
        showpage(num, 0);
        while ((c = readkey()) != -1) {
-               int maxhead = PDFROWS - fb_rows();
-               int maxleft = PDFCOLS - fb_cols();
                switch (c) {
                case CTRLKEY('f'):
                case 'J':
@@ -133,9 +140,13 @@ static void mainloop(void)
                        showpage(getcount(doc_pages(doc)), 0);
                        break;
                case 'z':
-                       _zoom = zoom;
-                       zoom = getcount(15);
-                       showpage(num, MIN(maxhead, head * zoom / _zoom));
+                       zoom_page(getcount(15));
+                       break;
+               case 'w':
+                       zoom_page(zoom * fb_cols() / pcols);
+                       break;
+               case 'f':
+                       zoom_page(zoom * fb_rows() / prows);
                        break;
                case 'r':
                        rotate = getcount(0);
@@ -187,10 +198,10 @@ static void mainloop(void)
                        head = 0;
                        break;
                case 'L':
-                       head = maxhead;
+                       head = MAX(0, prows - fb_rows());
                        break;
                case 'M':
-                       head = maxhead / 2;
+                       head = prows / 2;
                        break;
                case ' ':
                case CTRL('d'):
@@ -206,8 +217,8 @@ static void mainloop(void)
                        /* no need to redraw */
                        continue;
                }
-               head = MAX(0, MIN(maxhead, head));
-               left = MAX(0, MIN(maxleft, left));
+               head = MAX(0, MIN(PDFROWS - fb_rows(), head));
+               left = MAX(0, MIN(PDFCOLS - fb_cols(), left));
                draw();
        }
 }
diff --git a/mupdf.c b/mupdf.c
index e868dbc..69ec37f 100644 (file)
--- a/mupdf.c
+++ b/mupdf.c
@@ -11,7 +11,8 @@ struct doc {
        fz_document *pdf;
 };
 
-int doc_draw(struct doc *doc, fbval_t *bitmap, int p, int rows, int cols, int zoom, int rotate)
+int doc_draw(struct doc *doc, int p, int zoom, int rotate,
+               fbval_t *bitmap, int *rows, int *cols)
 {
        fz_matrix ctm;
        fz_bbox bbox;
@@ -31,8 +32,8 @@ int doc_draw(struct doc *doc, fbval_t *bitmap, int p, int rows, int cols, int zo
        rect = fz_bound_page(doc->pdf, page);
        rect = fz_transform_rect(ctm, rect);
        bbox = fz_round_rect(rect);
-       w = MIN_(cols, rect.x1 - rect.x0);
-       h = MIN_(rows, rect.y1 - rect.y0);
+       w = MIN_(*cols, rect.x1 - rect.x0);
+       h = MIN_(*rows, rect.y1 - rect.y0);
 
        pix = fz_new_pixmap_with_bbox(doc->ctx, fz_device_rgb, bbox);
        fz_clear_pixmap_with_value(doc->ctx, pix, 0xff);
@@ -42,7 +43,7 @@ int doc_draw(struct doc *doc, fbval_t *bitmap, int p, int rows, int cols, int zo
        fz_free_device(dev);
 
        for (y = 0; y < h; y++) {
-               int xs = (h - y - 1) * cols + (cols - w) / 2;
+               int xs = (h - y - 1) * *cols + (*cols - w) / 2;
                for (x = 0; x < w; x++) {
                        unsigned char *s = fz_pixmap_samples(doc->ctx, pix) +
                                        y * fz_pixmap_width(doc->ctx, pix) * 4 + x * 4;
@@ -52,6 +53,8 @@ int doc_draw(struct doc *doc, fbval_t *bitmap, int p, int rows, int cols, int zo
        }
        fz_drop_pixmap(doc->ctx, pix);
        fz_free_page(doc->pdf, page);
+       *cols = w;
+       *rows = h;
        return 0;
 }
 
index 3615116..4ff373f 100644 (file)
--- a/poppler.c
+++ b/poppler.c
@@ -8,8 +8,8 @@ struct doc {
        PopplerDocument *doc;
 };
 
-int doc_draw(struct doc *doc, fbval_t *bitmap, int p,
-               int rows, int cols, int zoom, int rotate)
+int doc_draw(struct doc *doc, int page, int zoom, int rotate,
+               fbval_t *bitmap, int *rows, int *cols)
 {
        cairo_t *cairo;
        cairo_surface_t *surface;
@@ -18,7 +18,7 @@ int doc_draw(struct doc *doc, fbval_t *bitmap, int p,
        int i, j;
        int h, w;
        int iw;
-       surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, cols, rows);
+       surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, *cols, *rows);
        cairo = cairo_create(surface);
        cairo_scale(cairo, (float) zoom / 10, (float) zoom / 10);
        cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0);
@@ -27,17 +27,19 @@ int doc_draw(struct doc *doc, fbval_t *bitmap, int p,
        page = poppler_document_get_page(doc->doc, p - 1);
        poppler_page_render(page, cairo);
        iw = cairo_image_surface_get_width(surface);
-       h = MIN(rows, cairo_image_surface_get_height(surface));
-       w = MIN(cols, iw);
+       h = MIN(*rows, cairo_image_surface_get_height(surface));
+       w = MIN(*cols, iw);
        for (i = 0; i < h; i++) {
                for (j = 0; j < w; j++) {
                        unsigned char *s = img + (i * iw + j) * 4;
-                       bitmap[i * cols + j] = FB_VAL(*(s + 2), *(s + 1), *s);
+                       bitmap[i * *cols + j] = FB_VAL(*(s + 2), *(s + 1), *s);
                }
        }
        cairo_destroy(cairo);
        cairo_surface_destroy(surface);
        g_object_unref(G_OBJECT(page));
+       *cols = w;
+       *rows = h;
        return 0;
 }