gtk-cairo-test.cc 4.64 KB
Newer Older
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//========================================================================
//
// GDKSplashOutputDev.cc
//
// Copyright 2003 Glyph & Cog, LLC
// Copyright 2004 Red Hat, Inc. (GDK port)
//
//========================================================================

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

16
#include <math.h>
Kristian Høgsberg's avatar
Kristian Høgsberg committed
17
18
19
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <cairo-xlib.h>
20
#include <X11/Xutil.h>
Kristian Høgsberg's avatar
Kristian Høgsberg committed
21
#include <gtk/gtk.h>
22
#include <poppler.h>
Kristian Høgsberg's avatar
Kristian Høgsberg committed
23
24
25
26
27
28

typedef struct
{
  GtkWidget *window;
  GtkWidget *sw;
  GtkWidget *drawing_area;
29
  GtkWidget *spin_button;
30
31
32
33
  PopplerPage *page;
  PopplerDocument *document;
  cairo_surface_t *surface;
  int *window_count;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
34
35
36
37
38
39
40
41
42
43
} View;

static void
drawing_area_expose (GtkWidget      *drawing_area,
                     GdkEventExpose *event,
                     void           *data)
{
  View *v = (View*) data;
  GdkRectangle document;
  GdkRectangle draw;
44
  cairo_t *cr;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
45
46

  gdk_window_clear (drawing_area->window);
47
  cr = gdk_cairo_create (drawing_area->window);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
48

49
50
51
  cairo_set_source_surface (cr, v->surface, 0, 0);
  cairo_paint (cr);
  cairo_destroy (cr);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
52
53
}

54
55
static void
view_set_page (View *v, int page)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
56
57
58
{
  int err;
  int w, h;
59
60
61
62
63
64
65
66
67
68
69
70
  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);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
71
  gtk_widget_set_size_request (v->drawing_area, w, h);
72
  gtk_widget_queue_draw (v->drawing_area);
73
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (v->spin_button), page);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
74
75
76
}

static void
77
redraw_callback (void *data)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
78
{
79
80
81
  View *v = (View*) data;

  gtk_widget_queue_draw (v->drawing_area);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
82
83
84
}

static void
85
page_changed_callback (GtkSpinButton *button, View *v)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
86
{
87
    int page;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
88

89
90
91
92
93
94
95
96
97
    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();
Kristian Høgsberg's avatar
Kristian Høgsberg committed
98
99
100
}

static View*
101
view_new (const char *filename, int *window_count)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
102
103
104
105
106
{
  View *v;
  GtkWidget *window;
  GtkWidget *drawing_area;
  GtkWidget *sw;
107
108
109
110
111
112
113
114
115
  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;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
116
117

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
118
  vbox = gtk_vbox_new(FALSE, 5);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
119

120
  gtk_container_add (GTK_CONTAINER (window), vbox);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
121
122
123
124
  drawing_area = gtk_drawing_area_new ();

  sw = gtk_scrolled_window_new (NULL, NULL);

125
126
127
  gtk_box_pack_end (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
					 drawing_area);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
128

129
130
131
132
133
134
  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);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
135

136
137
138
139
  gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

  gtk_widget_show_all (window);
  gtk_widget_realize (window);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
140
141
142
143

  v->window = window;
  v->drawing_area = drawing_area;
  v->sw = sw;
144
  v->window_count = window_count;
145
  v->spin_button = spin_button;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
146
147
148
149
150
151

  g_signal_connect (drawing_area,
                    "expose_event",
                    G_CALLBACK (drawing_area_expose),
                    (void*) v);
  
152
153
154
155
156
  g_signal_connect (window,
                    "destroy",
                    G_CALLBACK (destroy_window_callback),
                    (void*) v);

Kristian Høgsberg's avatar
Kristian Høgsberg committed
157
158
159
  return v;
}

160
161
162
163
164
165
static int option_page = 0;
static GOptionEntry demo_options[] = {
  { "page", 0, 0, G_OPTION_ARG_INT, &option_page, "Page number", "PAGE" },
  { NULL }
};
    
Kristian Høgsberg's avatar
Kristian Høgsberg committed
166
167
168
169
int
main (int argc, char *argv [])
{
  View *v;
170
  int i, window_count;
171
172
173
174
175
176
  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);
177

Kristian Høgsberg's avatar
Kristian Høgsberg committed
178
  gtk_init (&argc, &argv);
179
   
Kristian Høgsberg's avatar
Kristian Høgsberg committed
180
181
  if (argc == 1)
    {
182
      fprintf (stderr, "usage: %s PDF-FILES...\n", g_basename (argv[0]));
Kristian Høgsberg's avatar
Kristian Høgsberg committed
183
184
185
      return -1;
    }
      
186
187
188
189
190
191
192
  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;
      }
Kristian Høgsberg's avatar
Kristian Høgsberg committed
193
      
194
      view_set_page (v, option_page);
195
196
      window_count++;
  }
Kristian Høgsberg's avatar
Kristian Høgsberg committed
197
  
198
199
  if (window_count > 0)
    gtk_main ();
Kristian Høgsberg's avatar
Kristian Høgsberg committed
200
201
202
  
  return 0;
}