//======================================================================== // // GDKSplashOutputDev.cc // // Copyright 2003 Glyph & Cog, LLC // Copyright 2004 Red Hat, Inc. (GDK port) // //======================================================================== #include #ifdef USE_GCC_PRAGMAS #pragma implementation #endif #include #include #include #include typedef struct { GtkWidget *window; GtkWidget *sw; GtkWidget *drawing_area; GtkWidget *spin_button; PopplerPage *page; PopplerDocument *document; cairo_surface_t *surface; int *window_count; } View; static void drawing_area_expose (GtkWidget *drawing_area, GdkEventExpose *event, void *data) { View *v = (View*) data; cairo_t *cr; gdk_window_clear (drawing_area->window); cr = gdk_cairo_create (drawing_area->window); cairo_set_source_surface (cr, v->surface, 0, 0); cairo_paint (cr); cairo_destroy (cr); } static void view_set_page (View *v, int page) { int w, h; double width, height; cairo_t *cr; v->page = poppler_document_get_page (v->document, page); poppler_page_get_size (v->page, &width, &height); w = (int) ceil(width); h = (int) ceil(height); cairo_surface_destroy (v->surface); v->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); cr = cairo_create (v->surface); poppler_page_render (v->page, cr); cairo_destroy (cr); gtk_widget_set_size_request (v->drawing_area, w, h); gtk_widget_queue_draw (v->drawing_area); gtk_spin_button_set_value (GTK_SPIN_BUTTON (v->spin_button), page); } static void page_changed_callback (GtkSpinButton *button, View *v) { int page; page = gtk_spin_button_get_value_as_int (button); view_set_page (v, page); } static void destroy_window_callback (GtkWindow *window, View *v) { if (--(*v->window_count) == 0) gtk_main_quit(); } static View* view_new (const char *filename, int *window_count) { View *v; GtkWidget *window; GtkWidget *drawing_area; GtkWidget *sw; GtkWidget *vbox, *hbox; GtkWidget *spin_button; int n_pages; v = g_new0 (View, 1); v->document = poppler_document_new_from_file (filename, NULL, NULL); if (v->document == NULL) return NULL; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); vbox = gtk_vbox_new(FALSE, 5); gtk_container_add (GTK_CONTAINER (window), vbox); drawing_area = gtk_drawing_area_new (); sw = gtk_scrolled_window_new (NULL, NULL); gtk_box_pack_end (GTK_BOX (vbox), sw, TRUE, TRUE, 0); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), drawing_area); n_pages = poppler_document_get_n_pages (v->document); spin_button = gtk_spin_button_new_with_range (0, n_pages - 1, 1); g_signal_connect (G_OBJECT (spin_button), "value-changed", G_CALLBACK (page_changed_callback), v); hbox = gtk_hbox_new (FALSE, 5); gtk_box_pack_end (GTK_BOX (hbox), spin_button, FALSE, TRUE, 0); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, TRUE, 0); gtk_widget_show_all (window); gtk_widget_realize (window); v->window = window; v->drawing_area = drawing_area; v->sw = sw; v->window_count = window_count; v->spin_button = spin_button; g_signal_connect (drawing_area, "expose_event", G_CALLBACK (drawing_area_expose), (void*) v); g_signal_connect (window, "destroy", G_CALLBACK (destroy_window_callback), (void*) v); return v; } static int option_page = 0; static GOptionEntry demo_options[] = { { "page", 0, 0, G_OPTION_ARG_INT, &option_page, "Page number", "PAGE" }, { NULL } }; int main (int argc, char *argv []) { View *v; int i, window_count; GOptionContext *ctx; ctx = g_option_context_new("FILENAME ..."); g_option_context_add_main_entries(ctx, demo_options, "main"); g_option_context_parse(ctx, &argc, &argv, NULL); g_option_context_free(ctx); gtk_init (&argc, &argv); if (argc == 1) { fprintf (stderr, "usage: %s PDF-FILES...\n", g_basename (argv[0])); return -1; } window_count = 0; for (i = 1; i < argc; i++) { v = view_new (argv[i], &window_count); if (v == NULL) { g_printerr ("Error loading %s\n", argv[i]); continue; } view_set_page (v, option_page); window_count++; } if (window_count > 0) gtk_main (); return 0; }