Code

gtk-tpdfv/tpdfview: Implemented 'width', 'height', 'fit' zoom modes.
authorSebastian Harl <sh@tokkee.org>
Fri, 21 Oct 2011 12:42:59 +0000 (14:42 +0200)
committerSebastian Harl <sh@tokkee.org>
Fri, 21 Oct 2011 12:42:59 +0000 (14:42 +0200)
Currently, when leaving those modes, the zoom will be reset to the value
before entering any of those modes. This is done on purpose ;-)

src/gtk-tpdfv.c
src/gtk-tpdfv.h
src/tpdfview.c

index b04d2c6f9cb3ffb177e039dc45f10fa268b3f84d..4398719385557f7144ca42c674bdf66acfd47630 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#define TPDFV_MIN(a, b) ((a) <= (b) ? (a) : (b))
+#define TPDFV_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+typedef enum {
+       TPDFV_ZOOM_CUSTOM = 0,
+       TPDFV_ZOOM_WIDTH,
+       TPDFV_ZOOM_HEIGHT,
+       TPDFV_ZOOM_FIT,
+} tpdfv_zoommode_t;
+
 typedef struct {
        char *filename;
 
@@ -52,6 +62,7 @@ typedef struct {
        int current_page_no;
        int total_pages;
 
+       tpdfv_zoommode_t zoom_mode;
        double zoom_factor;
 
        double delta_x;
@@ -111,6 +122,7 @@ tpdfv_init(gtk_tpdfv_t *pdf, const char *filename)
 
        pdf->total_pages = poppler_document_get_n_pages(pdf->doc);
 
+       pdf->zoom_mode   = TPDFV_ZOOM_CUSTOM;
        pdf->zoom_factor = 1.0;
        pdf->delta_x = pdf->delta_y = 0.0;
        return TRUE;
@@ -178,7 +190,39 @@ gtk_tpdfv_expose(GtkWidget *tpdfv, GdkEventExpose *event)
        cairo_clip(cr);
 
        /* zoom, scrolling */
-       cairo_scale(cr, pdf->zoom_factor, pdf->zoom_factor);
+       if (pdf->zoom_mode == TPDFV_ZOOM_CUSTOM) {
+               cairo_scale(cr, pdf->zoom_factor, pdf->zoom_factor);
+       }
+       else {
+               gdouble width;
+               gdouble height;
+
+               gdouble page_width  = 0.0;
+               gdouble page_height = 0.0;
+
+               double zoom_factor  = 1.0;
+
+               poppler_page_get_size(pdf->current_page, &page_width, &page_height);
+               width  = (gdouble)tpdfv->allocation.width;
+               height = (gdouble)tpdfv->allocation.height;
+
+               if (pdf->zoom_mode == TPDFV_ZOOM_WIDTH) {
+                       zoom_factor = (double)(width / page_width);
+               }
+               else if (pdf->zoom_mode == TPDFV_ZOOM_HEIGHT) {
+                       zoom_factor = (double)(height / page_height);
+               }
+               else if (pdf->zoom_mode == TPDFV_ZOOM_FIT) {
+                       zoom_factor = (double)TPDFV_MIN(width / page_width,
+                                       height / page_height);
+               }
+               else {
+                       assert(0);
+               }
+
+               cairo_scale(cr, zoom_factor, zoom_factor);
+       }
+
        cairo_translate(cr, pdf->delta_x, pdf->delta_y);
 
        poppler_page_render(pdf->current_page, cr);
@@ -291,6 +335,7 @@ gtk_tpdfv_zoom_in(GtkWidget *widget)
 
        pdf = GTK_TPDFV_GET_PRIVATE(widget);
        pdf->zoom_factor *= 1.2;
+       pdf->zoom_mode    = TPDFV_ZOOM_CUSTOM;
        do_redraw(widget);
 } /* gtk_tpdfv_zoom_in */
 
@@ -303,6 +348,7 @@ gtk_tpdfv_zoom_out(GtkWidget *widget)
 
        if (pdf->zoom_factor > DBL_EPSILON * 2.0) {
                pdf->zoom_factor /= 1.2;
+               pdf->zoom_mode    = TPDFV_ZOOM_CUSTOM;
                do_redraw(widget);
        }
 } /* gtk_tpdfv_zoom_out */
@@ -314,9 +360,40 @@ gtk_tpdfv_zoom_1(GtkWidget *widget)
 
        pdf = GTK_TPDFV_GET_PRIVATE(widget);
        pdf->zoom_factor = 1.0;
+       pdf->zoom_mode   = TPDFV_ZOOM_CUSTOM;
        do_redraw(widget);
 } /* gtk_tpdfv_zoom_1 */
 
+void
+gtk_tpdfv_zoom_width(GtkWidget *widget)
+{
+       gtk_tpdfv_t *pdf;
+
+       pdf = GTK_TPDFV_GET_PRIVATE(widget);
+       pdf->zoom_mode = TPDFV_ZOOM_WIDTH;
+       do_redraw(widget);
+} /* gtk_tpdfv_zoom_width */
+
+void
+gtk_tpdfv_zoom_height(GtkWidget *widget)
+{
+       gtk_tpdfv_t *pdf;
+
+       pdf = GTK_TPDFV_GET_PRIVATE(widget);
+       pdf->zoom_mode = TPDFV_ZOOM_HEIGHT;
+       do_redraw(widget);
+} /* gtk_tpdfv_zoom_width */
+
+void
+gtk_tpdfv_zoom_fit(GtkWidget *widget)
+{
+       gtk_tpdfv_t *pdf;
+
+       pdf = GTK_TPDFV_GET_PRIVATE(widget);
+       pdf->zoom_mode = TPDFV_ZOOM_FIT;
+       do_redraw(widget);
+} /* gtk_tpdfv_zoom_width */
+
 void
 gtk_tpdfv_scroll_up(GtkWidget *widget)
 {
index c4e0599416b8043f75e4ac2b81abc095a1e2143a..7d260bd28e5491c213567de01a31dd338cc2d8fb 100644 (file)
@@ -90,6 +90,12 @@ void
 gtk_tpdfv_zoom_out(GtkWidget *widget);
 void
 gtk_tpdfv_zoom_1(GtkWidget *widget);
+void
+gtk_tpdfv_zoom_width(GtkWidget *widget);
+void
+gtk_tpdfv_zoom_height(GtkWidget *widget);
+void
+gtk_tpdfv_zoom_fit(GtkWidget *widget);
 
 /*
  * gtk_tpdfv_scroll_up, gtk_tpdfv_scroll_down,
index 8c556004540d712a2638292f35bce77e4056d684..d46aef030a44a977ebd72a4ed0d5b0f1aa40ca27 100644 (file)
@@ -135,6 +135,15 @@ key_press(GtkWidget __attribute__((unused)) *widget,
                case GDK_1:
                        gtk_tpdfv_zoom_1(tpdfv);
                        break;
+               case GDK_w:
+                       gtk_tpdfv_zoom_width(tpdfv);
+                       break;
+               case GDK_h:
+                       gtk_tpdfv_zoom_height(tpdfv);
+                       break;
+               case GDK_z:
+                       gtk_tpdfv_zoom_fit(tpdfv);
+                       break;
 
                /* scrolling */
                case GDK_Up: